From 4efb17fcf5c04bb4d991fc52f8aefadb3a23e098 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 18:41:22 +0900 Subject: [PATCH 001/336] mk: tests.mk simplify the method to clean arm testing directory --- mk/tests.mk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mk/tests.mk b/mk/tests.mk index 3858de3f264d..35d567ef771b 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -122,9 +122,7 @@ CFG_ADB_TEST_DIR=/data/tmp $(info check: android device test dir $(CFG_ADB_TEST_DIR) ready \ $(shell adb remount 1>/dev/null) \ $(shell adb shell mkdir $(CFG_ADB_TEST_DIR) 1>/dev/null) \ - $(shell adb shell rm $(CFG_ADB_TEST_DIR)/*.so 1>/dev/null) \ - $(shell adb shell rm $(CFG_ADB_TEST_DIR)/*-arm-linux-androideabi 1>/dev/null) \ - $(shell adb shell rm $(CFG_ADB_TEST_DIR)/*-arm-linux-androideabi.* 1>/dev/null) \ + $(shell adb shell rm -rf $(CFG_ADB_TEST_DIR)/* 1>/dev/null) \ $(shell adb push $(S)src/etc/adb_run_wrapper.sh $(CFG_ADB_TEST_DIR) 1>/dev/null) \ $(shell adb push $(CFG_ANDROID_CROSS_PATH)/arm-linux-androideabi/lib/armv7-a/libgnustl_shared.so \ $(CFG_ADB_TEST_DIR) 1>/dev/null) \ From 9e618cf95494469275eca6b108eb569db2600b75 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 18:44:30 +0900 Subject: [PATCH 002/336] etc: modify adb_run_wrapper.sh to avoid 'expr' unrecognization at some android devices --- src/etc/adb_run_wrapper.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/adb_run_wrapper.sh b/src/etc/adb_run_wrapper.sh index fb1e0937fc92..29d328c857d9 100755 --- a/src/etc/adb_run_wrapper.sh +++ b/src/etc/adb_run_wrapper.sh @@ -26,7 +26,7 @@ then /system/bin/sleep $WAIT /system/bin/sync fi - L_COUNT=`expr $L_COUNT+1` + L_COUNT=$((L_COUNT+1)) done echo $L_RET > $PATH/$RUN.exitcode From f7ee7d09dd520d5a392de7a28477e50465cce243 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 18:46:04 +0900 Subject: [PATCH 003/336] etc: add TEST_EXEC_ENV for run-pass to adb_run_wrapper.sh --- src/etc/adb_run_wrapper.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/etc/adb_run_wrapper.sh b/src/etc/adb_run_wrapper.sh index 29d328c857d9..7cbcf94dd409 100755 --- a/src/etc/adb_run_wrapper.sh +++ b/src/etc/adb_run_wrapper.sh @@ -17,9 +17,10 @@ then L_RET=1 L_COUNT=0 + cd $PATH while [ $L_RET -eq 1 ] do - LD_LIBRARY_PATH=$PATH $PATH/$RUN $@ 1>$PATH/$RUN.stdout 2>$PATH/$RUN.stderr + TEST_EXEC_ENV=22 LD_LIBRARY_PATH=$PATH $PATH/$RUN $@ 1>$PATH/$RUN.stdout 2>$PATH/$RUN.stderr L_RET=$? if [ $L_COUNT -gt 0 ] then From c4c7e0fb6689f606ec74d9cc29c8e0f7c71fd51c Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 18:50:29 +0900 Subject: [PATCH 004/336] test: adjust some test cases of run-pass for android --- src/test/run-pass/core-run-destroy.rs | 8 +++++++- src/test/run-pass/intrinsic-alignment.rs | 2 +- src/test/run-pass/rec-align-u64.rs | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index 81cdb926e5f9..64f9ecc9de22 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -42,12 +42,18 @@ fn test_destroy_actually_kills(force: bool) { #[cfg(windows)] static BLOCK_COMMAND: &'static str = "cmd"; - #[cfg(unix)] + #[cfg(unix,not(target_os="android"))] fn process_exists(pid: libc::pid_t) -> bool { let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]); str::from_bytes(output).contains(pid.to_str()) } + #[cfg(unix,target_os="android")] + fn process_exists(pid: libc::pid_t) -> bool { + let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]); + str::from_bytes(output).contains(~"root") + } + #[cfg(windows)] fn process_exists(pid: libc::pid_t) -> bool { diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs index 7a54b87404e4..27767db8733d 100644 --- a/src/test/run-pass/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsic-alignment.rs @@ -60,7 +60,7 @@ mod m { pub fn main() { unsafe { assert_eq!(::rusti::pref_align_of::(), 8u); - assert_eq!(::rusti::min_align_of::(), 4u); + assert_eq!(::rusti::min_align_of::(), 8u); } } } diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs index 8c67b971243f..7bc7a8583b91 100644 --- a/src/test/run-pass/rec-align-u64.rs +++ b/src/test/run-pass/rec-align-u64.rs @@ -63,8 +63,8 @@ mod m { mod m { #[cfg(target_arch = "arm")] pub mod m { - pub fn align() -> uint { 4u } - pub fn size() -> uint { 12u } + pub fn align() -> uint { 8u } + pub fn size() -> uint { 16u } } } From b82370cec65b17456b1d5b98a283d3f46a8ab09a Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 18:53:33 +0900 Subject: [PATCH 005/336] std: fix stat struct of android (SEGV error from run-pass/stat.rs on android) --- src/libstd/libc.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++- src/libstd/path.rs | 30 +++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 26205c930f0c..b5a8be23e42a 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -257,6 +257,8 @@ pub mod types { pub type intptr_t = int; pub type uintptr_t = uint; } + #[cfg(target_arch = "x86")] + #[cfg(target_arch = "mips")] pub mod posix88 { pub type off_t = i32; pub type dev_t = u64; @@ -268,6 +270,20 @@ pub mod types { pub type mode_t = u32; pub type ssize_t = i32; } + #[cfg(target_arch = "arm")] + pub mod posix88 { + pub type off_t = i32; + pub type dev_t = u32; + pub type ino_t = u32; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u16; + pub type ssize_t = i32; + } + #[cfg(target_arch = "x86")] + #[cfg(target_arch = "mips")] pub mod posix01 { use libc::types::os::arch::c95::{c_short, c_long, c_ulong, time_t}; use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t}; @@ -279,7 +295,6 @@ pub mod types { pub type blkcnt_t = i32; #[cfg(target_arch = "x86")] - #[cfg(target_arch = "arm")] pub struct stat { st_dev: dev_t, __pad1: c_short, @@ -327,6 +342,39 @@ pub mod types { st_pad5: [c_long, ..14], } } + #[cfg(target_arch = "arm")] + pub mod posix01 { + use libc::types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; + use libc::types::os::arch::c99::{c_longlong, c_ulonglong}; + use libc::types::os::arch::posix88::{uid_t, gid_t, ino_t}; + use libc::types::os::arch::posix88::{uid_t}; + + pub type nlink_t = u16; + pub type blksize_t = u32; + pub type blkcnt_t = u32; + + pub struct stat { + st_dev: c_ulonglong, + __pad0: [c_uchar, ..4], + __st_ino: ino_t, + st_mode: c_uint, + st_nlink: c_uint, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: c_ulonglong, + __pad3: [c_uchar, ..4], + st_size: c_longlong, + st_blksize: blksize_t, + st_blocks: c_ulonglong, + st_atime: time_t, + st_atime_nsec: c_ulong, + st_mtime: time_t, + st_mtime_nsec: c_ulong, + st_ctime: time_t, + st_ctime_nsec: c_ulong, + st_ino: c_ulonglong + } + } pub mod posix08 {} pub mod bsd44 {} pub mod extra {} diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9c4e8f083584..b1f0ffdae656 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -128,7 +128,6 @@ pub trait GenericPath { #[cfg(target_os = "android")] mod stat { #[cfg(target_arch = "x86")] - #[cfg(target_arch = "arm")] pub mod arch { use libc; @@ -158,6 +157,35 @@ mod stat { } } + #[cfg(target_arch = "arm")] + pub mod arch { + use libc; + + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + __pad0: [0, ..4], + __st_ino: 0, + st_mode: 0, + st_nlink: 0, + st_uid: 0, + st_gid: 0, + st_rdev: 0, + __pad3: [0, ..4], + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atime: 0, + st_atime_nsec: 0, + st_mtime: 0, + st_mtime_nsec: 0, + st_ctime: 0, + st_ctime_nsec: 0, + st_ino: 0 + } + } + } + #[cfg(target_arch = "mips")] pub mod arch { use libc; From 474bd60c1bc242664bff876804e8fa4c5b27214d Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 17 Jun 2013 20:20:24 +0900 Subject: [PATCH 006/336] rt: fix jemalloc android cross-compile for mac --- src/rt/jemalloc/Makefile.in | 1 + src/rt/jemalloc/configure | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rt/jemalloc/Makefile.in b/src/rt/jemalloc/Makefile.in index 74810472d117..e3cecb0e840a 100644 --- a/src/rt/jemalloc/Makefile.in +++ b/src/rt/jemalloc/Makefile.in @@ -9,6 +9,7 @@ vpath % . SHELL := /bin/sh CC := @CC@ +AR := @AR@ # Configuration parameters. DESTDIR = diff --git a/src/rt/jemalloc/configure b/src/rt/jemalloc/configure index 67f3dc309027..428ac770a229 100755 --- a/src/rt/jemalloc/configure +++ b/src/rt/jemalloc/configure @@ -4453,7 +4453,7 @@ PIC_CFLAGS='-fPIC -DPIC' CTARGET='-o $@' LDTARGET='-o $@' EXTRA_LDFLAGS= -MKLIB='ar crus $@' +MKLIB='$(AR) crus $@' CC_MM=1 default_munmap="1" From c1b1091a4a63971875e760bbfe76f90fec23d208 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Fri, 14 Jun 2013 21:31:36 -0700 Subject: [PATCH 007/336] Support printf formats in terminfo strings terminfo parameterized strings supports a limited subset of printf-style formatting operations, such as %#5.3d. --- src/libextra/terminfo/parm.rs | 274 ++++++++++++++++++++++++++++++---- 1 file changed, 243 insertions(+), 31 deletions(-) diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs index 11f0fc23be51..dca890ddf516 100644 --- a/src/libextra/terminfo/parm.rs +++ b/src/libextra/terminfo/parm.rs @@ -11,7 +11,8 @@ //! Parameterized string expansion use core::prelude::*; -use core::{char, int, vec}; +use core::{char, vec, util}; +use core::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common}; use core::iterator::IteratorUtil; #[deriving(Eq)] @@ -23,13 +24,21 @@ enum States { PushParam, CharConstant, CharClose, - IntConstant, + IntConstant(int), + FormatPattern(Flags, FormatState), SeekIfElse(int), SeekIfElsePercent(int), SeekIfEnd(int), SeekIfEndPercent(int) } +#[deriving(Eq)] +enum FormatState { + FormatStateFlags, + FormatStateWidth, + FormatStatePrecision +} + /// Types of parameters a capability can use pub enum Param { String(~str), @@ -71,8 +80,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) let mut stack: ~[Param] = ~[]; - let mut intstate = ~[]; - // Copy parameters into a local vector for mutability let mut mparams = [Number(0), ..9]; for mparams.mut_iter().zip(params.iter()).advance |(dst, &src)| { @@ -100,26 +107,11 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) _ => return Err(~"a non-char was used with %c") } } else { return Err(~"stack is empty") }, - 's' => if stack.len() > 0 { - match stack.pop() { - String(s) => output.push_all(s.as_bytes()), - _ => return Err(~"a non-str was used with %s") - } - } else { return Err(~"stack is empty") }, - 'd' => if stack.len() > 0 { - match stack.pop() { - Number(x) => { - let s = x.to_str(); - output.push_all(s.as_bytes()) - } - _ => return Err(~"a non-number was used with %d") - } - } else { return Err(~"stack is empty") }, 'p' => state = PushParam, 'P' => state = SetVar, 'g' => state = GetVar, '\'' => state = CharConstant, - '{' => state = IntConstant, + '{' => state = IntConstant(0), 'l' => if stack.len() > 0 { match stack.pop() { String(s) => stack.push(Number(s.len() as int)), @@ -231,6 +223,30 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) (_, _) => return Err(~"first two params not numbers with %i") }, + // printf-style support for %doxXs + 'd'|'o'|'x'|'X'|'s' => if stack.len() > 0 { + let flags = Flags::new(); + let res = format(stack.pop(), FormatOp::from_char(cur), flags); + if res.is_err() { return res } + output.push_all(res.unwrap()) + } else { return Err(~"stack is empty") }, + ':'|'#'|' '|'.'|'0'..'9' => { + let mut flags = Flags::new(); + let mut fstate = FormatStateFlags; + match cur { + ':' => (), + '#' => flags.alternate = true, + ' ' => flags.space = true, + '.' => fstate = FormatStatePrecision, + '0'..'9' => { + flags.width = (cur - '0') as uint; + fstate = FormatStateWidth; + } + _ => util::unreachable() + } + state = FormatPattern(flags, fstate); + } + // conditionals '?' => (), 't' => if stack.len() > 0 { @@ -288,17 +304,61 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) return Err(~"malformed character constant"); } }, - IntConstant => { - if cur == '}' { - stack.push(match int::parse_bytes(intstate, 10) { - Some(n) => Number(n), - None => return Err(~"bad int constant") - }); - intstate.clear(); - state = Nothing; - } else { - intstate.push(cur as u8); - old_state = Nothing; + IntConstant(i) => { + match cur { + '}' => { + stack.push(Number(i)); + state = Nothing; + } + '0'..'9' => { + state = IntConstant(i*10 + ((cur - '0') as int)); + old_state = Nothing; + } + _ => return Err(~"bad int constant") + } + } + FormatPattern(ref mut flags, ref mut fstate) => { + old_state = Nothing; + match (*fstate, cur) { + (_,'d')|(_,'o')|(_,'x')|(_,'X')|(_,'s') => if stack.len() > 0 { + let res = format(stack.pop(), FormatOp::from_char(cur), *flags); + if res.is_err() { return res } + output.push_all(res.unwrap()); + old_state = state; // will cause state to go to Nothing + } else { return Err(~"stack is empty") }, + (FormatStateFlags,'#') => { + flags.alternate = true; + } + (FormatStateFlags,'-') => { + flags.left = true; + } + (FormatStateFlags,'+') => { + flags.sign = true; + } + (FormatStateFlags,' ') => { + flags.space = true; + } + (FormatStateFlags,'0'..'9') => { + flags.width = (cur - '0') as uint; + *fstate = FormatStateWidth; + } + (FormatStateFlags,'.') => { + *fstate = FormatStatePrecision; + } + (FormatStateWidth,'0'..'9') => { + let old = flags.width; + flags.width = flags.width * 10 + ((cur - '0') as uint); + if flags.width < old { return Err(~"format width overflow") } + } + (FormatStateWidth,'.') => { + *fstate = FormatStatePrecision; + } + (FormatStatePrecision,'0'..'9') => { + let old = flags.precision; + flags.precision = flags.precision * 10 + ((cur - '0') as uint); + if flags.precision < old { return Err(~"format precision overflow") } + } + _ => return Err(~"invalid format specifier") } } SeekIfElse(level) => { @@ -349,6 +409,142 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) Ok(output) } +#[deriving(Eq)] +priv struct Flags { + width: uint, + precision: uint, + alternate: bool, + left: bool, + sign: bool, + space: bool +} + +impl Flags { + priv fn new() -> Flags { + Flags{ width: 0, precision: 0, alternate: false, + left: false, sign: false, space: false } + } +} + +priv enum FormatOp { + FormatDigit, + FormatOctal, + FormatHex, + FormatHEX, + FormatString +} + +impl FormatOp { + priv fn from_char(c: char) -> FormatOp { + match c { + 'd' => FormatDigit, + 'o' => FormatOctal, + 'x' => FormatHex, + 'X' => FormatHEX, + 's' => FormatString, + _ => fail!("bad FormatOp char") + } + } + priv fn to_char(self) -> char { + match self { + FormatDigit => 'd', + FormatOctal => 'o', + FormatHex => 'x', + FormatHEX => 'X', + FormatString => 's' + } + } +} + +priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> { + let mut s = match val { + Number(d) => { + match op { + FormatString => { + return Err(~"non-number on stack with %s") + } + _ => { + let radix = match op { + FormatDigit => 10, + FormatOctal => 8, + FormatHex|FormatHEX => 16, + FormatString => util::unreachable() + }; + let mut (s,_) = match op { + FormatDigit => { + let sign = if flags.sign { SignAll } else { SignNeg }; + to_str_bytes_common(&d, radix, false, sign, DigAll) + } + _ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll) + }; + if flags.precision > s.len() { + let mut s_ = vec::with_capacity(flags.precision); + let n = flags.precision - s.len(); + s_.grow(n, &('0' as u8)); + s_.push_all_move(s); + s = s_; + } + assert!(!s.is_empty(), "string conversion produced empty result"); + match op { + FormatDigit => { + if flags.space && !(s[0] == '-' as u8 || s[0] == '+' as u8) { + s.unshift(' ' as u8); + } + } + FormatOctal => { + if flags.alternate && s[0] != '0' as u8 { + s.unshift('0' as u8); + } + } + FormatHex => { + if flags.alternate { + let s_ = util::replace(&mut s, ~['0' as u8, 'x' as u8]); + s.push_all_move(s_); + } + } + FormatHEX => { + s = s.into_ascii().to_upper().into_bytes(); + if flags.alternate { + let s_ = util::replace(&mut s, ~['0' as u8, 'X' as u8]); + s.push_all_move(s_); + } + } + FormatString => util::unreachable() + } + s + } + } + } + String(s) => { + match op { + FormatString => { + let mut s = s.as_bytes_with_null_consume(); + s.pop(); // remove the null + if flags.precision > 0 && flags.precision < s.len() { + s.truncate(flags.precision); + } + s + } + _ => { + return Err(fmt!("non-string on stack with %%%c", op.to_char())) + } + } + } + }; + if flags.width > s.len() { + let n = flags.width - s.len(); + if flags.left { + s.grow(n, &(' ' as u8)); + } else { + let mut s_ = vec::with_capacity(flags.width); + s_.grow(n, &(' ' as u8)); + s_.push_all_move(s); + s = s_; + } + } + Ok(s) +} + #[cfg(test)] mod test { use super::*; @@ -443,4 +639,20 @@ mod test { assert!(res.is_ok(), res.unwrap_err()); assert_eq!(res.unwrap(), bytes!("\\E[38;5;42m").to_owned()); } + + #[test] + fn test_format() { + let mut varstruct = Variables::new(); + let vars = &mut varstruct; + assert_eq!(expand(bytes!("%p1%s%p2%2s%p3%2s%p4%.2s"), + [String(~"foo"), String(~"foo"), String(~"f"), String(~"foo")], vars), + Ok(bytes!("foofoo ffo").to_owned())); + assert_eq!(expand(bytes!("%p1%:-4.2s"), [String(~"foo")], vars), + Ok(bytes!("fo ").to_owned())); + + assert_eq!(expand(bytes!("%p1%d%p1%.3d%p1%5d%p1%:+d"), [Number(1)], vars), + Ok(bytes!("1001 1+1").to_owned())); + assert_eq!(expand(bytes!("%p1%o%p1%#o%p2%6.4x%p2%#6.4X"), [Number(15), Number(27)], vars), + Ok(bytes!("17017 001b0X001B").to_owned())); + } } From b8efa2ebe02eb59c6d493b3c428f40804011d413 Mon Sep 17 00:00:00 2001 From: Steven Stewart-Gallus Date: Sat, 15 Jun 2013 13:40:56 -0700 Subject: [PATCH 008/336] Cleanup src/librustc/back --- src/librustc/back/link.rs | 143 +++++++++++++++++-------------------- src/librustc/back/rpath.rs | 15 ++-- 2 files changed, 73 insertions(+), 85 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 6aa97e393eab..5df63d650e90 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -129,14 +129,12 @@ pub mod jit { debug!("linking: %s", path); - let _: () = str::as_c_str( - path, - |buf_t| { - if !llvm::LLVMRustLoadCrate(manager, buf_t) { - llvm_err(sess, ~"Could not link"); - } - debug!("linked: %s", path); - }); + do str::as_c_str(path) |buf_t| { + if !llvm::LLVMRustLoadCrate(manager, buf_t) { + llvm_err(sess, ~"Could not link"); + } + debug!("linked: %s", path); + } } // We custom-build a JIT execution engine via some rust wrappers @@ -203,11 +201,10 @@ pub mod write { use core::str; pub fn is_object_or_assembly_or_exe(ot: output_type) -> bool { - if ot == output_type_assembly || ot == output_type_object || - ot == output_type_exe { - return true; + match ot { + output_type_assembly | output_type_object | output_type_exe => true, + _ => false } - return false; } pub fn run_passes(sess: Session, @@ -290,11 +287,11 @@ pub mod write { session::Aggressive => LLVMOptAggressive }; - let FileType; - if output_type == output_type_object || - output_type == output_type_exe { - FileType = lib::llvm::ObjectFile; - } else { FileType = lib::llvm::AssemblyFile; } + let FileType = match output_type { + output_type_object | output_type_exe => lib::llvm::ObjectFile, + _ => lib::llvm::AssemblyFile + }; + // Write optimized bitcode if --save-temps was on. if opts.save_temps { @@ -384,11 +381,11 @@ pub mod write { (--android-cross-path)") } }; - let mut cc_args = ~[]; - cc_args.push(~"-c"); - cc_args.push(~"-o"); - cc_args.push(object.to_str()); - cc_args.push(assembly.to_str()); + + let cc_args = ~[ + ~"-c", + ~"-o", object.to_str(), + assembly.to_str()]; let prog = run::process_output(cc_prog, cc_args); @@ -474,19 +471,19 @@ pub fn build_link_meta(sess: Session, let linkage_metas = attr::find_linkage_metas(c.node.attrs); attr::require_unique_names(sess.diagnostic(), linkage_metas); for linkage_metas.each |meta| { - if "name" == attr::get_meta_item_name(*meta) { - match attr::get_meta_item_value_str(*meta) { - // Changing attr would avoid the need for the copy - // here - Some(v) => { name = Some(v); } - None => cmh_items.push(*meta) - } - } else if "vers" == attr::get_meta_item_name(*meta) { - match attr::get_meta_item_value_str(*meta) { - Some(v) => { vers = Some(v); } - None => cmh_items.push(*meta) - } - } else { cmh_items.push(*meta); } + match attr::get_meta_item_value_str(*meta) { + Some(value) => { + let item_name : &str = attr::get_meta_item_name(*meta); + match item_name { + // Changing attr would avoid the need for the copy + // here + "name" => name = Some(value), + "vers" => vers = Some(value), + _ => cmh_items.push(*meta) + } + }, + None => cmh_items.push(*meta) + } } ProvidedMetas { @@ -548,32 +545,32 @@ pub fn build_link_meta(sess: Session, } fn crate_meta_name(sess: Session, output: &Path, opt_name: Option<@str>) - -> @str { - return match opt_name { - Some(v) => v, - None => { + -> @str { + match opt_name { + Some(v) => v, + None => { // to_managed could go away if there was a version of // filestem that returned an @str let name = session::expect(sess, - output.filestem(), - || fmt!("output file name `%s` doesn't\ - appear to have a stem", - output.to_str())).to_managed(); + output.filestem(), + || fmt!("output file name `%s` doesn't\ + appear to have a stem", + output.to_str())).to_managed(); warn_missing(sess, "name", name); name - } - }; + } + } } fn crate_meta_vers(sess: Session, opt_vers: Option<@str>) -> @str { - return match opt_vers { - Some(v) => v, - None => { + match opt_vers { + Some(v) => v, + None => { let vers = @"0.0"; warn_missing(sess, "vers", vers); vers - } - }; + } + } } let ProvidedMetas { @@ -699,10 +696,10 @@ pub fn exported_name(sess: Session, path: path, hash: &str, vers: &str) -> ~str { - return mangle(sess, - vec::append_one( - vec::append_one(path, path_name(sess.ident_of(hash))), - path_name(sess.ident_of(vers)))); + mangle(sess, + vec::append_one( + vec::append_one(path, path_name(sess.ident_of(hash))), + path_name(sess.ident_of(vers)))) } pub fn mangle_exported_name(ccx: &mut CrateContext, @@ -739,16 +736,16 @@ pub fn mangle_internal_name_by_type_and_seq(ccx: &mut CrateContext, pub fn mangle_internal_name_by_path_and_seq(ccx: &mut CrateContext, path: path, flav: &str) -> ~str { - return mangle(ccx.sess, - vec::append_one(path, path_name((ccx.names)(flav)))); + mangle(ccx.sess, + vec::append_one(path, path_name((ccx.names)(flav)))) } pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str { - return mangle(ccx.sess, path); + mangle(ccx.sess, path) } pub fn mangle_internal_name_by_seq(ccx: &mut CrateContext, flav: &str) -> ~str { - return fmt!("%s_%u", flav, (ccx.names)(flav).name); + fmt!("%s_%u", flav, (ccx.names)(flav).name) } @@ -776,8 +773,8 @@ pub fn link_binary(sess: Session, // so we add a condition to make it use gcc. let cc_prog: ~str = match sess.opts.linker { Some(ref linker) => copy *linker, - None => { - if sess.targ_cfg.os == session::os_android { + None => match sess.targ_cfg.os { + session::os_android => match &sess.opts.android_cross_path { &Some(ref path) => { fmt!("%s/bin/arm-linux-androideabi-gcc", *path) @@ -786,12 +783,9 @@ pub fn link_binary(sess: Session, sess.fatal("need Android NDK path for linking \ (--android-cross-path)") } - } - } else if sess.targ_cfg.os == session::os_win32 { - ~"gcc" - } else { - ~"cc" - } + }, + session::os_win32 => ~"gcc", + _ => ~"cc" } }; // The invocations of cc share some flags across platforms @@ -866,17 +860,14 @@ pub fn link_args(sess: Session, let mut args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args); - args.push(~"-o"); - args.push(output.to_str()); - args.push(obj_filename.to_str()); + args.push_all([ + ~"-o", output.to_str(), + obj_filename.to_str()]); - let lib_cmd; - let os = sess.targ_cfg.os; - if os == session::os_macos { - lib_cmd = ~"-dynamiclib"; - } else { - lib_cmd = ~"-shared"; - } + let lib_cmd = match sess.targ_cfg.os { + session::os_macos => ~"-dynamiclib", + _ => ~"-shared" + }; // # Crate linking diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index ed70f41f3ec8..9bc7d31077dc 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -21,10 +21,7 @@ use core::util; use core::vec; fn not_win32(os: session::os) -> bool { - match os { - session::os_win32 => false, - _ => true - } + os != session::os_win32 } pub fn get_rpath_flags(sess: session::Session, out_filename: &Path) @@ -122,7 +119,7 @@ pub fn get_rpath_relative_to_output(os: session::os, // Mac doesn't appear to support $ORIGIN let prefix = match os { - session::os_android |session::os_linux | session::os_freebsd + session::os_android | session::os_linux | session::os_freebsd => "$ORIGIN", session::os_macos => "@executable_path", session::os_win32 => util::unreachable() @@ -159,10 +156,10 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { path.push_all(vec::slice(split2, start_idx, len2 - 1)); - if !path.is_empty() { - return Path("").push_many(path); + return if !path.is_empty() { + Path("").push_many(path) } else { - return Path("."); + Path(".") } } From 8066dfd4ad24c011f581c80b818ac352711a5942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Wed, 19 Jun 2013 13:42:47 +0200 Subject: [PATCH 009/336] syntax::diagnostics: Color the ^~~~ in green for better visibility Fixes #7164. --- src/libsyntax/diagnostic.rs | 41 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index e67ca5260b8f..5af6e3679aad 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -189,28 +189,34 @@ fn diagnosticcolor(lvl: level) -> u8 { } } -fn print_diagnostic(topic: &str, lvl: level, msg: &str) { - let t = term::Terminal::new(io::stderr()); +fn print_maybe_colored(msg: &str, color: u8) { + let stderr = io::stderr(); + let t = term::Terminal::new(stderr); + + match t { + Ok(term) => { + if stderr.get_type() == io::Screen { + term.fg(color); + stderr.write_str(msg); + term.reset(); + } else { + stderr.write_str(msg); + } + }, + _ => stderr.write_str(msg) + } +} + +fn print_diagnostic(topic: &str, lvl: level, msg: &str) { let stderr = io::stderr(); if !topic.is_empty() { stderr.write_str(fmt!("%s ", topic)); } - match t { - Ok(term) => { - if stderr.get_type() == io::Screen { - term.fg(diagnosticcolor(lvl)); - stderr.write_str(fmt!("%s: ", diagnosticstr(lvl))); - term.reset(); - stderr.write_str(fmt!("%s\n", msg)); - } else { - stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg)); - } - }, - _ => stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg)) - } + print_maybe_colored(fmt!("%s: ", diagnosticstr(lvl)), diagnosticcolor(lvl)); + stderr.write_str(fmt!("%s\n", msg)); } pub fn collect(messages: @mut ~[~str]) @@ -292,14 +298,15 @@ fn highlight_lines(cm: @codemap::CodeMap, _ => " " // -squigly-line as well (instead of a }; // space). This way the squigly-line will } // usually appear in the correct position. - s += "^"; + io::stderr().write_str(s); + let mut s = ~"^"; let hi = cm.lookup_char_pos(sp.hi); if hi.col != lo.col { // the ^ already takes up one space let num_squiglies = hi.col.to_uint()-lo.col.to_uint()-1u; for num_squiglies.times() { s += "~"; } } - io::stderr().write_str(s + "\n"); + print_maybe_colored(s + "\n", term::color_bright_green); } } From 2c7903d59946e6a091bdcbb5f2ff51021c57a1d2 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 17 Jun 2013 18:02:17 -0400 Subject: [PATCH 010/336] Consume once fns when calling them (#2549). --- src/librustc/middle/moves.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 2217e632d14a..4f31107620ff 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -183,6 +183,7 @@ struct VisitContext { move_maps: MoveMaps } +#[deriving(Eq)] enum UseMode { Move, // This value or something owned by it is moved. Read // Read no matter what the type. @@ -335,7 +336,27 @@ impl VisitContext { } expr_call(callee, ref args, _) => { // callee(args) - self.use_expr(callee, Read, visitor); + // Figure out whether the called function is consumed. + let mode = match ty::get(ty::expr_ty(self.tcx, callee)).sty { + ty::ty_closure(ref cty) => { + match cty.onceness { + Once => Move, + Many => Read, + } + }, + ty::ty_bare_fn(*) => Read, + ref x => + self.tcx.sess.span_bug(callee.span, + fmt!("non-function type in moves for expr_call: %?", x)), + }; + // Note we're not using consume_expr, which uses type_moves_by_default + // to determine the mode, for this. The reason is that while stack + // closures should be noncopyable, they shouldn't move by default; + // calling a closure should only consume it if it's once. + if mode == Move { + self.move_maps.moves_map.insert(callee.id); + } + self.use_expr(callee, mode, visitor); self.use_fn_args(callee.id, *args, visitor); } From 1496216db6e0ab266df6dcbda31d9fab495afcf9 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 17 Jun 2013 19:06:36 -0400 Subject: [PATCH 011/336] Permit moving out of captured upvars in once fns. Close #2549. --- .../borrowck/gather_loans/gather_moves.rs | 20 +++++++++++++++++-- src/librustc/middle/mem_categorization.rs | 10 +++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index 5431a0a29980..d982be684a2d 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -101,9 +101,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt, cmt0: mc::cmt, cmt: mc::cmt) -> bool { match cmt.cat { - mc::cat_stack_upvar(*) | mc::cat_implicit_self(*) | - mc::cat_copied_upvar(*) | mc::cat_deref(_, _, mc::region_ptr(*)) | mc::cat_deref(_, _, mc::gc_ptr(*)) | mc::cat_deref(_, _, mc::unsafe_ptr(*)) => { @@ -114,6 +112,24 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt, false } + // These are separate from the above cases for a better error message. + mc::cat_stack_upvar(*) | + mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, _ }) => { + bccx.span_err( + cmt0.span, + fmt!("cannot move out of %s \ + (unless the destination closure type is `once fn')", + bccx.cmt_to_str(cmt))); + false + } + + // Can move out of captured upvars only if the destination closure + // type is 'once'. 1-shot stack closures emit the copied_upvar form + // (see mem_categorization.rs). + mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Once, _ }) => { + true + } + // It seems strange to allow a move out of a static item, // but what happens in practice is that you have a // reference to a constant with a type that should be diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 14764e7bc37c..d020cf651a4a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -78,7 +78,7 @@ pub enum categorization { } #[deriving(Eq)] -struct CopiedUpvar { +pub struct CopiedUpvar { upvar_id: ast::node_id, onceness: ast::Onceness, } @@ -497,9 +497,8 @@ impl mem_categorization_ctxt { let ty = ty::node_id_to_type(self.tcx, fn_node_id); match ty::get(ty).sty { ty::ty_closure(ref closure_ty) => { - let sigil = closure_ty.sigil; - match sigil { - ast::BorrowedSigil => { + match (closure_ty.sigil, closure_ty.onceness) { + (ast::BorrowedSigil, ast::Many) => { let upvar_cmt = self.cat_def(id, span, expr_ty, *inner); @cmt_ { @@ -510,7 +509,8 @@ impl mem_categorization_ctxt { ty:upvar_cmt.ty } } - ast::OwnedSigil | ast::ManagedSigil => { + (ast::BorrowedSigil, ast::Once) | + (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => { // FIXME #2152 allow mutation of moved upvars @cmt_ { id:id, From c1f037e6ac75e05e6bc3f05ec6cab9de8c971e81 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 17 Jun 2013 19:25:06 -0400 Subject: [PATCH 012/336] Add tests for once functions (#2549). --- .../once-cant-call-twice-on-heap.rs | 29 +++++++++++++++++++ .../once-cant-call-twice-on-stack.rs | 29 +++++++++++++++++++ .../once-cant-copy-stack-once-fn-copy.rs | 20 +++++++++++++ .../once-cant-move-out-of-non-once-on-heap.rs | 29 +++++++++++++++++++ ...once-cant-move-out-of-non-once-on-stack.rs | 29 +++++++++++++++++++ src/test/run-pass/once-move-out-on-heap.rs | 27 +++++++++++++++++ src/test/run-pass/once-move-out-on-stack.rs | 27 +++++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 src/test/compile-fail/once-cant-call-twice-on-heap.rs create mode 100644 src/test/compile-fail/once-cant-call-twice-on-stack.rs create mode 100644 src/test/compile-fail/once-cant-copy-stack-once-fn-copy.rs create mode 100644 src/test/compile-fail/once-cant-move-out-of-non-once-on-heap.rs create mode 100644 src/test/compile-fail/once-cant-move-out-of-non-once-on-stack.rs create mode 100644 src/test/run-pass/once-move-out-on-heap.rs create mode 100644 src/test/run-pass/once-move-out-on-stack.rs diff --git a/src/test/compile-fail/once-cant-call-twice-on-heap.rs b/src/test/compile-fail/once-cant-call-twice-on-heap.rs new file mode 100644 index 000000000000..4436675d69a5 --- /dev/null +++ b/src/test/compile-fail/once-cant-call-twice-on-heap.rs @@ -0,0 +1,29 @@ +// 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. + +// Testing guarantees provided by once functions. +// This program would segfault if it were legal. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: ~once fn()) { + blk(); + blk(); //~ ERROR use of moved value +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); + } +} diff --git a/src/test/compile-fail/once-cant-call-twice-on-stack.rs b/src/test/compile-fail/once-cant-call-twice-on-stack.rs new file mode 100644 index 000000000000..7048f1a7a76f --- /dev/null +++ b/src/test/compile-fail/once-cant-call-twice-on-stack.rs @@ -0,0 +1,29 @@ +// 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. + +// Testing guarantees provided by once functions. +// This program would segfault if it were legal. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: &once fn()) { + blk(); + blk(); //~ ERROR use of moved value +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); + } +} diff --git a/src/test/compile-fail/once-cant-copy-stack-once-fn-copy.rs b/src/test/compile-fail/once-cant-copy-stack-once-fn-copy.rs new file mode 100644 index 000000000000..6f524c0068b9 --- /dev/null +++ b/src/test/compile-fail/once-cant-copy-stack-once-fn-copy.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. + +// Though it should be legal to copy a heap-allocated "once fn:Copy", +// stack closures are not deep-copied, so (counterintuitively) it should be +// illegal to copy them. + +fn foo<'r>(blk: &'r once fn:Copy()) -> (&'r once fn:Copy(), &'r once fn:Copy()) { + (copy blk, blk) //~ ERROR copying a value of non-copyable type +} + +fn main() { +} diff --git a/src/test/compile-fail/once-cant-move-out-of-non-once-on-heap.rs b/src/test/compile-fail/once-cant-move-out-of-non-once-on-heap.rs new file mode 100644 index 000000000000..61f158cec27e --- /dev/null +++ b/src/test/compile-fail/once-cant-move-out-of-non-once-on-heap.rs @@ -0,0 +1,29 @@ +// 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. + +// Testing guarantees provided by once functions. +// This program would segfault if it were legal. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: ~fn()) { + blk(); + blk(); +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); //~ ERROR cannot move out of captured outer variable + } +} diff --git a/src/test/compile-fail/once-cant-move-out-of-non-once-on-stack.rs b/src/test/compile-fail/once-cant-move-out-of-non-once-on-stack.rs new file mode 100644 index 000000000000..42c8b9a99982 --- /dev/null +++ b/src/test/compile-fail/once-cant-move-out-of-non-once-on-stack.rs @@ -0,0 +1,29 @@ +// 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. + +// Testing guarantees provided by once functions. +// This program would segfault if it were legal. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: &fn()) { + blk(); + blk(); +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); //~ ERROR cannot move out of captured outer variable + } +} diff --git a/src/test/run-pass/once-move-out-on-heap.rs b/src/test/run-pass/once-move-out-on-heap.rs new file mode 100644 index 000000000000..8846abb47fc7 --- /dev/null +++ b/src/test/run-pass/once-move-out-on-heap.rs @@ -0,0 +1,27 @@ +// 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. + +// Testing guarantees provided by once functions. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: ~once fn()) { + blk(); +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); + } +} diff --git a/src/test/run-pass/once-move-out-on-stack.rs b/src/test/run-pass/once-move-out-on-stack.rs new file mode 100644 index 000000000000..21e4a3fa4268 --- /dev/null +++ b/src/test/run-pass/once-move-out-on-stack.rs @@ -0,0 +1,27 @@ +// 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. + +// Testing guarantees provided by once functions. + +extern mod extra; +use extra::arc; +use std::util; + +fn foo(blk: &once fn()) { + blk(); +} + +fn main() { + let x = arc::ARC(true); + do foo { + assert!(*x.get()); + util::ignore(x); + } +} From 643be38cfe269effdc02111677559f74385b1056 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 15:53:05 -0400 Subject: [PATCH 013/336] Hide the once-move-out privilege for stack fns behind '-Z once-fns' --- src/librustc/driver/session.rs | 55 ++++++++++-------- src/librustc/middle/mem_categorization.rs | 57 +++++++++++-------- .../once-cant-call-twice-on-stack.rs | 1 + src/test/run-pass/once-move-out-on-stack.rs | 1 + 4 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 73e8cfea8ca2..e4cb614c948e 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -45,32 +45,33 @@ pub struct config { float_type: float_ty } -pub static verbose: uint = 1 << 0; -pub static time_passes: uint = 1 << 1; -pub static count_llvm_insns: uint = 1 << 2; -pub static time_llvm_passes: uint = 1 << 3; -pub static trans_stats: uint = 1 << 4; -pub static asm_comments: uint = 1 << 5; -pub static no_verify: uint = 1 << 6; -pub static trace: uint = 1 << 7; -pub static coherence: uint = 1 << 8; -pub static borrowck_stats: uint = 1 << 9; -pub static borrowck_note_pure: uint = 1 << 10; -pub static borrowck_note_loan: uint = 1 << 11; -pub static no_landing_pads: uint = 1 << 12; -pub static debug_llvm: uint = 1 << 13; -pub static count_type_sizes: uint = 1 << 14; -pub static meta_stats: uint = 1 << 15; -pub static no_opt: uint = 1 << 16; +pub static verbose: uint = 1 << 0; +pub static time_passes: uint = 1 << 1; +pub static count_llvm_insns: uint = 1 << 2; +pub static time_llvm_passes: uint = 1 << 3; +pub static trans_stats: uint = 1 << 4; +pub static asm_comments: uint = 1 << 5; +pub static no_verify: uint = 1 << 6; +pub static trace: uint = 1 << 7; +pub static coherence: uint = 1 << 8; +pub static borrowck_stats: uint = 1 << 9; +pub static borrowck_note_pure: uint = 1 << 10; +pub static borrowck_note_loan: uint = 1 << 11; +pub static no_landing_pads: uint = 1 << 12; +pub static debug_llvm: uint = 1 << 13; +pub static count_type_sizes: uint = 1 << 14; +pub static meta_stats: uint = 1 << 15; +pub static no_opt: uint = 1 << 16; pub static no_monomorphic_collapse: uint = 1 << 17; -pub static gc: uint = 1 << 18; -pub static jit: uint = 1 << 19; -pub static debug_info: uint = 1 << 20; -pub static extra_debug_info: uint = 1 << 21; -pub static statik: uint = 1 << 22; -pub static print_link_args: uint = 1 << 23; -pub static no_debug_borrows: uint = 1 << 24; -pub static lint_llvm : uint = 1 << 25; +pub static gc: uint = 1 << 18; +pub static jit: uint = 1 << 19; +pub static debug_info: uint = 1 << 20; +pub static extra_debug_info: uint = 1 << 21; +pub static statik: uint = 1 << 22; +pub static print_link_args: uint = 1 << 23; +pub static no_debug_borrows: uint = 1 << 24; +pub static lint_llvm: uint = 1 << 25; +pub static once_fns: uint = 1 << 26; pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"verbose", ~"in general, enable more debug printouts", verbose), @@ -112,6 +113,9 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] { (~"lint-llvm", ~"Run the LLVM lint pass on the pre-optimization IR", lint_llvm), + (~"once-fns", + ~"Allow 'once fn' closures to deinitialize captured variables", + once_fns), ] } @@ -293,6 +297,7 @@ impl Session_ { pub fn debug_borrows(@self) -> bool { self.opts.optimize == No && !self.debugging_opt(no_debug_borrows) } + pub fn once_fns(@self) -> bool { self.debugging_opt(once_fns) } // pointless function, now... pub fn str_of(@self, id: ast::ident) -> @str { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d020cf651a4a..2eedd35c314a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -497,30 +497,41 @@ impl mem_categorization_ctxt { let ty = ty::node_id_to_type(self.tcx, fn_node_id); match ty::get(ty).sty { ty::ty_closure(ref closure_ty) => { - match (closure_ty.sigil, closure_ty.onceness) { - (ast::BorrowedSigil, ast::Many) => { - let upvar_cmt = - self.cat_def(id, span, expr_ty, *inner); - @cmt_ { - id:id, - span:span, - cat:cat_stack_upvar(upvar_cmt), - mutbl:upvar_cmt.mutbl.inherit(), - ty:upvar_cmt.ty - } + // Decide whether to use implicit reference or by copy/move + // capture for the upvar. This, combined with the onceness, + // determines whether the closure can move out of it. + let var_is_refd = match (closure_ty.sigil, closure_ty.onceness) { + // Many-shot stack closures can never move out. + (ast::BorrowedSigil, ast::Many) => true, + // 1-shot stack closures can move out with "-Z once-fns". + (ast::BorrowedSigil, ast::Once) + if self.tcx.sess.once_fns() => false, + (ast::BorrowedSigil, ast::Once) => true, + // Heap closures always capture by copy/move, and can + // move out iff they are once. + (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => false, + + }; + if var_is_refd { + let upvar_cmt = + self.cat_def(id, span, expr_ty, *inner); + @cmt_ { + id:id, + span:span, + cat:cat_stack_upvar(upvar_cmt), + mutbl:upvar_cmt.mutbl.inherit(), + ty:upvar_cmt.ty } - (ast::BorrowedSigil, ast::Once) | - (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => { - // FIXME #2152 allow mutation of moved upvars - @cmt_ { - id:id, - span:span, - cat:cat_copied_upvar(CopiedUpvar { - upvar_id: upvar_id, - onceness: closure_ty.onceness}), - mutbl:McImmutable, - ty:expr_ty - } + } else { + // FIXME #2152 allow mutation of moved upvars + @cmt_ { + id:id, + span:span, + cat:cat_copied_upvar(CopiedUpvar { + upvar_id: upvar_id, + onceness: closure_ty.onceness}), + mutbl:McImmutable, + ty:expr_ty } } } diff --git a/src/test/compile-fail/once-cant-call-twice-on-stack.rs b/src/test/compile-fail/once-cant-call-twice-on-stack.rs index 7048f1a7a76f..10877be549e2 100644 --- a/src/test/compile-fail/once-cant-call-twice-on-stack.rs +++ b/src/test/compile-fail/once-cant-call-twice-on-stack.rs @@ -11,6 +11,7 @@ // Testing guarantees provided by once functions. // This program would segfault if it were legal. +// compile-flags:-Z once-fns extern mod extra; use extra::arc; use std::util; diff --git a/src/test/run-pass/once-move-out-on-stack.rs b/src/test/run-pass/once-move-out-on-stack.rs index 21e4a3fa4268..fb8a45172943 100644 --- a/src/test/run-pass/once-move-out-on-stack.rs +++ b/src/test/run-pass/once-move-out-on-stack.rs @@ -10,6 +10,7 @@ // Testing guarantees provided by once functions. +// compile-flags:-Z once-fns extern mod extra; use extra::arc; use std::util; From 3ba8404c88972f2324ce97fa7e5a433399d946ed Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 16:03:31 -0400 Subject: [PATCH 014/336] Oops, hide 'unless once fn' error message hint behind -Z once-fns too. --- .../middle/borrowck/gather_loans/gather_moves.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index d982be684a2d..b28b056e22b3 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -115,11 +115,14 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt, // These are separate from the above cases for a better error message. mc::cat_stack_upvar(*) | mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, _ }) => { + let once_hint = if bccx.tcx.sess.once_fns() { + " (unless the destination closure type is `once fn')" + } else { + "" + }; bccx.span_err( cmt0.span, - fmt!("cannot move out of %s \ - (unless the destination closure type is `once fn')", - bccx.cmt_to_str(cmt))); + fmt!("cannot move out of %s%s", bccx.cmt_to_str(cmt), once_hint)); false } From 5d5311dc74b2bce19a754538dfd3c849e8c989ed Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 18 Jun 2013 10:17:10 +0200 Subject: [PATCH 015/336] Added overview of the debuginfo module at the beginning of debuginfo.rs. --- src/librustc/middle/trans/debuginfo.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 91e3276d8aa6..f231af974735 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -8,6 +8,32 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +/*! +# Debug Info Module + +This module serves the purpose of generating debug symbols. We use LLVM's +[source level debugging](http://llvm.org/docs/SourceLevelDebugging.html) features for generating +the debug information. The general principle is this: + +Given the right metadata in the LLVM IR, the LLVM code generator is able to create DWARF debug +symbols for the given code. The [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is +structured much like DWARF *debugging information entries* (DIE), representing type information +such as datatype layout, function signatures, block layout, variable location and scope information, +etc. It is the purpose of this module to generate correct metadata and insert it into the LLVM IR. + +As the exact format of metadata trees may change between different LLVM versions, we now use LLVM +[DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) which to create metadata +where possible. This will hopefully ease the adaption of this module to future LLVM versions. + +The public API of the module is a set of functions that will insert the correct metadata into the +LLVM IR when called with the right parameters. The module is thus driven from an outside client with +function like `debuginfo::create_local_var(bcx: block, local: @ast::local)`. + +Internally the module will try to reuse already created metadata by utilizing a cache. All private +state used by the module is stored within a DebugContext struct, which in turn is contained in the +CrateContext. +*/ + use core::prelude::*; use driver::session; From f1bd3e7ca2c5094c1e197c3276e5759ce0e73b91 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 18 Jun 2013 11:25:54 +0200 Subject: [PATCH 016/336] Fixed compiler warnings about unnecessary string allocations in debuginfo.rs --- src/librustc/middle/trans/debuginfo.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index f231af974735..cbac33ebe8b0 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -268,7 +268,7 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { ast::ty_f32 => (~"f32", DW_ATE_float), ast::ty_f64 => (~"f64", DW_ATE_float) }, - _ => cx.sess.bug(~"debuginfo::create_basic_type - t is invalid type") + _ => cx.sess.bug("debuginfo::create_basic_type - t is invalid type") }; let (size, align) = size_and_align_of(cx, t); @@ -598,7 +598,7 @@ fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { ty::ty_tup(ref elements) => { create_tuple(cx, t, *elements, span) }, - _ => cx.sess.bug(~"debuginfo: unexpected type in create_ty") + _ => cx.sess.bug("debuginfo: unexpected type in create_ty") }; dbg_cx(cx).created_types.insert(ty_id, ty_md); From 290d35312a8c74d4652d2e8196234151f9efcabf Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 18 Jun 2013 13:06:41 +0200 Subject: [PATCH 017/336] Reordered debuginfo.rs and commented public fns --- src/librustc/middle/trans/debuginfo.rs | 445 ++++++++++++++----------- 1 file changed, 245 insertions(+), 200 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index cbac33ebe8b0..a5dd89a1cbc0 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -32,6 +32,13 @@ function like `debuginfo::create_local_var(bcx: block, local: @ast::local)`. Internally the module will try to reuse already created metadata by utilizing a cache. All private state used by the module is stored within a DebugContext struct, which in turn is contained in the CrateContext. + + +This file consists of three conceptual sections: +1. The public interface of the module +2. Module-internal metadata creation functions +3. Minor utility functions + */ use core::prelude::*; @@ -82,8 +89,14 @@ static DW_ATE_signed_char: int = 0x06; static DW_ATE_unsigned: int = 0x07; static DW_ATE_unsigned_char: int = 0x08; -//////////////// + + +//=------------------------------------------------------------------------------------------------- +// Public Interface of debuginfo module +//=------------------------------------------------------------------------------------------------- + +/// A context object for maintaining all state needed by the debuginfo module. pub struct DebugContext { names: namegen, crate_file: ~str, @@ -116,16 +129,6 @@ impl DebugContext { } } -#[inline] -fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { - cx.dbg_cx.get_mut_ref() -} - -#[inline] -fn DIB(cx: &CrateContext) -> DIBuilderRef { - cx.dbg_cx.get_ref().builder -} - /// Create any deferred debug metadata nodes pub fn finalize(cx: @mut CrateContext) { debug!("finalize"); @@ -136,6 +139,207 @@ pub fn finalize(cx: @mut CrateContext) { }; } +/// Creates debug information for the given local variable. +/// +/// 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_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), + // FIXME this should be handled (#2533) + _ => { + bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); + return ptr::null(); + } + }; + let name: &str = cx.sess.str_of(ident); + debug!("create_local_var: %s", name); + + let loc = span_start(cx, local.span); + let ty = node_id_type(bcx, local.node.id); + let tymd = create_ty(cx, ty, local.node.ty.span); + let filemd = create_file(cx, loc.file.name); + let context = match bcx.parent { + None => create_function(bcx.fcx), + Some(_) => create_block(bcx) + }; + + let var_md = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable( + DIB(cx), AutoVariableTag as u32, + context, name, filemd, + loc.line as c_uint, tymd, false, 0, 0) + }}; + + // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc + let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { + Some(v) => v, + None => { + bcx.tcx().sess.span_bug( + local.span, + fmt!("No entry in lllocals table for %?", local.node.id)); + } + }; + + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); + unsafe { + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); + } + + return var_md; +} + +/// Creates debug information for the given function argument. +/// +/// 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 { + debug!("create_arg"); + if true { + // XXX create_arg disabled for now because "node_id_type(bcx, arg.id)" below blows + // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" + return None; + } + + let fcx = bcx.fcx; + let cx = fcx.ccx; + + let loc = span_start(cx, span); + if "" == loc.file.name { + return None; + } + + let ty = node_id_type(bcx, arg.id); + let tymd = create_ty(cx, ty, arg.ty.span); + let filemd = create_file(cx, loc.file.name); + let context = create_function(fcx); + + match arg.pat.node { + ast::pat_ident(_, path, _) => { + // XXX: This is wrong; it should work for multiple bindings. + let ident = path.idents.last(); + let name: &str = cx.sess.str_of(*ident); + let mdnode = do as_c_str(name) |name| { unsafe { + llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), + ArgVariableTag as u32, context, name, + filemd, loc.line as c_uint, tymd, false, 0, 0) + // XXX need to pass in a real argument number + }}; + + let llptr = fcx.llargs.get_copy(&arg.id); + set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); + unsafe { + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( + DIB(cx), llptr, mdnode, bcx.llbb); + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); + } + return Some(mdnode); + } + _ => { + return None; + } + } +} + +/// Sets the current debug location at the beginning of the span +/// +/// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...) +pub fn update_source_pos(bcx: block, span: span) { + if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { + return; + } + debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); + let loc = span_start(bcx.ccx(), span); + set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint()) +} + +/// Creates debug information for the given function. +/// +/// 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_function(fcx: fn_ctxt) -> DISubprogram { + let cx = fcx.ccx; + 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, _) => { + match item.node { + ast::item_fn(ref decl, _, _, _, _) => { + (item.ident, decl.output, 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_expr(expr) => { + match expr.node { + ast::expr_fn_block(ref decl, _) => { + ((dbg_cx(cx).names)("fn"), decl.output, expr.id) + } + _ => fcx.ccx.sess.span_bug(expr.span, + "create_function: expected an expr_fn_block here") + } + } + _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") + }; + + match dbg_cx(cx).created_functions.find(&id) { + Some(fn_md) => return *fn_md, + None => () + } + + debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); + + let loc = span_start(cx, span); + let file_md = create_file(cx, loc.file.name); + + let ret_ty_md = if cx.sess.opts.extra_debuginfo { + match ret_ty.node { + ast::ty_nil => ptr::null(), + _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), + ret_ty.span) + } + } else { + ptr::null() + }; + + let fn_ty = unsafe { + llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), + file_md, create_DIArray(DIB(cx), [ret_ty_md])) + }; + + let fn_md = + do as_c_str(cx.sess.str_of(ident)) |name| { + do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { + llvm::LLVMDIBuilderCreateFunction( + DIB(cx), + file_md, + name, linkage, + file_md, loc.line as c_uint, + fn_ty, false, true, + loc.line as c_uint, + FlagPrototyped as c_uint, + cx.sess.opts.optimize != session::No, + fcx.llfn, ptr::null(), ptr::null()) + }}}; + + dbg_cx(cx).created_functions.insert(id, fn_md); + return fn_md; +} + + + + +//=------------------------------------------------------------------------------------------------- +// Module-Internal debug info creation functions +//=------------------------------------------------------------------------------------------------- + fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { return unsafe { llvm::LLVMDIBuilderGetOrCreateArray(builder, vec::raw::to_ptr(arr), arr.len() as u32) @@ -186,10 +390,7 @@ fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile { return file_md; } -/// Return codemap::Loc corresponding to the beginning of the span -fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { - return cx.sess.codemap.lookup_char_pos(span.lo); -} + fn create_block(bcx: block) -> DILexicalBlock { let mut bcx = bcx; @@ -231,10 +432,7 @@ fn create_block(bcx: block) -> DILexicalBlock { return block_md; } -fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { - let llty = type_of::type_of(cx, t); - (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) -} + fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { let ty_id = ty::type_id(t); @@ -350,11 +548,6 @@ impl StructContext { } } -#[inline] -fn roundup(x: uint, a: uint) -> uint { - ((x + (a - 1)) / a) * a -} - fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { let loc = span_start(cx, span); @@ -605,103 +798,6 @@ fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { return ty_md; } -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), - // FIXME this should be handled (#2533) - _ => { - bcx.sess().span_note(local.span, "debuginfo for pattern bindings NYI"); - return ptr::null(); - } - }; - let name: &str = cx.sess.str_of(ident); - debug!("create_local_var: %s", name); - - let loc = span_start(cx, local.span); - let ty = node_id_type(bcx, local.node.id); - let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, loc.file.name); - let context = match bcx.parent { - None => create_function(bcx.fcx), - Some(_) => create_block(bcx) - }; - - let var_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable( - DIB(cx), AutoVariableTag as u32, - context, name, filemd, - loc.line as c_uint, tymd, false, 0, 0) - }}; - - // FIXME(#6814) Should use `pat_util::pat_bindings` for pats like (a, b) etc - let llptr = match bcx.fcx.lllocals.find_copy(&local.node.pat.id) { - Some(v) => v, - None => { - bcx.tcx().sess.span_bug( - local.span, - fmt!("No entry in lllocals table for %?", local.node.id)); - } - }; - - set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); - unsafe { - let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb); - llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); - } - - return var_md; -} - -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 - // up: "error: internal compiler error: node_id_to_type: no type for node `arg (id=10)`" - return None; - } - - let fcx = bcx.fcx; - let cx = fcx.ccx; - - let loc = span_start(cx, span); - if "" == loc.file.name { - return None; - } - - let ty = node_id_type(bcx, arg.id); - let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, loc.file.name); - let context = create_function(fcx); - - match arg.pat.node { - ast::pat_ident(_, path, _) => { - // XXX: This is wrong; it should work for multiple bindings. - let ident = path.idents.last(); - let name: &str = cx.sess.str_of(*ident); - let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), - ArgVariableTag as u32, context, name, - filemd, loc.line as c_uint, tymd, false, 0, 0) - // XXX need to pass in a real argument number - }}; - - let llptr = fcx.llargs.get_copy(&arg.id); - set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint()); - unsafe { - let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( - DIB(cx), llptr, mdnode, bcx.llbb); - llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr); - } - return Some(mdnode); - } - _ => { - return None; - } - } -} - fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: uint) { if dbg_cx(cx).curr_loc == (line, col) { return; @@ -718,85 +814,34 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui } } -/// Set current debug location at the beginning of the span -pub fn update_source_pos(bcx: block, span: span) { - if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { - return; - } - debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span)); - let loc = span_start(bcx.ccx(), span); - set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint()) + + + +//=------------------------------------------------------------------------------------------------- +// Utility Functions +//=------------------------------------------------------------------------------------------------- + +#[inline] +fn roundup(x: uint, a: uint) -> uint { + ((x + (a - 1)) / a) * a } -pub fn create_function(fcx: fn_ctxt) -> DISubprogram { - let cx = fcx.ccx; - 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, _) => { - match item.node { - ast::item_fn(ref decl, _, _, _, _) => { - (item.ident, decl.output, 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_expr(expr) => { - match expr.node { - ast::expr_fn_block(ref decl, _) => { - ((dbg_cx(cx).names)("fn"), decl.output, expr.id) - } - _ => fcx.ccx.sess.span_bug(expr.span, - "create_function: expected an expr_fn_block here") - } - } - _ => fcx.ccx.sess.bug("create_function: unexpected sort of node") - }; - - match dbg_cx(cx).created_functions.find(&id) { - Some(fn_md) => return *fn_md, - None => () - } - - debug!("create_function: %s, %s", cx.sess.str_of(ident), cx.sess.codemap.span_to_str(span)); - - let loc = span_start(cx, span); - let file_md = create_file(cx, loc.file.name); - - let ret_ty_md = if cx.sess.opts.extra_debuginfo { - match ret_ty.node { - ast::ty_nil => ptr::null(), - _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), - ret_ty.span) - } - } else { - ptr::null() - }; - - let fn_ty = unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), - file_md, create_DIArray(DIB(cx), [ret_ty_md])) - }; - - let fn_md = - do as_c_str(cx.sess.str_of(ident)) |name| { - do as_c_str(cx.sess.str_of(ident)) |linkage| { unsafe { - llvm::LLVMDIBuilderCreateFunction( - DIB(cx), - file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, - loc.line as c_uint, - FlagPrototyped as c_uint, - cx.sess.opts.optimize != session::No, - fcx.llfn, ptr::null(), ptr::null()) - }}}; - - dbg_cx(cx).created_functions.insert(id, fn_md); - return fn_md; +/// Return codemap::Loc corresponding to the beginning of the span +fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { + return cx.sess.codemap.lookup_char_pos(span.lo); } + +fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { + let llty = type_of::type_of(cx, t); + (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) +} + +#[inline] +fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { + cx.dbg_cx.get_mut_ref() +} + +#[inline] +fn DIB(cx: &CrateContext) -> DIBuilderRef { + cx.dbg_cx.get_ref().builder +} \ No newline at end of file From 38743f51ade64148be396438b1f6fe4639336ab3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 09:53:47 +0200 Subject: [PATCH 018/336] debuginfo.rs: Removed some static constants not used anymore. --- src/librustc/middle/trans/debuginfo.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a5dd89a1cbc0..52fee4be781e 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -22,12 +22,12 @@ such as datatype layout, function signatures, block layout, variable location an etc. It is the purpose of this module to generate correct metadata and insert it into the LLVM IR. As the exact format of metadata trees may change between different LLVM versions, we now use LLVM -[DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) which to create metadata +[DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to create metadata where possible. This will hopefully ease the adaption of this module to future LLVM versions. The public API of the module is a set of functions that will insert the correct metadata into the LLVM IR when called with the right parameters. The module is thus driven from an outside client with -function like `debuginfo::create_local_var(bcx: block, local: @ast::local)`. +functions like `debuginfo::create_local_var(bcx: block, local: @ast::local)`. Internally the module will try to reuse already created metadata by utilizing a cache. All private state used by the module is stored within a DebugContext struct, which in turn is contained in the @@ -67,20 +67,8 @@ use syntax::{ast, codemap, ast_util, ast_map}; static DW_LANG_RUST: int = 0x9000; -static CompileUnitTag: int = 17; -static FileDescriptorTag: int = 41; -static SubprogramTag: int = 46; -static SubroutineTag: int = 21; -static BasicTypeDescriptorTag: int = 36; static AutoVariableTag: int = 256; static ArgVariableTag: int = 257; -static ReturnVariableTag: int = 258; -static LexicalBlockTag: int = 11; -static PointerTypeTag: int = 15; -static StructureTypeTag: int = 19; -static MemberTag: int = 13; -static ArrayTypeTag: int = 1; -static SubrangeTag: int = 33; static DW_ATE_boolean: int = 0x02; static DW_ATE_float: int = 0x04; From 60474f395c1736773fdd1d86d053dc380b2dad8c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 09:55:03 +0200 Subject: [PATCH 019/336] debuginfo.rs: Explained why a function is called although one could think it should not be. --- src/librustc/middle/trans/debuginfo.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 52fee4be781e..69e631a348bf 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -464,6 +464,9 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { size * 8 as u64, align * 8 as u64, encoding as c_uint) }}; + // One could think that this call is not necessary, as the create_ty() function will insert the + // type descriptor into the cache anyway. Mind, however, that create_basic_type() is also called + // directly from other functions (e.g. create_boxed_type()). dbg_cx(cx).created_types.insert(ty_id, ty_md); return ty_md; } From 6eb3c0f30daa0db6fc219694a3028917bb1596af Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 11:50:02 +0200 Subject: [PATCH 020/336] debuginfo.rs: Removed trailing whitespace. --- src/librustc/middle/trans/debuginfo.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 69e631a348bf..06938c807c95 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -11,21 +11,21 @@ /*! # Debug Info Module -This module serves the purpose of generating debug symbols. We use LLVM's +This module serves the purpose of generating debug symbols. We use LLVM's [source level debugging](http://llvm.org/docs/SourceLevelDebugging.html) features for generating the debug information. The general principle is this: -Given the right metadata in the LLVM IR, the LLVM code generator is able to create DWARF debug -symbols for the given code. The [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is -structured much like DWARF *debugging information entries* (DIE), representing type information +Given the right metadata in the LLVM IR, the LLVM code generator is able to create DWARF debug +symbols for the given code. The [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is +structured much like DWARF *debugging information entries* (DIE), representing type information such as datatype layout, function signatures, block layout, variable location and scope information, etc. It is the purpose of this module to generate correct metadata and insert it into the LLVM IR. As the exact format of metadata trees may change between different LLVM versions, we now use LLVM [DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to create metadata -where possible. This will hopefully ease the adaption of this module to future LLVM versions. +where possible. This will hopefully ease the adaption of this module to future LLVM versions. -The public API of the module is a set of functions that will insert the correct metadata into the +The public API of the module is a set of functions that will insert the correct metadata into the LLVM IR when called with the right parameters. The module is thus driven from an outside client with functions like `debuginfo::create_local_var(bcx: block, local: @ast::local)`. @@ -129,7 +129,7 @@ pub fn finalize(cx: @mut CrateContext) { /// Creates debug information for the given local variable. /// -/// Adds the created metadata nodes directly to the crate's IR. +/// 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_local_var(bcx: block, local: @ast::local) -> DIVariable { let cx = bcx.ccx(); @@ -182,7 +182,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable { /// Creates debug information for the given function argument. /// -/// Adds the created metadata nodes directly to the crate's IR. +/// 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 { debug!("create_arg"); @@ -246,7 +246,7 @@ pub fn update_source_pos(bcx: block, span: span) { /// Creates debug information for the given function. /// -/// Adds the created metadata nodes directly to the crate's IR. +/// 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_function(fcx: fn_ctxt) -> DISubprogram { let cx = fcx.ccx; From 91362bd22021e15e4f220863e6e3070af6db911e Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 21 Jun 2013 01:07:05 +1000 Subject: [PATCH 021/336] extra: Add a testcase for #7256. --- src/libextra/time.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 50592d5f7309..973aa58921c6 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -1138,6 +1138,9 @@ mod tests { assert!(result::unwrap(strptime("-0800", "%z")).tm_gmtoff == 0); assert!(test("%", "%%")); + + // Test for #7256 + assert_eq!(strptime("360", "%Y-%m-%d"), Err(~"Invalid year")) } fn test_ctime() { From dc262d9aa742adadb92558a588aeaa57267fdee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 19 Jun 2013 20:28:42 +0200 Subject: [PATCH 022/336] Avoid unnecessary scratch datums for by-copy function arguments Currently, by-copy function arguments are always stored into a scratch datum, which serves two purposes. First, it is required to be able to have a temporary cleanup, in case that the call fails before the callee actually takes ownership of the value. Second, if the argument is to be passed by reference, the copy is required, so that the function doesn't get a reference to the original value. But in case that the datum does not need a drop glue call and it is passed by value, there's no need to perform the extra copy. --- src/librustc/middle/trans/callee.rs | 39 ++++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index bfbe078c4f52..47e5f9bf35f8 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -826,24 +826,33 @@ pub fn trans_arg_expr(bcx: block, val = arg_datum.to_ref_llval(bcx); } ty::ByCopy => { - 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); + if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || + arg_datum.appropriate_mode().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); - arg_datum.store_to_datum(bcx, - arg_expr.id, - INIT, - scratch); + arg_datum.store_to_datum(bcx, + arg_expr.id, + INIT, + scratch); - // Technically, ownership of val passes to the callee. - // However, we must cleanup should we fail before the - // callee is actually invoked. - scratch.add_clean(bcx); - temp_cleanups.push(scratch.val); + // Technically, ownership of val passes to the callee. + // However, we must cleanup should we fail before the + // callee is actually invoked. + scratch.add_clean(bcx); + temp_cleanups.push(scratch.val); - match arg_datum.appropriate_mode() { - ByValue => val = Load(bcx, scratch.val), - ByRef(_) => val = scratch.val, + match scratch.appropriate_mode() { + ByValue => val = Load(bcx, scratch.val), + ByRef(_) => val = scratch.val, + } + } else { + debug!("by copy arg with type %s"); + match arg_datum.mode { + ByRef(_) => val = Load(bcx, arg_datum.val), + ByValue => val = arg_datum.val, + } } } } From 1a8969f64be0a7e7a2cd61f04d6c4d94abe35c75 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Wed, 12 Jun 2013 14:22:17 -0700 Subject: [PATCH 023/336] Get cross crate default methods working. This fixes the large number of problems that prevented cross crate methods from ever working. It also fixes a couple lingering bugs with polymorphic default methods and cleans up some of the code paths. Closes #4102. Closes #4103. --- src/librustc/metadata/csearch.rs | 2 +- src/librustc/metadata/decoder.rs | 41 +---- src/librustc/middle/trans/callee.rs | 49 ++---- src/librustc/middle/trans/inline.rs | 15 +- src/librustc/middle/trans/meth.rs | 89 ++++------ src/librustc/middle/typeck/check/method.rs | 4 + src/librustc/middle/typeck/coherence.rs | 163 +++++++++--------- .../auxiliary/trait_default_method_xc_aux.rs | 34 ++++ .../trait-default-method-bound-subst.rs | 2 + src/test/run-pass/trait-default-method-xc.rs | 71 ++++++++ 10 files changed, 254 insertions(+), 216 deletions(-) create mode 100644 src/test/auxiliary/trait_default_method_xc_aux.rs create mode 100644 src/test/run-pass/trait-default-method-xc.rs diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 5b154f6836c2..e1cd7caa19c1 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -229,7 +229,7 @@ pub fn get_impl_trait(tcx: ty::ctxt, pub fn get_impl_method(cstore: @mut cstore::CStore, def: ast::def_id, mname: ast::ident) - -> ast::def_id { + -> Option { let cdata = cstore::get_crate_data(cstore, def.crate); decoder::get_impl_method(cstore.intr, cdata, def.node, mname) } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index fdef25b5e711..7f06953663b3 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -415,7 +415,7 @@ pub fn get_impl_trait(cdata: cmd, } pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, - name: ast::ident) -> ast::def_id { + name: ast::ident) -> Option { let items = reader::get_doc(reader::Doc(cdata.data), tag_items); let mut found = None; for reader::tagged_docs(find_item(id, items), tag_item_impl_method) @@ -425,7 +425,7 @@ pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, found = Some(translate_def_id(cdata, m_did)); } } - found.get() + found } pub fn get_symbol(data: @~[u8], id: ast::node_id) -> ~str { @@ -755,40 +755,13 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, let item = lookup_item(id, data); let mut result = ~[]; - for reader::tagged_docs(item, tag_item_trait_method) |mth| { + for reader::tagged_docs(item, tag_item_trait_method) |mth_id| { + let did = item_def_id(mth_id, cdata); + let mth = lookup_item(did.node, data); + if item_method_sort(mth) != 'p' { loop; } - let did = item_def_id(mth, cdata); - - let type_param_defs = - item_ty_param_defs(mth, tcx, cdata, - tag_items_data_item_ty_param_bounds); - let name = item_name(intr, mth); - let ty = doc_type(mth, tcx, cdata); - - let fty = match ty::get(ty).sty { - ty::ty_bare_fn(ref f) => copy *f, - _ => { - tcx.diag.handler().bug("get_provided_trait_methods(): id \ - has non-function type"); - } - }; - - let transformed_self_ty = doc_transformed_self_ty(mth, tcx, cdata); - let explicit_self = get_explicit_self(mth); - - let ty_method = ty::Method::new( - name, - ty::Generics { - type_param_defs: type_param_defs, - region_param: None - }, - transformed_self_ty, - fty, - explicit_self, - ast::public, - did - ); + let ty_method = get_method(intr, cdata, did.node, tcx); let provided_trait_method_info = ProvidedTraitMethodInfo { ty: ty_method, def_id: did diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index bfbe078c4f52..7fab21b4156c 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -42,6 +42,7 @@ use middle::trans::type_of; use middle::ty; use middle::subst::Subst; use middle::typeck; +use middle::typeck::coherence::make_substs_for_receiver_types; use util::ppaux::Repr; use core::vec; @@ -253,50 +254,24 @@ pub fn trans_fn_ref_with_vtables( // So, what we need to do is find this substitution and // compose it with the one we already have. - // In order to find the substitution for the trait params, - // we look up the impl in the ast map, find its trait_ref - // id, then look up its trait ref. I feel like there - // should be a better way. - let map_node = session::expect( - ccx.sess, - ccx.tcx.items.find_copy(&source.impl_id.node), - || fmt!("couldn't find node while monomorphizing \ - default method: %?", source.impl_id.node)); - let item = match map_node { - ast_map::node_item(item, _) => item, - _ => ccx.tcx.sess.bug("Not an item") - }; - let ast_trait_ref = match copy item.node { - ast::item_impl(_, Some(tr), _, _) => tr, - _ => ccx.tcx.sess.bug("Not an impl with trait_ref") - }; - let trait_ref = ccx.tcx.trait_refs.get(&ast_trait_ref.ref_id); + let trait_ref = ty::impl_trait_ref(tcx, source.impl_id) + .expect("could not find trait_ref for impl with \ + default methods"); + let method = ty::method(tcx, source.method_id); - // The substs from the trait_ref only substitues for the - // trait parameters. Our substitution also needs to be - // able to substitute for the actual method type - // params. To do this, we figure out how many method - // parameters there are and pad out the substitution with - // substitution for the variables. - let item_ty = ty::lookup_item_type(tcx, source.method_id); - let num_params = item_ty.generics.type_param_defs.len() - - trait_ref.substs.tps.len(); - let id_subst = do vec::from_fn(num_params) |i| { - ty::mk_param(tcx, i, ast::def_id {crate: 0, node: 0}) - }; - // Merge the two substitions together now. - let first_subst = ty::substs {tps: trait_ref.substs.tps + id_subst, - .. trait_ref.substs}; + // Compute the first substitution + let first_subst = make_substs_for_receiver_types( + tcx, source.impl_id, trait_ref, method); - // And compose them. + // And compose them let new_substs = first_subst.subst(tcx, &substs); debug!("trans_fn_with_vtables - default method: \ - substs = %s, id_subst = %s, trait_subst = %s, \ + substs = %s, trait_subst = %s, \ first_subst = %s, new_subst = %s", - substs.repr(tcx), - id_subst.repr(tcx), trait_ref.substs.repr(tcx), + substs.repr(tcx), trait_ref.substs.repr(tcx), first_subst.repr(tcx), new_substs.repr(tcx)); + (source.method_id, Some(source.impl_id), new_substs) } }; diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index b0aedbae79bf..00afece91979 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -93,11 +93,16 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, csearch::found(ast::ii_method(impl_did, mth)) => { ccx.stats.n_inlines += 1; ccx.external.insert(fn_id, Some(mth.id)); - let impl_tpt = ty::lookup_item_type(ccx.tcx, impl_did); - let num_type_params = - impl_tpt.generics.type_param_defs.len() + - mth.generics.ty_params.len(); - if translate && num_type_params == 0 { + // If this is a default method, we can't look up the + // impl type. But we aren't going to translate anyways, so don't. + if !translate { return local_def(mth.id); } + + let impl_tpt = ty::lookup_item_type(ccx.tcx, impl_did); + let num_type_params = + impl_tpt.generics.type_param_defs.len() + + mth.generics.ty_params.len(); + + if num_type_params == 0 { let llfn = get_item_val(ccx, mth.id); let path = vec::append( ty::item_path(ccx.tcx, impl_did), diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index c59b3f36779b..bd79cb1cfeba 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -383,71 +383,48 @@ pub fn method_with_name_or_default(ccx: @mut CrateContext, name: ast::ident) -> ast::def_id { let imp = ccx.impl_method_cache.find_copy(&(impl_id, name)); match imp { - Some(m) => m, - None => { - let imp = if impl_id.crate == ast::local_crate { - match ccx.tcx.items.get_copy(&impl_id.node) { - ast_map::node_item(@ast::item { - node: ast::item_impl(_, _, _, ref ms), _ - }, _) => { - let did = method_from_methods(*ms, name); - if did.is_some() { - did.get() - } else { - // Look for a default method - let pmm = ccx.tcx.provided_methods; - match pmm.find(&impl_id) { - Some(pmis) => { - for pmis.each |pmi| { - if pmi.method_info.ident == name { - debug!("pmi.method_info.did = %?", pmi.method_info.did); - return pmi.method_info.did; - } - } - fail!() - } - None => fail!() - } - } + Some(m) => return m, + None => {} + } + + // None of this feels like it should be the best way to do this. + let mut did = if impl_id.crate == ast::local_crate { + match ccx.tcx.items.get_copy(&impl_id.node) { + ast_map::node_item(@ast::item { + node: ast::item_impl(_, _, _, ref ms), _ + }, _) => { method_from_methods(*ms, name) }, + _ => fail!("method_with_name") + } + } else { + csearch::get_impl_method(ccx.sess.cstore, impl_id, name) + }; + + if did.is_none() { + // Look for a default method + let pmm = ccx.tcx.provided_methods; + match pmm.find(&impl_id) { + Some(pmis) => { + for pmis.each |pmi| { + if pmi.method_info.ident == name { + debug!("pmi.method_info.did = %?", + pmi.method_info.did); + did = Some(pmi.method_info.did); } - _ => fail!("method_with_name") } - } else { - csearch::get_impl_method(ccx.sess.cstore, impl_id, name) - }; - - ccx.impl_method_cache.insert((impl_id, name), imp); - - imp + } + None => {} } } + + let imp = did.expect("could not find method while translating"); + ccx.impl_method_cache.insert((impl_id, name), imp); + imp } pub fn method_ty_param_count(ccx: &CrateContext, m_id: ast::def_id, i_id: ast::def_id) -> uint { debug!("method_ty_param_count: m_id: %?, i_id: %?", m_id, i_id); - if m_id.crate == ast::local_crate { - match ccx.tcx.items.find(&m_id.node) { - Some(&ast_map::node_method(m, _, _)) => m.generics.ty_params.len(), - None => { - match ccx.tcx.provided_method_sources.find(&m_id) { - Some(source) => { - method_ty_param_count( - ccx, source.method_id, source.impl_id) - } - None => fail!() - } - } - Some(&ast_map::node_trait_method(@ast::provided(@ref m), - _, _)) => { - m.generics.ty_params.len() - } - ref e => fail!("method_ty_param_count %?", *e) - } - } else { - csearch::get_type_param_count(ccx.sess.cstore, m_id) - - csearch::get_type_param_count(ccx.sess.cstore, i_id) - } + ty::method(ccx.tcx, m_id).generics.type_param_defs.len() } pub fn trans_monomorphized_callee(bcx: block, diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index b2c9d27241d4..7fc1728a720b 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -541,6 +541,10 @@ impl<'self> LookupContext<'self> { if !self.impl_dups.insert(impl_info.did) { return; // already visited } + debug!("push_candidates_from_impl: %s %s %s", + self.m_name.repr(self.tcx()), + impl_info.ident.repr(self.tcx()), + impl_info.methods.map(|m| m.ident).repr(self.tcx())); let idx = { match impl_info.methods.position(|m| m.ident == self.m_name) { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 9528c825fbed..d404ac39a151 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -279,7 +279,7 @@ impl CoherenceChecker { trait_ref.repr(self.crate_context.tcx), self.crate_context.tcx.sess.str_of(item.ident)); - self.instantiate_default_methods(item.id, trait_ref); + self.instantiate_default_methods(local_def(item.id), trait_ref); let implementation; if implementation_opt.is_none() { @@ -327,13 +327,13 @@ impl CoherenceChecker { // and trait pair. Then, for each provided method in the trait, inserts a // `ProvidedMethodInfo` instance into the `provided_method_sources` map. pub fn instantiate_default_methods(&self, - impl_id: ast::node_id, + impl_id: ast::def_id, trait_ref: &ty::TraitRef) { let tcx = self.crate_context.tcx; debug!("instantiate_default_methods(impl_id=%?, trait_ref=%s)", impl_id, trait_ref.repr(tcx)); - let impl_poly_type = ty::lookup_item_type(tcx, local_def(impl_id)); + let impl_poly_type = ty::lookup_item_type(tcx, impl_id); for self.each_provided_trait_method(trait_ref.def_id) |trait_method| { // Synthesize an ID. @@ -375,7 +375,7 @@ impl CoherenceChecker { // ID of the method. let source = ProvidedMethodSource { method_id: trait_method.def_id, - impl_id: local_def(impl_id) + impl_id: impl_id }; self.crate_context.tcx.provided_method_sources.insert(new_did, @@ -393,7 +393,7 @@ impl CoherenceChecker { }; let pmm = self.crate_context.tcx.provided_methods; - match pmm.find(&local_def(impl_id)) { + match pmm.find(&impl_id) { Some(&mis) => { // If the trait already has an entry in the // provided_methods_map, we just need to add this @@ -410,7 +410,7 @@ impl CoherenceChecker { for method `%s`", self.crate_context.tcx.sess.str_of( provided_method_info.method_info.ident)); - pmm.insert(local_def(impl_id), + pmm.insert(impl_id, @mut ~[provided_method_info]); } } @@ -733,10 +733,12 @@ impl CoherenceChecker { } // Default methods for ty::provided_trait_methods(tcx, trait_did).each |ident| { + debug!("inserting provided method %s", ident.repr(tcx)); provided_names.insert(*ident); } for (*ty::trait_methods(tcx, trait_did)).each |method| { + debug!("checking for %s", method.ident.repr(tcx)); if provided_names.contains(&method.ident) { loop; } tcx.sess.span_err(trait_ref_span, @@ -785,19 +787,41 @@ impl CoherenceChecker { } } + fn add_provided_methods_to_impl( + &self, + all_methods: &mut ~[@MethodInfo], + trait_did: &ast::def_id, + impl_id: &ast::def_id) { + + + match self.crate_context.tcx + .provided_methods + .find(impl_id) { + None => { + debug!("(creating impl) trait with node_id `%d` \ + has no provided methods", trait_did.node); + /* fall through */ + } + Some(&all_provided_methods) => { + debug!("(creating impl) trait with node_id `%d` \ + has provided methods", trait_did.node); + // Add all provided methods. + for all_provided_methods.each |provided_method| { + debug!( + "(creating impl) adding provided method \ + `%s` to impl", + provided_method.method_info + .ident.repr(self.crate_context.tcx)); + vec::push(all_methods, provided_method.method_info); + } + } + } + + + } + // Converts an implementation in the AST to an Impl structure. pub fn create_impl_from_item(&self, item: @item) -> @Impl { - fn add_provided_methods(all_methods: &mut ~[@MethodInfo], - all_provided_methods: &mut ~[@ProvidedMethodInfo], - sess: driver::session::Session) { - for all_provided_methods.each |provided_method| { - debug!( - "(creating impl) adding provided method `%s` to impl", - sess.str_of(provided_method.method_info.ident)); - vec::push(all_methods, provided_method.method_info); - } - } - match item.node { item_impl(_, ref trait_refs, _, ref ast_methods) => { let mut methods = ~[]; @@ -820,27 +844,11 @@ 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); - - match self.crate_context.tcx - .provided_methods - .find(&local_def(item.id)) { - None => { - debug!("(creating impl) trait with node_id `%d` \ - has no provided methods", trait_did.node); - /* fall through */ - } - Some(&all_provided) => { - debug!("(creating impl) trait with node_id `%d` \ - has provided methods", trait_did.node); - // Add all provided methods. - add_provided_methods( - &mut methods, - all_provided, - self.crate_context.tcx.sess); - } - } + let trait_did = self.trait_ref_to_trait_def_id(*trait_ref); + self.add_provided_methods_to_impl( + &mut methods, + &trait_did, + &local_def(item.id)); } return @Impl { @@ -917,9 +925,23 @@ impl CoherenceChecker { } } + let mut implementation = *implementation; + // Record all the trait methods. for associated_traits.iter().advance |trait_ref| { - self.add_trait_method(trait_ref.def_id, *implementation); + self.instantiate_default_methods(implementation.did, + &**trait_ref); + // Could we avoid these copies when we don't need them? + let mut methods = /*bad?*/ copy implementation.methods; + self.add_provided_methods_to_impl( + &mut methods, + &trait_ref.def_id, + &implementation.did); + implementation = @Impl { methods: methods, + .. *implementation }; + + + self.add_trait_method(trait_ref.def_id, implementation); } // Add the implementation to the mapping from @@ -937,7 +959,7 @@ impl CoherenceChecker { // `impl Trait for Type`: if associated_traits.is_none() { self.add_inherent_method(base_type_def_id, - *implementation); + implementation); } self.base_type_def_ids.insert(implementation.did, @@ -947,38 +969,6 @@ impl CoherenceChecker { } } - pub fn add_default_methods_for_external_trait(&self, - trait_def_id: ast::def_id) { - let tcx = self.crate_context.tcx; - let pmm = tcx.provided_methods; - - if pmm.contains_key(&trait_def_id) { return; } - - debug!("(adding default methods for trait) processing trait"); - - for csearch::get_provided_trait_methods(tcx, trait_def_id).each - |trait_method_info| { - debug!("(adding default methods for trait) found default method"); - - // Create a new def ID for this provided method. - let parse_sess = &self.crate_context.tcx.sess.parse_sess; - let new_did = local_def(parse::next_node_id(*parse_sess)); - - let provided_method_info = - @ProvidedMethodInfo { - method_info: @MethodInfo { - did: new_did, - n_tps: trait_method_info.ty.generics.type_param_defs.len(), - ident: trait_method_info.ty.ident, - explicit_self: trait_method_info.ty.explicit_self - }, - trait_method_def_id: trait_method_info.def_id - }; - - pmm.insert(trait_def_id, @mut ~[provided_method_info]); - } - } - // Adds implementations and traits from external crates to the coherence // info. pub fn add_external_crates(&self) { @@ -998,9 +988,6 @@ impl CoherenceChecker { crate_store, def_id); } - dl_def(def_trait(def_id)) => { - self.add_default_methods_for_external_trait(def_id); - } dl_def(_) | dl_impl(_) | dl_field => { // Skip this. loop; @@ -1063,12 +1050,11 @@ impl CoherenceChecker { } } -fn subst_receiver_types_in_method_ty(tcx: ty::ctxt, - impl_id: ast::node_id, - trait_ref: &ty::TraitRef, - new_def_id: ast::def_id, - method: &ty::Method) - -> ty::Method { +pub fn make_substs_for_receiver_types(tcx: ty::ctxt, + impl_id: ast::def_id, + trait_ref: &ty::TraitRef, + method: &ty::Method) + -> ty::substs { /*! * Substitutes the values for the receiver's type parameters * that are found in method, leaving the method's type parameters @@ -1079,7 +1065,7 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt, // determine how many type parameters were declared on the impl let num_impl_type_parameters = { - let impl_polytype = ty::lookup_item_type(tcx, local_def(impl_id)); + let impl_polytype = ty::lookup_item_type(tcx, impl_id); impl_polytype.generics.type_param_defs.len() }; @@ -1105,11 +1091,22 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt, } }); - let combined_substs = ty::substs { + return ty::substs { self_r: trait_ref.substs.self_r, self_ty: trait_ref.substs.self_ty, tps: combined_tps }; +} + +fn subst_receiver_types_in_method_ty(tcx: ty::ctxt, + impl_id: ast::def_id, + trait_ref: &ty::TraitRef, + new_def_id: ast::def_id, + method: &ty::Method) + -> ty::Method { + + let combined_substs = make_substs_for_receiver_types( + tcx, impl_id, trait_ref, method); ty::Method::new( method.ident, diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs new file mode 100644 index 000000000000..5ee243179df8 --- /dev/null +++ b/src/test/auxiliary/trait_default_method_xc_aux.rs @@ -0,0 +1,34 @@ +#[allow(default_methods)]; + +pub trait A { + fn f(&self) -> int; + fn g(&self) -> int { 10 } + fn h(&self) -> int { 10 } +} + + +impl A for int { + fn f(&self) -> int { 10 } +} + +trait B { + fn thing(&self, x: T, y: U) -> (T, U) { (x, y) } +} + +impl B for int { } +impl B for bool { } + + + +pub trait TestEquality { + fn test_eq(&self, rhs: &Self) -> bool; + fn test_neq(&self, rhs: &Self) -> bool { + !self.test_eq(rhs) + } +} + +impl TestEquality for int { + fn test_eq(&self, rhs: &int) -> bool { + *self == *rhs + } +} diff --git a/src/test/run-pass/trait-default-method-bound-subst.rs b/src/test/run-pass/trait-default-method-bound-subst.rs index adabafc082a0..9dbbcee0f770 100644 --- a/src/test/run-pass/trait-default-method-bound-subst.rs +++ b/src/test/run-pass/trait-default-method-bound-subst.rs @@ -15,6 +15,7 @@ trait A { } impl A for int { } +impl A for uint { } fn f>(i: V, j: T, k: U) -> (T, U) { i.g(j, k) @@ -22,4 +23,5 @@ fn f>(i: V, j: T, k: U) -> (T, U) { pub fn main () { assert_eq!(f(0, 1, 2), (1, 2)); + assert_eq!(f(0u, 1, 2), (1, 2)); } diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs new file mode 100644 index 000000000000..e6e5b8605a16 --- /dev/null +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -0,0 +1,71 @@ +// xfail-fast +// aux-build:trait_default_method_xc_aux.rs + +#[allow(default_methods)]; + +extern mod aux(name = "trait_default_method_xc_aux"); +use aux::{A, B, TestEquality}; + + +fn f(i: T) { + assert_eq!(i.g(), 10); +} + + +pub struct thing { x: int } +impl A for thing { + fn f(&self) -> int { 10 } +} + +fn g>(i: V, j: T, k: U) -> (T, U) { + i.thing(j, k) +} + +fn eq(lhs: &T, rhs: &T) -> bool { + lhs.test_eq(rhs) +} +fn neq(lhs: &T, rhs: &T) -> bool { + lhs.test_neq(rhs) +} + + +impl TestEquality for thing { + fn test_eq(&self, rhs: &thing) -> bool { + //self.x.test_eq(&rhs.x) + eq(&self.x, &rhs.x) + } +} + + +fn main () { + // Some tests of random things + f(0); + + let a = thing { x: 0 }; + let b = thing { x: 1 }; + + assert_eq!(0i.g(), 10); + assert_eq!(a.g(), 10); + assert_eq!(a.h(), 10); + + + 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)); + + let obj = @0i as @A; + assert_eq!(obj.h(), 10); + + + // Trying out a real one + assert!(12.test_neq(&10)); + assert!(!10.test_neq(&10)); + assert!(a.test_neq(&b)); + assert!(!a.test_neq(&a)); + + assert!(neq(&12, &10)); + assert!(!neq(&10, &10)); + assert!(neq(&a, &b)); + assert!(!neq(&a, &a)); +} From b8b2d1e5b41fd3351049fbb54846b42aa9b189bd Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 18 Jun 2013 11:54:00 -0700 Subject: [PATCH 024/336] Make task_rng() return @mut R instead of @@mut R --- src/libstd/rand.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 739e3dfedc7f..27ec5323841a 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -843,7 +843,7 @@ fn tls_rng_state(_v: @@mut IsaacRng) {} * `task_rng().gen::()`. */ #[inline] -pub fn task_rng() -> @@mut IsaacRng { +pub fn task_rng() -> @mut IsaacRng { let r : Option<@@mut IsaacRng>; unsafe { r = local_data::local_data_get(tls_rng_state); @@ -853,20 +853,18 @@ pub fn task_rng() -> @@mut IsaacRng { unsafe { let rng = @@mut IsaacRng::new_seeded(seed()); local_data::local_data_set(tls_rng_state, rng); - rng + *rng } } - Some(rng) => rng + Some(rng) => *rng } } // Allow direct chaining with `task_rng` -impl Rng for @@mut R { +impl Rng for @mut R { #[inline] fn next(&mut self) -> u32 { - match *self { - @@ref mut r => r.next() - } + (**self).next() } } @@ -876,9 +874,7 @@ impl Rng for @@mut R { */ #[inline] pub fn random() -> T { - match *task_rng() { - @ref mut r => r.gen() - } + task_rng().gen() } #[cfg(test)] From 31b4b53797337a3750bcb63b19b78642816f76de Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 20 Jun 2013 19:14:57 -0400 Subject: [PATCH 025/336] librustc: Don't allow enum struct variants to shadow structs. --- src/librustc/middle/resolve.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 3e656b3e5940..a91ee34f2985 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1415,24 +1415,26 @@ impl Resolver { (ReducedGraphParent, vt)) { let ident = variant.node.name; - let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues, - variant.span); - let privacy; - match variant.node.vis { - public => privacy = Public, - private => privacy = Private, - inherited => privacy = parent_privacy - } + let privacy = + match variant.node.vis { + public => Public, + private => Private, + inherited => parent_privacy + }; match variant.node.kind { tuple_variant_kind(_) => { + let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues, + variant.span); child.define_value(privacy, def_variant(item_id, local_def(variant.node.id)), variant.span); } struct_variant_kind(_) => { + let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues, + variant.span); child.define_type(privacy, def_variant(item_id, local_def(variant.node.id)), From 41e90f2156236d8b4a0ab74e3ed9aadaa7d11d58 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 20 Jun 2013 19:23:31 -0400 Subject: [PATCH 026/336] Add test for duplicate definitions of structs and enum struct variants. --- .../dup-struct-enum-struct-variant.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/compile-fail/dup-struct-enum-struct-variant.rs diff --git a/src/test/compile-fail/dup-struct-enum-struct-variant.rs b/src/test/compile-fail/dup-struct-enum-struct-variant.rs new file mode 100644 index 000000000000..69e6b5c6856a --- /dev/null +++ b/src/test/compile-fail/dup-struct-enum-struct-variant.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. + +enum Foo { C { a: int, b: int } } +struct C { a: int, b: int } //~ ERROR error: duplicate definition of type `C` + +struct A { x: int } +enum Bar { A { x: int } } //~ ERROR error: duplicate definition of type `A` + +fn main() {} From 7d61b0083af0b35f46902de86e629a89068397d4 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 17 Jun 2013 23:50:51 -0700 Subject: [PATCH 027/336] More 0.7 release notes --- RELEASES.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/RELEASES.txt b/RELEASES.txt index d099b1336dfd..54d527fcf20d 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -13,6 +13,7 @@ Version 0.7 (July 2013) * At long last, 'argument modes' no longer exist. * The `bytes!` macro returns a vector of bytes for string, u8, char, and unsuffixed integer literals. + * `#[static_assert]` makes compile-time assertions about static bools. * Semantic changes * The borrow checker has been rewritten with flow-sensitivity, fixing @@ -34,7 +35,7 @@ Version 0.7 (July 2013) * The `#[mutable]` attribute makes a type that would otherwise be `Const`, note. TODO this may change to non_freeze before 0.7 * Unbounded recursion will abort the process after reaching the limit - specified by the `RUST_MAX_STACK` environment variable. + specified by the `RUST_MAX_STACK` environment variable (default: 1GB). * The `vecs_implicitly_copyable` lint mode has been removed. Vectors are never implicitly copyable. @@ -46,11 +47,13 @@ Version 0.7 (July 2013) * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. * std: `iterator` module for external iterator objects. + * std: Many old internal vector and string iterators, + incl. `any`, `all`. removed. * std: new numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`. * std: Tuple traits and accessors defined for up to 12-tuples, e.g. `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. - * std: many types implement `Clone` - tuples, @, @mut. TODO + * std: many types implement `Clone`. * std: `path` type renamed to `Path`. * std: Many standalone functions removed in favor of methods in `vec`, `str`. In the future methods will also work as functions. @@ -60,16 +63,20 @@ Version 0.7 (July 2013) * std: `run` module for spawning processes overhauled. * std: Various atomic types added to `unstable::atomic`. * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`. + * std: Borrowed pointer functions moved from `ptr` to `borrow`. * std: Added `os::mkdir_recursive`. * std: Added `os::glob` function performs filesystems globs. * std: `FuzzyEq` renamed to `ApproxEq`. * std: `Map` now defines `pop` and `swap` methods. + * std: `Cell` constructors converted to static methods. + * extra: `rc` module adds the reference counted pointers, `Rc` and `RcMut`. * extra: `flate` module moved from `std` to `extra`. * extra: `FileInput` implements `std::io::Reader`. * extra: `Complex` number type and `complex` module. * extra: `Rational` number type and `rational` module. * extra: `BigInt`, `BigUint` implement numeric and comparison traits. * extra: `term` uses terminfo now, is more correct. + * extra: `arc` functions converted to methods. * Tooling * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks. From 525933d0a3444ca05f29f8777bf2bd1c5a2d92e3 Mon Sep 17 00:00:00 2001 From: Ralph Bodenner Date: Tue, 18 Jun 2013 23:50:06 -0700 Subject: [PATCH 028/336] Show defaults in rustdoc usage message --- src/librustdoc/config.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ef65cc8e5a1b..942d22fa3fc2 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -59,15 +59,15 @@ fn opt_help() -> ~str { ~"h" } fn opts() -> ~[(getopts::Opt, ~str)] { ~[ (getopts::optopt(opt_output_dir()), - ~"--output-dir put documents here"), + ~"--output-dir Put documents here (default: .)"), (getopts::optopt(opt_output_format()), - ~"--output-format either 'markdown' or 'html'"), + ~"--output-format 'markdown' or 'html' (default)"), (getopts::optopt(opt_output_style()), - ~"--output-style either 'doc-per-crate' or 'doc-per-mod'"), + ~"--output-style 'doc-per-crate' or 'doc-per-mod' (default)"), (getopts::optopt(opt_pandoc_cmd()), - ~"--pandoc-cmd the command for running pandoc"), + ~"--pandoc-cmd Command for running pandoc"), (getopts::optflag(opt_help()), - ~"-h print help") + ~"-h, --help Print help") ] } From 87c110506dcdb4cd5b4a10e2114832cc130a59c9 Mon Sep 17 00:00:00 2001 From: Joris Rehm Date: Wed, 19 Jun 2013 21:58:08 +0200 Subject: [PATCH 029/336] fix text of tutorials --- doc/tutorial-borrowed-ptr.md | 6 +++--- doc/tutorial-tasks.md | 2 +- doc/tutorial.md | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 90b8e1051eba..1da1d046878a 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -234,7 +234,7 @@ would therefore be subject to garbage collection. A heap box that is unrooted is one such that no pointer values in the heap point to it. It would violate memory safety for the box that was originally assigned to `x` to be garbage-collected, since a non-heap -pointer---`y`---still points into it. +pointer *`y`* still points into it. > ***Note:*** Our current implementation implements the garbage collector > using reference counting and cycle detection. @@ -475,7 +475,7 @@ but otherwise it requires that the data reside in immutable memory. # Returning borrowed pointers -So far, all of the examples we've looked at use borrowed pointers in a +So far, all of the examples we have looked at, use borrowed pointers in a “downward” direction. That is, a method or code block creates a borrowed pointer, then uses it within the same scope. It is also possible to return borrowed pointers as the result of a function, but @@ -509,7 +509,7 @@ guaranteed to refer to a distinct lifetime from the lifetimes of all other parameters. Named lifetimes that appear in function signatures are conceptually -the same as the other lifetimes we've seen before, but they are a bit +the same as the other lifetimes we have seen before, but they are a bit abstract: they don’t refer to a specific expression within `get_x()`, but rather to some expression within the *caller of `get_x()`*. The lifetime `r` is actually a kind of *lifetime parameter*: it is defined diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index 2e3ce40c9f7d..28ade2826b89 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -481,7 +481,7 @@ an `Error` result. TODO: Need discussion of `future_result` in order to make failure modes useful. -But not all failure is created equal. In some cases you might need to +But not all failures are created equal. In some cases you might need to abort the entire program (perhaps you're writing an assert which, if it trips, indicates an unrecoverable logic error); in other cases you might want to contain the failure at a certain boundary (perhaps a diff --git a/doc/tutorial.md b/doc/tutorial.md index f69f569faee4..92d88be6c949 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1084,8 +1084,8 @@ let managed_box : @Point = @Point { x: 5.0, y: 1.0 }; let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 }; ~~~ -Suppose we wanted to write a procedure that computed the distance -between any two points, no matter where they were stored. For example, +Suppose we want to write a procedure that computes the distance +between any two points, no matter where they are stored. For example, we might like to compute the distance between `on_the_stack` and `managed_box`, or between `managed_box` and `owned_box`. One option is to define a function that takes two arguments of type point—that is, @@ -1230,7 +1230,7 @@ let area = rect.area(); ~~~ You can write an expression that dereferences any number of pointers -automatically. For example, if you felt inclined, you could write +automatically. For example, if you feel inclined, you could write something silly like ~~~ @@ -1808,7 +1808,7 @@ s.draw_borrowed(); ~~~ Implementations may also define standalone (sometimes called "static") -methods. The absence of a `self` paramater distinguishes such methods. +methods. The absence of a `self` parameter distinguishes such methods. These methods are the preferred way to define constructor functions. ~~~~ {.xfail-test} @@ -2522,7 +2522,7 @@ will not be compiled successfully. ## A minimal example -Now for something that you can actually compile yourself. We have +Now for something that you can actually compile yourself, we have these two files: ~~~~ From 9e95bc4b196810f07b942927f85da4686929787f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 20 Jun 2013 00:56:21 -0700 Subject: [PATCH 030/336] Update AUTHORS.txt --- AUTHORS.txt | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 2f80341e21a0..e742886961f4 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -10,9 +10,11 @@ Aleksander Balicki Alex Crichton Alex Rønne Petersen Alexander Stavonin +Alexei Sholik Andreas Gal Andrew Dunham Andrew Paseltiner +Anthony Juckel Arkaitz Jimenez Armin Ronacher Ashok Gautham @@ -29,23 +31,32 @@ Benjamin Kircher Benjamin Peterson Bilal Husain Bill Fallon +Bill Myers +Bill Wendling +Björn Steinbrink Brendan Eich Brendan Zabarauskas Brett Cannon Brian Anderson Brian J. Burg Brian Leibig +Bryan Dunsmore +Caitlin Potter Chris Double Chris Peterson Chris Pressey Cody Schroeder +Corey Richardson Damian Gryski Damien Grassart Damien Schoof Daniel Brooks +Daniel Farina +Dan Luu Daniel Luz Daniel Micay Daniel Patterson +Daniel Ralston Daniel Ursache Dogariu Dave Herman David Forsythe @@ -62,17 +73,21 @@ Eric Holmes Erick Tryzelaar Erik Rose Evan McClanahan +Fedor Indutny Felix S. Klock II Francisco Souza Franklin Chen +Gábor Horváth Gabriel Gareth Daniel Smith +gifnksm Glenn Willen Gonçalo Cabrita <_@gmcabrita.com> Graham Fawcett Grahame Bowland Haitao Li hansjorg +Herman J. Radtke III Huon Wilson Ian D. Bollinger Ilyong Cho @@ -83,6 +98,7 @@ Jacob Harris Cryer Kragh Jacob Parker Jakub Wieczorek James Miller +James Tranovich Jason Orendorff Jed Davis Jeff Balogh @@ -92,6 +108,7 @@ Jeffrey Yasskin Jeong YunWon Jens Nockert Jesse Jones +Jesse Luehrs Jesse Ruderman Jihyun Yu Jim Blandy @@ -104,14 +121,18 @@ Jonathan Sternberg Josh Matthews Joshua Clark Joshua Wise +Junyoung Cho Jyun-Yan You Kang Seonghoon Kelly Wilson Kevin Atkinson +Kevin Ballard Kevin Cantu +klutzy Kyeongwoon Lee Laurent Bonnans Lawrence Velázquez +Leah Hanson Lennart Kudling Lindsey Kuper Luca Bruno @@ -122,6 +143,7 @@ Margaret Meyerhofer Marijn Haverbeke Mark Lacey <641@rudkx.com> Mark Vian +Marti Raudsepp Martin DeMello Marvin Löbel Matt Brubeck @@ -143,43 +165,64 @@ Patrick Walton Patrik Kårlin Paul Stansifer Paul Woolcock +Pavel Panchekha Peter Hull Peter Williams Philipp Brüschweiler Rafael Ávila de Espíndola +Ralph Bodenner Ralph Giles +Ramkumar Ramachandra Reuben Morais Rick Waldron Rob Arnold +Rob Hoelz Roland Tanglao +Ron Dahlgren Roy Frostig Ryan Scheel +Samuel Chase +Sander Mathijs van Veen +Sangeun Kim +Saurabh Anand +Sean Moon Sean Stangl Sebastian N. Fernandez Seth Pink Seo Sanghyeon sevrak +SiegeLord Simon Barber-Dueck Simon Sapin startling Stefan Plantikow Steve Klabnik +Steven De Coeyer +Steven Fackler +Steven Stewart-Gallus Taras Shpot Ted Horst Thad Guidry +Thomas Daede Tim Chevalier Tim Taubert Tom Lee +Tommy M. McGuire Tomoki Aonuma Tony Young Trinick Tycho Sci Tyler Bindon +Uwe Dauernheim +Vadim Chugunov Viktor Dahl Vincent Belliard +Vivek Galatage Wade Mealing William Ting Yasuhiro Fujii Young-il Choi +Youngmin Yoo Youngsoo Son Zack Corr +zofrex From 769c2e5f99c6f8d1dd5a20ecd176c4857f6f0ce4 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 20 Jun 2013 18:11:13 +1000 Subject: [PATCH 031/336] Minor doc updates to reflect #[deriving(Zero)], and small release notes adjustments. The `extra::fileinput` module landed just after 0.6 was released, and there are many more derivable traits. --- RELEASES.txt | 11 ++++++----- doc/rust.md | 1 + doc/tutorial.md | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/RELEASES.txt b/RELEASES.txt index 54d527fcf20d..9777245e40c9 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -7,8 +7,9 @@ Version 0.7 (July 2013) * `use mod` is no longer valid. * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style argument list. - * `Encodable`, `Decodable`, `TotalOrd`, `TotalEq`, `DeepClone` can all - be automatically derived with `#[deriving(...)]`. + * `Encodable`, `Decodable`, `Ord`, `TotalOrd`, `TotalEq`, `DeepClone`, + `Rand`, `Zero` and `ToStr` can all be automatically derived with + `#[deriving(...)]`. * The `Durable` trait is replaced with the `'static` bounds. * At long last, 'argument modes' no longer exist. * The `bytes!` macro returns a vector of bytes for string, u8, char, @@ -55,8 +56,8 @@ Version 0.7 (July 2013) `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. * std: many types implement `Clone`. * std: `path` type renamed to `Path`. - * std: Many standalone functions removed in favor of methods in - `vec`, `str`. In the future methods will also work as functions. + * std: Many standalone functions removed in favor of methods and iterators + in `vec`, `str`. In the future methods will also work as functions. * std: `reinterpret_cast` removed. Used `transmute`. * std: ascii string handling in `std::ascii`. * std: `Rand` is implemented for ~/@. @@ -71,7 +72,7 @@ Version 0.7 (July 2013) * std: `Cell` constructors converted to static methods. * extra: `rc` module adds the reference counted pointers, `Rc` and `RcMut`. * extra: `flate` module moved from `std` to `extra`. - * extra: `FileInput` implements `std::io::Reader`. + * extra: `fileinput` module for iterating over a series of files. * extra: `Complex` number type and `complex` module. * extra: `Rational` number type and `rational` module. * extra: `BigInt`, `BigUint` implement numeric and comparison traits. diff --git a/doc/rust.md b/doc/rust.md index 9edbc44d6c21..f533bb50f751 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1561,6 +1561,7 @@ Supported traits for `deriving` are: * `Clone` and `DeepClone`, to perform (deep) copies. * `IterBytes`, to iterate over the bytes in a data type. * `Rand`, to create a random instance of a data type. +* `Zero`, to create an zero (or empty) instance of a data type. * `ToStr`, to convert to a string. For a type with this instance, `obj.to_str()` has the same output as `fmt!("%?", obj)`. diff --git a/doc/tutorial.md b/doc/tutorial.md index 92d88be6c949..ee01f2a5bdf9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2319,7 +2319,7 @@ enum ABC { A, B, C } The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`, -`IterBytes`, `Rand` and `ToStr`. +`IterBytes`, `Rand`, `Zero`, and `ToStr`. # Modules and crates From fd24cb7eae24959d4f1765def01a187ccb6bbf38 Mon Sep 17 00:00:00 2001 From: Ralph Bodenner Date: Tue, 18 Jun 2013 22:34:35 -0700 Subject: [PATCH 032/336] Usable instructions for generating docs from source --- doc/README | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/doc/README b/doc/README index c3bb28a9e85e..bb6ab77a8021 100644 --- a/doc/README +++ b/doc/README @@ -1,10 +1,25 @@ -The markdown docs are only generated by make when node is installed (use -`make doc`). If you don't have node installed you can generate them yourself. -Unfortunately there's no real standard for markdown and all the tools work -differently. pandoc is one that seems to work well. +Pandoc, a universal document converter, is required to generate docs as HTML +from Rust's source code. It's available for most platforms here: +http://johnmacfarlane.net/pandoc/installing.html -To generate an html version of a doc do something like: -pandoc --from=markdown --to=html --number-sections -o build/doc/rust.html doc/rust.md && git web--browse build/doc/rust.html +Node.js (http://nodejs.org/) is also required for generating HTML from +the Markdown docs (reference manual, tutorials, etc.) distributed with +this git repository. + +To generate all the docs, run `make docs` from the root of the repository. +This will convert the distributed Markdown docs to HTML and generate HTML doc +for the 'std' and 'extra' libraries. + +To generate HTML documentation from one source file/crate, do something like: + + rustdoc --output-dir html-doc/ --output-format html ../src/libstd/path.rs + +(This, of course, requires that you've built/installed the `rustdoc` tool.) + +To generate an HTML version of a doc from Markdown, without having Node.js +installed, do something like: + + pandoc --from=markdown --to=html --number-sections -o rust.html rust.md The syntax for pandoc flavored markdown can be found at: http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown From 62dc4e0d4cebc390de4053da881a74b9e72c52e6 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 17 Jun 2013 16:32:06 -0400 Subject: [PATCH 033/336] vec: remove each_const An Iterator implementation can be made for &const [T] if it turns out to be necessary for some use case. --- src/libextra/sha1.rs | 8 ++++---- src/libstd/vec.rs | 15 --------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs index 7c4b3f4ce39f..78c4f5f13ec8 100644 --- a/src/libextra/sha1.rs +++ b/src/libextra/sha1.rs @@ -36,7 +36,7 @@ use core::vec; /// The SHA-1 interface trait Sha1 { /// Provide message input as bytes - fn input(&mut self, &const [u8]); + fn input(&mut self, &[u8]); /// Provide message input as string fn input_str(&mut self, &str); /** @@ -74,9 +74,9 @@ pub fn sha1() -> @Sha1 { computed: bool, work_buf: @mut ~[u32]}; - fn add_input(st: &mut Sha1State, msg: &const [u8]) { + fn add_input(st: &mut Sha1State, msg: &[u8]) { assert!((!st.computed)); - for vec::each_const(msg) |element| { + for msg.iter().advance |element| { st.msg_block[st.msg_block_idx] = *element; st.msg_block_idx += 1u; st.len_low += 8u32; @@ -242,7 +242,7 @@ pub fn sha1() -> @Sha1 { self.h[4] = 0xC3D2E1F0u32; self.computed = false; } - fn input(&mut self, msg: &const [u8]) { add_input(self, msg); } + fn input(&mut self, msg: &[u8]) { add_input(self, msg); } fn input_str(&mut self, msg: &str) { add_input(self, msg.as_bytes()); } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 7f683d0070fb..1131abfafa87 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1427,21 +1427,6 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { return !broke; } -/// Like `each()`, but for the case where you have a vector that *may or may -/// not* have mutable contents. -#[inline] -pub fn each_const(v: &const [T], f: &fn(elem: &const T) -> bool) -> bool { - let mut i = 0; - let n = v.len(); - while i < n { - if !f(&const v[i]) { - return false; - } - i += 1; - } - return true; -} - /** * Iterates over a vector's elements and indices * From cbad1da3db7eda0911e988fb6255ac5c16961aa7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 17 Jun 2013 16:37:11 -0400 Subject: [PATCH 034/336] vec: remove eachi replaced by the `enumerate` method from std::iterator --- src/compiletest/runtest.rs | 2 +- src/librustc/middle/trans/cabi.rs | 4 +-- src/librustc/middle/trans/closure.rs | 2 +- src/librustc/middle/trans/glue.rs | 2 +- src/libstd/vec.rs | 41 ---------------------- src/test/bench/shootout-chameneos-redux.rs | 14 ++++---- 6 files changed, 12 insertions(+), 53 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index e0ceb79a37df..71146c7e6658 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -358,7 +358,7 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError], // is the ending point, and * represents ANSI color codes. for ProcRes.stderr.line_iter().advance |line| { let mut was_expected = false; - for vec::eachi(expected_errors) |i, ee| { + for expected_errors.iter().enumerate().advance |(i, ee)| { if !found_flags[i] { debug!("prefix=%s ee.kind=%s ee.msg=%s line=%s", prefixes[i], ee.kind, ee.msg, line); diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index acc3293f2678..891eb0b1f1c1 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -43,7 +43,7 @@ impl FnType { let fnty = T_fn(atys, rty); let llfn = decl(fnty); - for vec::eachi(self.attrs) |i, a| { + for self.attrs.iter().enumerate().advance |(i, a)| { match *a { option::Some(attr) => { unsafe { @@ -100,7 +100,7 @@ impl FnType { ret_def: bool, llargbundle: ValueRef, llretval: ValueRef) { - for vec::eachi(self.attrs) |i, a| { + for self.attrs.iter().enumerate().advance |(i, a)| { match *a { option::Some(attr) => { unsafe { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index c368ab5c9bdf..8bc3889eb115 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -225,7 +225,7 @@ pub fn store_environment(bcx: block, // Copy expr values into boxed bindings. let mut bcx = bcx; - for vec::eachi(bound_values) |i, bv| { + for bound_values.iter().enumerate().advance |(i, bv)| { debug!("Copy %s into closure", bv.to_str(ccx)); if ccx.sess.asm_comments() { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 05461c936318..0ea63dde972a 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -462,7 +462,7 @@ pub fn trans_struct_drop(bcx: block, // Drop the fields let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs); - for vec::eachi(field_tys) |i, fld| { + for field_tys.iter().enumerate().advance |(i, fld)| { let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i); bcx = drop_ty(bcx, llfld_a, fld.mt.ty); } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1131abfafa87..0d5a84a4a76f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1427,21 +1427,6 @@ pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { return !broke; } -/** - * Iterates over a vector's elements and indices - * - * Return true to continue, false to break. - */ -#[inline] -pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { - let mut i = 0; - for each(v) |p| { - if !f(i, p) { return false; } - i += 1; - } - return true; -} - /** * Iterate over all permutations of vector `v`. * @@ -3259,17 +3244,6 @@ mod tests { assert_eq!(i, 6); } - #[test] - fn test_eachi() { - let mut i = 0; - for eachi([1, 2, 3]) |j, v| { - if i == 0 { assert!(*v == 1); } - assert_eq!(j + 1u, *v as uint); - i += *v; - } - assert_eq!(i, 6); - } - #[test] fn test_each_ret_len0() { let a0 : [int, .. 0] = []; @@ -4111,21 +4085,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_eachi_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do eachi(v) |_i, _elt| { - if i == 2 { - fail!() - } - i += 0; - false - }; - } - #[test] #[ignore(windows)] #[should_fail] diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 53b47b121443..2a9ea783c149 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -23,11 +23,11 @@ use std::uint; use std::vec; fn print_complements() { - let all = ~[Blue, Red, Yellow]; - for vec::each(all) |aa| { - for vec::each(all) |bb| { - io::println(show_color(*aa) + " + " + show_color(*bb) + - " -> " + show_color(transform(*aa, *bb))); + let all = [Blue, Red, Yellow]; + for all.iter().advance |aa| { + for all.iter().advance |bb| { + println(show_color(*aa) + " + " + show_color(*bb) + + " -> " + show_color(transform(*aa, *bb))); } } } @@ -49,7 +49,7 @@ fn show_color(cc: color) -> ~str { fn show_color_list(set: ~[color]) -> ~str { let mut out = ~""; - for vec::eachi(set) |_ii, col| { + for set.iter().advance |col| { out += " "; out += show_color(*col); } @@ -182,7 +182,7 @@ fn rendezvous(nn: uint, set: ~[color]) { } // tell each creature to stop - for vec::eachi(to_creature) |_ii, to_one| { + for to_creature.iter().advance |to_one| { to_one.send(None); } From 49c74524e2c5a2a81ce4cbe2c50a507c0be9f24e Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 17 Jun 2013 19:43:22 -0400 Subject: [PATCH 035/336] vec: rm old_iter implementations, except BaseIter The removed test for issue #2611 is well covered by the `std::iterator` module itself. This adds the `count` method to `IteratorUtil` to replace `EqIter`. --- doc/tutorial-tasks.md | 2 +- src/libextra/bitv.rs | 10 +- src/libextra/fileinput.rs | 10 +- src/libextra/flatpipes.rs | 10 +- src/libextra/net_ip.rs | 2 +- src/libextra/net_tcp.rs | 2 +- src/libextra/net_url.rs | 3 +- src/libextra/num/bigint.rs | 8 +- src/libextra/serialize.rs | 8 +- src/libextra/sort.rs | 4 +- src/libextra/terminfo/parser/compiled.rs | 2 +- src/libextra/treemap.rs | 2 +- src/librust/rust.rc | 4 +- src/librustc/front/config.rs | 8 +- src/librustc/lib/llvm.rs | 2 +- src/librustc/metadata/creader.rs | 20 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/metadata/encoder.rs | 3 +- src/librustc/middle/borrowck/mod.rs | 2 +- src/librustc/middle/borrowck/move_data.rs | 6 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_match.rs | 16 +- src/librustc/middle/dataflow.rs | 32 +-- src/librustc/middle/kind.rs | 6 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/lint.rs | 2 +- src/librustc/middle/mem_categorization.rs | 6 +- src/librustc/middle/moves.rs | 4 +- src/librustc/middle/privacy.rs | 24 +-- src/librustc/middle/region.rs | 6 +- src/librustc/middle/resolve.rs | 9 +- src/librustc/middle/trans/_match.rs | 17 +- src/librustc/middle/trans/adt.rs | 6 +- src/librustc/middle/trans/asm.rs | 2 +- src/librustc/middle/trans/base.rs | 10 +- src/librustc/middle/trans/callee.rs | 4 +- src/librustc/middle/trans/common.rs | 4 +- src/librustc/middle/trans/consts.rs | 6 +- src/librustc/middle/trans/expr.rs | 4 +- src/librustc/middle/trans/meth.rs | 6 +- src/librustc/middle/trans/monomorphize.rs | 2 +- src/librustc/middle/trans/reflect.rs | 12 +- src/librustc/middle/trans/tvec.rs | 2 +- src/librustc/middle/ty.rs | 13 +- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/check/_match.rs | 6 +- src/librustc/middle/typeck/check/method.rs | 13 +- src/librustc/middle/typeck/check/mod.rs | 16 +- .../middle/typeck/check/regionmanip.rs | 4 +- src/librustc/middle/typeck/check/vtable.rs | 2 +- src/librustc/middle/typeck/collect.rs | 8 +- src/librustc/middle/typeck/infer/combine.rs | 2 +- src/librustc/middle/typeck/infer/lattice.rs | 2 +- src/librustc/middle/typeck/infer/lub.rs | 4 +- .../middle/typeck/infer/region_inference.rs | 2 +- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/middle/typeck/mod.rs | 2 +- src/librustc/rustc.rc | 5 +- src/librustdoc/attr_parser.rs | 5 +- src/librustdoc/markdown_pass.rs | 2 +- src/librustdoc/prune_private_pass.rs | 2 +- src/librustdoc/rustdoc.rc | 2 +- src/librusti/rusti.rc | 6 +- src/librustpkg/package_source.rs | 4 +- src/librustpkg/tests.rs | 14 +- src/librustpkg/util.rs | 2 +- src/librustpkg/version.rs | 6 +- src/libstd/io.rs | 4 +- src/libstd/iterator.rs | 39 +++- src/libstd/old_iter.rs | 2 +- src/libstd/str.rs | 2 +- src/libstd/task/local_data_priv.rs | 4 +- src/libstd/unstable/extfmt.rs | 2 +- src/libstd/vec.rs | 187 ++---------------- src/libsyntax/abi.rs | 4 +- src/libsyntax/attr.rs | 2 +- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/ext/concat_idents.rs | 2 +- src/libsyntax/ext/deriving/decodable.rs | 2 +- src/libsyntax/ext/deriving/encodable.rs | 4 +- src/libsyntax/ext/deriving/generic.rs | 8 +- src/libsyntax/ext/expand.rs | 6 +- src/libsyntax/ext/pipes/liveness.rs | 8 +- src/libsyntax/ext/pipes/pipec.rs | 12 +- src/libsyntax/ext/pipes/proto.rs | 12 +- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/print/pprust.rs | 6 +- src/test/bench/core-std.rs | 2 +- src/test/bench/graph500-bfs.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 10 +- src/test/bench/shootout-spectralnorm.rs | 2 +- .../run-pass/deriving-cmp-generic-enum.rs | 4 +- .../run-pass/deriving-cmp-generic-struct.rs | 4 +- .../deriving-cmp-generic-tuple-struct.rs | 4 +- src/test/run-pass/issue-2611.rs | 24 --- src/test/run-pass/vec-position.rs | 16 -- 96 files changed, 310 insertions(+), 490 deletions(-) delete mode 100644 src/test/run-pass/issue-2611.rs delete mode 100644 src/test/run-pass/vec-position.rs diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index 2e3ce40c9f7d..97c85a5c436c 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -283,7 +283,7 @@ let ports = do vec::from_fn(3) |init_val| { }; // Wait on each port, accumulating the results -let result = ports.foldl(0, |accum, port| *accum + port.recv() ); +let result = ports.iter().fold(0, |accum, port| accum + port.recv() ); # fn some_expensive_computation(_i: uint) -> int { 42 } ~~~ diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 647fa81c7185..940c89bb0c68 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -639,7 +639,7 @@ impl BitvSet { if self.capacity() < other.capacity() { self.bitv.storage.grow(other.capacity() / uint::bits, &0); } - for other.bitv.storage.eachi |i, &w| { + for other.bitv.storage.iter().enumerate().advance |(i, &w)| { let old = self.bitv.storage[i]; let new = f(old, w); self.bitv.storage[i] = new; @@ -672,7 +672,7 @@ impl BaseIter for BitvSet { fn size_hint(&self) -> Option { Some(self.len()) } fn each(&self, blk: &fn(v: &uint) -> bool) -> bool { - for self.bitv.storage.eachi |i, &w| { + for self.bitv.storage.iter().enumerate().advance |(i, &w)| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { return false; } @@ -826,7 +826,7 @@ impl BitvSet { f: &fn(uint, uint, uint) -> bool) -> bool { let min = uint::min(self.bitv.storage.len(), other.bitv.storage.len()); - self.bitv.storage.slice(0, min).eachi(|i, &w| { + self.bitv.storage.slice(0, min).iter().enumerate().advance(|(i, &w)| { f(i * uint::bits, w, other.bitv.storage[i]) }) } @@ -845,12 +845,12 @@ impl BitvSet { let min = uint::min(len1, len2); /* only one of these loops will execute and that's the point */ - for self.bitv.storage.slice(min, len1).eachi |i, &w| { + for self.bitv.storage.slice(min, len1).iter().enumerate().advance |(i, &w)| { if !f(true, (i + min) * uint::bits, w) { return false; } } - for other.bitv.storage.slice(min, len2).eachi |i, &w| { + for other.bitv.storage.slice(min, len2).iter().enumerate().advance |(i, &w)| { if !f(false, (i + min) * uint::bits, w) { return false; } diff --git a/src/libextra/fileinput.rs b/src/libextra/fileinput.rs index ed38db1d686e..46646e2af563 100644 --- a/src/libextra/fileinput.rs +++ b/src/libextra/fileinput.rs @@ -448,7 +448,7 @@ mod test { |i| fmt!("tmp/lib-fileinput-test-fileinput-read-byte-%u.tmp", i)), true); // 3 files containing 0\n, 1\n, and 2\n respectively - for filenames.eachi |i, &filename| { + for filenames.iter().enumerate().advance |(i, &filename)| { make_file(filename.get_ref(), [fmt!("%u", i)]); } @@ -478,7 +478,7 @@ mod test { |i| fmt!("tmp/lib-fileinput-test-fileinput-read-%u.tmp", i)), true); // 3 files containing 1\n, 2\n, and 3\n respectively - for filenames.eachi |i, &filename| { + for filenames.iter().enumerate().advance |(i, &filename)| { make_file(filename.get_ref(), [fmt!("%u", i)]); } @@ -498,7 +498,7 @@ mod test { 3, |i| fmt!("tmp/lib-fileinput-test-input-vec-%u.tmp", i)), true); - for filenames.eachi |i, &filename| { + for filenames.iter().enumerate().advance |(i, &filename)| { let contents = vec::from_fn(3, |j| fmt!("%u %u", i, j)); make_file(filename.get_ref(), contents); @@ -518,7 +518,7 @@ mod test { 3, |i| fmt!("tmp/lib-fileinput-test-input-vec-state-%u.tmp", i)),true); - for filenames.eachi |i, &filename| { + for filenames.iter().enumerate().advance |(i, &filename)| { let contents = vec::from_fn(3, |j| fmt!("%u %u", i, j + 1)); make_file(filename.get_ref(), contents); @@ -582,7 +582,7 @@ mod test { 3, |i| fmt!("tmp/lib-fileinput-test-next-file-%u.tmp", i)),true); - for filenames.eachi |i, &filename| { + for filenames.iter().enumerate().advance |(i, &filename)| { let contents = vec::from_fn(3, |j| fmt!("%u %u", i, j + 1)); make_file(&filename.get(), contents); diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index 9a8ee3959364..60fbfdeb62c1 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -307,11 +307,11 @@ impl,P:BytePort> GenericPort for FlatPort { impl,C:ByteChan> GenericChan for FlatChan { fn send(&self, val: T) { - self.byte_chan.send(CONTINUE.to_vec()); + self.byte_chan.send(CONTINUE.to_owned()); let bytes = self.flattener.flatten(val); let len = bytes.len() as u64; do io::u64_to_be_bytes(len, size_of::()) |len_bytes| { - self.byte_chan.send(len_bytes.to_vec()); + self.byte_chan.send(len_bytes.to_owned()); } self.byte_chan.send(bytes); } @@ -937,7 +937,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_vec() + [0]; + let bytes = CONTINUE.to_owned() + [0]; let port = loader(bytes); let res: Option = port.try_recv(); assert!(res.is_none()); @@ -959,9 +959,9 @@ mod test { // then undeserializable garbage let len_bytes = do io::u64_to_be_bytes( 1, sys::size_of::()) |len_bytes| { - len_bytes.to_vec() + len_bytes.to_owned() }; - let bytes = CONTINUE.to_vec() + len_bytes + [0, 0, 0, 0]; + let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0]; let port = loader(bytes); diff --git a/src/libextra/net_ip.rs b/src/libextra/net_ip.rs index 518a9d8685a5..91c357088c98 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net_ip.rs @@ -205,7 +205,7 @@ pub mod v4 { }).collect(); if parts.len() != 4 { Err(fmt!("'%s' doesn't have 4 parts", ip)) - } else if parts.contains(&256) { + } else if parts.iter().any_(|x| *x == 256u) { Err(fmt!("invalid octal in addr '%s'", ip)) } else { Ok(Ipv4Rep { diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index 51d744955b81..d44340121789 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -978,7 +978,7 @@ impl io::Writer for TcpSocketBuf { let w_result = write_common_impl(socket_data_ptr, vec::slice(data, 0, - data.len()).to_vec()); + data.len()).to_owned()); if w_result.is_err() { let err_data = w_result.get_err(); debug!( diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index a0ce1669a448..289f3888f638 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -519,8 +519,9 @@ fn get_authority(rawurl: &str) -> let end = end; // make end immutable so it can be captured let host_is_end_plus_one: &fn() -> bool = || { + let xs = ['?', '#', '/']; end+1 == len - && !['?', '#', '/'].contains(&(rawurl[end] as char)) + && !xs.iter().any_(|x| *x == (rawurl[end] as char)) }; // finish up diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 14156e8b901b..7ec2bd8b9b6f 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -1175,8 +1175,8 @@ mod biguint_tests { fn test_cmp() { let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ] .map(|v| BigUint::from_slice(*v)); - for data.eachi |i, ni| { - for vec::slice(data, i, data.len()).eachi |j0, nj| { + for data.iter().enumerate().advance |(i, ni)| { + for vec::slice(data, i, data.len()).iter().enumerate().advance |(j0, nj)| { let j = j0 + i; if i == j { assert_eq!(ni.cmp(nj), Equal); @@ -1651,8 +1651,8 @@ mod bigint_tests { nums.push(Zero::zero()); nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); - for nums.eachi |i, ni| { - for vec::slice(nums, i, nums.len()).eachi |j0, nj| { + for nums.iter().enumerate().advance |(i, ni)| { + for vec::slice(nums, i, nums.len()).iter().enumerate().advance |(j0, nj)| { let j = i + j0; if i == j { assert_eq!(ni.cmp(nj), Equal); diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index a54db07261a6..34fd7e9f1ec1 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -432,7 +432,7 @@ impl> Decodable for @T { impl<'self, S:Encoder,T:Encodable> Encodable for &'self [T] { fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { - for self.eachi |i, e| { + for self.iter().enumerate().advance |(i, e)| { s.emit_seq_elt(i, |s| e.encode(s)) } } @@ -442,7 +442,7 @@ impl<'self, S:Encoder,T:Encodable> Encodable for &'self [T] { impl> Encodable for ~[T] { fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { - for self.eachi |i, e| { + for self.iter().enumerate().advance |(i, e)| { s.emit_seq_elt(i, |s| e.encode(s)) } } @@ -462,7 +462,7 @@ impl> Decodable for ~[T] { impl> Encodable for @[T] { fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { - for self.eachi |i, e| { + for self.iter().enumerate().advance |(i, e)| { s.emit_seq_elt(i, |s| e.encode(s)) } } @@ -901,7 +901,7 @@ pub trait EncoderHelpers { impl EncoderHelpers for S { fn emit_from_vec(&mut self, v: &[T], f: &fn(&mut S, &T)) { do self.emit_seq(v.len()) |this| { - for v.eachi |i, e| { + for v.iter().enumerate().advance |(i, e)| { do this.emit_seq_elt(i) |this| { f(this, e) } diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 3e81216fc3a1..df5e8b2f176e 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -731,7 +731,7 @@ fn copy_vec(dest: &mut [T], from: &[T]) { assert!(s1+from.len() <= dest.len()); - for from.eachi |i, v| { + for from.iter().enumerate().advance |(i, v)| { dest[s1+i] = copy *v; } } @@ -743,7 +743,7 @@ fn shift_vec(dest: &mut [T], len: uint) { assert!(s1+len <= dest.len()); - let tmp = dest.slice(s2, s2+len).to_vec(); + let tmp = dest.slice(s2, s2+len).to_owned(); copy_vec(dest, s1, tmp); } diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 66649c62fcaf..123a388900b8 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -271,7 +271,7 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { return Err(~"error: hit EOF before end of string table"); } - for string_offsets.eachi |i, v| { + for string_offsets.iter().enumerate().advance |(i, v)| { let offset = *v; if offset == 0xFFFF { // non-entry loop; diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f857581c17dd..97b459bcc9ed 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -853,7 +853,7 @@ mod test_treemap { for 90.times { let k = rng.gen(); let v = rng.gen(); - if !ctrl.contains(&(k, v)) { + if !ctrl.iter().any_(|x| x == &(k, v)) { assert!(map.insert(k, v)); ctrl.push((k, v)); check_structure(&map); diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 9d8f1c1a0917..cf705d722535 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -135,9 +135,9 @@ fn rustc_help() { } fn find_cmd(command_string: &str) -> Option { - do commands.find |command| { + do commands.iter().find_ |command| { command.cmd == command_string - } + }.map_consume(|x| copy *x) } fn cmd_help(args: &[~str]) -> ValidUsage { diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 3e6ac283da0a..517b3f9ed857 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -197,13 +197,13 @@ pub fn metas_in_cfg(cfg: ast::crate_cfg, // which the item is valid let cfg_metas = vec::filter_map(cfg_metas, |i| attr::get_meta_item_list(i)); - if cfg_metas.all(|c| c.is_empty()) { return true; } + if cfg_metas.iter().all(|c| c.is_empty()) { return true; } - cfg_metas.any(|cfg_meta| { - cfg_meta.all(|cfg_mi| { + cfg_metas.iter().any_(|cfg_meta| { + cfg_meta.iter().all(|cfg_mi| { match cfg_mi.node { ast::meta_list(s, ref it) if "not" == s - => it.all(|mi| !attr::contains(cfg, *mi)), + => it.iter().all(|mi| !attr::contains(cfg, *mi)), _ => attr::contains(cfg, *cfg_mi) } }) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 5d5a5e736bce..8d6cad62e753 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2157,7 +2157,7 @@ pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef) _ => {} } - let outer = vec::append_one(outer0.to_vec(), ty); + let outer = vec::append_one(outer0.to_owned(), ty); let kind = llvm::LLVMGetTypeKind(ty); diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index e95c841b9f78..c8b0f4a488ad 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -85,16 +85,16 @@ fn warn_if_multiple_versions(e: @mut Env, *crate_cache[crate_cache.len() - 1].metas ); - let (matches, non_matches) = - partition(crate_cache.map_to_vec(|&entry| { - let othername = loader::crate_name_from_metas( - copy *entry.metas); - if name == othername { - Left(entry) - } else { - Right(entry) - } - })); + let vec: ~[Either] = crate_cache.iter().transform(|&entry| { + let othername = loader::crate_name_from_metas( + copy *entry.metas); + if name == othername { + Left(entry) + } else { + Right(entry) + } + }).collect(); + let (matches, non_matches) = partition(vec); assert!(!matches.is_empty()); diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 2819340ae453..399ad215fdb3 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -104,7 +104,7 @@ pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] { pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool { assert!(!lib.is_empty()); - if cstore.used_libraries.contains(&lib) { return false; } + if cstore.used_libraries.iter().any_(|x| x == &lib) { return false; } cstore.used_libraries.push(lib); true } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5d5d7582b5f3..bc2e95f4d1b1 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1014,7 +1014,8 @@ fn encode_info_for_item(ecx: &EncodeContext, ebml_w.end_tag(); // Now output the method info for each method. - for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| { + let r = ty::trait_method_def_ids(tcx, local_def(item.id)); + for r.iter().enumerate().advance |(i, &method_def_id)| { assert_eq!(method_def_id.crate, ast::local_crate); let method_ty = ty::method(tcx, method_def_id); diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index d7186ad93335..745e792eec75 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -132,7 +132,7 @@ fn borrowck_fn(fk: &visit::fn_kind, LoanDataFlowOperator, id_range, all_loans.len()); - for all_loans.eachi |loan_idx, loan| { + for all_loans.iter().enumerate().advance |(loan_idx, loan)| { loan_dfcx.add_gen(loan.gen_scope, loan_idx); loan_dfcx.add_kill(loan.kill_scope, loan_idx); } diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 3b1c451d0a6e..0ed909b64829 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -348,11 +348,11 @@ impl MoveData { * killed by scoping. See `doc.rs` for more details. */ - for self.moves.eachi |i, move| { + for self.moves.iter().enumerate().advance |(i, move)| { dfcx_moves.add_gen(move.id, i); } - for self.var_assignments.eachi |i, assignment| { + for self.var_assignments.iter().enumerate().advance |(i, assignment)| { dfcx_assign.add_gen(assignment.id, i); self.kill_moves(assignment.path, assignment.id, dfcx_moves); } @@ -375,7 +375,7 @@ impl MoveData { } // Kill all assignments when the variable goes out of scope: - for self.var_assignments.eachi |assignment_index, assignment| { + for self.var_assignments.iter().enumerate().advance |(assignment_index, assignment)| { match *self.path(assignment.path).loan_path { LpVar(id) => { let kill_id = tcx.region_maps.encl_scope(id); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index f44fb0e058bc..79fe6420e278 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -225,7 +225,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.contains(&(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 ad89d790761e..4da88981a635 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -155,7 +155,7 @@ pub fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) { }; let variants = ty::enum_variants(cx.tcx, id); - match variants.find(|v| v.id == vid) { + match variants.iter().find_(|v| v.id == vid) { Some(v) => Some(cx.tcx.sess.str_of(v.name)), None => { fail!("check_exhaustive: bad variant in ctor") @@ -208,7 +208,7 @@ pub enum ctor { pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { if m.len() == 0u { return useful_; } if m[0].len() == 0u { return not_useful; } - let real_pat = match m.find(|r| r[0].id != 0) { + let real_pat = match m.iter().find_(|r| r[0].id != 0) { Some(r) => r[0], None => v[0] }; let left_ty = if real_pat.id == 0 { ty::mk_nil() } @@ -372,7 +372,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, let variants = ty::enum_variants(cx.tcx, eid); if found.len() != (*variants).len() { for (*variants).each |v| { - if !found.contains(&(variant(v.id))) { + if !found.iter().any_(|x| x == &(variant(v.id))) { return Some(variant(v.id)); } } @@ -613,7 +613,7 @@ pub fn specialize(cx: @MatchCheckCtxt, if variant(variant_id) == *ctor_id { // FIXME #4731: Is this right? --pcw let args = flds.map(|ty_field| { - match flds.find(|f| + match flds.iter().find_(|f| f.ident == ty_field.ident) { Some(f) => f.pat, _ => wild() @@ -644,7 +644,7 @@ pub fn specialize(cx: @MatchCheckCtxt, } } let args = vec::map(class_fields, |class_field| { - match flds.find(|f| + match flds.iter().find_(|f| f.ident == class_field.ident) { Some(f) => f.pat, _ => wild() @@ -806,13 +806,13 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool { } pat_lit(_) | pat_range(_, _) => { true } pat_struct(_, ref fields, _) => { - fields.any(|f| is_refutable(cx, f.pat)) + fields.iter().any_(|f| is_refutable(cx, f.pat)) } pat_tup(ref elts) => { - elts.any(|elt| is_refutable(cx, *elt)) + elts.iter().any_(|elt| is_refutable(cx, *elt)) } pat_enum(_, Some(ref args)) => { - args.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 b4942fba05da..1e14a558db28 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -266,7 +266,7 @@ impl DataFlowContext { f: &fn(uint) -> bool) -> bool { //! Helper for iterating over the bits in a bit set. - for words.eachi |word_index, &word| { + for words.iter().enumerate().advance |(word_index, &word)| { if word != 0 { let base_index = word_index * uint::bits; for uint::range(0, uint::bits) |offset| { @@ -342,14 +342,14 @@ impl DataFlowContext { let entry_str = bits_to_str(on_entry); let gens = vec::slice(self.gens, start, end); - let gens_str = if gens.any(|&u| u != 0) { + let gens_str = if gens.iter().any_(|&u| u != 0) { fmt!(" gen: %s", bits_to_str(gens)) } else { ~"" }; let kills = vec::slice(self.kills, start, end); - let kills_str = if kills.any(|&u| u != 0) { + let kills_str = if kills.iter().any_(|&u| u != 0) { fmt!(" kill: %s", bits_to_str(kills)) } else { ~"" @@ -503,12 +503,12 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // func_bits represents the state when the function // returns - let mut func_bits = reslice(in_out).to_vec(); + let mut func_bits = reslice(in_out).to_owned(); loop_scopes.push(LoopScope { loop_id: expr.id, loop_kind: ForLoop, - break_bits: reslice(in_out).to_vec() + break_bits: reslice(in_out).to_owned() }); for decl.inputs.each |input| { self.walk_pat(input.pat, func_bits, loop_scopes); @@ -547,7 +547,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // self.walk_expr(cond, in_out, loop_scopes); - let mut then_bits = reslice(in_out).to_vec(); + let mut then_bits = reslice(in_out).to_owned(); self.walk_block(then, then_bits, loop_scopes); self.walk_opt_expr(els, in_out, loop_scopes); @@ -569,11 +569,11 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.walk_expr(cond, in_out, loop_scopes); - let mut body_bits = reslice(in_out).to_vec(); + let mut body_bits = reslice(in_out).to_owned(); loop_scopes.push(LoopScope { loop_id: expr.id, loop_kind: TrueLoop, - break_bits: reslice(in_out).to_vec() + break_bits: reslice(in_out).to_owned() }); self.walk_block(blk, body_bits, loop_scopes); self.add_to_entry_set(expr.id, body_bits); @@ -591,12 +591,12 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // <--+ (break) // - let mut body_bits = reslice(in_out).to_vec(); + let mut body_bits = reslice(in_out).to_owned(); self.reset(in_out); loop_scopes.push(LoopScope { loop_id: expr.id, loop_kind: TrueLoop, - break_bits: reslice(in_out).to_vec() + break_bits: reslice(in_out).to_owned() }); self.walk_block(blk, body_bits, loop_scopes); self.add_to_entry_set(expr.id, body_bits); @@ -620,7 +620,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // self.walk_expr(discr, in_out, loop_scopes); - let mut guards = reslice(in_out).to_vec(); + let mut guards = reslice(in_out).to_owned(); // We know that exactly one arm will be taken, so we // can start out with a blank slate and just union @@ -633,7 +633,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // determine the bits for the body and then union // them into `in_out`, which reflects all bodies to date - let mut body = reslice(guards).to_vec(); + let mut body = reslice(guards).to_owned(); self.walk_pat_alternatives(arm.pats, body, loop_scopes); self.walk_block(&arm.body, body, loop_scopes); join_bits(&self.dfcx.oper, body, in_out); @@ -644,7 +644,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.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 @@ -735,7 +735,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { ast::expr_binary(_, op, l, r) if ast_util::lazy_binop(op) => { self.walk_expr(l, in_out, loop_scopes); - let temp = reslice(in_out).to_vec(); + let temp = reslice(in_out).to_owned(); self.walk_expr(r, in_out, loop_scopes); join_bits(&self.dfcx.oper, temp, in_out); } @@ -896,7 +896,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // In the general case, the patterns in `pats` are // alternatives, so we must treat this like an N-way select // statement. - let initial_state = reslice(in_out).to_vec(); + let initial_state = reslice(in_out).to_owned(); for pats.each |&pat| { let mut temp = copy initial_state; self.walk_pat(pat, temp, loop_scopes); @@ -917,7 +917,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.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 70ad0e1c3a9f..6492850b6685 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -477,7 +477,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.any(|r| is_re_scope(*r)) { + if target_regions.iter().any_(|r| is_re_scope(*r)) { return; /* case (1) */ } @@ -492,7 +492,7 @@ pub fn check_cast_for_escaping_regions( |_r| { // FIXME(#5723) --- turn this check on once &Objects are usable // - // if !target_regions.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 \ @@ -506,7 +506,7 @@ pub fn check_cast_for_escaping_regions( |ty| { match ty::get(ty).sty { ty::ty_param(source_param) => { - if target_params.contains(&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 7f54e265b7ba..2f66ca0f516c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -90,7 +90,7 @@ impl LanguageItems { } pub fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) -> bool { - self.items.eachi(|i, &item| f(item.get(), i)) + self.items.iter().enumerate().advance(|(i, &item)| f(item.get(), i)) } pub fn item_name(index: uint) -> &'static str { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index c0421b2d4748..054498545b7b 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -1003,7 +1003,7 @@ 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.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); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 14764e7bc37c..297b454bd83a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -872,7 +872,7 @@ impl mem_categorization_ctxt { } }; - for subpats.eachi |i, &subpat| { + for subpats.iter().enumerate().advance |(i, &subpat)| { let subpat_ty = self.pat_ty(subpat); // see (*) let subcmt = @@ -885,7 +885,7 @@ impl mem_categorization_ctxt { } Some(&ast::def_fn(*)) | Some(&ast::def_struct(*)) => { - for subpats.eachi |i, &subpat| { + for subpats.iter().enumerate().advance |(i, &subpat)| { let subpat_ty = self.pat_ty(subpat); // see (*) let cmt_field = self.cat_imm_interior( @@ -926,7 +926,7 @@ impl mem_categorization_ctxt { ast::pat_tup(ref subpats) => { // (p1, ..., pN) - for subpats.eachi |i, &subpat| { + for subpats.iter().enumerate().advance |(i, &subpat)| { let subpat_ty = self.pat_ty(subpat); // see (*) let subcmt = self.cat_imm_interior( diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 2217e632d14a..8a29a026dc2f 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -370,8 +370,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.any(|tf| { - !fields.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/privacy.rs b/src/librustc/middle/privacy.rs index 60193f3fe5db..5cfe44e1554e 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -252,7 +252,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, method_id.node); if is_private && (container_id.crate != local_crate || - !privileged_items.contains(&(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))); @@ -280,7 +280,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.contains(&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,8 +324,8 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match (*methods)[method_num] { provided(method) if method.vis == private && - !privileged_items - .contains(&(trait_id.node)) => { + !privileged_items.iter() + .any_(|x| x == &(trait_id.node)) => { tcx.sess.span_err(span, fmt!("method `%s` is private", token::ident_to_str(&method @@ -409,7 +409,8 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::type_autoderef(tcx, ty::expr_ty(tcx, base))).sty { ty_struct(id, _) - if id.crate != local_crate || !privileged_items.contains(&(id.node)) => { + if id.crate != local_crate || !privileged_items.iter() + .any_(|x| x == &(id.node)) => { debug!("(privacy checking) checking field access"); check_field(expr.span, id, ident); } @@ -422,7 +423,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, base))).sty { ty_struct(id, _) if id.crate != local_crate || - !privileged_items.contains(&(id.node)) => { + !privileged_items.iter().any_(|x| x == &(id.node)) => { match method_map.find(&expr.id) { None => { tcx.sess.span_bug(expr.span, @@ -448,7 +449,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, match ty::get(ty::expr_ty(tcx, expr)).sty { ty_struct(id, _) => { if id.crate != local_crate || - !privileged_items.contains(&(id.node)) { + !privileged_items.iter().any_(|x| x == &(id.node)) { for (*fields).each |field| { debug!("(privacy checking) checking \ field in struct literal"); @@ -459,7 +460,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(id, _) => { if id.crate != local_crate || - !privileged_items.contains(&(id.node)) { + !privileged_items.iter().any_(|x| x == &(id.node)) { match tcx.def_map.get_copy(&expr.id) { def_variant(_, variant_id) => { for (*fields).each |field| { @@ -496,7 +497,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.contains(&(id.node)) { + !privileged_items.iter().any_(|x| x == &(id.node)) { check_variant(expr.span, id); } } @@ -514,7 +515,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.contains(&(id.node)) { + !privileged_items.iter().any_(|x| x == &(id.node)) { for fields.each |field| { debug!("(privacy checking) checking \ struct pattern"); @@ -525,8 +526,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } ty_enum(enum_id, _) => { if enum_id.crate != local_crate || - !privileged_items.contains( - &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.each |field| { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index f8d0b19922e8..eef43574c14b 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.contains(&sup) { + if !sups.iter().any_(|x| x == &sup) { sups.push(sup); } return; @@ -202,7 +202,7 @@ impl RegionMaps { return true; } - if !queue.contains(parent) { + if !queue.iter().any_(|x| x == parent) { queue.push(*parent); } } @@ -632,7 +632,7 @@ impl DetermineRpCtxt { ambient_variance: self.ambient_variance, id: self.item_id }; - if !vec.contains(&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 diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 3e656b3e5940..0248a5f43cce 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1463,7 +1463,7 @@ impl Resolver { let path_len = full_path.idents.len(); assert!(path_len != 0); - for full_path.idents.eachi |i, ident| { + for full_path.idents.iter().enumerate().advance |(i, ident)| { if i != path_len - 1 { module_path.push(*ident); } @@ -4033,7 +4033,7 @@ impl Resolver { pub fn check_consistent_bindings(@mut self, arm: &arm) { if arm.pats.len() == 0 { return; } let map_0 = self.binding_mode_map(arm.pats[0]); - for arm.pats.eachi() |i, p| { + for arm.pats.iter().enumerate().advance |(i, p)| { let map_i = self.binding_mode_map(*p); for map_0.each |&key, &binding_0| { @@ -4605,7 +4605,7 @@ impl Resolver { pub fn intern_module_part_of_path(@mut self, path: @Path) -> ~[ident] { let mut module_path_idents = ~[]; - for path.idents.eachi |index, ident| { + for path.idents.iter().enumerate().advance |(index, ident)| { if index == path.idents.len() - 1 { break; } @@ -4843,8 +4843,7 @@ impl Resolver { } let mut smallest = 0; - for maybes.eachi |i, &other| { - + for maybes.iter().enumerate().advance |(i, &other)| { values[i] = name.lev_distance(other); if values[i] <= values[smallest] { diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 029063b8c0df..945f94a0877f 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -388,7 +388,7 @@ pub fn expand_nested_bindings<'r>(bcx: block, match br.pats[col].node { ast::pat_ident(_, path, Some(inner)) => { let pats = vec::append( - vec::slice(br.pats, 0u, col).to_vec(), + vec::slice(br.pats, 0u, col).to_owned(), vec::append(~[inner], vec::slice(br.pats, col + 1u, br.pats.len()))); @@ -581,8 +581,7 @@ pub fn enter_opt<'r>(bcx: block, let mut reordered_patterns = ~[]; for ty::lookup_struct_fields(tcx, struct_id).each |field| { - match field_pats.find(|p| - p.ident == field.ident) { + match field_pats.iter().find_(|p| p.ident == field.ident) { None => reordered_patterns.push(dummy), Some(fp) => reordered_patterns.push(fp.pat) } @@ -642,7 +641,7 @@ pub fn enter_rec_or_struct<'r>(bcx: block, ast::pat_struct(_, ref fpats, _) => { let mut pats = ~[]; for fields.each |fname| { - match fpats.find(|p| p.ident == *fname) { + match fpats.iter().find_(|p| p.ident == *fname) { None => pats.push(dummy), Some(pat) => pats.push(pat.pat) } @@ -1308,11 +1307,11 @@ pub fn compile_submatch(bcx: block, if has_nested_bindings(m, col) { expand_nested_bindings(bcx, m, col, val) } else { - m.to_vec() + m.to_owned() } }; - let vals_left = vec::append(vec::slice(vals, 0u, col).to_vec(), + let vals_left = vec::append(vec::slice(vals, 0u, col).to_owned(), vec::slice(vals, col + 1u, vals.len())); let ccx = bcx.fcx.ccx; let mut pat_id = 0; @@ -1808,7 +1807,7 @@ pub fn bind_irrefutable_pat(bcx: block, vinfo.disr_val, val); for sub_pats.iter().advance |sub_pat| { - for args.vals.eachi |i, argval| { + for args.vals.iter().enumerate().advance |(i, argval)| { bcx = bind_irrefutable_pat(bcx, sub_pat[i], *argval, @@ -1826,7 +1825,7 @@ pub fn bind_irrefutable_pat(bcx: block, Some(ref elems) => { // This is the tuple struct case. let repr = adt::represent_node(bcx, pat.id); - for elems.eachi |i, elem| { + for elems.iter().enumerate().advance |(i, elem)| { let fldptr = adt::trans_field_ptr(bcx, repr, val, 0, i); bcx = bind_irrefutable_pat(bcx, @@ -1865,7 +1864,7 @@ pub fn bind_irrefutable_pat(bcx: block, } ast::pat_tup(ref elems) => { let repr = adt::represent_node(bcx, pat.id); - for elems.eachi |i, elem| { + for elems.iter().enumerate().advance |(i, elem)| { let fldptr = adt::trans_field_ptr(bcx, repr, val, 0, i); bcx = bind_irrefutable_pat(bcx, *elem, diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 0976407b0bd0..79b5aba227c3 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -145,7 +145,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.position(|&ty| mono_data_classify(ty) == MonoNonNull) + self.tys.iter().position_(|&ty| mono_data_classify(ty) == MonoNonNull) } } @@ -161,7 +161,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { return Univariant(mk_struct(cx, [], false), false); } - if cases.all(|c| c.tys.len() == 0) { + if cases.iter().all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); return CEnum(*discrs.iter().min().unwrap(), *discrs.iter().max().unwrap()); @@ -545,7 +545,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef]) let mut offset = 0; let mut cfields = ~[]; - for st.fields.eachi |i, &ty| { + for st.fields.iter().enumerate().advance |(i, &ty)| { let llty = type_of::sizing_type_of(ccx, ty); let type_align = machine::llalign_of_min(ccx, llty) /*bad*/as u64; diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index d73d57efbbf7..3814ff319f2d 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -133,7 +133,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); Store(bcx, r, op); } else { - for aoutputs.eachi |i, o| { + for aoutputs.iter().enumerate().advance |(i, o)| { let v = ExtractValue(bcx, r, i); let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i]))); Store(bcx, v, op); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d7d21707f40f..e96a4e1b5ad0 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -670,7 +670,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, let tcx = cx.tcx(); let mut cx = cx; - for variant.args.eachi |i, &arg| { + for variant.args.iter().enumerate().advance |(i, &arg)| { cx = f(cx, adt::trans_field_ptr(cx, repr, av, variant.disr_val, i), ty::subst_tps(tcx, tps, None, arg)); @@ -683,7 +683,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, ty::ty_struct(*) => { let repr = adt::represent_type(cx.ccx(), t); do expr::with_field_tys(cx.tcx(), t, None) |discr, field_tys| { - for field_tys.eachi |i, field_ty| { + for field_tys.iter().enumerate().advance |(i, field_ty)| { let llfld_a = adt::trans_field_ptr(cx, repr, av, discr, i); cx = f(cx, llfld_a, field_ty.mt.ty); } @@ -696,7 +696,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, } ty::ty_tup(ref args) => { let repr = adt::represent_type(cx.ccx(), t); - for args.eachi |i, arg| { + for args.iter().enumerate().advance |(i, arg)| { let llfld_a = adt::trans_field_ptr(cx, repr, av, 0, i); cx = f(cx, llfld_a, *arg); } @@ -2017,7 +2017,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, repr, ty_to_str(ccx.tcx, enum_ty)); adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr); - for args.eachi |i, va| { + for args.iter().enumerate().advance |(i, va)| { let lldestptr = adt::trans_field_ptr(bcx, repr, fcx.llretptr.get(), @@ -2092,7 +2092,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, let repr = adt::represent_type(ccx, tup_ty); adt::trans_start_init(bcx, repr, fcx.llretptr.get(), 0); - for fields.eachi |i, field| { + for fields.iter().enumerate().advance |(i, field)| { let lldestptr = adt::trans_field_ptr(bcx, repr, fcx.llretptr.get(), diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index bfbe078c4f52..582d51c2cbf2 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -225,7 +225,7 @@ pub fn trans_fn_ref_with_vtables( type_params.repr(bcx.tcx()), vtables.repr(bcx.tcx())); - assert!(type_params.all(|t| !ty::type_needs_infer(*t))); + assert!(type_params.iter().all(|t| !ty::type_needs_infer(*t))); // Polytype of the function item (may have type params) let fn_tpt = ty::lookup_item_type(tcx, def_id); @@ -706,7 +706,7 @@ pub fn trans_args(cx: block, match args { ArgExprs(arg_exprs) => { let last = arg_exprs.len() - 1u; - for arg_exprs.eachi |i, arg_expr| { + for arg_exprs.iter().enumerate().advance |(i, arg_expr)| { let arg_val = unpack_result!(bcx, { trans_arg_expr(bcx, arg_tys[i], diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index ff98e5a177f2..fc79c8c23d45 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -476,7 +476,7 @@ pub fn revoke_clean(cx: block, val: ValueRef) { }); for cleanup_pos.iter().advance |i| { scope_info.cleanups = - vec::append(vec::slice(scope_info.cleanups, 0u, *i).to_vec(), + vec::append(vec::slice(scope_info.cleanups, 0u, *i).to_owned(), vec::slice(scope_info.cleanups, *i + 1u, scope_info.cleanups.len())); @@ -1397,7 +1397,7 @@ pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] { let tcx = bcx.tcx(); let params = ty::node_id_to_type_params(tcx, id); - if !params.all(|t| !ty::type_needs_infer(*t)) { + if !params.iter().all(|t| !ty::type_needs_infer(*t)) { bcx.sess().bug( fmt!("Type parameters for node %d include inference types: %s", id, params.map(|t| bcx.ty_to_str(*t)).connect(","))); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index f6b1ba0ffe4c..dcdb53ec532a 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.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) @@ -487,8 +487,8 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { do expr::with_field_tys(tcx, ety, Some(e.id)) |discr, field_tys| { let cs = field_tys.map(|field_ty| { - match fs.find(|f| field_ty.ident == f.node.ident) { - Some(ref f) => const_expr(cx, (*f).node.expr), + match fs.iter().find_(|f| field_ty.ident == f.node.ident) { + Some(f) => const_expr(cx, (*f).node.expr), None => { cx.tcx.sess.span_bug(e.span, "missing struct field"); } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index cbe20afe9192..3cbbd61aed6f 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1168,7 +1168,7 @@ fn trans_rec_or_struct(bcx: block, let optbase = match base { Some(base_expr) => { let mut leftovers = ~[]; - for need_base.eachi |i, b| { + for need_base.iter().enumerate().advance |(i, b)| { if *b { leftovers.push((i, field_tys[i].mt.ty)) } @@ -1177,7 +1177,7 @@ fn trans_rec_or_struct(bcx: block, fields: leftovers }) } None => { - if need_base.any(|b| *b) { + if need_base.iter().any_(|b| *b) { tcx.sess.span_bug(expr_span, "missing fields and no base expr") } None diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index c59b3f36779b..b01c4b50324d 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -345,7 +345,7 @@ pub fn trans_static_method_callee(bcx: block, match vtbls[bound_index] { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { - assert!(rcvr_substs.all(|t| !ty::type_needs_infer(*t))); + assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t))); let mth_id = method_with_name_or_default(bcx.ccx(), impl_did, @@ -375,7 +375,7 @@ pub fn trans_static_method_callee(bcx: block, pub fn method_from_methods(ms: &[@ast::method], name: ast::ident) -> Option { - ms.find(|m| m.ident == name).map(|m| ast_util::local_def(m.id)) + ms.iter().find_(|m| m.ident == name).map(|m| ast_util::local_def(m.id)) } pub fn method_with_name_or_default(ccx: @mut CrateContext, @@ -535,7 +535,7 @@ pub fn combine_impl_and_methods_tps(bcx: block, let node_substs = node_id_type_params(bcx, callee_id); debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t))); let ty_substs - = vec::append(rcvr_substs.to_vec(), + = vec::append(rcvr_substs.to_owned(), vec::tailn(node_substs, node_substs.len() - n_m_tps)); debug!("n_m_tps=%?", n_m_tps); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index df2831947130..368ad0674e1e 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -60,7 +60,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, impl_did_opt.repr(ccx.tcx), ref_id); - assert!(real_substs.tps.all(|t| !ty::type_needs_infer(*t))); + assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); let _icx = ccx.insn_ctxt("monomorphic_fn"); let mut must_cast = false; let substs = vec::map(real_substs.tps, |t| { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index e4924e3a8db3..16a6d62f1767 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -95,7 +95,7 @@ impl Reflector { let v = self.visitor_val; debug!("passing %u args:", args.len()); let bcx = self.bcx; - for args.eachi |i, a| { + for args.iter().enumerate().advance |(i, a)| { debug!("arg %u: %s", i, val_str(bcx.ccx().tn, *a)); } let bool_ty = ty::mk_bool(); @@ -207,7 +207,7 @@ impl Reflector { let extra = ~[self.c_uint(tys.len())] + self.c_size_and_align(t); do self.bracketed(~"tup", extra) |this| { - for tys.eachi |i, t| { + for tys.iter().enumerate().advance |(i, t)| { let extra = ~[this.c_uint(i), this.c_tydesc(*t)]; this.visit(~"tup_field", extra); } @@ -252,7 +252,7 @@ impl Reflector { let extra = ~[self.c_uint(fields.len())] + self.c_size_and_align(t); do self.bracketed(~"class", extra) |this| { - for fields.eachi |i, field| { + for fields.iter().enumerate().advance |(i, field)| { let extra = ~[this.c_uint(i), this.c_slice( bcx.ccx().sess.str_of(field.ident))] @@ -310,14 +310,14 @@ impl Reflector { let enum_args = ~[self.c_uint(variants.len()), make_get_disr()] + self.c_size_and_align(t); do self.bracketed(~"enum", enum_args) |this| { - for variants.eachi |i, v| { + for variants.iter().enumerate().advance |(i, v)| { let name = ccx.sess.str_of(v.name); let variant_args = ~[this.c_uint(i), this.c_int(v.disr_val), this.c_uint(v.args.len()), this.c_slice(name)]; do this.bracketed(~"enum_variant", variant_args) |this| { - for v.args.eachi |j, a| { + for v.args.iter().enumerate().advance |(j, a)| { let bcx = this.bcx; let null = C_null(llptrty); let ptr = adt::trans_field_ptr(bcx, repr, null, v.disr_val, j); @@ -352,7 +352,7 @@ impl Reflector { } pub fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) { - for sig.inputs.eachi |i, arg| { + for sig.inputs.iter().enumerate().advance |(i, arg)| { let modeval = 5u; // "by copy" let extra = ~[self.c_uint(i), self.c_uint(modeval), diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 11a4e82050d2..09905a761879 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -386,7 +386,7 @@ pub fn write_content(bcx: block, SaveIn(lldest) => { let mut temp_cleanups = ~[]; - for elements.eachi |i, element| { + for elements.iter().enumerate().advance |(i, element)| { let lleltptr = GEPi(bcx, lldest, [i]); debug!("writing index %? with lleltptr=%?", i, bcx.val_str(lleltptr)); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4fc431e0a54c..a4702808746e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2116,7 +2116,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ty_struct(did, ref substs) => { let flds = struct_fields(cx, did, substs); - let mut res = flds.foldl( + let mut res = flds.iter().fold( TC_NONE, |tc, f| tc + tc_mt(cx, f.mt, cache)); if ty::has_dtor(cx, did) { @@ -2126,7 +2126,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } ty_tup(ref tys) => { - tys.foldl(TC_NONE, |tc, ty| *tc + tc_ty(cx, *ty, cache)) + tys.iter().fold(TC_NONE, |tc, ty| tc + tc_ty(cx, *ty, cache)) } ty_enum(did, ref substs) => { @@ -2136,10 +2136,9 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { // are non-copyable TC_EMPTY_ENUM } else { - variants.foldl(TC_NONE, |tc, variant| { - variant.args.foldl( - *tc, - |tc, arg_ty| *tc + tc_ty(cx, *arg_ty, cache)) + variants.iter().fold(TC_NONE, |tc, variant| { + variant.args.iter().fold(tc, + |tc, arg_ty| tc + tc_ty(cx, *arg_ty, cache)) }) }; apply_tc_attr(cx, did, res) @@ -2365,7 +2364,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { } ty_tup(ref ts) => { - ts.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 vec::contains(*seen, did) => { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 4b5f416cdd17..660ff83b5b3e 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -534,7 +534,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.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`", diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 97e933496c81..3a661f74239a 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -274,7 +274,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt, // Index the class fields. let mut field_map = HashMap::new(); - for class_fields.eachi |i, class_field| { + for class_fields.iter().enumerate().advance |(i, class_field)| { field_map.insert(class_field.ident, i); } @@ -303,7 +303,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt, // Report an error if not all the fields were specified. if !etc { - for class_fields.eachi |i, field| { + for class_fields.iter().enumerate().advance |(i, field)| { if found_fields.contains(&i) { loop; } @@ -510,7 +510,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { let e_count = elts.len(); match s { ty::ty_tup(ref ex_elts) if e_count == ex_elts.len() => { - for elts.eachi |i, elt| { + for elts.iter().enumerate().advance |(i, elt)| { check_pat(pcx, *elt, ex_elts[i]); } fcx.write_ty(pat.id, expected); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index b2c9d27241d4..bdf88cb6df44 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -254,7 +254,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.contains(&did) { + if enum_dids.iter().any_(|x| x == &did) { return None; } enum_dids.push(did); @@ -376,7 +376,7 @@ impl<'self> LookupContext<'self> { let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id); let pos = { - match trait_methods.position(|m| { + match trait_methods.iter().position_(|m| { m.explicit_self != ast::sty_static && m.ident == self.m_name }) { @@ -543,7 +543,7 @@ impl<'self> LookupContext<'self> { } let idx = { - match impl_info.methods.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. } @@ -813,8 +813,9 @@ impl<'self> LookupContext<'self> { rcvr_ty: ty::t, candidates: &mut ~[Candidate]) -> Option { - let relevant_candidates = - candidates.filter_to_vec(|c| self.is_relevant(rcvr_ty, c)); + let relevant_candidates: ~[Candidate] = + candidates.iter().transform(|c| copy *c). + filter(|c| self.is_relevant(rcvr_ty, c)).collect(); let relevant_candidates = self.merge_candidates(relevant_candidates); @@ -942,7 +943,7 @@ impl<'self> LookupContext<'self> { parameters given for this method"); self.fcx.infcx().next_ty_vars(num_method_tps) } else { - self.supplied_tps.to_vec() + self.supplied_tps.to_owned() } }; diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 12b413bc5af9..2d8233f8c0aa 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1236,7 +1236,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, vtable::early_resolve_expr(callee_expr, fcx, true); } - for args.eachi |i, arg| { + for args.iter().enumerate().advance |(i, arg)| { let is_block = match arg.node { ast::expr_fn_block(*) | ast::expr_loop_body(*) | ast::expr_do_body(*) => true, @@ -2492,13 +2492,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let discrim_ty = fcx.expr_ty(discrim); let arm_tys = arms.map(|a| fcx.node_ty(a.body.node.id)); if ty::type_is_error(discrim_ty) || - arm_tys.any(|t| ty::type_is_error(*t)) { + arm_tys.iter().any_(|t| ty::type_is_error(*t)) { fcx.write_error(id); } // keep in mind that `all` returns true in the empty vec case, // which is what we want else if ty::type_is_bot(discrim_ty) || - arm_tys.all(|t| ty::type_is_bot(*t)) { + arm_tys.iter().all(|t| ty::type_is_bot(*t)) { fcx.write_bot(id); } else { @@ -2561,8 +2561,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ast::expr_call(f, ref args, sugar) => { check_call(fcx, expr.id, expr, f, *args, sugar); let f_ty = fcx.expr_ty(f); - let (args_bot, args_err) = args.foldl((false, false), - |&(rest_bot, rest_err), a| { + let (args_bot, args_err) = args.iter().fold((false, false), + |(rest_bot, rest_err), a| { // is this not working? let a_ty = fcx.expr_ty(*a); (rest_bot || ty::type_is_bot(a_ty), @@ -2578,8 +2578,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, check_method_call(fcx, callee_id, expr, rcvr, ident, *args, *tps, sugar); let f_ty = fcx.expr_ty(rcvr); let arg_tys = args.map(|a| fcx.expr_ty(*a)); - let (args_bot, args_err) = arg_tys.foldl((false, false), - |&(rest_bot, rest_err), a| { + let (args_bot, args_err) = arg_tys.iter().fold((false, false), + |(rest_bot, rest_err), a| { (rest_bot || ty::type_is_bot(*a), rest_err || ty::type_is_error(*a))}); if ty::type_is_error(f_ty) || args_err { @@ -3419,7 +3419,7 @@ pub fn check_bounds_are_used(ccx: @mut CrateCtxt, true }); - for tps_used.eachi |i, b| { + for tps_used.iter().enumerate().advance |(i, b)| { if !*b { ccx.tcx.sess.span_err( span, fmt!("type parameter `%s` is unused", diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index a5cfa629cf09..9db873a25b0d 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -103,8 +103,8 @@ pub fn replace_bound_regions_in_fn_sig( } // For each type `ty` in `tys`... - do tys.foldl(isr) |isr, ty| { - let mut isr = *isr; + do tys.iter().fold(isr) |isr, ty| { + let mut isr = isr; // Using fold_regions is inefficient, because it // constructs new types, but it avoids code duplication in diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 197bf5d82cce..e1b9ebf977f8 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -68,7 +68,7 @@ impl VtableContext { } fn has_trait_bounds(type_param_defs: &[ty::TypeParameterDef]) -> bool { - type_param_defs.any( + type_param_defs.iter().any_( |type_param_def| !type_param_def.bounds.trait_bounds.is_empty()) } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 56e9875d2ba6..ef456e9a1f90 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -421,7 +421,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt, generics, self_ty); // FIXME(#5527) Could have same trait multiple times - if ty_trait_refs.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"); @@ -515,7 +515,7 @@ pub fn compare_impl_method(tcx: ty::ctxt, return; } - for trait_m.generics.type_param_defs.eachi |i, trait_param_def| { + for trait_m.generics.type_param_defs.iter().enumerate().advance |(i, trait_param_def)| { // For each of the corresponding impl ty param's bounds... let impl_param_def = &impl_m.generics.type_param_defs[i]; @@ -687,11 +687,11 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, // we'll catch it in coherence let trait_ms = ty::trait_methods(tcx, trait_ref.def_id); for impl_ms.each |impl_m| { - match trait_ms.find(|trait_m| trait_m.ident == impl_m.mty.ident) { + match trait_ms.iter().find_(|trait_m| trait_m.ident == impl_m.mty.ident) { Some(trait_m) => { let num_impl_tps = generics.ty_params.len(); compare_impl_method( - ccx.tcx, num_impl_tps, impl_m, trait_m, + ccx.tcx, num_impl_tps, impl_m, *trait_m, &trait_ref.substs, selfty); } None => { diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 766816748920..773860ffc64b 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -265,7 +265,7 @@ pub fn super_tps( if vec::same_length(as_, bs) { iter_vec2(as_, bs, |a, b| { eq_tys(this, *a, *b) - }).then(|| Ok(as_.to_vec()) ) + }).then(|| Ok(as_.to_owned()) ) } else { Err(ty::terr_ty_param_size( expected_found(this, as_.len(), bs.len()))) diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 7a3230079ee3..658fd67ee585 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -503,7 +503,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.contains(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 1a73d5bd36bb..213af316549a 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -175,7 +175,7 @@ impl Combine for Lub { // Variables created during LUB computation which are // *related* to regions that pre-date the LUB computation // stay as they are. - if !tainted.all(|r| is_var_in_set(new_vars, *r)) { + if !tainted.iter().all(|r| is_var_in_set(new_vars, *r)) { debug!("generalize_region(r0=%?): \ non-new-variables found in %?", r0, tainted); @@ -189,7 +189,7 @@ impl Combine for Lub { // with. for list::each(a_isr) |pair| { let (a_br, a_r) = *pair; - if tainted.contains(&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/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 9d6176af0bab..529fc48ebdf4 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -980,7 +980,7 @@ impl RegionVarBindings { { let mut result_set = result_set; if *r == *r1 { // Clearly, this is potentially inefficient. - if !result_set.contains(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 2578f7c85535..b0f055dc77d3 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -203,7 +203,7 @@ impl Combine for Sub { // or new variables: match *tainted_region { ty::re_infer(ty::ReVar(ref vid)) => { - if new_vars.contains(vid) { loop; } + if new_vars.iter().any_(|x| x == vid) { loop; } } _ => { if *tainted_region == skol { loop; } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index dc561f413c71..99fa745fa8b0 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -198,7 +198,7 @@ pub fn write_substs_to_tcx(tcx: ty::ctxt, if substs.len() > 0u { debug!("write_substs_to_tcx(%d, %?)", node_id, substs.map(|t| ppaux::ty_to_str(tcx, *t))); - assert!(substs.all(|t| !ty::type_needs_infer(*t))); + assert!(substs.iter().all(|t| !ty::type_needs_infer(*t))); tcx.node_type_substs.insert(node_id, substs); } } diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 021dd6648cbf..52247d64cdc8 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -216,7 +216,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.contains(&~"help") || + let show_lint_options = lint_flags.iter().any_(|x| x == &~"help") || (opt_present(matches, "W") && lint_flags.is_empty()); if show_lint_options { @@ -224,7 +224,8 @@ pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { return; } - if getopts::opt_strs(matches, "Z").contains(&~"help") { + let r = getopts::opt_strs(matches, "Z"); + if r.iter().any_(|x| x == &~"help") { describe_debug_flags(); return; } diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 1abdae113c59..7b5a738f7dd2 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -57,7 +57,8 @@ pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { } pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { - do doc_metas(attrs).find |meta| { + let r = doc_metas(attrs); + do r.iter().any_ |meta| { match attr::get_meta_item_list(*meta) { Some(metas) => { let hiddens = attr::find_meta_items_by_name(metas, "hidden"); @@ -65,7 +66,7 @@ pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { } None => false } - }.is_some() + } } #[cfg(test)] diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 075b64a674cb..1d024d1f8b40 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -190,7 +190,7 @@ pub fn header_name(doc: doc::ItemTag) -> ~str { }; let self_ty = doc.self_ty.get_ref(); let mut trait_part = ~""; - for doc.trait_types.eachi |i, trait_type| { + for doc.trait_types.iter().enumerate().advance |(i, trait_type)| { if i == 0 { trait_part += " of "; } else { diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index 741da3e265ee..157f33fb170f 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -82,7 +82,7 @@ fn strip_priv_methods( item_vis: ast::visibility ) -> doc::ImplDoc { let methods = do (&doc.methods).filtered |method| { - let ast_method = do methods.find |m| { + let ast_method = do methods.iter().find_ |m| { extract::to_str(m.ident) == method.name }; assert!(ast_method.is_some()); diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 7ed5d5f55163..d02620229f5b 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -78,7 +78,7 @@ mod std { pub fn main() { let args = os::args(); - if args.contains(&~"-h") || args.contains(&~"--help") { + if args.iter().any_(|x| "-h" == *x) || args.iter().any_(|x| "--help" == *x) { config::usage(); return; } diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index c618623a2cb7..263f5395e51b 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -287,7 +287,7 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option { // 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.find |file| { + 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, @@ -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.contains(&crate_dir) { + if !repl.lib_search_paths.iter().any_(|x| x == &crate_dir) { repl.lib_search_paths.push(crate_dir); } } @@ -430,7 +430,7 @@ pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str, if !cmd.is_empty() { let args = if len > 1 { - vec::slice(split, 1, len).to_vec() + vec::slice(split, 1, len).to_owned() } else { ~[] }; match run_cmd(repl, in, out, cmd, args, use_rl) { diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 01cc48fc037b..23fb130941c9 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -60,9 +60,9 @@ impl PkgSrc { let dir; let dirs = pkgid_src_in_workspace(&self.id, &self.root); debug!("Checking dirs: %?", dirs); - let path = dirs.find(|d| os::path_exists(d)); + let path = dirs.iter().find_(|&d| os::path_exists(d)); match path { - Some(d) => dir = d, + Some(d) => dir = copy *d, None => dir = match self.fetch_git() { None => cond.raise((copy self.id, ~"supplied path for package dir does not \ exist, and couldn't interpret it as a URL fragment")), diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 8b9158732696..355cbed9ab55 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -570,14 +570,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.contains(&~"foo")); - assert!(list_output.contains(&~"bar")); - assert!(list_output.contains(&~"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.contains(&~"foo")); - assert!(list_output.contains(&~"bar")); - assert!(list_output.contains(&~"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] @@ -643,7 +643,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.contains(&~"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 60fe7d52321a..7a6384421209 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -56,7 +56,7 @@ pub fn root() -> Path { } pub fn is_cmd(cmd: &str) -> bool { - Commands.any(|&c| c == cmd) + Commands.iter().any_(|&c| c == cmd) } struct ListenerFn { diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs index 7431b5e4c011..1350751b74ce 100644 --- a/src/librustpkg/version.rs +++ b/src/librustpkg/version.rs @@ -155,7 +155,7 @@ fn try_parsing_version(s: &str) -> Option { /// Just an approximation fn is_url_like(p: &RemotePath) -> bool { let str = p.to_str(); - str.split_iter('/').count() > 2 + str.split_iter('/').len_() > 2 } /// If s is of the form foo#bar, where bar is a valid version @@ -170,7 +170,7 @@ pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, Vers for s.split_iter(sep).advance |st| { debug!("whole = %s part = %s", s, st); } - if s.split_iter(sep).count() > 2 { + if s.split_iter(sep).len_() > 2 { return None; } match s.rfind(sep) { @@ -208,4 +208,4 @@ fn test_split_version() { let s = "a#1.2"; assert!(split_version(s) == Some((s.slice(0, 1), ExactRevision(~"1.2")))); assert!(split_version("a#a#3.4") == None); -} \ No newline at end of file +} diff --git a/src/libstd/io.rs b/src/libstd/io.rs index e5e8a4cb6018..715f2fdabd3b 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -65,7 +65,7 @@ use str::StrSlice; use to_str::ToStr; use uint; use vec; -use vec::{OwnedVector, OwnedCopyableVector}; +use vec::{OwnedVector, OwnedCopyableVector, CopyableVector}; #[allow(non_camel_case_types)] // not sure what to do about this pub type fd_t = c_int; @@ -698,7 +698,7 @@ impl ReaderUtil for T { // over-read by reading 1-byte per char needed nbread = if ncreq > nbreq { ncreq } else { nbreq }; if nbread > 0 { - bytes = vec::slice(bytes, offset, bytes.len()).to_vec(); + bytes = vec::slice(bytes, offset, bytes.len()).to_owned(); } } chars diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index eefad1a03dcb..57f23d8e657c 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -22,7 +22,7 @@ use iter::{FromIter, Times}; use num::{Zero, One}; use option::{Option, Some, None}; use ops::{Add, Mul}; -use cmp::Ord; +use cmp::{Ord, Eq}; use clone::Clone; /// An interface for dealing with "external iterators". These types of iterators @@ -273,6 +273,7 @@ pub trait IteratorUtil { /// ~~~ fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; + // FIXME: #5898: should be called len /// Counts the number of elements in this iterator. /// /// # Example @@ -280,10 +281,10 @@ pub trait IteratorUtil { /// ~~~ {.rust} /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); - /// assert!(it.count() == 5); - /// assert!(it.count() == 0); + /// assert!(it.len_() == 5); + /// assert!(it.len_() == 0); /// ~~~ - fn count(&mut self) -> uint; + fn len_(&mut self) -> uint; /// Tests whether the predicate holds true for all elements in the iterator. /// @@ -314,6 +315,9 @@ pub trait IteratorUtil { /// Return the index of the first element satisfying the specified predicate 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; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -432,7 +436,7 @@ impl> IteratorUtil for T { /// Count the number of items yielded by an iterator #[inline] - fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } + fn len_(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } #[inline] fn all(&mut self, f: &fn(A) -> bool) -> bool { @@ -467,6 +471,15 @@ impl> IteratorUtil for T { } None } + + #[inline] + fn count(&mut self, predicate: &fn(A) -> bool) -> uint { + let mut i = 0; + for self.advance |x| { + if predicate(x) { i += 1 } + } + i + } } /// A trait for iterators over elements which can be added together @@ -1020,11 +1033,11 @@ mod tests { } #[test] - fn test_iterator_count() { + fn test_iterator_len() { let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - assert_eq!(v.slice(0, 4).iter().count(), 4); - assert_eq!(v.slice(0, 10).iter().count(), 10); - assert_eq!(v.slice(0, 0).iter().count(), 0); + assert_eq!(v.slice(0, 4).iter().len_(), 4); + assert_eq!(v.slice(0, 10).iter().len_(), 10); + assert_eq!(v.slice(0, 0).iter().len_(), 0); } #[test] @@ -1099,4 +1112,12 @@ mod tests { assert_eq!(v.iter().position_(|x| *x % 3 == 0).unwrap(), 1); assert!(v.iter().position_(|x| *x % 12 == 0).is_none()); } + + #[test] + fn test_count() { + let xs = &[1, 2, 2, 1, 5, 9, 0, 2]; + assert_eq!(xs.iter().count(|x| *x == 2), 3); + assert_eq!(xs.iter().count(|x| *x == 5), 1); + assert_eq!(xs.iter().count(|x| *x == 95), 0); + } } diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 83bb9eb09088..9b87d76a309d 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -16,7 +16,7 @@ #[allow(missing_doc)]; -use cmp::{Eq}; +use cmp::Eq; use kinds::Copy; use option::{None, Option, Some}; use vec; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 04f5247782b0..fd11b49a00a3 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1317,7 +1317,7 @@ impl<'self> StrSlice<'self> for &'self str { } /// Returns the number of characters that a string holds #[inline] - fn char_len(&self) -> uint { self.iter().count() } + fn char_len(&self) -> uint { self.iter().len_() } /** * Returns a slice of the given string from the byte range diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index f6b14a515397..0956b76c970a 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).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).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/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index d466488ce5e5..87bd25bdad32 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -350,7 +350,7 @@ pub mod ct { #[test] fn test_parse_flags() { fn pack(fs: &[Flag]) -> uint { - fs.foldl(0, |&p, &f| p | (1 << f as uint)) + fs.iter().fold(0, |p, &f| p | (1 << f as uint)) } fn test(s: &str, flags: &[Flag], next: uint) { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 0d5a84a4a76f..ad03d8fc4a0b 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -24,7 +24,6 @@ use iter::FromIter; use kinds::Copy; use libc; use num::Zero; -use old_iter::CopyableIter; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; @@ -324,12 +323,12 @@ pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i).to_vec()); + result.push(slice(v, start, i).to_owned()); start = i + 1u; } } } - result.push(slice(v, start, ln).to_vec()); + result.push(slice(v, start, ln).to_owned()); result } @@ -348,14 +347,14 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i).to_vec()); + result.push(slice(v, start, i).to_owned()); // Make sure to skip the separator. start = i + 1u; count -= 1u; } } } - result.push(slice(v, start, ln).to_vec()); + result.push(slice(v, start, ln).to_owned()); result } @@ -373,12 +372,12 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1, end).to_vec()); + result.push(slice(v, i + 1, end).to_owned()); end = i; } } } - result.push(slice(v, 0u, end).to_vec()); + result.push(slice(v, 0u, end).to_owned()); reverse(result); result } @@ -398,14 +397,14 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0u, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1u, end).to_vec()); + result.push(slice(v, i + 1u, end).to_owned()); // Make sure to skip the separator. end = i; count -= 1u; } } } - result.push(slice(v, 0u, end).to_vec()); + result.push(slice(v, 0u, end).to_owned()); reverse(result); result } @@ -1792,7 +1791,6 @@ pub trait ImmutableVector<'self, T> { fn initn(&self, n: uint) -> &'self [T]; fn last(&self) -> &'self T; fn last_opt(&self) -> Option<&'self T>; - fn position(&self, f: &fn(t: &T) -> bool) -> Option; fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; @@ -1860,18 +1858,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { #[inline] fn last_opt(&self) -> Option<&'self T> { last_opt(*self) } - /** - * Find the first index matching some predicate - * - * Apply function `f` to each element of `v`. When function `f` returns - * true then an option containing the index is returned. If `f` matches no - * elements then none is returned. - */ - #[inline] - fn position(&self, f: &fn(t: &T) -> bool) -> Option { - position(*self, f) - } - /** * Find the last index matching some predicate * @@ -2434,9 +2420,6 @@ pub mod bytes { } } -// ___________________________________________________________________________ -// ITERATION TRAIT METHODS - impl<'self,A> old_iter::BaseIter for &'self [A] { #[inline] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { @@ -2446,152 +2429,6 @@ impl<'self,A> old_iter::BaseIter for &'self [A] { fn size_hint(&self) -> Option { Some(self.len()) } } -// FIXME(#4148): This should be redundant -impl old_iter::BaseIter for ~[A] { - #[inline] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { - each(*self, blk) - } - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } -} - -// FIXME(#4148): This should be redundant -impl old_iter::BaseIter for @[A] { - #[inline] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { - each(*self, blk) - } - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } -} - -impl<'self,A> old_iter::ExtendedIter for &'self [A] { - pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { - old_iter::eachi(self, blk) - } - pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::all(self, blk) - } - pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::any(self, blk) - } - pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - old_iter::foldl(self, b0, blk) - } - pub fn position(&self, f: &fn(&A) -> bool) -> Option { - old_iter::position(self, f) - } - fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { - old_iter::map_to_vec(self, op) - } - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) - -> ~[B] { - old_iter::flat_map_to_vec(self, op) - } -} - -// FIXME(#4148): This should be redundant -impl old_iter::ExtendedIter for ~[A] { - pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { - old_iter::eachi(self, blk) - } - pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::all(self, blk) - } - pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::any(self, blk) - } - pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - old_iter::foldl(self, b0, blk) - } - pub fn position(&self, f: &fn(&A) -> bool) -> Option { - old_iter::position(self, f) - } - fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { - old_iter::map_to_vec(self, op) - } - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) - -> ~[B] { - old_iter::flat_map_to_vec(self, op) - } -} - -// FIXME(#4148): This should be redundant -impl old_iter::ExtendedIter for @[A] { - pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool { - old_iter::eachi(self, blk) - } - pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::all(self, blk) - } - pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::any(self, blk) - } - pub fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - old_iter::foldl(self, b0, blk) - } - pub fn position(&self, f: &fn(&A) -> bool) -> Option { - old_iter::position(self, f) - } - fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { - old_iter::map_to_vec(self, op) - } - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) - -> ~[B] { - old_iter::flat_map_to_vec(self, op) - } -} - -impl<'self,A:Eq> old_iter::EqIter for &'self [A] { - pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } -} - -// FIXME(#4148): This should be redundant -impl old_iter::EqIter for ~[A] { - pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } -} - -// FIXME(#4148): This should be redundant -impl old_iter::EqIter for @[A] { - pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } -} - -impl<'self,A:Copy> old_iter::CopyableIter for &'self [A] { - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - old_iter::filter_to_vec(self, pred) - } - fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } - pub fn find(&self, f: &fn(&A) -> bool) -> Option { - old_iter::find(self, f) - } -} - -// FIXME(#4148): This should be redundant -impl old_iter::CopyableIter for ~[A] { - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - old_iter::filter_to_vec(self, pred) - } - fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } - pub fn find(&self, f: &fn(&A) -> bool) -> Option { - old_iter::find(self, f) - } -} - -// FIXME(#4148): This should be redundant -impl old_iter::CopyableIter for @[A] { - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - old_iter::filter_to_vec(self, pred) - } - fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } - pub fn find(&self, f: &fn(&A) -> bool) -> Option { - old_iter::find(self, f) - } -} - impl Clone for ~[A] { #[inline] fn clone(&self) -> ~[A] { @@ -2916,7 +2753,7 @@ mod tests { fn test_slice() { // Test fixed length vector. let vec_fixed = [1, 2, 3, 4]; - let v_a = slice(vec_fixed, 1u, vec_fixed.len()).to_vec(); + let v_a = slice(vec_fixed, 1u, vec_fixed.len()).to_owned(); assert_eq!(v_a.len(), 3u); assert_eq!(v_a[0], 2); assert_eq!(v_a[1], 3); @@ -2924,14 +2761,14 @@ mod tests { // Test on stack. let vec_stack = &[1, 2, 3]; - let v_b = slice(vec_stack, 1u, 3u).to_vec(); + let v_b = slice(vec_stack, 1u, 3u).to_owned(); assert_eq!(v_b.len(), 2u); assert_eq!(v_b[0], 2); assert_eq!(v_b[1], 3); // Test on managed heap. let vec_managed = @[1, 2, 3, 4, 5]; - let v_c = slice(vec_managed, 0u, 3u).to_vec(); + let v_c = slice(vec_managed, 0u, 3u).to_owned(); assert_eq!(v_c.len(), 3u); assert_eq!(v_c[0], 1); assert_eq!(v_c[1], 2); @@ -2939,7 +2776,7 @@ mod tests { // Test on exchange heap. let vec_unique = ~[1, 2, 3, 4, 5, 6]; - let v_d = slice(vec_unique, 1u, 6u).to_vec(); + let v_d = slice(vec_unique, 1u, 6u).to_owned(); assert_eq!(v_d.len(), 5u); assert_eq!(v_d[0], 2); assert_eq!(v_d[1], 3); diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 53729dbd1157..943a38a337ff 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -211,7 +211,7 @@ impl AbiSet { let mut abis = ~[]; for self.each |abi| { abis.push(abi); } - for abis.eachi |i, abi| { + for abis.iter().enumerate().advance |(i, abi)| { let data = abi.data(); for abis.slice(0, i).each |other_abi| { let other_data = other_abi.data(); @@ -374,7 +374,7 @@ fn abi_to_str_rust() { #[test] fn indices_are_correct() { - for AbiDatas.eachi |i, abi_data| { + for AbiDatas.iter().enumerate().advance |(i, abi_data)| { assert!(i == abi_data.abi.index()); } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index e096711262fb..96e05fd2beb4 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -194,7 +194,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.each |mi| { - if !misb.contains(mi) { return false; } + if !misb.iter().any_(|x| x == mi) { return false; } } true } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index e67ca5260b8f..249c1c79a377 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -246,7 +246,7 @@ fn highlight_lines(cm: @codemap::CodeMap, let mut elided = false; let mut display_lines = /* FIXME (#2543) */ copy lines.lines; if display_lines.len() > max_lines { - display_lines = vec::slice(display_lines, 0u, max_lines).to_vec(); + display_lines = vec::slice(display_lines, 0u, max_lines).to_owned(); elided = true; } // Print the offending lines diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index bfb234106b8b..e7fb15fbd51c 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -20,7 +20,7 @@ use parse::token::{str_to_ident}; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult { let mut res_str = ~""; - for tts.eachi |i, e| { + for tts.iter().enumerate().advance |(i, e)| { if i & 1 == 1 { match *e { ast::tt_tok(_, token::COMMA) => (), diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index abea7912fc8b..7d17f436a41d 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -111,7 +111,7 @@ fn decodable_substructure(cx: @ExtCtxt, span: span, let mut variants = ~[]; let rvariant_arg = cx.ident_of("read_enum_variant_arg"); - for fields.eachi |i, f| { + for fields.iter().enumerate().advance |(i, f)| { let (name, parts) = match *f { (i, ref p) => (i, p) }; variants.push(cx.expr_str(span, cx.str_of(name))); diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index d7e64caa5c87..2b73dc24d33a 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -124,7 +124,7 @@ fn encodable_substructure(cx: @ExtCtxt, span: span, Struct(ref fields) => { let emit_struct_field = cx.ident_of("emit_struct_field"); let mut stmts = ~[]; - for fields.eachi |i, f| { + for fields.iter().enumerate().advance |(i, f)| { let (name, val) = match *f { (Some(id), e, _) => (cx.str_of(id), e), (None, e, _) => (fmt!("_field%u", i).to_managed(), e) @@ -155,7 +155,7 @@ fn encodable_substructure(cx: @ExtCtxt, span: span, let encoder = cx.expr_ident(span, blkarg); let emit_variant_arg = cx.ident_of("emit_enum_variant_arg"); let mut stmts = ~[]; - for fields.eachi |i, f| { + for fields.iter().enumerate().advance |(i, f)| { let val = match *f { (_, e, _) => e }; let enc = cx.expr_method_call(span, val, encode, ~[blkencoder]); let lambda = cx.lambda_expr_1(span, enc, blkarg); diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 22ce305b8575..d44d46682994 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -487,7 +487,7 @@ impl<'self> MethodDef<'self> { None => respan(span, ast::sty_static), }; - for self.args.eachi |i, ty| { + for self.args.iter().enumerate().advance |(i, ty)| { let ast_ty = ty.to_ty(cx, span, type_ident, generics); let ident = cx.ident_of(fmt!("__arg_%u", i)); arg_tys.push((ident, ast_ty)); @@ -741,7 +741,7 @@ impl<'self> MethodDef<'self> { let mut enum_matching_fields = vec::from_elem(self_vec.len(), ~[]); for matches_so_far.tail().each |&(_, _, other_fields)| { - for other_fields.eachi |i, &(_, other_field)| { + for other_fields.iter().enumerate().advance |(i, &(_, other_field))| { enum_matching_fields[i].push(other_field); } } @@ -809,7 +809,7 @@ impl<'self> MethodDef<'self> { } } else { // create an arm matching on each variant - for enum_def.variants.eachi |index, variant| { + for enum_def.variants.iter().enumerate().advance |(index, variant)| { let (pattern, idents) = create_enum_variant_pattern(cx, span, variant, current_match_str, @@ -923,7 +923,7 @@ fn create_struct_pattern(cx: @ExtCtxt, let mut ident_expr = ~[]; let mut struct_type = Unknown; - for struct_def.fields.eachi |i, struct_field| { + for struct_def.fields.iter().enumerate().advance |(i, struct_field)| { let opt_id = match struct_field.node.kind { ast::named_field(ident, _) if (struct_type == Unknown || struct_type == Record) => { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2e7e8240bc0d..f6504e85b43b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -200,7 +200,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.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 @@ -425,8 +425,8 @@ fn renames_to_fold(renames : @mut ~[(ast::ident,ast::Name)]) -> @ast_fold { fold_ident: |id,_| { // the individual elements are memoized... it would // also be possible to memoize on the whole list at once. - let new_ctxt = renames.foldl(id.ctxt,|ctxt,&(from,to)| { - new_rename(from,to,*ctxt) + let new_ctxt = renames.iter().fold(id.ctxt,|ctxt,&(from,to)| { + new_rename(from,to,ctxt) }); ast::ident{name:id.name,ctxt:new_ctxt} }, diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 1076c5d0b98f..8b044bd14e11 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -47,13 +47,13 @@ use extra::bitv::Bitv; pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) { debug!("initializing colive analysis"); let num_states = proto.num_states(); - let mut colive = do (copy proto.states).map_to_vec |state| { + let mut colive: ~[~Bitv] = do (copy proto.states).iter().transform() |state| { let mut bv = ~Bitv::new(num_states, false); for state.reachable |s| { bv.set(s.id, true); } bv - }; + }.collect(); let mut i = 0; let mut changed = true; @@ -61,7 +61,7 @@ pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) { changed = false; debug!("colive iteration %?", i); let mut new_colive = ~[]; - for colive.eachi |i, this_colive| { + for colive.iter().enumerate().advance |(i, this_colive)| { let mut result = this_colive.clone(); let this = proto.get_state_by_id(i); for this_colive.ones |j| { @@ -80,7 +80,7 @@ pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) { // Determine if we're bounded let mut self_live = ~[]; - for colive.eachi |i, bv| { + for colive.iter().enumerate().advance |(i, bv)| { if bv.get(i) { self_live.push(proto.get_state_by_id(i)) } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 9adbbb7d7f3e..083386fe720c 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -333,14 +333,14 @@ impl gen_init for protocol { dummy_sp(), path(~[ext_cx.ident_of("__Buffer")], dummy_sp()), - self.states.map_to_vec(|s| { + self.states.iter().transform(|s| { let fty = s.to_ty(ext_cx); ext_cx.field_imm(dummy_sp(), ext_cx.ident_of(s.name), quote_expr!( ::std::pipes::mk_packet::<$fty>() )) - })) + }).collect()) } fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr { @@ -354,10 +354,10 @@ impl gen_init for protocol { let entangle_body = ext_cx.expr_blk( ext_cx.blk( dummy_sp(), - self.states.map_to_vec( + self.states.iter().transform( |s| ext_cx.parse_stmt( fmt!("data.%s.set_buffer(buffer)", - s.name).to_managed())), + s.name).to_managed())).collect(), Some(ext_cx.parse_expr(fmt!( "::std::ptr::to_mut_unsafe_ptr(&mut (data.%s))", self.states[0].name).to_managed())))); @@ -390,7 +390,7 @@ impl gen_init for protocol { 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).map_to_vec |s| { + let fields = do (copy self.states).iter().transform |s| { for s.generics.ty_params.each |tp| { match params.find(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), @@ -411,7 +411,7 @@ impl gen_init for protocol { }, span: dummy_sp() } - }; + }.collect(); let generics = Generics { lifetimes: opt_vec::Empty, diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 32714f372726..3df19ed0a76e 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -146,13 +146,13 @@ pub struct protocol_ { impl protocol_ { /// Get a state. pub fn get_state(&self, name: &str) -> state { - self.states.find(|i| name == i.name).get() + *self.states.iter().find_(|i| name == i.name).get() } pub fn get_state_by_id(&self, id: uint) -> state { self.states[id] } pub fn has_state(&self, name: &str) -> bool { - self.states.find(|i| name == i.name).is_some() + self.states.iter().find_(|i| name == i.name).is_some() } pub fn filename(&self) -> ~str { @@ -216,12 +216,12 @@ pub fn visit>( proto: protocol, visitor: V) -> Tproto { // the copy keywords prevent recursive use of dvec - let states = do (copy proto.states).map_to_vec |&s| { - let messages = do (copy s.messages).map_to_vec |&m| { + let states: ~[Tstate] = do (copy proto.states).iter().transform |&s| { + let messages: ~[Tmessage] = do (copy s.messages).iter().transform |&m| { let message(name, span, tys, this, next) = m; visitor.visit_message(name, span, tys, this, next) - }; + }.collect(); visitor.visit_state(s, messages) - }; + }.collect(); visitor.visit_proto(proto, states) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 7cca7162fc86..2b65e6599f66 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -94,7 +94,7 @@ pub fn add_new_extension(cx: @ExtCtxt, let s_d = cx.parse_sess().span_diagnostic; - for lhses.eachi |i, lhs| { // try each arm's matchers + for lhses.iter().enumerate().advance |(i, lhs)| { // try each arm's matchers match *lhs { @matched_nonterminal(nt_matchers(ref mtcs)) => { // `none` is because we're not interpolating diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e72d9b502dcd..d73c5240a1c0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -592,7 +592,7 @@ pub fn print_item(s: @ps, item: @ast::item) { print_generics(s, generics); if traits.len() != 0u { word(s.s, ":"); - for traits.eachi |i, trait_| { + for traits.iter().enumerate().advance |(i, trait_)| { nbsp(s); if i != 0 { word_space(s, "+"); @@ -758,7 +758,7 @@ pub fn print_tt(s: @ps, tt: &ast::token_tree) { pub fn print_tts(s: @ps, tts: &[ast::token_tree]) { ibox(s, 0); - for tts.eachi |i, tt| { + for tts.iter().enumerate().advance |(i, tt)| { if i != 0 { space(s.s); } @@ -1229,7 +1229,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { space(s.s); bopen(s); let len = arms.len(); - for arms.eachi |i, arm| { + for arms.iter().enumerate().advance |(i, arm)| { space(s.s); cbox(s, indent_unit); ibox(s, 0u); diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 287daf68effb..4b5880de8a52 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.contains(&~"all") || argv.contains(&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 8b7f5829cbeb..a2edc1efa66a 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -378,7 +378,7 @@ fn validate(edges: ~[(node_id, node_id)], info!(~"Verifying graph edges..."); - let status = do edges.all() |e| { + let status = do edges.iter().all |e| { let (u, v) = *e; abs(level[u] - level[v]) <= 1 @@ -402,7 +402,7 @@ fn validate(edges: ~[(node_id, node_id)], if *v == -1i64 || u == root { true } else { - edges.contains(&(u, *v)) || edges.contains(&(*v, u)) + edges.iter().any_(|x| x == &(u, *v)) || edges.iter().any_(|x| x == &(*v, u)) } }; result diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index e12df5811eee..81a3482b4f88 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -90,7 +90,7 @@ fn find(mm: &HashMap<~[u8], uint>, key: ~str) -> uint { // given a map, increment the counter for a key fn update_freq(mm: &mut HashMap<~[u8], uint>, key: &[u8]) { - let key = vec::slice(key, 0, key.len()).to_vec(); + let key = vec::slice(key, 0, key.len()).to_owned(); let newval = match mm.pop(&key) { Some(v) => v + 1, None => 1 @@ -111,7 +111,7 @@ fn windows_with_carry(bb: &[u8], nn: uint, ii += 1u; } - return vec::slice(bb, len - (nn - 1u), len).to_vec(); + return vec::slice(bb, len - (nn - 1u), len).to_owned(); } fn make_sequence_processor(sz: uint, @@ -211,7 +211,7 @@ fn main() { (_, true) => { let line_bytes = line.as_bytes(); - for sizes.eachi |ii, _sz| { + for sizes.iter().enumerate().advance |(ii, _sz)| { let mut lb = line_bytes.to_owned(); to_child[ii].send(lb); } @@ -223,12 +223,12 @@ fn main() { } // finish... - for sizes.eachi |ii, _sz| { + for sizes.iter().enumerate().advance |(ii, _sz)| { to_child[ii].send(~[]); } // now fetch and print result messages - for sizes.eachi |ii, _sz| { + for sizes.iter().enumerate().advance |(ii, _sz)| { io::println(from_child[ii].recv()); } } diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 95139239517a..534df512a481 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -10,7 +10,7 @@ fn A(i: i32, j: i32) -> i32 { fn dot(v: &[f64], u: &[f64]) -> f64 { let mut sum = 0.0; - for v.eachi |i, &v_i| { + for v.iter().enumerate().advance |(i, &v_i)| { sum += v_i * u[i]; } sum diff --git a/src/test/run-pass/deriving-cmp-generic-enum.rs b/src/test/run-pass/deriving-cmp-generic-enum.rs index e3cca832b75e..e5cf15367719 100644 --- a/src/test/run-pass/deriving-cmp-generic-enum.rs +++ b/src/test/run-pass/deriving-cmp-generic-enum.rs @@ -25,8 +25,8 @@ pub fn main() { // in order for both Ord and TotalOrd let es = [e0, e11, e12, e21, e22]; - for es.eachi |i, e1| { - for es.eachi |j, e2| { + for es.iter().enumerate().advance |(i, e1)| { + for es.iter().enumerate().advance |(j, e2)| { let ord = i.cmp(&j); let eq = i == j; diff --git a/src/test/run-pass/deriving-cmp-generic-struct.rs b/src/test/run-pass/deriving-cmp-generic-struct.rs index 4e49ecb8991f..426bfd7eb2f1 100644 --- a/src/test/run-pass/deriving-cmp-generic-struct.rs +++ b/src/test/run-pass/deriving-cmp-generic-struct.rs @@ -21,8 +21,8 @@ pub fn main() { // in order for both Ord and TotalOrd let ss = [s1, s2]; - for ss.eachi |i, s1| { - for ss.eachi |j, s2| { + for ss.iter().enumerate().advance |(i, s1)| { + for ss.iter().enumerate().advance |(j, s2)| { let ord = i.cmp(&j); let eq = i == j; diff --git a/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs b/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs index f119b8b1c48e..0acebdf05f4e 100644 --- a/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs +++ b/src/test/run-pass/deriving-cmp-generic-tuple-struct.rs @@ -19,8 +19,8 @@ pub fn main() { // in order for both Ord and TotalOrd let tss = [ts1, ts2]; - for tss.eachi |i, ts1| { - for tss.eachi |j, ts2| { + for tss.iter().enumerate().advance |(i, ts1)| { + for tss.iter().enumerate().advance |(j, ts2)| { let ord = i.cmp(&j); let eq = i == j; diff --git a/src/test/run-pass/issue-2611.rs b/src/test/run-pass/issue-2611.rs deleted file mode 100644 index d7508bca41e1..000000000000 --- a/src/test/run-pass/issue-2611.rs +++ /dev/null @@ -1,24 +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. - -use std::old_iter::BaseIter; -use std::old_iter; - -trait FlatMapToVec { - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; -} - -impl FlatMapToVec for ~[A] { - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { - old_iter::flat_map_to_vec(self, op) - } -} - -pub fn main() {} diff --git a/src/test/run-pass/vec-position.rs b/src/test/run-pass/vec-position.rs deleted file mode 100644 index aaf232f20465..000000000000 --- a/src/test/run-pass/vec-position.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -pub fn main() { - let mut v = ~[1, 2, 3]; - assert!(v.position(|x| *x == 1) == Some(0)); - assert!(v.position(|x| *x == 3) == Some(2)); - assert!(v.position(|x| *x == 17) == None); -} From 883c966d5c6ba93bf8834543500b01f644ab362f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 18 Jun 2013 22:59:48 -0400 Subject: [PATCH 036/336] vec: replace `position` with `iter().position_` --- src/libextra/getopts.rs | 2 +- src/libextra/json.rs | 2 +- src/librustc/middle/trans/common.rs | 3 +- src/librustc/middle/trans/expr.rs | 3 +- src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/check/method.rs | 7 ++-- src/libstd/iterator.rs | 2 +- src/libstd/vec.rs | 46 ++-------------------- 8 files changed, 13 insertions(+), 54 deletions(-) diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 05649104c316..5980bd7c9e47 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -177,7 +177,7 @@ fn name_str(nm: &Name) -> ~str { } fn find_opt(opts: &[Opt], nm: Name) -> Option { - vec::position(opts, |opt| opt.name == nm) + opts.iter().position_(|opt| opt.name == nm) } /** diff --git a/src/libextra/json.rs b/src/libextra/json.rs index db95327f0aac..0bbccd4df4a0 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -950,7 +950,7 @@ impl serialize::Decoder for Decoder { } ref json => fail!("invalid variant: %?", *json), }; - let idx = match vec::position(names, |n| str::eq_slice(*n, name)) { + let idx = match names.iter().position_(|n| str::eq_slice(*n, name)) { Some(idx) => idx, None => fail!("Unknown variant name: %?", name), }; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index fc79c8c23d45..e9a0d42f29b9 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -468,8 +468,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { pub fn revoke_clean(cx: block, val: ValueRef) { do in_scope_cx(cx) |scope_info| { let scope_info = &mut *scope_info; // FIXME(#5074) workaround borrowck - let cleanup_pos = vec::position( - scope_info.cleanups, + let cleanup_pos = scope_info.cleanups.iter().position_( |cu| match *cu { clean_temp(v, _, _) if v == val => true, _ => false diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 3cbbd61aed6f..d1467edd94d5 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1152,8 +1152,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 = vec::position(field_tys, |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; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a4702808746e..2340ffc76b38 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3372,7 +3372,7 @@ pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field]) } pub fn method_idx(id: ast::ident, meths: &[@Method]) -> Option { - vec::position(meths, |m| m.ident == id) + meths.iter().position_(|m| m.ident == id) } /// Returns a vector containing the indices of all type parameters that appear diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index bdf88cb6df44..2b7f7d0f77c6 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -420,7 +420,7 @@ impl<'self> LookupContext<'self> { let tcx = self.tcx(); let ms = ty::trait_methods(tcx, did); - let index = match vec::position(*ms, |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 }; @@ -474,7 +474,7 @@ impl<'self> LookupContext<'self> { // First, try self methods let mut method_info: Option = None; let methods = ty::trait_methods(tcx, did); - match vec::position(*methods, |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], @@ -489,8 +489,7 @@ impl<'self> LookupContext<'self> { for ty::trait_supertraits(tcx, did).each() |trait_ref| { let supertrait_methods = ty::trait_methods(tcx, trait_ref.def_id); - match vec::position(*supertrait_methods, - |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], diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 57f23d8e657c..394066f1d4cf 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -22,7 +22,7 @@ use iter::{FromIter, Times}; use num::{Zero, One}; use option::{Option, Some, None}; use ops::{Add, Mul}; -use cmp::{Ord, Eq}; +use cmp::Ord; use clone::Clone; /// An interface for dealing with "external iterators". These types of iterators diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index ad03d8fc4a0b..ce5662c6d4b3 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -19,7 +19,7 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use old_iter::BaseIter; use old_iter; -use iterator::{Iterator}; +use iterator::{Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; use libc; @@ -1107,18 +1107,7 @@ pub fn rfind_between(v: &[T], /// Find the first index containing a matching value pub fn position_elem(v: &[T], x: &T) -> Option { - position(v, |y| *x == *y) -} - -/** - * Find the first index matching some predicate - * - * Apply function `f` to each element of `v`. When function `f` returns true - * then an option containing the index is returned. If `f` matches no elements - * then none is returned. - */ -pub fn position(v: &[T], f: &fn(t: &T) -> bool) -> Option { - position_between(v, 0u, v.len(), f) + v.iter().position_(|y| *x == *y) } /** @@ -3146,18 +3135,6 @@ mod tests { assert!(position_elem(v1, &4).is_none()); } - #[test] - fn test_position() { - fn less_than_three(i: &int) -> bool { *i < 3 } - fn is_eighteen(i: &int) -> bool { *i == 18 } - - assert!(position([], less_than_three).is_none()); - - let v1 = ~[5, 4, 3, 2, 1]; - assert_eq!(position(v1, less_than_three), Some(3u)); - assert!(position(v1, is_eighteen).is_none()); - } - #[test] fn test_position_between() { assert!(position_between([], 0u, 0u, f).is_none()); @@ -3234,8 +3211,8 @@ mod tests { fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - assert_eq!(position(v, f), Some(1u)); - assert!(position(v, g).is_none()); + assert_eq!(rposition(v, f), Some(3u)); + assert!(rposition(v, g).is_none()); } #[test] @@ -3877,21 +3854,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_position_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do position(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - false - }; - } - #[test] #[ignore(windows)] #[should_fail] From 06bec77fafb1c30052b9c69a3fb17b2835cb608f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 19 Jun 2013 18:56:57 -0400 Subject: [PATCH 037/336] replace vec::find with the IteratorUtil method --- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/trans/monomorphize.rs | 2 +- src/librustc/middle/ty.rs | 5 +-- src/librustc/middle/typeck/check/mod.rs | 2 +- src/librustdoc/attr_pass.rs | 2 +- src/librustdoc/config.rs | 9 +++-- src/librustdoc/tystr_pass.rs | 8 ++--- src/libstd/str.rs | 2 +- src/libstd/vec.rs | 41 ----------------------- 9 files changed, 16 insertions(+), 57 deletions(-) diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 4da88981a635..346e2162385c 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -456,7 +456,7 @@ pub fn ctor_arity(cx: @MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint { ty::ty_enum(eid, _) => { let id = match *ctor { variant(id) => id, _ => fail!("impossible case") }; - match vec::find(*ty::enum_variants(cx.tcx, eid), |v| v.id == id ) { + match ty::enum_variants(cx.tcx, eid).iter().find_(|v| v.id == id ) { Some(v) => v.args.len(), None => fail!("impossible case") } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 368ad0674e1e..f082150e3949 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -209,7 +209,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } ast_map::node_variant(ref v, enum_item, _) => { let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id)); - let this_tv = vec::find(*tvs, |tv| { tv.id.node == fn_id.node}).get(); + let this_tv = *tvs.iter().find_(|tv| { tv.id.node == fn_id.node}).get(); let d = mk_lldecl(); set_inline_hint(d); match v.node.kind { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 2340ffc76b38..8595adcd1c73 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4128,9 +4128,10 @@ pub fn lookup_struct_field(cx: ctxt, parent: ast::def_id, field_id: ast::def_id) -> field_ty { - match vec::find(lookup_struct_fields(cx, parent), + let r = lookup_struct_fields(cx, parent); + match r.iter().find_( |f| f.id.node == field_id.node) { - Some(t) => t, + Some(t) => *t, None => cx.sess.bug("struct ID not found in parent's fields") } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 2d8233f8c0aa..13ded5016793 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1107,7 +1107,7 @@ pub fn lookup_field_ty(tcx: ty::ctxt, fieldname: ast::ident, substs: &ty::substs) -> Option { - let o_field = vec::find(items, |f| f.ident == fieldname); + let o_field = items.iter().find_(|f| f.ident == fieldname); do o_field.map() |f| { ty::lookup_field_type(tcx, class_id, f.id, substs) } diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index a1dad7d17f8e..1c34007c99d4 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -135,7 +135,7 @@ fn fold_enum( node: ast::item_enum(ref enum_definition, _), _ }, _) => { let ast_variant = - vec::find(enum_definition.variants, |v| { + copy *enum_definition.variants.iter().find_(|v| { to_str(v.node.name) == variant.name }).get(); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ef65cc8e5a1b..84a194627fb5 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -230,16 +230,15 @@ pub fn maybe_find_pandoc( } }; - let pandoc = do vec::find(possible_pandocs) |pandoc| { + let pandoc = do possible_pandocs.iter().find_ |&pandoc| { let output = process_output(*pandoc, [~"--version"]); debug!("testing pandoc cmd %s: %?", *pandoc, output); output.status == 0 }; - if pandoc.is_some() { - result::Ok(pandoc) - } else { - result::Err(~"couldn't find pandoc") + match pandoc { + Some(x) => Ok(Some(copy *x)), // ugly, shouldn't be doubly wrapped + None => Err(~"couldn't find pandoc") } } diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index 82336addb62f..e3abe6e926a5 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -124,7 +124,7 @@ fn fold_enum( node: ast::item_enum(ref enum_definition, _), _ }, _) => { let ast_variant = - do vec::find(enum_definition.variants) |v| { + copy *do enum_definition.variants.iter().find_ |v| { to_str(v.node.name) == variant.name }.get(); @@ -178,14 +178,14 @@ fn get_method_sig( ast_map::node_item(@ast::item { node: ast::item_trait(_, _, ref methods), _ }, _) => { - match vec::find(*methods, |method| { + match methods.iter().find_(|&method| { match copy *method { ast::required(ty_m) => to_str(ty_m.ident) == method_name, ast::provided(m) => to_str(m.ident) == method_name, } }) { Some(method) => { - match method { + match copy *method { ast::required(ty_m) => { Some(pprust::fun_to_str( &ty_m.decl, @@ -214,7 +214,7 @@ fn get_method_sig( ast_map::node_item(@ast::item { node: ast::item_impl(_, _, _, ref methods), _ }, _) => { - match vec::find(*methods, |method| { + match methods.iter().find_(|method| { to_str(method.ident) == method_name }) { Some(method) => { diff --git a/src/libstd/str.rs b/src/libstd/str.rs index fd11b49a00a3..f3226b27d1be 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -60,7 +60,7 @@ pub fn from_bytes(vv: &[u8]) -> ~str { use str::not_utf8::cond; if !is_utf8(vv) { - let first_bad_byte = vec::find(vv, |b| !is_utf8([*b])).get(); + let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get(); cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u", first_bad_byte as uint)) } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index ce5662c6d4b3..703224e37c57 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1056,17 +1056,6 @@ pub fn contains(v: &[T], x: &T) -> bool { false } -/** - * Search for the first element that matches a given predicate - * - * Apply function `f` to each element of `v`, starting from the first. - * When function `f` returns true then an option containing the element - * is returned. If `f` matches no elements then none is returned. - */ -pub fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { - find_between(v, 0u, v.len(), f) -} - /** * Search for the first element that matches a given predicate within a range * @@ -3163,18 +3152,6 @@ mod tests { assert!(position_between(v, 4u, 4u, f).is_none()); } - #[test] - fn test_find() { - assert!(find([], f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert_eq!(find(v, f), Some((1, 'b'))); - assert!(find(v, g).is_none()); - } - #[test] fn test_find_between() { assert!(find_between([], 0u, 0u, f).is_none()); @@ -3205,8 +3182,6 @@ mod tests { #[test] fn test_rposition() { - assert!(find([], f).is_none()); - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; @@ -3838,22 +3813,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_find_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do find(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - false - }; - } - #[test] #[ignore(windows)] #[should_fail] From 4fb2c09541a5cb7ea91785a9c972ee57ff110c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 20 Jun 2013 16:42:44 +0200 Subject: [PATCH 038/336] Avoid pointless allocas for "nil" return values By using "void" instead of "{}" as the LLVM type for nil, we can avoid the alloca/store/load sequence for the return value, resulting in less and simpler IR code. This reduces compile times by about 10%. --- src/librustc/middle/trans/base.rs | 9 +++++---- src/librustc/middle/trans/cabi.rs | 24 +++++++++++++----------- src/librustc/middle/trans/cabi_x86.rs | 5 +++++ src/librustc/middle/trans/closure.rs | 5 ++++- src/librustc/middle/trans/controlflow.rs | 13 ++++++++----- src/librustc/middle/trans/foreign.rs | 18 +++++++++++------- src/librustc/middle/trans/type_of.rs | 6 +++--- 7 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d7d21707f40f..26d2df2e4795 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1653,7 +1653,9 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, fcx.llenv = unsafe { llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) }; - fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type)); + if !ty::type_is_nil(substd_output_type) { + fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type)); + } fcx } @@ -1808,7 +1810,7 @@ pub fn build_return_block(fcx: fn_ctxt) { let ret_cx = raw_block(fcx, false, fcx.llreturn); // Return the value if this function immediate; otherwise, return void. - if fcx.has_immediate_return_value { + if fcx.llretptr.is_some() && fcx.has_immediate_return_value { Ret(ret_cx, Load(ret_cx, fcx.llretptr.get())) } else { RetVoid(ret_cx) @@ -2340,8 +2342,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, llvm::LLVMGetParam(llfdecl, env_arg as c_uint) }; let args = ~[llenvarg]; - let llresult = Call(bcx, main_llfn, args); - Store(bcx, llresult, fcx.llretptr.get()); + Call(bcx, main_llfn, args); build_return(bcx); finish_fn(fcx, lltop); diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index acc3293f2678..373980569c34 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -179,16 +179,18 @@ impl FnType { } } - let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]); - let llretval = if self.ret_ty.cast { - let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty)); - Load(bcx, retptr) - } else { - Load(bcx, llretval) - }; - let llretptr = BitCast(bcx, - bcx.fcx.llretptr.get(), - T_ptr(self.ret_ty.ty)); - Store(bcx, llretval, llretptr); + if bcx.fcx.llretptr.is_some() { + let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]); + let llretval = if self.ret_ty.cast { + let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty)); + Load(bcx, retptr) + } else { + Load(bcx, llretval) + }; + let llretptr = BitCast(bcx, + bcx.fcx.llretptr.get(), + T_ptr(self.ret_ty.ty)); + Store(bcx, llretval, llretptr); + } } } diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 53af55bca6ca..da7c0d5272da 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -60,6 +60,11 @@ impl ABIInfo for X86_ABIInfo { cast: false, ty: T_void(), }; + } else if !ret_def { + ret_ty = LLVMType { + cast: false, + ty: T_void() + }; } return FnType { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index c368ab5c9bdf..a8ff0bf54faf 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -297,7 +297,10 @@ pub fn build_closure(bcx0: block, // the right thing): let ret_true = match bcx.fcx.loop_ret { Some((_, retptr)) => retptr, - None => bcx.fcx.llretptr.get() + None => match bcx.fcx.llretptr { + None => C_null(T_ptr(T_nil())), + Some(retptr) => retptr, + } }; let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(), diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index fe3e2940907b..55436e5946ef 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -298,24 +298,27 @@ pub fn trans_cont(bcx: block, label_opt: Option) -> block { pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { let _icx = bcx.insn_ctxt("trans_ret"); let mut bcx = bcx; - let retptr = match copy bcx.fcx.loop_ret { + let dest = match copy bcx.fcx.loop_ret { Some((flagptr, retptr)) => { // This is a loop body return. Must set continue flag (our retptr) // to false, return flag to true, and then store the value in the // parent's retptr. Store(bcx, C_bool(true), flagptr); Store(bcx, C_bool(false), bcx.fcx.llretptr.get()); - match e { + expr::SaveIn(match e { Some(x) => PointerCast(bcx, retptr, T_ptr(type_of(bcx.ccx(), expr_ty(bcx, x)))), None => retptr - } + }) + } + None => match bcx.fcx.llretptr { + None => expr::Ignore, + Some(retptr) => expr::SaveIn(retptr), } - None => bcx.fcx.llretptr.get() }; match e { Some(x) => { - bcx = expr::trans_into(bcx, x, expr::SaveIn(retptr)); + bcx = expr::trans_into(bcx, x, dest); } _ => () } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 40fa44d92ba4..9516a8b83ab3 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -127,7 +127,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { llsig: llsig, ret_def: ret_def, bundle_ty: bundle_ty, - shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_nil()), + shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_void()), fn_ty: fn_ty } } @@ -170,7 +170,7 @@ fn build_shim_fn_(ccx: @mut CrateContext, tie_up_header_blocks(fcx, lltop); let ret_cx = raw_block(fcx, false, fcx.llreturn); - Ret(ret_cx, C_null(T_nil())); + RetVoid(ret_cx); return llshimfn; } @@ -530,8 +530,10 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, store_inbounds(bcx, llargval, llargbundle, [0u, i]); } - let llretptr = bcx.fcx.llretptr.get(); - store_inbounds(bcx, llretptr, llargbundle, [0u, n]); + + for bcx.fcx.llretptr.iter().advance |&retptr| { + store_inbounds(bcx, retptr, llargbundle, [0u, n]); + } } fn build_ret(bcx: block, @@ -539,8 +541,10 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, llargbundle: ValueRef) { let _icx = bcx.insn_ctxt("foreign::wrap::build_ret"); let arg_count = shim_types.fn_sig.inputs.len(); - let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]); - Store(bcx, Load(bcx, llretptr), bcx.fcx.llretptr.get()); + for bcx.fcx.llretptr.iter().advance |&retptr| { + let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]); + Store(bcx, Load(bcx, llretptr), retptr); + } build_return(bcx); } } @@ -1294,7 +1298,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, shim_types: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - if ty::type_is_immediate(shim_types.fn_sig.output) { + if bcx.fcx.llretptr.is_some() && ty::type_is_immediate(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/type_of.rs b/src/librustc/middle/trans/type_of.rs index 268d60d44176..058a6b9f48ef 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -55,7 +55,7 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) atys.push_all(type_of_explicit_args(cx, inputs)); // Use the output as the actual return value if it's immediate. - if output_is_immediate { + if output_is_immediate && !ty::type_is_nil(output) { T_fn(atys, lloutputtype) } else { T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx)) @@ -352,7 +352,7 @@ pub fn llvm_type_name(cx: &CrateContext, } pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> TypeRef { - T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_nil()) + T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_void()) } pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef { @@ -364,5 +364,5 @@ pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef { pub fn type_of_glue_fn(ccx: &CrateContext) -> TypeRef { let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); - return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_nil()); + return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void()); } From f3966e4a08c17c1610a21e0b343f69369ad0eb31 Mon Sep 17 00:00:00 2001 From: Honza Strnad Date: Fri, 21 Jun 2013 21:27:58 +0200 Subject: [PATCH 039/336] Added filtered method for Option type --- src/libstd/option.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 80f4fb7643c8..894d29df5d71 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -159,6 +159,15 @@ impl Option { } } + /// Filters an optional value using given function. + #[inline(always)] + pub fn filtered<'a>(self, f: &fn(t: &'a T) -> bool) -> Option { + match self { + Some(x) => if(f(&x)) {Some(x)} else {None}, + None => None + } + } + /// Maps a `some` value from one type to another by reference #[inline(always)] pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option { @@ -459,3 +468,11 @@ fn test_get_or_zero() { let no_stuff: Option = None; assert_eq!(no_stuff.get_or_zero(), 0); } + +#[test] +fn test_filtered() { + let some_stuff = Some(42); + let modified_stuff = some_stuff.filtered(|&x| {x < 10}); + assert_eq!(some_stuff.get(), 42); + assert!(modified_stuff.is_none()); +} \ No newline at end of file From 116897fa6cba39ba43180debf0f9136be6a44205 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Fri, 21 Jun 2013 18:10:23 -0400 Subject: [PATCH 040/336] Remove `ast::pure_fn` and all concept of `pure` from the compiler --- src/librustc/metadata/decoder.rs | 14 +------------- src/librustc/metadata/encoder.rs | 2 -- src/librustc/metadata/tydecode.rs | 3 +-- src/librustc/metadata/tyencode.rs | 1 - src/librustc/middle/trans/reflect.rs | 1 - src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 2 +- src/librustc/middle/typeck/infer/glb.rs | 3 +-- src/librustc/middle/typeck/infer/lub.rs | 5 ++--- src/libsyntax/ast.rs | 2 -- src/libsyntax/print/pprust.rs | 25 ++++++++++++++----------- 11 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 7f06953663b3..9521b391b190 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -100,10 +100,8 @@ enum Family { Const, // c Fn, // f UnsafeFn, // u - PureFn, // p StaticMethod, // F UnsafeStaticMethod, // U - PureStaticMethod, // P ForeignFn, // e Type, // y ForeignType, // T @@ -125,10 +123,8 @@ fn item_family(item: ebml::Doc) -> Family { 'c' => Const, 'f' => Fn, 'u' => UnsafeFn, - 'p' => PureFn, 'F' => StaticMethod, 'U' => UnsafeStaticMethod, - 'P' => PureStaticMethod, 'e' => ForeignFn, 'y' => Type, 'T' => ForeignType, @@ -325,7 +321,6 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) Struct => dl_def(ast::def_struct(did)), UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)), Fn => dl_def(ast::def_fn(did, ast::impure_fn)), - PureFn => dl_def(ast::def_fn(did, ast::pure_fn)), ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)), UnsafeStaticMethod => { let trait_did_opt = translated_parent_item_opt(cnum, item); @@ -335,10 +330,6 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) let trait_did_opt = translated_parent_item_opt(cnum, item); dl_def(ast::def_static_method(did, trait_did_opt, ast::impure_fn)) } - PureStaticMethod => { - let trait_did_opt = translated_parent_item_opt(cnum, item); - dl_def(ast::def_static_method(did, trait_did_opt, ast::pure_fn)) - } Type | ForeignType => dl_def(ast::def_ty(did)), Mod => dl_def(ast::def_mod(did)), ForeignMod => dl_def(ast::def_foreign_mod(did)), @@ -822,12 +813,11 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, let impl_method_doc = lookup_item(impl_method_id.node, cdata.data); let family = item_family(impl_method_doc); match family { - StaticMethod | UnsafeStaticMethod | PureStaticMethod => { + StaticMethod | UnsafeStaticMethod => { let purity; match item_family(impl_method_doc) { StaticMethod => purity = ast::impure_fn, UnsafeStaticMethod => purity = ast::unsafe_fn, - PureStaticMethod => purity = ast::pure_fn, _ => fail!() } @@ -934,10 +924,8 @@ fn item_family_to_str(fam: Family) -> ~str { Const => ~"const", Fn => ~"fn", UnsafeFn => ~"unsafe fn", - PureFn => ~"pure fn", StaticMethod => ~"static method", UnsafeStaticMethod => ~"unsafe static method", - PureStaticMethod => ~"pure static method", ForeignFn => ~"foreign fn", Type => ~"type", ForeignType => ~"foreign type", diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index bc2e95f4d1b1..d2724400be5d 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -753,7 +753,6 @@ fn encode_info_for_method(ecx: &EncodeContext, fn purity_fn_family(p: purity) -> char { match p { unsafe_fn => 'u', - pure_fn => 'p', impure_fn => 'f', extern_fn => 'e' } @@ -762,7 +761,6 @@ fn purity_fn_family(p: purity) -> char { fn purity_static_method_family(p: purity) -> char { match p { unsafe_fn => 'U', - pure_fn => 'P', impure_fn => 'F', _ => fail!("extern fn can't be static") } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index cf2a92b291f2..91917cb807f0 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -439,10 +439,9 @@ fn parse_hex(st: &mut PState) -> uint { fn parse_purity(c: char) -> purity { match c { 'u' => unsafe_fn, - 'p' => pure_fn, 'i' => impure_fn, 'c' => extern_fn, - _ => fail!("parse_purity: bad purity") + _ => fail!("parse_purity: bad purity %c", c) } } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index d9377afa9a52..a96e07862ac3 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -347,7 +347,6 @@ fn enc_sigil(w: @io::Writer, sigil: Sigil) { fn enc_purity(w: @io::Writer, p: purity) { match p { - pure_fn => w.write_char('p'), impure_fn => w.write_char('i'), unsafe_fn => w.write_char('u'), extern_fn => w.write_char('c') diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 16a6d62f1767..65a6e8d3c4b5 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -398,7 +398,6 @@ pub fn ast_sigil_constant(sigil: ast::Sigil) -> uint { pub fn ast_purity_constant(purity: ast::purity) -> uint { match purity { - ast::pure_fn => 0u, ast::unsafe_fn => 1u, ast::impure_fn => 2u, ast::extern_fn => 3u diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8595adcd1c73..eb42945e6393 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1253,7 +1253,7 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t { let input_args = input_tys.map(|t| *t); mk_bare_fn(cx, BareFnTy { - purity: ast::pure_fn, + purity: ast::impure_fn, abis: AbiSet::Rust(), sig: FnSig { bound_lifetime_names: opt_vec::Empty, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 13ded5016793..b00c963c2912 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -275,7 +275,7 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, err_count_on_creation: ccx.tcx.sess.err_count(), ret_ty: rty, indirect_ret_ty: None, - ps: PurityState::function(ast::pure_fn, 0), + ps: PurityState::function(ast::impure_fn, 0), region_lb: region_bnd, in_scope_regions: @Nil, fn_kind: Vanilla, diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 700a78699b1e..7d2d8dd523dd 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -23,7 +23,7 @@ use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::isr_alist; use syntax::ast; use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl}; -use syntax::ast::{pure_fn, unsafe_fn}; +use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::abi::AbiSet; use syntax::codemap::span; @@ -103,7 +103,6 @@ impl Combine for Glb { fn purities(&self, a: purity, b: purity) -> cres { match (a, b) { - (pure_fn, _) | (_, pure_fn) => Ok(pure_fn), (extern_fn, _) | (_, extern_fn) => Ok(extern_fn), (impure_fn, _) | (_, impure_fn) => Ok(impure_fn), (unsafe_fn, unsafe_fn) => Ok(unsafe_fn) diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 213af316549a..c77bef835e4f 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -28,7 +28,7 @@ use extra::list; use syntax::abi::AbiSet; use syntax::ast; use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn}; -use syntax::ast::{pure_fn, unsafe_fn}; +use syntax::ast::{unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::codemap::span; @@ -92,8 +92,7 @@ impl Combine for Lub { match (a, b) { (unsafe_fn, _) | (_, unsafe_fn) => Ok(unsafe_fn), (impure_fn, _) | (_, impure_fn) => Ok(impure_fn), - (extern_fn, _) | (_, extern_fn) => Ok(extern_fn), - (pure_fn, pure_fn) => Ok(pure_fn) + (extern_fn, extern_fn) => Ok(extern_fn), } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1758433aa737..a3ead99a7143 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -845,7 +845,6 @@ pub struct fn_decl { #[deriving(Eq, Encodable, Decodable)] pub enum purity { - pure_fn, // declared with "pure fn" unsafe_fn, // declared with "unsafe fn" impure_fn, // declared with "fn" extern_fn, // declared with "extern fn" @@ -856,7 +855,6 @@ impl ToStr for purity { match *self { impure_fn => ~"impure", unsafe_fn => ~"unsafe", - pure_fn => ~"pure", extern_fn => ~"extern" } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d73c5240a1c0..e166e30bd78b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2188,26 +2188,29 @@ pub fn print_fn_header_info(s: @ps, print_opt_sigil(s, opt_sigil); } -pub fn opt_sigil_to_str(opt_p: Option) -> ~str { +pub fn opt_sigil_to_str(opt_p: Option) -> &'static str { match opt_p { - None => ~"fn", - Some(p) => fmt!("fn%s", p.to_str()) + None => "fn", + Some(p) => match p { + ast::BorrowedSigil => "fn&", + ast::OwnedSigil => "fn~", + ast::ManagedSigil => "fn@" + } } } -pub fn purity_to_str(p: ast::purity) -> ~str { +pub fn purity_to_str(p: ast::purity) -> &'static str { match p { - ast::impure_fn => ~"impure", - ast::unsafe_fn => ~"unsafe", - ast::pure_fn => ~"pure", - ast::extern_fn => ~"extern" + ast::impure_fn => "impure", + ast::unsafe_fn => "unsafe", + ast::extern_fn => "extern" } } -pub fn onceness_to_str(o: ast::Onceness) -> ~str { +pub fn onceness_to_str(o: ast::Onceness) -> &'static str { match o { - ast::Once => ~"once", - ast::Many => ~"many" + ast::Once => "once", + ast::Many => "many" } } From 3dbdb3a3646931cb11db90d65971da8b16d819e4 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 15 Jun 2013 14:31:52 +1200 Subject: [PATCH 041/336] Methodize TypeNames --- src/librustc/lib/llvm.rs | 168 ++++++++++----------------- src/librustc/middle/trans/context.rs | 8 +- 2 files changed, 69 insertions(+), 107 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 8d6cad62e753..771cc8e6fea2 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2121,121 +2121,81 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef { /* Memory-managed object interface to type handles. */ pub struct TypeNames { - type_names: @mut HashMap, - named_types: @mut HashMap<@str, TypeRef> + type_names: HashMap, + named_types: HashMap<@str, TypeRef> } -pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) { - assert!(tn.type_names.insert(t, s)); - assert!(tn.named_types.insert(s, t)); -} - -pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> { - return tn.type_names.find(&t).map_consume(|x| *x); -} - -pub fn name_has_type(tn: @TypeNames, s: @str) -> Option { - return tn.named_types.find(&s).map_consume(|x| *x); -} - -pub fn mk_type_names() -> @TypeNames { - @TypeNames { - type_names: @mut HashMap::new(), - named_types: @mut HashMap::new() +impl TypeNames { + pub fn new() -> TypeNames { + TypeNames { + type_names: HashMap::new(), + named_types: HashMap::new() + } } -} -pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str { - return type_to_str_inner(names, [], ty); -} + pub fn associate_type(&mut self, s: @str, t: TypeRef) { + assert!(self.type_names.insert(t, s)); + assert!(self.named_types.insert(s, t)); + } -pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef) - -> @str { - unsafe { - match type_has_name(names, ty) { - option::Some(n) => return n, - _ => {} + pub fn find_name(&self, ty: &TypeRef) -> Option<@str> { + self.type_names.find_copy(ty) + } + + pub fn find_type(&self, s: &str) -> Option { + self.named_types.find_equiv(s).map_consume(|x| *x) + } + + pub fn type_to_str(&self, ty: TypeRef) -> ~str { + match self.find_name(&ty) { + option::Some(name) => return name.to_owned(), + None => () } - let outer = vec::append_one(outer0.to_owned(), ty); + unsafe { + let kind = llvm::LLVMGetTypeKind(ty); - let kind = llvm::LLVMGetTypeKind(ty); + match kind { + Void => ~"Void", + Half => ~"Half", + Double => ~"Double", + X86_FP80 => ~"X86_FP80", + FP128 => ~"FP128", + PPC_FP128 => ~"PPC_FP128", + Label => ~"Label", + Vector => ~"Vector", + Metadata => ~"Metadata", + X86_MMX => ~"X86_MMAX", + Integer => { + fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) as int) + } + Function => { + let out_ty = llvm::LLVMGetReturnType(ty); + let n_args = llvm::LLVMCountParamTypes(ty) as uint; + let args = vec::from_elem(n_args, 0 as TypeRef); + llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - fn tys_str(names: @TypeNames, outer: &[TypeRef], - tys: ~[TypeRef]) -> @str { - let mut s = ~""; - let mut first: bool = true; - for tys.each |t| { - if first { first = false; } else { s += ", "; } - s += type_to_str_inner(names, outer, *t); - } - // [Note at-str] FIXME #2543: Could rewrite this without the copy, - // but need better @str support. - return s.to_managed(); - } - - match kind { - Void => return @"Void", - Half => return @"Half", - Float => return @"Float", - Double => return @"Double", - X86_FP80 => return @"X86_FP80", - FP128 => return @"FP128", - PPC_FP128 => return @"PPC_FP128", - Label => return @"Label", - Integer => { - // See [Note at-str] - return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) - as int).to_managed(); - } - Function => { - let out_ty: TypeRef = llvm::LLVMGetReturnType(ty); - let n_args = llvm::LLVMCountParamTypes(ty) as uint; - let args = vec::from_elem(n_args, 0 as TypeRef); - llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - // See [Note at-str] - return fmt!("fn(%s) -> %s", - tys_str(names, outer, args), - type_to_str_inner(names, outer, out_ty)).to_managed(); - } - Struct => { - let elts = struct_tys(ty); - // See [Note at-str] - return fmt!("{%s}", tys_str(names, outer, elts)).to_managed(); - } - Array => { - let el_ty = llvm::LLVMGetElementType(ty); - // See [Note at-str] - return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty), - llvm::LLVMGetArrayLength(ty) as uint).to_managed(); - } - Pointer => { - let mut i = 0; - for outer0.each |tout| { - i += 1; - if *tout as int == ty as int { - let n = outer0.len() - i; - // See [Note at-str] - return fmt!("*\\%d", n as int).to_managed(); + let args = args.map(|&ty| self.type_to_str(ty)).connect(", "); + let out_ty = self.type_to_str(out_ty); + fmt!("fn(%s) -> %s", args, out_ty) + } + Struct => { + let tys = struct_tys(ty); + let tys = tys.map(|ty| self.type_to_str(ty)).connect(", "); + fmt!("{%s}", tys) + } + Array => { + let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = self.type_to_str(el_ty); + let len = llvm::LLVMGetArrayLength(ty) as uint; + fmt!("[%s x %u]", el_ty, len) + } + Pointer => { + let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = self.type_to_str(el_ty); + fmt!("*%s", el_ty) } } - let addrstr = { - let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint; - if addrspace == 0 { - ~"" - } else { - fmt!("addrspace(%u)", addrspace) - } - }; - // See [Note at-str] - return fmt!("%s*%s", addrstr, type_to_str_inner(names, - outer, - llvm::LLVMGetElementType(ty))).to_managed(); - } - Vector => return @"Vector", - Metadata => return @"Metadata", - X86_MMX => return @"X86_MMAX", - _ => fail!() } } } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index d6c7472424f7..8391ff95599b 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -46,7 +46,7 @@ pub struct CrateContext { llmod: ModuleRef, llcx: ContextRef, td: TargetData, - tn: @TypeNames, + tn: TypeNames, externs: ExternMap, intrinsics: HashMap<&'static str, ValueRef>, item_vals: HashMap, @@ -136,8 +136,10 @@ impl CrateContext { str::as_c_str(data_layout, |buf| llvm::LLVMSetDataLayout(llmod, buf)); str::as_c_str(targ_triple, |buf| llvm::LLVMSetTarget(llmod, buf)); let targ_cfg = sess.targ_cfg; + let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); - let tn = mk_type_names(); + let tn = TypeNames::new(); + let mut intrinsics = base::declare_intrinsics(llmod); if sess.opts.extra_debuginfo { base::declare_dbg_intrinsics(llmod, &mut intrinsics); @@ -145,7 +147,7 @@ impl CrateContext { let int_type = T_int(targ_cfg); let float_type = T_float(targ_cfg); let tydesc_type = T_tydesc(targ_cfg); - lib::llvm::associate_type(tn, @"tydesc", tydesc_type); + tn.associate_type(@"tydesc", tydesc_type); let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { Some(debuginfo::DebugContext::new(llmod, name.to_owned())) From b4b2cbb299842a6854a7e82e745b8a9b63c8d6b9 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 15 Jun 2013 15:16:03 +1200 Subject: [PATCH 042/336] Change calls for TypeName stuff to methods --- src/librustc/lib/llvm.rs | 11 ++++- src/librustc/middle/trans/_match.rs | 28 ++++++------ src/librustc/middle/trans/build.rs | 20 ++++----- src/librustc/middle/trans/callee.rs | 10 ++--- src/librustc/middle/trans/common.rs | 54 ++++++++++-------------- src/librustc/middle/trans/context.rs | 4 +- src/librustc/middle/trans/datum.rs | 6 +-- src/librustc/middle/trans/expr.rs | 8 ++-- src/librustc/middle/trans/machine.rs | 2 +- src/librustc/middle/trans/meth.rs | 2 +- src/librustc/middle/trans/reflect.rs | 2 +- src/librustc/middle/trans/tvec.rs | 8 ++-- src/librustc/middle/trans/write_guard.rs | 4 +- 13 files changed, 78 insertions(+), 81 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 771cc8e6fea2..4ed8ee6d157e 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2143,7 +2143,7 @@ impl TypeNames { } pub fn find_type(&self, s: &str) -> Option { - self.named_types.find_equiv(s).map_consume(|x| *x) + self.named_types.find_equiv(&s).map_consume(|x| *x) } pub fn type_to_str(&self, ty: TypeRef) -> ~str { @@ -2181,7 +2181,7 @@ impl TypeNames { } Struct => { let tys = struct_tys(ty); - let tys = tys.map(|ty| self.type_to_str(ty)).connect(", "); + let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", "); fmt!("{%s}", tys) } Array => { @@ -2195,9 +2195,16 @@ impl TypeNames { let el_ty = self.type_to_str(el_ty); fmt!("*%s", el_ty) } + _ => fail!("Unknown Type Kind (%u)", kind as uint) } } } + + pub fn val_to_str(&self, val: ValueRef) -> ~str { + unsafe { + self.type_to_str(llvm::LLVMTypeOf(val)) + } + } } pub fn float_width(llt: TypeRef) -> uint { diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 945f94a0877f..2b46b3b27248 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -381,7 +381,7 @@ pub fn expand_nested_bindings<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); do m.map |br| { @@ -428,7 +428,7 @@ pub fn enter_match<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let mut result = ~[]; @@ -474,7 +474,7 @@ pub fn enter_default<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); do enter_match(bcx, dm, m, col, val) |p| { @@ -521,7 +521,7 @@ pub fn enter_opt<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let tcx = bcx.tcx(); @@ -632,7 +632,7 @@ pub fn enter_rec_or_struct<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -667,7 +667,7 @@ pub fn enter_tup<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -695,7 +695,7 @@ pub fn enter_tuple_struct<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -720,7 +720,7 @@ pub fn enter_box<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -747,7 +747,7 @@ pub fn enter_uniq<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -774,7 +774,7 @@ pub fn enter_region<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat { id: 0, node: ast::pat_wild, span: dummy_sp() }; @@ -1202,9 +1202,7 @@ fn insert_lllocals(bcx: block, } }; - debug!("binding %? to %s", - binding_info.id, - val_str(bcx.ccx().tn, llval)); + debug!("binding %? to %s", binding_info.id, bcx.val_to_str(llval)); llmap.insert(binding_info.id, llval); } return bcx; @@ -1221,7 +1219,7 @@ pub fn compile_guard(bcx: block, bcx.to_str(), bcx.expr_to_str(guard_expr), matches_to_str(bcx, m), - vals.map(|v| bcx.val_str(*v))); + vals.map(|v| bcx.val_to_str(*v))); let _indenter = indenter(); let mut bcx = bcx; @@ -1272,7 +1270,7 @@ pub fn compile_submatch(bcx: block, debug!("compile_submatch(bcx=%s, m=%s, vals=%?)", bcx.to_str(), matches_to_str(bcx, m), - vals.map(|v| bcx.val_str(*v))); + vals.map(|v| bcx.val_to_str(*v))); let _indenter = indenter(); /* diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index a55e89747f5b..f6c9c15f19bd 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -191,8 +191,8 @@ pub fn Invoke(cx: block, check_not_terminated(cx); terminate(cx, "Invoke"); debug!("Invoke(%s with arguments (%s))", - val_str(cx.ccx().tn, Fn), - Args.map(|a| val_str(cx.ccx().tn, *a).to_owned()).connect(", ")); + cx.val_to_str(Fn), + Args.map(|a| cx.val_to_str(*a)).connect(", ")); unsafe { count_insn(cx, "invoke"); llvm::LLVMBuildInvoke(B(cx), @@ -576,8 +576,8 @@ pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) { unsafe { if cx.unreachable { return; } debug!("Store %s -> %s", - val_str(cx.ccx().tn, Val), - val_str(cx.ccx().tn, Ptr)); + cx.val_to_str(Val), + cx.val_to_str(Ptr)); count_insn(cx, "store"); llvm::LLVMBuildStore(B(cx), Val, Ptr); } @@ -587,8 +587,8 @@ pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrderin unsafe { if cx.unreachable { return; } debug!("Store %s -> %s", - val_str(cx.ccx().tn, Val), - val_str(cx.ccx().tn, Ptr)); + cx.val_to_str(Val), + cx.val_to_str(Ptr)); count_insn(cx, "store.atomic"); let align = llalign_of_min(cx.ccx(), cx.ccx().int_type); llvm::LLVMBuildAtomicStore(B(cx), Val, Ptr, order, align as c_uint); @@ -911,11 +911,11 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, else { lib::llvm::False }; let argtys = do inputs.map |v| { - debug!("Asm Input Type: %?", val_str(cx.ccx().tn, *v)); + debug!("Asm Input Type: %?", cx.val_to_str(*v)); val_ty(*v) }; - debug!("Asm Output Type: %?", ty_str(cx.ccx().tn, output)); + debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); let llfty = T_fn(argtys, output); let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, alignstack, dia as c_uint); @@ -930,8 +930,8 @@ pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { count_insn(cx, "call"); debug!("Call(Fn=%s, Args=%?)", - val_str(cx.ccx().tn, Fn), - Args.map(|arg| val_str(cx.ccx().tn, *arg))); + cx.val_to_str(Fn), + Args.map(|arg| cx.val_to_str(*arg))); do vec::as_imm_buf(Args) |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 7666684f2579..e5006c854cda 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -572,9 +572,9 @@ pub fn trans_call_inner(in_cx: block, // Uncomment this to debug calls. /* - io::println(fmt!("calling: %s", bcx.val_str(llfn))); + io::println(fmt!("calling: %s", bcx.val_to_str(llfn))); for llargs.each |llarg| { - io::println(fmt!("arg: %s", bcx.val_str(*llarg))); + io::println(fmt!("arg: %s", bcx.val_to_str(*llarg))); } io::println("---"); */ @@ -731,7 +731,7 @@ pub fn trans_arg_expr(bcx: block, formal_arg_ty.repr(bcx.tcx()), self_mode, arg_expr.repr(bcx.tcx()), - ret_flag.map(|v| bcx.val_str(*v))); + ret_flag.map(|v| bcx.val_to_str(*v))); // translate the arg expr to a datum let arg_datumblock = match ret_flag { @@ -842,11 +842,11 @@ pub fn trans_arg_expr(bcx: block, ty::ByCopy => llformal_arg_ty, }; debug!("casting actual type (%s) to match formal (%s)", - bcx.val_str(val), bcx.llty_str(llformal_arg_ty)); + bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty)); val = PointerCast(bcx, val, llformal_arg_ty); } } - debug!("--- trans_arg_expr passing %s", val_str(bcx.ccx().tn, val)); + debug!("--- trans_arg_expr passing %s", bcx.val_to_str(val)); return rslt(bcx, val); } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index e9a0d42f29b9..b8bf295e809a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -17,7 +17,7 @@ use driver::session; use driver::session::Session; use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef}; use lib::llvm::{True, False, Bool}; -use lib::llvm::{llvm, TypeNames, associate_type, name_has_type}; +use lib::llvm::{llvm, TypeNames}; use lib; use middle::trans::base; use middle::trans::build; @@ -372,7 +372,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } debug!("add_clean(%s, %s, %s)", bcx.to_str(), - val_str(bcx.ccx().tn, val), + bcx.val_to_str(val), t.repr(bcx.tcx())); let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); @@ -387,7 +387,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { if !ty::type_needs_drop(cx.tcx(), ty) { return; } debug!("add_clean_temp_immediate(%s, %s, %s)", - cx.to_str(), val_str(cx.ccx().tn, val), + 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| { @@ -400,7 +400,7 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { pub fn add_clean_temp_mem(bcx: block, 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(), val_str(bcx.ccx().tn, val), + bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); @@ -427,8 +427,8 @@ pub fn add_clean_return_to_mut(bcx: block, debug!("add_clean_return_to_mut(%s, %s, %s)", bcx.to_str(), - val_str(bcx.ccx().tn, frozen_val_ref), - val_str(bcx.ccx().tn, bits_val_ref)); + bcx.val_to_str(frozen_val_ref), + bcx.val_to_str(bits_val_ref)); do in_scope_cx(bcx) |scope_info| { scope_info.cleanups.push( clean_temp( @@ -623,20 +623,12 @@ impl Result { } } -pub fn ty_str(tn: @TypeNames, t: TypeRef) -> @str { - return lib::llvm::type_to_str(tn, t); -} - pub fn val_ty(v: ValueRef) -> TypeRef { unsafe { return llvm::LLVMTypeOf(v); } } -pub fn val_str(tn: @TypeNames, v: ValueRef) -> @str { - return ty_str(tn, val_ty(v)); -} - pub fn in_scope_cx(cx: block, f: &fn(si: @mut scope_info)) { let mut cur = cx; loop { @@ -664,27 +656,27 @@ pub fn block_parent(cx: block) -> block { // Accessors impl block_ { - pub fn ccx(@mut self) -> @mut CrateContext { self.fcx.ccx } - pub fn tcx(@mut self) -> ty::ctxt { self.fcx.ccx.tcx } - pub fn sess(@mut self) -> Session { self.fcx.ccx.sess } + pub fn ccx(&self) -> @mut CrateContext { self.fcx.ccx } + pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx } + pub fn sess(&self) -> Session { self.fcx.ccx.sess } - pub fn node_id_to_str(@mut self, id: ast::node_id) -> ~str { + pub fn node_id_to_str(&self, id: ast::node_id) -> ~str { ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr()) } - pub fn expr_to_str(@mut self, e: @ast::expr) -> ~str { + pub fn expr_to_str(&self, e: @ast::expr) -> ~str { e.repr(self.tcx()) } - pub fn expr_is_lval(@mut self, e: @ast::expr) -> bool { + pub fn expr_is_lval(&self, e: @ast::expr) -> bool { ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e) } - pub fn expr_kind(@mut self, e: @ast::expr) -> ty::ExprKind { + pub fn expr_kind(&self, e: @ast::expr) -> ty::ExprKind { ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e) } - pub fn def(@mut self, nid: ast::node_id) -> ast::def { + pub fn def(&self, nid: ast::node_id) -> ast::def { match self.tcx().def_map.find(&nid) { Some(&v) => v, None => { @@ -694,19 +686,19 @@ impl block_ { } } - pub fn val_str(@mut self, val: ValueRef) -> @str { - val_str(self.ccx().tn, val) + pub fn val_to_str(&self, val: ValueRef) -> ~str { + self.ccx().tn.val_to_str(val) } - pub fn llty_str(@mut self, llty: TypeRef) -> @str { - ty_str(self.ccx().tn, llty) + pub fn llty_str(&self, llty: TypeRef) -> ~str { + self.ccx().tn.type_to_str(llty) } - pub fn ty_to_str(@mut self, t: ty::t) -> ~str { + pub fn ty_to_str(&self, t: ty::t) -> ~str { t.repr(self.tcx()) } - pub fn to_str(@mut self) -> ~str { + pub fn to_str(&self) -> ~str { unsafe { match self.node_info { Some(node_info) => fmt!("[block %d]", node_info.id), @@ -885,12 +877,12 @@ pub fn T_tydesc_field(cx: &CrateContext, field: uint) -> TypeRef { pub fn T_generic_glue_fn(cx: &mut CrateContext) -> TypeRef { let s = @"glue_fn"; - match name_has_type(cx.tn, s) { + match cx.tn.find_type(s) { Some(t) => return t, _ => () } let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue); - associate_type(cx.tn, s, t); + cx.tn.associate_type(s, t); return t; } @@ -1227,7 +1219,7 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint]) }; debug!("const_get_elt(v=%s, us=%?, r=%s)", - val_str(cx.tn, v), us, val_str(cx.tn, r)); + cx.tn.val_to_str(v), us, cx.tn.val_to_str(r)); return r; } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 8391ff95599b..76b7189a9d4c 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -14,7 +14,7 @@ use back::{upcall}; use driver::session; use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef}; use lib::llvm::{llvm, TargetData, TypeNames}; -use lib::llvm::{mk_target_data, mk_type_names}; +use lib::llvm::{mk_target_data}; use lib; use metadata::common::LinkMeta; use middle::astencode; @@ -138,7 +138,7 @@ impl CrateContext { let targ_cfg = sess.targ_cfg; let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); - let tn = TypeNames::new(); + let mut tn = TypeNames::new(); let mut intrinsics = base::declare_intrinsics(llmod); if sess.opts.extra_debuginfo { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index b0276cf0e29a..c162318824f5 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -280,7 +280,7 @@ impl Datum { } debug!("copy_to(self=%s, action=%?, dst=%s)", - self.to_str(bcx.ccx()), action, bcx.val_str(dst)); + self.to_str(bcx.ccx()), action, bcx.val_to_str(dst)); // Watch out for the case where we are writing the copying the // value into the same location we read it out from. We want @@ -345,7 +345,7 @@ impl Datum { let mut bcx = bcx; debug!("move_to(self=%s, action=%?, dst=%s)", - self.to_str(bcx.ccx()), action, bcx.val_str(dst)); + self.to_str(bcx.ccx()), action, bcx.val_to_str(dst)); if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { return bcx; @@ -409,7 +409,7 @@ impl Datum { pub fn to_str(&self, ccx: &CrateContext) -> ~str { fmt!("Datum { val=%s, ty=%s, mode=%? }", - val_str(ccx.tn, self.val), + ccx.tn.val_to_str(self.val), ty_to_str(ccx.tcx, self.ty), self.mode) } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d1467edd94d5..d79e725a2b7d 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -173,7 +173,7 @@ pub enum Dest { impl Dest { pub fn to_str(&self, ccx: &CrateContext) -> ~str { match *self { - SaveIn(v) => fmt!("SaveIn(%s)", val_str(ccx.tn, v)), + SaveIn(v) => fmt!("SaveIn(%s)", ccx.tn.val_to_str(v)), Ignore => ~"Ignore" } } @@ -914,8 +914,8 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { len = Sub(bcx, len, C_uint(bcx.ccx(), 1u)); } - debug!("trans_index: base %s", val_str(bcx.ccx().tn, base)); - debug!("trans_index: len %s", val_str(bcx.ccx().tn, len)); + debug!("trans_index: base %s", bcx.val_to_str(base)); + debug!("trans_index: len %s", bcx.val_to_str(len)); let bounds_check = ICmp(bcx, lib::llvm::IntUGE, scaled_ix, len); let bcx = do with_cond(bcx, bounds_check) |bcx| { @@ -1081,7 +1081,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { }; let ty = node_id_type(bcx, nid); debug!("take_local(nid=%?, v=%s, ty=%s)", - nid, bcx.val_str(v), bcx.ty_to_str(ty)); + nid, bcx.val_to_str(v), bcx.ty_to_str(ty)); Datum { val: v, ty: ty, diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index fb94fe4752a3..dc3fe3fb9315 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -140,7 +140,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { debug!("static_size_of_enum: variant %s type %s", cx.tcx.sess.str_of(variant.name), - ty_str(cx.tn, T_struct(lltypes, false))); + cx.tn.type_to_str(T_struct(lltypes, false))); let this_size = llsize_of_real(cx, T_struct(lltypes, false)); if max_size < this_size { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 8b327c196e60..ee429a247465 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -623,7 +623,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Load the vtable from the @Trait pair debug!("(translating trait callee) loading vtable from pair %s", - val_str(bcx.ccx().tn, llpair)); + bcx.val_to_str(llpair)); let llvtable = Load(bcx, PointerCast(bcx, GEPi(bcx, llpair, diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 16a6d62f1767..cb7e2cb4e6e1 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -96,7 +96,7 @@ impl Reflector { debug!("passing %u args:", args.len()); let bcx = self.bcx; for args.iter().enumerate().advance |(i, a)| { - debug!("arg %u: %s", i, val_str(bcx.ccx().tn, *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); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 09905a761879..b39fff61d64f 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -155,8 +155,8 @@ impl VecTypes { fmt!("VecTypes {vec_ty=%s, unit_ty=%s, llunit_ty=%s, llunit_size=%s}", ty_to_str(ccx.tcx, self.vec_ty), ty_to_str(ccx.tcx, self.unit_ty), - ty_str(ccx.tn, self.llunit_ty), - val_str(ccx.tn, self.llunit_size)) + ccx.tn.type_to_str(self.llunit_ty), + ccx.tn.val_to_str(self.llunit_size)) } } @@ -336,7 +336,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val)); debug!("alloc_vec() returned val=%s, dataptr=%s", - bcx.val_str(val), bcx.val_str(dataptr)); + bcx.val_to_str(val), bcx.val_to_str(dataptr)); let bcx = write_content(bcx, &vt, vstore_expr, content_expr, SaveIn(dataptr)); @@ -389,7 +389,7 @@ pub fn write_content(bcx: block, for elements.iter().enumerate().advance |(i, element)| { let lleltptr = GEPi(bcx, lldest, [i]); debug!("writing index %? with lleltptr=%?", - i, bcx.val_str(lleltptr)); + i, bcx.val_to_str(lleltptr)); bcx = expr::trans_into(bcx, *element, SaveIn(lleltptr)); add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index d76d4642801b..91885f4dc4ff 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -64,8 +64,8 @@ pub fn return_to_mut(mut bcx: block, debug!("write_guard::return_to_mut(root_key=%?, %s, %s, %s)", root_key, bcx.to_str(), - val_str(bcx.ccx().tn, frozen_val_ref), - val_str(bcx.ccx().tn, bits_val_ref)); + bcx.val_to_str(frozen_val_ref), + bcx.val_to_str(bits_val_ref)); let box_ptr = Load(bcx, PointerCast(bcx, From 66d8e8b481a487d372936c553bf7a6d7435056c7 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 15 Jun 2013 16:31:37 +1200 Subject: [PATCH 043/336] Make log_fn_time a method --- src/librustc/middle/trans/base.rs | 14 +------------- src/librustc/middle/trans/context.rs | 7 +++++++ src/librustc/middle/trans/glue.rs | 5 +---- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 1ba2f15ebda8..18d87b46e193 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -138,13 +138,6 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } -pub fn log_fn_time(ccx: @mut CrateContext, 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; - ccx.stats.fn_times.push((name, elapsed)); -} - pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, @@ -1962,7 +1955,7 @@ pub fn trans_fn(ccx: @mut CrateContext, |_bcx| { }); if do_time { let end = time::get_time(); - log_fn_time(ccx, the_path_str, start, end); + ccx.log_fn_time(the_path_str, start, end); } } @@ -3130,11 +3123,6 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("n_closures: %u", ccx.stats.n_closures)); } - if ccx.sess.count_llvm_insns() { - for ccx.stats.llvm_insns.each |&k, &v| { - io::println(fmt!("%-7u %s", v, k)); - } - } let llcx = ccx.llcx; let link_meta = ccx.link_meta; let llmod = ccx.llmod; diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 76b7189a9d4c..3a66be04585c 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -31,6 +31,7 @@ use core::hash; use core::hashmap::{HashMap, HashSet}; use core::str; use core::local_data; +use extra::time; use syntax::ast; use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen,addrspace_gen}; @@ -222,6 +223,12 @@ 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/glue.rs b/src/librustc/middle/trans/glue.rs index 0ea63dde972a..6f1442637aee 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -731,10 +731,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext, let start = time::get_time(); let llval = make_generic_glue_inner(ccx, t, llfn, helper); let end = time::get_time(); - log_fn_time(ccx, - fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), - start, - end); + ccx.log_fn_time(fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), start, end); return llval; } From 1968622798ce565fe9f3905c972513393070a78e Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 15 Jun 2013 22:16:47 +1200 Subject: [PATCH 044/336] Start refacting LLVM Type handling --- src/librustc/lib/llvm.rs | 23 ++- src/librustc/middle/trans/context.rs | 23 ++- src/librustc/middle/trans/mod.rs | 1 + src/librustc/middle/trans/type_.rs | 269 +++++++++++++++++++++++++++ 4 files changed, 298 insertions(+), 18 deletions(-) create mode 100644 src/librustc/middle/trans/type_.rs diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 4ed8ee6d157e..14f5166b123a 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -17,6 +17,8 @@ use core::ptr; use core::str; use core::vec; +use middle::trans::type_::Type; + pub type Opcode = u32; pub type Bool = c_uint; @@ -2121,8 +2123,8 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef { /* Memory-managed object interface to type handles. */ pub struct TypeNames { - type_names: HashMap, - named_types: HashMap<@str, TypeRef> + type_names: HashMap, + named_types: HashMap<~str, TypeRef> } impl TypeNames { @@ -2133,17 +2135,20 @@ impl TypeNames { } } - pub fn associate_type(&mut self, s: @str, t: TypeRef) { - assert!(self.type_names.insert(t, s)); - assert!(self.named_types.insert(s, t)); + pub fn associate_type(&mut self, s: &str, t: &Type) { + assert!(self.type_names.insert(t.to_ref(), s.to_owned())); + assert!(self.named_types.insert(s.to_owned(), t.to_ref())); } - pub fn find_name(&self, ty: &TypeRef) -> Option<@str> { - self.type_names.find_copy(ty) + pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> { + match self.type_names.find(ty.to_ref()) { + Some(a) => Some(a.slice(0, a.len())), + None => None + } } - pub fn find_type(&self, s: &str) -> Option { - self.named_types.find_equiv(&s).map_consume(|x| *x) + pub fn find_type(&self, s: &str) -> Option { + self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) } pub fn type_to_str(&self, ty: TypeRef) -> ~str { diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 3a66be04585c..ed5c2aa2e0b9 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -27,6 +27,8 @@ use middle::trans::shape; use middle::trans::type_use; use middle::ty; +use middle::trans::type_::Type; + use core::hash; use core::hashmap::{HashMap, HashSet}; use core::str; @@ -106,10 +108,10 @@ pub struct CrateContext { maps: astencode::Maps, stats: Stats, upcalls: @upcall::Upcalls, - tydesc_type: TypeRef, - int_type: TypeRef, - float_type: TypeRef, - opaque_vec_type: TypeRef, + tydesc_type: Type, + int_type: Type, + float_type: Type, + opaque_vec_type: Type, builder: BuilderRef_res, shape_cx: shape::Ctxt, crate_map: ValueRef, @@ -145,10 +147,13 @@ impl CrateContext { if sess.opts.extra_debuginfo { base::declare_dbg_intrinsics(llmod, &mut intrinsics); } - let int_type = T_int(targ_cfg); - let float_type = T_float(targ_cfg); - let tydesc_type = T_tydesc(targ_cfg); - tn.associate_type(@"tydesc", tydesc_type); + let int_type = Type::int(targ_cfg.arch); + let float_type = Type::float(targ_cfg.arch); + let tydesc_type = Type::tydesc(targ_cfg.arch); + let opaque_vec_type = Type::opaque_vec(targ_cfg.arch); + + tn.associate_type("tydesc", &tydesc_type); + let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { Some(debuginfo::DebugContext::new(llmod, name.to_owned())) @@ -213,7 +218,7 @@ impl CrateContext { tydesc_type: tydesc_type, int_type: int_type, float_type: float_type, - opaque_vec_type: T_opaque_vec(targ_cfg), + opaque_vec_type: opaque_vec_type, builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), shape_cx: mk_ctxt(llmod), crate_map: crate_map, diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index 49cadfbcc81a..1345b92418e3 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -42,3 +42,4 @@ pub mod reachable; pub mod machine; pub mod adt; pub mod asm; +pub mod type_; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs new file mode 100644 index 000000000000..65f86c30ea30 --- /dev/null +++ b/src/librustc/middle/trans/type_.rs @@ -0,0 +1,269 @@ +// 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. + +use core::prelude::*; + +use lib::llvm::{llvm, TypeRef, Bool, False, True}; + +use middle::trans::context::CrateContext; +use middle::trans::base; + +use syntax::{ast,abi}; +use syntax::abi::{X86, X86_64, Arm, Mips}; + +use core::vec; + +use core::libc::{c_uint}; + +pub struct Type { + priv rf: TypeRef +} + +macro_rules! ty ( + ($e:expr) => ( Type::from_ref(unsafe { + + })) +) + +/** + * Wrapper for LLVM TypeRef + */ +impl Type { + pub fn from_ref(r: TypeRef) -> Type { + Type { + rf: r + } + } + + pub fn to_ref(&self) -> TypeRef { + self.rf + } + + pub fn void() -> Type { + ty!(llvm::LLVMVoidTypeInContext(base::task_llcx())) + } + + pub fn nil() -> Type { + Type::empty_struct() + } + + pub fn metadata() -> Type { + ty!(llvm::LLVMMetadataTypeInContext(base::task_llcx())) + } + + pub fn i1() -> Type { + ty!(llvm::LLVMInt1TypeInContext(base::task_llcx())) + } + + pub fn i8() -> Type { + ty!(llvm::LLVMInt8TypeInContext(base::task_llcx())) + } + + pub fn i16() -> Type { + ty!(llvm::LLVMInt16TypeInContext(base::task_llcx())) + } + + pub fn i32() -> Type { + ty!(llvm::LLVMInt32TypeInContext(base::task_llcx())) + } + + pub fn i64() -> Type { + ty!(llvm::LLVMInt64TypeInContext(base::task_llcx())) + } + + pub fn f32() -> Type { + ty!(llvm::LLVMFloatTypeInContext(base::task_llcx())) + } + + pub fn f64() -> Type { + ty!(llvm::LLVMDoubleTypeInContext(base::task_llcx())) + } + + pub fn bool() -> Type { + Type::i8() + } + + pub fn char() -> Type { + Type::i32() + } + + pub fn int(arch: abi::Architecture) -> Type { + match arch { + X86 | Arm | Mips => Type::i32(), + X86_64 => Type::i64() + } + } + + pub fn float(_: abi::Architecture) -> Type { + // All architectures currently just use doubles as the default + // float size + Type::f64() + } + + pub fn int_from_ty(ctx: &CrateContext, t: ast::int_ty) -> Type { + match t { + ast::ty_i => ctx.int_type, + ast::ty_char => Type::char(), + ast::ty_i8 => Type::i8(), + ast::ty_i16 => Type::i16(), + ast::ty_i32 => Type::i32(), + ast::ty_i64 => Type::i64() + } + } + + pub fn uint_from_ty(ctx: &CrateContext, t: ast::uint_ty) -> Type { + match t { + ast::ty_u => ctx.int_type, + ast::ty_u8 => Type::i8(), + ast::ty_u16 => Type::i16(), + ast::ty_u32 => Type::i32(), + ast::ty_u64 => Type::i64() + } + } + + pub fn float_from_ty(ctx: &CrateContext, t: ast::float_ty) -> Type { + match t { + ast::ty_f => ctx.float_ty, + ast::ty_f32 => Type::f32(), + ast::ty_f64 => Type::f64() + } + } + + pub fn size_t(arch: abi::Architecture) -> Type { + Type::int(arch) + } + + pub fn func(args: &[Type], ret: &Type) -> Type { + let vec : &[TypeRef] = unsafe { cast::transmute() }; + ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec), + args.len() as c_uint, False)) + } + + pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type { + assert!(fn_ty.is_func(), "`fn_ty` must be a function type"); + + Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false) + } + + pub fn ptr(ty: Type) -> Type { + ty!(llvm::LLVMPointerType(ty, 0 as c_uint)) + } + + pub fn struct_(els: &[Type], packed: bool) -> Type { + let els : &[TypeRef] = unsafe { cast::transmute(els) }; + ty!(llvm::LLVMStructType(vec::raw::to_ptr(els), els.len() as c_uint, packed as Bool)) + } + + pub fn named_struct(name: &str) -> Type { + let ctx = base::task_llcx(); + ty!(name.as_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s))) + } + + pub fn empty_struct() -> Type { + Type::struct_([], false) + } + + pub fn vtable() -> Type { + Type::array(Type::i8().ptr_to(), 1) + } + + pub fn generic_glue_fn(cx: &mut CrateContext) -> Type { + match cx.tn.find_type("glue_fn") { + Some(ty) => return ty, + None => () + } + + let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); + cx.tn.associate_type("glue_fn", ty); + + return ty; + } + + pub fn tydesc(arch: abi::Architecture) -> Type { + let mut tydesc = Type::named_struct("tydesc"); + let tydescpp = tydesc.ptr_to().ptr_to(); + let pvoid = Type::i8().ptr_to(); + let glue_fn_ty = Type::func( + [ Type::nil.ptr_to(), tydescpp, pvoid ], + Type::void()).ptr_to(); + + let int_ty = Type::int(arch); + + let elems = [ + int_type, int_type, + glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, + pvoid, pvoid + ]; + + tydesc.set_struct_body(elems, false); + + return tydesc; + } + + pub fn array(ty: &Type, len: uint) -> Type { + ty!(llvm::LLVMArrayType(ty.to_ref(), len as c_uint)) + } + + pub fn vector(ty: &Type, len: uint) -> Type { + ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) + } + + pub fn vec(arch: abi::Architecture, ty: &Type) -> Type { + Type::struct_( + [ Type::int(arch), Type::int(arch), Type::array(ty, 0) ], + false) + } + + pub fn opaque_vec(arch: abi::Architecture) -> Type { + Type::vec(arch, Type::i8()) + } + + #[inline] + pub fn box_header_fields(ctx: &CrateContext) -> ~[Type] { + ~[ + ctx.int_type, ctx.tydesc_type.ptr_to(), + Type::i8().ptr_to(), Type::i8().ptr_to() + ] + } + + pub fn box_header(ctx: &CrateContext) -> Type { + Type::struct_(Type::box_header_fields(ctx), false) + } + + pub fn box(ctx: &CrateContext, ty: &Type) -> Type { + Type::struct_(Type::box_header_fields(ctx) + [t], false) + } + + pub fn opaque_box(ctx: &CrateContext) -> Type { + Type::box(ctx, Type::i8()) + } + + pub fn unique(ctx: &CrateContext, ty: &Type) -> Type { + Type::box(ctx, ty) + } + + pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type { + Type::opaque_box().ptr_to() + } + + pub fn enum_discrim(cx: &CrateContext) -> Type { + cx.int_type + } + + pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { + assert!(self.is_struct(), "Type must be a struct"); + + unsafe { + let vec : &[TypeRef] = cast::transmute(els); + llvm::LLVMStructSetBody(self.to_ref(), to_ptr(vec), + els.len() as c_uint, packed as Bool) + } + } +} From fd83b92b598219d74317406a25234d572de584e0 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 02:29:52 +1200 Subject: [PATCH 045/336] More Type refactorings --- src/librustc/back/upcall.rs | 61 ++-- src/librustc/lib/llvm.rs | 12 - src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/adt.rs | 32 +- src/librustc/middle/trans/asm.rs | 8 +- src/librustc/middle/trans/base.rs | 465 +++++++++---------------- src/librustc/middle/trans/build.rs | 209 ++++++----- src/librustc/middle/trans/cabi.rs | 18 +- src/librustc/middle/trans/cabi_arm.rs | 65 ++-- src/librustc/middle/trans/cabi_mips.rs | 20 +- src/librustc/middle/trans/common.rs | 32 +- src/librustc/middle/trans/context.rs | 3 +- src/librustc/middle/trans/type_.rs | 121 +++++-- 13 files changed, 470 insertions(+), 578 deletions(-) diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 4d2ea4eb4a64..731fa1c0ad79 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -11,8 +11,8 @@ use driver::session; use middle::trans::base; -use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void}; -use lib::llvm::{ModuleRef, ValueRef, TypeRef}; +use middle::trans::type_::Type; +use lib::llvm::{ModuleRef, ValueRef}; pub struct Upcalls { trace: ValueRef, @@ -22,40 +22,35 @@ pub struct Upcalls { reset_stack_limit: ValueRef } -pub fn declare_upcalls(targ_cfg: @session::config, - llmod: ModuleRef) -> @Upcalls { - fn decl(llmod: ModuleRef, prefix: ~str, name: ~str, - tys: ~[TypeRef], rv: TypeRef) -> - ValueRef { - let arg_tys = tys.map(|t| *t); - let fn_ty = T_fn(arg_tys, rv); - return base::decl_cdecl_fn(llmod, prefix + name, fn_ty); - } - fn nothrow(f: ValueRef) -> ValueRef { - base::set_no_unwind(f); f - } - let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef = - |a,b,c| decl(llmod, ~"upcall_", a, b, c); - let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef = - |a,b| decl(llmod, ~"upcall_", a, b, T_void()); +macro_rules! upcall ( + (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ + let fn_ty = Type::func([ $($arg),* ], $ret); + base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty) + }); + (nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ + let fn_ty = Type::func([ $($arg),* ], $ret); + let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); + base::set_no_unwind(decl); + decl + }); + (nothrow fn $name:ident -> $ret:expr) => ({ + let fn_ty = Type::func([], $ret); + let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); + base::set_no_unwind(decl); + decl + }) +) - let int_t = T_int(targ_cfg); +pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { + let opaque_ptr = Type::i8().to_ptr(); + let int_ty = Type::int(targ_cfg.arch); @Upcalls { - trace: dv(~"trace", ~[T_ptr(T_i8()), - T_ptr(T_i8()), - int_t]), - call_shim_on_c_stack: - d(~"call_shim_on_c_stack", - // arguments: void *args, void *fn_ptr - ~[T_ptr(T_i8()), T_ptr(T_i8())], - int_t), + trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()), + call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty), call_shim_on_rust_stack: - d(~"call_shim_on_rust_stack", - ~[T_ptr(T_i8()), T_ptr(T_i8())], int_t), - rust_personality: - nothrow(d(~"rust_personality", ~[], T_i32())), - reset_stack_limit: - nothrow(dv(~"reset_stack_limit", ~[])) + upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty), + rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()), + reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void()) } } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 14f5166b123a..627474b21892 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2233,18 +2233,6 @@ pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] { } } -pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; - if n_elts == 0 { - return ~[]; - } - let mut elts = vec::from_elem(n_elts, ptr::null()); - llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); - return elts; - } -} - /* Memory-managed interface to target data. */ diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 2b46b3b27248..db5a642019c0 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1644,7 +1644,7 @@ fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap { // but during matching we need to store a *T as explained // above let is_move = ccx.maps.moves_map.contains(&p_id); - llmatch = alloca(bcx, T_ptr(llvariable_ty)); + llmatch = alloca(bcx, llvariable_ty.ptr_to()); trmode = TrByValue(is_move, alloca(bcx, llvariable_ty)); } ast::bind_by_ref(_) => { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 79b5aba227c3..65163e384b1f 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -49,7 +49,7 @@ use core::libc::c_ulonglong; use core::option::{Option, Some, None}; use core::vec; -use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE}; +use lib::llvm::{ValueRef, True, IntEQ, IntNE}; use middle::trans::_match; use middle::trans::build::*; use middle::trans::common::*; @@ -212,7 +212,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty)); - let llty_rec = T_struct(lltys, packed); + let llty_rec = Type::struct_(lltys, packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64, align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64, @@ -226,17 +226,16 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { * All nominal types are LLVM structs, in order to be able to use * forward-declared opaque types to prevent circularity in `type_of`. */ -pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, false) } /// Like `fields_of`, but for `type_of::sizing_type_of` (q.v.). -pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, true) } -fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) - -> ~[TypeRef] { +fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { match *r { - CEnum(*) => ~[T_enum_discrim(cx)], + CEnum(*) => ~[Type::enum_discrim(cx)], Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing), NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing), General(ref sts) => { @@ -261,14 +260,15 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) let most_aligned = most_aligned.get(); let padding = largest_size - most_aligned.size; + assert!(padding >= 0); + struct_llfields(cx, most_aligned, sizing) - + [T_array(T_i8(), padding /*bad*/as uint)] + + [Type::array(Type::i8(), padding /*bad*/as uint)] } } } -fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) - -> ~[TypeRef] { +fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) -> ~[Type] { if sizing { st.fields.map(|&ty| type_of::sizing_type_of(cx, ty)) } else { @@ -309,7 +309,7 @@ pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef) (cases.len() - 1) as int), NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee), - T_enum_discrim(bcx.ccx())) + Type::enum_discrim(bcx.ccx())) } } } @@ -438,11 +438,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, } else { // The unit-like case might have a nonzero number of unit-like fields. // (e.g., Result or Either with () as one side.) - let llty = type_of::type_of(bcx.ccx(), nullfields[ix]); + let ty = type_of::type_of(bcx.ccx(), nullfields[ix]); assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0); // The contents of memory at this pointer can't matter, but use // the value that's "reasonable" in case of pointer comparison. - PointerCast(bcx, val, T_ptr(llty)) + PointerCast(bcx, val, ty.ptr_to()) } } } @@ -456,8 +456,8 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, let fields = do st.fields.map |&ty| { type_of::type_of(ccx, ty) }; - let real_llty = T_struct(fields, st.packed); - PointerCast(bcx, val, T_ptr(real_llty)) + let real_ty = Type::struct_(fields, st.packed); + PointerCast(bcx, val, real_llty.to_ptr().to_ref()) } else { val }; @@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef]) } fn padding(size: u64) -> ValueRef { - C_undef(T_array(T_i8(), size /*bad*/as uint)) + C_undef(Type::array(Type::i8(), size).to_ref()) } // XXX this utility routine should be somewhere more general diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 3814ff319f2d..17294107ce36 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -110,11 +110,11 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Depending on how many outputs we have, the return type is different let output = if numOutputs == 0 { - T_void() + Type::void() } else if numOutputs == 1 { val_ty(outputs[0]) } else { - T_struct(outputs.map(|o| val_ty(*o)), false) + Type::struct_(outputs.map(|o| val_ty(*o)), false) }; let dialect = match ia.dialect { @@ -130,12 +130,12 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Again, based on how many outputs we have if numOutputs == 1 { - let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); + let op = PointerCast(bcx, aoutputs[0], val_ty(outputs[0]).ptr_to()); Store(bcx, r, op); } else { for aoutputs.iter().enumerate().advance |(i, o)| { let v = ExtractValue(bcx, r, i); - let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i]))); + let op = PointerCast(bcx, *o, val_ty(outputs[i]).ptr_to()); Store(bcx, v, op); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 18d87b46e193..de91a9c593a5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -29,7 +29,7 @@ use back::link::{mangle_exported_name}; use back::{link, abi}; use driver::session; use driver::session::Session; -use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef, BasicBlockRef}; +use lib::llvm::{ContextRef, ModuleRef, ValueRef, BasicBlockRef}; use lib::llvm::{llvm, True, False}; use lib; use metadata::common::LinkMeta; @@ -138,42 +138,33 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } -pub fn decl_fn(llmod: ModuleRef, - name: &str, - cc: lib::llvm::CallConv, - llty: TypeRef) - -> ValueRef { - let llfn: ValueRef = str::as_c_str(name, |buf| { +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 { - llvm::LLVMGetOrInsertFunction(llmod, buf, llty) + llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref()) } - }); + }; lib::llvm::SetFunctionCallConv(llfn, cc); return llfn; } -pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, llty: TypeRef) - -> ValueRef { +pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { return decl_fn(llmod, name, lib::llvm::CCallConv, llty); } // Only use this if you are going to actually define the function. It's // not valid to simply declare a function as internal. -pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> - ValueRef { - let llfn = decl_cdecl_fn(llmod, name, llty); +pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, ty: Type) -> ValueRef { + let llfn = decl_cdecl_fn(llmod, name, ty); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); return llfn; } -pub fn get_extern_fn(externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - cc: lib::llvm::CallConv, - ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, +pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: @str, + cc: lib::llvm::CallConv, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } let f = decl_fn(llmod, name, cc, ty); @@ -182,43 +173,19 @@ pub fn get_extern_fn(externs: &mut ExternMap, } pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, - name: @str, ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, + name: @str, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } unsafe { - let c = str::as_c_str(name, |buf| { - llvm::LLVMAddGlobal(llmod, ty, buf) - }); + let c = do name.as_c_str |buf| { + llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf) + }; externs.insert(name, c); return c; } } - -fn get_simple_extern_fn(cx: block, - externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - n_args: int) -> ValueRef { - let _icx = cx.insn_ctxt("get_simple_extern_fn"); - let ccx = cx.fcx.ccx; - let inputs = vec::from_elem(n_args as uint, ccx.int_type); - let output = ccx.int_type; - let t = T_fn(inputs, output); - return get_extern_fn(externs, llmod, name, lib::llvm::CCallConv, t); -} - -pub fn trans_foreign_call(cx: block, externs: &mut ExternMap, - llmod: ModuleRef, name: @str, args: &[ValueRef]) -> - ValueRef { - let _icx = cx.insn_ctxt("trans_foreign_call"); - let n = args.len() as int; - let llforeign: ValueRef = - get_simple_extern_fn(cx, externs, llmod, name, n); - return Call(cx, llforeign, args); -} - pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("umax"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); @@ -236,7 +203,7 @@ pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { // return type, use bump_ptr(). pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { let _icx = bcx.insn_ctxt("ptr_offs"); - let raw = PointerCast(bcx, base, T_ptr(T_i8())); + let raw = PointerCast(bcx, base, Type::i8p()); InBoundsGEP(bcx, raw, [sz]) } @@ -247,7 +214,7 @@ pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> let _icx = bcx.insn_ctxt("bump_ptr"); let ccx = bcx.ccx(); let bumped = ptr_offs(bcx, base, sz); - let typ = T_ptr(type_of(ccx, t)); + let typ = type_of(ccx, t).ptr_to(); PointerCast(bcx, bumped, typ) } @@ -262,8 +229,8 @@ pub fn opaque_box_body(bcx: block, let _icx = bcx.insn_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); - let ty = T_box(ccx, ty); - let boxptr = PointerCast(bcx, boxptr, T_ptr(ty)); + let ty = Type::box(ccx, ty); + let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); GEPi(bcx, boxptr, [0u, abi::box_field_body]) } @@ -294,8 +261,8 @@ pub fn malloc_raw_dyn(bcx: block, glue::lazily_emit_all_tydesc_glue(ccx, static_ti); // Allocate space: - let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8())); - let rval = alloca(bcx, T_ptr(T_i8())); + let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, langcall, @@ -320,7 +287,7 @@ pub fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef { add_comment(bcx, "non_gc_box_cast"); assert!(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == gc_box_addrspace || bcx.unreachable); - let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val))); + let non_gc_t = llvm::LLVMGetElementType(val_ty(val)).ptr_to(); PointerCast(bcx, val, non_gc_t) } } @@ -760,8 +727,8 @@ pub fn cast_shift_const_rhs(op: ast::binop, pub fn cast_shift_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef, - trunc: &fn(ValueRef, TypeRef) -> ValueRef, - zext: &fn(ValueRef, TypeRef) -> ValueRef) + trunc: &fn(ValueRef, Type) -> ValueRef, + zext: &fn(ValueRef, Type) -> ValueRef) -> ValueRef { // Shifts may have any size int on the rhs unsafe { @@ -794,11 +761,11 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, }; let is_zero = match ty::get(rhs_t).sty { ty::ty_int(t) => { - let zero = C_integral(T_int_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, False); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } ty::ty_uint(t) => { - let zero = C_integral(T_uint_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, False); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } _ => { @@ -812,7 +779,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, } pub fn null_env_ptr(bcx: block) -> ValueRef { - C_null(T_opaque_box_ptr(bcx.ccx())) + C_null(Type::opaque_box(bcx.ccx()).to_ptr()) } pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) @@ -835,7 +802,7 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> (ValueRef, block) { let _icx = bcx.insn_ctxt("invoke_"); if bcx.unreachable { - return (C_null(T_i8()), bcx); + return (C_null(Type::i8()), bcx); } match bcx.node_info { @@ -968,7 +935,7 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { // The landing pad return type (the type being propagated). Not sure what // this represents but it's determined by the personality function and // this is what the EH proposal example uses. - let llretty = T_struct([T_ptr(T_i8()), T_i32()], false); + let llretty = Type::struct_([Type::i8p(), Type::i32()], false); // The exception handling personality function. This is the C++ // personality function __gxx_personality_v0, wrapped in our naming // convention. @@ -1026,7 +993,7 @@ pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block { pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef { if ty::type_is_bot(t) { - return C_null(T_ptr(T_i8())); + return C_null(Type::i8p()); } let llptr = alloc_ty(bcx, t); Store(bcx, v, llptr); @@ -1069,8 +1036,8 @@ pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { } }; let ccx = bcx.ccx(); - let V_trace_str = PointerCast(bcx, V_trace_str, T_ptr(T_i8())); - let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8())); + let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p()); + let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)]; Call(bcx, ccx.upcalls.trace, args); } @@ -1466,8 +1433,8 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; let memcpy = ccx.intrinsics.get_copy(&key); - let src_ptr = PointerCast(cx, src, T_ptr(T_i8())); - let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8())); + let src_ptr = PointerCast(cx, src, Type::i8p()); + let dst_ptr = PointerCast(cx, dst, Type::i8p()); let size = IntCast(cx, n_bytes, ccx.int_type); let align = C_i32(align as i32); let volatile = C_i1(false); @@ -1510,10 +1477,10 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { }; let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key); - let llptr = PointerCast(cx, llptr, T_ptr(T_i8())); + let llptr = PointerCast(cx, llptr, Type::i8().ptr_to()); let llzeroval = C_u8(0); - let size = IntCast(cx, machine::llsize_of(ccx, llty), ccx.int_type); - let align = C_i32(llalign_of_min(ccx, llty) as i32); + let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type.to_ref()); + let align = C_i32(llalign_of_min(ccx, ty) as i32); let volatile = C_i1(false); Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]); } @@ -1521,39 +1488,37 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef { let _icx = bcx.insn_ctxt("alloc_ty"); let ccx = bcx.ccx(); - let llty = type_of::type_of(ccx, t); - if ty::type_has_params(t) { debug!("%s", ty_to_str(ccx.tcx, t)); } - assert!(!ty::type_has_params(t)); - let val = alloca(bcx, llty); + let ty = type_of::type_of(ccx, t); + assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t)); + let val = alloca(bcx, ty); return val; } -pub fn alloca(cx: block, t: TypeRef) -> ValueRef { - alloca_maybe_zeroed(cx, t, false) +pub fn alloca(cx: block, ty: Type) -> ValueRef { + alloca_maybe_zeroed(cx, ty, false) } pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { let _icx = cx.insn_ctxt("alloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty.to_ref()); } } let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); - let p = Alloca(initcx, t); - if zero { memzero(initcx, p, t); } - return p; + let p = Alloca(initcx, ty.to_ref()); + if zero { memzero(initcx, p, ty); } + p } pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("arrayalloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty); } } - return ArrayAlloca( - base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty.to_ref(), v); } pub struct BasicBlocks { @@ -1623,7 +1588,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { - llvm::LLVMGetUndef(T_ptr(T_i8())) + llvm::LLVMGetUndef(Type::i8p()) }, llretptr: None, llstaticallocas: llbbs.sa, @@ -1741,7 +1706,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, Store(bcx, tmp, alloc); alloc } else { - PointerCast(bcx, slf.v, T_ptr(type_of(bcx.ccx(), slf.t))) + PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) }; fcx.llself = Some(ValSelfData {v: self_val, ..slf}); @@ -2268,7 +2233,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, attrs: &[ast::attribute], node_type: ty::t, cc: lib::llvm::CallConv, - llfty: TypeRef) + fn_ty: Type) -> ValueRef { debug!("register_fn_fuller creating fn for item %d with path %s", node_id, @@ -2280,12 +2245,11 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, mangle_exported_name(ccx, /*bad*/copy path, node_type) }; - let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty); + let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty); ccx.item_symbols.insert(node_id, ps); // FIXME #4404 android JNI hacks - let is_entry = is_entry_fn(&ccx.sess, node_id) && - (!*ccx.sess.building_library || + let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library || (*ccx.sess.building_library && ccx.sess.targ_cfg.os == session::os_android)); if is_entry { @@ -2345,7 +2309,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, fn create_entry_fn(ccx: @mut CrateContext, rust_main: ValueRef, use_start_lang_item: bool) { - let llfty = T_fn([ccx.int_type, T_ptr(T_ptr(T_i8()))], ccx.int_type); + let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], ccx.int_type); // FIXME #4404 android JNI hacks let llfn = if *ccx.sess.building_library { @@ -2376,7 +2340,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, let crate_map = ccx.crate_map; let opaque_crate_map = llvm::LLVMBuildPointerCast(bld, crate_map, - T_ptr(T_i8()), + Type::i8p(), noname()); let (start_fn, args) = if use_start_lang_item { @@ -2391,10 +2355,10 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, let args = { let opaque_rust_main = llvm::LLVMBuildPointerCast( - bld, rust_main, T_ptr(T_i8()), noname()); + bld, rust_main, Type::i8p(), noname()); ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), opaque_rust_main, llvm::LLVMGetParam(llfn, 0), llvm::LLVMGetParam(llfn, 1), @@ -2406,7 +2370,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, debug!("using user-defined start fn"); let args = { ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), llvm::LLVMGetParam(llfn, 0 as c_uint), llvm::LLVMGetParam(llfn, 1 as c_uint), opaque_crate_map @@ -2432,7 +2396,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef, let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]); Store(bcx, llfn, code_cell); let env_cell = GEPi(bcx, pair, [0u, abi::fn_field_box]); - let llenvblobptr = PointerCast(bcx, llenvptr, T_opaque_box_ptr(ccx)); + let llenvblobptr = PointerCast(bcx, llenvptr, Type::opaque_box(ccx).ptr_to()); Store(bcx, llenvblobptr, env_cell); } @@ -2656,215 +2620,98 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef { } } -pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { - let T_memcpy32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i32(), T_i32(), T_i1()]; - let T_memcpy64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i64(), T_i32(), T_i1()]; - let T_memset32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i32(), T_i32(), T_i1()]; - let T_memset64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()]; - let T_trap_args: ~[TypeRef] = ~[]; - let T_frameaddress_args: ~[TypeRef] = ~[T_i32()]; - let gcroot = - decl_cdecl_fn(llmod, "llvm.gcroot", - T_fn([T_ptr(T_ptr(T_i8())), T_ptr(T_i8())], - T_void())); - let gcread = - decl_cdecl_fn(llmod, "llvm.gcread", - T_fn([T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))], - T_void())); - let memcpy32 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); - let memcpy64 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64", - T_fn(T_memcpy64_args, T_void())); - let memmove32 = - decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); - let memmove64 = - decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i64", - T_fn(T_memcpy64_args, T_void())); - let memset32 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i32", - T_fn(T_memset32_args, T_void())); - let memset64 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i64", - T_fn(T_memset64_args, T_void())); - let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, - T_void())); - let frameaddress = decl_cdecl_fn(llmod, "llvm.frameaddress", - T_fn(T_frameaddress_args, - T_ptr(T_i8()))); - let sqrtf32 = decl_cdecl_fn(llmod, "llvm.sqrt.f32", - T_fn([T_f32()], T_f32())); - let sqrtf64 = decl_cdecl_fn(llmod, "llvm.sqrt.f64", - T_fn([T_f64()], T_f64())); - let powif32 = decl_cdecl_fn(llmod, "llvm.powi.f32", - T_fn([T_f32(), T_i32()], T_f32())); - let powif64 = decl_cdecl_fn(llmod, "llvm.powi.f64", - T_fn([T_f64(), T_i32()], T_f64())); - let sinf32 = decl_cdecl_fn(llmod, "llvm.sin.f32", - T_fn([T_f32()], T_f32())); - let sinf64 = decl_cdecl_fn(llmod, "llvm.sin.f64", - T_fn([T_f64()], T_f64())); - let cosf32 = decl_cdecl_fn(llmod, "llvm.cos.f32", - T_fn([T_f32()], T_f32())); - let cosf64 = decl_cdecl_fn(llmod, "llvm.cos.f64", - T_fn([T_f64()], T_f64())); - let powf32 = decl_cdecl_fn(llmod, "llvm.pow.f32", - T_fn([T_f32(), T_f32()], T_f32())); - let powf64 = decl_cdecl_fn(llmod, "llvm.pow.f64", - T_fn([T_f64(), T_f64()], T_f64())); - let expf32 = decl_cdecl_fn(llmod, "llvm.exp.f32", - T_fn([T_f32()], T_f32())); - let expf64 = decl_cdecl_fn(llmod, "llvm.exp.f64", - T_fn([T_f64()], T_f64())); - let exp2f32 = decl_cdecl_fn(llmod, "llvm.exp2.f32", - T_fn([T_f32()], T_f32())); - let exp2f64 = decl_cdecl_fn(llmod, "llvm.exp2.f64", - T_fn([T_f64()], T_f64())); - let logf32 = decl_cdecl_fn(llmod, "llvm.log.f32", - T_fn([T_f32()], T_f32())); - let logf64 = decl_cdecl_fn(llmod, "llvm.log.f64", - T_fn([T_f64()], T_f64())); - let log10f32 = decl_cdecl_fn(llmod, "llvm.log10.f32", - T_fn([T_f32()], T_f32())); - let log10f64 = decl_cdecl_fn(llmod, "llvm.log10.f64", - T_fn([T_f64()], T_f64())); - let log2f32 = decl_cdecl_fn(llmod, "llvm.log2.f32", - T_fn([T_f32()], T_f32())); - let log2f64 = decl_cdecl_fn(llmod, "llvm.log2.f64", - T_fn([T_f64()], T_f64())); - let fmaf32 = decl_cdecl_fn(llmod, "llvm.fma.f32", - T_fn([T_f32(), T_f32(), T_f32()], T_f32())); - let fmaf64 = decl_cdecl_fn(llmod, "llvm.fma.f64", - T_fn([T_f64(), T_f64(), T_f64()], T_f64())); - let fabsf32 = decl_cdecl_fn(llmod, "llvm.fabs.f32", - T_fn([T_f32()], T_f32())); - let fabsf64 = decl_cdecl_fn(llmod, "llvm.fabs.f64", - T_fn([T_f64()], T_f64())); - let floorf32 = decl_cdecl_fn(llmod, "llvm.floor.f32", - T_fn([T_f32()], T_f32())); - let floorf64 = decl_cdecl_fn(llmod, "llvm.floor.f64", - T_fn([T_f64()], T_f64())); - let ceilf32 = decl_cdecl_fn(llmod, "llvm.ceil.f32", - T_fn([T_f32()], T_f32())); - let ceilf64 = decl_cdecl_fn(llmod, "llvm.ceil.f64", - T_fn([T_f64()], T_f64())); - let truncf32 = decl_cdecl_fn(llmod, "llvm.trunc.f32", - T_fn([T_f32()], T_f32())); - let truncf64 = decl_cdecl_fn(llmod, "llvm.trunc.f64", - T_fn([T_f64()], T_f64())); - let ctpop8 = decl_cdecl_fn(llmod, "llvm.ctpop.i8", - T_fn([T_i8()], T_i8())); - let ctpop16 = decl_cdecl_fn(llmod, "llvm.ctpop.i16", - T_fn([T_i16()], T_i16())); - let ctpop32 = decl_cdecl_fn(llmod, "llvm.ctpop.i32", - T_fn([T_i32()], T_i32())); - let ctpop64 = decl_cdecl_fn(llmod, "llvm.ctpop.i64", - T_fn([T_i64()], T_i64())); - let ctlz8 = decl_cdecl_fn(llmod, "llvm.ctlz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let ctlz16 = decl_cdecl_fn(llmod, "llvm.ctlz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let ctlz32 = decl_cdecl_fn(llmod, "llvm.ctlz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let ctlz64 = decl_cdecl_fn(llmod, "llvm.ctlz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let cttz8 = decl_cdecl_fn(llmod, "llvm.cttz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let cttz16 = decl_cdecl_fn(llmod, "llvm.cttz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let cttz32 = decl_cdecl_fn(llmod, "llvm.cttz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let cttz64 = decl_cdecl_fn(llmod, "llvm.cttz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let bswap16 = decl_cdecl_fn(llmod, "llvm.bswap.i16", - T_fn([T_i16()], T_i16())); - let bswap32 = decl_cdecl_fn(llmod, "llvm.bswap.i32", - T_fn([T_i32()], T_i32())); - let bswap64 = decl_cdecl_fn(llmod, "llvm.bswap.i64", - T_fn([T_i64()], T_i64())); +macro_rules! ifn ( + ($name:expr, $args:expr, $ret:expr) => ({ + let name = $name; + let f = decl_cdecl_fn(llmod, name, Type::func($args, $ret)); + intrinsics.insert(name, f); + }) +) +pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { + let i8p = Type::i8p(); let mut intrinsics = HashMap::new(); - intrinsics.insert("llvm.gcroot", gcroot); - intrinsics.insert("llvm.gcread", gcread); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i32", memcpy32); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i64", memcpy64); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64); - intrinsics.insert("llvm.memset.p0i8.i32", memset32); - intrinsics.insert("llvm.memset.p0i8.i64", memset64); - intrinsics.insert("llvm.trap", trap); - intrinsics.insert("llvm.frameaddress", frameaddress); - intrinsics.insert("llvm.sqrt.f32", sqrtf32); - intrinsics.insert("llvm.sqrt.f64", sqrtf64); - intrinsics.insert("llvm.powi.f32", powif32); - intrinsics.insert("llvm.powi.f64", powif64); - intrinsics.insert("llvm.sin.f32", sinf32); - intrinsics.insert("llvm.sin.f64", sinf64); - intrinsics.insert("llvm.cos.f32", cosf32); - intrinsics.insert("llvm.cos.f64", cosf64); - intrinsics.insert("llvm.pow.f32", powf32); - intrinsics.insert("llvm.pow.f64", powf64); - intrinsics.insert("llvm.exp.f32", expf32); - intrinsics.insert("llvm.exp.f64", expf64); - intrinsics.insert("llvm.exp2.f32", exp2f32); - intrinsics.insert("llvm.exp2.f64", exp2f64); - intrinsics.insert("llvm.log.f32", logf32); - intrinsics.insert("llvm.log.f64", logf64); - intrinsics.insert("llvm.log10.f32", log10f32); - intrinsics.insert("llvm.log10.f64", log10f64); - intrinsics.insert("llvm.log2.f32", log2f32); - intrinsics.insert("llvm.log2.f64", log2f64); - intrinsics.insert("llvm.fma.f32", fmaf32); - intrinsics.insert("llvm.fma.f64", fmaf64); - intrinsics.insert("llvm.fabs.f32", fabsf32); - intrinsics.insert("llvm.fabs.f64", fabsf64); - intrinsics.insert("llvm.floor.f32", floorf32); - intrinsics.insert("llvm.floor.f64", floorf64); - intrinsics.insert("llvm.ceil.f32", ceilf32); - intrinsics.insert("llvm.ceil.f64", ceilf64); - intrinsics.insert("llvm.trunc.f32", truncf32); - intrinsics.insert("llvm.trunc.f64", truncf64); - intrinsics.insert("llvm.ctpop.i8", ctpop8); - intrinsics.insert("llvm.ctpop.i16", ctpop16); - intrinsics.insert("llvm.ctpop.i32", ctpop32); - intrinsics.insert("llvm.ctpop.i64", ctpop64); - intrinsics.insert("llvm.ctlz.i8", ctlz8); - intrinsics.insert("llvm.ctlz.i16", ctlz16); - intrinsics.insert("llvm.ctlz.i32", ctlz32); - intrinsics.insert("llvm.ctlz.i64", ctlz64); - intrinsics.insert("llvm.cttz.i8", cttz8); - intrinsics.insert("llvm.cttz.i16", cttz16); - intrinsics.insert("llvm.cttz.i32", cttz32); - intrinsics.insert("llvm.cttz.i64", cttz64); - intrinsics.insert("llvm.bswap.i16", bswap16); - intrinsics.insert("llvm.bswap.i32", bswap32); - intrinsics.insert("llvm.bswap.i64", bswap64); + + ifn!("llvm.memcpy.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memcpy.p0i8.p0i8.i64", + [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i64", + [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memset.p0i8.i32", + [i8p, Type::i8(), Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memcpy.p0i8.i64", + [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); + + ifn!("llvm.trap", [], Type::void()); + ifn!("llvm.frameaddress", [Type::i32()], i8p); + + ifn!("llvm.powi.f32", [Type::f32(), Type::i32()], Type::f32()); + ifn!("llvm.powi.f64", [Type::f64(), Type::i32()], Type::f64()); + ifn!("llvm.pow.f32", [Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.pow.f64", [Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.sqrt.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sqrt.f64", [Type::f64()], Type::f64()); + ifn!("llvm.sin.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sin.f64", [Type::f64()], Type::f64()); + ifn!("llvm.cos.f32", [Type::f32()], Type::f32()); + ifn!("llvm.cos.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp2.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log10.f32",[Type::f32()], Type::f32()); + ifn!("llvm.log10.f64",[Type::f64()], Type::f64()); + ifn!("llvm.log2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log2.f64", [Type::f64()], Type::f64()); + + ifn!("llvm.fma.f32", [Type::f32(), Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.fma.f64", [Type::f64(), Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.fabs.f32", [Type::f32()], Type::f32()); + ifn!("llvm.fabs.f64", [Type::f64()], Type::f64()); + ifn!("llvm.floor.f32",[Type::f32()], Type::f32()); + ifn!("llvm.floor.f64",[Type::f64()], Type::f64()); + ifn!("llvm.ceil.f32", [Type::f32()], Type::f32()); + ifn!("llvm.ceil.f64", [Type::f64()], Type::f64()); + ifn!("llvm.trunc.f32",[Type::f32()], Type::f32()); + ifn!("llvm.trunc.f64",[Type::f64()], Type::f64()); + + ifn!("llvm.ctpop.i8", [Type::i8()], Type::i8()); + ifn!("llvm.ctpop.i16",[Type::i16()], Type::i16()); + ifn!("llvm.ctpop.i32",[Type::i32()], Type::i32()); + ifn!("llvm.ctpop.i64",[Type::i64()], Type::i64()); + + ifn!("llvm.ctlz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.ctlz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.ctlz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.ctlz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.cttz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.cttz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.cttz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.cttz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.bswap.i16",[Type::i16()], Type::i16()); + ifn!("llvm.bswap.i32",[Type::i32()], Type::i32()); + ifn!("llvm.bswap.i64",[Type::i64()], Type::i64()); return intrinsics; } -pub fn declare_dbg_intrinsics(llmod: ModuleRef, - intrinsics: &mut HashMap<&'static str, ValueRef>) { - let declare = - decl_cdecl_fn(llmod, "llvm.dbg.declare", - T_fn([T_metadata(), T_metadata()], T_void())); - let value = - decl_cdecl_fn(llmod, "llvm.dbg.value", - T_fn([T_metadata(), T_i64(), T_metadata()], T_void())); - intrinsics.insert("llvm.dbg.declare", declare); - intrinsics.insert("llvm.dbg.value", value); +pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'static str, ValueRef>) { + ifn!("llvm.dbg.declare", [Type::metadata(), Type::metadata()], Type::void()); + ifn!("llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void()); } pub fn trap(bcx: block) { - let v: ~[ValueRef] = ~[]; - match bcx.ccx().intrinsics.find(& &"llvm.trap") { - Some(&x) => { Call(bcx, x, v); }, + match bcx.ccx().intrinsics.find_equiv("llvm.trap") { + Some(&x) => { Call(bcx, x, []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") } } @@ -2877,7 +2724,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id; let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) } }; unsafe { @@ -2888,8 +2735,8 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { } pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { - let elttype = T_struct([ccx.int_type, ccx.int_type], false); - let maptype = T_array(elttype, ccx.module_data.len() + 1); + let elttype = Type::struct_([ccx.int_type, ccx.int_type], false); + let maptype = Type::array(elttype, ccx.module_data.len() + 1); let map = str::as_c_str("_rust_mod_map", |buf| { unsafe { llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) @@ -2926,7 +2773,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, llmod: ModuleRef) -> ValueRef { let targ_cfg = sess.targ_cfg; - let int_type = T_int(targ_cfg); + let int_type = Type::int(targ_cfg.arch); let mut n_subcrates = 1; let cstore = sess.cstore; while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } @@ -2936,8 +2783,8 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, ~"toplevel" }; let sym_name = ~"_rust_crate_map_" + mapname; - let arrtype = T_array(int_type, n_subcrates as uint); - let maptype = T_struct([T_i32(), T_ptr(T_i8()), int_type, arrtype], false); + let arrtype = Type::array(int_type, n_subcrates as u64); + let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false); let map = str::as_c_str(sym_name, |buf| { unsafe { llvm::LLVMAddGlobal(llmod, maptype, buf) @@ -2984,7 +2831,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { llvm::LLVMSetInitializer(map, C_struct( [C_i32(1), lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, - T_ptr(T_i8())), + Type::i8p()), p2i(ccx, mod_map), C_array(ccx.int_type, subcrates)])); } @@ -3032,11 +2879,11 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { }); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - let t_ptr_i8 = T_ptr(T_i8()); + let t_ptr_i8 = Type::i8p(); llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8); - let llvm_used = str::as_c_str("llvm.used", |buf| { - llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf) - }); + let llvm_used = do "llvm.used".as_c_str |buf| { + llvm::LLVMAddGlobal(cx.llmod, Type::array(t_ptr_i8, 1u), buf) + }; lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage); llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal])); } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index f6c9c15f19bd..be14da66a162 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -13,7 +13,7 @@ use core::prelude::*; use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; use lib::llvm::{Opcode, IntPredicate, RealPredicate, False}; -use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef}; +use lib::llvm::{ValueRef, Type, BasicBlockRef, BuilderRef, ModuleRef}; use lib; use middle::trans::common::*; use middle::trans::machine::llalign_of_min; @@ -186,7 +186,7 @@ pub fn Invoke(cx: block, Catch: BasicBlockRef) -> ValueRef { if cx.unreachable { - return C_null(T_i8()); + return C_null(Type::i8()); } check_not_terminated(cx); terminate(cx, "Invoke"); @@ -486,35 +486,35 @@ pub fn Not(cx: block, V: ValueRef) -> ValueRef { } /* Memory */ -pub fn Malloc(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Malloc(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "malloc"); - return llvm::LLVMBuildMalloc(B(cx), Ty, noname()); + return llvm::LLVMBuildMalloc(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "arraymalloc"); - return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayMalloc(B(cx), Ty.to_ref(), Val, noname()); } } -pub fn Alloca(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Alloca(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } count_insn(cx, "alloca"); - return llvm::LLVMBuildAlloca(B(cx), Ty, noname()); + return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } count_insn(cx, "arrayalloca"); - return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname()); } } @@ -597,7 +597,7 @@ pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrderin pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "gep"); return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); @@ -617,7 +617,7 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "inboundsgep"); return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), @@ -628,7 +628,7 @@ pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "structgep"); return llvm::LLVMBuildStructGEP(B(cx), Pointer, @@ -639,7 +639,7 @@ pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } count_insn(cx, "globalstring"); return llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } @@ -647,163 +647,163 @@ pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } count_insn(cx, "globalstringptr"); return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } } /* Casts */ -pub fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn Trunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "trunc"); - return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zext"); - return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sext"); - return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToUI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptoui"); - return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToSI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptosi"); - return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy.to_ref(),noname()); } } -pub fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn UIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "uitofp"); - return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sitofp"); - return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptrunc"); - return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpext"); - return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "ptrtoint"); - return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "inttoptr"); - return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn BitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "bitcast"); - return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zextorbitcast"); - return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sextorbitcast"); - return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "truncorbitcast"); - return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _: *u8) +pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } count_insn(cx, "cast"); - return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } + return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy.to_ref(), noname()); } } -pub fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PointerCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "pointercast"); - return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "intcast"); - return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpcast"); - return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPCast(B(cx), Val, DestTy.to_ref(), noname()); } } @@ -812,7 +812,7 @@ pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "icmp"); return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname()); } @@ -821,27 +821,27 @@ pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) pub fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "fcmp"); return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname()); } } /* Miscellaneous instructions */ -pub fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef { +pub fn EmptyPhi(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "emptyphi"); - return llvm::LLVMBuildPhi(B(cx), Ty, noname()); + return llvm::LLVMBuildPhi(B(cx), Ty.to_ref(), noname()); } } -pub fn Phi(cx: block, Ty: TypeRef, vals: &[ValueRef], bbs: &[BasicBlockRef]) +pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } assert_eq!(vals.len(), bbs.len()); - let phi = EmptyPhi(cx, Ty); + let phi = EmptyPhi(cx, Ty.to_ref()); count_insn(cx, "addincoming"); llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals), vec::raw::to_ptr(bbs), @@ -886,12 +886,9 @@ pub fn add_comment(bcx: block, text: &str) { let sanitized = text.replace("$", ""); let comment_text = ~"# " + sanitized.replace("\n", "\n\t# "); + count_insn(bcx, "inlineasm"); let asm = str::as_c_str(comment_text, |c| { - str::as_c_str("", |e| { - count_insn(bcx, "inlineasm"); - llvm::LLVMConstInlineAsm(T_fn([], T_void()), c, e, - False, False) - }) + llvm::LLVMConstInlineAsm(Type::func([], Type::void()), c, noname(), False, False) }); Call(bcx, asm, []); } @@ -899,7 +896,7 @@ pub fn add_comment(bcx: block, text: &str) { } pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, - inputs: &[ValueRef], output: TypeRef, + inputs: &[ValueRef], output: Type, volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { unsafe { @@ -916,9 +913,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, }; debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); - let llfty = T_fn(argtys, output); - let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, - alignstack, dia as c_uint); + let fty = Type::func(argtys, output); + let v = llvm::LLVMInlineAsm(llfty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); Call(cx, v, inputs) } @@ -971,18 +967,18 @@ pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> } } -pub fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef { +pub fn VAArg(cx: block, list: ValueRef, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "vaarg"); - return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); + return llvm::LLVMBuildVAArg(B(cx), list, Ty.to_ref(), noname()); } } pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractelement"); return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); } @@ -991,7 +987,7 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "insertelement"); llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()) } @@ -1000,7 +996,7 @@ pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, Mask: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "shufflevector"); llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()) } @@ -1008,15 +1004,16 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { unsafe { - let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts)); + let elt_ty = val_ty(EltVal); + let Undef = llvm::LLVMGetUndef(Type::vector(elt_ty, NumElts).to_ref()); let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0)); - ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts))) + ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(Type::i32().to_ref(), NumElts))) } } pub fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractvalue"); return llvm::LLVMBuildExtractValue( B(cx), AggVal, Index as c_uint, noname()); @@ -1035,7 +1032,7 @@ pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef, pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnull"); return llvm::LLVMBuildIsNull(B(cx), Val, noname()); } @@ -1043,7 +1040,7 @@ pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnotnull"); return llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); } @@ -1076,13 +1073,13 @@ pub fn Trap(cx: block) { } } -pub fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef, +pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef, NumClauses: uint) -> ValueRef { unsafe { check_not_terminated(cx); assert!(!cx.unreachable); count_insn(cx, "landingpad"); - return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, + return llvm::LLVMBuildLandingPad(B(cx), Ty.to_ref(), PersFn, NumClauses as c_uint, noname()); } } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index ced19ce57ad5..036f34b1974e 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -26,7 +26,7 @@ pub trait ABIInfo { pub struct LLVMType { cast: bool, - ty: TypeRef + ty: Type } pub struct FnType { @@ -37,10 +37,10 @@ pub struct FnType { } impl FnType { - pub fn decl_fn(&self, decl: &fn(fnty: TypeRef) -> ValueRef) -> ValueRef { + pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef { let atys = vec::map(self.arg_tys, |t| t.ty); let rty = self.ret_ty.ty; - let fnty = T_fn(atys, rty); + let fnty = Type::func(atys, rty); let llfn = decl(fnty); for self.attrs.iter().enumerate().advance |(i, a)| { @@ -59,7 +59,7 @@ impl FnType { pub fn build_shim_args(&self, bcx: block, - arg_tys: &[TypeRef], + arg_tys: &[Type], llargbundle: ValueRef) -> ~[ValueRef] { let mut atys: &[LLVMType] = self.arg_tys; @@ -96,7 +96,7 @@ impl FnType { pub fn build_shim_ret(&self, bcx: block, - arg_tys: &[TypeRef], + arg_tys: &[Type], ret_def: bool, llargbundle: ValueRef, llretval: ValueRef) { @@ -132,7 +132,7 @@ impl FnType { pub fn build_wrap_args(&self, bcx: block, - ret_ty: TypeRef, + ret_ty: Type, llwrapfn: ValueRef, llargbundle: ValueRef) { let mut atys: &[LLVMType] = self.arg_tys; @@ -145,7 +145,7 @@ impl FnType { get_param(llwrapfn, 0u) } else if self.ret_ty.cast { let retptr = alloca(bcx, self.ret_ty.ty); - BitCast(bcx, retptr, T_ptr(ret_ty)) + BitCast(bcx, retptr, ret_ty.ptr_to()) } else { alloca(bcx, ret_ty) }; @@ -182,14 +182,14 @@ impl FnType { if bcx.fcx.llretptr.is_some() { let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]); let llretval = if self.ret_ty.cast { - let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty)); + let retptr = BitCast(bcx, llretval, self.ret_ty.ty.ptr_to()); Load(bcx, retptr) } else { Load(bcx, llretval) }; let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), - T_ptr(self.ret_ty.ty)); + self.ret_ty.ty.ptr_to()); Store(bcx, llretval, llretptr); } } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 9ad66c066715..f29ccad76b17 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -10,12 +10,9 @@ use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::struct_tys; -use lib::llvm::TypeRef; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; -use middle::trans::common::{T_i8, T_i16, T_i32, T_i64}; -use middle::trans::common::{T_array, T_ptr, T_void}; use core::option::{Option, None, Some}; use core::uint; @@ -24,102 +21,102 @@ fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn ty_align(ty: TypeRef) -> uint { +fn ty_align(ty: Type) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } Pointer => 4, Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { + if ty.is_packed() { 1 } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) } } Array => { - let elt = llvm::LLVMGetElementType(ty); + let elt = ty.element_type(); ty_align(elt) } _ => fail!("ty_align: unhandled type") - }; + } } } -fn ty_size(ty: TypeRef) -> uint { +fn ty_size(ty: Type) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } Pointer => 4, Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); + if ty.is_packed() { + let str_tys = ty.field_types(); str_tys.iter().fold(0, |s, t| s + ty_size(*t)) } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); align(size, ty) } } Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); + let len = ty.array_length(); + let elt = ty.element_type(); let eltsz = ty_size(elt); len * eltsz } _ => fail!("ty_size: unhandled type") - }; + } } } -fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_ret_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let size = ty_size(ty); if size <= 4 { let llty = if size <= 1 { - T_i8() + Type::i8() } else if size <= 2 { - T_i16() + Type::i16() } else { - T_i32() + Type::i32() }; return (LLVMType { cast: true, ty: llty }, None); } - (LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute)) + (LLVMType { cast: false, ty: ty.ptr_to() }, Some(StructRetAttribute)) } -fn classify_arg_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_arg_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - T_array(T_i32(), (size + 3) / 4) + Type::array(Type::i32(), (size + 3) / 4) } else { - T_array(T_i64(), (size + 7) / 8) + Type::array(Type::i64(), (size + 7) / 8) }; (LLVMType { cast: true, ty: llty }, None) } -fn is_reg_ty(ty: TypeRef) -> bool { +fn is_reg_ty(ty: Type) -> bool { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer | Pointer | Float @@ -133,8 +130,8 @@ enum ARM_ABIInfo { ARM_ABIInfo } impl ABIInfo for ARM_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut arg_tys = ~[]; let mut attrs = ~[]; @@ -147,14 +144,14 @@ impl ABIInfo for ARM_ABIInfo { let mut (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { - (LLVMType { cast: false, ty: T_void() }, None) + (LLVMType { cast: false, ty: Type::void() }, None) }; let sret = ret_attr.is_some(); if sret { arg_tys.unshift(ret_ty); attrs.unshift(ret_attr); - ret_ty = LLVMType { cast: false, ty: T_void() }; + ret_ty = LLVMType { cast: false, ty: Type::void() }; } return FnType { diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 0c771d21da5c..de988493b471 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -14,9 +14,9 @@ use core::libc::c_uint; use core::ptr; use core::uint; use core::vec; -use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; -use lib::llvm::{Struct, Array, Attribute}; -use lib::llvm::{StructRetAttribute}; +use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; +use lib::llvm::struct_tys; +use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::context::task_llcx; use middle::trans::common::*; @@ -26,23 +26,11 @@ fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn struct_tys(ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n = llvm::LLVMCountStructElementTypes(ty); - if (n == 0) { - return ~[]; - } - let mut elts = vec::from_elem(n as uint, ptr::null()); - llvm::LLVMGetStructElementTypes(ty, &mut elts[0]); - return elts; - } -} - fn ty_align(ty: TypeRef) -> uint { unsafe { return match llvm::LLVMGetTypeKind(ty) { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b8bf295e809a..a72f9489abcc 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -690,8 +690,8 @@ impl block_ { self.ccx().tn.val_to_str(val) } - pub fn llty_str(&self, llty: TypeRef) -> ~str { - self.ccx().tn.type_to_str(llty) + pub fn llty_str(&self, ty: Type) -> ~str { + self.ccx().tn.type_to_str(ty) } pub fn ty_to_str(&self, t: ty::t) -> ~str { @@ -708,6 +708,7 @@ impl block_ { } } +/* // LLVM type constructors. pub fn T_void() -> TypeRef { unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); } @@ -931,19 +932,6 @@ pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef { return T_vec2(targ_cfg, T_i8()); } -// Let T be the content of a box @T. tuplify_box_ty(t) returns the -// representation of @T as a tuple (i.e., the ty::t version of what T_box() -// returns). -pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { - let ptr = ty::mk_ptr( - tcx, - ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} - ); - return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), - ptr, ptr, - t]); -} - pub fn T_box_header_fields(cx: &CrateContext) -> ~[TypeRef] { let ptr = T_ptr(T_i8()); return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr]; @@ -1025,6 +1013,20 @@ pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef { pub fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); } pub fn T_opaque_chan_ptr() -> TypeRef { return T_ptr(T_i8()); } +*/ + +// Let T be the content of a box @T. tuplify_box_ty(t) returns the +// representation of @T as a tuple (i.e., the ty::t version of what T_box() +// returns). +pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { + let ptr = ty::mk_ptr( + tcx, + ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} + ); + return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), + ptr, ptr, + t]); +} // LLVM constant constructors. diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index ed5c2aa2e0b9..ada0284e0e31 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -37,8 +37,7 @@ use extra::time; use syntax::ast; use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen,addrspace_gen}; -use middle::trans::common::{mono_id,T_int,T_float,T_tydesc,T_opaque_vec}; -use middle::trans::common::{new_namegen,new_addrspace_gen}; +use middle::trans::common::{mono_id,new_namegen,new_addrspace_gen}; use middle::trans::base::{decl_crate_map}; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 65f86c30ea30..851ff4511a03 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -10,15 +10,19 @@ use core::prelude::*; -use lib::llvm::{llvm, TypeRef, Bool, False, True}; +use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; + +use middle::ty; use middle::trans::context::CrateContext; use middle::trans::base; -use syntax::{ast,abi}; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::ast; +use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; +use back::abi; use core::vec; +use core::cast; use core::libc::{c_uint}; @@ -27,9 +31,7 @@ pub struct Type { } macro_rules! ty ( - ($e:expr) => ( Type::from_ref(unsafe { - - })) + ($e:expr) => ( Type::from_ref(unsafe { $e })) ) /** @@ -94,14 +96,18 @@ impl Type { Type::i32() } - pub fn int(arch: abi::Architecture) -> Type { + pub fn i8p() -> Type { + Type::i8().ptr_to() + } + + pub fn int(arch: Architecture) -> Type { match arch { X86 | Arm | Mips => Type::i32(), X86_64 => Type::i64() } } - pub fn float(_: abi::Architecture) -> Type { + pub fn float(_: Architecture) -> Type { // All architectures currently just use doubles as the default // float size Type::f64() @@ -136,7 +142,7 @@ impl Type { } } - pub fn size_t(arch: abi::Architecture) -> Type { + pub fn size_t(arch: Architecture) -> Type { Type::int(arch) } @@ -147,8 +153,6 @@ impl Type { } pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type { - assert!(fn_ty.is_func(), "`fn_ty` must be a function type"); - Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false) } @@ -186,7 +190,7 @@ impl Type { return ty; } - pub fn tydesc(arch: abi::Architecture) -> Type { + pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); let tydescpp = tydesc.ptr_to().ptr_to(); let pvoid = Type::i8().ptr_to(); @@ -197,7 +201,7 @@ impl Type { let int_ty = Type::int(arch); let elems = [ - int_type, int_type, + int_ty, int_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, pvoid, pvoid ]; @@ -207,21 +211,21 @@ impl Type { return tydesc; } - pub fn array(ty: &Type, len: uint) -> Type { + pub fn array(ty: &Type, len: u64) -> Type { ty!(llvm::LLVMArrayType(ty.to_ref(), len as c_uint)) } - pub fn vector(ty: &Type, len: uint) -> Type { + pub fn vector(ty: &Type, len: u64) -> Type { ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) } - pub fn vec(arch: abi::Architecture, ty: &Type) -> Type { + pub fn vec(arch: Architecture, ty: &Type) -> Type { Type::struct_( [ Type::int(arch), Type::int(arch), Type::array(ty, 0) ], false) } - pub fn opaque_vec(arch: abi::Architecture) -> Type { + pub fn opaque_vec(arch: Architecture) -> Type { Type::vec(arch, Type::i8()) } @@ -238,7 +242,7 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [t], false) + Type::struct_(Type::box_header_fields(ctx) + [ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { @@ -257,13 +261,88 @@ impl Type { cx.int_type } - pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { - assert!(self.is_struct(), "Type must be a struct"); + pub fn captured_tydescs(ctx: &CrateContext, num: uint) -> Type { + Type::struct_(vec::from_elem(num, ctx.tydesc_type.ptr_to()), false) + } + pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { + let tydesc_ptr = ctx.tydesc_type.ptr_to(); + match store { + ty::BoxTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::opaque_box(ctx).ptr_to() ], + false) + } + ty::UniqTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::unique(ctx, Type::i8()).ptr_to()], + false) + } + ty::RegionTraitStore(*) => { + Type::struct_( + [ tydesc_ptr, Type::i8().ptr_to() ], + false) + } + } + } + + pub fn kind(&self) -> TypeKind { + unsafe { + llvm::LLVMGetTypeKind(self.to_ref()) + } + } + + pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { unsafe { let vec : &[TypeRef] = cast::transmute(els); - llvm::LLVMStructSetBody(self.to_ref(), to_ptr(vec), + llvm::LLVMStructSetBody(self.to_ref(), vec::raw::to_ptr(vec), els.len() as c_uint, packed as Bool) } } + + pub fn ptr_to(&self) -> Type { + ty!(llvm::LLVMPointerType(self.to_ref())) + } + + pub fn get_field(&self, idx: uint) -> Type { + unsafe { + let num_fields = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint; + let mut elems = vec::from_elem(num_fields, 0 as TypeRef); + + llvm::LLVMGetStructElementTypes(self.to_ref(), vec::raw::to_mut_ptr(elems)); + + Type::from_ref(elems[idx]) + } + } + + pub fn is_packed(&self) -> bool { + unsafe { + llvm::LLVMIsPackedStruct(self.to_ref()) == True + } + } + + pub fn element_type(&self) -> Type { + unsafe { + Type::from_ref(llvm::LLVMGetElementType(self.to_ref())) + } + } + + pub fn array_length(&self) -> uint { + unsafe { + llvm::LLVMGetArrayLength(self.to_ref()) as uint + } + } + + pub fn field_types(&self) -> ~[Type] { + unsafe { + let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; + if n_elts == 0 { + return ~[]; + } + let mut elts = vec::from_elem(n_elts, 0 as TypeRef); + llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); + cast::transmute(elts) + } + } + } From befbd3a680e79672108845e1b2d9d5278f92659c Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 11:58:51 +1200 Subject: [PATCH 046/336] Add the rest of the atomic operations. This makes the handling of atomic operations more generic, which does impose a specific naming convention for the intrinsics, but that seems ok with me, rather than having an individual case for each name. It also adds the intrinsics to the the intrinsics file. --- src/librustc/middle/trans/foreign.rs | 176 +++------ src/librustc/middle/trans/type_use.rs | 61 ++- src/librustc/middle/typeck/check/mod.rs | 500 ++++++++++++------------ src/libstd/unstable/intrinsics.rs | 112 ++++++ 4 files changed, 464 insertions(+), 385 deletions(-) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 9516a8b83ab3..34898e20f1e4 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -11,7 +11,6 @@ use core::prelude::*; use back::{link, abi}; -use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; use lib::llvm::{TypeRef, ValueRef}; use lib; use middle::trans::base::*; @@ -578,118 +577,73 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let mut bcx = top_scope_block(fcx, None); let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); - match ccx.sess.str_of(item.ident).as_slice() { - "atomic_cxchg" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), + + let nm = ccx.sess.str_of(item.ident); + let name = nm.as_slice(); + + // This requires that atomic intrinsics follow a specific naming pattern: + // "atomic_[_], and no ordering means SeqCst + if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); + let order = if split.len() == 2 { + lib::llvm::SequentiallyConsistent + } else { + match split[2] { + "relaxed" => lib::llvm::Monotonic, + "acq" => lib::llvm::Acquire, + "rel" => lib::llvm::Release, + "acqrel" => lib::llvm::AcquireRelease, + _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic") + } + }; + + match split[1] { + "cxchg" => { + let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), + get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg + 2u), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "load" => { + let old = AtomicLoad(bcx, get_param(decl, first_real_arg), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "store" => { + AtomicStore(bcx, get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg), + order); + } + op => { + // These are all AtomicRMW ops + let atom_op = match op { + "xchg" => lib::llvm::Xchg, + "xadd" => lib::llvm::Add, + "xsub" => lib::llvm::Sub, + "and" => lib::llvm::And, + "nand" => lib::llvm::Nand, + "or" => lib::llvm::Or, + "xor" => lib::llvm::Xor, + "max" => lib::llvm::Max, + "min" => lib::llvm::Min, + "umax" => lib::llvm::UMax, + "umin" => lib::llvm::UMin, + _ => ccx.sess.fatal("Unknown atomic operation") + }; + + let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_acq" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_rel" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load_acq" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_store" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - SequentiallyConsistent); - } - "atomic_store_rel" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - Release); - } - "atomic_xchg" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_acq" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_rel" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); + order); + Store(bcx, old, fcx.llretptr.get()); + } } + + return; + } + + match name { "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 8c4ff4415641..4f532885c92f 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -117,46 +117,43 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) _, _) => { if abi.is_intrinsic() { - let flags = match cx.ccx.sess.str_of(i.ident).as_slice() { - "size_of" | "pref_align_of" | "min_align_of" | - "uninit" | "init" | "transmute" | "move_val" | - "move_val_init" => use_repr, + let nm = cx.ccx.sess.str_of(i.ident); + let name = nm.as_slice(); + let flags = if name.starts_with("atomic_") { + 0 + } else { + match name { + "size_of" | "pref_align_of" | "min_align_of" | + "uninit" | "init" | "transmute" | "move_val" | + "move_val_init" => use_repr, - "get_tydesc" | "needs_drop" => use_tydesc, + "get_tydesc" | "needs_drop" => use_tydesc, - "atomic_cxchg" | "atomic_cxchg_acq"| - "atomic_cxchg_rel"| "atomic_load" | - "atomic_load_acq" | "atomic_store" | - "atomic_store_rel"| "atomic_xchg" | - "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | - "atomic_xsub_acq" | "atomic_xchg_rel" | - "atomic_xadd_rel" | "atomic_xsub_rel" => 0, + "visit_tydesc" | "forget" | "frame_address" | + "morestack_addr" => 0, - "visit_tydesc" | "forget" | "frame_address" | - "morestack_addr" => 0, + "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | + "memset32" | "memset64" => use_repr, - "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | - "memset32" | "memset64" => use_repr, + "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | + "sinf32" | "sinf64" | "cosf32" | "cosf64" | + "powf32" | "powf64" | "expf32" | "expf64" | + "exp2f32" | "exp2f64" | "logf32" | "logf64" | + "log10f32"| "log10f64"| "log2f32" | "log2f64" | + "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | + "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | + "truncf32"| "truncf64" => 0, - "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | - "sinf32" | "sinf64" | "cosf32" | "cosf64" | - "powf32" | "powf64" | "expf32" | "expf64" | - "exp2f32" | "exp2f64" | "logf32" | "logf64" | - "log10f32"| "log10f64"| "log2f32" | "log2f64" | - "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | - "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | - "truncf32"| "truncf64" => 0, + "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, - "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, + "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, + "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, - "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, - "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, + "bswap16" | "bswap32" | "bswap64" => 0, - "bswap16" | "bswap32" | "bswap64" => 0, - - // would be cool to make these an enum instead of strings! - _ => fail!("unknown intrinsic in type_use") + // would be cool to make these an enum instead of strings! + _ => fail!("unknown intrinsic in type_use") + } }; for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;} } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 13ded5016793..1ac300271166 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3434,252 +3434,268 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } let tcx = ccx.tcx; - let str = ccx.tcx.sess.str_of(it.ident); - let (n_tps, inputs, output) = match str.as_slice() { - "size_of" | - "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), - "init" => (1u, ~[], param(ccx, 0u)), - "uninit" => (1u, ~[], param(ccx, 0u)), - "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), - "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), - "move_val" | "move_val_init" => { - (1u, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), - param(ccx, 0u) - ], - ty::mk_nil()) - } - "needs_drop" => (1u, ~[], ty::mk_bool()), + let nm = ccx.tcx.sess.str_of(it.ident); + let name = nm.as_slice(); + let (n_tps, inputs, output) = if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); - "atomic_cxchg" | "atomic_cxchg_acq"| "atomic_cxchg_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, - ty::re_bound(ty::br_anon(0)), - ty::mk_int()), - ty::mk_int(), - ty::mk_int() - ], - ty::mk_int()) - } - "atomic_load" | "atomic_load_acq" => { - (0, - ~[ - ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) - ], - ty::mk_int()) - } - "atomic_store" | "atomic_store_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_nil()) - } - "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | - "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_int()) + //We only care about the operation here + match split[1] { + "cxchg" => (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), + ty::mk_int(), + ty::mk_int() + ], ty::mk_int()), + "load" => (0, + ~[ + ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) + ], + ty::mk_int()), + "store" => (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_nil()), + + "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | + "min" | "umax" | "umin" => { + (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), ty::mk_int() ], ty::mk_int()) + } + + op => { + tcx.sess.span_err(it.span, + fmt!("unrecognized atomic operation function: `%s`", + op)); + return; + } } - "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "visit_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); - let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); - let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { - ty: tydesc_ty, - mutbl: ast::m_imm - }); - (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) - } - "frame_address" => { - let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { - purity: ast::impure_fn, - sigil: ast::BorrowedSigil, - onceness: ast::Once, - region: ty::re_bound(ty::br_anon(0)), - bounds: ty::EmptyBuiltinBounds(), - sig: ty::FnSig { - bound_lifetime_names: opt_vec::Empty, - inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], - output: ty::mk_nil() - } - }); - (0u, ~[fty], ty::mk_nil()) - } - "morestack_addr" => { - (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "memcpy32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), + } else { + match name { + "size_of" | + "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), + "init" => (1u, ~[], param(ccx, 0u)), + "uninit" => (1u, ~[], param(ccx, 0u)), + "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), + "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), + "move_val" | "move_val_init" => { + (1u, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), + param(ccx, 0u) + ], + ty::mk_nil()) + } + "needs_drop" => (1u, ~[], ty::mk_bool()), + + "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | + "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | + "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { + (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_int()) + } + + "get_tydesc" => { + // FIXME (#3730): return *intrinsic::tydesc, not *() + (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "visit_tydesc" => { + let tydesc_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memcpy64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memmove32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memmove64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memset32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memset64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u64() - ], - ty::mk_nil()) - } - "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powif32" => { - (0, - ~[ ty::mk_f32(), ty::mk_i32() ], - ty::mk_f32()) - } - "powif64" => { - (0, - ~[ ty::mk_f64(), ty::mk_i32() ], - ty::mk_f64()) - } - "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "powf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "fmaf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "fmaf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - ref other => { - tcx.sess.span_err(it.span, - fmt!("unrecognized intrinsic function: `%s`", - *other)); - return; + }); + (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) + } + "frame_address" => { + let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { + purity: ast::impure_fn, + sigil: ast::BorrowedSigil, + onceness: ast::Once, + region: ty::re_bound(ty::br_anon(0)), + bounds: ty::EmptyBuiltinBounds(), + sig: ty::FnSig { + bound_lifetime_names: opt_vec::Empty, + inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], + output: ty::mk_nil() + } + }); + (0u, ~[fty], ty::mk_nil()) + } + "morestack_addr" => { + (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "memcpy32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memcpy64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memmove32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memmove64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memset32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memset64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u64() + ], + ty::mk_nil()) + } + "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powif32" => { + (0, + ~[ ty::mk_f32(), ty::mk_i32() ], + ty::mk_f32()) + } + "powif64" => { + (0, + ~[ ty::mk_f64(), ty::mk_i32() ], + ty::mk_f64()) + } + "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "powf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "fmaf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "fmaf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + ref other => { + tcx.sess.span_err(it.span, + fmt!("unrecognized intrinsic function: `%s`", + *other)); + return; + } } }; let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 134250077853..e1daf6c81b2a 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -42,22 +42,38 @@ pub extern "rust-intrinsic" { /// Atomic compare and exchange, release ordering. pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int; + + /// Atomic load, sequentially consistent. pub fn atomic_load(src: &int) -> int; /// Atomic load, acquire ordering. pub fn atomic_load_acq(src: &int) -> int; + #[cfg(not(stage0))] + pub fn atomic_load_relaxed(src: &int) -> int; + /// Atomic store, sequentially consistent. pub fn atomic_store(dst: &mut int, val: int); /// Atomic store, release ordering. pub fn atomic_store_rel(dst: &mut int, val: int); + #[cfg(not(stage0))] + pub fn atomic_store_relaxed(dst: &mut int, val: int); + /// Atomic exchange, sequentially consistent. pub fn atomic_xchg(dst: &mut int, src: int) -> int; /// Atomic exchange, acquire ordering. pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int; /// Atomic exchange, release ordering. pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int; /// Atomic addition, sequentially consistent. pub fn atomic_xadd(dst: &mut int, src: int) -> int; @@ -65,6 +81,10 @@ pub extern "rust-intrinsic" { pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; /// Atomic addition, release ordering. pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int; /// Atomic subtraction, sequentially consistent. pub fn atomic_xsub(dst: &mut int, src: int) -> int; @@ -72,6 +92,98 @@ pub extern "rust-intrinsic" { pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; /// Atomic subtraction, release ordering. pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_and(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_nand(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_or(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_xor(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_max(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_min(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umin(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umin(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. /// From 57a75374d63604e88c33a0cb16aaa17ac1442fa1 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 15:45:48 +1200 Subject: [PATCH 047/336] Initial Type Refactoring done --- src/librustc/middle/trans/cabi_mips.rs | 49 +++-- src/librustc/middle/trans/cabi_x86.rs | 10 +- src/librustc/middle/trans/cabi_x86_64.rs | 225 +++++++++++------------ src/librustc/middle/trans/callee.rs | 12 +- src/librustc/middle/trans/closure.rs | 18 +- src/librustc/middle/trans/common.rs | 101 +++++----- src/librustc/middle/trans/context.rs | 5 + src/librustc/middle/trans/controlflow.rs | 10 +- src/librustc/middle/trans/datum.rs | 2 +- src/librustc/middle/trans/expr.rs | 18 +- src/librustc/middle/trans/foreign.rs | 68 +++---- src/librustc/middle/trans/glue.rs | 59 +++--- src/librustc/middle/trans/machine.rs | 42 ++--- src/librustc/middle/trans/meth.rs | 14 +- src/librustc/middle/trans/reflect.rs | 10 +- src/librustc/middle/trans/shape.rs | 12 +- src/librustc/middle/trans/tvec.rs | 23 +-- src/librustc/middle/trans/type_of.rs | 193 ++++++++++--------- src/librustc/middle/trans/write_guard.rs | 18 +- src/librustc/util/ppaux.rs | 18 +- 20 files changed, 429 insertions(+), 478 deletions(-) diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index de988493b471..73d26b91672d 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -31,7 +31,7 @@ fn align(off: uint, ty: Type) -> uint { return align_up_to(off, a); } -fn ty_align(ty: TypeRef) -> uint { +fn ty_align(ty: Type) -> uint { unsafe { return match llvm::LLVMGetTypeKind(ty) { Integer => { @@ -41,7 +41,7 @@ fn ty_align(ty: TypeRef) -> uint { Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { + if ty.is_packed() { 1 } else { let str_tys = struct_tys(ty); @@ -71,32 +71,31 @@ fn ty_size(ty: TypeRef) -> uint { let str_tys = struct_tys(ty); str_tys.iter().fold(0, |s, t| s + ty_size(*t)) } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); align(size, ty) } } Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - len * eltsz + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz } _ => fail!("ty_size: unhandled type") }; } } -fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_ret_ty(ty: Type) -> (LLVMType, Option) { return if is_reg_ty(ty) { (LLVMType { cast: false, ty: ty }, None) } else { - (LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute)) + (LLVMType { cast: false, ty: ty.ptr_to() }, Some(StructRetAttribute)) }; } -fn classify_arg_ty(ty: TypeRef, - offset: &mut uint) -> (LLVMType, Option) { +fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option) { let orig_offset = *offset; let size = ty_size(ty) * 8; let mut align = ty_align(ty); @@ -123,7 +122,7 @@ fn classify_arg_ty(ty: TypeRef, fn is_reg_ty(ty: TypeRef) -> bool { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + return match ty.kind() { Integer | Pointer | Float @@ -133,16 +132,16 @@ fn is_reg_ty(ty: TypeRef) -> bool { } } -fn padding_ty(align: uint, offset: uint) -> Option { +fn padding_ty(align: uint, offset: uint) -> Option { if ((align - 1 ) & offset) > 0 { - return Some(T_i32()); + return Some(Type::i32()); } return None; } -fn coerce_to_int(size: uint) -> ~[TypeRef] { - let int_ty = T_i32(); +fn coerce_to_int(size: uint) -> ~[Type] { + let int_ty = Type::i32(); let mut args = ~[]; let mut n = size / 32; @@ -154,16 +153,16 @@ fn coerce_to_int(size: uint) -> ~[TypeRef] { let r = size % 32; if r > 0 { unsafe { - args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint)) + Type::from_ref(args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))) } } return args; } -fn struct_ty(ty: TypeRef, - padding: Option, - coerce: bool) -> TypeRef { +fn struct_ty(ty: Type, + padding: Option, + coerce: bool) -> Type { let size = ty_size(ty) * 8; let mut fields = padding.map_default(~[], |p| ~[*p]); @@ -173,20 +172,20 @@ fn struct_ty(ty: TypeRef, fields.push(ty); } - return T_struct(fields, false); + return Type::struct_(fields, false); } enum MIPS_ABIInfo { MIPS_ABIInfo } impl ABIInfo for MIPS_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { - (LLVMType { cast: false, ty: T_void() }, None) + (LLVMType { cast: false, ty: Type::void() }, None) }; let sret = ret_attr.is_some(); @@ -203,7 +202,7 @@ impl ABIInfo for MIPS_ABIInfo { if sret { arg_tys = vec::append(~[ret_ty], arg_tys); attrs = vec::append(~[ret_attr], attrs); - ret_ty = LLVMType { cast: false, ty: T_void() }; + ret_ty = LLVMType { cast: false, ty: Type::void() }; } return FnType { diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index da7c0d5272da..0f02f7d2f868 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -23,8 +23,8 @@ struct X86_ABIInfo { impl ABIInfo for X86_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut arg_tys = do atys.map |a| { LLVMType { cast: false, ty: *a } @@ -41,7 +41,7 @@ impl ABIInfo for X86_ABIInfo { // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let sret = { - let returning_a_struct = unsafe { LLVMGetTypeKind(rty) == Struct && ret_def }; + let returning_a_struct = unsafe { rty.kind() == Struct && ret_def }; let big_struct = match self.ccx.sess.targ_cfg.os { os_win32 | os_macos => llsize_of_alloc(self.ccx, rty) > 8, _ => true @@ -52,13 +52,13 @@ impl ABIInfo for X86_ABIInfo { if sret { let ret_ptr_ty = LLVMType { cast: false, - ty: T_ptr(ret_ty.ty) + ty: ret_ty.ty.ptr_to() }; arg_tys = ~[ret_ptr_ty] + arg_tys; attrs = ~[Some(StructRetAttribute)] + attrs; ret_ty = LLVMType { cast: false, - ty: T_void(), + ty: Type::void(), }; } else if !ret_def { ret_ty = LLVMType { diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 3ff54e9d3d8c..e0f9ad85e10a 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -26,66 +26,81 @@ use core::uint; use core::vec; #[deriving(Eq)] -enum x86_64_reg_class { - no_class, - integer_class, - sse_fs_class, - sse_fv_class, - sse_ds_class, - sse_dv_class, - sse_int_class, - sseup_class, - x87_class, - x87up_class, - complex_x87_class, - memory_class +enum RegClass { + NoClass, + Integer, + SSEFs, + SSEFv, + SSEDs, + SSEDv, + SSEInt, + SSEUp, + X87, + X87Up, + ComplexX87, + Memory } -fn is_sse(c: x86_64_reg_class) -> bool { - return match c { - sse_fs_class | sse_fv_class | - sse_ds_class | sse_dv_class => true, - _ => false - }; +impl Type { + fn is_reg_ty(&self) -> bool { + match ty.kind() { + Integer | Pointer | Float | Double => true, + _ => false + } + } } -fn is_ymm(cls: &[x86_64_reg_class]) -> bool { - let len = cls.len(); - return (len > 2u && - is_sse(cls[0]) && - cls[1] == sseup_class && - cls[2] == sseup_class) || - (len > 3u && - is_sse(cls[1]) && - cls[2] == sseup_class && - cls[3] == sseup_class); +impl RegClass { + fn is_sse(&self) -> bool { + match *self { + SSEFs | SSEFv | SSEDs | SSEDv => true, + _ => false + } + } } -fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { - fn align(off: uint, ty: TypeRef) -> uint { +impl<'self> ClassList for &'self [RegClass] { + fn is_pass_byval(&self) -> bool { + if self.len() == 0 { return false; } + + let class = self[0]; + class == Memory + || class == X87 + || class == ComplexX87 + } + + fn is_ret_bysret(&self) -> bool { + if self.len() == 0 { return false; } + + self[0] == Memory + } +} + +fn classify_ty(ty: Type) -> ~[RegClass] { + fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return (off + a - 1u) / a * a; } - fn ty_align(ty: TypeRef) -> uint { + fn ty_align(ty: Type) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } Pointer => 8, Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { + if ty.is_packed() { 1 } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) } } Array => { - let elt = llvm::LLVMGetElementType(ty); + let elt = ty.element_type(); ty_align(elt) } _ => fail!("ty_size: unhandled type") @@ -95,7 +110,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { fn ty_size(ty: TypeRef) -> uint { unsafe { - return match llvm::LLVMGetTypeKind(ty) { + match ty.kind() { Integer => { ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 } @@ -103,35 +118,35 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { Float => 4, Double => 8, Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); + if ty.is_packed() { + let str_tys = ty.field_types(); str_tys.iter().fold(0, |s, t| s + ty_size(*t)) } else { - let str_tys = struct_tys(ty); + let str_tys = ty.field_types(); let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); align(size, ty) } } Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - len * eltsz + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz } _ => fail!("ty_size: unhandled type") - }; + } } } - fn all_mem(cls: &mut [x86_64_reg_class]) { + fn all_mem(cls: &mut [RegClass]) { for uint::range(0, cls.len()) |i| { cls[i] = memory_class; } } - fn unify(cls: &mut [x86_64_reg_class], + fn unify(cls: &mut [RegClass], i: uint, - newv: x86_64_reg_class) { + newv: RegClass) { if cls[i] == newv { return; } else if cls[i] == no_class { @@ -154,8 +169,8 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { } } - fn classify_struct(tys: &[TypeRef], - cls: &mut [x86_64_reg_class], i: uint, + fn classify_struct(tys: &[Type], + cls: &mut [RegClass], i: uint, off: uint) { let mut field_off = off; for tys.each |ty| { @@ -165,8 +180,8 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { } } - fn classify(ty: TypeRef, - cls: &mut [x86_64_reg_class], ix: uint, + fn classify(ty: Type, + cls: &mut [RegClass], ix: uint, off: uint) { unsafe { let t_align = ty_align(ty); @@ -183,28 +198,28 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { return; } - match llvm::LLVMGetTypeKind(ty) as int { - 8 /* integer */ | - 12 /* pointer */ => { + match ty.kind() { + Integer | + Pointer => { unify(cls, ix + off / 8u, integer_class); } - 2 /* float */ => { + Float => { if off % 8u == 4u { unify(cls, ix + off / 8u, sse_fv_class); } else { unify(cls, ix + off / 8u, sse_fs_class); } } - 3 /* double */ => { + Double => { unify(cls, ix + off / 8u, sse_ds_class); } - 10 /* struct */ => { - classify_struct(struct_tys(ty), cls, ix, off); + Struct => { + classify_struct(ty.field_types(), cls, ix, off); } - 11 /* array */ => { - let elt = llvm::LLVMGetElementType(ty); + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); let eltsz = ty_size(elt); - let len = llvm::LLVMGetArrayLength(ty) as uint; let mut i = 0u; while i < len { classify(elt, cls, ix, off + i * eltsz); @@ -216,15 +231,15 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { } } - fn fixup(ty: TypeRef, cls: &mut [x86_64_reg_class]) { + fn fixup(ty: Type, cls: &mut [RegClass]) { unsafe { let mut i = 0u; - let llty = llvm::LLVMGetTypeKind(ty) as int; + let ty_kind = ty.kind(); let e = cls.len(); if cls.len() > 2u && - (llty == 10 /* struct */ || - llty == 11 /* array */) { - if is_sse(cls[i]) { + (ty_kind == Struct || + ty_kind == Array) { + if cls[i].is_sse() { i += 1u; while i < e { if cls[i] != sseup_class { @@ -251,7 +266,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { } if cls[i] == sseup_class { cls[i] = sse_int_class; - } else if is_sse(cls[i]) { + } else if cls[i].is_sse() { i += 1; while i != e && cls[i] == sseup_class { i += 1u; } } else if cls[i] == x87_class { @@ -277,8 +292,8 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { return cls; } -fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { - fn llvec_len(cls: &[x86_64_reg_class]) -> uint { +fn llreg_ty(cls: &[RegClass]) -> Type { + fn llvec_len(cls: &[RegClass]) -> uint { let mut len = 1u; for cls.each |c| { if *c != sseup_class { @@ -296,96 +311,68 @@ fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { while i < e { match cls[i] { integer_class => { - tys.push(T_i64()); + tys.push(Type::i64()); } sse_fv_class => { let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; - let vec_ty = llvm::LLVMVectorType(T_f32(), - vec_len as c_uint); + let vec_ty = Type::vector(Type::f32(), vec_len); tys.push(vec_ty); i += vec_len; loop; } sse_fs_class => { - tys.push(T_f32()); + tys.push(Type::f32()); } sse_ds_class => { - tys.push(T_f64()); + tys.push(Type::f64()); } _ => fail!("llregtype: unhandled class") } i += 1u; } - return T_struct(tys, false); + return Type::struct_(tys, false); } } -fn x86_64_tys(atys: &[TypeRef], - rty: TypeRef, +fn x86_64_tys(atys: &[Type], + rty: Type, ret_def: bool) -> FnType { - fn is_reg_ty(ty: TypeRef) -> bool { - unsafe { - return match llvm::LLVMGetTypeKind(ty) as int { - 8 /* integer */ | - 12 /* pointer */ | - 2 /* float */ | - 3 /* double */ => true, - _ => false - }; - } - } - fn is_pass_byval(cls: &[x86_64_reg_class]) -> bool { - return cls.len() > 0 && - (cls[0] == memory_class || - cls[0] == x87_class || - cls[0] == complex_x87_class); - } - - fn is_ret_bysret(cls: &[x86_64_reg_class]) -> bool { - return cls.len() > 0 && cls[0] == memory_class; - } - - fn x86_64_ty(ty: TypeRef, - is_mem_cls: &fn(cls: &[x86_64_reg_class]) -> bool, + fn x86_64_ty(ty: Type, + is_mem_cls: &fn(cls: &[RegClass]) -> bool, attr: Attribute) -> (LLVMType, Option) { - let mut cast = false; - let mut ty_attr = option::None; - let mut llty = ty; - if !is_reg_ty(ty) { + let (cast, attr, ty) = if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls) { - llty = T_ptr(ty); - ty_attr = option::Some(attr); + (false, option::Some(attr), ty.ptr_to()) } else { - cast = true; - llty = llreg_ty(cls); + (true, option::None, llreg_ty(cls)) } - } - return (LLVMType { cast: cast, ty: llty }, ty_attr); + }; + return (LLVMType { cast: cast, ty: ty }, attr); } let mut arg_tys = ~[]; let mut attrs = ~[]; for atys.each |t| { - let (ty, attr) = x86_64_ty(*t, is_pass_byval, ByValAttribute); + let (ty, attr) = x86_64_ty(*t, |cls| cls.is_pass_byval(), ByValAttribute); arg_tys.push(ty); attrs.push(attr); } - let mut (ret_ty, ret_attr) = x86_64_ty(rty, is_ret_bysret, + let mut (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(), StructRetAttribute); let sret = ret_attr.is_some(); if sret { arg_tys = vec::append(~[ret_ty], arg_tys); ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; attrs = vec::append(~[ret_attr], attrs); } else if !ret_def { ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; } return FnType { @@ -400,8 +387,8 @@ enum X86_64_ABIInfo { X86_64_ABIInfo } impl ABIInfo for X86_64_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { return x86_64_tys(atys, rty, ret_def); } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index e5006c854cda..6d2446f01370 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -326,7 +326,7 @@ pub fn trans_fn_ref_with_vtables( let ref_ty = common::node_id_type(bcx, ref_id); val = PointerCast( - bcx, val, T_ptr(type_of::type_of_fn_from_ty(ccx, ref_ty))); + bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to()); } return FnData {llfn: val}; } @@ -516,7 +516,7 @@ pub fn trans_call_inner(in_cx: block, let mut bcx = callee.bcx; let ccx = cx.ccx(); let ret_flag = if ret_in_loop { - let flag = alloca(bcx, T_bool()); + let flag = alloca(bcx, Type::bool()); Store(bcx, C_bool(false), flag); Some(flag) } else { @@ -526,13 +526,13 @@ pub fn trans_call_inner(in_cx: block, let (llfn, llenv) = unsafe { match callee.data { Fn(d) => { - (d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx))) + (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to())) } Method(d) => { // Weird but true: we pass self in the *environment* slot! let llself = PointerCast(bcx, d.llself, - T_opaque_box_ptr(ccx)); + Type::opaque_box(ccx).ptr_to()); (d.llfn, llself) } Closure(d) => { @@ -653,7 +653,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) expr::Ignore => { if ty::type_is_nil(retty) { unsafe { - llvm::LLVMGetUndef(T_ptr(T_nil())) + llvm::LLVMGetUndef(Type::nil().ptr_to()) } } else { alloc_ty(bcx, retty) @@ -838,7 +838,7 @@ pub fn trans_arg_expr(bcx: block, // this could happen due to e.g. subtyping let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, &formal_arg_ty); let llformal_arg_ty = match self_mode { - ty::ByRef => T_ptr(llformal_arg_ty), + ty::ByRef => llformal_arg_ty.ptr_to(), ty::ByCopy => llformal_arg_ty, }; debug!("casting actual type (%s) to match formal (%s)", diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index acb89755c7fa..35e8e866039c 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -72,7 +72,7 @@ use syntax::parse::token::special_idents; // closure". // // Typically an opaque closure suffices because we only manipulate it -// by ptr. The routine common::T_opaque_box_ptr() returns an +// by ptr. The routine Type::opaque_box().ptr_to() returns an // appropriate type for such an opaque closure; it allows access to // the box fields, but not the closure_data itself. // @@ -168,7 +168,7 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) let _icx = bcx.insn_ctxt("closure::nuke_ref_count"); // Initialize ref count to arbitrary value for debugging: let ccx = bcx.ccx(); - let llbox = PointerCast(bcx, llbox, T_opaque_box_ptr(ccx)); + let llbox = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to()); let ref_cnt = GEPi(bcx, llbox, [0u, abi::box_field_refcnt]); let rc = C_int(ccx, 0x12345678); Store(bcx, rc, ref_cnt); @@ -302,7 +302,7 @@ pub fn build_closure(bcx0: block, Some(retptr) => retptr, } }; - let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); + let ret_casted = PointerCast(bcx, ret_true, Type::nil().ptr_to()); let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(), mode: ByRef(ZeroMem)}; env_vals.push(EnvValue {action: EnvRef, @@ -509,22 +509,22 @@ pub fn make_opaque_cbox_take_glue( // ~fn requires a deep copy. let ccx = bcx.ccx(); let tcx = ccx.tcx; - let llopaquecboxty = T_opaque_box_ptr(ccx); + let llopaquecboxty = Type::opaque_box(ccx).ptr_to(); let cbox_in = Load(bcx, cboxptr); do with_cond(bcx, IsNotNull(bcx, cbox_in)) |bcx| { // Load the size from the type descr found in the cbox let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty); let tydescptr = GEPi(bcx, cbox_in, [0u, abi::box_field_tydesc]); let tydesc = Load(bcx, tydescptr); - let tydesc = PointerCast(bcx, tydesc, T_ptr(ccx.tydesc_type)); + let tydesc = PointerCast(bcx, tydesc, ccx.tydesc_type.ptr_to()); let sz = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_size])); // Adjust sz to account for the rust_opaque_box header fields - let sz = Add(bcx, sz, machine::llsize_of(ccx, T_box_header(ccx))); + let sz = Add(bcx, sz, machine::llsize_of(ccx, Type::box_header(ccx))); // Allocate memory, update original ptr, and copy existing data - let opaque_tydesc = PointerCast(bcx, tydesc, T_ptr(T_i8())); - let rval = alloca(bcx, T_ptr(T_i8())); + let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.exchange_malloc_fn(), @@ -585,7 +585,7 @@ pub fn make_opaque_cbox_free_glue( let ccx = bcx.ccx(); do with_cond(bcx, IsNotNull(bcx, cbox)) |bcx| { // Load the type descr found in the cbox - let lltydescty = T_ptr(ccx.tydesc_type); + let lltydescty = ccx.tydesc_type.ptr_to(); let cbox = Load(bcx, cbox); let tydescptr = GEPi(bcx, cbox, [0u, abi::box_field_tydesc]); let tydesc = Load(bcx, tydescptr); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index a72f9489abcc..01b0411a07b2 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -53,9 +53,7 @@ pub use middle::trans::context::CrateContext; pub type namegen = @fn(s: &str) -> ident; pub fn new_namegen() -> namegen { let f: @fn(s: &str) -> ident = |prefix| { - token::str_to_ident(fmt!("%s_%u", - prefix, - token::gensym(prefix))) + token::str_to_ident(fmt!("%s_%u", prefix, token::gensym(prefix))) }; f } @@ -1030,27 +1028,29 @@ pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { // LLVM constant constructors. -pub fn C_null(t: TypeRef) -> ValueRef { +pub fn C_null(t: Type) -> ValueRef { unsafe { - return llvm::LLVMConstNull(t); + llvm::LLVMConstNull(t.to_ref()) } } -pub fn C_undef(t: TypeRef) -> ValueRef { +pub fn C_undef(t: Type) -> ValueRef { unsafe { - return llvm::LLVMGetUndef(t); + llvm::LLVMGetUndef(t.to_ref()) } } -pub fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef { +pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { unsafe { - return llvm::LLVMConstInt(t, u, sign_extend); + llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool) } } -pub fn C_floating(s: &str, t: TypeRef) -> ValueRef { +pub fn C_floating(s: &str, t: Type) -> ValueRef { unsafe { - return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf)); + do s.as_c_str |buf| { + llvm::LLVMConstRealOfString(t.to_ref(), buf) + } } } @@ -1058,32 +1058,32 @@ pub fn C_nil() -> ValueRef { return C_struct([]); } -pub fn C_bool(b: bool) -> ValueRef { - C_integral(T_bool(), if b { 1u64 } else { 0u64 }, False) +pub fn C_bool(val: bool) -> ValueRef { + C_integral(Type::bool(), val as u64, false) } -pub fn C_i1(b: bool) -> ValueRef { - return C_integral(T_i1(), if b { 1 } else { 0 }, False); +pub fn C_i1(val: bool) -> ValueRef { + C_integral(Type::i1(), val as u64, false) } pub fn C_i32(i: i32) -> ValueRef { - return C_integral(T_i32(), i as u64, True); + return C_integral(Type::i32(), i as u64, true); } pub fn C_i64(i: i64) -> ValueRef { - return C_integral(T_i64(), i as u64, True); + return C_integral(Type::i64(), i as u64, true); } pub fn C_int(cx: &CrateContext, i: int) -> ValueRef { - return C_integral(cx.int_type, i as u64, True); + return C_integral(cx.int_type, i as u64, true); } pub fn C_uint(cx: &CrateContext, i: uint) -> ValueRef { - return C_integral(cx.int_type, i as u64, False); + return C_integral(cx.int_type, i as u64, false); } pub fn C_u8(i: uint) -> ValueRef { - return C_integral(T_i8(), i as u64, False); + return C_integral(Type::i8(), i as u64, false); } @@ -1091,18 +1091,19 @@ pub fn C_u8(i: uint) -> ValueRef { // our boxed-and-length-annotated strings. pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { unsafe { - match cx.const_cstr_cache.find(&s) { + match cx.const_cstr_cache.find_equiv(&s) { Some(&llval) => return llval, None => () } - let sc = do str::as_c_str(s) |buf| { - llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, - False) + let sc = do s.as_c_str |buf| { + llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False) + }; + + let gsym = token::gensym("str"); + let g = fmt!("str%u", gsym).as_c_str |buf| { + llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf) }; - let g = - str::as_c_str(fmt!("str%u", (cx.names)("str").name), - |buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf)); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage); @@ -1118,7 +1119,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { pub fn C_estr_slice(cx: &mut CrateContext, s: @str) -> ValueRef { unsafe { let len = s.len(); - let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8())); + let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p().to_ref()); C_struct([cs, C_uint(cx, len + 1u /* +1 for null */)]) } } @@ -1126,10 +1127,9 @@ pub fn C_estr_slice(cx: &mut CrateContext, s: @str) -> ValueRef { // Returns a Plain Old LLVM String: pub fn C_postr(s: &str) -> ValueRef { unsafe { - return do str::as_c_str(s) |buf| { - llvm::LLVMConstStringInContext(base::task_llcx(), - buf, s.len() as c_uint, False) - }; + do s.as_c_str |buf| { + llvm::LLVMConstStringInContext(base::task_llcx(), buf, s.len() as c_uint, False) + } } } @@ -1138,17 +1138,14 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { let mut i = 0u; let mut elts: ~[ValueRef] = ~[]; while i < size { elts.push(C_u8(0u)); i += 1u; } - return llvm::LLVMConstArray(T_i8(), - vec::raw::to_ptr(elts), - elts.len() as c_uint); + return llvm::LLVMConstArray(Type::i8(), vec::raw::to_ptr(elts), elts.len() as c_uint); } } pub fn C_struct(elts: &[ValueRef]) -> ValueRef { unsafe { do vec::as_imm_buf(elts) |ptr, len| { - llvm::LLVMConstStructInContext(base::task_llcx(), - ptr, len as c_uint, False) + llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False) } } } @@ -1156,8 +1153,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| { - llvm::LLVMConstStructInContext(base::task_llcx(), - ptr, len as c_uint, True) + llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True) } } } @@ -1172,38 +1168,35 @@ pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef { pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef { unsafe { - return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), - elts.len() as c_uint); + return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), elts.len() as c_uint); } } pub fn C_bytes(bytes: &[u8]) -> ValueRef { unsafe { - return llvm::LLVMConstStringInContext(base::task_llcx(), - cast::transmute(vec::raw::to_ptr(bytes)), - bytes.len() as c_uint, True); + let ptr = cast::transmute(vec::raw::to_ptr(bytes)); + return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint, True); } } pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { unsafe { - return llvm::LLVMConstStringInContext(base::task_llcx(), - cast::transmute(vec::raw::to_ptr(bytes)), - bytes.len() as c_uint, False); + let ptr = cast::transmute(vec::raw::to_ptr(bytes)); + return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint,False); } } pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { unsafe { let llshape = C_bytes_plus_null(bytes); - let name = fmt!("shape%u", (ccx.names)("shape").name); - let llglobal = str::as_c_str(name, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf) - }); - llvm::LLVMSetInitializer(llglobal, llshape); + let name = fmt!("shape%u", token::gensym("shape")); + let llglobal = do name.as_c_str |buf| { + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) + }; + llvm::LLVMSetInitializer(llglobal, llshape.to_ref()); llvm::LLVMSetGlobalConstant(llglobal, True); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8())); + return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); } } @@ -1478,7 +1471,7 @@ pub fn filename_and_line_num_from_span(bcx: block, span: span) -> (ValueRef, ValueRef) { let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo); let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); - let filename = build::PointerCast(bcx, filename_cstr, T_ptr(T_i8())); + let filename = build::PointerCast(bcx, filename_cstr, Type::i8p()); let line = C_int(bcx.ccx(), loc.line as int); (filename, line) } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index ada0284e0e31..bf9d3932298d 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -151,7 +151,11 @@ impl CrateContext { let tydesc_type = Type::tydesc(targ_cfg.arch); let opaque_vec_type = Type::opaque_vec(targ_cfg.arch); + let str_slice_ty = Type::named_struct("str_slice"); + str_slice_ty.set_struct_body([Type::i8p(), int_type]); + tn.associate_type("tydesc", &tydesc_type); + tn.associate_type("str_slice", &str_slice_ty); let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { @@ -233,6 +237,7 @@ impl CrateContext { ((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 55436e5946ef..17009afda491 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -204,10 +204,10 @@ pub fn trans_log(log_ex: @ast::expr, let global; unsafe { global = str::as_c_str(s, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) }); llvm::LLVMSetGlobalConstant(global, False); - llvm::LLVMSetInitializer(global, C_null(T_i32())); + llvm::LLVMSetInitializer(global, C_null(Type::i32())); lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage); } ccx.module_data.insert(modname, global); @@ -307,7 +307,7 @@ pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { Store(bcx, C_bool(false), bcx.fcx.llretptr.get()); expr::SaveIn(match e { Some(x) => PointerCast(bcx, retptr, - T_ptr(type_of(bcx.ccx(), expr_ty(bcx, x)))), + type_of(bcx.ccx(), expr_ty(bcx, x)).ptr_to()), None => retptr }) } @@ -381,8 +381,8 @@ fn trans_fail_value(bcx: block, (C_cstr(bcx.ccx(), @""), 0) } }; - let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8())); - let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8())); + let V_str = PointerCast(bcx, V_fail_str, Type::i8p()); + 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); diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index c162318824f5..8e25da202cca 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -474,7 +474,7 @@ impl Datum { ByRef(_) => self.val, ByValue => { if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { - C_null(T_ptr(type_of::type_of(bcx.ccx(), self.ty))) + C_null(type_of::type_of(bcx.ccx(), self.ty).ptr_to()) } else { let slot = alloc_ty(bcx, self.ty); Store(bcx, self.val, slot); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d79e725a2b7d..92cbf2c09570 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -122,7 +122,7 @@ lvalues are *never* stored by value. use core::prelude::*; use back::abi; -use lib::llvm::{ValueRef, TypeRef, llvm}; +use lib::llvm::{ValueRef, llvm}; use lib; use metadata::csearch; use middle::trans::_match; @@ -794,7 +794,7 @@ fn trans_def_datum_unadjusted(bcx: block, ty: ty::mk_mach_uint(ast::ty_u8), mutbl: ast::m_imm }); // *u8 - (rust_ty, PointerCast(bcx, fn_data.llfn, T_ptr(T_i8()))) + (rust_ty, PointerCast(bcx, fn_data.llfn, Type::i8p())) } else { let fn_ty = expr_ty(bcx, ref_expr); (fn_ty, fn_data.llfn) @@ -924,7 +924,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { ix_val, unscaled_len) }; let elt = InBoundsGEP(bcx, base, [ix_val]); - let elt = PointerCast(bcx, elt, T_ptr(vt.llunit_ty)); + let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to()); return DatumBlock { bcx: bcx, datum: Datum {val: elt, @@ -963,7 +963,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { // which may not be equal to the enum's type for // non-C-like enums. let val = base::get_item_val(bcx.ccx(), did.node); - let pty = T_ptr(type_of(bcx.ccx(), const_ty)); + let pty = type_of(bcx.ccx(), const_ty).ptr_to(); PointerCast(bcx, val, pty) } else { { @@ -1054,7 +1054,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { // This cast should not be necessary. We should cast self *once*, // but right now this conflicts with default methods. let real_self_ty = monomorphize_type(bcx, self_info.t); - let llselfty = T_ptr(type_of::type_of(bcx.ccx(), real_self_ty)); + let llselfty = type_of::type_of(bcx.ccx(), real_self_ty).ptr_to(); let casted_val = PointerCast(bcx, self_info.v, llselfty); Datum { @@ -1438,7 +1438,7 @@ fn trans_eager_binop(bcx: block, } let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op); bcx = cmpr.bcx; - ZExt(bcx, cmpr.val, T_i8()) + ZExt(bcx, cmpr.val, Type::i8()) } } _ => { @@ -1491,7 +1491,7 @@ fn trans_lazy_binop(bcx: block, } Br(past_rhs, join.llbb); - let phi = Phi(join, T_bool(), [lhs, rhs], [past_lhs.llbb, + let phi = Phi(join, Type::bool(), [lhs, rhs], [past_lhs.llbb, past_rhs.llbb]); return immediate_rvalue_bcx(join, phi, binop_ty); @@ -1548,7 +1548,7 @@ fn trans_overloaded_op(bcx: block, DoAutorefArg) } -fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, +fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef, signed: bool) -> ValueRef { let _icx = bcx.insn_ctxt("int_cast"); unsafe { @@ -1566,7 +1566,7 @@ fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, } } -fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, +fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef) -> ValueRef { let _icx = bcx.insn_ctxt("float_cast"); let srcsz = lib::llvm::float_width(llsrctype); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 34898e20f1e4..50d4709735ca 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -11,7 +11,7 @@ use core::prelude::*; use back::{link, abi}; -use lib::llvm::{TypeRef, ValueRef}; +use lib::llvm::{ValueRef}; use lib; use middle::trans::base::*; use middle::trans::cabi; @@ -72,10 +72,10 @@ struct ShimTypes { /// Type of the struct we will use to shuttle values back and forth. /// This is always derived from the llsig. - bundle_ty: TypeRef, + bundle_ty: Type, /// Type of the shim function itself. - shim_fn_ty: TypeRef, + shim_fn_ty: Type, /// Adapter object for handling native ABI rules (trust me, you /// don't want to know). @@ -83,8 +83,8 @@ struct ShimTypes { } struct LlvmSignature { - llarg_tys: ~[TypeRef], - llret_ty: TypeRef, + llarg_tys: ~[Type], + llret_ty: Type, sret: bool, } @@ -113,20 +113,16 @@ 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 = T_struct(vec::append_one(copy llsig.llarg_tys, - T_ptr(llsig.llret_ty)), - 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); + let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def); ShimTypes { fn_sig: fn_sig, llsig: llsig, ret_def: ret_def, bundle_ty: bundle_ty, - shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_void()), + shim_fn_ty: Type::func([bundle_ty.ptr_to()], Type::void()), fn_ty: fn_ty } } @@ -210,8 +206,8 @@ fn build_wrap_fn_(ccx: @mut CrateContext, arg_builder(bcx, tys, llwrapfn, llargbundle); // Create call itself. - let llshimfnptr = PointerCast(bcx, llshimfn, T_ptr(T_i8())); - let llrawargbundle = PointerCast(bcx, llargbundle, T_ptr(T_i8())); + let llshimfnptr = PointerCast(bcx, llshimfn, Type::i8p()); + let llrawargbundle = PointerCast(bcx, llargbundle, Type::i8p()); Call(bcx, shim_upcall, [llrawargbundle, llshimfnptr]); ret_builder(bcx, tys, llargbundle); @@ -239,7 +235,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, // XXX: This is ugly. let llretptr = BitCast(return_context, fcx.llretptr.get(), - T_ptr(llfunctionreturntype)); + llfunctionreturntype.ptr_to()); Ret(return_context, Load(return_context, llretptr)); } } @@ -688,9 +684,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); - // FIXME (#3727): change this to T_ptr(ccx.tydesc_ty) when the + // FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the // core::sys copy of the get_tydesc interface dies off. - let td = PointerCast(bcx, static_ti.tydesc, T_ptr(T_nil())); + let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to()); Store(bcx, td, fcx.llretptr.get()); } "init" => { @@ -734,7 +730,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // code bloat when `transmute` is used on large structural // types. let lldestptr = fcx.llretptr.get(); - let lldestptr = PointerCast(bcx, lldestptr, T_ptr(T_i8())); + let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcval = get_param(decl, first_real_arg); let llsrcptr = if ty::type_is_immediate(in_type) { @@ -744,7 +740,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } else { llsrcval }; - let llsrcptr = PointerCast(bcx, llsrcptr, T_ptr(T_i8())); + let llsrcptr = PointerCast(bcx, llsrcptr, Type::i8p()); let llsize = llsize_of(ccx, llintype); call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); @@ -761,12 +757,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let visitor = get_param(decl, first_real_arg + 1u); //let llvisitorptr = alloca(bcx, val_ty(visitor)); //Store(bcx, visitor, llvisitorptr); - let td = PointerCast(bcx, td, T_ptr(ccx.tydesc_type)); - glue::call_tydesc_glue_full(bcx, - visitor, - td, - abi::tydesc_field_visit_glue, - None); + let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to()); + glue::call_tydesc_glue_full(bcx, visitor, td, + abi::tydesc_field_visit_glue, None); } "frame_address" => { let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress"); @@ -801,8 +794,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let llfty = type_of_fn(bcx.ccx(), [], ty::mk_nil()); let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); - let morestack_addr = PointerCast(bcx, morestack_addr, - T_ptr(T_nil())); + let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); Store(bcx, morestack_addr, fcx.llretptr.get()); } "memcpy32" => { @@ -811,8 +803,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); @@ -824,8 +816,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); @@ -837,8 +829,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); @@ -850,8 +842,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); @@ -863,7 +855,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); let val = get_param(decl, first_real_arg + 1); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); @@ -876,7 +868,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); let val = get_param(decl, first_real_arg + 1); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); @@ -1231,7 +1223,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, llargvals.push(llretptr); } - let llenvptr = C_null(T_opaque_box_ptr(bcx.ccx())); + let llenvptr = C_null(Type::opaque_box(bcx.ccx()).ptr_to()); llargvals.push(llenvptr); while i < n { // Get a pointer to the argument: diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 6f1442637aee..7396508fb8dd 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -18,7 +18,7 @@ use back::abi; use back::link::*; use driver::session; use lib; -use lib::llvm::{llvm, ValueRef, TypeRef, True}; +use lib::llvm::{llvm, ValueRef, Type, True}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::callee; @@ -44,19 +44,17 @@ use syntax::ast; pub fn trans_free(cx: block, v: ValueRef) -> block { let _icx = cx.insn_ctxt("trans_free"); - callee::trans_lang_call( - cx, + callee::trans_lang_call(cx, cx.tcx().lang_items.free_fn(), - [PointerCast(cx, v, T_ptr(T_i8()))], + [PointerCast(cx, v, Type::i8p())], expr::Ignore) } pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { let _icx = cx.insn_ctxt("trans_exchange_free"); - callee::trans_lang_call( - cx, + callee::trans_lang_call(cx, cx.tcx().lang_items.exchange_free_fn(), - [PointerCast(cx, v, T_ptr(T_i8()))], + [PointerCast(cx, v, Type::i8p())], expr::Ignore) } @@ -78,14 +76,10 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { return cx; } -pub fn drop_ty_root(bcx: block, - v: ValueRef, - rooted: bool, - t: ty::t) - -> block { +pub fn drop_ty_root(bcx: block, v: ValueRef, rooted: bool, t: ty::t) -> block { if rooted { // NB: v is a raw ptr to an addrspace'd ptr to the value. - let v = PointerCast(bcx, Load(bcx, v), T_ptr(type_of(bcx.ccx(), t))); + let v = PointerCast(bcx, Load(bcx, v), type_of(bcx.ccx(), t).ptr_to()); drop_ty(bcx, v, t) } else { drop_ty(bcx, v, t) @@ -95,14 +89,14 @@ pub fn drop_ty_root(bcx: block, pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { let _icx = bcx.insn_ctxt("drop_ty_immediate"); match ty::get(t).sty { - ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) => { + ty::ty_uniq(_) + | ty::ty_evec(_, ty::vstore_uniq) + | ty::ty_estr(ty::vstore_uniq) => { free_ty_immediate(bcx, v, t) } - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_box) => { + ty::ty_box(_) | ty::ty_opaque_box + | ty::ty_evec(_, ty::vstore_box) + | ty::ty_estr(ty::vstore_box) => { decr_refcnt_maybe_free(bcx, v, None, t) } _ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty") @@ -340,7 +334,7 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - let llrawptr = PointerCast(bcx, v, T_ptr(T_i8())); + let llrawptr = PointerCast(bcx, v, Type::i8p()); let llfn = { match static_glue_fn { @@ -353,8 +347,8 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - Call(bcx, llfn, [C_null(T_ptr(T_nil())), - C_null(T_ptr(T_ptr(bcx.ccx().tydesc_type))), + Call(bcx, llfn, [C_null(Type::nil().ptr_to()), + C_null(bcx.ccx().tydesc_type.ptr_to().ptr_to()), llrawptr]); } @@ -372,7 +366,7 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { let bcx = do with_scope(bcx, None, "visitor cleanup") |bcx| { let mut bcx = bcx; let (visitor_trait, object_ty) = ty::visitor_object_ty(bcx.tcx()); - let v = PointerCast(bcx, v, T_ptr(type_of::type_of(bcx.ccx(), object_ty))); + let v = PointerCast(bcx, v, type_of::type_of(bcx.ccx(), object_ty).ptr_to()); bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, visitor_trait.def_id); // The visitor is a boxed object and needs to be dropped add_clean(bcx, v, object_ty); @@ -390,7 +384,7 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { let v = Load(bcx, v); let body = GEPi(bcx, v, [0u, abi::box_field_body]); // Cast away the addrspace of the box pointer. - let body = PointerCast(bcx, body, T_ptr(type_of(ccx, body_mt.ty))); + let body = PointerCast(bcx, body, type_of(ccx, body_mt.ty).ptr_to()); let bcx = drop_ty(bcx, body, body_mt.ty); trans_free(bcx, v) } @@ -517,9 +511,8 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable])); // Cast the vtable to a pointer to a pointer to a tydesc. - let llvtable = PointerCast(bcx, - llvtable, - T_ptr(T_ptr(ccx.tydesc_type))); + let llvtable = PointerCast(bcx, llvtable, + ccx.tydesc_type.ptr_to().ptr_to()); let lltydesc = Load(bcx, llvtable); call_tydesc_glue_full(bcx, lluniquevalue, @@ -680,7 +673,7 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { pub type glue_helper = @fn(block, ValueRef, ty::t); -pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: TypeRef, +pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: Type, name: ~str) -> ValueRef { let _icx = ccx.insn_ctxt("declare_generic_glue"); let name = name; @@ -711,7 +704,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, let rawptr0_arg = fcx.arg_pos(1u); let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; let llty = type_of(ccx, t); - let llrawptr0 = PointerCast(bcx, llrawptr0, T_ptr(llty)); + let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to()); helper(bcx, llrawptr0, t); finish_fn(fcx, lltop); return llfn; @@ -739,7 +732,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { //let _icx = ccx.insn_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx)); + let glue_fn_ty = T_generic_glue_fn(ccx).ptr_to(); let tyds = &mut ccx.tydescs; for tyds.each_value |&val| { let ti = val; @@ -789,8 +782,8 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { } }; - let shape = C_null(T_ptr(T_i8())); - let shape_tables = C_null(T_ptr(T_i8())); + let shape = C_null(Type::i8p()); + let shape_tables = C_null(Type::i8p()); let tydesc = C_named_struct(ccx.tydesc_type, @@ -811,7 +804,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { // Index tydesc by addrspace. if ti.addrspace > gc_box_addrspace { - let llty = T_ptr(ccx.tydesc_type); + let llty = ccx.tydesc_type.ptr_to(); let addrspace_name = fmt!("_gc_addrspace_metadata_%u", ti.addrspace as uint); let addrspace_gvar = str::as_c_str(addrspace_name, |buf| { diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index dc3fe3fb9315..eb7240419ed6 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -22,17 +22,17 @@ use util::ppaux::ty_to_str; // compute sizeof / alignof // Returns the number of bytes clobbered by a Store to this type. -pub fn llsize_of_store(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_store(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint; + return llvm::LLVMStoreSizeOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the number of bytes between successive elements of type T in an // array of T. This is the "ABI" size. It includes any ABI-mandated padding. -pub fn llsize_of_alloc(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint; + return llvm::LLVMABISizeOfType(cx.td.lltd, ty.to_ref()) as uint; } } @@ -44,9 +44,9 @@ pub fn llsize_of_alloc(cx: &CrateContext, t: TypeRef) -> uint { // that LLVM *does* distinguish between e.g. a 1-bit value and an 8-bit value // at the codegen level! In general you should prefer `llbitsize_of_real` // below. -pub fn llsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_real(cx: &CrateContext, ty: Type) -> uint { unsafe { - let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint; + let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint; if nbits & 7u != 0u { // Not an even number of bytes, spills into "next" byte. 1u + (nbits >> 3) @@ -57,14 +57,14 @@ pub fn llsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { } /// Returns the "real" size of the type in bits. -pub fn llbitsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llbitsize_of_real(cx: &CrateContext, ty: Type) -> uint { unsafe { - llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint + llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint } } /// Returns the size of the type as an LLVM constant integer value. -pub fn llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { +pub fn llsize_of(cx: &CrateContext, ty: Type) -> ValueRef { // Once upon a time, this called LLVMSizeOf, which does a // getelementptr(1) on a null pointer and casts to an int, in // order to obtain the type size as a value without requiring the @@ -72,17 +72,17 @@ pub fn llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { // there's no need for that contrivance. The instruction // selection DAG generator would flatten that GEP(1) node into a // constant of the type's alloc size, so let's save it some work. - return C_uint(cx, llsize_of_alloc(cx, t)); + return C_uint(cx, llsize_of_alloc(cx, ty)); } // Returns the "default" size of t (see above), or 1 if the size would // be zero. This is important for things like vectors that expect // space to be consumed. -pub fn nonzero_llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { - if llbitsize_of_real(cx, t) == 0 { - unsafe { llvm::LLVMConstInt(cx.int_type, 1, False) } +pub fn nonzero_llsize_of(cx: &CrateContext, ty: Type) -> ValueRef { + if llbitsize_of_real(cx, ty) == 0 { + unsafe { llvm::LLVMConstInt(cx.int_type.to_ref(), 1, False) } } else { - llsize_of(cx, t) + llsize_of(cx, ty) } } @@ -90,28 +90,28 @@ pub fn nonzero_llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { // The preferred alignment may be larger than the alignment used when // packing the type into structs. This will be used for things like // allocations inside a stack frame, which LLVM has a free hand in. -pub fn llalign_of_pref(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llalign_of_pref(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint; + return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the minimum alignment of a type required by the platform. // This is the alignment that will be used for struct fields, arrays, // and similar ABI-mandated things. -pub fn llalign_of_min(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint; + return llvm::LLVMABIAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the "default" alignment of t, which is calculated by casting // null to a record containing a single-bit followed by a t value, then // doing gep(0,1) to get at the trailing (and presumably padded) t cell. -pub fn llalign_of(cx: &CrateContext, t: TypeRef) -> ValueRef { +pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef { unsafe { return llvm::LLVMConstIntCast( - llvm::LLVMAlignOf(t), cx.int_type, False); + llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False); } } @@ -142,7 +142,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { cx.tcx.sess.str_of(variant.name), cx.tn.type_to_str(T_struct(lltypes, false))); - let this_size = llsize_of_real(cx, T_struct(lltypes, false)); + let this_size = llsize_of_real(cx, Type::struct_(lltypes, false)); if max_size < this_size { max_size = this_size; } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index ee429a247465..ce240dc2484e 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -363,7 +363,7 @@ pub fn trans_static_method_callee(bcx: block, Some(callee_origins)); let callee_ty = node_id_type(bcx, callee_id); - let llty = T_ptr(type_of_fn_from_ty(ccx, callee_ty)); + let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to(); FnData {llfn: PointerCast(bcx, lval, llty)} } _ => { @@ -463,7 +463,7 @@ pub fn trans_monomorphized_callee(bcx: block, // create a llvalue that represents the fn ptr let fn_ty = node_id_type(bcx, callee_id); - let llfn_ty = T_ptr(type_of_fn_from_ty(ccx, fn_ty)); + let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).to_ptr(); let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty); // combine the self environment with the rest @@ -628,7 +628,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, PointerCast(bcx, GEPi(bcx, llpair, [0u, abi::trt_field_vtable]), - T_ptr(T_ptr(T_vtable())))); + Type::vtable().ptr_to().ptr_to())); // Load the box from the @Trait pair and GEP over the box header if // necessary: @@ -705,7 +705,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Plus one in order to skip past the type descriptor. let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method + 1])); - let mptr = PointerCast(bcx, mptr, T_ptr(llcallee_ty)); + let mptr = PointerCast(bcx, mptr, llcallee_ty.ptr_to()); return Callee { bcx: bcx, @@ -814,7 +814,7 @@ pub fn make_impl_vtable(bcx: block, if im.generics.has_type_params() || ty::type_has_self(fty) { debug!("(making impl vtable) method has self or type params: %s", tcx.sess.str_of(im.ident)); - C_null(T_ptr(T_nil())) + C_null(Type::nil().ptr_to()) } else { debug!("(making impl vtable) adding method to vtable: %s", tcx.sess.str_of(im.ident)); @@ -857,7 +857,7 @@ pub fn trans_trait_cast(bcx: block, // have no type descriptor field.) llboxdest = PointerCast(bcx, llboxdest, - T_ptr(type_of(bcx.ccx(), v_ty))); + type_of(bcx.ccx(), v_ty).ptr_to()); bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); // Store the vtable into the pair or triple. @@ -866,7 +866,7 @@ pub fn trans_trait_cast(bcx: block, let vtable = get_vtable(bcx, v_ty, orig); Store(bcx, vtable, PointerCast(bcx, GEPi(bcx, lldest, [0u, abi::trt_field_vtable]), - T_ptr(val_ty(vtable)))); + val_ty(vtable).ptr_to())); bcx } diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index cb7e2cb4e6e1..ebf2d888148a 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -9,7 +9,7 @@ // except according to those terms. use back::link::mangle_internal_name_by_path_and_seq; -use lib::llvm::{TypeRef, ValueRef, llvm}; +use lib::llvm::{Type, ValueRef, llvm}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::build::*; @@ -37,7 +37,7 @@ pub struct Reflector { visitor_val: ValueRef, visitor_methods: @~[@ty::Method], final_bcx: block, - tydesc_ty: TypeRef, + tydesc_ty: Type, bcx: block } @@ -58,7 +58,7 @@ impl Reflector { let str_ty = ty::mk_estr(bcx.tcx(), str_vstore); let scratch = scratch_datum(bcx, str_ty, false); let len = C_uint(bcx.ccx(), s.len() + 1); - let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8())); + let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), Type::i8p()); Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ])); Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ])); scratch.val @@ -76,7 +76,7 @@ impl Reflector { let bcx = self.bcx; let static_ti = get_tydesc(bcx.ccx(), t); glue::lazily_emit_all_tydesc_glue(bcx.ccx(), static_ti); - PointerCast(bcx, static_ti.tydesc, T_ptr(self.tydesc_ty)) + PointerCast(bcx, static_ti.tydesc, self.tydesc_ty.ptr_to()) } pub fn c_mt(&mut self, mt: &ty::mt) -> ~[ValueRef] { @@ -271,7 +271,7 @@ impl Reflector { let ccx = bcx.ccx(); let repr = adt::represent_type(bcx.ccx(), t); let variants = ty::substd_enum_variants(ccx.tcx, did, substs); - let llptrty = T_ptr(type_of(ccx, t)); + let llptrty = type_of(ccx, t).ptr_to(); let (_, opaquety) = ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque")) .expect("Failed to resolve intrinsic::Opaque"); diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index 89ffb4b5bbaa..f3554b348061 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -48,23 +48,22 @@ pub fn mk_global(ccx: &CrateContext, pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { unsafe { - let llshapetablesty = trans::common::T_named_struct("shapes"); - let _llshapetables = str::as_c_str("shapes", |buf| { + let llshapetablesty = Type::named_struct("shapes"); + do "shapes".as_c_str |buf| { llvm::LLVMAddGlobal(llmod, llshapetablesty, buf) - }); + }; - return Ctxt { + Ctxt { next_tag_id: 0u16, pad: 0u16, pad2: 0u32 - }; + } } } /* Although these two functions are never called, they are here for a VERY GOOD REASON. See #3670 -*/ pub fn add_u16(dest: &mut ~[u8], val: u16) { *dest += [(val & 0xffu16) as u8, (val >> 8u16) as u8]; } @@ -73,3 +72,4 @@ pub fn add_substr(dest: &mut ~[u8], src: ~[u8]) { add_u16(&mut *dest, src.len() as u16); *dest += src; } +*/ diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index b39fff61d64f..009338650122 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -11,7 +11,7 @@ use back::abi; use lib; -use lib::llvm::{llvm, ValueRef, TypeRef}; +use lib::llvm::{llvm, ValueRef}; use middle::trans::base; use middle::trans::base::*; use middle::trans::build::*; @@ -73,7 +73,7 @@ pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef { pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { let _icx = bcx.insn_ctxt("tvec::pointer_add"); let old_ty = val_ty(ptr); - let bptr = PointerCast(bcx, ptr, T_ptr(T_i8())); + let bptr = PointerCast(bcx, ptr, Type::i8p()); return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty); } @@ -146,7 +146,7 @@ pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> pub struct VecTypes { vec_ty: ty::t, unit_ty: ty::t, - llunit_ty: TypeRef, + llunit_ty: Type, llunit_size: ValueRef } @@ -227,7 +227,7 @@ pub fn trans_slice_vstore(bcx: block, let fixed_ty = ty::mk_evec(bcx.tcx(), ty::mt {ty: vt.unit_ty, mutbl: ast::m_mutbl}, ty::vstore_fixed(count)); - let llfixed_ty = T_ptr(type_of::type_of(bcx.ccx(), fixed_ty)); + let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); add_clean(bcx, llfixed_casted, fixed_ty); @@ -271,13 +271,10 @@ pub fn trans_lit_str(bcx: block, let bytes = str_lit.len() + 1; // count null-terminator too let llbytes = C_uint(bcx.ccx(), bytes); let llcstr = C_cstr(bcx.ccx(), str_lit); - let llcstr = llvm::LLVMConstPointerCast(llcstr, - T_ptr(T_i8())); - Store(bcx, - llcstr, + let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p().to_ref()); + Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base])); - Store(bcx, - llbytes, + Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len])); bcx } @@ -286,9 +283,7 @@ pub fn trans_lit_str(bcx: block, } -pub fn trans_uniq_or_managed_vstore(bcx: block, - heap: heap, - vstore_expr: @ast::expr, +pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::expr, content_expr: @ast::expr) -> DatumBlock { //! // @@ -307,7 +302,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, node: ast::lit_str(s), _ }) => { let llptrval = C_cstr(bcx.ccx(), s); - let llptrval = PointerCast(bcx, llptrval, T_ptr(T_i8())); + let llptrval = PointerCast(bcx, llptrval, Type::i8p()); let llsizeval = C_uint(bcx.ccx(), s.len()); let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq); let lldestval = scratch_datum(bcx, typ, false); diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 058a6b9f48ef..9ace4991f1ba 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -11,7 +11,6 @@ use core::prelude::*; use lib::llvm::llvm; -use lib::llvm::{TypeRef}; use middle::trans::adt; use middle::trans::base; use middle::trans::common::*; @@ -25,46 +24,50 @@ pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool { !ty::type_is_immediate(*arg_ty) } -pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> TypeRef { +pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type { let llty = type_of(ccx, *arg_ty); - if arg_is_indirect(ccx, arg_ty) {T_ptr(llty)} else {llty} + if arg_is_indirect(ccx, arg_ty) { + llty.ptr_to() + } else { + llty + } } pub fn type_of_explicit_args(ccx: &mut CrateContext, - inputs: &[ty::t]) -> ~[TypeRef] { + inputs: &[ty::t]) -> ~[Type] { inputs.map(|arg_ty| type_of_explicit_arg(ccx, arg_ty)) } pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) - -> TypeRef { + -> Type { unsafe { - let mut atys: ~[TypeRef] = ~[]; + let mut atys: ~[Type] = ~[]; // Arg 0: Output pointer. // (if the output type is non-immediate) let output_is_immediate = ty::type_is_immediate(output); let lloutputtype = type_of(cx, output); if !output_is_immediate { - atys.push(T_ptr(lloutputtype)); + atys.push(lloutputtype.ptr_to()); } // Arg 1: Environment - atys.push(T_opaque_box_ptr(cx)); + atys.push(Type::opaque_box(cx).ptr_to()); // ... then explicit args. atys.push_all(type_of_explicit_args(cx, inputs)); // Use the output as the actual return value if it's immediate. if output_is_immediate && !ty::type_is_nil(output) { - T_fn(atys, lloutputtype) + Type::func(atys, lloutputtype) } else { - T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx)) + Type::func(atys, Type::void()) } } } // Given a function type and a count of ty params, construct an llvm type -pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> TypeRef { +pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type { match ty::get(fty).sty { ty::ty_closure(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), ty::ty_bare_fn(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), @@ -74,7 +77,7 @@ pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> TypeRef { } } -pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { +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); @@ -84,11 +87,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { match ty::get(t).sty { ty::ty_box(mt) => { let ty = type_of(cx, mt.ty); - T_ptr(T_box(cx, ty)) + Type::box(cx, ty).ptr_to() } ty::ty_uniq(mt) => { let ty = type_of(cx, mt.ty); - T_ptr(T_unique(cx, ty)) + Type::unique(cx, ty).ptr_to() } _ => { cx.sess.bug("non-box in type_of_non_gc_box"); @@ -109,18 +112,18 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { // recursive types. For example, `static_size_of_enum()` relies on this // behavior. -pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { - match cx.llsizingtypes.find(&t) { - Some(t) => return *t, +pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { + match cx.llsizingtypes.find_copy(&t) { + Some(t) => return t, None => () } let llsizingty = match ty::get(t).sty { - ty::ty_nil | ty::ty_bot => T_nil(), - ty::ty_bool => T_bool(), - ty::ty_int(t) => T_int_ty(cx, t), - ty::ty_uint(t) => T_uint_ty(cx, t), - ty::ty_float(t) => T_float_ty(cx, t), + ty::ty_nil | ty::ty_bot => Type::nil(), + ty::ty_bool => Type::bool(), + ty::ty_int(t) => Type::int_from_ty(cx, t), + ty::ty_uint(t) => Type::uint_from_ty(cx, t), + ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | @@ -132,48 +135,46 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { ty::ty_ptr(*) | ty::ty_rptr(*) | ty::ty_type | - ty::ty_opaque_closure_ptr(*) => T_ptr(T_i8()), + ty::ty_opaque_closure_ptr(*) => Type::i8p(), ty::ty_estr(ty::vstore_slice(*)) | ty::ty_evec(_, ty::vstore_slice(*)) => { - T_struct([T_ptr(T_i8()), T_ptr(T_i8())], false) + Type::struct_([Type::i8p(), Type::i8p()], false) } - ty::ty_bare_fn(*) => T_ptr(T_i8()), - ty::ty_closure(*) => T_struct([T_ptr(T_i8()), T_ptr(T_i8())], false), - ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store), + ty::ty_bare_fn(*) => Type::i8p(), + ty::ty_closure(*) => Type::struct_([Type::i8p(), Type::i8p()], false), + ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), - ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size), + ty::ty_estr(ty::vstore_fixed(size)) => Type::array(Type::i8(), size), ty::ty_evec(mt, ty::vstore_fixed(size)) => { - T_array(sizing_type_of(cx, mt.ty), size) + Type::array(sizing_type_of(cx, mt.ty), size) } ty::ty_unboxed_vec(mt) => { let sz_ty = sizing_type_of(cx, mt.ty); - T_vec(cx, sz_ty) + Type::vec(cx.sess.targ_cfg.arch, sz_ty) } ty::ty_tup(*) | ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::sizing_fields_of(cx, repr), false) + Type::struct_(adt::sizing_fields_of(cx, repr), false) } ty::ty_struct(did, _) => { if ty::type_is_simd(cx.tcx, t) { let et = ty::simd_type(cx.tcx, t); let n = ty::simd_size(cx.tcx, t); - T_vector(type_of(cx, et), n) + Type::vector(type_of(cx, et), n) } else { let repr = adt::represent_type(cx, t); let packed = ty::lookup_packed(cx.tcx, did); - T_struct(adt::sizing_fields_of(cx, repr), packed) + Type::struct_(adt::sizing_fields_of(cx, repr), packed) } } ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { - cx.tcx.sess.bug( - fmt!("fictitious type %? in sizing_type_of()", - ty::get(t).sty)) + cx.tcx.sess.bug(fmt!("fictitious type %? in sizing_type_of()", ty::get(t).sty)) } }; @@ -182,7 +183,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { } // NB: If you update this, be sure to update `sizing_type_of()` as well. -pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { +pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { debug!("type_of %?: %?", t, ty::get(t)); // Check the cache. @@ -205,13 +206,13 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { } let llty = match ty::get(t).sty { - ty::ty_nil | ty::ty_bot => T_nil(), - ty::ty_bool => T_bool(), - ty::ty_int(t) => T_int_ty(cx, t), - ty::ty_uint(t) => T_uint_ty(cx, t), - ty::ty_float(t) => T_float_ty(cx, t), + ty::ty_nil | ty::ty_bot => Type::nil(), + ty::ty_bool => Type::bool(), + ty::ty_int(t) => Type::int_from_ty(cx, t), + ty::ty_uint(t) => Type::uint_from_ty(cx, t), + ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_estr(ty::vstore_uniq) => { - T_unique_ptr(T_unique(cx, T_vec(cx, T_i8()))) + Type::unique(cx, Type::vec(cx.sess.targ_cfg.arch, Type::i8())).ptr_to() } ty::ty_enum(did, ref substs) => { // Only create the named struct, but don't fill it in. We @@ -219,84 +220,79 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { // avoids creating more than one copy of the enum when one // of the enum's variants refers to the enum itself. - common::T_named_struct(llvm_type_name(cx, - an_enum, - did, - substs.tps)) + Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps)) } ty::ty_estr(ty::vstore_box) => { - T_box_ptr(T_box(cx, T_vec(cx, T_i8()))) + Type::box(cx, Type::vec(cx, Type::i8())).ptr_to() } ty::ty_evec(ref mt, ty::vstore_box) => { let e_ty = type_of(cx, mt.ty); - let v_ty = T_vec(cx, e_ty); - T_box_ptr(T_box(cx, v_ty)) + let v_ty = Type::vec(cx.sess.targ_cfg.arch, e_ty); + Type::box(cx, v_ty).ptr_to() } ty::ty_box(ref mt) => { let ty = type_of(cx, mt.ty); - T_box_ptr(T_box(cx, ty)) + Type::box(cx, ty).ptr_to() } - ty::ty_opaque_box => T_box_ptr(T_box(cx, T_i8())), + ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); - T_unique_ptr(T_unique(cx, ty)) + Type::unique(cx, ty).ptr_to() } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); - let ty = T_vec(cx, ty); - T_unique_ptr(T_unique(cx, ty)) + let ty = Type::vec(cx, ty); + Type::unique(cx, ty).ptr_to() } ty::ty_unboxed_vec(ref mt) => { let ty = type_of(cx, mt.ty); - T_vec(cx, ty) + Type::vec(cx.sess.targ_cfg.arch, ty) } - ty::ty_ptr(ref mt) => T_ptr(type_of(cx, mt.ty)), - ty::ty_rptr(_, ref mt) => T_ptr(type_of(cx, mt.ty)), + ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(), + ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(), ty::ty_evec(ref mt, ty::vstore_slice(_)) => { - let p_ty = T_ptr(type_of(cx, mt.ty)); - let u_ty = T_uint_ty(cx, ast::ty_u); - T_struct([p_ty, u_ty], false) + let p_ty = type_of(cx, mt.ty).ptr_to(); + let u_ty = Type::uint_from_ty(cx, ast::ty_u); + Type::struct_([p_ty, u_ty], false) } ty::ty_estr(ty::vstore_slice(_)) => { - T_struct([T_ptr(T_i8()), T_uint_ty(cx, ast::ty_u)], false) + // This means we get a nicer name in the output + cx.tn.find_type("str_slice").get() } ty::ty_estr(ty::vstore_fixed(n)) => { - T_array(T_i8(), n + 1u /* +1 for trailing null */) + Type::array(Type::i8(), n + 1u /* +1 for trailing null */) } ty::ty_evec(ref mt, ty::vstore_fixed(n)) => { - T_array(type_of(cx, mt.ty), n) + Type::array(type_of(cx, mt.ty), n) } - ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)), + ty::ty_bare_fn(_) => type_of_fn_from_ty(cx, t).ptr_to(), ty::ty_closure(_) => { let ty = type_of_fn_from_ty(cx, t); - T_fn_pair(cx, ty) + Type::func_pair(cx, ty) } - ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store), - ty::ty_type => T_ptr(cx.tydesc_type), + ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), + ty::ty_type => cx.tydesc_type.to_ptr(), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::fields_of(cx, repr), false) + Type::struct_(adt::fields_of(cx, repr), false) } - ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), + ty::ty_opaque_closure_ptr(_) => Type::opaque_box(cx).ptr_to(), ty::ty_struct(did, ref substs) => { - if ty::type_is_simd(cx.tcx, t) { - let et = ty::simd_type(cx.tcx, t); - let n = ty::simd_size(cx.tcx, t); - T_vector(type_of(cx, et), n) - } else { - // Only create the named struct, but don't fill it in. We fill it - // in *after* placing it into the type cache. This prevents - // infinite recursion with recursive struct types. - T_named_struct(llvm_type_name(cx, - a_struct, - did, - substs.tps)) - } + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + Type::vector(type_of(cx, et), n) + } else { + // Only create the named struct, but don't fill it in. We fill it + // in *after* placing it into the type cache. This prevents + // infinite recursion with recursive struct types. + Type::named_struct(llvm_type_name(cx, a_struct, did, substs.tps)) + } } ty::ty_self(*) => cx.tcx.sess.unimpl("type_of: ty_self"), ty::ty_infer(*) => cx.tcx.sess.bug("type_of with ty_infer"), @@ -336,33 +332,32 @@ pub fn llvm_type_name(cx: &CrateContext, did: ast::def_id, tps: &[ty::t]) -> ~str { let name = match what { - a_struct => { "~struct" } - an_enum => { "~enum" } + a_struct => { "struct" } + an_enum => { "enum" } }; - return fmt!( - "%s %s[#%d]", - name, - ppaux::parameterized( - cx.tcx, - ty::item_path_str(cx.tcx, did), - None, - tps), - did.crate - ); + let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did), None, tps); + if did.crate == 0 { + fmt!("%s.%s", name, tstr) + } else { + fmt!("%s.%s[#%d]", name, tstr, did.crate) + } } -pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> TypeRef { - T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_void()) +pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> Type { + let self_ty = type_of(ccx, self_ty).ptr_to(); + Type::func([self_ty], Type::viod()) } -pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef { +/* +pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> Type { let addrspace = base::get_tydesc(ccx, t).addrspace; debug!("type_of_rooted %s in addrspace %u", ppaux::ty_to_str(ccx.tcx, t), addrspace as uint); return T_root(type_of(ccx, t), addrspace); } -pub fn type_of_glue_fn(ccx: &CrateContext) -> TypeRef { +pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void()); } +*/ diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 91885f4dc4ff..6b2c6801e589 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -67,17 +67,12 @@ pub fn return_to_mut(mut bcx: block, bcx.val_to_str(frozen_val_ref), bcx.val_to_str(bits_val_ref)); - let box_ptr = - Load(bcx, PointerCast(bcx, - frozen_val_ref, - T_ptr(T_ptr(T_i8())))); + let box_ptr = Load(bcx, PointerCast(bcx, frozen_val_ref, Type::i8p().ptr_to())); - let bits_val = - Load(bcx, bits_val_ref); + let bits_val = Load(bcx, bits_val_ref); if bcx.tcx().sess.debug_borrows() { - bcx = callee::trans_lang_call( - bcx, + bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.unrecord_borrow_fn(), [ box_ptr, @@ -146,10 +141,7 @@ fn root(datum: &Datum, DynaMut => bcx.tcx().lang_items.borrow_as_mut_fn(), }; - let box_ptr = Load(bcx, - PointerCast(bcx, - scratch.val, - T_ptr(T_ptr(T_i8())))); + let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to())); bcx = callee::trans_lang_call( bcx, @@ -194,6 +186,6 @@ fn perform_write_guard(datum: &Datum, callee::trans_lang_call( bcx, bcx.tcx().lang_items.check_not_borrowed_fn(), - [PointerCast(bcx, llval, T_ptr(T_i8())), filename, line], + [PointerCast(bcx, llval, Type::i8p()), filename, line], expr::Ignore) } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 64af555bb37a..05833a52be28 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -457,9 +457,9 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { } ty_estr(vs) => fmt!("%s%s", vstore_to_str(cx, vs), "str"), ty_opaque_box => ~"@?", - ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"closure&", - ty_opaque_closure_ptr(ast::ManagedSigil) => ~"closure@", - ty_opaque_closure_ptr(ast::OwnedSigil) => ~"closure~", + ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"&closure", + ty_opaque_closure_ptr(ast::ManagedSigil) => ~"@closure", + ty_opaque_closure_ptr(ast::OwnedSigil) => ~"~closure", } } @@ -469,17 +469,17 @@ pub fn parameterized(cx: ctxt, tps: &[ty::t]) -> ~str { let r_str = match self_r { - None => ~"", - Some(r) => { - fmt!("/%s", region_to_str(cx, r)) - } + None => ~"", + Some(r) => { + region_to_str(cx, r) + } }; if tps.len() > 0u { let strs = vec::map(tps, |t| ty_to_str(cx, *t)); - fmt!("%s%s<%s>", base, r_str, strs.connect(",")) + fmt!("%s%s<%s>", r_str, base, strs.connect(",")) } else { - fmt!("%s%s", base, r_str) + fmt!("%s%s", r_str, base) } } From 81cf72c264efae4a16616ba6fc998ae862068d8b Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 22:52:44 +1200 Subject: [PATCH 048/336] Finish up Type refactoring --- src/librustc/back/upcall.rs | 8 +- src/librustc/lib/llvm.rs | 47 +-- src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/adt.rs | 12 +- src/librustc/middle/trans/asm.rs | 2 + src/librustc/middle/trans/base.rs | 92 +++--- src/librustc/middle/trans/build.rs | 55 ++-- src/librustc/middle/trans/cabi.rs | 57 ++-- src/librustc/middle/trans/cabi_arm.rs | 93 +++--- src/librustc/middle/trans/cabi_mips.rs | 101 +++--- src/librustc/middle/trans/cabi_x86.rs | 2 + src/librustc/middle/trans/cabi_x86_64.rs | 180 ++++++----- src/librustc/middle/trans/callee.rs | 8 +- src/librustc/middle/trans/closure.rs | 2 + src/librustc/middle/trans/common.rs | 392 ++--------------------- src/librustc/middle/trans/consts.rs | 54 ++-- src/librustc/middle/trans/context.rs | 16 +- src/librustc/middle/trans/controlflow.rs | 4 +- src/librustc/middle/trans/expr.rs | 14 +- src/librustc/middle/trans/foreign.rs | 19 +- src/librustc/middle/trans/glue.rs | 78 ++--- src/librustc/middle/trans/machine.rs | 4 +- src/librustc/middle/trans/meth.rs | 6 +- src/librustc/middle/trans/reflect.rs | 4 +- src/librustc/middle/trans/shape.rs | 6 +- src/librustc/middle/trans/tvec.rs | 2 + src/librustc/middle/trans/type_.rs | 64 ++-- src/librustc/middle/trans/type_of.rs | 73 ++--- src/librustc/middle/trans/write_guard.rs | 2 + src/libstd/unstable/intrinsics.rs | 10 +- 30 files changed, 520 insertions(+), 889 deletions(-) diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 731fa1c0ad79..76bba4816198 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -24,17 +24,17 @@ pub struct Upcalls { macro_rules! upcall ( (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ - let fn_ty = Type::func([ $($arg),* ], $ret); + let fn_ty = Type::func([ $($arg),* ], &$ret); base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty) }); (nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ - let fn_ty = Type::func([ $($arg),* ], $ret); + let fn_ty = Type::func([ $($arg),* ], &$ret); let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); base::set_no_unwind(decl); decl }); (nothrow fn $name:ident -> $ret:expr) => ({ - let fn_ty = Type::func([], $ret); + let fn_ty = Type::func([], &$ret); let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); base::set_no_unwind(decl); decl @@ -42,7 +42,7 @@ macro_rules! upcall ( ) pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { - let opaque_ptr = Type::i8().to_ptr(); + let opaque_ptr = Type::i8().ptr_to(); let int_ty = Type::int(targ_cfg.arch); @Upcalls { diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 627474b21892..ec3bf61608c3 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2141,7 +2141,7 @@ impl TypeNames { } pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> { - match self.type_names.find(ty.to_ref()) { + match self.type_names.find(&ty.to_ref()) { Some(a) => Some(a.slice(0, a.len())), None => None } @@ -2151,14 +2151,14 @@ impl TypeNames { self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) } - pub fn type_to_str(&self, ty: TypeRef) -> ~str { + pub fn type_to_str(&self, ty: Type) -> ~str { match self.find_name(&ty) { option::Some(name) => return name.to_owned(), None => () } unsafe { - let kind = llvm::LLVMGetTypeKind(ty); + let kind = ty.kind(); match kind { Void => ~"Void", @@ -2172,31 +2172,28 @@ impl TypeNames { Metadata => ~"Metadata", X86_MMX => ~"X86_MMAX", Integer => { - fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) as int) + fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) } Function => { - let out_ty = llvm::LLVMGetReturnType(ty); - let n_args = llvm::LLVMCountParamTypes(ty) as uint; - let args = vec::from_elem(n_args, 0 as TypeRef); - llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - + let out_ty = ty.return_type(); + let args = ty.func_params(); let args = args.map(|&ty| self.type_to_str(ty)).connect(", "); let out_ty = self.type_to_str(out_ty); fmt!("fn(%s) -> %s", args, out_ty) } Struct => { - let tys = struct_tys(ty); + let tys = ty.field_types(); let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", "); fmt!("{%s}", tys) } Array => { - let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = ty.element_type(); let el_ty = self.type_to_str(el_ty); - let len = llvm::LLVMGetArrayLength(ty) as uint; + let len = ty.array_length(); fmt!("[%s x %u]", el_ty, len) } Pointer => { - let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = ty.element_type(); let el_ty = self.type_to_str(el_ty); fmt!("*%s", el_ty) } @@ -2207,32 +2204,12 @@ impl TypeNames { pub fn val_to_str(&self, val: ValueRef) -> ~str { unsafe { - self.type_to_str(llvm::LLVMTypeOf(val)) + let ty = Type::from_ref(llvm::LLVMTypeOf(val)); + self.type_to_str(ty) } } } -pub fn float_width(llt: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(llt) as int { - 1 => 32u, - 2 => 64u, - 3 => 80u, - 4 | 5 => 128u, - _ => fail!("llvm_float_width called on a non-float type") - }; - } -} - -pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint, - 0 as TypeRef); - llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args)); - return args; - } -} - /* Memory-managed interface to target data. */ diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index db5a642019c0..72da71afed6e 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -911,7 +911,7 @@ pub fn extract_vec_elems(bcx: block, Sub(bcx, count, C_int(bcx.ccx(), (elem_count - i) as int))]) } - _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty) } + _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty.to_ref()) } } }; if slice.is_some() { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 65163e384b1f..906c9d028ebc 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -59,6 +59,8 @@ use middle::ty; use syntax::ast; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + /// Representations. pub enum Repr { @@ -260,10 +262,8 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let most_aligned = most_aligned.get(); let padding = largest_size - most_aligned.size; - assert!(padding >= 0); - struct_llfields(cx, most_aligned, sizing) - + [Type::array(Type::i8(), padding /*bad*/as uint)] + + [Type::array(&Type::i8(), padding)] } } } @@ -439,7 +439,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, // The unit-like case might have a nonzero number of unit-like fields. // (e.g., Result or Either with () as one side.) let ty = type_of::type_of(bcx.ccx(), nullfields[ix]); - assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0); + assert_eq!(machine::llsize_of_alloc(bcx.ccx(), ty), 0); // The contents of memory at this pointer can't matter, but use // the value that's "reasonable" in case of pointer comparison. PointerCast(bcx, val, ty.ptr_to()) @@ -457,7 +457,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, type_of::type_of(ccx, ty) }; let real_ty = Type::struct_(fields, st.packed); - PointerCast(bcx, val, real_llty.to_ptr().to_ref()) + PointerCast(bcx, val, real_ty.ptr_to()) } else { val }; @@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef]) } fn padding(size: u64) -> ValueRef { - C_undef(Type::array(Type::i8(), size).to_ref()) + C_undef(Type::array(&Type::i8(), size)) } // XXX this utility routine should be somewhere more general diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 17294107ce36..dd8b7ebc00b7 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -20,6 +20,8 @@ use middle::trans::callee; use middle::trans::common::*; use middle::ty; +use middle::trans::type_::Type; + use core::str; use syntax::ast; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index de91a9c593a5..8ec05f447ee3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -63,6 +63,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::{Repr, ty_to_str}; +use middle::trans::type_::Type; + use core::hash; use core::hashmap::{HashMap}; use core::int; @@ -150,7 +152,7 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) } pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { - return decl_fn(llmod, name, lib::llvm::CCallConv, llty); + return decl_fn(llmod, name, lib::llvm::CCallConv, ty); } // Only use this if you are going to actually define the function. It's @@ -229,7 +231,7 @@ pub fn opaque_box_body(bcx: block, let _icx = bcx.insn_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); - let ty = Type::box(ccx, ty); + let ty = Type::box(ccx, &ty); let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); GEPi(bcx, boxptr, [0u, abi::box_field_body]) } @@ -281,15 +283,8 @@ pub fn malloc_raw_dyn(bcx: block, * address space 0. Otherwise the resulting (non-box) pointer will be in the * wrong address space and thus be the wrong type. */ -pub fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef { - unsafe { - debug!("non_gc_box_cast"); - add_comment(bcx, "non_gc_box_cast"); - assert!(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == - gc_box_addrspace || bcx.unreachable); - let non_gc_t = llvm::LLVMGetElementType(val_ty(val)).ptr_to(); - PointerCast(bcx, val, non_gc_t) - } +pub fn non_gc_box_cast(_: block, val: ValueRef) -> ValueRef { + val } // malloc_raw: expects an unboxed type and returns a pointer to @@ -721,8 +716,8 @@ pub fn cast_shift_expr_rhs(cx: block, op: ast::binop, pub fn cast_shift_const_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef) -> ValueRef { cast_shift_rhs(op, lhs, rhs, - |a, b| unsafe { llvm::LLVMConstTrunc(a, b) }, - |a, b| unsafe { llvm::LLVMConstZExt(a, b) }) + |a, b| unsafe { llvm::LLVMConstTrunc(a, b.to_ref()) }, + |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) }) } pub fn cast_shift_rhs(op: ast::binop, @@ -735,8 +730,8 @@ pub fn cast_shift_rhs(op: ast::binop, if ast_util::is_shift_binop(op) { let rhs_llty = val_ty(rhs); let lhs_llty = val_ty(lhs); - let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty); - let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty); + let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty.to_ref()); + let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty.to_ref()); if lhs_sz < rhs_sz { trunc(rhs, lhs_llty) } else if lhs_sz > rhs_sz { @@ -761,11 +756,11 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, }; let is_zero = match ty::get(rhs_t).sty { ty::ty_int(t) => { - let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } ty::ty_uint(t) => { - let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } _ => { @@ -779,7 +774,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, } pub fn null_env_ptr(bcx: block) -> ValueRef { - C_null(Type::opaque_box(bcx.ccx()).to_ptr()) + C_null(Type::opaque_box(bcx.ccx()).ptr_to()) } pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) @@ -1479,7 +1474,7 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key); let llptr = PointerCast(cx, llptr, Type::i8().ptr_to()); let llzeroval = C_u8(0); - let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type.to_ref()); + let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type); let align = C_i32(llalign_of_min(ccx, ty) as i32); let volatile = C_i1(false); Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]); @@ -1506,7 +1501,7 @@ pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { } } let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); - let p = Alloca(initcx, ty.to_ref()); + let p = Alloca(initcx, ty); if zero { memzero(initcx, p, ty); } p } @@ -1515,10 +1510,10 @@ pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("arrayalloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(ty); + return llvm::LLVMGetUndef(ty.to_ref()); } } - return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty.to_ref(), v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty, v); } pub struct BasicBlocks { @@ -1588,7 +1583,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { - llvm::LLVMGetUndef(Type::i8p()) + llvm::LLVMGetUndef(Type::i8p().to_ref()) }, llretptr: None, llstaticallocas: llbbs.sa, @@ -2309,7 +2304,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, fn create_entry_fn(ccx: @mut CrateContext, rust_main: ValueRef, use_start_lang_item: bool) { - let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], ccx.int_type); + let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], &ccx.int_type); // FIXME #4404 android JNI hacks let llfn = if *ccx.sess.building_library { @@ -2338,10 +2333,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, } let crate_map = ccx.crate_map; - let opaque_crate_map = llvm::LLVMBuildPointerCast(bld, - crate_map, - Type::i8p(), - noname()); + let opaque_crate_map = do "crate_map".as_c_str |buf| { + llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf) + }; let (start_fn, args) = if use_start_lang_item { let start_def_id = ccx.tcx.lang_items.start_fn(); @@ -2354,8 +2348,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, }; let args = { - let opaque_rust_main = llvm::LLVMBuildPointerCast( - bld, rust_main, Type::i8p(), noname()); + let opaque_rust_main = do "rust_main".as_c_str |buf| { + llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf) + }; ~[ C_null(Type::opaque_box(ccx).ptr_to()), @@ -2487,7 +2482,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { let g = do str::as_c_str(ident) |buf| { unsafe { let ty = type_of(ccx, typ); - llvm::LLVMAddGlobal(ccx.llmod, ty, buf) + llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf) } }; g @@ -2583,7 +2578,7 @@ pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { note_unique_llvm_symbol(ccx, s); let discrim_gvar = str::as_c_str(s, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) } }); unsafe { @@ -2616,14 +2611,14 @@ pub fn vp2i(cx: block, v: ValueRef) -> ValueRef { pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef { unsafe { - return llvm::LLVMConstPtrToInt(v, ccx.int_type); + return llvm::LLVMConstPtrToInt(v, ccx.int_type.to_ref()); } } macro_rules! ifn ( ($name:expr, $args:expr, $ret:expr) => ({ let name = $name; - let f = decl_cdecl_fn(llmod, name, Type::func($args, $ret)); + let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret)); intrinsics.insert(name, f); }) ) @@ -2642,7 +2637,7 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); ifn!("llvm.memset.p0i8.i32", [i8p, Type::i8(), Type::i32(), Type::i32(), Type::i1()], Type::void()); - ifn!("llvm.memcpy.p0i8.i64", + ifn!("llvm.memset.p0i8.i64", [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); ifn!("llvm.trap", [], Type::void()); @@ -2710,7 +2705,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati } pub fn trap(bcx: block) { - match bcx.ccx().intrinsics.find_equiv("llvm.trap") { + match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") { Some(&x) => { Call(bcx, x, []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") } @@ -2724,7 +2719,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id; let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) } }; unsafe { @@ -2736,12 +2731,12 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { let elttype = Type::struct_([ccx.int_type, ccx.int_type], false); - let maptype = Type::array(elttype, ccx.module_data.len() + 1); - let map = str::as_c_str("_rust_mod_map", |buf| { + let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64); + let map = do "_rust_mod_map".as_c_str |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) + llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf) } - }); + }; lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage); let mut elts: ~[ValueRef] = ~[]; @@ -2783,11 +2778,11 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, ~"toplevel" }; let sym_name = ~"_rust_crate_map_" + mapname; - let arrtype = Type::array(int_type, n_subcrates as u64); + let arrtype = Type::array(&int_type, n_subcrates as u64); let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false); let map = str::as_c_str(sym_name, |buf| { unsafe { - llvm::LLVMAddGlobal(llmod, maptype, buf) + llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf) } }); lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage); @@ -2806,7 +2801,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { cstore::get_crate_hash(cstore, i)); let cr = str::as_c_str(nm, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) } }); subcrates.push(p2i(ccx, cr)); @@ -2830,8 +2825,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { let mod_map = create_module_map(ccx); llvm::LLVMSetInitializer(map, C_struct( [C_i32(1), - lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, - Type::i8p()), + lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, Type::i8p().to_ref()), p2i(ccx, mod_map), C_array(ccx.int_type, subcrates)])); } @@ -2869,7 +2863,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { let llconst = C_struct([llmeta]); let mut llglobal = str::as_c_str("rust_metadata", |buf| { unsafe { - llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf) + llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf) } }); unsafe { @@ -2880,9 +2874,9 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); let t_ptr_i8 = Type::i8p(); - llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8); + llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref()); let llvm_used = do "llvm.used".as_c_str |buf| { - llvm::LLVMAddGlobal(cx.llmod, Type::array(t_ptr_i8, 1u), buf) + llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf) }; lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage); llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal])); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index be14da66a162..3e5a23cb18eb 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -13,12 +13,14 @@ use core::prelude::*; use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; use lib::llvm::{Opcode, IntPredicate, RealPredicate, False}; -use lib::llvm::{ValueRef, Type, BasicBlockRef, BuilderRef, ModuleRef}; +use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef}; use lib; use middle::trans::common::*; use middle::trans::machine::llalign_of_min; use syntax::codemap::span; +use middle::trans::type_::Type; + use core::cast; use core::hashmap::HashMap; use core::libc::{c_uint, c_ulonglong, c_char}; @@ -232,7 +234,7 @@ pub fn Unreachable(cx: block) { pub fn _Undef(val: ValueRef) -> ValueRef { unsafe { - return llvm::LLVMGetUndef(val_ty(val)); + return llvm::LLVMGetUndef(val_ty(val).to_ref()); } } @@ -504,7 +506,7 @@ pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { pub fn Alloca(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "alloca"); return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname()); } @@ -512,7 +514,7 @@ pub fn Alloca(cx: block, Ty: Type) -> ValueRef { pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "arrayalloca"); return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname()); } @@ -531,9 +533,12 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef { let ccx = cx.fcx.ccx; if cx.unreachable { let ty = val_ty(PointerVal); - let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array { - llvm::LLVMGetElementType(ty) } else { ccx.int_type }; - return llvm::LLVMGetUndef(eltty); + let eltty = if ty.kind() == lib::llvm::Array { + ty.element_type() + } else { + ccx.int_type + }; + return llvm::LLVMGetUndef(eltty.to_ref()); } count_insn(cx, "load"); return llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); @@ -544,7 +549,7 @@ pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> Val unsafe { let ccx = cx.fcx.ccx; if cx.unreachable { - return llvm::LLVMGetUndef(ccx.int_type); + return llvm::LLVMGetUndef(ccx.int_type.to_ref()); } count_insn(cx, "load.atomic"); let align = llalign_of_min(ccx, ccx.int_type); @@ -639,7 +644,7 @@ pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstring"); return llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } @@ -647,7 +652,7 @@ pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstringptr"); return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } @@ -841,7 +846,7 @@ pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) unsafe { if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } assert_eq!(vals.len(), bbs.len()); - let phi = EmptyPhi(cx, Ty.to_ref()); + let phi = EmptyPhi(cx, Ty); count_insn(cx, "addincoming"); llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals), vec::raw::to_ptr(bbs), @@ -863,10 +868,13 @@ pub fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef { unsafe { let ccx = cx.fcx.ccx; let ty = val_ty(Fn); - let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer { - llvm::LLVMGetReturnType(ty) } else { ccx.int_type }; - count_insn(cx, ""); - return llvm::LLVMGetUndef(retty); + let retty = if ty.kind() == lib::llvm::Integer { + ty.return_type() + } else { + ccx.int_type + }; + count_insn(cx, "ret_undef"); + return llvm::LLVMGetUndef(retty.to_ref()); } } @@ -887,9 +895,10 @@ pub fn add_comment(bcx: block, text: &str) { let comment_text = ~"# " + sanitized.replace("\n", "\n\t# "); count_insn(bcx, "inlineasm"); - let asm = str::as_c_str(comment_text, |c| { - llvm::LLVMConstInlineAsm(Type::func([], Type::void()), c, noname(), False, False) - }); + let asm = do comment_text.as_c_str |c| { + llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(), + c, noname(), False, False) + }; Call(bcx, asm, []); } } @@ -913,8 +922,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, }; debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); - let fty = Type::func(argtys, output); - let v = llvm::LLVMInlineAsm(llfty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); + let fty = Type::func(argtys, &output); + let v = llvm::LLVMInlineAsm(fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); Call(cx, v, inputs) } @@ -1005,9 +1014,9 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { unsafe { let elt_ty = val_ty(EltVal); - let Undef = llvm::LLVMGetUndef(Type::vector(elt_ty, NumElts).to_ref()); + let Undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, NumElts as u64).to_ref()); let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0)); - ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(Type::i32().to_ref(), NumElts))) + ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(&Type::i32(), NumElts as u64))) } } @@ -1049,7 +1058,7 @@ pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef { pub fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { let ccx = cx.fcx.ccx; - if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); } + if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type.to_ref()); } count_insn(cx, "ptrdiff"); return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 036f34b1974e..dffa5a7f1ad0 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -8,20 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use lib::llvm::{llvm, TypeRef, ValueRef, Attribute, Void}; +use lib::llvm::{llvm, ValueRef, Attribute, Void}; use middle::trans::base::*; use middle::trans::build::*; use middle::trans::common::*; +use middle::trans::type_::Type; + use core::libc::c_uint; use core::option; use core::vec; pub trait ABIInfo { - fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, - ret_def: bool) -> FnType; + fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType; } pub struct LLVMType { @@ -40,7 +39,7 @@ impl FnType { pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef { let atys = vec::map(self.arg_tys, |t| t.ty); let rty = self.ret_ty.ty; - let fnty = Type::func(atys, rty); + let fnty = Type::func(atys, &rty); let llfn = decl(fnty); for self.attrs.iter().enumerate().advance |(i, a)| { @@ -57,10 +56,7 @@ impl FnType { return llfn; } - pub fn build_shim_args(&self, - bcx: block, - arg_tys: &[Type], - llargbundle: ValueRef) + pub fn build_shim_args(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) -> ~[ValueRef] { let mut atys: &[LLVMType] = self.arg_tys; let mut attrs: &[option::Option] = self.attrs; @@ -80,7 +76,7 @@ impl FnType { while i < n { let llargval = if atys[i].cast { let arg_ptr = GEPi(bcx, llargbundle, [0u, i]); - let arg_ptr = BitCast(bcx, arg_ptr, T_ptr(atys[i].ty)); + let arg_ptr = BitCast(bcx, arg_ptr, atys[i].ty.ptr_to()); Load(bcx, arg_ptr) } else if attrs[i].is_some() { GEPi(bcx, llargbundle, [0u, i]) @@ -94,19 +90,14 @@ impl FnType { return llargvals; } - pub fn build_shim_ret(&self, - bcx: block, - arg_tys: &[Type], - ret_def: bool, - llargbundle: ValueRef, - llretval: ValueRef) { + pub fn build_shim_ret(&self, bcx: block, arg_tys: &[Type], ret_def: bool, + llargbundle: ValueRef, llretval: ValueRef) { + for vec::eachi(self.attrs) |i, a| { for self.attrs.iter().enumerate().advance |(i, a)| { match *a { option::Some(attr) => { unsafe { - llvm::LLVMAddInstrAttribute(llretval, - (i + 1u) as c_uint, - attr as c_uint); + llvm::LLVMAddInstrAttribute(llretval, (i + 1u) as c_uint, attr as c_uint); } } _ => () @@ -121,7 +112,7 @@ impl FnType { // R* llretloc = *llretptr; /* (args->r) */ let llretloc = Load(bcx, llretptr); if self.ret_ty.cast { - let tmp_ptr = BitCast(bcx, llretloc, T_ptr(self.ret_ty.ty)); + let tmp_ptr = BitCast(bcx, llretloc, self.ret_ty.ty.ptr_to()); // *args->r = r; Store(bcx, llretval, tmp_ptr); } else { @@ -130,11 +121,8 @@ impl FnType { }; } - pub fn build_wrap_args(&self, - bcx: block, - ret_ty: Type, - llwrapfn: ValueRef, - llargbundle: ValueRef) { + pub fn build_wrap_args(&self, bcx: block, ret_ty: Type, + llwrapfn: ValueRef, llargbundle: ValueRef) { let mut atys: &[LLVMType] = self.arg_tys; let mut attrs: &[option::Option] = self.attrs; let mut j = 0u; @@ -159,7 +147,7 @@ impl FnType { store_inbounds(bcx, argval, llargbundle, [0u, i]); } else if atys[i].cast { let argptr = GEPi(bcx, llargbundle, [0u, i]); - let argptr = BitCast(bcx, argptr, T_ptr(atys[i].ty)); + let argptr = BitCast(bcx, argptr, atys[i].ty.ptr_to()); Store(bcx, argval, argptr); } else { store_inbounds(bcx, argval, llargbundle, [0u, i]); @@ -169,14 +157,9 @@ impl FnType { store_inbounds(bcx, llretptr, llargbundle, [0u, n]); } - pub fn build_wrap_ret(&self, - bcx: block, - arg_tys: &[TypeRef], - llargbundle: ValueRef) { - unsafe { - if llvm::LLVMGetTypeKind(self.ret_ty.ty) == Void { - return; - } + pub fn build_wrap_ret(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) { + if self.ret_ty.ty.kind() == Void { + return; } if bcx.fcx.llretptr.is_some() { @@ -187,9 +170,7 @@ impl FnType { } else { Load(bcx, llretval) }; - let llretptr = BitCast(bcx, - bcx.fcx.llretptr.get(), - self.ret_ty.ty.ptr_to()); + let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), self.ret_ty.ty.ptr_to()); Store(bcx, llretval, llretptr); } } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index f29ccad76b17..69896972ef06 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -9,11 +9,12 @@ // except according to those terms. use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; -use lib::llvm::struct_tys; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; +use middle::trans::type_::Type; + use core::option::{Option, None, Some}; use core::uint; @@ -27,58 +28,58 @@ fn align(off: uint, ty: Type) -> uint { } fn ty_align(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + match ty.kind() { + Integer => { + unsafe { ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - 1 - } else { - let str_tys = ty.field_types(); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } - } - Array => { - let elt = ty.element_type(); - ty_align(elt) - } - _ => fail!("ty_align: unhandled type") } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) + } + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_align: unhandled type") } } fn ty_size(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + match ty.kind() { + Integer => { + unsafe { ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - let str_tys = ty.field_types(); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = ty.field_types(); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } - } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) + } + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } @@ -107,9 +108,9 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option) { let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - Type::array(Type::i32(), (size + 3) / 4) + Type::array(&Type::i32(), (size + 3) / 4 as u64) } else { - Type::array(Type::i64(), (size + 7) / 8) + Type::array(&Type::i64(), (size + 7) / 8 as u64) }; (LLVMType { cast: true, ty: llty }, None) } @@ -122,7 +123,7 @@ fn is_reg_ty(ty: Type) -> bool { | Float | Double => true, _ => false - }; + } } } diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 73d26b91672d..27ac267895b3 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -15,13 +15,14 @@ use core::ptr; use core::uint; use core::vec; use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; -use lib::llvm::struct_tys; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::context::task_llcx; use middle::trans::common::*; use middle::trans::cabi::*; +use middle::trans::type_::Type; + fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } @@ -32,58 +33,58 @@ fn align(off: uint, ty: Type) -> uint { } fn ty_align(ty: Type) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - 1 - } else { - let str_tys = struct_tys(ty); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } - } - Array => { - let elt = llvm::LLVMGetElementType(ty); - ty_align(elt) - } - _ => fail!("ty_size: unhandled type") - }; + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) + } + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_size: unhandled type") } } -fn ty_size(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 +fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = ty.field_types(); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") - }; + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } @@ -120,7 +121,7 @@ fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option) }; } -fn is_reg_ty(ty: TypeRef) -> bool { +fn is_reg_ty(ty: Type) -> bool { unsafe { return match ty.kind() { Integer @@ -153,11 +154,11 @@ fn coerce_to_int(size: uint) -> ~[Type] { let r = size % 32; if r > 0 { unsafe { - Type::from_ref(args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))) + args.push(Type::from_ref(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))); } } - return args; + args } fn struct_ty(ty: Type, diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 0f02f7d2f868..bdfe0e3d77da 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -17,6 +17,8 @@ use super::cabi::*; use super::common::*; use super::machine::*; +use middle::trans::type_::Type; + struct X86_ABIInfo { ccx: @mut CrateContext } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index e0f9ad85e10a..01ec4a90cb08 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -11,14 +11,15 @@ // The classification code for the x86_64 ABI is taken from the clay language // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp -use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; +use lib::llvm::{llvm, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute, ByValAttribute}; -use lib::llvm::struct_tys; use lib::llvm::True; use middle::trans::common::*; use middle::trans::cabi::*; +use middle::trans::type_::Type; + use core::libc::c_uint; use core::option; use core::option::Option; @@ -28,7 +29,7 @@ use core::vec; #[deriving(Eq)] enum RegClass { NoClass, - Integer, + Int, SSEFs, SSEFv, SSEDs, @@ -43,7 +44,7 @@ enum RegClass { impl Type { fn is_reg_ty(&self) -> bool { - match ty.kind() { + match self.kind() { Integer | Pointer | Float | Double => true, _ => false } @@ -59,6 +60,11 @@ impl RegClass { } } +trait ClassList { + fn is_pass_byval(&self) -> bool; + fn is_ret_bysret(&self) -> bool; +} + impl<'self> ClassList for &'self [RegClass] { fn is_pass_byval(&self) -> bool { if self.len() == 0 { return false; } @@ -83,64 +89,64 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } fn ty_align(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + match ty.kind() { + Integer => { + unsafe { ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 8, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - 1 - } else { - let str_tys = ty.field_types(); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } - } - Array => { - let elt = ty.element_type(); - ty_align(elt) - } - _ => fail!("ty_size: unhandled type") - }; + } + Pointer => 8, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) + } + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_size: unhandled type") } } - fn ty_size(ty: TypeRef) -> uint { - unsafe { - match ty.kind() { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 8, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - let str_tys = ty.field_types(); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = ty.field_types(); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } - } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") } + Pointer => 8, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) + } + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } fn all_mem(cls: &mut [RegClass]) { for uint::range(0, cls.len()) |i| { - cls[i] = memory_class; + cls[i] = Memory; } } @@ -149,21 +155,21 @@ fn classify_ty(ty: Type) -> ~[RegClass] { newv: RegClass) { if cls[i] == newv { return; - } else if cls[i] == no_class { + } else if cls[i] == NoClass { cls[i] = newv; - } else if newv == no_class { + } else if newv == NoClass { return; - } else if cls[i] == memory_class || newv == memory_class { - cls[i] = memory_class; - } else if cls[i] == integer_class || newv == integer_class { - cls[i] = integer_class; - } else if cls[i] == x87_class || - cls[i] == x87up_class || - cls[i] == complex_x87_class || - newv == x87_class || - newv == x87up_class || - newv == complex_x87_class { - cls[i] = memory_class; + } else if cls[i] == Memory || newv == Memory { + cls[i] = Memory; + } else if cls[i] == Int || newv == Int { + cls[i] = Int; + } else if cls[i] == X87 || + cls[i] == X87Up || + cls[i] == ComplexX87 || + newv == X87 || + newv == X87Up || + newv == ComplexX87 { + cls[i] = Memory; } else { cls[i] = newv; } @@ -192,7 +198,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { let mut i = off / 8u; let e = (off + t_size + 7u) / 8u; while i < e { - unify(cls, ix + i, memory_class); + unify(cls, ix + i, Memory); i += 1u; } return; @@ -201,17 +207,17 @@ fn classify_ty(ty: Type) -> ~[RegClass] { match ty.kind() { Integer | Pointer => { - unify(cls, ix + off / 8u, integer_class); + unify(cls, ix + off / 8u, Int); } Float => { if off % 8u == 4u { - unify(cls, ix + off / 8u, sse_fv_class); + unify(cls, ix + off / 8u, SSEFv); } else { - unify(cls, ix + off / 8u, sse_fs_class); + unify(cls, ix + off / 8u, SSEFs); } } Double => { - unify(cls, ix + off / 8u, sse_ds_class); + unify(cls, ix + off / 8u, SSEDs); } Struct => { classify_struct(ty.field_types(), cls, ix, off); @@ -242,7 +248,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { if cls[i].is_sse() { i += 1u; while i < e { - if cls[i] != sseup_class { + if cls[i] != SSEUp { all_mem(cls); return; } @@ -254,24 +260,24 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } } else { while i < e { - if cls[i] == memory_class { + if cls[i] == Memory { all_mem(cls); return; } - if cls[i] == x87up_class { + if cls[i] == X87Up { // for darwin - // cls[i] = sse_ds_class; + // cls[i] = SSEDs; all_mem(cls); return; } - if cls[i] == sseup_class { - cls[i] = sse_int_class; + if cls[i] == SSEUp { + cls[i] = SSEInt; } else if cls[i].is_sse() { i += 1; - while i != e && cls[i] == sseup_class { i += 1u; } - } else if cls[i] == x87_class { + while i != e && cls[i] == SSEUp { i += 1u; } + } else if cls[i] == X87 { i += 1; - while i != e && cls[i] == x87up_class { i += 1u; } + while i != e && cls[i] == X87Up { i += 1u; } } else { i += 1; } @@ -281,7 +287,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } let words = (ty_size(ty) + 7) / 8; - let mut cls = vec::from_elem(words, no_class); + let mut cls = vec::from_elem(words, NoClass); if words > 4 { all_mem(cls); let cls = cls; @@ -296,7 +302,7 @@ fn llreg_ty(cls: &[RegClass]) -> Type { fn llvec_len(cls: &[RegClass]) -> uint { let mut len = 1u; for cls.each |c| { - if *c != sseup_class { + if *c != SSEUp { break; } len += 1u; @@ -310,20 +316,20 @@ fn llreg_ty(cls: &[RegClass]) -> Type { let e = cls.len(); while i < e { match cls[i] { - integer_class => { + Int => { tys.push(Type::i64()); } - sse_fv_class => { + SSEFv => { let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; - let vec_ty = Type::vector(Type::f32(), vec_len); + let vec_ty = Type::vector(&Type::f32(), vec_len as u64); tys.push(vec_ty); i += vec_len; loop; } - sse_fs_class => { + SSEFs => { tys.push(Type::f32()); } - sse_ds_class => { + SSEDs => { tys.push(Type::f64()); } _ => fail!("llregtype: unhandled class") @@ -341,6 +347,7 @@ fn x86_64_tys(atys: &[Type], fn x86_64_ty(ty: Type, is_mem_cls: &fn(cls: &[RegClass]) -> bool, attr: Attribute) -> (LLVMType, Option) { + let (cast, attr, ty) = if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls) { @@ -348,8 +355,11 @@ fn x86_64_tys(atys: &[Type], } else { (true, option::None, llreg_ty(cls)) } + } else { + (false, option::None, ty) }; - return (LLVMType { cast: cast, ty: ty }, attr); + + (LLVMType { cast: cast, ty: ty }, attr) } let mut arg_tys = ~[]; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 6d2446f01370..c74a2320b5b9 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -45,6 +45,8 @@ use middle::typeck; use middle::typeck::coherence::make_substs_for_receiver_types; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::vec; use syntax::ast; use syntax::ast_map; @@ -526,7 +528,7 @@ pub fn trans_call_inner(in_cx: block, let (llfn, llenv) = unsafe { match callee.data { Fn(d) => { - (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to())) + (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref())) } Method(d) => { // Weird but true: we pass self in the *environment* slot! @@ -653,7 +655,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) expr::Ignore => { if ty::type_is_nil(retty) { unsafe { - llvm::LLVMGetUndef(Type::nil().ptr_to()) + llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) } } else { alloc_ty(bcx, retty) @@ -777,7 +779,7 @@ pub fn trans_arg_expr(bcx: block, // to have type lldestty (the callee's expected type). let llformal_arg_ty = type_of::type_of(ccx, formal_arg_ty); unsafe { - val = llvm::LLVMGetUndef(llformal_arg_ty); + val = llvm::LLVMGetUndef(llformal_arg_ty.to_ref()); } } else { // FIXME(#3548) use the adjustments table diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 35e8e866039c..7d7c024640ab 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -26,6 +26,8 @@ use middle::trans::type_of::*; use middle::ty; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 01b0411a07b2..3f9f39ac852d 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -31,6 +31,8 @@ use middle::typeck; use middle::borrowck::root_map_key; use util::ppaux::{Repr}; +use middle::trans::type_::Type; + use core::cast::transmute; use core::cast; use core::hashmap::{HashMap}; @@ -58,29 +60,11 @@ pub fn new_namegen() -> namegen { f } -pub type addrspace = c_uint; - -// Address spaces communicate to LLVM which destructors need to run for -// specific types. -// 0 is ignored by the GC, and is used for all non-GC'd pointers. -// 1 is for opaque GC'd boxes. -// >= 2 are for specific types (e.g. resources). -pub static default_addrspace: addrspace = 0; -pub static gc_box_addrspace: addrspace = 1; - -pub type addrspace_gen = @fn() -> addrspace; -pub fn new_addrspace_gen() -> addrspace_gen { - let i = @mut 1; - let result: addrspace_gen = || { *i += 1; *i }; - result -} - pub struct tydesc_info { ty: ty::t, tydesc: ValueRef, size: ValueRef, align: ValueRef, - addrspace: addrspace, take_glue: Option, drop_glue: Option, free_glue: Option, @@ -345,39 +329,14 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype { } } -// This is not the same as datum::Datum::root(), which is used to keep copies -// of @ values live for as long as a borrowed pointer to the interior exists. -// In the new GC, we can identify immediates on the stack without difficulty, -// but have trouble knowing where non-immediates are on the stack. For -// non-immediates, we must add an additional level of indirection, which -// allows us to alloca a pointer with the right addrspace. -pub fn root_for_cleanup(bcx: block, v: ValueRef, t: ty::t) - -> (ValueRef, bool) { - let ccx = bcx.ccx(); - - let addrspace = base::get_tydesc(ccx, t).addrspace; - if addrspace > gc_box_addrspace { - let llty = type_of::type_of_rooted(ccx, t); - let root = base::alloca(bcx, llty); - build::Store(bcx, build::PointerCast(bcx, v, llty), root); - (root, true) - } else { - (v, false) - } -} - pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } - debug!("add_clean(%s, %s, %s)", - bcx.to_str(), - bcx.val_to_str(val), - t.repr(bcx.tcx())); - let (root, rooted) = root_for_cleanup(bcx, val, 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| { - scope_info.cleanups.push( - clean(|a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } @@ -400,12 +359,9 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean_temp_mem(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); - let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { - scope_info.cleanups.push( - clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } @@ -431,12 +387,8 @@ pub fn add_clean_return_to_mut(bcx: block, scope_info.cleanups.push( clean_temp( frozen_val_ref, - |bcx| write_guard::return_to_mut(bcx, - root_key, - frozen_val_ref, - bits_val_ref, - filename_val, - line_val), + |bcx| write_guard::return_to_mut(bcx, root_key, frozen_val_ref, bits_val_ref, + filename_val, line_val), normal_exit_only)); grow_scope_clean(scope_info); } @@ -621,9 +573,9 @@ impl Result { } } -pub fn val_ty(v: ValueRef) -> TypeRef { +pub fn val_ty(v: ValueRef) -> Type { unsafe { - return llvm::LLVMTypeOf(v); + Type::from_ref(llvm::LLVMTypeOf(v)) } } @@ -706,313 +658,6 @@ impl block_ { } } -/* -// LLVM type constructors. -pub fn T_void() -> TypeRef { - unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); } -} - -pub fn T_nil() -> TypeRef { - return T_struct([], false) -} - -pub fn T_metadata() -> TypeRef { - unsafe { return llvm::LLVMMetadataTypeInContext(base::task_llcx()); } -} - -pub fn T_i1() -> TypeRef { - unsafe { return llvm::LLVMInt1TypeInContext(base::task_llcx()); } -} - -pub fn T_i8() -> TypeRef { - unsafe { return llvm::LLVMInt8TypeInContext(base::task_llcx()); } -} - -pub fn T_i16() -> TypeRef { - unsafe { return llvm::LLVMInt16TypeInContext(base::task_llcx()); } -} - -pub fn T_i32() -> TypeRef { - unsafe { return llvm::LLVMInt32TypeInContext(base::task_llcx()); } -} - -pub fn T_i64() -> TypeRef { - unsafe { return llvm::LLVMInt64TypeInContext(base::task_llcx()); } -} - -pub fn T_f32() -> TypeRef { - unsafe { return llvm::LLVMFloatTypeInContext(base::task_llcx()); } -} - -pub fn T_f64() -> TypeRef { - unsafe { return llvm::LLVMDoubleTypeInContext(base::task_llcx()); } -} - -pub fn T_bool() -> TypeRef { return T_i8(); } - -pub fn T_int(targ_cfg: &session::config) -> TypeRef { - return match targ_cfg.arch { - X86 => T_i32(), - X86_64 => T_i64(), - Arm => T_i32(), - Mips => T_i32() - }; -} - -pub fn T_int_ty(cx: &CrateContext, t: ast::int_ty) -> TypeRef { - match t { - ast::ty_i => cx.int_type, - ast::ty_char => T_char(), - ast::ty_i8 => T_i8(), - ast::ty_i16 => T_i16(), - ast::ty_i32 => T_i32(), - ast::ty_i64 => T_i64() - } -} - -pub fn T_uint_ty(cx: &CrateContext, t: ast::uint_ty) -> TypeRef { - match t { - ast::ty_u => cx.int_type, - ast::ty_u8 => T_i8(), - ast::ty_u16 => T_i16(), - ast::ty_u32 => T_i32(), - ast::ty_u64 => T_i64() - } -} - -pub fn T_float_ty(cx: &CrateContext, t: ast::float_ty) -> TypeRef { - match t { - ast::ty_f => cx.float_type, - ast::ty_f32 => T_f32(), - ast::ty_f64 => T_f64() - } -} - -pub fn T_float(targ_cfg: &session::config) -> TypeRef { - return match targ_cfg.arch { - X86 => T_f64(), - X86_64 => T_f64(), - Arm => T_f64(), - Mips => T_f64() - }; -} - -pub fn T_char() -> TypeRef { return T_i32(); } - -pub fn T_size_t(targ_cfg: &session::config) -> TypeRef { - return T_int(targ_cfg); -} - -pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMFunctionType(output, to_ptr(inputs), - inputs.len() as c_uint, - False); - } -} - -pub fn T_fn_pair(cx: &CrateContext, tfn: TypeRef) -> TypeRef { - return T_struct([T_ptr(tfn), T_opaque_cbox_ptr(cx)], false); -} - -pub fn T_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, default_addrspace); - } -} - -pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, addrspace); - } -} - -pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef { - unsafe { - return llvm::LLVMStructTypeInContext(base::task_llcx(), - to_ptr(elts), - elts.len() as c_uint, - packed as Bool); - } -} - -pub fn T_named_struct(name: &str) -> TypeRef { - unsafe { - return str::as_c_str(name, |buf| { - llvm::LLVMStructCreateNamed(base::task_llcx(), buf) - }); - } -} - -pub fn set_struct_body(t: TypeRef, elts: &[TypeRef], packed: bool) { - unsafe { - llvm::LLVMStructSetBody(t, - to_ptr(elts), - elts.len() as c_uint, - packed as Bool); - } -} - -pub fn T_empty_struct() -> TypeRef { return T_struct([], false); } - -// A vtable is, in reality, a vtable pointer followed by zero or more pointers -// to tydescs and other vtables that it closes over. But the types and number -// of those are rarely known to the code that needs to manipulate them, so -// they are described by this opaque type. -pub fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) } - -pub fn T_tydesc_field(cx: &CrateContext, field: uint) -> TypeRef { - // Bit of a kludge: pick the fn typeref out of the tydesc.. - - unsafe { - let mut tydesc_elts: ~[TypeRef] = - vec::from_elem::(abi::n_tydesc_fields, - T_nil()); - llvm::LLVMGetStructElementTypes(cx.tydesc_type, &mut tydesc_elts[0]); - let t = llvm::LLVMGetElementType(tydesc_elts[field]); - return t; - } -} - -pub fn T_generic_glue_fn(cx: &mut CrateContext) -> TypeRef { - let s = @"glue_fn"; - match cx.tn.find_type(s) { - Some(t) => return t, - _ => () - } - let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue); - cx.tn.associate_type(s, t); - return t; -} - -pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef { - let tydesc = T_named_struct("tydesc"); - let tydescpp = T_ptr(T_ptr(tydesc)); - let pvoid = T_ptr(T_i8()); - let glue_fn_ty = - T_ptr(T_fn([T_ptr(T_nil()), tydescpp, pvoid], T_void())); - - let int_type = T_int(targ_cfg); - let elems = - ~[int_type, int_type, - glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, - T_ptr(T_i8()), T_ptr(T_i8())]; - set_struct_body(tydesc, elems, false); - return tydesc; -} - -pub fn T_array(t: TypeRef, n: uint) -> TypeRef { - unsafe { - return llvm::LLVMArrayType(t, n as c_uint); - } -} - -pub fn T_vector(t: TypeRef, n: uint) -> TypeRef { - unsafe { - return llvm::LLVMVectorType(t, n as c_uint); - } -} - -// Interior vector. -pub fn T_vec2(targ_cfg: &session::config, t: TypeRef) -> TypeRef { - return T_struct([T_int(targ_cfg), // fill - T_int(targ_cfg), // alloc - T_array(t, 0u)], // elements - false); -} - -pub fn T_vec(ccx: &CrateContext, t: TypeRef) -> TypeRef { - return T_vec2(ccx.sess.targ_cfg, t); -} - -// Note that the size of this one is in bytes. -pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef { - return T_vec2(targ_cfg, T_i8()); -} - -pub fn T_box_header_fields(cx: &CrateContext) -> ~[TypeRef] { - let ptr = T_ptr(T_i8()); - return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr]; -} - -pub fn T_box_header(cx: &CrateContext) -> TypeRef { - return T_struct(T_box_header_fields(cx), false); -} - -pub fn T_box(cx: &CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), [t]), false); -} - -pub fn T_box_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, gc_box_addrspace); - } -} - -pub fn T_opaque_box(cx: &CrateContext) -> TypeRef { - return T_box(cx, T_i8()); -} - -pub fn T_opaque_box_ptr(cx: &CrateContext) -> TypeRef { - return T_box_ptr(T_opaque_box(cx)); -} - -pub fn T_unique(cx: &CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), [t]), false); -} - -pub fn T_unique_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, gc_box_addrspace); - } -} - -pub fn T_port(cx: &CrateContext, _t: TypeRef) -> TypeRef { - return T_struct([cx.int_type], false); // Refcount - -} - -pub fn T_chan(cx: &CrateContext, _t: TypeRef) -> TypeRef { - return T_struct([cx.int_type], false); // Refcount - -} - - -pub fn T_opaque_cbox_ptr(cx: &CrateContext) -> TypeRef { - // closures look like boxes (even when they are ~fn or &fn) - // see trans_closure.rs - return T_opaque_box_ptr(cx); -} - -pub fn T_enum_discrim(cx: &CrateContext) -> TypeRef { - return cx.int_type; -} - -pub fn T_captured_tydescs(cx: &CrateContext, n: uint) -> TypeRef { - return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type)), false); -} - -pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef { - match store { - ty::BoxTraitStore => { - T_struct([T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)], false) - } - ty::UniqTraitStore => { - T_struct([T_ptr(cx.tydesc_type), - T_unique_ptr(T_unique(cx, T_i8()))], - false) - } - ty::RegionTraitStore(_) => { - T_struct([T_ptr(cx.tydesc_type), T_ptr(T_i8())], false) - } - } -} - -pub fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); } - -pub fn T_opaque_chan_ptr() -> TypeRef { return T_ptr(T_i8()); } -*/ - // Let T be the content of a box @T. tuplify_box_ty(t) returns the // representation of @T as a tuple (i.e., the ty::t version of what T_box() // returns). @@ -1101,7 +746,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { }; let gsym = token::gensym("str"); - let g = fmt!("str%u", gsym).as_c_str |buf| { + let g = do fmt!("str%u", gsym).as_c_str |buf| { llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf) }; llvm::LLVMSetInitializer(g, sc); @@ -1138,7 +783,8 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { let mut i = 0u; let mut elts: ~[ValueRef] = ~[]; while i < size { elts.push(C_u8(0u)); i += 1u; } - return llvm::LLVMConstArray(Type::i8(), vec::raw::to_ptr(elts), elts.len() as c_uint); + return llvm::LLVMConstArray(Type::i8().to_ref(), + vec::raw::to_ptr(elts), elts.len() as c_uint); } } @@ -1158,17 +804,17 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { } } -pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef { +pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef { unsafe { do vec::as_imm_buf(elts) |ptr, len| { - llvm::LLVMConstNamedStruct(T, ptr, len as c_uint) + llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint) } } } -pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef { +pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef { unsafe { - return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), elts.len() as c_uint); + return llvm::LLVMConstArray(ty.to_ref(), vec::raw::to_ptr(elts), elts.len() as c_uint); } } @@ -1193,7 +839,7 @@ pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { let llglobal = do name.as_c_str |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) }; - llvm::LLVMSetInitializer(llglobal, llshape.to_ref()); + llvm::LLVMSetInitializer(llglobal, llshape); llvm::LLVMSetGlobalConstant(llglobal, True); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index dcdb53ec532a..456dc6edfb6b 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -11,7 +11,7 @@ use core::prelude::*; use back::abi; -use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool, +use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True, False}; use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; @@ -30,6 +30,8 @@ use middle::trans::type_of; use middle::ty; use util::ppaux::{Repr, ty_to_str}; +use middle::trans::type_::Type; + use core::libc::c_uint; use core::str; use syntax::{ast, ast_util, ast_map}; @@ -38,28 +40,28 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { let _icx = cx.insn_ctxt("trans_lit"); match lit.node { - ast::lit_int(i, t) => C_integral(T_int_ty(cx, t), i as u64, True), - ast::lit_uint(u, t) => C_integral(T_uint_ty(cx, t), u, False), + ast::lit_int(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true), + ast::lit_uint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false), ast::lit_int_unsuffixed(i) => { let lit_int_ty = ty::node_id_to_type(cx.tcx, e.id); match ty::get(lit_int_ty).sty { ty::ty_int(t) => { - C_integral(T_int_ty(cx, t), i as u64, True) + C_integral(Type::int_from_ty(cx, t), i as u64, true) } ty::ty_uint(t) => { - C_integral(T_uint_ty(cx, t), i as u64, False) + C_integral(Type::uint_from_ty(cx, t), i as u64, false) } _ => cx.sess.span_bug(lit.span, fmt!("integer literal has type %s (expected int or uint)", ty_to_str(cx.tcx, lit_int_ty))) } } - ast::lit_float(fs, t) => C_floating(fs, T_float_ty(cx, t)), + ast::lit_float(fs, t) => C_floating(fs, Type::float_from_ty(cx, t)), ast::lit_float_unsuffixed(fs) => { let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id); match ty::get(lit_float_ty).sty { ty::ty_float(t) => { - C_floating(fs, T_float_ty(cx, t)) + C_floating(fs, Type::float_from_ty(cx, t)) } _ => { cx.sess.span_bug(lit.span, @@ -73,16 +75,16 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) } } -pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: TypeRef) -> ValueRef { +pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef { unsafe { - let b = llvm::LLVMConstPointerCast(a, T_ptr(t)); + let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref()); assert!(cx.const_globals.insert(b as int, a)); b } } pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) - -> (ValueRef, ValueRef, TypeRef) { + -> (ValueRef, ValueRef, Type) { unsafe { let vec_ty = ty::expr_ty(cx.tcx, e); let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty); @@ -102,8 +104,8 @@ pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) fn const_addr_of(cx: @mut CrateContext, cv: ValueRef) -> ValueRef { unsafe { - let gv = do str::as_c_str("const") |name| { - llvm::LLVMAddGlobal(cx.llmod, val_ty(cv), name) + let gv = do "const".as_c_str |name| { + llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name) }; llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetGlobalConstant(gv, True); @@ -180,7 +182,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { match adjustment { None => { } Some(@ty::AutoAddEnv(ty::re_static, ast::BorrowedSigil)) => { - llconst = C_struct([llconst, C_null(T_opaque_box_ptr(cx))]) + llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())]) } Some(@ty::AutoAddEnv(ref r, ref s)) => { cx.sess.span_bug(e.span, fmt!("unexpected static function: \ @@ -349,9 +351,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { ty::ty_bool => { // Somewhat questionable, but I believe this is // correct. - let te = llvm::LLVMConstTrunc(te, T_i1()); + let te = llvm::LLVMConstTrunc(te, Type::i1().to_ref()); let te = llvm::LLVMConstNot(te); - llvm::LLVMConstZExt(te, T_bool()) + llvm::LLVMConstZExt(te, Type::bool().to_ref()) } _ => llvm::LLVMConstNot(te), } @@ -426,21 +428,21 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { (expr::cast_integral, expr::cast_integral) => { let s = ty::type_is_signed(basety) as Bool; - llvm::LLVMConstIntCast(v, llty, s) + llvm::LLVMConstIntCast(v, llty.to_ref(), s) } (expr::cast_integral, expr::cast_float) => { if ty::type_is_signed(basety) { - llvm::LLVMConstSIToFP(v, llty) + llvm::LLVMConstSIToFP(v, llty.to_ref()) } else { - llvm::LLVMConstUIToFP(v, llty) + llvm::LLVMConstUIToFP(v, llty.to_ref()) } } (expr::cast_float, expr::cast_float) => { - llvm::LLVMConstFPCast(v, llty) + llvm::LLVMConstFPCast(v, llty.to_ref()) } (expr::cast_float, expr::cast_integral) => { - if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) } - else { llvm::LLVMConstFPToUI(v, llty) } + if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) } + else { llvm::LLVMConstFPToUI(v, llty.to_ref()) } } (expr::cast_enum, expr::cast_integral) | (expr::cast_enum, expr::cast_float) => { @@ -451,18 +453,18 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { match ety_cast { expr::cast_integral => { let s = ty::type_is_signed(ety) as Bool; - llvm::LLVMConstIntCast(iv, llty, s) + llvm::LLVMConstIntCast(iv, llty.to_ref(), s) } - expr::cast_float => llvm::LLVMConstUIToFP(iv, llty), + expr::cast_float => llvm::LLVMConstUIToFP(iv, llty.to_ref()), _ => cx.sess.bug("enum cast destination is not \ integral or float") } } (expr::cast_pointer, expr::cast_pointer) => { - llvm::LLVMConstPointerCast(v, llty) + llvm::LLVMConstPointerCast(v, llty.to_ref()) } (expr::cast_integral, expr::cast_pointer) => { - llvm::LLVMConstIntToPtr(v, llty) + llvm::LLVMConstIntToPtr(v, llty.to_ref()) } _ => { cx.sess.impossible_case(e.span, @@ -513,7 +515,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { let (cv, sz, llunitty) = const_vec(cx, e, *es); let llty = val_ty(cv); let gv = do str::as_c_str("const") |name| { - llvm::LLVMAddGlobal(cx.llmod, llty, name) + llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name) }; llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetGlobalConstant(gv, True); diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index bf9d3932298d..a709600cb9dc 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -12,7 +12,7 @@ use core::prelude::*; use back::{upcall}; use driver::session; -use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef}; +use lib::llvm::{ContextRef, ModuleRef, ValueRef}; use lib::llvm::{llvm, TargetData, TypeNames}; use lib::llvm::{mk_target_data}; use lib; @@ -36,8 +36,8 @@ use core::local_data; use extra::time; use syntax::ast; -use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen,addrspace_gen}; -use middle::trans::common::{mono_id,new_namegen,new_addrspace_gen}; +use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen}; +use middle::trans::common::{mono_id,new_namegen}; use middle::trans::base::{decl_crate_map}; @@ -94,11 +94,10 @@ pub struct CrateContext { impl_method_cache: HashMap<(ast::def_id, ast::ident), ast::def_id>, module_data: HashMap<~str, ValueRef>, - lltypes: HashMap, - llsizingtypes: HashMap, + lltypes: HashMap, + llsizingtypes: HashMap, adt_reprs: HashMap, names: namegen, - next_addrspace: addrspace_gen, symbol_hasher: hash::State, type_hashcodes: HashMap, type_short_names: HashMap, @@ -151,8 +150,8 @@ impl CrateContext { let tydesc_type = Type::tydesc(targ_cfg.arch); let opaque_vec_type = Type::opaque_vec(targ_cfg.arch); - let str_slice_ty = Type::named_struct("str_slice"); - str_slice_ty.set_struct_body([Type::i8p(), int_type]); + let mut str_slice_ty = Type::named_struct("str_slice"); + str_slice_ty.set_struct_body([Type::i8p(), int_type], false); tn.associate_type("tydesc", &tydesc_type); tn.associate_type("str_slice", &str_slice_ty); @@ -197,7 +196,6 @@ impl CrateContext { llsizingtypes: HashMap::new(), adt_reprs: HashMap::new(), names: new_namegen(), - next_addrspace: new_addrspace_gen(), symbol_hasher: symbol_hasher, type_hashcodes: HashMap::new(), type_short_names: HashMap::new(), diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 17009afda491..a9892b34ccd7 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -24,6 +24,8 @@ use middle::ty; use util::common::indenter; use util::ppaux; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast; @@ -204,7 +206,7 @@ pub fn trans_log(log_ex: @ast::expr, let global; unsafe { global = str::as_c_str(s, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) }); llvm::LLVMSetGlobalConstant(global, False); llvm::LLVMSetInitializer(global, C_null(Type::i32())); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 92cbf2c09570..c0a3b76aca4b 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -152,6 +152,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::cast::transmute; use core::hashmap::HashMap; use core::vec; @@ -981,9 +983,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let symbol = csearch::get_symbol( bcx.ccx().sess.cstore, did); - let llval = llvm::LLVMAddGlobal( - bcx.ccx().llmod, - llty, + let llval = llvm::LLVMAddGlobal( bcx.ccx().llmod, llty.to_ref(), transmute::<&u8,*i8>(&symbol[0])); let extern_const_values = &mut bcx.ccx().extern_const_values; extern_const_values.insert(did, llval); @@ -1552,8 +1552,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef, signed: bool) -> ValueRef { let _icx = bcx.insn_ctxt("int_cast"); unsafe { - let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype); - let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype); + let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref()); + let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref()); return if dstsz == srcsz { BitCast(bcx, llsrc, lldsttype) } else if srcsz > dstsz { @@ -1569,8 +1569,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef) -> ValueRef { let _icx = bcx.insn_ctxt("float_cast"); - let srcsz = lib::llvm::float_width(llsrctype); - let dstsz = lib::llvm::float_width(lldsttype); + let srcsz = llsrctype.float_width(); + let dstsz = lldsttype.float_width(); return if dstsz > srcsz { FPExt(bcx, llsrc, lldsttype) } else if srcsz > dstsz { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 50d4709735ca..5cad76e471ef 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -44,6 +44,7 @@ use syntax::parse::token; use syntax::abi::{X86, X86_64, Arm, Mips}; use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, Cdecl, Aapcs, C}; +use middle::trans::type_::Type; fn abi_info(ccx: @mut CrateContext) -> @cabi::ABIInfo { return match ccx.sess.targ_cfg.arch { @@ -122,7 +123,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { llsig: llsig, ret_def: ret_def, bundle_ty: bundle_ty, - shim_fn_ty: Type::func([bundle_ty.ptr_to()], Type::void()), + shim_fn_ty: Type::func([bundle_ty.ptr_to()], &Type::void()), fn_ty: fn_ty } } @@ -220,12 +221,9 @@ fn build_wrap_fn_(ccx: @mut CrateContext, let return_context = raw_block(fcx, false, fcx.llreturn); let llfunctiontype = val_ty(llwrapfn); - let llfunctiontype = - ::lib::llvm::llvm::LLVMGetElementType(llfunctiontype); - let llfunctionreturntype = - ::lib::llvm::llvm::LLVMGetReturnType(llfunctiontype); - if ::lib::llvm::llvm::LLVMGetTypeKind(llfunctionreturntype) == - ::lib::llvm::Void { + let llfunctiontype = llfunctiontype.element_type(); + let return_type = llfunctiontype.return_type(); + if return_type.kind() == ::lib::llvm::Void { // XXX: This might be wrong if there are any functions for which // the C ABI specifies a void output pointer and the Rust ABI // does not. @@ -233,9 +231,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, } else { // Cast if we have to... // XXX: This is ugly. - let llretptr = BitCast(return_context, - fcx.llretptr.get(), - llfunctionreturntype.ptr_to()); + let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to()); Ret(return_context, Load(return_context, llretptr)); } } @@ -636,6 +632,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } } + build_return(bcx); + finish_fn(fcx, lltop); + return; } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 7396508fb8dd..294d56dcd766 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -18,7 +18,7 @@ use back::abi; use back::link::*; use driver::session; use lib; -use lib::llvm::{llvm, ValueRef, Type, True}; +use lib::llvm::{llvm, ValueRef, True}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::callee; @@ -29,12 +29,14 @@ use middle::trans::expr; use middle::trans::machine::*; use middle::trans::reflect; use middle::trans::tvec; -use middle::trans::type_of::{type_of, type_of_glue_fn}; +use middle::trans::type_of::type_of; use middle::trans::uniq; use middle::ty; use util::ppaux; use util::ppaux::ty_to_short_str; +use middle::trans::type_::Type; + use core::io; use core::libc::c_uint; use core::str; @@ -76,16 +78,6 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { return cx; } -pub fn drop_ty_root(bcx: block, v: ValueRef, rooted: bool, t: ty::t) -> block { - if rooted { - // NB: v is a raw ptr to an addrspace'd ptr to the value. - let v = PointerCast(bcx, Load(bcx, v), type_of(bcx.ccx(), t).ptr_to()); - drop_ty(bcx, v, t) - } else { - drop_ty(bcx, v, t) - } -} - pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { let _icx = bcx.insn_ctxt("drop_ty_immediate"); match ty::get(t).sty { @@ -436,8 +428,8 @@ pub fn trans_struct_drop(bcx: block, // The second argument is the "self" argument for drop let params = unsafe { - lib::llvm::fn_ty_param_tys( - llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr))) + let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr)); + ty.element_type().func_params() }; // Class dtors have no explicit args, so the params should @@ -617,20 +609,6 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { } -// Chooses the addrspace for newly declared types. -pub fn declare_tydesc_addrspace(ccx: &CrateContext, t: ty::t) -> addrspace { - if !ty::type_needs_drop(ccx.tcx, t) { - return default_addrspace; - } else if ty::type_is_immediate(t) { - // For immediate types, we don't actually need an addrspace, because - // e.g. boxed types include pointers to their contents which are - // already correctly tagged with addrspaces. - return default_addrspace; - } else { - return (ccx.next_addrspace)(); - } -} - // Generates the declaration for (but doesn't emit) a type descriptor. pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { // If emit_tydescs already ran, then we shouldn't be creating any new @@ -640,20 +618,18 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { let llty = type_of(ccx, t); if ccx.sess.count_type_sizes() { - io::println(fmt!("%u\t%s", - llsize_of_real(ccx, llty), + io::println(fmt!("%u\t%s", llsize_of_real(ccx, llty), ppaux::ty_to_str(ccx.tcx, t))); } let llsize = llsize_of(ccx, llty); let llalign = llalign_of(ccx, llty); - let addrspace = declare_tydesc_addrspace(ccx, t); let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed(); note_unique_llvm_symbol(ccx, name); debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name); let gvar = str::as_c_str(name, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf) } }); let inf = @mut tydesc_info { @@ -661,7 +637,6 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { tydesc: gvar, size: llsize, align: llalign, - addrspace: addrspace, take_glue: None, drop_glue: None, free_glue: None, @@ -706,7 +681,11 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, let llty = type_of(ccx, t); let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to()); helper(bcx, llrawptr0, t); - finish_fn(fcx, lltop); + + // This is from the general finish fn, but that emits a ret {} that we don't want + Br(raw_block(fcx, false, fcx.llstaticallocas), lltop); + RetVoid(raw_block(fcx, false, fcx.llreturn)); + return llfn; } @@ -732,7 +711,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { //let _icx = ccx.insn_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - let glue_fn_ty = T_generic_glue_fn(ccx).ptr_to(); + let glue_fn_ty = Type::generic_glue_fn(ccx); let tyds = &mut ccx.tydescs; for tyds.each_value |&val| { let ti = val; @@ -747,7 +726,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -757,7 +736,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -767,7 +746,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -777,16 +756,16 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; + let shape = C_null(Type::i8p()); let shape_tables = C_null(Type::i8p()); - let tydesc = - C_named_struct(ccx.tydesc_type, + let tydesc = C_named_struct(ccx.tydesc_type, [ti.size, // size ti.align, // align take_glue, // take_glue @@ -802,18 +781,11 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { llvm::LLVMSetGlobalConstant(gvar, True); lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage); - // Index tydesc by addrspace. - if ti.addrspace > gc_box_addrspace { - let llty = ccx.tydesc_type.ptr_to(); - let addrspace_name = fmt!("_gc_addrspace_metadata_%u", - ti.addrspace as uint); - let addrspace_gvar = str::as_c_str(addrspace_name, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, llty, buf) - }); - lib::llvm::SetLinkage(addrspace_gvar, - lib::llvm::InternalLinkage); - llvm::LLVMSetInitializer(addrspace_gvar, gvar); - } } }; } + +fn type_of_glue_fn(ccx: &CrateContext) -> Type { + let tydescpp = ccx.tydesc_type.ptr_to().ptr_to(); + Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void()) +} diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index eb7240419ed6..495d3bcae16e 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -18,6 +18,8 @@ use middle::trans::type_of; use middle::ty; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + // ______________________________________________________________________ // compute sizeof / alignof @@ -140,7 +142,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { debug!("static_size_of_enum: variant %s type %s", cx.tcx.sess.str_of(variant.name), - cx.tn.type_to_str(T_struct(lltypes, false))); + 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 { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index ce240dc2484e..055e1ebbd371 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -30,6 +30,8 @@ use middle::typeck; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast_map::{path, path_mod, path_name}; @@ -463,7 +465,7 @@ pub fn trans_monomorphized_callee(bcx: block, // create a llvalue that represents the fn ptr let fn_ty = node_id_type(bcx, callee_id); - let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).to_ptr(); + let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).ptr_to(); let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty); // combine the self environment with the rest @@ -778,7 +780,7 @@ pub fn make_vtable(ccx: @mut CrateContext, let tbl = C_struct(components); let vtable = ccx.sess.str_of((ccx.names)("vtable")); let vt_gvar = do str::as_c_str(vtable) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf) + llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf) }; llvm::LLVMSetInitializer(vt_gvar, tbl); llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index ebf2d888148a..cb68a2af92bb 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -9,7 +9,7 @@ // except according to those terms. use back::link::mangle_internal_name_by_path_and_seq; -use lib::llvm::{Type, ValueRef, llvm}; +use lib::llvm::{ValueRef, llvm}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::build::*; @@ -33,6 +33,8 @@ use syntax::ast; use syntax::ast_map::path_name; use syntax::parse::token::special_idents; +use middle::trans::type_::Type; + pub struct Reflector { visitor_val: ValueRef, visitor_methods: @~[@ty::Method], diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index f3554b348061..82db5d405da6 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -17,6 +17,8 @@ use lib::llvm::{True, ModuleRef, ValueRef}; use middle::trans::common::*; use middle::trans; +use middle::trans::type_::Type; + use core::str; pub struct Ctxt { @@ -32,7 +34,7 @@ pub fn mk_global(ccx: &CrateContext, -> ValueRef { unsafe { let llglobal = do str::as_c_str(name) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf) + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) }; llvm::LLVMSetInitializer(llglobal, llval); llvm::LLVMSetGlobalConstant(llglobal, True); @@ -50,7 +52,7 @@ pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { unsafe { let llshapetablesty = Type::named_struct("shapes"); do "shapes".as_c_str |buf| { - llvm::LLVMAddGlobal(llmod, llshapetablesty, buf) + llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf) }; Ctxt { diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 009338650122..014c46b06e4a 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -27,6 +27,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + use core::option::None; use syntax::ast; use syntax::codemap; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 851ff4511a03..14c4ac71d97e 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -11,6 +11,7 @@ use core::prelude::*; use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; +use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use middle::ty; @@ -26,6 +27,7 @@ use core::cast; use core::libc::{c_uint}; +#[deriving(Eq)] pub struct Type { priv rf: TypeRef } @@ -38,12 +40,14 @@ macro_rules! ty ( * Wrapper for LLVM TypeRef */ impl Type { + #[inline(always)] pub fn from_ref(r: TypeRef) -> Type { Type { rf: r } } + #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler pub fn to_ref(&self) -> TypeRef { self.rf } @@ -136,7 +140,7 @@ impl Type { pub fn float_from_ty(ctx: &CrateContext, t: ast::float_ty) -> Type { match t { - ast::ty_f => ctx.float_ty, + ast::ty_f => ctx.float_type, ast::ty_f32 => Type::f32(), ast::ty_f64 => Type::f64() } @@ -147,7 +151,7 @@ impl Type { } pub fn func(args: &[Type], ret: &Type) -> Type { - let vec : &[TypeRef] = unsafe { cast::transmute() }; + let vec : &[TypeRef] = unsafe { cast::transmute(args) }; ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec), args.len() as c_uint, False)) } @@ -157,12 +161,13 @@ impl Type { } pub fn ptr(ty: Type) -> Type { - ty!(llvm::LLVMPointerType(ty, 0 as c_uint)) + ty!(llvm::LLVMPointerType(ty.to_ref(), 0 as c_uint)) } pub fn struct_(els: &[Type], packed: bool) -> Type { let els : &[TypeRef] = unsafe { cast::transmute(els) }; - ty!(llvm::LLVMStructType(vec::raw::to_ptr(els), els.len() as c_uint, packed as Bool)) + ty!(llvm::LLVMStructTypeInContext(base::task_llcx(), vec::raw::to_ptr(els), + els.len() as c_uint, packed as Bool)) } pub fn named_struct(name: &str) -> Type { @@ -175,7 +180,7 @@ impl Type { } pub fn vtable() -> Type { - Type::array(Type::i8().ptr_to(), 1) + Type::array(&Type::i8().ptr_to(), 1) } pub fn generic_glue_fn(cx: &mut CrateContext) -> Type { @@ -185,7 +190,7 @@ impl Type { } let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); - cx.tn.associate_type("glue_fn", ty); + cx.tn.associate_type("glue_fn", &ty); return ty; } @@ -193,10 +198,9 @@ impl Type { pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); let tydescpp = tydesc.ptr_to().ptr_to(); - let pvoid = Type::i8().ptr_to(); - let glue_fn_ty = Type::func( - [ Type::nil.ptr_to(), tydescpp, pvoid ], - Type::void()).ptr_to(); + let pvoid = Type::i8p(); + let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ], + &Type::void()).ptr_to(); let int_ty = Type::int(arch); @@ -226,7 +230,7 @@ impl Type { } pub fn opaque_vec(arch: Architecture) -> Type { - Type::vec(arch, Type::i8()) + Type::vec(arch, &Type::i8()) } #[inline] @@ -242,11 +246,11 @@ 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 { - Type::box(ctx, Type::i8()) + Type::box(ctx, &Type::i8()) } pub fn unique(ctx: &CrateContext, ty: &Type) -> Type { @@ -254,7 +258,7 @@ impl Type { } pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type { - Type::opaque_box().ptr_to() + Type::opaque_box(cx).ptr_to() } pub fn enum_discrim(cx: &CrateContext) -> Type { @@ -275,7 +279,7 @@ impl Type { } ty::UniqTraitStore => { Type::struct_( - [ tydesc_ptr, Type::unique(ctx, Type::i8()).ptr_to()], + [ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()], false) } ty::RegionTraitStore(*) => { @@ -301,7 +305,7 @@ impl Type { } pub fn ptr_to(&self) -> Type { - ty!(llvm::LLVMPointerType(self.to_ref())) + ty!(llvm::LLVMPointerType(self.to_ref(), 0)) } pub fn get_field(&self, idx: uint) -> Type { @@ -335,14 +339,38 @@ impl Type { pub fn field_types(&self) -> ~[Type] { unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; + let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint; if n_elts == 0 { return ~[]; } let mut elts = vec::from_elem(n_elts, 0 as TypeRef); - llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); + llvm::LLVMGetStructElementTypes(self.to_ref(), &mut elts[0]); cast::transmute(elts) } } + pub fn return_type(&self) -> Type { + unsafe { + ty!(llvm::LLVMGetReturnType(self.to_ref())) + } + } + + pub fn func_params(&self) -> ~[Type] { + unsafe { + let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint; + let args = vec::from_elem(n_args, 0 as TypeRef); + llvm::LLVMGetParamTypes(self.to_ref(), vec::raw::to_ptr(args)); + cast::transmute(args) + } + } + + pub fn float_width(&self) -> uint { + match self.kind() { + Float => 32, + Double => 64, + X86_FP80 => 80, + FP128 | PPC_FP128 => 128, + _ => fail!("llvm_float_width called on a non-float type") + } + } } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 9ace4991f1ba..0f4ffb04b281 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -18,6 +18,8 @@ use middle::trans::common; use middle::ty; use util::ppaux; +use middle::trans::type_::Type; + use syntax::ast; pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool { @@ -58,10 +60,15 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) atys.push_all(type_of_explicit_args(cx, inputs)); // Use the output as the actual return value if it's immediate. +<<<<<<< HEAD if output_is_immediate && !ty::type_is_nil(output) { Type::func(atys, lloutputtype) +======= + if output_is_immediate { + Type::func(atys, &lloutputtype) +>>>>>>> Finish up Type refactoring } else { - Type::func(atys, Type::void()) + Type::func(atys, &Type::void()) } } } @@ -87,11 +94,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { match ty::get(t).sty { ty::ty_box(mt) => { let ty = type_of(cx, mt.ty); - Type::box(cx, ty).ptr_to() + Type::box(cx, &ty).ptr_to() } ty::ty_uniq(mt) => { let ty = type_of(cx, mt.ty); - Type::unique(cx, ty).ptr_to() + Type::unique(cx, &ty).ptr_to() } _ => { cx.sess.bug("non-box in type_of_non_gc_box"); @@ -146,14 +153,14 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { ty::ty_closure(*) => Type::struct_([Type::i8p(), Type::i8p()], false), ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), - ty::ty_estr(ty::vstore_fixed(size)) => Type::array(Type::i8(), size), + ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), ty::ty_evec(mt, ty::vstore_fixed(size)) => { - Type::array(sizing_type_of(cx, mt.ty), size) + Type::array(&sizing_type_of(cx, mt.ty), size as u64) } ty::ty_unboxed_vec(mt) => { let sz_ty = sizing_type_of(cx, mt.ty); - Type::vec(cx.sess.targ_cfg.arch, sz_ty) + Type::vec(cx.sess.targ_cfg.arch, &sz_ty) } ty::ty_tup(*) | ty::ty_enum(*) => { @@ -165,7 +172,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { if ty::type_is_simd(cx.tcx, t) { let et = ty::simd_type(cx.tcx, t); let n = ty::simd_size(cx.tcx, t); - Type::vector(type_of(cx, et), n) + Type::vector(&type_of(cx, et), n as u64) } else { let repr = adt::represent_type(cx, t); let packed = ty::lookup_packed(cx.tcx, did); @@ -205,14 +212,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { return llty; } - let llty = match ty::get(t).sty { + let mut llty = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => Type::nil(), ty::ty_bool => Type::bool(), ty::ty_int(t) => Type::int_from_ty(cx, t), ty::ty_uint(t) => Type::uint_from_ty(cx, t), ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_estr(ty::vstore_uniq) => { - Type::unique(cx, Type::vec(cx.sess.targ_cfg.arch, Type::i8())).ptr_to() + Type::unique(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() } ty::ty_enum(did, ref substs) => { // Only create the named struct, but don't fill it in. We @@ -223,30 +230,30 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps)) } ty::ty_estr(ty::vstore_box) => { - Type::box(cx, Type::vec(cx, Type::i8())).ptr_to() + Type::box(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() } ty::ty_evec(ref mt, ty::vstore_box) => { let e_ty = type_of(cx, mt.ty); - let v_ty = Type::vec(cx.sess.targ_cfg.arch, e_ty); - Type::box(cx, v_ty).ptr_to() + let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty); + Type::box(cx, &v_ty).ptr_to() } ty::ty_box(ref mt) => { let ty = type_of(cx, mt.ty); - Type::box(cx, ty).ptr_to() + Type::box(cx, &ty).ptr_to() } 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() + Type::unique(cx, &ty).ptr_to() } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); - let ty = Type::vec(cx, ty); - Type::unique(cx, ty).ptr_to() + let ty = Type::vec(cx.sess.targ_cfg.arch, &ty); + Type::unique(cx, &ty).ptr_to() } ty::ty_unboxed_vec(ref mt) => { let ty = type_of(cx, mt.ty); - Type::vec(cx.sess.targ_cfg.arch, ty) + Type::vec(cx.sess.targ_cfg.arch, &ty) } ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(), ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(), @@ -263,20 +270,20 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { } ty::ty_estr(ty::vstore_fixed(n)) => { - Type::array(Type::i8(), n + 1u /* +1 for trailing null */) + Type::array(&Type::i8(), (n + 1u) as u64) } ty::ty_evec(ref mt, ty::vstore_fixed(n)) => { - Type::array(type_of(cx, mt.ty), n) + Type::array(&type_of(cx, mt.ty), n as u64) } ty::ty_bare_fn(_) => type_of_fn_from_ty(cx, t).ptr_to(), ty::ty_closure(_) => { let ty = type_of_fn_from_ty(cx, t); - Type::func_pair(cx, ty) + Type::func_pair(cx, &ty) } ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), - ty::ty_type => cx.tydesc_type.to_ptr(), + ty::ty_type => cx.tydesc_type.ptr_to(), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); Type::struct_(adt::fields_of(cx, repr), false) @@ -286,7 +293,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { if ty::type_is_simd(cx.tcx, t) { let et = ty::simd_type(cx.tcx, t); let n = ty::simd_size(cx.tcx, t); - Type::vector(type_of(cx, et), n) + Type::vector(&type_of(cx, et), n as u64) } else { // Only create the named struct, but don't fill it in. We fill it // in *after* placing it into the type cache. This prevents @@ -306,16 +313,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { match ty::get(t).sty { ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - common::set_struct_body(llty, adt::fields_of(cx, repr), - false); + llty.set_struct_body(adt::fields_of(cx, repr), false); } ty::ty_struct(did, _) => { if !ty::type_is_simd(cx.tcx, t) { let repr = adt::represent_type(cx, t); let packed = ty::lookup_packed(cx.tcx, did); - common::set_struct_body(llty, adt::fields_of(cx, repr), - packed); + llty.set_struct_body(adt::fields_of(cx, repr), packed); } } _ => () @@ -345,19 +350,5 @@ pub fn llvm_type_name(cx: &CrateContext, pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> Type { let self_ty = type_of(ccx, self_ty).ptr_to(); - Type::func([self_ty], Type::viod()) + Type::func([self_ty], Type::void()) } - -/* -pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> Type { - let addrspace = base::get_tydesc(ccx, t).addrspace; - debug!("type_of_rooted %s in addrspace %u", - ppaux::ty_to_str(ccx.tcx, t), addrspace as uint); - return T_root(type_of(ccx, t), addrspace); -} - -pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { - let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); - return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void()); -} -*/ diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 6b2c6801e589..eb5376da6969 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -28,6 +28,8 @@ use middle::ty; use syntax::codemap::span; use syntax::ast; +use middle::trans::type_::Type; + pub fn root_and_write_guard(datum: &Datum, mut bcx: block, span: span, diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index e1daf6c81b2a..c38b013a75aa 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -175,15 +175,15 @@ pub extern "rust-intrinsic" { pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin(dst: &mut int, src: int) -> int; + pub fn atomic_umax(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + pub fn atomic_umax_acq(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + pub fn atomic_umax_rel(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; + pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. /// From 0b0c756c9cbef3a0d42de4cee0ada34638ba7b04 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 16 Jun 2013 23:11:17 +1200 Subject: [PATCH 049/336] Fix warnings in trans --- src/librustc/lib/llvm.rs | 2 - src/librustc/middle/trans/base.rs | 11 +- src/librustc/middle/trans/build.rs | 18 +- src/librustc/middle/trans/cabi_arm.rs | 15 +- src/librustc/middle/trans/cabi_mips.rs | 19 +-- src/librustc/middle/trans/cabi_x86.rs | 3 +- src/librustc/middle/trans/cabi_x86_64.rs | 209 +++++++++++------------ src/librustc/middle/trans/common.rs | 9 +- src/librustc/middle/trans/consts.rs | 3 +- src/librustc/middle/trans/context.rs | 1 - src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/trans/foreign.rs | 30 ++-- src/librustc/middle/trans/machine.rs | 2 +- src/librustc/middle/trans/shape.rs | 14 -- src/librustc/middle/trans/type_.rs | 4 +- src/librustc/middle/trans/type_of.rs | 47 ++--- 16 files changed, 164 insertions(+), 225 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index ec3bf61608c3..4bc96117ff51 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -13,9 +13,7 @@ use core::prelude::*; use core::hashmap::HashMap; use core::libc::{c_uint, c_ushort}; use core::option; -use core::ptr; use core::str; -use core::vec; use middle::trans::type_::Type; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 8ec05f447ee3..b94442c85ef7 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -30,7 +30,7 @@ use back::{link, abi}; use driver::session; use driver::session::Session; use lib::llvm::{ContextRef, ModuleRef, ValueRef, BasicBlockRef}; -use lib::llvm::{llvm, True, False}; +use lib::llvm::{llvm, True}; use lib; use metadata::common::LinkMeta; use metadata::{csearch, cstore, encoder}; @@ -1462,7 +1462,7 @@ pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) { // allocation for large data structures, and the generated code will be // awful. (A telltale sign of this is large quantities of // `mov [byte ptr foo],0` in the generated code.) -pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { +pub fn memzero(cx: block, llptr: ValueRef, ty: Type) { let _icx = cx.insn_ctxt("memzero"); let ccx = cx.ccx(); @@ -1493,7 +1493,7 @@ pub fn alloca(cx: block, ty: Type) -> ValueRef { alloca_maybe_zeroed(cx, ty, false) } -pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { +pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef { let _icx = cx.insn_ctxt("alloca"); if cx.unreachable { unsafe { @@ -1506,7 +1506,7 @@ pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { p } -pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { +pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("arrayalloca"); if cx.unreachable { unsafe { @@ -2885,8 +2885,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { // Writes the current ABI version into the crate. pub fn write_abi_version(ccx: &mut CrateContext) { - mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), - false); + mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); } pub fn trans_crate(sess: session::Session, diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 3e5a23cb18eb..f1ccfba5b30d 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -22,8 +22,8 @@ use syntax::codemap::span; use middle::trans::type_::Type; use core::cast; -use core::hashmap::HashMap; use core::libc::{c_uint, c_ulonglong, c_char}; +use core::hashmap::HashMap; use core::str; use core::vec; @@ -619,15 +619,12 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { return InBoundsGEP(cx, base, v); } -pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> - ValueRef { +pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "inboundsgep"); - return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, - vec::raw::to_ptr(Indices), - Indices.len() as c_uint, - noname()); + return llvm::LLVMBuildInBoundsGEP( + B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); } } @@ -1077,8 +1074,7 @@ pub fn Trap(cx: block) { assert!((T as int != 0)); let Args: ~[ValueRef] = ~[]; count_insn(cx, "trap"); - llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), - Args.len() as c_uint, noname()); + llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), Args.len() as c_uint, noname()); } } @@ -1088,8 +1084,8 @@ pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef, check_not_terminated(cx); assert!(!cx.unreachable); count_insn(cx, "landingpad"); - return llvm::LLVMBuildLandingPad(B(cx), Ty.to_ref(), PersFn, - NumClauses as c_uint, noname()); + return llvm::LLVMBuildLandingPad( + B(cx), Ty.to_ref(), PersFn, NumClauses as c_uint, noname()); } } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 69896972ef06..2f4579afe9c1 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -10,7 +10,6 @@ use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::{Attribute, StructRetAttribute}; -use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; use middle::trans::type_::Type; @@ -116,14 +115,12 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option) { } fn is_reg_ty(ty: Type) -> bool { - unsafe { - match ty.kind() { - Integer - | Pointer - | Float - | Double => true, - _ => false - } + match ty.kind() { + Integer + | Pointer + | Float + | Double => true, + _ => false } } diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 27ac267895b3..ab5296b0c7a0 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -11,14 +11,11 @@ use core::prelude::*; use core::libc::c_uint; -use core::ptr; use core::uint; use core::vec; use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::{Attribute, StructRetAttribute}; -use lib::llvm::True; use middle::trans::context::task_llcx; -use middle::trans::common::*; use middle::trans::cabi::*; use middle::trans::type_::Type; @@ -122,15 +119,13 @@ fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option) } fn is_reg_ty(ty: Type) -> bool { - unsafe { - return match ty.kind() { - Integer - | Pointer - | Float - | Double => true, - _ => false - }; - } + return match ty.kind() { + Integer + | Pointer + | Float + | Double => true, + _ => false + }; } fn padding_ty(align: uint, offset: uint) -> Option { diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index bdfe0e3d77da..e2f4cef5a111 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -12,7 +12,6 @@ use core::prelude::*; use driver::session::{os_win32, os_macos}; use lib::llvm::*; -use lib::llvm::llvm::*; use super::cabi::*; use super::common::*; use super::machine::*; @@ -43,7 +42,7 @@ impl ABIInfo for X86_ABIInfo { // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let sret = { - let returning_a_struct = unsafe { rty.kind() == Struct && ret_def }; + let returning_a_struct = rty.kind() == Struct && ret_def; let big_struct = match self.ccx.sess.targ_cfg.os { os_win32 | os_macos => llsize_of_alloc(self.ccx, rty) > 8, _ => true diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 01ec4a90cb08..4a92b940190a 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -14,13 +14,10 @@ use lib::llvm::{llvm, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute, ByValAttribute}; -use lib::llvm::True; -use middle::trans::common::*; use middle::trans::cabi::*; use middle::trans::type_::Type; -use core::libc::c_uint; use core::option; use core::option::Option; use core::uint; @@ -189,98 +186,94 @@ fn classify_ty(ty: Type) -> ~[RegClass] { fn classify(ty: Type, cls: &mut [RegClass], ix: uint, off: uint) { - unsafe { - let t_align = ty_align(ty); - let t_size = ty_size(ty); + let t_align = ty_align(ty); + let t_size = ty_size(ty); - let misalign = off % t_align; - if misalign != 0u { - let mut i = off / 8u; - let e = (off + t_size + 7u) / 8u; - while i < e { - unify(cls, ix + i, Memory); + let misalign = off % t_align; + if misalign != 0u { + let mut i = off / 8u; + let e = (off + t_size + 7u) / 8u; + while i < e { + unify(cls, ix + i, Memory); + i += 1u; + } + return; + } + + match ty.kind() { + Integer | + Pointer => { + unify(cls, ix + off / 8u, Int); + } + Float => { + if off % 8u == 4u { + unify(cls, ix + off / 8u, SSEFv); + } else { + unify(cls, ix + off / 8u, SSEFs); + } + } + Double => { + unify(cls, ix + off / 8u, SSEDs); + } + Struct => { + classify_struct(ty.field_types(), cls, ix, off); + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + let mut i = 0u; + while i < len { + classify(elt, cls, ix, off + i * eltsz); i += 1u; } - return; - } - - match ty.kind() { - Integer | - Pointer => { - unify(cls, ix + off / 8u, Int); - } - Float => { - if off % 8u == 4u { - unify(cls, ix + off / 8u, SSEFv); - } else { - unify(cls, ix + off / 8u, SSEFs); - } - } - Double => { - unify(cls, ix + off / 8u, SSEDs); - } - Struct => { - classify_struct(ty.field_types(), cls, ix, off); - } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - let mut i = 0u; - while i < len { - classify(elt, cls, ix, off + i * eltsz); - i += 1u; - } - } - _ => fail!("classify: unhandled type") } + _ => fail!("classify: unhandled type") } } fn fixup(ty: Type, cls: &mut [RegClass]) { - unsafe { - let mut i = 0u; - let ty_kind = ty.kind(); - let e = cls.len(); - if cls.len() > 2u && - (ty_kind == Struct || - ty_kind == Array) { - if cls[i].is_sse() { - i += 1u; - while i < e { - if cls[i] != SSEUp { - all_mem(cls); - return; - } - i += 1u; + let mut i = 0u; + let ty_kind = ty.kind(); + let e = cls.len(); + if cls.len() > 2u && + (ty_kind == Struct || + ty_kind == Array) { + if cls[i].is_sse() { + i += 1u; + while i < e { + if cls[i] != SSEUp { + all_mem(cls); + return; } - } else { - all_mem(cls); - return + i += 1u; } } else { - while i < e { - if cls[i] == Memory { - all_mem(cls); - return; - } - if cls[i] == X87Up { - // for darwin - // cls[i] = SSEDs; - all_mem(cls); - return; - } - if cls[i] == SSEUp { - cls[i] = SSEInt; - } else if cls[i].is_sse() { - i += 1; - while i != e && cls[i] == SSEUp { i += 1u; } - } else if cls[i] == X87 { - i += 1; - while i != e && cls[i] == X87Up { i += 1u; } - } else { - i += 1; - } + all_mem(cls); + return + } + } else { + while i < e { + if cls[i] == Memory { + all_mem(cls); + return; + } + if cls[i] == X87Up { + // for darwin + // cls[i] = SSEDs; + all_mem(cls); + return; + } + if cls[i] == SSEUp { + cls[i] = SSEInt; + } else if cls[i].is_sse() { + i += 1; + while i != e && cls[i] == SSEUp { i += 1u; } + } else if cls[i] == X87 { + i += 1; + while i != e && cls[i] == X87Up { i += 1u; } + } else { + i += 1; } } } @@ -310,34 +303,32 @@ fn llreg_ty(cls: &[RegClass]) -> Type { return len; } - unsafe { - let mut tys = ~[]; - let mut i = 0u; - let e = cls.len(); - while i < e { - match cls[i] { - Int => { - tys.push(Type::i64()); - } - SSEFv => { - let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; - let vec_ty = Type::vector(&Type::f32(), vec_len as u64); - tys.push(vec_ty); - i += vec_len; - loop; - } - SSEFs => { - tys.push(Type::f32()); - } - SSEDs => { - tys.push(Type::f64()); - } - _ => fail!("llregtype: unhandled class") + let mut tys = ~[]; + let mut i = 0u; + let e = cls.len(); + while i < e { + match cls[i] { + Int => { + tys.push(Type::i64()); } - i += 1u; + SSEFv => { + let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; + let vec_ty = Type::vector(&Type::f32(), vec_len as u64); + tys.push(vec_ty); + i += vec_len; + loop; + } + SSEFs => { + tys.push(Type::f32()); + } + SSEDs => { + tys.push(Type::f64()); + } + _ => fail!("llregtype: unhandled class") } - return Type::struct_(tys, false); + i += 1u; } + return Type::struct_(tys, false); } fn x86_64_tys(atys: &[Type], diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 3f9f39ac852d..c8b5b00d6246 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -12,18 +12,16 @@ use core::prelude::*; -use back::{abi}; use driver::session; use driver::session::Session; -use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef}; +use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef}; use lib::llvm::{True, False, Bool}; -use lib::llvm::{llvm, TypeNames}; +use lib::llvm::{llvm}; use lib; use middle::trans::base; use middle::trans::build; use middle::trans::datum; use middle::trans::glue; -use middle::trans::type_of; use middle::trans::write_guard; use middle::ty::substs; use middle::ty; @@ -37,16 +35,13 @@ use core::cast::transmute; use core::cast; use core::hashmap::{HashMap}; use core::libc::{c_uint, c_longlong, c_ulonglong}; -use core::str; use core::to_bytes; -use core::vec::raw::to_ptr; use core::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; use syntax::codemap::span; use syntax::parse::token; use syntax::{ast, ast_map}; -use syntax::abi::{X86, X86_64, Arm, Mips}; pub use middle::trans::context::CrateContext; diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 456dc6edfb6b..b688ca66c2b3 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -11,8 +11,7 @@ use core::prelude::*; use back::abi; -use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, - True, False}; +use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True}; use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index a709600cb9dc..ee6ead72c1e0 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -15,7 +15,6 @@ use driver::session; use lib::llvm::{ContextRef, ModuleRef, ValueRef}; use lib::llvm::{llvm, TargetData, TypeNames}; use lib::llvm::{mk_target_data}; -use lib; use metadata::common::LinkMeta; use middle::astencode; use middle::resolve; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 269451b13070..43d434b9d33d 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -693,7 +693,7 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui } /// Set current debug location at the beginning of the span -pub fn update_source_pos(bcx: block, span: span) { +pub fn update_source_pos(bcx: @mut Block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 5cad76e471ef..913a857e0fb9 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -217,23 +217,21 @@ fn build_wrap_fn_(ccx: @mut CrateContext, tie_up_header_blocks(fcx, lltop); // Then return according to the C ABI. - unsafe { - let return_context = raw_block(fcx, false, fcx.llreturn); + let return_context = raw_block(fcx, false, fcx.llreturn); - let llfunctiontype = val_ty(llwrapfn); - let llfunctiontype = llfunctiontype.element_type(); - let return_type = llfunctiontype.return_type(); - if return_type.kind() == ::lib::llvm::Void { - // XXX: This might be wrong if there are any functions for which - // the C ABI specifies a void output pointer and the Rust ABI - // does not. - RetVoid(return_context); - } else { - // Cast if we have to... - // XXX: This is ugly. - let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to()); - Ret(return_context, Load(return_context, llretptr)); - } + let llfunctiontype = val_ty(llwrapfn); + let llfunctiontype = llfunctiontype.element_type(); + let return_type = llfunctiontype.return_type(); + if return_type.kind() == ::lib::llvm::Void { + // XXX: This might be wrong if there are any functions for which + // the C ABI specifies a void output pointer and the Rust ABI + // does not. + RetVoid(return_context); + } else { + // Cast if we have to... + // XXX: This is ugly. + let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to()); + Ret(return_context, Load(return_context, llretptr)); } } diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 495d3bcae16e..6fcab95996e8 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -10,7 +10,7 @@ // Information concerning the machine representation of various types. -use lib::llvm::{ValueRef, TypeRef}; +use lib::llvm::{ValueRef}; use lib::llvm::False; use lib::llvm::llvm; use middle::trans::common::*; diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index 82db5d405da6..4118291dca0d 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -15,7 +15,6 @@ use lib::llvm::llvm; use lib::llvm::{True, ModuleRef, ValueRef}; use middle::trans::common::*; -use middle::trans; use middle::trans::type_::Type; @@ -62,16 +61,3 @@ pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { } } } - -/* -Although these two functions are never called, they are here -for a VERY GOOD REASON. See #3670 -pub fn add_u16(dest: &mut ~[u8], val: u16) { - *dest += [(val & 0xffu16) as u8, (val >> 8u16) as u8]; -} - -pub fn add_substr(dest: &mut ~[u8], src: ~[u8]) { - add_u16(&mut *dest, src.len() as u16); - *dest += src; -} -*/ diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 14c4ac71d97e..34a150331091 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -350,9 +350,7 @@ impl Type { } pub fn return_type(&self) -> Type { - unsafe { - ty!(llvm::LLVMGetReturnType(self.to_ref())) - } + ty!(llvm::LLVMGetReturnType(self.to_ref())) } pub fn func_params(&self) -> ~[Type] { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 0f4ffb04b281..5b85209219cd 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -10,11 +10,8 @@ use core::prelude::*; -use lib::llvm::llvm; use middle::trans::adt; -use middle::trans::base; use middle::trans::common::*; -use middle::trans::common; use middle::ty; use util::ppaux; @@ -40,36 +37,28 @@ pub fn type_of_explicit_args(ccx: &mut CrateContext, inputs.map(|arg_ty| type_of_explicit_arg(ccx, arg_ty)) } -pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) - -> Type { - unsafe { - let mut atys: ~[Type] = ~[]; +pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Type { + let mut atys: ~[Type] = ~[]; - // Arg 0: Output pointer. - // (if the output type is non-immediate) - let output_is_immediate = ty::type_is_immediate(output); - let lloutputtype = type_of(cx, output); - if !output_is_immediate { - atys.push(lloutputtype.ptr_to()); - } + // Arg 0: Output pointer. + // (if the output type is non-immediate) + let output_is_immediate = ty::type_is_immediate(output); + let lloutputtype = type_of(cx, output); + if !output_is_immediate { + atys.push(lloutputtype.ptr_to()); + } - // Arg 1: Environment - atys.push(Type::opaque_box(cx).ptr_to()); + // Arg 1: Environment + atys.push(Type::opaque_box(cx).ptr_to()); - // ... then explicit args. - atys.push_all(type_of_explicit_args(cx, inputs)); + // ... then explicit args. + atys.push_all(type_of_explicit_args(cx, inputs)); - // Use the output as the actual return value if it's immediate. -<<<<<<< HEAD - if output_is_immediate && !ty::type_is_nil(output) { - Type::func(atys, lloutputtype) -======= - if output_is_immediate { - Type::func(atys, &lloutputtype) ->>>>>>> Finish up Type refactoring - } else { - Type::func(atys, &Type::void()) - } + // Use the output as the actual return value if it's immediate. + if output_is_immediate && !ty::type_is_nil(output) { + Type::func(atys, &lloutputtype) + } else { + Type::func(atys, &Type::void()) } } From 048ed1486f16191fbe72e32cc99f6f30a28a80e4 Mon Sep 17 00:00:00 2001 From: James Miller Date: Mon, 17 Jun 2013 16:23:24 +1200 Subject: [PATCH 050/336] Move count-llvm-insn code into task-local storage --- src/librustc/middle/trans/_match.rs | 16 +- src/librustc/middle/trans/base.rs | 178 +++++++++++----------- src/librustc/middle/trans/build.rs | 5 +- src/librustc/middle/trans/callee.rs | 14 +- src/librustc/middle/trans/closure.rs | 20 +-- src/librustc/middle/trans/common.rs | 1 - src/librustc/middle/trans/consts.rs | 8 +- src/librustc/middle/trans/context.rs | 7 +- src/librustc/middle/trans/controlflow.rs | 22 +-- src/librustc/middle/trans/datum.rs | 8 +- src/librustc/middle/trans/expr.rs | 46 +++--- src/librustc/middle/trans/foreign.rs | 32 ++-- src/librustc/middle/trans/glue.rs | 44 +++--- src/librustc/middle/trans/inline.rs | 5 +- src/librustc/middle/trans/meth.rs | 20 +-- src/librustc/middle/trans/monomorphize.rs | 4 +- src/librustc/middle/trans/tvec.rs | 22 +-- src/librustc/middle/trans/uniq.rs | 4 +- 18 files changed, 229 insertions(+), 227 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 72da71afed6e..958677eab4ae 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -259,7 +259,7 @@ pub enum opt_result { range_result(Result, Result), } pub fn trans_opt(bcx: block, o: &Opt) -> opt_result { - let _icx = bcx.insn_ctxt("match::trans_opt"); + let _icx = push_ctxt("match::trans_opt"); let ccx = bcx.ccx(); let bcx = bcx; match *o { @@ -870,7 +870,7 @@ pub fn extract_variant_args(bcx: block, disr_val: int, val: ValueRef) -> ExtractedBlock { - let _icx = bcx.insn_ctxt("match::extract_variant_args"); + let _icx = push_ctxt("match::extract_variant_args"); let args = do vec::from_fn(adt::num_args(repr, disr_val)) |i| { adt::trans_field_ptr(bcx, repr, val, disr_val, i) }; @@ -896,7 +896,7 @@ pub fn extract_vec_elems(bcx: block, val: ValueRef, count: ValueRef) -> ExtractedBlock { - let _icx = bcx.insn_ctxt("match::extract_vec_elems"); + let _icx = push_ctxt("match::extract_vec_elems"); let vec_datum = match_datum(bcx, val, pat_id); let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0); @@ -1088,7 +1088,7 @@ pub fn compare_values(cx: block, rhs: ValueRef, rhs_t: ty::t) -> Result { - let _icx = cx.insn_ctxt("compare_values"); + let _icx = push_ctxt("compare_values"); if ty::type_is_scalar(rhs_t) { let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::eq); return rslt(rs.bcx, rs.val); @@ -1277,7 +1277,7 @@ pub fn compile_submatch(bcx: block, For an empty match, a fall-through case must exist */ assert!((m.len() > 0u || chk.is_some())); - let _icx = bcx.insn_ctxt("match::compile_submatch"); + let _icx = push_ctxt("match::compile_submatch"); let mut bcx = bcx; let tcx = bcx.tcx(); let dm = tcx.def_map; @@ -1617,7 +1617,7 @@ pub fn trans_match(bcx: block, discr_expr: @ast::expr, arms: ~[ast::arm], dest: Dest) -> block { - let _icx = bcx.insn_ctxt("match::trans_match"); + let _icx = push_ctxt("match::trans_match"); do with_scope(bcx, match_expr.info(), "match") |bcx| { trans_match_inner(bcx, discr_expr, arms, dest) } @@ -1664,7 +1664,7 @@ pub fn trans_match_inner(scope_cx: block, discr_expr: @ast::expr, arms: &[ast::arm], dest: Dest) -> block { - let _icx = scope_cx.insn_ctxt("match::trans_match_inner"); + let _icx = push_ctxt("match::trans_match_inner"); let mut bcx = scope_cx; let tcx = bcx.tcx(); @@ -1751,7 +1751,7 @@ pub fn bind_irrefutable_pat(bcx: block, make_copy: bool, binding_mode: IrrefutablePatternBindingMode) -> block { - let _icx = bcx.insn_ctxt("match::bind_irrefutable_pat"); + let _icx = push_ctxt("match::bind_irrefutable_pat"); let ccx = bcx.fcx.ccx; let mut bcx = bcx; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b94442c85ef7..bd57a709a90b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -73,6 +73,7 @@ use core::libc::c_uint; use core::str; use core::uint; use core::vec; +use core::local_data; use extra::time; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; @@ -88,49 +89,52 @@ use syntax::abi::{X86, X86_64, Arm, Mips}; pub use middle::trans::context::task_llcx; -pub struct icx_popper { - ccx: @mut CrateContext, +fn task_local_insn_key(_v: @~[&'static str]) {} + +pub fn with_insn_ctxt(blk: &fn(&[&'static str])) { + unsafe { + let opt = local_data::local_data_get(task_local_insn_key); + if opt.is_some() { + blk(*opt.unwrap()); + } + } } +pub fn init_insn_ctxt() { + unsafe { + local_data::local_data_set(task_local_insn_key, @~[]); + } +} + +pub struct _InsnCtxt { _x: () } + #[unsafe_destructor] -impl Drop for icx_popper { +impl Drop for _InsnCtxt { fn finalize(&self) { - if self.ccx.sess.count_llvm_insns() { - self.ccx.stats.llvm_insn_ctxt.pop(); + unsafe { + do local_data::local_data_modify(task_local_insn_key) |c| { + do c.map_consume |@ctx| { + let mut ctx = ctx; + ctx.pop(); + @ctx + } + } } } } -pub fn icx_popper(ccx: @mut CrateContext) -> icx_popper { - icx_popper { - ccx: ccx - } -} - -pub trait get_insn_ctxt { - fn insn_ctxt(&self, s: &str) -> icx_popper; -} - -impl get_insn_ctxt for @mut CrateContext { - fn insn_ctxt(&self, s: &str) -> icx_popper { - debug!("new insn_ctxt: %s", s); - if self.sess.count_llvm_insns() { - self.stats.llvm_insn_ctxt.push(str::to_owned(s)); +pub fn push_ctxt(s: &'static str) -> _InsnCtxt { + debug!("new InsnCtxt: %s", s); + unsafe { + do local_data::local_data_modify(task_local_insn_key) |c| { + do c.map_consume |@ctx| { + let mut ctx = ctx; + ctx.push(s); + @ctx + } } - icx_popper(*self) - } -} - -impl get_insn_ctxt for block { - fn insn_ctxt(&self, s: &str) -> icx_popper { - self.ccx().insn_ctxt(s) - } -} - -impl get_insn_ctxt for fn_ctxt { - fn insn_ctxt(&self, s: &str) -> icx_popper { - self.ccx.insn_ctxt(s) } + _InsnCtxt { _x: () } } fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { @@ -189,13 +193,13 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, } } pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("umax"); + let _icx = push_ctxt("umax"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); return Select(cx, cond, b, a); } pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("umin"); + let _icx = push_ctxt("umin"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); return Select(cx, cond, a, b); } @@ -204,7 +208,7 @@ pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { // The type of the returned pointer is always i8*. If you care about the // return type, use bump_ptr(). pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("ptr_offs"); + let _icx = push_ctxt("ptr_offs"); let raw = PointerCast(bcx, base, Type::i8p()); InBoundsGEP(bcx, raw, [sz]) } @@ -213,7 +217,7 @@ pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { // to a given type. pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("bump_ptr"); + let _icx = push_ctxt("bump_ptr"); let ccx = bcx.ccx(); let bumped = ptr_offs(bcx, base, sz); let typ = type_of(ccx, t).ptr_to(); @@ -228,7 +232,7 @@ pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> pub fn opaque_box_body(bcx: block, body_t: ty::t, boxptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("opaque_box_body"); + let _icx = push_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); let ty = Type::box(ccx, &ty); @@ -242,7 +246,7 @@ pub fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> Result { - let _icx = bcx.insn_ctxt("malloc_raw"); + let _icx = push_ctxt("malloc_raw"); let ccx = bcx.ccx(); let (mk_fn, langcall) = match heap { @@ -306,7 +310,7 @@ pub struct MallocResult { // and pulls out the body pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> MallocResult { - let _icx = bcx.insn_ctxt("malloc_general"); + let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); let non_gc_box = non_gc_box_cast(bcx, llbox); let body = GEPi(bcx, non_gc_box, [0u, abi::box_field_body]); @@ -457,7 +461,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext, parent_id: ast::def_id, substs: &[ty::t]) -> ValueRef { - let _icx = ccx.insn_ctxt("trans_res_dtor"); + let _icx = push_ctxt("trans_res_dtor"); if !substs.is_empty() { let did = if did.crate != ast::local_crate { inline::maybe_instantiate_inline(ccx, did, true) @@ -547,7 +551,7 @@ pub fn compare_scalar_values(cx: block, nt: scalar_type, op: ast::binop) -> ValueRef { - let _icx = cx.insn_ctxt("compare_scalar_values"); + let _icx = push_ctxt("compare_scalar_values"); fn die(cx: block) -> ! { cx.tcx().sess.bug("compare_scalar_values: must be a\ comparison operator"); @@ -616,12 +620,12 @@ pub fn store_inbounds(cx: block, v: ValueRef, p: ValueRef, idxs: &[uint]) { // Iterates through the elements of a structural type. pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, f: val_and_ty_fn) -> block { - let _icx = cx.insn_ctxt("iter_structural_ty"); + let _icx = push_ctxt("iter_structural_ty"); fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef, variant: ty::VariantInfo, tps: &[ty::t], f: val_and_ty_fn) -> block { - let _icx = cx.insn_ctxt("iter_variant"); + let _icx = push_ctxt("iter_variant"); let tcx = cx.tcx(); let mut cx = cx; @@ -795,7 +799,7 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> (ValueRef, block) { - let _icx = bcx.insn_ctxt("invoke_"); + let _icx = push_ctxt("invoke_"); if bcx.unreachable { return (C_null(Type::i8()), bcx); } @@ -911,7 +915,7 @@ pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) { } pub fn get_landing_pad(bcx: block) -> BasicBlockRef { - let _icx = bcx.insn_ctxt("get_landing_pad"); + let _icx = push_ctxt("get_landing_pad"); let mut cached = None; let mut pad_bcx = bcx; // Guaranteed to be set below @@ -1004,20 +1008,20 @@ 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 = cx.insn_ctxt("spill_if_immediate"); + let _icx = push_ctxt("spill_if_immediate"); if ty::type_is_immediate(t) { return do_spill(cx, v, t); } return v; } pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { - let _icx = cx.insn_ctxt("load_if_immediate"); + let _icx = push_ctxt("load_if_immediate"); if ty::type_is_immediate(t) { return Load(cx, v); } return v; } pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { if !bcx.sess().trace() { return; } - let _icx = bcx.insn_ctxt("trans_trace"); + let _icx = push_ctxt("trans_trace"); add_comment(bcx, trace_str); let V_trace_str = C_cstr(bcx.ccx(), trace_str); let (V_filename, V_line) = match sp_opt { @@ -1038,7 +1042,7 @@ pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { } pub fn build_return(bcx: block) { - let _icx = bcx.insn_ctxt("build_return"); + let _icx = push_ctxt("build_return"); Br(bcx, bcx.fcx.llreturn); } @@ -1054,7 +1058,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block { bcx.to_str(), local.node.id); let _indenter = indenter(); - let _icx = bcx.insn_ctxt("init_local"); + let _icx = push_ctxt("init_local"); let ty = node_id_type(bcx, local.node.id); debug!("ty=%s", bcx.ty_to_str(ty)); @@ -1102,7 +1106,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block { } pub fn trans_stmt(cx: block, s: &ast::stmt) -> block { - let _icx = cx.insn_ctxt("trans_stmt"); + let _icx = push_ctxt("trans_stmt"); debug!("trans_stmt(%s)", stmt_to_str(s, cx.tcx().sess.intr())); if cx.sess().asm_comments() { @@ -1230,7 +1234,7 @@ pub fn trans_block_cleanups_(bcx: block, cleanups: &[cleanup], /* cleanup_cx: block, */ is_lpad: bool) -> block { - let _icx = bcx.insn_ctxt("trans_block_cleanups"); + let _icx = push_ctxt("trans_block_cleanups"); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. let no_lpads = @@ -1257,7 +1261,7 @@ pub fn trans_block_cleanups_(bcx: block, pub fn cleanup_and_leave(bcx: block, upto: Option, leave: Option) { - let _icx = bcx.insn_ctxt("cleanup_and_leave"); + let _icx = push_ctxt("cleanup_and_leave"); let mut cur = bcx; let mut bcx = bcx; let is_lpad = leave == None; @@ -1324,12 +1328,12 @@ pub fn cleanup_and_leave(bcx: block, } pub fn cleanup_and_Br(bcx: block, upto: block, target: BasicBlockRef) { - let _icx = bcx.insn_ctxt("cleanup_and_Br"); + let _icx = push_ctxt("cleanup_and_Br"); cleanup_and_leave(bcx, Some(upto.llbb), Some(target)); } pub fn leave_block(bcx: block, out_of: block) -> block { - let _icx = bcx.insn_ctxt("leave_block"); + let _icx = push_ctxt("leave_block"); let next_cx = sub_block(block_parent(out_of), "next"); if bcx.unreachable { Unreachable(next_cx); } cleanup_and_Br(bcx, out_of, next_cx.llbb); @@ -1340,7 +1344,7 @@ pub fn with_scope(bcx: block, opt_node_info: Option, name: &str, f: &fn(block) -> block) -> block { - let _icx = bcx.insn_ctxt("with_scope"); + let _icx = push_ctxt("with_scope"); debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)", bcx.to_str(), opt_node_info, name); @@ -1355,7 +1359,7 @@ pub fn with_scope_result(bcx: block, opt_node_info: Option, name: &str, f: &fn(block) -> Result) -> Result { - let _icx = bcx.insn_ctxt("with_scope_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); @@ -1367,7 +1371,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, -> datum::DatumBlock { use middle::trans::datum::DatumBlock; - let _icx = bcx.insn_ctxt("with_scope_result"); + let _icx = push_ctxt("with_scope_result"); let scope_cx = scope_block(bcx, opt_node_info, name); Br(bcx, scope_cx.llbb); let DatumBlock {bcx, datum} = f(scope_cx); @@ -1389,7 +1393,7 @@ pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { } pub fn alloc_local(cx: block, local: @ast::local) -> block { - let _icx = cx.insn_ctxt("alloc_local"); + 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)), @@ -1411,7 +1415,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block { pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { - let _icx = bcx.insn_ctxt("with_cond"); + let _icx = push_ctxt("with_cond"); let next_cx = base::sub_block(bcx, "next"); let cond_cx = base::sub_block(bcx, "cond"); CondBr(bcx, val, cond_cx.llbb, next_cx.llbb); @@ -1421,7 +1425,7 @@ pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { } pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { - let _icx = cx.insn_ctxt("call_memcpy"); + let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess.targ_cfg.arch { X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32", @@ -1437,7 +1441,7 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a } pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("memcpy_ty"); + let _icx = push_ctxt("memcpy_ty"); let ccx = bcx.ccx(); if ty::type_is_structural(t) { let llty = type_of::type_of(ccx, t); @@ -1450,7 +1454,7 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) { } pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) { - let _icx = cx.insn_ctxt("zero_mem"); + let _icx = push_ctxt("zero_mem"); let bcx = cx; let ccx = cx.ccx(); let llty = type_of::type_of(ccx, t); @@ -1463,7 +1467,7 @@ pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) { // awful. (A telltale sign of this is large quantities of // `mov [byte ptr foo],0` in the generated code.) pub fn memzero(cx: block, llptr: ValueRef, ty: Type) { - let _icx = cx.insn_ctxt("memzero"); + let _icx = push_ctxt("memzero"); let ccx = cx.ccx(); let intrinsic_key = match ccx.sess.targ_cfg.arch { @@ -1481,7 +1485,7 @@ pub fn memzero(cx: block, llptr: ValueRef, ty: Type) { } pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef { - let _icx = bcx.insn_ctxt("alloc_ty"); + let _icx = push_ctxt("alloc_ty"); let ccx = bcx.ccx(); let ty = type_of::type_of(ccx, t); assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t)); @@ -1494,7 +1498,7 @@ pub fn alloca(cx: block, ty: Type) -> ValueRef { } pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef { - let _icx = cx.insn_ctxt("alloca"); + let _icx = push_ctxt("alloca"); if cx.unreachable { unsafe { return llvm::LLVMGetUndef(ty.to_ref()); @@ -1507,7 +1511,7 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef { } pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("arrayalloca"); + let _icx = push_ctxt("arrayalloca"); if cx.unreachable { unsafe { return llvm::LLVMGetUndef(ty.to_ref()); @@ -1639,7 +1643,7 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt, self_arg: self_arg, args: &[ast::arg]) -> ~[ValueRef] { - let _icx = cx.insn_ctxt("create_llargs_for_fn_args"); + let _icx = push_ctxt("create_llargs_for_fn_args"); match self_arg { impl_self(tt) => { @@ -1687,7 +1691,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, args: &[ast::arg], raw_llargs: &[ValueRef], arg_tys: &[ty::t]) -> block { - let _icx = fcx.insn_ctxt("copy_args_to_allocas"); + let _icx = push_ctxt("copy_args_to_allocas"); let mut bcx = bcx; match fcx.llself { @@ -1753,7 +1757,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, // Ties up the llstaticallocas -> llloadenv -> lltop edges, // and builds the return block. pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef) { - let _icx = fcx.insn_ctxt("finish_fn"); + let _icx = push_ctxt("finish_fn"); tie_up_header_blocks(fcx, lltop); build_return_block(fcx); } @@ -1771,7 +1775,7 @@ pub fn build_return_block(fcx: fn_ctxt) { } pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) { - let _icx = fcx.insn_ctxt("tie_up_header_blocks"); + let _icx = push_ctxt("tie_up_header_blocks"); match fcx.llloadenv { Some(ll) => { Br(raw_block(fcx, false, fcx.llstaticallocas), ll); @@ -1802,7 +1806,7 @@ pub fn trans_closure(ccx: @mut CrateContext, maybe_load_env: &fn(fn_ctxt), finish: &fn(block)) { ccx.stats.n_closures += 1; - let _icx = ccx.insn_ctxt("trans_closure"); + let _icx = push_ctxt("trans_closure"); set_uwtable(llfndecl); debug!("trans_closure(..., param_substs=%s)", @@ -1891,7 +1895,7 @@ pub fn trans_fn(ccx: @mut CrateContext, debug!("trans_fn(self_arg=%?, param_substs=%s)", self_arg, param_substs.repr(ccx.tcx)); - let _icx = ccx.insn_ctxt("trans_fn"); + 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)); @@ -1926,7 +1930,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, disr: int, param_substs: Option<@param_substs>, llfndecl: ValueRef) { - let _icx = ccx.insn_ctxt("trans_enum_variant"); + let _icx = push_ctxt("trans_enum_variant"); // Translate variant arguments to function arguments. let fn_args = do args.map |varg| { ast::arg { @@ -2000,7 +2004,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, ctor_id: ast::node_id, param_substs: Option<@param_substs>, llfndecl: ValueRef) { - let _icx = ccx.insn_ctxt("trans_tuple_struct"); + let _icx = push_ctxt("trans_tuple_struct"); // Translate struct fields to function arguments. let fn_args = do fields.map |field| { @@ -2086,7 +2090,7 @@ pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def, } pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { - let _icx = ccx.insn_ctxt("trans_item"); + let _icx = push_ctxt("trans_item"); let path = match ccx.tcx.items.get_copy(&item.id) { ast_map::node_item(_, p) => p, // tjc: ? @@ -2193,7 +2197,7 @@ pub fn trans_struct_def(ccx: @mut CrateContext, struct_def: @ast::struct_def) { // only as a convenience for humans working with the code, to organize names // and control visibility. pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) { - let _icx = ccx.insn_ctxt("trans_mod"); + let _icx = push_ctxt("trans_mod"); for m.items.each |item| { trans_item(ccx, *item); } @@ -2560,7 +2564,7 @@ pub fn register_method(ccx: @mut CrateContext, // The constant translation pass. pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { - let _icx = ccx.insn_ctxt("trans_constant"); + let _icx = push_ctxt("trans_constant"); match it.node { ast::item_enum(ref enum_definition, _) => { let vi = ty::enum_variants(ccx.tcx, @@ -2922,19 +2926,13 @@ pub fn trans_crate(sess: session::Session, let ccx = @mut CrateContext::new(sess, llmod_id, tcx, emap2, maps, symbol_hasher, link_meta, reachable); - // FIXME(#6511): get LLVM building with --enable-threads so this - // function can be called - // if !llvm::LLVMRustStartMultithreading() { - // sess.bug("couldn't enable multi-threaded LLVM"); - // } - { - let _icx = ccx.insn_ctxt("data"); + let _icx = push_ctxt("data"); trans_constants(ccx, crate); } { - let _icx = ccx.insn_ctxt("text"); + let _icx = push_ctxt("text"); trans_mod(ccx, &crate.node.module); } @@ -2963,6 +2961,12 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("n_closures: %u", ccx.stats.n_closures)); } + if ccx.sess.count_llvm_insns() { + for ccx.stats.llvm_insns.each |&k, &v| { + io::println(fmt!("%-7u %s", v, k)); + } + } + let llcx = ccx.llcx; let link_meta = ccx.link_meta; let llmod = ccx.llmod; diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index f1ccfba5b30d..83c1a3c80db2 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -19,6 +19,7 @@ use middle::trans::common::*; use middle::trans::machine::llalign_of_min; use syntax::codemap::span; +use middle::trans::base; use middle::trans::type_::Type; use core::cast; @@ -46,10 +47,8 @@ pub fn B(cx: block) -> BuilderRef { } pub fn count_insn(cx: block, category: &str) { - if cx.ccx().sess.count_llvm_insns() { - + do base::with_insn_ctxt |v| { let h = &mut cx.ccx().stats.llvm_insns; - let v : &[~str] = cx.ccx().stats.llvm_insn_ctxt; // Build version of path with cycles removed. diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index c74a2320b5b9..0809b1c124e0 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -78,7 +78,7 @@ pub struct Callee { } pub fn trans(bcx: block, expr: @ast::expr) -> Callee { - let _icx = bcx.insn_ctxt("trans_callee"); + let _icx = push_ctxt("trans_callee"); debug!("callee::trans(expr=%s)", expr.repr(bcx.tcx())); // pick out special kinds of expressions that can be called: @@ -172,7 +172,7 @@ pub fn trans_fn_ref(bcx: block, * with id `def_id` into a function pointer. This may require * monomorphization or inlining. */ - let _icx = bcx.insn_ctxt("trans_fn_ref"); + let _icx = push_ctxt("trans_fn_ref"); let type_params = node_id_type_params(bcx, ref_id); let vtables = node_vtables(bcx, ref_id); @@ -216,7 +216,7 @@ pub fn trans_fn_ref_with_vtables( // - `type_params`: values for each of the fn/method's type parameters // - `vtables`: values for each bound on each of the type parameters - let _icx = bcx.insn_ctxt("trans_fn_ref_with_vtables"); + let _icx = push_ctxt("trans_fn_ref_with_vtables"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -357,7 +357,7 @@ pub fn trans_call(in_cx: block, id: ast::node_id, dest: expr::Dest) -> block { - let _icx = in_cx.insn_ctxt("trans_call"); + let _icx = push_ctxt("trans_call"); trans_call_inner(in_cx, call_ex.info(), expr_ty(in_cx, f), @@ -375,7 +375,7 @@ pub fn trans_method_call(in_cx: block, args: CallArgs, dest: expr::Dest) -> block { - let _icx = in_cx.insn_ctxt("trans_method_call"); + let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_ex=%s, rcvr=%s)", call_ex.repr(in_cx.tcx()), rcvr.repr(in_cx.tcx())); @@ -671,7 +671,7 @@ pub fn trans_args(cx: block, autoref_arg: AutorefArg, llargs: &mut ~[ValueRef]) -> block { - let _icx = cx.insn_ctxt("trans_args"); + let _icx = push_ctxt("trans_args"); let mut temp_cleanups = ~[]; let arg_tys = ty::ty_fn_args(fn_ty); @@ -725,7 +725,7 @@ pub fn trans_arg_expr(bcx: block, temp_cleanups: &mut ~[ValueRef], ret_flag: Option, autoref_arg: AutorefArg) -> Result { - let _icx = bcx.insn_ctxt("trans_arg_expr"); + let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \ diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 7d7c024640ab..613bd86ab918 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -162,12 +162,12 @@ pub fn mk_closure_tys(tcx: ty::ctxt, pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("closure::allocate_cbox"); + let _icx = push_ctxt("closure::allocate_cbox"); let ccx = bcx.ccx(); let tcx = ccx.tcx; fn nuke_ref_count(bcx: block, llbox: ValueRef) { - let _icx = bcx.insn_ctxt("closure::nuke_ref_count"); + let _icx = push_ctxt("closure::nuke_ref_count"); // Initialize ref count to arbitrary value for debugging: let ccx = bcx.ccx(); let llbox = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to()); @@ -206,7 +206,7 @@ pub struct ClosureResult { pub fn store_environment(bcx: block, bound_values: ~[EnvValue], sigil: ast::Sigil) -> ClosureResult { - let _icx = bcx.insn_ctxt("closure::store_environment"); + let _icx = push_ctxt("closure::store_environment"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -260,7 +260,7 @@ pub fn build_closure(bcx0: block, cap_vars: &[moves::CaptureVar], sigil: ast::Sigil, include_ret_handle: Option) -> ClosureResult { - let _icx = bcx0.insn_ctxt("closure::build_closure"); + let _icx = push_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call let bcx = bcx0; @@ -322,7 +322,7 @@ pub fn load_environment(fcx: fn_ctxt, cap_vars: &[moves::CaptureVar], load_ret_handle: bool, sigil: ast::Sigil) { - let _icx = fcx.insn_ctxt("closure::load_environment"); + let _icx = push_ctxt("closure::load_environment"); let llloadenv = match fcx.llloadenv { Some(ll) => ll, @@ -393,7 +393,7 @@ pub fn trans_expr_fn(bcx: block, (fn ptr, env) pair */ - let _icx = bcx.insn_ctxt("closure::trans_expr_fn"); + let _icx = push_ctxt("closure::trans_expr_fn"); let dest_addr = match dest { expr::SaveIn(p) => p, @@ -470,7 +470,7 @@ pub fn make_closure_glue( v: ValueRef, t: ty::t, glue_fn: @fn(block, v: ValueRef, t: ty::t) -> block) -> block { - let _icx = cx.insn_ctxt("closure::make_closure_glue"); + let _icx = push_ctxt("closure::make_closure_glue"); let bcx = cx; let tcx = cx.tcx(); @@ -494,7 +494,7 @@ pub fn make_opaque_cbox_take_glue( cboxptr: ValueRef) // ptr to ptr to the opaque closure -> block { // Easy cases: - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_take_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_take_glue"); match sigil { ast::BorrowedSigil => { return bcx; @@ -553,7 +553,7 @@ pub fn make_opaque_cbox_drop_glue( sigil: ast::Sigil, cboxptr: ValueRef) // ptr to the opaque closure -> block { - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_drop_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue"); match sigil { ast::BorrowedSigil => bcx, ast::ManagedSigil => { @@ -574,7 +574,7 @@ pub fn make_opaque_cbox_free_glue( sigil: ast::Sigil, cbox: ValueRef) // ptr to ptr to the opaque closure -> block { - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_free_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_free_glue"); match sigil { ast::BorrowedSigil => { return bcx; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index c8b5b00d6246..21e173fd0b43 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -101,7 +101,6 @@ pub struct Stats { n_monos: uint, n_inlines: uint, n_closures: uint, - llvm_insn_ctxt: ~[~str], llvm_insns: HashMap<~str, uint>, fn_times: ~[(~str, int)] // (ident, time) } diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index b688ca66c2b3..e40534773c2d 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -19,7 +19,7 @@ use metadata::csearch; use middle::const_eval; use middle::trans::adt; use middle::trans::base; -use middle::trans::base::get_insn_ctxt; +use middle::trans::base::push_ctxt; use middle::trans::common::*; use middle::trans::consts; use middle::trans::expr; @@ -37,7 +37,7 @@ use syntax::{ast, ast_util, ast_map}; pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { - let _icx = cx.insn_ctxt("trans_lit"); + let _icx = push_ctxt("trans_lit"); match lit.node { ast::lit_int(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true), ast::lit_uint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false), @@ -249,7 +249,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { unsafe { - let _icx = cx.insn_ctxt("const_expr"); + let _icx = push_ctxt("const_expr"); return match e.node { ast::expr_lit(lit) => consts::const_lit(cx, e, *lit), ast::expr_binary(_, b, e1, e2) => { @@ -589,7 +589,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) { unsafe { - let _icx = ccx.insn_ctxt("trans_const"); + let _icx = push_ctxt("trans_const"); let g = base::get_item_val(ccx, id); // At this point, get_item_val has already translated the // constant's initializer to determine its LLVM type. diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index ee6ead72c1e0..715b1c88327f 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -162,6 +162,10 @@ impl CrateContext { None }; + if sess.count_llvm_insns() { + base::init_insn_ctxt() + } + CrateContext { sess: sess, llmod: llmod, @@ -210,7 +214,6 @@ impl CrateContext { n_monos: 0u, n_inlines: 0u, n_closures: 0u, - llvm_insn_ctxt: ~[], llvm_insns: HashMap::new(), fn_times: ~[] }, @@ -234,7 +237,6 @@ impl CrateContext { ((end.nsec as int) - (start.nsec as int)) / 1000000; self.stats.fn_times.push((name, elapsed)); } - } #[unsafe_destructor] @@ -247,7 +249,6 @@ impl Drop for CrateContext { } fn task_local_llcx_key(_v: @ContextRef) {} - pub fn task_llcx() -> ContextRef { let opt = unsafe { local_data::local_data_get(task_local_llcx_key) }; *opt.expect("task-local LLVMContextRef wasn't ever set!") diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index a9892b34ccd7..6be26354db16 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -35,7 +35,7 @@ use syntax::ast_util; use syntax::codemap::span; pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { - let _icx = bcx.insn_ctxt("trans_block"); + let _icx = push_ctxt("trans_block"); let mut bcx = bcx; do block_locals(b) |local| { bcx = alloc_local(bcx, local); @@ -67,7 +67,7 @@ pub fn trans_if(bcx: block, dest.to_str(bcx.ccx())); let _indenter = indenter(); - let _icx = bcx.insn_ctxt("trans_if"); + let _icx = push_ctxt("trans_if"); let Result {bcx, val: cond_val} = expr::trans_to_datum(bcx, cond).to_result(); @@ -126,7 +126,7 @@ pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block { } pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::blk) -> block { - let _icx = bcx.insn_ctxt("trans_while"); + let _icx = push_ctxt("trans_while"); let next_bcx = sub_block(bcx, "while next"); // bcx @@ -168,7 +168,7 @@ pub fn trans_loop(bcx:block, body: &ast::blk, opt_label: Option) -> block { - let _icx = bcx.insn_ctxt("trans_loop"); + let _icx = push_ctxt("trans_loop"); let next_bcx = sub_block(bcx, "next"); let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`", body.info()); @@ -182,7 +182,7 @@ pub fn trans_log(log_ex: @ast::expr, lvl: @ast::expr, bcx: block, e: @ast::expr) -> block { - let _icx = bcx.insn_ctxt("trans_log"); + let _icx = push_ctxt("trans_log"); let ccx = bcx.ccx(); let mut bcx = bcx; if ty::type_is_bot(expr_ty(bcx, lvl)) { @@ -244,7 +244,7 @@ pub fn trans_break_cont(bcx: block, opt_label: Option, to_end: bool) -> block { - let _icx = bcx.insn_ctxt("trans_break_cont"); + let _icx = push_ctxt("trans_break_cont"); // Locate closest loop block, outputting cleanup as we go. let mut unwind = bcx; let mut target; @@ -298,7 +298,7 @@ pub fn trans_cont(bcx: block, label_opt: Option) -> block { } pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { - let _icx = bcx.insn_ctxt("trans_ret"); + let _icx = push_ctxt("trans_ret"); let mut bcx = bcx; let dest = match copy bcx.fcx.loop_ret { Some((flagptr, retptr)) => { @@ -333,7 +333,7 @@ pub fn trans_fail_expr(bcx: block, sp_opt: Option, fail_expr: Option<@ast::expr>) -> block { - let _icx = bcx.insn_ctxt("trans_fail_expr"); + let _icx = push_ctxt("trans_fail_expr"); let mut bcx = bcx; match fail_expr { Some(arg_expr) => { @@ -361,7 +361,7 @@ pub fn trans_fail(bcx: block, sp_opt: Option, fail_str: @str) -> block { - let _icx = bcx.insn_ctxt("trans_fail"); + let _icx = push_ctxt("trans_fail"); let V_fail_str = C_cstr(bcx.ccx(), fail_str); return trans_fail_value(bcx, sp_opt, V_fail_str); } @@ -370,7 +370,7 @@ fn trans_fail_value(bcx: block, sp_opt: Option, V_fail_str: ValueRef) -> block { - let _icx = bcx.insn_ctxt("trans_fail_value"); + let _icx = push_ctxt("trans_fail_value"); let ccx = bcx.ccx(); let (V_filename, V_line) = match sp_opt { Some(sp) => { @@ -394,7 +394,7 @@ fn trans_fail_value(bcx: block, pub fn trans_fail_bounds_check(bcx: block, sp: span, index: ValueRef, len: ValueRef) -> block { - let _icx = bcx.insn_ctxt("trans_fail_bounds_check"); + let _icx = push_ctxt("trans_fail_bounds_check"); let (filename, line) = filename_and_line_num_from_span(bcx, sp); let args = ~[filename, line, index, len]; let bcx = callee::trans_lang_call( diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 8e25da202cca..32d0f8887b90 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -273,7 +273,7 @@ impl Datum { * `store_to()` instead, which will move if possible but copy if * neccessary. */ - let _icx = bcx.insn_ctxt("copy_to"); + let _icx = push_ctxt("copy_to"); if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { return bcx; @@ -317,7 +317,7 @@ impl Datum { * A helper for `copy_to()` which does not check to see if we * are copying to/from the same value. */ - let _icx = bcx.insn_ctxt("copy_to_no_check"); + let _icx = push_ctxt("copy_to_no_check"); let mut bcx = bcx; if action == DROP_EXISTING { @@ -341,7 +341,7 @@ impl Datum { // pub fn move_to(&self, bcx: block, action: CopyAction, dst: ValueRef) -> block { - let _icx = bcx.insn_ctxt("move_to"); + let _icx = push_ctxt("move_to"); let mut bcx = bcx; debug!("move_to(self=%s, action=%?, dst=%s)", @@ -740,7 +740,7 @@ impl Datum { expr_id: ast::node_id, max: uint) -> DatumBlock { - let _icx = bcx.insn_ctxt("autoderef"); + let _icx = push_ctxt("autoderef"); debug!("autoderef(expr_id=%d, max=%?, self=%?)", expr_id, max, self.to_str(bcx.ccx())); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index c0a3b76aca4b..44e571dfb2ff 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -451,7 +451,7 @@ fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_rvalue_datum_unadjusted"); + let _icx = push_ctxt("trans_rvalue_datum_unadjusted"); trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); @@ -502,7 +502,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { let mut bcx = bcx; - let _icx = bcx.insn_ctxt("trans_rvalue_stmt"); + let _icx = push_ctxt("trans_rvalue_stmt"); if bcx.unreachable { return bcx; @@ -558,7 +558,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_rvalue_dps_unadjusted"); + let _icx = push_ctxt("trans_rvalue_dps_unadjusted"); let tcx = bcx.tcx(); trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); @@ -707,7 +707,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr, def: ast::def, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_def_dps_unadjusted"); + let _icx = push_ctxt("trans_def_dps_unadjusted"); let ccx = bcx.ccx(); let lldest = match dest { @@ -755,7 +755,7 @@ fn trans_def_datum_unadjusted(bcx: block, ref_expr: @ast::expr, def: ast::def) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_def_datum_unadjusted"); + let _icx = push_ctxt("trans_def_datum_unadjusted"); match def { ast::def_fn(did, _) | ast::def_static_method(did, None, _) => { @@ -816,7 +816,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { * Translates an lvalue expression, always yielding a by-ref * datum. Does not apply any adjustments. */ - let _icx = bcx.insn_ctxt("trans_lval"); + let _icx = push_ctxt("trans_lval"); let mut bcx = bcx; debug!("trans_lvalue(expr=%s)", bcx.expr_to_str(expr)); @@ -855,7 +855,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { //! Translates `base.field`. let mut bcx = bcx; - let _icx = bcx.insn_ctxt("trans_rec_field"); + let _icx = push_ctxt("trans_rec_field"); let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base)); let repr = adt::represent_type(bcx.ccx(), base_datum.ty); @@ -878,7 +878,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { idx: @ast::expr) -> DatumBlock { //! Translates `base[idx]`. - let _icx = bcx.insn_ctxt("trans_index"); + let _icx = push_ctxt("trans_index"); let ccx = bcx.ccx(); let base_ty = expr_ty(bcx, base); let mut bcx = bcx; @@ -942,7 +942,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { { //! Translates a reference to a path. - let _icx = bcx.insn_ctxt("trans_def_lvalue"); + let _icx = push_ctxt("trans_def_lvalue"); let ccx = bcx.ccx(); match def { ast::def_const(did) => { @@ -1012,7 +1012,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { - let _icx = bcx.insn_ctxt("trans_local_var"); + let _icx = push_ctxt("trans_local_var"); return match def { ast::def_upvar(nid, _, _, _) => { @@ -1143,7 +1143,7 @@ fn trans_rec_or_struct(bcx: block, id: ast::node_id, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_rec"); + let _icx = push_ctxt("trans_rec"); let bcx = bcx; let ty = node_id_type(bcx, id); @@ -1217,7 +1217,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, fields: &[(uint, @ast::expr)], optbase: Option, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_adt"); + let _icx = push_ctxt("trans_adt"); let mut bcx = bcx; let addr = match dest { Ignore => { @@ -1263,7 +1263,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, fn trans_immediate_lit(bcx: block, expr: @ast::expr, lit: ast::lit) -> DatumBlock { // must not be a string constant, that is a RvalueDpsExpr - let _icx = bcx.insn_ctxt("trans_immediate_lit"); + let _icx = push_ctxt("trans_immediate_lit"); let ty = expr_ty(bcx, expr); immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty) } @@ -1272,7 +1272,7 @@ fn trans_unary_datum(bcx: block, un_expr: @ast::expr, op: ast::unop, sub_expr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_unary_datum"); + let _icx = push_ctxt("trans_unary_datum"); // if deref, would be LvalueExpr assert!(op != ast::deref); @@ -1333,7 +1333,7 @@ fn trans_unary_datum(bcx: block, contents: @ast::expr, contents_ty: ty::t, heap: heap) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_boxed_expr"); + 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); @@ -1345,7 +1345,7 @@ fn trans_unary_datum(bcx: block, fn trans_addr_of(bcx: block, expr: @ast::expr, subexpr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_addr_of"); + let _icx = push_ctxt("trans_addr_of"); let mut bcx = bcx; let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr)); let llval = sub_datum.to_ref_llval(bcx); @@ -1361,7 +1361,7 @@ fn trans_eager_binop(bcx: block, lhs_datum: &Datum, rhs_datum: &Datum) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_eager_binop"); + let _icx = push_ctxt("trans_eager_binop"); let lhs = lhs_datum.to_appropriate_llval(bcx); let lhs_t = lhs_datum.ty; @@ -1457,7 +1457,7 @@ fn trans_lazy_binop(bcx: block, op: lazy_binop_ty, a: @ast::expr, b: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_lazy_binop"); + let _icx = push_ctxt("trans_lazy_binop"); let binop_ty = expr_ty(bcx, binop_expr); let bcx = bcx; @@ -1503,7 +1503,7 @@ fn trans_binary(bcx: block, lhs: @ast::expr, rhs: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_binary"); + let _icx = push_ctxt("trans_binary"); match op { ast::and => { @@ -1550,7 +1550,7 @@ fn trans_overloaded_op(bcx: block, fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef, signed: bool) -> ValueRef { - let _icx = bcx.insn_ctxt("int_cast"); + let _icx = push_ctxt("int_cast"); unsafe { let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref()); let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref()); @@ -1568,7 +1568,7 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("float_cast"); + let _icx = push_ctxt("float_cast"); let srcsz = llsrctype.float_width(); let dstsz = lldsttype.float_width(); return if dstsz > srcsz { @@ -1602,7 +1602,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind { fn trans_imm_cast(bcx: block, expr: @ast::expr, id: ast::node_id) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_cast"); + let _icx = push_ctxt("trans_cast"); let ccx = bcx.ccx(); let t_out = node_id_type(bcx, id); @@ -1669,7 +1669,7 @@ fn trans_assign_op(bcx: block, dst: @ast::expr, src: @ast::expr) -> block { - let _icx = bcx.insn_ctxt("trans_assign_op"); + let _icx = push_ctxt("trans_assign_op"); let mut bcx = bcx; debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr)); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 913a857e0fb9..2d23942f601f 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -188,7 +188,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, needs_c_return: bool, arg_builder: wrap_arg_builder, ret_builder: wrap_ret_builder) { - let _icx = ccx.insn_ctxt("foreign::build_wrap_fn_"); + let _icx = push_ctxt("foreign::build_wrap_fn_"); let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None); // Patch up the return type if it's not immediate and we're returning via @@ -274,7 +274,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, pub fn trans_foreign_mod(ccx: @mut CrateContext, path: &ast_map::path, foreign_mod: &ast::foreign_mod) { - let _icx = ccx.insn_ctxt("foreign::trans_foreign_mod"); + let _icx = push_ctxt("foreign::trans_foreign_mod"); let arch = ccx.sess.targ_cfg.arch; let abi = match foreign_mod.abis.for_arch(arch) { @@ -370,11 +370,11 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, * } */ - let _icx = ccx.insn_ctxt("foreign::build_shim_fn"); + let _icx = push_ctxt("foreign::build_shim_fn"); fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) -> ~[ValueRef] { - let _icx = bcx.insn_ctxt("foreign::shim::build_args"); + let _icx = push_ctxt("foreign::shim::build_args"); tys.fn_ty.build_shim_args(bcx, tys.llsig.llarg_tys, llargbundle) } @@ -382,7 +382,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, tys: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::shim::build_ret"); + let _icx = push_ctxt("foreign::shim::build_ret"); tys.fn_ty.build_shim_ret(bcx, tys.llsig.llarg_tys, tys.ret_def, @@ -488,7 +488,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, * account for the Rust modes. */ - let _icx = ccx.insn_ctxt("foreign::build_wrap_fn"); + let _icx = push_ctxt("foreign::build_wrap_fn"); build_wrap_fn_(ccx, tys, @@ -503,7 +503,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, tys: &ShimTypes, llwrapfn: ValueRef, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::wrap::build_args"); + let _icx = push_ctxt("foreign::wrap::build_args"); let ccx = bcx.ccx(); let n = tys.llsig.llarg_tys.len(); for uint::range(0, n) |i| { @@ -528,7 +528,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, fn build_ret(bcx: block, shim_types: &ShimTypes, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::wrap::build_ret"); + let _icx = push_ctxt("foreign::wrap::build_ret"); let arg_count = shim_types.fn_sig.inputs.len(); for bcx.fcx.llretptr.iter().advance |&retptr| { let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]); @@ -1155,7 +1155,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, body: &ast::blk, llwrapfn: ValueRef, id: ast::node_id) { - let _icx = ccx.insn_ctxt("foreign::build_foreign_fn"); + let _icx = push_ctxt("foreign::build_foreign_fn"); fn build_rust_fn(ccx: @mut CrateContext, path: ast_map::path, @@ -1163,7 +1163,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, body: &ast::blk, id: ast::node_id) -> ValueRef { - let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn"); + let _icx = push_ctxt("foreign::foreign::build_rust_fn"); let t = ty::node_id_to_type(ccx.tcx, id); // XXX: Bad copy. let ps = link::mangle_internal_name_by_path( @@ -1205,11 +1205,11 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, * one of those types that is passed by pointer in Rust. */ - let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn"); + let _icx = push_ctxt("foreign::foreign::build_shim_fn"); fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) -> ~[ValueRef] { - let _icx = bcx.insn_ctxt("foreign::extern::shim::build_args"); + let _icx = push_ctxt("foreign::extern::shim::build_args"); let ccx = bcx.ccx(); let mut llargvals = ~[]; let mut i = 0u; @@ -1284,7 +1284,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, * } */ - let _icx = ccx.insn_ctxt("foreign::foreign::build_wrap_fn"); + let _icx = push_ctxt("foreign::foreign::build_wrap_fn"); build_wrap_fn_(ccx, tys, @@ -1299,7 +1299,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, tys: &ShimTypes, llwrapfn: ValueRef, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args"); + let _icx = push_ctxt("foreign::foreign::wrap::build_args"); tys.fn_ty.build_wrap_args(bcx, tys.llsig.llret_ty, llwrapfn, @@ -1307,7 +1307,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, } fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_ret"); + let _icx = push_ctxt("foreign::foreign::wrap::build_ret"); tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle); build_return(bcx); } @@ -1329,7 +1329,7 @@ pub fn register_foreign_fn(ccx: @mut CrateContext, node_id: ast::node_id, attrs: &[ast::attribute]) -> ValueRef { - let _icx = ccx.insn_ctxt("foreign::register_foreign_fn"); + let _icx = push_ctxt("foreign::register_foreign_fn"); let t = ty::node_id_to_type(ccx.tcx, node_id); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 294d56dcd766..127177118a07 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -45,7 +45,7 @@ use extra::time; use syntax::ast; pub fn trans_free(cx: block, v: ValueRef) -> block { - let _icx = cx.insn_ctxt("trans_free"); + let _icx = push_ctxt("trans_free"); callee::trans_lang_call(cx, cx.tcx().lang_items.free_fn(), [PointerCast(cx, v, Type::i8p())], @@ -53,7 +53,7 @@ pub fn trans_free(cx: block, v: ValueRef) -> block { } pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { - let _icx = cx.insn_ctxt("trans_exchange_free"); + let _icx = push_ctxt("trans_exchange_free"); callee::trans_lang_call(cx, cx.tcx().lang_items.exchange_free_fn(), [PointerCast(cx, v, Type::i8p())], @@ -62,7 +62,7 @@ pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("take_ty"); + let _icx = push_ctxt("take_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue); } @@ -71,7 +71,7 @@ pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("drop_ty"); + let _icx = push_ctxt("drop_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_drop_glue); } @@ -79,7 +79,7 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { } pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("drop_ty_immediate"); + let _icx = push_ctxt("drop_ty_immediate"); match ty::get(t).sty { ty::ty_uniq(_) | ty::ty_evec(_, ty::vstore_uniq) @@ -96,7 +96,7 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { } pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result { - let _icx = bcx.insn_ctxt("take_ty_immediate"); + let _icx = push_ctxt("take_ty_immediate"); match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | ty::ty_evec(_, ty::vstore_box) | @@ -117,7 +117,7 @@ pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result { pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("free_ty"); + let _icx = push_ctxt("free_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue); } @@ -125,7 +125,7 @@ pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { } pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("free_ty_immediate"); + let _icx = push_ctxt("free_ty_immediate"); match ty::get(t).sty { ty::ty_uniq(_) | ty::ty_evec(_, ty::vstore_uniq) | @@ -207,7 +207,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) -> bool { - let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue"); + let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue"); let simpl = simplified_glue_type(ccx.tcx, field, ti.ty); if simpl != ti.ty { let simpl_ti = get_tydesc(ccx, simpl); @@ -232,7 +232,7 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext, pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) { - let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue"); + let _icx = push_ctxt("lazily_emit_tydesc_glue"); let llfnty = type_of_glue_fn(ccx); if lazily_emit_simplified_tydesc_glue(ccx, field, ti) { @@ -300,7 +300,7 @@ pub fn call_tydesc_glue_full(bcx: block, tydesc: ValueRef, field: uint, static_ti: Option<@mut tydesc_info>) { - let _icx = bcx.insn_ctxt("call_tydesc_glue_full"); + let _icx = push_ctxt("call_tydesc_glue_full"); let ccx = bcx.ccx(); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. @@ -347,14 +347,14 @@ pub fn call_tydesc_glue_full(bcx: block, // See [Note-arg-mode] pub fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint) -> block { - let _icx = cx.insn_ctxt("call_tydesc_glue"); + let _icx = push_ctxt("call_tydesc_glue"); let ti = get_tydesc(cx.ccx(), t); call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti)); return cx; } pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("make_visit_glue"); + let _icx = push_ctxt("make_visit_glue"); let bcx = do with_scope(bcx, None, "visitor cleanup") |bcx| { let mut bcx = bcx; let (visitor_trait, object_ty) = ty::visitor_object_ty(bcx.tcx()); @@ -369,7 +369,7 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. - let _icx = bcx.insn_ctxt("make_free_glue"); + let _icx = push_ctxt("make_free_glue"); let ccx = bcx.ccx(); let bcx = match ty::get(t).sty { ty::ty_box(body_mt) => { @@ -461,7 +461,7 @@ pub fn trans_struct_drop(bcx: block, pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. - let _icx = bcx.insn_ctxt("make_drop_glue"); + let _icx = push_ctxt("make_drop_glue"); let ccx = bcx.ccx(); let bcx = match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | @@ -532,7 +532,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, box_ptr_ptr: Option, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("decr_refcnt_maybe_free"); + let _icx = push_ctxt("decr_refcnt_maybe_free"); let ccx = bcx.ccx(); do with_cond(bcx, IsNotNull(bcx, box_ptr)) |bcx| { @@ -551,7 +551,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("make_take_glue"); + let _icx = push_ctxt("make_take_glue"); // NB: v is a *pointer* to type t here, not a direct value. let bcx = match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | @@ -600,7 +600,7 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { } pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { - let _icx = cx.insn_ctxt("incr_refcnt_of_boxed"); + let _icx = push_ctxt("incr_refcnt_of_boxed"); let ccx = cx.ccx(); let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]); let rc = Load(cx, rc_ptr); @@ -650,7 +650,7 @@ pub type glue_helper = @fn(block, ValueRef, ty::t); pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: Type, name: ~str) -> ValueRef { - let _icx = ccx.insn_ctxt("declare_generic_glue"); + let _icx = push_ctxt("declare_generic_glue"); let name = name; let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed(); debug!("%s is for type %s", fn_nm, ppaux::ty_to_str(ccx.tcx, t)); @@ -665,7 +665,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, llfn: ValueRef, helper: glue_helper) -> ValueRef { - let _icx = ccx.insn_ctxt("make_generic_glue_inner"); + let _icx = push_ctxt("make_generic_glue_inner"); let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); ccx.stats.n_glues_created += 1u; @@ -695,7 +695,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext, helper: glue_helper, name: &str) -> ValueRef { - let _icx = ccx.insn_ctxt("make_generic_glue"); + let _icx = push_ctxt("make_generic_glue"); if !ccx.sess.trans_stats() { return make_generic_glue_inner(ccx, t, llfn, helper); } @@ -708,7 +708,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext, } pub fn emit_tydescs(ccx: &mut CrateContext) { - //let _icx = ccx.insn_ctxt("emit_tydescs"); + let _icx = push_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; let glue_fn_ty = Type::generic_glue_fn(ccx); diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 00afece91979..01849ac6e8f1 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -12,8 +12,7 @@ use core::prelude::*; use metadata::csearch; use middle::astencode; -use middle::trans::base::{get_insn_ctxt}; -use middle::trans::base::{impl_owned_self, impl_self, no_self}; +use middle::trans::base::{push_ctxt,impl_owned_self, impl_self, no_self}; use middle::trans::base::{trans_item, get_item_val, trans_fn}; use middle::trans::common::*; use middle::ty; @@ -30,7 +29,7 @@ use syntax::ast_util::local_def; pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, translate: bool) -> ast::def_id { - let _icx = ccx.insn_ctxt("maybe_instantiate_inline"); + let _icx = push_ctxt("maybe_instantiate_inline"); match ccx.external.find(&fn_id) { Some(&Some(node_id)) => { // Already inline diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 055e1ebbd371..3a8efb55c151 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @mut CrateContext, generics: &ast::Generics, self_ty: Option, id: ast::node_id) { - let _icx = ccx.insn_ctxt("impl::trans_impl"); + let _icx = push_ctxt("impl::trans_impl"); let tcx = ccx.tcx; debug!("trans_impl(path=%s, name=%s, self_ty=%s, id=%?)", @@ -159,7 +159,7 @@ pub fn trans_method(ccx: @mut CrateContext, pub fn trans_self_arg(bcx: block, base: @ast::expr, mentry: typeck::method_map_entry) -> Result { - let _icx = bcx.insn_ctxt("impl::trans_self_arg"); + let _icx = push_ctxt("impl::trans_self_arg"); let mut temp_cleanups = ~[]; // Compute the type of self. @@ -187,7 +187,7 @@ pub fn trans_method_callee(bcx: block, this: @ast::expr, mentry: typeck::method_map_entry) -> Callee { - let _icx = bcx.insn_ctxt("impl::trans_method_callee"); + let _icx = push_ctxt("impl::trans_method_callee"); let tcx = bcx.tcx(); debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)", @@ -293,7 +293,7 @@ pub fn trans_static_method_callee(bcx: block, trait_id: ast::def_id, callee_id: ast::node_id) -> FnData { - let _icx = bcx.insn_ctxt("impl::trans_static_method_callee"); + let _icx = push_ctxt("impl::trans_static_method_callee"); let ccx = bcx.ccx(); debug!("trans_static_method_callee(method_id=%?, trait_id=%s, \ @@ -437,7 +437,7 @@ pub fn trans_monomorphized_callee(bcx: block, n_method: uint, vtbl: typeck::vtable_origin) -> Callee { - let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee"); + let _icx = push_ctxt("impl::trans_monomorphized_callee"); return match vtbl { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { let ccx = bcx.ccx(); @@ -586,7 +586,7 @@ pub fn trans_trait_callee(bcx: block, // first evaluate the self expression (expected a by-ref result) and then // extract the self data and vtable out of the pair. - let _icx = bcx.insn_ctxt("impl::trans_trait_callee"); + let _icx = push_ctxt("impl::trans_trait_callee"); let mut bcx = bcx; let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr)); @@ -619,7 +619,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Same as `trans_trait_callee()` above, except that it is given // a by-ref pointer to the @Trait pair. - let _icx = bcx.insn_ctxt("impl::trans_trait_callee"); + let _icx = push_ctxt("impl::trans_trait_callee"); let ccx = bcx.ccx(); let mut bcx = bcx; @@ -770,7 +770,7 @@ pub fn make_vtable(ccx: @mut CrateContext, ptrs: &[ValueRef]) -> ValueRef { unsafe { - let _icx = ccx.insn_ctxt("impl::make_vtable"); + let _icx = push_ctxt("impl::make_vtable"); let mut components = ~[ tydesc.tydesc ]; for ptrs.each |&ptr| { @@ -797,7 +797,7 @@ pub fn make_impl_vtable(bcx: block, vtables: typeck::vtable_res) -> ValueRef { let ccx = bcx.ccx(); - let _icx = ccx.insn_ctxt("impl::make_impl_vtable"); + let _icx = push_ctxt("impl::make_impl_vtable"); let tcx = ccx.tcx; let trt_id = match ty::impl_trait_ref(tcx, impl_id) { @@ -841,7 +841,7 @@ pub fn trans_trait_cast(bcx: block, _store: ty::TraitStore) -> block { let mut bcx = bcx; - let _icx = bcx.insn_ctxt("impl::trans_cast"); + let _icx = push_ctxt("impl::trans_cast"); let lldest = match dest { Ignore => { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index f082150e3949..17605fdd5be6 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -13,9 +13,8 @@ use core::prelude::*; use back::link::mangle_exported_name; use driver::session; use lib::llvm::ValueRef; -use middle::trans::base::{get_insn_ctxt}; use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint}; -use middle::trans::base::{trans_enum_variant}; +use middle::trans::base::{trans_enum_variant,push_ctxt}; use middle::trans::base::{trans_fn, decl_internal_cdecl_fn}; use middle::trans::base::{get_item_val, no_self}; use middle::trans::base; @@ -61,6 +60,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, ref_id); assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); + let _icx = push_ctxt("monomorphic_fn"); let _icx = ccx.insn_ctxt("monomorphic_fn"); let mut must_cast = false; let substs = vec::map(real_substs.tps, |t| { diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 014c46b06e4a..d7c8c06c7071 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -53,7 +53,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { } pub fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::get_fill"); + let _icx = push_ctxt("tvec::get_fill"); Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])) } pub fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) { @@ -68,12 +68,12 @@ pub fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef { } pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::get_dataptr"); + let _icx = push_ctxt("tvec::get_dataptr"); GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u]) } pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::pointer_add"); + let _icx = push_ctxt("tvec::pointer_add"); let old_ty = val_ty(ptr); let bptr = PointerCast(bcx, ptr, Type::i8p()); return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty); @@ -81,7 +81,7 @@ pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { pub fn alloc_raw(bcx: block, unit_ty: ty::t, fill: ValueRef, alloc: ValueRef, heap: heap) -> Result { - let _icx = bcx.insn_ctxt("tvec::alloc_uniq"); + let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); @@ -105,7 +105,7 @@ pub fn alloc_vec(bcx: block, elts: uint, heap: heap) -> Result { - let _icx = bcx.insn_ctxt("tvec::alloc_uniq"); + let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); let llunitty = type_of::type_of(ccx, unit_ty); let unit_sz = nonzero_llsize_of(ccx, llunitty); @@ -119,7 +119,7 @@ pub fn alloc_vec(bcx: block, } pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("tvec::duplicate_uniq"); + let _icx = push_ctxt("tvec::duplicate_uniq"); let fill = get_fill(bcx, get_bodyptr(bcx, vptr)); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); @@ -137,7 +137,7 @@ pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> block { - let _icx = bcx.insn_ctxt("tvec::make_drop_glue_unboxed"); + let _icx = push_ctxt("tvec::make_drop_glue_unboxed"); let tcx = bcx.tcx(); let unit_ty = ty::sequence_element_type(tcx, vec_ty); if ty::type_needs_drop(tcx, unit_ty) { @@ -349,7 +349,7 @@ pub fn write_content(bcx: block, content_expr: @ast::expr, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("tvec::write_content"); + let _icx = push_ctxt("tvec::write_content"); let mut bcx = bcx; debug!("write_content(vt=%s, dest=%s, vstore_expr=%?)", @@ -548,7 +548,7 @@ pub type iter_vec_block<'self> = &'self fn(block, ValueRef, ty::t) -> block; pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, fill: ValueRef, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_raw"); + let _icx = push_ctxt("tvec::iter_vec_raw"); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); @@ -579,14 +579,14 @@ pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t, fill: ValueRef, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_uniq"); + let _icx = push_ctxt("tvec::iter_vec_uniq"); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr)); iter_vec_raw(bcx, data_ptr, vec_ty, fill, f) } pub fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_unboxed"); + let _icx = push_ctxt("tvec::iter_vec_unboxed"); let fill = get_fill(bcx, body_ptr); let dataptr = get_dataptr(bcx, body_ptr); return iter_vec_raw(bcx, dataptr, vec_ty, fill, f); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index 4ce2b780011e..d27d6efb2416 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -21,7 +21,7 @@ use middle::ty; pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) -> block { - let _icx = bcx.insn_ctxt("uniq::make_free_glue"); + let _icx = push_ctxt("uniq::make_free_glue"); let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); let not_null = IsNotNull(bcx, box_datum.val); @@ -38,7 +38,7 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) } pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("uniq::duplicate"); + let _icx = push_ctxt("uniq::duplicate"); // Load the body of the source (*src) let src_datum = immediate_rvalue(src_box, src_ty); From 761fc16c60507c1d8f1d56ccc3ae9b7fd4edbc54 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 18 Jun 2013 11:49:45 +1200 Subject: [PATCH 051/336] Fix-up PP Code to reflect new lifetime param syntax --- src/librustc/middle/mem_categorization.rs | 4 +- src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/ty.rs | 6 +- src/librustc/middle/typeck/check/mod.rs | 4 +- src/librustc/middle/typeck/check/regionck.rs | 6 +- .../middle/typeck/check/regionmanip.rs | 2 +- src/librustc/middle/typeck/infer/mod.rs | 2 +- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/util/ppaux.rs | 81 ++++++++++--------- src/test/compile-fail/regions-bounds.rs | 4 +- 10 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 297b454bd83a..ffb7a1daf359 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -50,7 +50,7 @@ use core::prelude::*; use middle::ty; use middle::typeck; -use util::ppaux::{ty_to_str, region_to_str, Repr}; +use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::common::indenter; use core::uint; @@ -1026,7 +1026,7 @@ impl mem_categorization_ctxt { } pub fn region_to_str(&self, r: ty::Region) -> ~str { - region_to_str(self.tcx, r) + region_ptr_to_str(self.tcx, r) } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 43d434b9d33d..269451b13070 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -693,7 +693,7 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui } /// Set current debug location at the beginning of the span -pub fn update_source_pos(bcx: @mut Block, span: span) { +pub fn update_source_pos(bcx: block, span: span) { if !bcx.sess().opts.debuginfo || (*span.lo == 0 && *span.hi == 0) { return; } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8595adcd1c73..e67955505f6d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -21,7 +21,7 @@ use middle::ty; use middle::subst::Subst; use middle::typeck; use middle; -use util::ppaux::{note_and_explain_region, bound_region_to_str}; +use util::ppaux::{note_and_explain_region, bound_region_to_str, bound_region_ptr_to_str}; use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str}; use util::ppaux::{Repr, UserString}; use util::common::{indenter}; @@ -3531,12 +3531,12 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { terr_regions_insufficiently_polymorphic(br, _) => { fmt!("expected bound lifetime parameter %s, \ but found concrete lifetime", - bound_region_to_str(cx, br)) + bound_region_ptr_to_str(cx, br)) } terr_regions_overly_polymorphic(br, _) => { fmt!("expected concrete lifetime, \ but found bound lifetime parameter %s", - bound_region_to_str(cx, br)) + bound_region_ptr_to_str(cx, br)) } terr_vstores_differ(k, ref values) => { fmt!("%s storage differs: expected %s but found %s", diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 1ac300271166..a8ae90414826 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -107,7 +107,7 @@ use middle::typeck::{isr_alist, lookup_def_ccx}; use middle::typeck::no_params; use middle::typeck::{require_same_types, method_map, vtable_map}; use util::common::{block_query, indenter, loop_query}; -use util::ppaux::{bound_region_to_str}; +use util::ppaux::{bound_region_to_str,bound_region_ptr_to_str}; use util::ppaux; @@ -680,7 +680,7 @@ impl FnCtxt { } else { result::Err(RegionError { msg: fmt!("named region `%s` not in scope here", - bound_region_to_str(self.tcx(), br)), + bound_region_ptr_to_str(self.tcx(), br)), replacement: self.infcx().next_region_var_nb(span) }) } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 4cedb71245a8..2ff8ffdd6b21 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -690,13 +690,13 @@ fn constrain_regions_in_type( let tcx = rcx.fcx.ccx.tcx; debug!("constrain_regions_in_type(minimum_lifetime=%s, ty=%s)", - region_to_str(tcx, minimum_lifetime), + region_to_str(tcx, "", false, minimum_lifetime), ty_to_str(tcx, ty)); do relate_nested_regions(tcx, Some(minimum_lifetime), ty) |r_sub, r_sup| { debug!("relate(r_sub=%s, r_sup=%s)", - region_to_str(tcx, r_sub), - region_to_str(tcx, r_sup)); + region_to_str(tcx, "", false, r_sub), + region_to_str(tcx, "", false, r_sup)); if r_sup.is_bound() || r_sub.is_bound() { // a bound region is one which appears inside an fn type. diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 9db873a25b0d..54b449eeb40f 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -149,7 +149,7 @@ pub fn replace_bound_regions_in_fn_sig( tcx.sess.bug( fmt!("Bound region not found in \ in_scope_regions list: %s", - region_to_str(tcx, r))); + region_to_str(tcx, "", false, r))); } } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 410e2fe23c10..2e83acfa9f4b 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -821,7 +821,7 @@ impl InferCtxt { // debug message. let rvar = self.next_region_var_nb(span); debug!("Bound region %s maps to %?", - bound_region_to_str(self.tcx, br), + bound_region_to_str(self.tcx, "", false, br), rvar); rvar }); diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index b0f055dc77d3..c5e0e2c8f016 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -179,7 +179,7 @@ impl Combine for Sub { None, b) |br| { let skol = self.infcx.region_vars.new_skolemized(br); debug!("Bound region %s skolemized to %?", - bound_region_to_str(self.infcx.tcx, br), + bound_region_to_str(self.infcx.tcx, "", false, br), skol); skol } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 05833a52be28..8994c81bfb96 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -112,7 +112,7 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) idx + 1), br_fresh(_) => fmt!("an anonymous lifetime defined on"), _ => fmt!("the lifetime %s as defined on", - bound_region_to_str(cx, fr.bound_region)) + bound_region_ptr_to_str(cx, fr.bound_region)) }; match cx.items.find(&fr.scope_id) { @@ -147,22 +147,23 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) } } -pub fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str { - bound_region_to_str_space(cx, "&", br) +pub fn bound_region_ptr_to_str(cx: ctxt, br: bound_region) -> ~str { + bound_region_to_str(cx, "&", true, br) } -pub fn bound_region_to_str_space(cx: ctxt, - prefix: &str, - br: bound_region) - -> ~str { - if cx.sess.verbose() { return fmt!("%s%? ", prefix, br); } +pub fn bound_region_to_str(cx: ctxt, + prefix: &str, space: bool, + br: bound_region) -> ~str { + let space_str = if space { " " } else { "" }; + + if cx.sess.verbose() { return fmt!("%s%?%s", prefix, br, space_str); } match br { - br_named(id) => fmt!("%s'%s ", prefix, cx.sess.str_of(id)), - br_self => fmt!("%s'self ", prefix), + br_named(id) => fmt!("%s'%s%s", prefix, cx.sess.str_of(id), space_str), + br_self => fmt!("%s'self%s", prefix, space_str), br_anon(_) => prefix.to_str(), br_fresh(_) => prefix.to_str(), - br_cap_avoid(_, br) => bound_region_to_str_space(cx, prefix, *br) + br_cap_avoid(_, br) => bound_region_to_str(cx, prefix, space, *br) } } @@ -208,13 +209,15 @@ pub fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str { // In general, if you are giving a region error message, // you should use `explain_region()` or, better yet, // `note_and_explain_region()` -pub fn region_to_str(cx: ctxt, region: Region) -> ~str { - region_to_str_space(cx, "&", region) +pub fn region_ptr_to_str(cx: ctxt, region: Region) -> ~str { + region_to_str(cx, "&", true, region) } -pub fn region_to_str_space(cx: ctxt, prefix: &str, region: Region) -> ~str { +pub fn region_to_str(cx: ctxt, prefix: &str, space: bool, region: Region) -> ~str { + let space_str = if space { " " } else { "" }; + if cx.sess.verbose() { - return fmt!("%s%? ", prefix, region); + return fmt!("%s%?%s", prefix, region, space_str); } // These printouts are concise. They do not contain all the information @@ -223,14 +226,14 @@ pub fn region_to_str_space(cx: ctxt, prefix: &str, region: Region) -> ~str { // `explain_region()` or `note_and_explain_region()`. match region { re_scope(_) => prefix.to_str(), - re_bound(br) => bound_region_to_str_space(cx, prefix, br), - re_free(ref fr) => bound_region_to_str_space(cx, prefix, fr.bound_region), + re_bound(br) => bound_region_to_str(cx, prefix, space, br), + re_free(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region), re_infer(ReSkolemized(_, br)) => { - bound_region_to_str_space(cx, prefix, br) + bound_region_to_str(cx, prefix, space, br) } re_infer(ReVar(_)) => prefix.to_str(), - re_static => fmt!("%s'static ", prefix), - re_empty => fmt!("%s' ", prefix) + re_static => fmt!("%s'static%s", prefix, space_str), + re_empty => fmt!("%s'%s", prefix, space_str) } } @@ -256,7 +259,7 @@ pub fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str { ty::vstore_fixed(n) => fmt!("%u", n), ty::vstore_uniq => ~"~", ty::vstore_box => ~"@", - ty::vstore_slice(r) => region_to_str_space(cx, "&", r) + ty::vstore_slice(r) => region_ptr_to_str(cx, r) } } @@ -264,7 +267,7 @@ pub fn trait_store_to_str(cx: ctxt, s: ty::TraitStore) -> ~str { match s { ty::UniqTraitStore => ~"~", ty::BoxTraitStore => ~"@", - ty::RegionTraitStore(r) => region_to_str_space(cx, "&", r) + ty::RegionTraitStore(r) => region_ptr_to_str(cx, r) } } @@ -340,7 +343,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { (ast::OwnedSigil, ty::re_static) => {} (_, region) => { - s.push_str(region_to_str_space(cx, "", region)); + s.push_str(region_to_str(cx, "", true, region)); } } @@ -414,7 +417,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_uniq(ref tm) => ~"~" + mt_to_str(cx, tm), ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm), ty_rptr(r, ref tm) => { - region_to_str_space(cx, "&", r) + mt_to_str(cx, tm) + region_ptr_to_str(cx, r) + mt_to_str(cx, tm) } ty_unboxed_vec(ref tm) => { fmt!("unboxed_vec<%s>", mt_to_str(cx, tm)) } ty_type => ~"type", @@ -431,13 +434,15 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_infer(infer_ty) => infer_ty.to_str(), ty_err => ~"[type error]", ty_param(param_ty {idx: id, def_id: did}) => { + let mut parm = (('T' as uint) + id) as char; + if (parm as uint) > ('Z' as uint) { + parm = (parm as uint - 26) as char; + } + if cx.sess.verbose() { - fmt!("'%s:%?", - str::from_bytes([('a' as u8) + (id as u8)]), - did) + fmt!("%c:%?", parm, did) } else { - fmt!("'%s", - str::from_bytes([('a' as u8) + (id as u8)])) + fmt!("%c", parm) } } ty_self(*) => ~"Self", @@ -468,18 +473,20 @@ pub fn parameterized(cx: ctxt, self_r: Option, tps: &[ty::t]) -> ~str { - let r_str = match self_r { - None => ~"", + let mut strs = ~[]; + match self_r { + None => (), Some(r) => { - region_to_str(cx, r) + strs.push(region_to_str(cx, "", false, r)) } }; - if tps.len() > 0u { - let strs = vec::map(tps, |t| ty_to_str(cx, *t)); - fmt!("%s%s<%s>", r_str, base, strs.connect(",")) + strs += vec::map(tps, |t| ty_to_str(cx, *t)); + + if strs.len() > 0u { + fmt!("%s<%s>", base, strs.connect(",")) } else { - fmt!("%s%s", r_str, base) + fmt!("%s", base) } } @@ -597,7 +604,7 @@ impl Repr for @ast::pat { impl Repr for ty::Region { fn repr(&self, tcx: ctxt) -> ~str { - region_to_str(tcx, *self) + region_to_str(tcx, "", false, *self) } } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index ab2620d46fdc..35ba38624380 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -16,11 +16,11 @@ struct an_enum<'self>(&'self int); struct a_class<'self> { x:&'self int } fn a_fn1<'a,'b>(e: an_enum<'a>) -> an_enum<'b> { - return e; //~ ERROR mismatched types: expected `an_enum/&'b ` but found `an_enum/&'a ` + return e; //~ ERROR mismatched types: expected `an_enum<'b>` but found `an_enum<'a>` } fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> { - return e; //~ ERROR mismatched types: expected `a_class/&'b ` but found `a_class/&'a ` + return e; //~ ERROR mismatched types: expected `a_class<'b>` but found `a_class<'a>` } fn a_fn4<'a,'b>() { From fb6dc957d6fcd64f01fbaf43ed9b059ae695e5b4 Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 21 Jun 2013 22:15:26 +1200 Subject: [PATCH 052/336] Remove remaining address space related code --- src/librustc/middle/trans/_match.rs | 8 ++------ src/librustc/middle/trans/base.rs | 25 +------------------------ src/librustc/middle/trans/glue.rs | 2 -- src/librustc/middle/trans/tvec.rs | 2 +- 4 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 958677eab4ae..a6e8cf666dae 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1389,9 +1389,7 @@ pub fn compile_submatch(bcx: block, if any_box_pat(m, col) { bcx = root_pats_as_necessary(bcx, m, col, val); let llbox = Load(bcx, val); - let box_no_addrspace = non_gc_box_cast(bcx, llbox); - let unboxed = - GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); + let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); compile_submatch(bcx, enter_box(bcx, dm, m, col, val), vec::append(~[unboxed], vals_left), chk); return; @@ -1399,9 +1397,7 @@ pub fn compile_submatch(bcx: block, if any_uniq_pat(m, col) { let llbox = Load(bcx, val); - let box_no_addrspace = non_gc_box_cast(bcx, llbox); - let unboxed = - GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); + let unboxed = 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; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index bd57a709a90b..7132af24d45a 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -279,18 +279,6 @@ pub fn malloc_raw_dyn(bcx: block, r } -/** -* Get the type of a box in the default address space. -* -* Shared box pointers live in address space 1 so the GC strategy can find -* them. Before taking a pointer to the inside of a box it should be cast into -* address space 0. Otherwise the resulting (non-box) pointer will be in the -* wrong address space and thus be the wrong type. -*/ -pub fn non_gc_box_cast(_: block, val: ValueRef) -> ValueRef { - val -} - // malloc_raw: expects an unboxed type and returns a pointer to // enough space for a box of that type. This includes a rust_opaque_box // header. @@ -312,8 +300,7 @@ pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> MallocResult { let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); - let non_gc_box = non_gc_box_cast(bcx, llbox); - let body = GEPi(bcx, non_gc_box, [0u, abi::box_field_body]); + let body = GEPi(bcx, llbox, [0u, abi::box_field_body]); MallocResult { bcx: bcx, box: llbox, body: body } } @@ -1829,16 +1816,6 @@ pub fn trans_closure(ccx: @mut CrateContext, set_fixed_stack_segment(fcx.llfn); } - // Set GC for function. - if ccx.sess.opts.gc { - do str::as_c_str("generic") |strategy| { - unsafe { - llvm::LLVMSetGC(fcx.llfn, strategy); - } - } - ccx.uses_gc = true; - } - // Create the first basic block in the function and keep a handle on it to // pass to finish_fn later. let bcx_top = top_scope_block(fcx, body.info()); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 127177118a07..b35ec1c09b43 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -375,8 +375,6 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_box(body_mt) => { let v = Load(bcx, v); let body = GEPi(bcx, v, [0u, abi::box_field_body]); - // Cast away the addrspace of the box pointer. - let body = PointerCast(bcx, body, type_of(ccx, body_mt.ty).ptr_to()); let bcx = drop_ty(bcx, body, body_mt.ty); trans_free(bcx, v) } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index d7c8c06c7071..d543b2cc61c0 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -64,7 +64,7 @@ pub fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef { } pub fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef { - base::non_gc_box_cast(bcx, GEPi(bcx, vptr, [0u, abi::box_field_body])) + GEPi(bcx, vptr, [0u, abi::box_field_body]) } pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef { From e3ef7504e9496f72820af55f8b9838ec0f54d9f0 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sat, 22 Jun 2013 13:41:52 +1200 Subject: [PATCH 053/336] Fix merge fallout --- src/librustc/middle/trans/cabi.rs | 1 - src/librustc/middle/trans/cabi_x86.rs | 2 +- src/librustc/middle/trans/closure.rs | 7 +++---- src/librustc/middle/trans/glue.rs | 1 - src/librustc/middle/trans/monomorphize.rs | 1 - src/librustc/middle/trans/type_of.rs | 2 +- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index dffa5a7f1ad0..4526af2da0f4 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -92,7 +92,6 @@ impl FnType { pub fn build_shim_ret(&self, bcx: block, arg_tys: &[Type], ret_def: bool, llargbundle: ValueRef, llretval: ValueRef) { - for vec::eachi(self.attrs) |i, a| { for self.attrs.iter().enumerate().advance |(i, a)| { match *a { option::Some(attr) => { diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index e2f4cef5a111..8131fd009eed 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -64,7 +64,7 @@ impl ABIInfo for X86_ABIInfo { } else if !ret_def { ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 613bd86ab918..4ab9cd6c9571 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -300,12 +300,11 @@ pub fn build_closure(bcx0: block, let ret_true = match bcx.fcx.loop_ret { Some((_, retptr)) => retptr, None => match bcx.fcx.llretptr { - None => C_null(T_ptr(T_nil())), - Some(retptr) => retptr, + None => C_null(Type::nil().ptr_to()), + Some(retptr) => PointerCast(bcx, retptr, Type::nil().ptr_to()), } }; - let ret_casted = PointerCast(bcx, ret_true, Type::nil().ptr_to()); - let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(), + let ret_datum = Datum {val: ret_true, ty: ty::mk_nil(), mode: ByRef(ZeroMem)}; env_vals.push(EnvValue {action: EnvRef, datum: ret_datum}); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index b35ec1c09b43..3e3fdf686e34 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -370,7 +370,6 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. let _icx = push_ctxt("make_free_glue"); - let ccx = bcx.ccx(); let bcx = match ty::get(t).sty { ty::ty_box(body_mt) => { let v = Load(bcx, v); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 17605fdd5be6..ac5f53c243ef 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -61,7 +61,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); let _icx = push_ctxt("monomorphic_fn"); - let _icx = ccx.insn_ctxt("monomorphic_fn"); let mut must_cast = false; let substs = vec::map(real_substs.tps, |t| { match normalize_for_monomorphization(ccx.tcx, *t) { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 5b85209219cd..448ded6b70f2 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -339,5 +339,5 @@ pub fn llvm_type_name(cx: &CrateContext, pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> Type { let self_ty = type_of(ccx, self_ty).ptr_to(); - Type::func([self_ty], Type::void()) + Type::func([self_ty], &Type::void()) } From dfc04e5edb5494f150019ad8cec31be0552e9c43 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Jun 2013 16:08:37 -0700 Subject: [PATCH 054/336] rustc: Fix formatting of --help --- src/librustc/rustc.rc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 021dd6648cbf..fcf75a581f85 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -140,10 +140,10 @@ pub fn version(argv0: &str) { pub fn usage(argv0: &str) { let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0); - io::println(fmt!("%s \ - Additional help: \ - -W help Print 'lint' options and default settings \ - -Z help Print internal options for debugging rustc", + io::println(fmt!("%s\ +Additional help: + -W help Print 'lint' options and default settings + -Z help Print internal options for debugging rustc\n", groups::usage(message, optgroups()))); } From de471a2eca15e6b9f3e4b81fc50d31b2ca9ee164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sat, 22 Jun 2013 09:37:40 +0200 Subject: [PATCH 055/336] Fix take glue of owned trait objects This finishes the incomplete conversion of unique traits as two-word allocations started in 211d038abc05c77785f72a31840016517cf218c2. Fixes #5882, #6717, #7153, #7208. --- src/librustc/back/abi.rs | 6 ++-- src/librustc/middle/trans/glue.rs | 19 ++++++++---- src/test/run-pass/owned-trait-objects.rs | 37 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 src/test/run-pass/owned-trait-objects.rs diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index e722e1a33c62..004170dea7fe 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -57,12 +57,10 @@ pub static n_tydesc_fields: uint = 8u; pub static fn_field_code: uint = 0u; pub static fn_field_box: uint = 1u; -// The three fields of a trait object/trait instance: vtable, box, and type -// description. +// The two fields of a trait object/trait instance: vtable and box. +// The vtable contains the type descriptor as first element. pub static trt_field_vtable: uint = 0u; pub static trt_field_box: uint = 1u; -// This field is only present in unique trait objects, so it comes last. -pub static trt_field_tydesc: uint = 2u; pub static vec_elt_fill: uint = 0u; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 3e3fdf686e34..e9febb51005c 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -40,7 +40,6 @@ use middle::trans::type_::Type; use core::io; use core::libc::c_uint; use core::str; -use core::vec; use extra::time; use syntax::ast; @@ -578,11 +577,19 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { bcx } ty::ty_trait(_, _, ty::UniqTraitStore, _) => { - let llval = GEPi(bcx, v, [0, abi::trt_field_box]); - let lltydesc = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_tydesc])); - call_tydesc_glue_full(bcx, llval, lltydesc, - abi::tydesc_field_take_glue, None); - bcx + let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]); + let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable])); + + // Cast the vtable to a pointer to a pointer to a tydesc. + let llvtable = PointerCast(bcx, llvtable, + bcx.ccx().tydesc_type.ptr_to().ptr_to()); + let lltydesc = Load(bcx, llvtable); + call_tydesc_glue_full(bcx, + lluniquevalue, + lltydesc, + abi::tydesc_field_take_glue, + None); + bcx } ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_take_glue(bcx, ck, v) diff --git a/src/test/run-pass/owned-trait-objects.rs b/src/test/run-pass/owned-trait-objects.rs new file mode 100644 index 000000000000..50b6666a20be --- /dev/null +++ b/src/test/run-pass/owned-trait-objects.rs @@ -0,0 +1,37 @@ +// 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. + +use std::uint::{range}; + +trait FooTrait { + fn foo(&self) -> uint; +} + +struct BarStruct { + x: uint +} + +impl FooTrait for BarStruct { + fn foo(&self) -> uint { + self.x + } +} + +pub fn main() { + let foos: ~[ ~FooTrait ] = ~[ + ~BarStruct{ x: 0 } as ~FooTrait, + ~BarStruct{ x: 1 } as ~FooTrait, + ~BarStruct{ x: 2 } as ~FooTrait + ]; + + for range(0, foos.len()) |i| { + assert_eq!(i, foos[i].foo()); + } +} From 9b2d9a9539d77695e915ebed189575d1249e7064 Mon Sep 17 00:00:00 2001 From: reus Date: Sat, 22 Jun 2013 17:49:32 +0800 Subject: [PATCH 056/336] replaced some 'std::' with 'extra::' in comments --- src/libextra/arc.rs | 2 +- src/libextra/base64.rs | 20 ++++++++++---------- src/libextra/future.rs | 2 +- src/libextra/net_ip.rs | 4 ++-- src/libstd/os.rs | 2 +- src/libstd/str.rs | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 661224b0a803..7746e0f06a65 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -19,7 +19,7 @@ * * ~~~ {.rust} * extern mod std; - * use std::arc; + * use extra::arc; * let numbers=vec::from_fn(100, |ind| (ind as float)*rand::random()); * let shared_numbers=arc::ARC(numbers); * diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index 5bf4dd517a5b..392e7ff29a22 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -36,8 +36,8 @@ impl<'self> ToBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * extern mod std; - * use std::base64::ToBase64; + * extern mod extra; + * use extra::base64::ToBase64; * * fn main () { * let str = [52,32].to_base64(); @@ -99,8 +99,8 @@ impl<'self> ToBase64 for &'self str { * # Example * * ~~~ {.rust} - * extern mod std; - * use std::base64::ToBase64; + * extern mod extra; + * use extra::base64::ToBase64; * * fn main () { * let str = "Hello, World".to_base64(); @@ -127,9 +127,9 @@ impl<'self> FromBase64 for &'self [u8] { * # Example * * ~~~ {.rust} - * extern mod std; - * use std::base64::ToBase64; - * use std::base64::FromBase64; + * extern mod extra; + * use extra::base64::ToBase64; + * use extra::base64::FromBase64; * * fn main () { * let str = [52,32].to_base64(); @@ -207,9 +207,9 @@ impl<'self> FromBase64 for &'self str { * This converts a string literal to base64 and back. * * ~~~ {.rust} - * extern mod std; - * use std::base64::ToBase64; - * use std::base64::FromBase64; + * extern mod extra; + * use extra::base64::ToBase64; + * use extra::base64::FromBase64; * use core::str; * * fn main () { diff --git a/src/libextra/future.rs b/src/libextra/future.rs index 4652e1d64770..030e63adca96 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -17,7 +17,7 @@ * ~~~ {.rust} * # fn fib(n: uint) -> uint {42}; * # fn make_a_sandwich() {}; - * let mut delayed_fib = std::future::spawn (|| fib(5000) ); + * let mut delayed_fib = extra::future::spawn (|| fib(5000) ); * make_a_sandwich(); * println(fmt!("fib(5000) = %?", delayed_fib.get())) * ~~~ diff --git a/src/libextra/net_ip.rs b/src/libextra/net_ip.rs index 91c357088c98..718da87af250 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net_ip.rs @@ -55,7 +55,7 @@ pub struct ParseAddrErr { * * # Arguments * - * * ip - a `std::net::ip::IpAddr` + * * ip - a `extra::net::ip::IpAddr` */ pub fn format_addr(ip: &IpAddr) -> ~str { match *ip { @@ -80,7 +80,7 @@ pub fn format_addr(ip: &IpAddr) -> ~str { * Get the associated port * * # Arguments - * * ip - a `std::net::ip::IpAddr` + * * ip - a `extra::net::ip::IpAddr` */ pub fn get_port(ip: &IpAddr) -> uint { match *ip { diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 59b40b93d4d1..dff72e844bf9 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1716,5 +1716,5 @@ mod tests { assert!(!os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); } - // More recursive_mkdir tests are in std::tempfile + // More recursive_mkdir tests are in extra::tempfile } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index f3226b27d1be..33380c9e1506 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -14,7 +14,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 std::rope. + * some heavy-duty uses, try extra::rope. */ use at_vec; From 30d755957a0f2cc3be3b355671da79cdf34fd50a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 17 Jun 2013 17:23:18 -0700 Subject: [PATCH 057/336] Expand the deriving(ToStr) implementation --- doc/rust.md | 4 +- src/libsyntax/ext/deriving/to_str.rs | 75 ++++++++++++++++++++++++---- src/test/run-pass/deriving-to-str.rs | 68 +++++++++++++------------ 3 files changed, 102 insertions(+), 45 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 9edbc44d6c21..4eedcb9a9520 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1562,7 +1562,9 @@ Supported traits for `deriving` are: * `IterBytes`, to iterate over the bytes in a data type. * `Rand`, to create a random instance of a data type. * `ToStr`, to convert to a string. For a type with this instance, - `obj.to_str()` has the same output as `fmt!("%?", obj)`. + `obj.to_str()` has similar output as `fmt!("%?", obj)`, but it differs in that + each constituent field of the type must also implement `ToStr` and will have + `field.to_str()` invoked to build up the result. # Statements and expressions diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index 41be3a775c16..4cd168b12c0c 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -10,6 +10,7 @@ use core::prelude::*; +use ast; use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; @@ -40,16 +41,68 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt, trait_def.expand(cx, span, mitem, in_items) } -fn to_str_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { - match substr.self_args { - [self_obj] => { - let self_addr = cx.expr_addr_of(span, self_obj); - cx.expr_call_global(span, - ~[cx.ident_of("std"), - cx.ident_of("sys"), - cx.ident_of("log_str")], - ~[self_addr]) +// It used to be the case that this deriving implementation invoked +// std::sys::log_str, but this isn't sufficient because it doesn't invoke the +// to_str() method on each field. Hence we mirror the logic of the log_str() +// method, but with tweaks to call to_str() on sub-fields. +fn to_str_substructure(cx: @ExtCtxt, span: span, + substr: &Substructure) -> @expr { + let to_str = cx.ident_of("to_str"); + + let doit = |start: &str, end: @str, name: ast::ident, + fields: &[(Option, @expr, ~[@expr])]| { + if fields.len() == 0 { + cx.expr_str_uniq(span, cx.str_of(name)) + } else { + let buf = cx.ident_of("buf"); + let start = cx.str_of(name) + start; + let init = cx.expr_str_uniq(span, start.to_managed()); + let mut stmts = ~[cx.stmt_let(span, true, buf, init)]; + let push_str = cx.ident_of("push_str"); + + let push = |s: @expr| { + let ebuf = cx.expr_ident(span, buf); + let call = cx.expr_method_call(span, ebuf, push_str, ~[s]); + stmts.push(cx.stmt_expr(call)); + }; + + for fields.iter().enumerate().advance |(i, &(name, e, _))| { + if i > 0 { + push(cx.expr_str(span, @", ")); + } + match name { + None => {} + Some(id) => { + let name = cx.str_of(id) + ": "; + push(cx.expr_str(span, name.to_managed())); + } + } + push(cx.expr_method_call(span, e, to_str, ~[])); + } + push(cx.expr_str(span, end)); + + cx.expr_blk(cx.blk(span, stmts, Some(cx.expr_ident(span, buf)))) } - _ => cx.span_bug(span, "Invalid number of arguments in `deriving(ToStr)`") - } + }; + + return match *substr.fields { + Struct(ref fields) => { + if fields.len() == 0 || fields[0].n0_ref().is_none() { + doit("(", @")", substr.type_ident, *fields) + } else { + doit("{", @"}", substr.type_ident, *fields) + } + } + + EnumMatching(_, variant, ref fields) => { + match variant.node.kind { + ast::tuple_variant_kind(*) => + doit("(", @")", variant.node.name, *fields), + ast::struct_variant_kind(*) => + doit("{", @"}", variant.node.name, *fields), + } + } + + _ => cx.bug("expected Struct or EnumMatching in deriving(ToStr)") + }; } diff --git a/src/test/run-pass/deriving-to-str.rs b/src/test/run-pass/deriving-to-str.rs index fcf0a009d9b2..1fc1d6815f5f 100644 --- a/src/test/run-pass/deriving-to-str.rs +++ b/src/test/run-pass/deriving-to-str.rs @@ -1,5 +1,4 @@ -// xfail-fast #6330 -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -9,39 +8,42 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rand; +#[deriving(ToStr)] +enum A {} +#[deriving(ToStr)] +enum B { B1, B2, B3 } +#[deriving(ToStr)] +enum C { C1(int), C2(B), C3(~str) } +#[deriving(ToStr)] +enum D { D1{ a: int } } +#[deriving(ToStr)] +struct E; +#[deriving(ToStr)] +struct F(int); +#[deriving(ToStr)] +struct G(int, int); +#[deriving(ToStr)] +struct H { a: int } +#[deriving(ToStr)] +struct I { a: int, b: int } +#[deriving(ToStr)] +struct J(Custom); -#[deriving(Rand,ToStr)] -struct A; - -#[deriving(Rand,ToStr)] -struct B(int, int); - -#[deriving(Rand,ToStr)] -struct C { - x: f64, - y: (u8, u8) -} - -#[deriving(Rand,ToStr)] -enum D { - D0, - D1(uint), - D2 { x: (), y: () } +struct Custom; +impl ToStr for Custom { + fn to_str(&self) -> ~str { ~"yay" } } fn main() { - macro_rules! t( - ($ty:ty) => {{ - let x =rand::random::<$ty>(); - assert_eq!(x.to_str(), fmt!("%?", x)); - }} - ); - - for 20.times { - t!(A); - t!(B); - t!(C); - t!(D); - } + assert_eq!(B1.to_str(), ~"B1"); + assert_eq!(B2.to_str(), ~"B2"); + assert_eq!(C1(3).to_str(), ~"C1(3)"); + assert_eq!(C2(B2).to_str(), ~"C2(B2)"); + assert_eq!(D1{ a: 2 }.to_str(), ~"D1{a: 2}"); + assert_eq!(E.to_str(), ~"E"); + assert_eq!(F(3).to_str(), ~"F(3)"); + assert_eq!(G(3, 4).to_str(), ~"G(3, 4)"); + assert_eq!(G(3, 4).to_str(), ~"G(3, 4)"); + assert_eq!(I{ a: 2, b: 4 }.to_str(), ~"I{a: 2, b: 4}"); + assert_eq!(J(Custom).to_str(), ~"J(yay)"); } From df626ea137af1436cb2e5eda19c145363db801c9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 18 Jun 2013 23:16:44 -0700 Subject: [PATCH 058/336] Fix compiling empty fmt! strings --- src/libsyntax/ext/fmt.rs | 5 +++++ src/test/run-pass/syntax-extension-fmt.rs | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 74496ac53598..4425d54987cd 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -249,6 +249,11 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, } } + /* Short circuit an easy case up front (won't work otherwise) */ + if pieces.len() == 0 { + return cx.expr_str_uniq(args[0].span, @""); + } + let fmt_sp = args[0].span; let mut n = 0u; let nargs = args.len(); diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs index 67573fce2cd2..fe7b510cfe78 100644 --- a/src/test/run-pass/syntax-extension-fmt.rs +++ b/src/test/run-pass/syntax-extension-fmt.rs @@ -58,6 +58,9 @@ fn part1() { test(fmt!("%x", 0xffffffff_u), ~"ffffffff"); test(fmt!("%o", 0xffffffff_u), ~"37777777777"); test(fmt!("%t", 0xffffffff_u), ~"11111111111111111111111111111111"); + + // Don't result in a compilation error + test(fmt!(""), ~""); } fn part2() { // Widths From 468cbd9d014d4f8610694057f1a8132f1eaf0b19 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 21 Jun 2013 06:12:01 -0400 Subject: [PATCH 059/336] iterator: add a size_hint default method also adds an implementation for the vector iterators --- src/libstd/iterator.rs | 49 ++++++++++++++++++++++++++++++++++++++++++ src/libstd/vec.rs | 27 +++++++++++++++++------ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 394066f1d4cf..fa27f4560c14 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -17,6 +17,8 @@ implementing the `Iterator` trait. */ +#[allow(default_methods)]; // solid enough for the use case here + use cmp; use iter::{FromIter, Times}; use num::{Zero, One}; @@ -31,6 +33,12 @@ use clone::Clone; pub trait Iterator { /// Advance the iterator and return the next value. Return `None` when the end is reached. fn next(&mut self) -> Option; + + /// 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. + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, Option) { (None, None) } } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -594,6 +602,27 @@ impl, U: Iterator> Iterator for ChainIterator { self.b.next() } } + + #[inline] + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, 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 upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(x + y), + _ => None + }; + + (lower, upper) + } } /// An iterator which iterates two other iterators simultaneously @@ -627,6 +656,12 @@ impl<'self, A, B, T: Iterator> Iterator for MapIterator<'self, A, B, T> { _ => None } } + + #[inline] + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, Option) { + self.iter.size_hint() + } } /// An iterator which filters the elements of `iter` with `predicate` @@ -647,6 +682,13 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } None } + + #[inline] + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, Option) { + let (_, upper) = self.iter.size_hint(); + (None, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which uses `f` to both filter and map elements from `iter` @@ -666,6 +708,13 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } None } + + #[inline] + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, Option) { + let (_, upper) = self.iter.size_hint(); + (None, upper) // can't know a lower bound, due to the predicate + } } /// An iterator which yields the current count and the element during iteration diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 703224e37c57..b03b6efcaaf3 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -29,6 +29,7 @@ use ptr::to_unsafe_ptr; use ptr; use ptr::RawPtr; use sys; +use sys::size_of; use uint; use unstable::intrinsics; use vec; @@ -2454,6 +2455,13 @@ macro_rules! iterator { } } } + + #[inline] + #[cfg(not(stage0))] + fn size_hint(&self) -> (Option, Option) { + let exact = Some(((self.end as uint) - (self.ptr as uint)) / size_of::<$elem>()); + (exact, exact) + } } } } @@ -3909,16 +3917,23 @@ mod tests { } #[test] + #[cfg(not(stage0))] fn test_iterator() { use iterator::*; let xs = [1, 2, 5, 10, 11]; - let ys = [1, 2, 5, 10, 11, 19]; let mut it = xs.iter(); - let mut i = 0; - for it.advance |&x| { - assert_eq!(x, ys[i]); - i += 1; - } + assert_eq!(it.size_hint(), (Some(5), Some(5))); + assert_eq!(it.next().unwrap(), &1); + assert_eq!(it.size_hint(), (Some(4), Some(4))); + assert_eq!(it.next().unwrap(), &2); + assert_eq!(it.size_hint(), (Some(3), Some(3))); + assert_eq!(it.next().unwrap(), &5); + assert_eq!(it.size_hint(), (Some(2), Some(2))); + assert_eq!(it.next().unwrap(), &10); + assert_eq!(it.size_hint(), (Some(1), Some(1))); + assert_eq!(it.next().unwrap(), &11); + assert_eq!(it.size_hint(), (Some(0), Some(0))); + assert!(it.next().is_none()); } #[test] From c9342663df3e705f6fe380f3d4f46c4a7be8035e Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 21 Jun 2013 07:57:22 -0400 Subject: [PATCH 060/336] iterator: add a FromIterator trait This is able to take advantage of the lower bound from the size hint. --- src/libstd/iterator.rs | 8 +++++++- src/libstd/vec.rs | 14 +++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index fa27f4560c14..46e059355941 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -27,6 +27,12 @@ use ops::{Add, Mul}; use cmp::Ord; use clone::Clone; +/// Conversion from an `Iterator` +pub trait FromIterator> { + /// Build a container with elements from an external iterator. + pub fn from_iterator(iterator: &mut T) -> Self; +} + /// An interface for dealing with "external iterators". These types of iterators /// can be resumed at any time as all state is stored internally as opposed to /// being located on the call stack. @@ -931,7 +937,7 @@ mod tests { #[test] fn test_counter_from_iter() { let mut it = Counter::new(0, 5).take_(10); - let xs: ~[int] = iter::FromIter::from_iter::(|f| it.advance(f)); + let xs: ~[int] = FromIterator::from_iterator(&mut it); assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index b03b6efcaaf3..62b42eebfbbd 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -19,7 +19,7 @@ use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use old_iter::BaseIter; use old_iter; -use iterator::{Iterator, IteratorUtil}; +use iterator::{FromIterator, Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; use libc; @@ -2511,6 +2511,18 @@ impl FromIter for ~[T]{ } } +#[cfg(not(stage0))] +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()); + for iterator.advance |x| { + xs.push(x); + } + xs + } +} + #[cfg(test)] mod tests { use option::{None, Option, Some}; From 0f55c9cc7ec4613bc3f85c25799b6020d57e7605 Mon Sep 17 00:00:00 2001 From: Steven Stewart-Gallus Date: Sat, 22 Jun 2013 18:58:41 -0700 Subject: [PATCH 061/336] Cleaned up middle a bit. The only really tricky change is that a long chain of ifs, and elses was turned into a single if, and a match in astencode.rs. Some methods can only be called in certain cases, and so have to come after the if. --- src/librustc/metadata/common.rs | 16 ++- src/librustc/middle/astencode.rs | 175 +++++++++++++++-------------- src/librustc/middle/check_const.rs | 29 ++--- src/librustc/middle/const_eval.rs | 71 +++--------- 4 files changed, 128 insertions(+), 163 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 9426cd6041d9..f487c73372fa 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -7,7 +7,8 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - +use core::prelude::*; +use core::cast; // EBML enum definitions and utils shared by the encoder and decoder @@ -111,6 +112,7 @@ pub static tag_items_data_item_reexport_def_id: uint = 0x4e; pub static tag_items_data_item_reexport_name: uint = 0x4f; // used to encode crate_ctxt side tables +#[deriving(Eq)] pub enum astencode_tag { // Reserves 0x50 -- 0x6f tag_ast = 0x50, @@ -136,6 +138,16 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f tag_table_moves_map = 0x63, tag_table_capture_map = 0x64 } +static first_astencode_tag : uint = tag_ast as uint; +static last_astencode_tag : uint = tag_table_capture_map as uint; +impl astencode_tag { + pub fn from_uint(value : uint) -> Option { + let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag; + if !is_a_tag { None } else { + Some(unsafe { cast::transmute(value as int) }) + } + } +} pub static tag_item_trait_method_sort: uint = 0x70; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 925b1f506d75..d405dc0bc207 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -319,15 +319,10 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { }); match *ii { - ast::ii_item(i) => { - ast::ii_item(fld.fold_item(i).get()) //hack: we're not dropping items - } - ast::ii_method(d, m) => { - ast::ii_method(d, fld.fold_method(m)) - } - ast::ii_foreign(i) => { - ast::ii_foreign(fld.fold_foreign_item(i)) - } + //hack: we're not dropping items + ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()), + ast::ii_method(d, m) => ast::ii_method(d, fld.fold_method(m)), + ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)) } } @@ -346,16 +341,10 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item) }); match ii { - ast::ii_item(i) => { - ast::ii_item(fld.fold_item(i).get()) - } - ast::ii_method(d, m) => { - ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m)) - } - ast::ii_foreign(i) => { - ast::ii_foreign(fld.fold_foreign_item(i)) - } - } + ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()), + ast::ii_method(d, m) => ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m)), + ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)), + } } // ______________________________________________________________________ @@ -374,22 +363,22 @@ fn decode_def(xcx: @ExtendedDecodeContext, doc: ebml::Doc) -> ast::def { impl tr for ast::def { fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::def { match *self { - ast::def_fn(did, p) => { ast::def_fn(did.tr(xcx), p) } + ast::def_fn(did, p) => ast::def_fn(did.tr(xcx), p), ast::def_static_method(did, did2_opt, p) => { ast::def_static_method(did.tr(xcx), did2_opt.map(|did2| did2.tr(xcx)), p) - } - ast::def_self_ty(nid) => { ast::def_self_ty(xcx.tr_id(nid)) } - ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) } - ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) } - ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) } - ast::def_const(did) => { ast::def_const(did.tr(xcx)) } - ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) } - ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) } + }, + ast::def_self_ty(nid) => ast::def_self_ty(xcx.tr_id(nid)), + ast::def_self(nid, i) => ast::def_self(xcx.tr_id(nid), i), + ast::def_mod(did) => ast::def_mod(did.tr(xcx)), + ast::def_foreign_mod(did) => ast::def_foreign_mod(did.tr(xcx)), + ast::def_const(did) => ast::def_const(did.tr(xcx)), + ast::def_arg(nid, b) => ast::def_arg(xcx.tr_id(nid), b), + ast::def_local(nid, b) => ast::def_local(xcx.tr_id(nid), b), ast::def_variant(e_did, v_did) => { ast::def_variant(e_did.tr(xcx), v_did.tr(xcx)) - } + }, ast::def_trait(did) => ast::def_trait(did.tr(xcx)), ast::def_ty(did) => ast::def_ty(did.tr(xcx)), ast::def_prim_ty(p) => ast::def_prim_ty(p), @@ -402,9 +391,7 @@ impl tr for ast::def { xcx.tr_id(nid2), xcx.tr_id(nid3)) } - ast::def_struct(did) => { - ast::def_struct(did.tr(xcx)) - } + ast::def_struct(did) => ast::def_struct(did.tr(xcx)), ast::def_region(nid) => ast::def_region(xcx.tr_id(nid)), ast::def_typaram_binder(nid) => { ast::def_typaram_binder(xcx.tr_id(nid)) @@ -419,12 +406,9 @@ impl tr for ast::def { impl tr for ty::AutoAdjustment { fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment { - match self { - &ty::AutoAddEnv(r, s) => { - ty::AutoAddEnv(r.tr(xcx), s) - } - - &ty::AutoDerefRef(ref adr) => { + match *self { + ty::AutoAddEnv(r, s) => ty::AutoAddEnv(r.tr(xcx), s), + ty::AutoDerefRef(ref adr) => { ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: adr.autoderefs, autoref: adr.autoref.map(|ar| ar.tr(xcx)), @@ -1110,56 +1094,75 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext, found for id %d (orig %d)", tag, id, id0); - if tag == (c::tag_table_moves_map as uint) { - dcx.maps.moves_map.insert(id); - } else { - let val_doc = entry_doc.get(c::tag_table_val as uint); - let mut val_dsr = reader::Decoder(val_doc); - let val_dsr = &mut val_dsr; - if tag == (c::tag_table_def as uint) { - let def = decode_def(xcx, val_doc); - dcx.tcx.def_map.insert(id, def); - } else if tag == (c::tag_table_node_type as uint) { - let ty = val_dsr.read_ty(xcx); - debug!("inserting ty for node %?: %s", - id, ty_to_str(dcx.tcx, ty)); - dcx.tcx.node_types.insert(id as uint, ty); - } else if tag == (c::tag_table_node_type_subst as uint) { - let tys = val_dsr.read_tys(xcx); - dcx.tcx.node_type_substs.insert(id, tys); - } else if tag == (c::tag_table_freevars as uint) { - let fv_info = @val_dsr.read_to_vec(|val_dsr| { - @val_dsr.read_freevar_entry(xcx) - }); - dcx.tcx.freevars.insert(id, fv_info); - } else if tag == (c::tag_table_tcache as uint) { - let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx); - let lid = ast::def_id { crate: ast::local_crate, node: id }; - dcx.tcx.tcache.insert(lid, tpbt); - } else if tag == (c::tag_table_param_defs as uint) { - let bounds = val_dsr.read_type_param_def(xcx); - dcx.tcx.ty_param_defs.insert(id, bounds); - } else if tag == (c::tag_table_method_map as uint) { - dcx.maps.method_map.insert( - id, - val_dsr.read_method_map_entry(xcx)); - } else if tag == (c::tag_table_vtable_map as uint) { - dcx.maps.vtable_map.insert(id, - val_dsr.read_vtable_res(xcx)); - } else if tag == (c::tag_table_adjustments as uint) { - let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr); - adj.tr(xcx); - dcx.tcx.adjustments.insert(id, adj); - } else if tag == (c::tag_table_capture_map as uint) { - let cvars = - at_vec::to_managed_consume( - val_dsr.read_to_vec( - |val_dsr| val_dsr.read_capture_var(xcx))); - dcx.maps.capture_map.insert(id, cvars); - } else { + match c::astencode_tag::from_uint(tag) { + None => { xcx.dcx.tcx.sess.bug( fmt!("unknown tag found in side tables: %x", tag)); } + Some(value) => if value == c::tag_table_moves_map { + dcx.maps.moves_map.insert(id); + } else { + let val_doc = entry_doc.get(c::tag_table_val as uint); + let mut val_dsr = reader::Decoder(val_doc); + let val_dsr = &mut val_dsr; + + match value { + c::tag_table_def => { + let def = decode_def(xcx, val_doc); + dcx.tcx.def_map.insert(id, def); + } + c::tag_table_node_type => { + let ty = val_dsr.read_ty(xcx); + debug!("inserting ty for node %?: %s", + id, ty_to_str(dcx.tcx, ty)); + dcx.tcx.node_types.insert(id as uint, ty); + } + c::tag_table_node_type_subst => { + let tys = val_dsr.read_tys(xcx); + dcx.tcx.node_type_substs.insert(id, tys); + } + c::tag_table_freevars => { + let fv_info = @val_dsr.read_to_vec(|val_dsr| { + @val_dsr.read_freevar_entry(xcx) + }); + dcx.tcx.freevars.insert(id, fv_info); + } + c::tag_table_tcache => { + let tpbt = val_dsr.read_ty_param_bounds_and_ty(xcx); + let lid = ast::def_id { crate: ast::local_crate, node: id }; + dcx.tcx.tcache.insert(lid, tpbt); + } + c::tag_table_param_defs => { + let bounds = val_dsr.read_type_param_def(xcx); + dcx.tcx.ty_param_defs.insert(id, bounds); + } + c::tag_table_method_map => { + dcx.maps.method_map.insert( + id, + val_dsr.read_method_map_entry(xcx)); + } + c::tag_table_vtable_map => { + dcx.maps.vtable_map.insert(id, + val_dsr.read_vtable_res(xcx)); + } + c::tag_table_adjustments => { + let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr); + adj.tr(xcx); + dcx.tcx.adjustments.insert(id, adj); + } + c::tag_table_capture_map => { + let cvars = + at_vec::to_managed_consume( + val_dsr.read_to_vec( + |val_dsr| val_dsr.read_capture_var(xcx))); + dcx.maps.capture_map.insert(id, cvars); + } + _ => { + xcx.dcx.tcx.sess.bug( + fmt!("unknown tag found in side tables: %x", tag)); + } + } + } } debug!(">< Side table doc loaded"); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 79fe6420e278..3722a5ba5a93 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -235,22 +235,17 @@ pub fn check_item_recursion(sess: Session, fn visit_expr(e: @expr, (env, v): (env, visit::vt)) { match e.node { - expr_path(*) => { - match env.def_map.find(&e.id) { - Some(&def_const(def_id)) => { - if ast_util::is_local(def_id) { - match env.ast_map.get_copy(&def_id.node) { - ast_map::node_item(it, _) => { - (v.visit_item)(it, (env, v)); - } - _ => fail!("const not bound to an item") - } - } - } - _ => () - } - } - _ => () + expr_path(*) => match env.def_map.find(&e.id) { + Some(&def_const(def_id)) if ast_util::is_local(def_id) => + match env.ast_map.get_copy(&def_id.node) { + ast_map::node_item(it, _) => { + (v.visit_item)(it, (env, v)); + } + _ => fail!("const not bound to an item") + }, + _ => () + }, + _ => () } visit::visit_expr(e, (env, v)); } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 988ad519f42b..78bc59c5647d 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -420,57 +420,18 @@ pub fn lit_to_const(lit: @lit) -> const_val { } } +fn compare_vals(a: T, b: T) -> Option { + Some(if a == b { 0 } else if a < b { -1 } else { 1 }) +} pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option { - match (a, b) { - (&const_int(a), &const_int(b)) => { - if a == b { - Some(0) - } else if a < b { - Some(-1) - } else { - Some(1) - } + match (a, b) { + (&const_int(a), &const_int(b)) => compare_vals(a, b), + (&const_uint(a), &const_uint(b)) => compare_vals(a, b), + (&const_float(a), &const_float(b)) => compare_vals(a, b), + (&const_str(a), &const_str(b)) => compare_vals(a, b), + (&const_bool(a), &const_bool(b)) => compare_vals(a, b), + _ => None } - (&const_uint(a), &const_uint(b)) => { - if a == b { - Some(0) - } else if a < b { - Some(-1) - } else { - Some(1) - } - } - (&const_float(a), &const_float(b)) => { - if a == b { - Some(0) - } else if a < b { - Some(-1) - } else { - Some(1) - } - } - (&const_str(ref a), &const_str(ref b)) => { - if (*a) == (*b) { - Some(0) - } else if (*a) < (*b) { - Some(-1) - } else { - Some(1) - } - } - (&const_bool(a), &const_bool(b)) => { - if a == b { - Some(0) - } else if a < b { - Some(-1) - } else { - Some(1) - } - } - _ => { - None - } - } } pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option { @@ -478,15 +439,9 @@ pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option Option { - match compare_lit_exprs(tcx, a, b) { - Some(val) => Some(val == 0), - None => None, - } + compare_lit_exprs(tcx, a, b).map(|&val| val == 0) } pub fn lit_eq(a: @lit, b: @lit) -> Option { - match compare_const_vals(&lit_to_const(a), &lit_to_const(b)) { - Some(val) => Some(val == 0), - None => None, - } + compare_const_vals(&lit_to_const(a), &lit_to_const(b)).map(|&val| val == 0) } From d2e9912aea87f9b1812a0f44e093c0405848f7ce Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 21 Jun 2013 08:29:53 -0400 Subject: [PATCH 062/336] vec: remove BaseIter implementation I removed the `static-method-test.rs` test because it was heavily based on `BaseIter` and there are plenty of other more complex uses of static methods anyway. --- doc/rust.md | 6 +- doc/tutorial.md | 8 +- src/compiletest/compiletest.rc | 7 +- src/compiletest/runtest.rs | 7 +- src/libextra/arc.rs | 7 +- src/libextra/fileinput.rs | 2 +- src/libextra/getopts.rs | 6 +- src/libextra/json.rs | 2 +- src/libextra/net_ip.rs | 2 +- src/libextra/net_url.rs | 4 +- src/libextra/num/bigint.rs | 38 ++++---- src/libextra/num/complex.rs | 16 ++-- src/libextra/num/rational.rs | 6 +- src/libextra/priority_queue.rs | 4 +- src/libextra/sha1.rs | 6 +- src/libextra/sort.rs | 2 +- src/libextra/stats.rs | 2 +- src/libextra/sync.rs | 10 +- src/libextra/task_pool.rs | 2 +- src/libextra/terminfo/searcher.rs | 2 +- src/libextra/test.rs | 6 +- src/libextra/time.rs | 20 ++-- src/libextra/timer.rs | 2 +- src/libextra/treemap.rs | 8 +- src/libextra/workcache.rs | 2 +- src/librust/rust.rc | 2 +- src/librustc/back/link.rs | 22 +++-- src/librustc/back/passes.rs | 16 ++-- src/librustc/back/rpath.rs | 6 +- src/librustc/driver/driver.rs | 12 +-- src/librustc/front/config.rs | 2 +- src/librustc/front/test.rs | 2 +- src/librustc/metadata/creader.rs | 13 +-- src/librustc/metadata/cstore.rs | 2 +- src/librustc/metadata/decoder.rs | 13 ++- src/librustc/metadata/encoder.rs | 55 +++++------ src/librustc/metadata/filesearch.rs | 5 +- src/librustc/metadata/loader.rs | 10 +- src/librustc/metadata/tyencode.rs | 8 +- src/librustc/middle/borrowck/check_loans.rs | 8 +- .../borrowck/gather_loans/gather_moves.rs | 2 +- .../middle/borrowck/gather_loans/mod.rs | 4 +- .../borrowck/gather_loans/restrictions.rs | 6 +- src/librustc/middle/borrowck/move_data.rs | 4 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_match.rs | 24 ++--- src/librustc/middle/dataflow.rs | 18 ++-- src/librustc/middle/entry.rs | 2 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/lint.rs | 42 +++++---- src/librustc/middle/liveness.rs | 14 +-- src/librustc/middle/mem_categorization.rs | 14 +-- src/librustc/middle/moves.rs | 16 ++-- src/librustc/middle/privacy.rs | 18 ++-- src/librustc/middle/region.rs | 10 +- src/librustc/middle/resolve.rs | 66 ++++++------- src/librustc/middle/trans/_match.rs | 40 ++++---- src/librustc/middle/trans/adt.rs | 2 +- src/librustc/middle/trans/asm.rs | 4 +- src/librustc/middle/trans/base.rs | 22 ++--- src/librustc/middle/trans/cabi_arm.rs | 2 +- src/librustc/middle/trans/cabi_mips.rs | 2 +- src/librustc/middle/trans/cabi_x86_64.rs | 6 +- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/closure.rs | 4 +- src/librustc/middle/trans/common.rs | 4 +- src/librustc/middle/trans/controlflow.rs | 4 +- src/librustc/middle/trans/debuginfo.rs | 4 +- src/librustc/middle/trans/expr.rs | 6 +- src/librustc/middle/trans/foreign.rs | 2 +- src/librustc/middle/trans/machine.rs | 2 +- src/librustc/middle/trans/meth.rs | 8 +- src/librustc/middle/trans/monomorphize.rs | 6 +- src/librustc/middle/trans/reachable.rs | 10 +- src/librustc/middle/trans/tvec.rs | 4 +- src/librustc/middle/trans/type_use.rs | 16 ++-- src/librustc/middle/ty.rs | 43 ++++----- src/librustc/middle/typeck/check/_match.rs | 20 ++-- src/librustc/middle/typeck/check/method.rs | 10 +- src/librustc/middle/typeck/check/mod.rs | 33 +++---- src/librustc/middle/typeck/check/regionck.rs | 16 ++-- .../middle/typeck/check/regionmanip.rs | 6 +- src/librustc/middle/typeck/check/vtable.rs | 2 +- src/librustc/middle/typeck/check/writeback.rs | 6 +- src/librustc/middle/typeck/coherence.rs | 24 +++-- src/librustc/middle/typeck/collect.rs | 14 +-- src/librustc/middle/typeck/infer/glb.rs | 2 +- .../middle/typeck/infer/region_inference.rs | 8 +- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/middle/typeck/infer/test.rs | 6 +- src/librustc/middle/typeck/rscope.rs | 2 +- src/librustc/rustc.rc | 8 +- src/librustc/util/ppaux.rs | 4 +- src/librustdoc/config.rs | 3 +- src/librustdoc/extract.rs | 2 +- src/librustdoc/markdown_pass.rs | 12 +-- src/librusti/program.rs | 6 +- src/librusti/rusti.rc | 10 +- src/librustpkg/package_source.rs | 4 +- src/librustpkg/path_util.rs | 7 +- src/librustpkg/tests.rs | 4 +- src/librustpkg/util.rs | 10 +- src/librustpkg/workspace.rs | 4 +- src/libstd/at_vec.rs | 7 +- src/libstd/either.rs | 8 +- src/libstd/hash.rs | 7 +- src/libstd/hashmap.rs | 5 +- src/libstd/io.rs | 18 ++-- src/libstd/iter.rs | 36 +++---- src/libstd/os.rs | 13 +-- src/libstd/path.rs | 9 +- src/libstd/rand.rs | 9 +- src/libstd/result.rs | 6 +- src/libstd/rt/uv/net.rs | 3 +- src/libstd/run.rs | 11 ++- src/libstd/str.rs | 10 +- src/libstd/str/ascii.rs | 3 +- src/libstd/to_bytes.rs | 5 +- src/libstd/to_str.rs | 8 +- src/libstd/trie.rs | 2 +- src/libstd/unstable/sync.rs | 2 +- src/libstd/vec.rs | 16 +--- src/libsyntax/abi.rs | 6 +- src/libsyntax/ast_map.rs | 12 +-- src/libsyntax/ast_util.rs | 16 ++-- src/libsyntax/attr.rs | 8 +- src/libsyntax/codemap.rs | 4 +- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/ext/bytes.rs | 2 +- src/libsyntax/ext/deriving/generic.rs | 6 +- src/libsyntax/ext/deriving/iter_bytes.rs | 2 +- src/libsyntax/ext/fmt.rs | 6 +- src/libsyntax/ext/pipes/pipec.rs | 6 +- src/libsyntax/ext/pipes/proto.rs | 4 +- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 8 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/opt_vec.rs | 2 +- src/libsyntax/parse/lexer.rs | 2 +- src/libsyntax/parse/parser.rs | 10 +- src/libsyntax/print/pprust.rs | 46 ++++----- src/libsyntax/util/interner.rs | 4 +- src/libsyntax/visit.rs | 60 ++++++------ src/test/auxiliary/cci_nested_lib.rs | 2 +- src/test/bench/graph500-bfs.rs | 6 +- src/test/bench/shootout-fasta-redux.rs | 4 +- src/test/bench/shootout-fasta.rs | 8 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- src/test/bench/shootout-pfib.rs | 2 +- .../compile-fail/borrowck-mut-boxed-vec.rs | 2 +- src/test/compile-fail/issue-2149.rs | 2 +- src/test/compile-fail/issue-2150.rs | 2 +- src/test/compile-fail/issue-5100.rs | 2 +- src/test/pretty/block-comment-wchar.pp | 2 +- src/test/pretty/block-comment-wchar.rs | 2 +- src/test/run-pass/block-iter-1.rs | 2 +- src/test/run-pass/block-iter-2.rs | 2 +- .../run-pass/borrowck-borrow-from-at-vec.rs | 2 +- .../borrowck-wg-borrow-mut-to-imm-3.rs | 2 +- src/test/run-pass/const-vec-of-fns.rs | 6 +- src/test/run-pass/explicit-self-closures.rs | 4 +- .../run-pass/fn-pattern-expected-type-2.rs | 2 +- src/test/run-pass/for-loop-fail.rs | 2 +- src/test/run-pass/hashmap-memory.rs | 2 +- src/test/run-pass/issue-2904.rs | 2 +- src/test/run-pass/issue-3389.rs | 2 +- src/test/run-pass/issue-3563-2.rs | 2 +- src/test/run-pass/issue-3563-3.rs | 68 +++++--------- src/test/run-pass/linear-for-loop.rs | 2 +- src/test/run-pass/loop-scope.rs | 2 +- src/test/run-pass/monad.rs | 2 +- src/test/run-pass/morestack6.rs | 2 +- ...ility-inherits-through-fixed-length-vec.rs | 2 +- src/test/run-pass/overload-index-operator.rs | 2 +- src/test/run-pass/packed-struct-vec.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 3 +- src/test/run-pass/shadow.rs | 14 +-- src/test/run-pass/static-impl.rs | 4 +- src/test/run-pass/static-method-test.rs | 94 ------------------- src/test/run-pass/task-comm-3.rs | 4 +- src/test/run-pass/trait-generic.rs | 2 +- 181 files changed, 796 insertions(+), 876 deletions(-) delete mode 100644 src/test/run-pass/static-method-test.rs diff --git a/doc/rust.md b/doc/rust.md index f533bb50f751..4c963c5ab7b6 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -882,11 +882,11 @@ the function name. ~~~~ {.xfail-test} fn iter(seq: &[T], f: &fn(T)) { - for seq.each |elt| { f(elt); } + for seq.iter().advance |elt| { f(elt); } } fn map(seq: &[T], f: &fn(T) -> U) -> ~[U] { let mut acc = ~[]; - for seq.each |elt| { acc.push(f(elt)); } + for seq.iter().advance |elt| { acc.push(f(elt)); } acc } ~~~~ @@ -2327,7 +2327,7 @@ An example of a for loop over the contents of a vector: let v: &[foo] = &[a, b, c]; -for v.each |e| { +for v.iter().advance |e| { bar(*e); } ~~~~ diff --git a/doc/tutorial.md b/doc/tutorial.md index ee01f2a5bdf9..9c61a04930ac 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1396,7 +1396,7 @@ assert!(!crayons.is_empty()); // Iterate over a vector, obtaining a pointer to each element // (`for` is explained in the next section) -for crayons.each |crayon| { +for crayons.iter().advance |crayon| { let delicious_crayon_wax = unwrap_crayon(*crayon); eat_crayon_wax(delicious_crayon_wax); } @@ -2119,7 +2119,7 @@ generic types. ~~~~ # trait Printable { fn print(&self); } fn print_all(printable_things: ~[T]) { - for printable_things.each |thing| { + for printable_things.iter().advance |thing| { thing.print(); } } @@ -2165,7 +2165,7 @@ However, consider this function: trait Drawable { fn draw(&self); } fn draw_all(shapes: ~[T]) { - for shapes.each |shape| { shape.draw(); } + for shapes.iter().advance |shape| { shape.draw(); } } # let c: Circle = new_circle(); # draw_all(~[c]); @@ -2180,7 +2180,7 @@ an _object_. ~~~~ # trait Drawable { fn draw(&self); } fn draw_all(shapes: &[@Drawable]) { - for shapes.each |shape| { shape.draw(); } + for shapes.iter().advance |shape| { shape.draw(); } } ~~~~ diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index e832534b227a..e8876c4851bc 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -208,7 +208,8 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] { debug!("making tests from %s", config.src_base.to_str()); let mut tests = ~[]; - for os::list_dir_path(&config.src_base).each |file| { + let dirs = os::list_dir_path(&config.src_base); + for dirs.iter().advance |file| { let file = copy *file; debug!("inspecting file %s", file.to_str()); if is_test(config, file) { @@ -230,11 +231,11 @@ pub fn is_test(config: &config, testfile: &Path) -> bool { let mut valid = false; - for valid_extensions.each |ext| { + for valid_extensions.iter().advance |ext| { if name.ends_with(*ext) { valid = true; } } - for invalid_prefixes.each |pre| { + for invalid_prefixes.iter().advance |pre| { if name.starts_with(*pre) { valid = false; } } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 71146c7e6658..fd56031ccf94 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -327,7 +327,7 @@ fn check_error_patterns(props: &TestProps, fatal_ProcRes(fmt!("error pattern '%s' not found!", missing_patterns[0]), ProcRes); } else { - for missing_patterns.each |pattern| { + for missing_patterns.iter().advance |pattern| { error(fmt!("error pattern '%s' not found!", *pattern)); } fatal_ProcRes(~"multiple error patterns not found", ProcRes); @@ -757,7 +757,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps, runargs.push(fmt!("%s", config.adb_test_dir)); runargs.push(fmt!("%s", prog_short)); - for args.args.each |tv| { + for args.args.iter().advance |tv| { runargs.push(tv.to_owned()); } @@ -822,7 +822,8 @@ fn _dummy_exec_compiled_test(config: &config, props: &TestProps, fn _arm_push_aux_shared_library(config: &config, testfile: &Path) { let tstr = aux_output_dir_name(config, testfile).to_str(); - for os::list_dir_path(&Path(tstr)).each |file| { + let dirs = os::list_dir_path(&Path(tstr)); + for dirs.iter().advance |file| { if (file.filetype() == Some(~".so")) { diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 661224b0a803..32114f4037ec 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -517,6 +517,7 @@ mod tests { use arc::*; + use core::vec; use core::cell::Cell; use core::comm; use core::task; @@ -725,7 +726,7 @@ mod tests { } // Wait for children to pass their asserts - for children.each |r| { + for children.iter().advance |r| { r.recv(); } @@ -790,7 +791,7 @@ mod tests { assert_eq!(*state, 42); *state = 31337; // send to other readers - for reader_convos.each |x| { + for vec::each(reader_convos) |x| { match *x { (ref rc, _) => rc.send(()), } @@ -799,7 +800,7 @@ mod tests { let read_mode = arc.downgrade(write_mode); do (&read_mode).read |state| { // complete handshake with other readers - for reader_convos.each |x| { + for vec::each(reader_convos) |x| { match *x { (_, ref rp) => rp.recv(), } diff --git a/src/libextra/fileinput.rs b/src/libextra/fileinput.rs index 46646e2af563..7a1e925a15dc 100644 --- a/src/libextra/fileinput.rs +++ b/src/libextra/fileinput.rs @@ -421,7 +421,7 @@ mod test { fn make_file(path : &Path, contents: &[~str]) { let file = io::file_writer(path, [io::Create, io::Truncate]).get(); - for contents.each |&str| { + for contents.iter().advance |&str| { file.write_str(str); file.write_char('\n'); } diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 5980bd7c9e47..d97804722f25 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -295,7 +295,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result { } } let mut name_pos = 0; - for names.each() |nm| { + for names.iter().advance() |nm| { name_pos += 1; let optid = match find_opt(opts, copy *nm) { Some(id) => id, @@ -373,7 +373,7 @@ pub fn opt_count(mm: &Matches, nm: &str) -> uint { /// Returns true if any of several options were matched pub fn opts_present(mm: &Matches, names: &[~str]) -> bool { - for names.each |nm| { + for names.iter().advance |nm| { match find_opt(mm.opts, mkname(*nm)) { Some(id) if !mm.vals[id].is_empty() => return true, _ => (), @@ -400,7 +400,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str { * option took an argument */ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str { - for names.each |nm| { + for names.iter().advance |nm| { match opt_val(mm, *nm) { Val(ref s) => return copy *s, _ => () diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 0bbccd4df4a0..24c4c5b27c49 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -1385,7 +1385,7 @@ mod tests { fn mk_object(items: &[(~str, Json)]) -> Json { let mut d = ~HashMap::new(); - for items.each |item| { + for items.iter().advance |item| { match *item { (ref key, ref value) => { d.insert(copy *key, copy *value); }, } diff --git a/src/libextra/net_ip.rs b/src/libextra/net_ip.rs index 91c357088c98..1d0b9829242d 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net_ip.rs @@ -426,7 +426,7 @@ mod test { let results = result::unwrap(ga_result); debug!("test_get_addr: Number of results for %s: %?", localhost_name, results.len()); - for results.each |r| { + for results.iter().advance |r| { let ipv_prefix = match *r { Ipv4(_) => ~"IPv4", Ipv6(_) => ~"IPv6" diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index 289f3888f638..dda4b85df4bf 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -210,7 +210,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str { for m.each |key, values| { let key = encode_plus(*key); - for values.each |value| { + for values.iter().advance |value| { if first { first = false; } else { @@ -342,7 +342,7 @@ fn query_from_str(rawquery: &str) -> Query { pub fn query_to_str(query: &Query) -> ~str { let mut strvec = ~[]; - for query.each |kv| { + for query.iter().advance |kv| { match kv { &(ref k, ref v) => { strvec.push(fmt!("%s=%s", diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 7ec2bd8b9b6f..4b080e0153cc 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -1349,7 +1349,7 @@ mod biguint_tests { #[test] fn test_add() { - for sum_triples.each |elm| { + for sum_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1362,7 +1362,7 @@ mod biguint_tests { #[test] fn test_sub() { - for sum_triples.each |elm| { + for sum_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1413,7 +1413,7 @@ mod biguint_tests { #[test] fn test_mul() { - for mul_triples.each |elm| { + for mul_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1423,7 +1423,7 @@ mod biguint_tests { assert!(b * a == c); } - for div_rem_quadruples.each |elm| { + for div_rem_quadruples.iter().advance |elm| { let (aVec, bVec, cVec, dVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1437,7 +1437,7 @@ mod biguint_tests { #[test] fn test_div_rem() { - for mul_triples.each |elm| { + for mul_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1451,7 +1451,7 @@ mod biguint_tests { } } - for div_rem_quadruples.each |elm| { + for div_rem_quadruples.iter().advance |elm| { let (aVec, bVec, cVec, dVec) = *elm; let a = BigUint::from_slice(aVec); let b = BigUint::from_slice(bVec); @@ -1567,9 +1567,10 @@ mod biguint_tests { #[test] fn test_to_str_radix() { - for to_str_pairs().each |num_pair| { + let r = to_str_pairs(); + for r.iter().advance |num_pair| { let &(n, rs) = num_pair; - for rs.each |str_pair| { + for rs.iter().advance |str_pair| { let &(radix, str) = str_pair; assert_eq!(n.to_str_radix(radix), str); } @@ -1578,9 +1579,10 @@ mod biguint_tests { #[test] fn test_from_str_radix() { - for to_str_pairs().each |num_pair| { + let r = to_str_pairs(); + for r.iter().advance |num_pair| { let &(n, rs) = num_pair; - for rs.each |str_pair| { + for rs.iter().advance |str_pair| { let &(radix, str) = str_pair; assert_eq!(&n, &FromStrRadix::from_str_radix(str, radix).get()); } @@ -1756,7 +1758,7 @@ mod bigint_tests { #[test] fn test_add() { - for sum_triples.each |elm| { + for sum_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1775,7 +1777,7 @@ mod bigint_tests { #[test] fn test_sub() { - for sum_triples.each |elm| { + for sum_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1832,7 +1834,7 @@ mod bigint_tests { #[test] fn test_mul() { - for mul_triples.each |elm| { + for mul_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1845,7 +1847,7 @@ mod bigint_tests { assert!((-b) * a == -c); } - for div_rem_quadruples.each |elm| { + for div_rem_quadruples.iter().advance |elm| { let (aVec, bVec, cVec, dVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1884,7 +1886,7 @@ mod bigint_tests { } } - for mul_triples.each |elm| { + for mul_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1894,7 +1896,7 @@ mod bigint_tests { if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); } } - for div_rem_quadruples.each |elm| { + for div_rem_quadruples.iter().advance |elm| { let (aVec, bVec, cVec, dVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1927,7 +1929,7 @@ mod bigint_tests { check_sub(&a.neg(), b, &q.neg(), &r.neg()); check_sub(&a.neg(), &b.neg(), q, &r.neg()); } - for mul_triples.each |elm| { + for mul_triples.iter().advance |elm| { let (aVec, bVec, cVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); @@ -1937,7 +1939,7 @@ mod bigint_tests { if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); } } - for div_rem_quadruples.each |elm| { + for div_rem_quadruples.iter().advance |elm| { let (aVec, bVec, cVec, dVec) = *elm; let a = BigInt::from_slice(Plus, aVec); let b = BigInt::from_slice(Plus, bVec); diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index c626260043ee..3a63549cf3ac 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -238,14 +238,14 @@ mod test { fn test_scale_unscale() { assert_eq!(_05_05i.scale(2f), _1_1i); assert_eq!(_1_1i.unscale(2f), _05_05i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(c.scale(2f).unscale(2f), c); } } #[test] fn test_conj() { - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(c.conj(), Cmplx::new(c.re, -c.im)); assert_eq!(c.conj().conj(), c); } @@ -282,7 +282,7 @@ mod test { let (r, theta) = c.to_polar(); assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6); } - for all_consts.each |&c| { test(c); } + for all_consts.iter().advance |&c| { test(c); } } mod arith { @@ -295,7 +295,7 @@ mod test { assert_eq!(_0_1i + _1_0i, _1_1i); assert_eq!(_1_0i + _neg1_1i, _0_1i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(_0_0i + c, c); assert_eq!(c + _0_0i, c); } @@ -307,7 +307,7 @@ mod test { assert_eq!(_0_1i - _1_0i, _neg1_1i); assert_eq!(_0_1i - _neg1_1i, _1_0i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(c - _0_0i, c); assert_eq!(c - c, _0_0i); } @@ -322,7 +322,7 @@ mod test { assert_eq!(_0_1i * _0_1i, -_1_0i); assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(c * _1_0i, c); assert_eq!(_1_0i * c, c); } @@ -330,7 +330,7 @@ mod test { #[test] fn test_div() { assert_eq!(_neg1_1i / _0_1i, _1_1i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { if c != Zero::zero() { assert_eq!(c / c, _1_0i); } @@ -340,7 +340,7 @@ mod test { fn test_neg() { assert_eq!(-_1_0i + _0_1i, _neg1_1i); assert_eq!((-_0_1i) * _0_1i, _1_0i); - for all_consts.each |&c| { + for all_consts.iter().advance |&c| { assert_eq!(-(-c), c); } } diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs index b2b966928e9a..339d35e25936 100644 --- a/src/libextra/num/rational.rs +++ b/src/libextra/num/rational.rs @@ -482,7 +482,8 @@ mod test { assert_eq!(FromStr::from_str::(s), None); } - for ["0 /1", "abc", "", "1/", "--1/2","3/2/1"].each |&s| { + let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"]; + for xs.iter().advance |&s| { test(s); } } @@ -521,7 +522,8 @@ mod test { assert_eq!(FromStrRadix::from_str_radix::(s, 3), None); } - for ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"].each |&s| { + let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"]; + for xs.iter().advance |&s| { test(s); } } diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index efbf23f11b15..31c9acbbd54d 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -28,9 +28,9 @@ impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. - fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) } + fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.iter().advance(f) } - fn size_hint(&self) -> Option { self.data.size_hint() } + fn size_hint(&self) -> Option { Some(self.data.len()) } } impl Container for PriorityQueue { diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs index 78c4f5f13ec8..84b48c87890b 100644 --- a/src/libextra/sha1.rs +++ b/src/libextra/sha1.rs @@ -250,7 +250,7 @@ pub fn sha1() -> @Sha1 { fn result_str(&mut self) -> ~str { let rr = mk_result(self); let mut s = ~""; - for rr.each |b| { + for rr.iter().advance |b| { let hex = uint::to_str_radix(*b as uint, 16u); if hex.len() == 1 { s += "0"; @@ -375,7 +375,7 @@ mod tests { // Test that it works when accepting the message all at once let mut sh = sha1::sha1(); - for tests.each |t| { + for tests.iter().advance |t| { sh.input_str(t.input); let out = sh.result(); check_vec_eq(copy t.output, out); @@ -389,7 +389,7 @@ mod tests { // Test that it works when accepting the message in pieces - for tests.each |t| { + for tests.iter().advance |t| { let len = t.input.len(); let mut left = len; while left > 0u { diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index df5e8b2f176e..ae2a5c01993d 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -846,7 +846,7 @@ mod test_qsort { let immut_names = names; let pairs = vec::zip_slice(expected, immut_names); - for pairs.each |p| { + for pairs.iter().advance |p| { let (a, b) = *p; debug!("%d %d", a, b); assert_eq!(a, b); diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 3a1de5de01d6..69f75037c7e4 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -72,7 +72,7 @@ impl<'self> Stats for &'self [f64] { } else { let mean = self.mean(); let mut v = 0.0; - for self.each |s| { + for self.iter().advance |s| { let x = *s - mean; v += x*x; } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index f5d0b6946d33..6990d35f0613 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -994,13 +994,13 @@ mod tests { } // wait until all children get in the mutex - for ports.each |port| { let _ = port.recv(); } + for ports.iter().advance |port| { let _ = port.recv(); } do m.lock_cond |cond| { let num_woken = cond.broadcast(); assert_eq!(num_woken, num_waiters); } // wait until all children wake up - for ports.each |port| { let _ = port.recv(); } + for ports.iter().advance |port| { let _ = port.recv(); } } #[test] fn test_mutex_cond_broadcast() { @@ -1085,7 +1085,7 @@ mod tests { } } } - for sibling_convos.each |p| { + for sibling_convos.iter().advance |p| { let _ = p.recv(); // wait for sibling to get in the mutex } do m2.lock { } @@ -1361,13 +1361,13 @@ mod tests { } // wait until all children get in the mutex - for ports.each |port| { let _ = port.recv(); } + for ports.iter().advance |port| { let _ = port.recv(); } do lock_cond(x, dg2) |cond| { let num_woken = cond.broadcast(); assert_eq!(num_woken, num_waiters); } // wait until all children wake up - for ports.each |port| { let _ = port.recv(); } + for ports.iter().advance |port| { let _ = port.recv(); } } #[test] fn test_rwlock_cond_broadcast() { diff --git a/src/libextra/task_pool.rs b/src/libextra/task_pool.rs index b88bbff2a666..643081d4a7ad 100644 --- a/src/libextra/task_pool.rs +++ b/src/libextra/task_pool.rs @@ -36,7 +36,7 @@ pub struct TaskPool { #[unsafe_destructor] impl Drop for TaskPool { fn finalize(&self) { - for self.channels.each |channel| { + for self.channels.iter().advance |channel| { channel.send(Quit); } } diff --git a/src/libextra/terminfo/searcher.rs b/src/libextra/terminfo/searcher.rs index f82514475722..da12a1c4203f 100644 --- a/src/libextra/terminfo/searcher.rs +++ b/src/libextra/terminfo/searcher.rs @@ -55,7 +55,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~path> { }; // Look for the terminal in all of the search directories - for dirs_to_search.each |p| { + for dirs_to_search.iter().advance |p| { let newp = ~p.push_many(&[str::from_char(first_char), term.to_owned()]); if os::path_exists(p) && os::path_exists(newp) { return Some(newp); diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 72837cb4ae1f..e058a098fa49 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -369,7 +369,7 @@ fn print_failures(st: &ConsoleTestState) { failures.push(name.to_str()); } sort::tim_sort(failures); - for failures.each |name| { + for failures.iter().advance |name| { st.out.write_line(fmt!(" %s", name.to_str())); } } @@ -947,7 +947,7 @@ mod tests { { fn testfn() { } let mut tests = ~[]; - for names.each |name| { + for names.iter().advance |name| { let test = TestDescAndFn { desc: TestDesc { name: DynTestName(copy *name), @@ -973,7 +973,7 @@ mod tests { let pairs = vec::zip(expected, filtered); - for pairs.each |p| { + for pairs.iter().advance |p| { match *p { (ref a, ref b) => { assert!(*a == b.desc.name.to_str()); diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 005238a564e8..ef156ccfb45f 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -1033,7 +1033,7 @@ mod tests { } } - for [ + let days = [ ~"Sunday", ~"Monday", ~"Tuesday", @@ -1041,11 +1041,12 @@ mod tests { ~"Thursday", ~"Friday", ~"Saturday" - ].each |day| { + ]; + for days.iter().advance |day| { assert!(test(*day, "%A")); } - for [ + let days = [ ~"Sun", ~"Mon", ~"Tue", @@ -1053,11 +1054,12 @@ mod tests { ~"Thu", ~"Fri", ~"Sat" - ].each |day| { + ]; + for days.iter().advance |day| { assert!(test(*day, "%a")); } - for [ + let months = [ ~"January", ~"February", ~"March", @@ -1070,11 +1072,12 @@ mod tests { ~"October", ~"November", ~"December" - ].each |day| { + ]; + for months.iter().advance |day| { assert!(test(*day, "%B")); } - for [ + let months = [ ~"Jan", ~"Feb", ~"Mar", @@ -1087,7 +1090,8 @@ mod tests { ~"Oct", ~"Nov", ~"Dec" - ].each |day| { + ]; + for months.iter().advance |day| { assert!(test(*day, "%b")); } diff --git a/src/libextra/timer.rs b/src/libextra/timer.rs index 7a4ad34b5089..71d8a5d81e7e 100644 --- a/src/libextra/timer.rs +++ b/src/libextra/timer.rs @@ -217,7 +217,7 @@ mod test { for repeat.times { let ch = ch.clone(); - for spec.each |spec| { + for spec.iter().advance |spec| { let (times, maxms) = *spec; let ch = ch.clone(); let hl_loop_clone = hl_loop.clone(); diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 97b459bcc9ed..87932c25cda1 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -781,13 +781,13 @@ mod test_treemap { fn check_equal(ctrl: &[(K, V)], map: &TreeMap) { assert_eq!(ctrl.is_empty(), map.is_empty()); - for ctrl.each |x| { + for ctrl.iter().advance |x| { let &(k, v) = x; assert!(map.find(&k).unwrap() == &v) } for map.each |map_k, map_v| { let mut found = false; - for ctrl.each |x| { + for ctrl.iter().advance |x| { let &(ctrl_k, ctrl_v) = x; if *map_k == ctrl_k { assert!(*map_v == ctrl_v); @@ -1135,8 +1135,8 @@ mod test_set { let mut set_a = TreeSet::new(); let mut set_b = TreeSet::new(); - for a.each |x| { assert!(set_a.insert(*x)) } - for b.each |y| { assert!(set_b.insert(*y)) } + for a.iter().advance |x| { assert!(set_a.insert(*x)) } + for b.iter().advance |y| { assert!(set_b.insert(*y)) } let mut i = 0; for f(&set_a, &set_b) |x| { diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 12a26606f36e..63c89ebf5865 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -157,7 +157,7 @@ impl Decodable for WorkMap { fn decode(d: &mut D) -> WorkMap { let v : ~[(WorkKey,~str)] = Decodable::decode(d); let mut w = WorkMap::new(); - for v.each |&(k, v)| { + for v.iter().advance |&(k, v)| { w.insert(copy k, copy v); } w diff --git a/src/librust/rust.rc b/src/librust/rust.rc index cf705d722535..68427745ff59 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -222,7 +222,7 @@ fn usage() { \n" ); - for commands.each |command| { + for commands.iter().advance |command| { let padding = " ".repeat(indent - command.cmd.len()); io::println(fmt!(" %s%s%s", command.cmd, padding, command.usage_line)); diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 5df63d650e90..01ad3507b83e 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -124,7 +124,8 @@ pub mod jit { // incase the user wants to use an older extra library. let cstore = sess.cstore; - for cstore::get_used_crate_files(cstore).each |cratepath| { + let r = cstore::get_used_crate_files(cstore); + for r.iter().advance |cratepath| { let path = cratepath.to_str(); debug!("linking: %s", path); @@ -470,7 +471,7 @@ pub fn build_link_meta(sess: Session, let mut cmh_items = ~[]; let linkage_metas = attr::find_linkage_metas(c.node.attrs); attr::require_unique_names(sess.diagnostic(), linkage_metas); - for linkage_metas.each |meta| { + for linkage_metas.iter().advance |meta| { match attr::get_meta_item_value_str(*meta) { Some(value) => { let item_name : &str = attr::get_meta_item_name(*meta); @@ -518,7 +519,7 @@ pub fn build_link_meta(sess: Session, } ast::meta_list(name, ref mis) => { write_string(symbol_hasher, len_and_str(name)); - for mis.each |m_| { + for mis.iter().advance |m_| { hash(symbol_hasher, m_); } } @@ -526,11 +527,11 @@ pub fn build_link_meta(sess: Session, } symbol_hasher.reset(); - for cmh_items.each |m| { + for cmh_items.iter().advance |m| { hash(symbol_hasher, m); } - for dep_hashes.each |dh| { + for dep_hashes.iter().advance |dh| { write_string(symbol_hasher, len_and_str(*dh)); } @@ -682,7 +683,7 @@ pub fn mangle(sess: Session, ss: path) -> ~str { let mut n = ~"_ZN"; // Begin name-sequence. - for ss.each |s| { + for ss.iter().advance |s| { match *s { path_name(s) | path_mod(s) => { let sani = sanitize(sess.str_of(s)); n += fmt!("%u%s", sani.len(), sani); @@ -872,7 +873,8 @@ pub fn link_args(sess: Session, // # Crate linking let cstore = sess.cstore; - for cstore::get_used_crate_files(cstore).each |cratepath| { + let r = cstore::get_used_crate_files(cstore); + for r.iter().advance |cratepath| { if cratepath.filetype() == Some(~".rlib") { args.push(cratepath.to_str()); loop; @@ -884,7 +886,7 @@ pub fn link_args(sess: Session, } let ula = cstore::get_used_link_args(cstore); - for ula.each |arg| { args.push(arg.to_owned()); } + for ula.iter().advance |arg| { args.push(arg.to_owned()); } // Add all the link args for external crates. do cstore::iter_crate_data(cstore) |crate_num, _| { @@ -902,13 +904,13 @@ pub fn link_args(sess: Session, // to be found at compile time so it is still entirely up to outside // forces to make sure that library can be found at runtime. - for sess.opts.addl_lib_search_paths.each |path| { + for sess.opts.addl_lib_search_paths.iter().advance |path| { args.push(~"-L" + path.to_str()); } // The names of the extern libraries let used_libs = cstore::get_used_libraries(cstore); - for used_libs.each |l| { args.push(~"-l" + *l); } + for used_libs.iter().advance |l| { args.push(~"-l" + *l); } if *sess.building_library { args.push(lib_cmd); diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index 987c76dccb42..2c994fbc3fc1 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -147,7 +147,7 @@ pub fn create_standard_passes(level:OptLevel) -> ~[~str] { } pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~str]) { - for pass_list.each |&nm| { + for pass_list.iter().advance |&nm| { match create_pass(nm) { Some(p) => pm.add_pass(p), None => sess.warn(fmt!("Unknown pass %s", nm)) @@ -172,15 +172,15 @@ pub fn list_passes() { io::println("\nAvailable Passes:"); io::println("\nAnalysis Passes:"); - for analysis_passes.each |&(name, desc)| { + for analysis_passes.iter().advance |&(name, desc)| { io::println(fmt!(" %-30s -- %s", name, desc)); } io::println("\nTransformation Passes:"); - for transform_passes.each |&(name, desc)| { + for transform_passes.iter().advance |&(name, desc)| { io::println(fmt!(" %-30s -- %s", name, desc)); } io::println("\nUtility Passes:"); - for utility_passes.each |&(name, desc)| { + for utility_passes.iter().advance |&(name, desc)| { io::println(fmt!(" %-30s -- %s", name, desc)); } } @@ -298,7 +298,7 @@ static utility_passes : &'static [(&'static str, &'static str)] = &'static [ fn passes_exist() { let mut failed = ~[]; unsafe { llvm::LLVMInitializePasses(); } - for analysis_passes.each() |&(name,_)| { + for analysis_passes.iter().advance |&(name,_)| { let pass = create_pass(name); if !pass.is_some() { failed.push(name); @@ -306,7 +306,7 @@ fn passes_exist() { unsafe { llvm::LLVMDestroyPass(pass.get()) } } } - for transform_passes.each() |&(name,_)| { + for transform_passes.iter().advance |&(name,_)| { let pass = create_pass(name); if !pass.is_some() { failed.push(name); @@ -314,7 +314,7 @@ fn passes_exist() { unsafe { llvm::LLVMDestroyPass(pass.get()) } } } - for utility_passes.each() |&(name,_)| { + for utility_passes.iter().advance |&(name,_)| { let pass = create_pass(name); if !pass.is_some() { failed.push(name); @@ -325,7 +325,7 @@ fn passes_exist() { if failed.len() > 0 { io::println("Some passes don't exist:"); - for failed.each |&n| { + for failed.iter().advance |&n| { io::println(fmt!(" %s", n)); } fail!(); diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index bf88b88b0581..4657c069c21e 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -64,7 +64,7 @@ fn get_rpaths(os: session::os, debug!("sysroot: %s", sysroot.to_str()); debug!("output: %s", output.to_str()); debug!("libs:"); - for libs.each |libpath| { + for libs.iter().advance |libpath| { debug!(" %s", libpath.to_str()); } debug!("target_triple: %s", target_triple); @@ -83,7 +83,7 @@ fn get_rpaths(os: session::os, fn log_rpaths(desc: &str, rpaths: &[Path]) { debug!("%s rpaths:", desc); - for rpaths.each |rpath| { + for rpaths.iter().advance |rpath| { debug!(" %s", rpath.to_str()); } } @@ -185,7 +185,7 @@ pub fn get_install_prefix_rpath(target_triple: &str) -> Path { pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { let mut set = HashSet::new(); let mut minimized = ~[]; - for rpaths.each |rpath| { + for rpaths.iter().advance |rpath| { if set.insert(rpath.to_str()) { minimized.push(copy *rpath); } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 43b3397094b5..1a7041c08840 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -453,7 +453,7 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input, } pub fn get_os(triple: &str) -> Option { - for os_names.each |&(name, os)| { + for os_names.iter().advance |&(name, os)| { if triple.contains(name) { return Some(os) } } None @@ -467,7 +467,7 @@ static os_names : &'static [(&'static str, session::os)] = &'static [ ("freebsd", session::os_freebsd)]; pub fn get_arch(triple: &str) -> Option { - for architecture_abis.each |&(arch, abi)| { + for architecture_abis.iter().advance |&(arch, abi)| { if triple.contains(arch) { return Some(abi) } } None @@ -556,7 +556,7 @@ pub fn build_session_options(binary: @str, lint::deny, lint::forbid]; let mut lint_opts = ~[]; let lint_dict = lint::get_lint_dict(); - for lint_levels.each |level| { + for lint_levels.iter().advance |level| { let level_name = lint::level_to_str(*level); // FIXME: #4318 Instead of to_ascii and to_str_ascii, could use @@ -565,7 +565,7 @@ pub fn build_session_options(binary: @str, let level_short = level_short.to_ascii().to_upper().to_str_ascii(); let flags = vec::append(getopts::opt_strs(matches, level_short), getopts::opt_strs(matches, level_name)); - for flags.each |lint_name| { + for flags.iter().advance |lint_name| { let lint_name = lint_name.replace("-", "_"); match lint_dict.find_equiv(&lint_name) { None => { @@ -582,9 +582,9 @@ pub fn build_session_options(binary: @str, let mut debugging_opts = 0u; let debug_flags = getopts::opt_strs(matches, "Z"); let debug_map = session::debugging_opts_map(); - for debug_flags.each |debug_flag| { + for debug_flags.iter().advance |debug_flag| { let mut this_bit = 0u; - for debug_map.each |tuple| { + for debug_map.iter().advance |tuple| { let (name, bit) = match *tuple { (ref a, _, b) => (a, b) }; if name == debug_flag { this_bit = bit; break; } } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 517b3f9ed857..71375966a28b 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -143,7 +143,7 @@ fn fold_block( let filtered_view_items = filtered_view_items.map(|x| fld.fold_view_item(*x)); let mut resulting_stmts = ~[]; - for filtered_stmts.each |stmt| { + for filtered_stmts.iter().advance |stmt| { match fld.fold_stmt(*stmt) { None => {} Some(stmt) => resulting_stmts.push(stmt), diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index de6fc322c637..c9eb97b44cd7 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -386,7 +386,7 @@ fn is_std(cx: &TestCtxt) -> bool { fn mk_test_descs(cx: &TestCtxt) -> @ast::expr { debug!("building test vector from %u tests", cx.testfns.len()); let mut descs = ~[]; - for cx.testfns.each |test| { + for cx.testfns.iter().advance |test| { descs.push(mk_test_desc_and_fn_rec(cx, test)); } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index c8b0f4a488ad..2743cd1ddc1e 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -66,7 +66,7 @@ struct cache_entry { fn dump_crates(crate_cache: @mut ~[cache_entry]) { debug!("resolved crates:"); - for crate_cache.each |entry| { + for crate_cache.iter().advance |entry| { debug!("cnum: %?", entry.cnum); debug!("span: %?", entry.span); debug!("hash: %?", entry.hash); @@ -101,7 +101,7 @@ fn warn_if_multiple_versions(e: @mut Env, if matches.len() != 1u { diag.handler().warn( fmt!("using multiple versions of crate `%s`", name)); - for matches.each |match_| { + for matches.iter().advance |match_| { diag.span_note(match_.span, "used here"); let attrs = ~[ attr::mk_attr(attr::mk_list_item( @@ -130,7 +130,7 @@ fn visit_crate(e: @mut Env, c: &ast::crate) { let cstore = e.cstore; let link_args = attr::find_attrs_by_name(c.node.attrs, "link_args"); - for link_args.each |a| { + for link_args.iter().advance |a| { match attr::get_meta_item_value_str(attr::attr_meta(*a)) { Some(ref linkarg) => { cstore::add_used_link_args(cstore, *linkarg); @@ -191,7 +191,7 @@ fn visit_item(e: @mut Env, i: @ast::item) { ast::anonymous => { /* do nothing */ } } - for link_args.each |a| { + for link_args.iter().advance |a| { match attr::get_meta_item_value_str(attr::attr_meta(*a)) { Some(linkarg) => { cstore::add_used_link_args(cstore, linkarg); @@ -221,7 +221,7 @@ fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item]) fn existing_match(e: @mut Env, metas: &[@ast::meta_item], hash: @str) -> Option { - for e.crate_cache.each |c| { + for e.crate_cache.iter().advance |c| { if loader::metadata_matches(*c.metas, metas) && (hash.is_empty() || c.hash == hash) { return Some(c.cnum); @@ -303,7 +303,8 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map { // The map from crate numbers in the crate we're resolving to local crate // numbers let mut cnum_map = HashMap::new(); - for decoder::get_crate_deps(cdata).each |dep| { + let r = decoder::get_crate_deps(cdata); + for r.iter().advance |dep| { let extrn_cnum = dep.cnum; let cname = dep.name; let cname_str = token::ident_to_str(&dep.name); diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 399ad215fdb3..c6c1ac720e8e 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -160,7 +160,7 @@ pub fn get_dep_hashes(cstore: &CStore) -> ~[@str] { }; debug!("sorted:"); - for sorted.each |x| { + for sorted.iter().advance |x| { debug!(" hash[%s]: %s", x.name, x.hash); } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 7f06953663b3..9ace8677dab7 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -598,7 +598,7 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id, let mut infos: ~[ty::VariantInfo] = ~[]; let variant_ids = enum_variant_ids(item, cdata); let mut disr_val = 0; - for variant_ids.each |did| { + for variant_ids.iter().advance |did| { let item = find_item(did.node, items); let ctor_ty = item_type(ast::def_id { crate: cdata.cnum, node: id}, item, tcx, cdata); @@ -818,7 +818,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, } let mut static_impl_methods = ~[]; - for impl_method_ids.each |impl_method_id| { + for impl_method_ids.iter().advance |impl_method_id| { let impl_method_doc = lookup_item(impl_method_id.node, cdata.data); let family = item_family(impl_method_doc); match family { @@ -1008,7 +1008,8 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { fn list_meta_items(intr: @ident_interner, meta_items: ebml::Doc, out: @io::Writer) { - for get_meta_items(meta_items).each |mi| { + let r = get_meta_items(meta_items); + for r.iter().advance |mi| { out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr))); } } @@ -1017,7 +1018,8 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str, out: @io::Writer) { out.write_str(fmt!("=Crate Attributes (%s)=\n", hash)); - for get_attributes(md).each |attr| { + let r = get_attributes(md); + for r.iter().advance |attr| { out.write_str(fmt!("%s\n", pprust::attribute_to_str(*attr, intr))); } @@ -1057,7 +1059,8 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] { fn list_crate_deps(data: @~[u8], out: @io::Writer) { out.write_str("=External Dependencies=\n"); - for get_crate_deps(data).each |dep| { + let r = get_crate_deps(data); + for r.iter().advance |dep| { out.write_str( fmt!("%d %s-%s-%s\n", dep.cnum, token::ident_to_str(&dep.name), dep.hash, dep.vers)); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index bc2e95f4d1b1..826b64b9a64b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -187,7 +187,7 @@ fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder, tcx: ecx.tcx, reachable: |a| r.contains(&a), abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; - for params.each |param| { + for params.iter().advance |param| { ebml_w.start_tag(tag); tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param); ebml_w.end_tag(); @@ -325,7 +325,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let mut i = 0; let vi = ty::enum_variants(ecx.tcx, ast::def_id { crate: local_crate, node: id }); - for variants.each |variant| { + for variants.iter().advance |variant| { index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); @@ -373,7 +373,7 @@ fn encode_path(ecx: &EncodeContext, ebml_w.start_tag(tag_path); ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32); - for path.each |pe| { + for path.iter().advance |pe| { encode_path_elt(ecx, ebml_w, *pe); } encode_path_elt(ecx, ebml_w, name); @@ -403,8 +403,8 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext, -> bool { match ecx.tcx.base_impls.find(&exp.def_id) { Some(implementations) => { - for implementations.each |&base_impl| { - for base_impl.methods.each |&m| { + for implementations.iter().advance |&base_impl| { + for base_impl.methods.iter().advance |&m| { if m.explicit_self == ast::sty_static { encode_reexported_static_method(ecx, ebml_w, exp, m.did, m.ident); @@ -424,7 +424,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext, -> bool { match ecx.tcx.trait_methods_cache.find(&exp.def_id) { Some(methods) => { - for methods.each |&m| { + for methods.iter().advance |&m| { if m.explicit_self == ast::sty_static { encode_reexported_static_method(ecx, ebml_w, exp, m.def_id, m.ident); @@ -486,7 +486,7 @@ fn encode_info_for_mod(ecx: &EncodeContext, debug!("(encoding info for module) encoding info for module ID %d", id); // Encode info about all the module children. - for md.items.each |item| { + for md.items.iter().advance |item| { match item.node { item_impl(*) => { let (ident, did) = (item.ident, item.id); @@ -511,7 +511,7 @@ fn encode_info_for_mod(ecx: &EncodeContext, match ecx.reexports2.find(&id) { Some(ref exports) => { debug!("(encoding info for module) found reexports for %d", id); - for exports.each |exp| { + for exports.iter().advance |exp| { debug!("(encoding info for module) reexport '%s' for %d", exp.name, id); ebml_w.start_tag(tag_items_data_item_reexport); @@ -617,7 +617,7 @@ fn encode_info_for_struct(ecx: &EncodeContext, let tcx = ecx.tcx; /* We encode both private and public fields -- need to include private fields to get the offsets right */ - for fields.each |field| { + for fields.iter().advance |field| { let (nm, vis) = match field.node.kind { named_field(nm, vis) => (nm, vis), unnamed_field => (special_idents::unnamed_field, inherited) @@ -862,7 +862,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ecx, ebml_w, item.ident); - for (*enum_definition).variants.each |v| { + for (*enum_definition).variants.iter().advance |v| { encode_variant_id(ebml_w, local_def(v.node.id)); } (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); @@ -921,7 +921,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - for struct_def.fields.each |f| { + for struct_def.fields.iter().advance |f| { match f.node.kind { named_field(ident, vis) => { ebml_w.start_tag(tag_item_field); @@ -960,7 +960,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } _ => {} } - for methods.each |m| { + for methods.iter().advance |m| { ebml_w.start_tag(tag_item_impl_method); let method_def_id = local_def(m.id); let s = def_to_str(method_def_id); @@ -978,7 +978,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let mut impl_path = vec::append(~[], path); impl_path += [ast_map::path_name(item.ident)]; - for methods.each |m| { + for methods.iter().advance |m| { index.push(entry {val: m.id, pos: ebml_w.writer.tell()}); encode_info_for_method(ecx, ebml_w, @@ -1001,13 +1001,13 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); - for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| { + for ty::trait_method_def_ids(tcx, local_def(item.id)).iter().advance |&method_def_id| { ebml_w.start_tag(tag_item_trait_method); encode_def_id(ebml_w, method_def_id); ebml_w.end_tag(); } encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); - for super_traits.each |ast_trait_ref| { + for super_traits.iter().advance |ast_trait_ref| { let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id); encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref); } @@ -1183,13 +1183,13 @@ fn create_index(index: ~[entry]) -> ~[@~[entry]] { let mut buckets: ~[@mut ~[entry]] = ~[]; for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; - for index.each |elt| { + for index.iter().advance |elt| { let h = elt.val.hash() as uint; buckets[h % 256].push(copy *elt); } let mut buckets_frozen = ~[]; - for buckets.each |bucket| { + for buckets.iter().advance |bucket| { buckets_frozen.push(@/*bad*/copy **bucket); } return buckets_frozen; @@ -1202,10 +1202,10 @@ fn encode_index(ebml_w: &mut writer::Encoder, ebml_w.start_tag(tag_index); let mut bucket_locs: ~[uint] = ~[]; ebml_w.start_tag(tag_index_buckets); - for buckets.each |bucket| { + for buckets.iter().advance |bucket| { bucket_locs.push(ebml_w.writer.tell()); ebml_w.start_tag(tag_index_buckets_bucket); - for (**bucket).each |elt| { + for (**bucket).iter().advance |elt| { ebml_w.start_tag(tag_index_buckets_bucket_elt); assert!(elt.pos < 0xffff_ffff); writer.write_be_u32(elt.pos as u32); @@ -1216,7 +1216,7 @@ fn encode_index(ebml_w: &mut writer::Encoder, } ebml_w.end_tag(); ebml_w.start_tag(tag_index_table); - for bucket_locs.each |pos| { + for bucket_locs.iter().advance |pos| { assert!(*pos < 0xffff_ffff); writer.write_be_u32(*pos as u32); } @@ -1262,7 +1262,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { ebml_w.start_tag(tag_meta_item_name); ebml_w.writer.write(name.as_bytes()); ebml_w.end_tag(); - for items.each |inner_item| { + for items.iter().advance |inner_item| { encode_meta_item(ebml_w, *inner_item); } ebml_w.end_tag(); @@ -1272,7 +1272,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) { ebml_w.start_tag(tag_attributes); - for attrs.each |attr| { + for attrs.iter().advance |attr| { ebml_w.start_tag(tag_attribute); encode_meta_item(ebml_w, attr.node.value); ebml_w.end_tag(); @@ -1314,7 +1314,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext, let mut attrs: ~[attribute] = ~[]; let mut found_link_attr = false; - for crate.node.attrs.each |attr| { + for crate.node.attrs.iter().advance |attr| { attrs.push( if "link" != attr::get_attr_name(attr) { copy *attr @@ -1356,7 +1356,7 @@ fn encode_crate_deps(ecx: &EncodeContext, // Sanity-check the crate numbers let mut expected_cnum = 1; - for deps.each |n| { + for deps.iter().advance |n| { assert_eq!(n.cnum, expected_cnum); expected_cnum += 1; } @@ -1370,7 +1370,8 @@ fn encode_crate_deps(ecx: &EncodeContext, // FIXME (#2166): This is not nearly enough to support correct versioning // but is enough to get transitive crate dependencies working. ebml_w.start_tag(tag_crate_deps); - for get_ordered_deps(ecx, cstore).each |dep| { + let r = get_ordered_deps(ecx, cstore); + for r.iter().advance |dep| { encode_crate_dep(ecx, ebml_w, *dep); } ebml_w.end_tag(); @@ -1404,7 +1405,7 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.start_tag(tag_link_args); let link_args = cstore::get_used_link_args(ecx.cstore); - for link_args.each |link_arg| { + for link_args.iter().advance |link_arg| { ebml_w.start_tag(tag_link_args_arg); ebml_w.writer.write_str(link_arg.to_str()); ebml_w.end_tag(); @@ -1515,7 +1516,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { ecx.stats.total_bytes = *wr.pos; if (tcx.sess.meta_stats()) { - for wr.bytes.each |e| { + for wr.bytes.iter().advance |e| { if *e == 0 { ecx.stats.zero_bytes += 1; } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 6314cb626976..6268932ba995 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -48,7 +48,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, debug!("filesearch: searching additional lib search paths [%?]", self.addl_lib_search_paths.len()); // a little weird - self.addl_lib_search_paths.each(f); + self.addl_lib_search_paths.iter().advance(f); debug!("filesearch: searching target lib path"); if !f(&make_target_lib_path(self.sysroot, @@ -89,7 +89,8 @@ pub fn search(filesearch: @FileSearch, pick: pick) -> Option { let mut rslt = None; for filesearch.for_each_lib_search_path() |lib_search_path| { debug!("searching %s", lib_search_path.to_str()); - for os::list_dir_path(lib_search_path).each |path| { + let r = os::list_dir_path(lib_search_path); + for r.iter().advance |path| { debug!("testing %s", path.to_str()); let maybe_picked = pick(*path); if maybe_picked.is_some() { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 585704381b69..f6ad676546dd 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -130,7 +130,7 @@ fn find_library_crate_aux( cx.diag.span_err( cx.span, fmt!("multiple matching crates for `%s`", crate_name)); cx.diag.handler().note("candidates:"); - for matches.each |&(ident, data)| { + for matches.iter().advance |&(ident, data)| { cx.diag.handler().note(fmt!("path: %s", ident)); let attrs = decoder::get_crate_attributes(data); note_linkage_attrs(cx.intr, cx.diag, attrs); @@ -158,9 +158,9 @@ pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { pub fn note_linkage_attrs(intr: @ident_interner, diag: @span_handler, attrs: ~[ast::attribute]) { - for attr::find_linkage_metas(attrs).each |mi| { - diag.handler().note(fmt!("meta: %s", - pprust::meta_item_to_str(*mi,intr))); + let r = attr::find_linkage_metas(attrs); + for r.iter().advance |mi| { + diag.handler().note(fmt!("meta: %s", pprust::meta_item_to_str(*mi,intr))); } } @@ -182,7 +182,7 @@ pub fn metadata_matches(extern_metas: &[@ast::meta_item], debug!("matching %u metadata requirements against %u items", local_metas.len(), extern_metas.len()); - for local_metas.each |needed| { + for local_metas.iter().advance |needed| { if !attr::contains(extern_metas, *needed) { return false; } diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index d9377afa9a52..5f854b1f24e0 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -125,7 +125,7 @@ fn enc_substs(w: @io::Writer, cx: @ctxt, substs: &ty::substs) { do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) } do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) } w.write_char('['); - for substs.tps.each |t| { enc_ty(w, cx, *t); } + for substs.tps.iter().advance |t| { enc_ty(w, cx, *t); } w.write_char(']'); } @@ -272,7 +272,7 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) { } ty::ty_tup(ts) => { w.write_str(&"T["); - for ts.each |t| { enc_ty(w, cx, *t); } + for ts.iter().advance |t| { enc_ty(w, cx, *t); } w.write_char(']'); } ty::ty_box(mt) => { w.write_char('@'); enc_mt(w, cx, mt); } @@ -389,7 +389,7 @@ fn enc_closure_ty(w: @io::Writer, cx: @ctxt, ft: &ty::ClosureTy) { fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) { w.write_char('['); - for fsig.inputs.each |ty| { + for fsig.inputs.iter().advance |ty| { enc_ty(w, cx, *ty); } w.write_char(']'); @@ -407,7 +407,7 @@ fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) { } } - for bs.trait_bounds.each |&tp| { + for bs.trait_bounds.iter().advance |&tp| { w.write_char('I'); enc_trait_ref(w, cx, tp); } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index be87beba7784..5730eb0d9bd8 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -118,7 +118,7 @@ impl<'self> CheckLoanCtxt<'self> { //! given `loan_path` for self.each_in_scope_loan(scope_id) |loan| { - for loan.restrictions.each |restr| { + for loan.restrictions.iter().advance |restr| { if restr.loan_path == loan_path { if !op(loan, restr) { return false; @@ -152,7 +152,7 @@ impl<'self> CheckLoanCtxt<'self> { debug!("new_loan_indices = %?", new_loan_indices); for self.each_issued_loan(scope_id) |issued_loan| { - for new_loan_indices.each |&new_loan_index| { + for new_loan_indices.iter().advance |&new_loan_index| { let new_loan = &self.all_loans[new_loan_index]; self.report_error_if_loans_conflict(issued_loan, new_loan); } @@ -210,7 +210,7 @@ impl<'self> CheckLoanCtxt<'self> { }; debug!("illegal_if=%?", illegal_if); - for loan1.restrictions.each |restr| { + for loan1.restrictions.iter().advance |restr| { if !restr.set.intersects(illegal_if) { loop; } if restr.loan_path != loan2.loan_path { loop; } @@ -634,7 +634,7 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind, closure_id: ast::node_id, span: span) { let cap_vars = this.bccx.capture_map.get(&closure_id); - for cap_vars.each |cap_var| { + for cap_vars.iter().advance |cap_var| { match cap_var.mode { moves::CapRef | moves::CapCopy => { let var_id = ast_util::def_id_of_def(cap_var.def).node; diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index 5431a0a29980..c7bad60e90e8 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -71,7 +71,7 @@ pub fn gather_captures(bccx: @BorrowckCtxt, move_data: &mut MoveData, closure_expr: @ast::expr) { let captured_vars = bccx.capture_map.get(&closure_expr.id); - for captured_vars.each |captured_var| { + for captured_vars.iter().advance |captured_var| { match captured_var.mode { moves::CapMove => { let fvar_id = ast_util::def_id_of_def(captured_var.def).node; diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 02b45995e43c..9d8fdb062782 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -229,8 +229,8 @@ fn gather_loans_in_expr(ex: @ast::expr, ast::expr_match(ex_v, ref arms) => { let cmt = this.bccx.cat_expr(ex_v); - for arms.each |arm| { - for arm.pats.each |pat| { + for arms.iter().advance |arm| { + for arm.pats.iter().advance |pat| { this.gather_pat(cmt, *pat, arm.body.node.id, ex.id); } } diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index 6bd32f04ce5b..bedb465c5c14 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -140,7 +140,7 @@ impl RestrictionsContext { // static errors. For example, if there is code like // // let v = @mut ~[1, 2, 3]; - // for v.each |e| { + // for v.iter().advance |e| { // v.push(e + 1); // } // @@ -152,7 +152,7 @@ impl RestrictionsContext { // // let v = @mut ~[1, 2, 3]; // let w = v; - // for v.each |e| { + // for v.iter().advance |e| { // w.push(e + 1); // } // @@ -165,7 +165,7 @@ impl RestrictionsContext { // } // ... // let v: &V = ...; - // for v.get_list().each |e| { + // for v.get_list().iter().advance |e| { // v.get_list().push(e + 1); // } match opt_loan_path(cmt_base) { diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 0ed909b64829..0b94eeecba87 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -357,13 +357,13 @@ impl MoveData { self.kill_moves(assignment.path, assignment.id, dfcx_moves); } - for self.path_assignments.each |assignment| { + for self.path_assignments.iter().advance |assignment| { self.kill_moves(assignment.path, assignment.id, dfcx_moves); } // Kill all moves related to a variable `x` when it goes out // of scope: - for self.paths.each |path| { + for self.paths.iter().advance |path| { match *path.loan_path { LpVar(id) => { let kill_id = tcx.region_maps.encl_scope(id); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 79fe6420e278..126d2db6879d 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -48,7 +48,7 @@ pub fn check_item(sess: Session, check_item_recursion(sess, ast_map, def_map, it); } item_enum(ref enum_definition, _) => { - for (*enum_definition).variants.each |var| { + for (*enum_definition).variants.iter().advance |var| { for var.node.disr_expr.iter().advance |ex| { (v.visit_expr)(*ex, (true, v)); } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 346e2162385c..a25324058707 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -64,7 +64,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { expr_match(scrut, ref arms) => { // First, check legality of move bindings. let is_non_moving_lvalue = expr_is_non_moving_lvalue(cx, ex); - for arms.each |arm| { + for arms.iter().advance |arm| { check_legality_of_move_bindings(cx, is_non_moving_lvalue, arm.guard.is_some(), @@ -110,8 +110,8 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { // Check for unreachable patterns pub fn check_arms(cx: @MatchCheckCtxt, arms: &[arm]) { let mut seen = ~[]; - for arms.each |arm| { - for arm.pats.each |pat| { + for arms.iter().advance |arm| { + for arm.pats.iter().advance |pat| { let v = ~[*pat]; match is_useful(cx, &seen, v) { not_useful => { @@ -232,7 +232,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } } ty::ty_enum(eid, _) => { - for (*ty::enum_variants(cx.tcx, eid)).each |va| { + for (*ty::enum_variants(cx.tcx, eid)).iter().advance |va| { match is_useful_specialized(cx, m, v, variant(va.id), va.args.len(), left_ty) { not_useful => (), @@ -354,14 +354,14 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, match ty::get(left_ty).sty { ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) | ty::ty_struct(*) => { - for m.each |r| { + for m.iter().advance |r| { if !is_wild(cx, r[0]) { return None; } } return Some(single); } ty::ty_enum(eid, _) => { let mut found = ~[]; - for m.each |r| { + for m.iter().advance |r| { let r = pat_ctor_id(cx, r[0]); for r.iter().advance |id| { if !vec::contains(found, id) { @@ -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).each |v| { + for (*variants).iter().advance |v| { if !found.iter().any_(|x| x == &(variant(v.id))) { return Some(variant(v.id)); } @@ -383,7 +383,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, ty::ty_bool => { let mut true_found = false; let mut false_found = false; - for m.each |r| { + for m.iter().advance |r| { match pat_ctor_id(cx, r[0]) { None => (), Some(val(const_bool(true))) => true_found = true, @@ -423,7 +423,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, let mut found_slice = false; let mut next = 0; let mut missing = None; - for sorted_vec_lens.each |&(length, slice)| { + for sorted_vec_lens.iter().advance |&(length, slice)| { if length != next { missing = Some(next); break; @@ -775,7 +775,7 @@ pub fn check_fn(cx: @MatchCheckCtxt, (s, v): ((), visit::vt<()>)) { visit::visit_fn(kind, decl, body, sp, id, (s, v)); - for decl.inputs.each |input| { + for decl.inputs.iter().advance |input| { if is_refutable(cx, input.pat) { cx.tcx.sess.span_err(input.pat.span, "refutable pattern in function argument"); @@ -829,7 +829,7 @@ pub fn check_legality_of_move_bindings(cx: @MatchCheckCtxt, let def_map = tcx.def_map; let mut by_ref_span = None; let mut any_by_move = false; - for pats.each |pat| { + for pats.iter().advance |pat| { do pat_bindings(def_map, *pat) |bm, id, span, _path| { match bm { bind_by_ref(_) => { @@ -871,7 +871,7 @@ pub fn check_legality_of_move_bindings(cx: @MatchCheckCtxt, }; if !any_by_move { return; } // pointless micro-optimization - for pats.each |pat| { + for pats.iter().advance |pat| { for walk_pat(*pat) |p| { if pat_is_binding(def_map, p) { match p.node { diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 1e14a558db28..acd47eca7265 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -389,7 +389,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.merge_with_entry_set(blk.node.id, in_out); - for blk.node.stmts.each |&stmt| { + for blk.node.stmts.iter().advance |&stmt| { self.walk_stmt(stmt, in_out, loop_scopes); } @@ -510,7 +510,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { loop_kind: ForLoop, break_bits: reslice(in_out).to_owned() }); - for decl.inputs.each |input| { + for decl.inputs.iter().advance |input| { self.walk_pat(input.pat, func_bits, loop_scopes); } self.walk_block(body, func_bits, loop_scopes); @@ -627,7 +627,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // together the bits from each arm: self.reset(in_out); - for arms.each |arm| { + for arms.iter().advance |arm| { // in_out reflects the discr and all guards to date self.walk_opt_expr(arm.guard, guards, loop_scopes); @@ -702,7 +702,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { } ast::expr_struct(_, ref fields, with_expr) => { - for fields.each |field| { + for fields.iter().advance |field| { self.walk_expr(field.node.expr, in_out, loop_scopes); } self.walk_opt_expr(with_expr, in_out, loop_scopes); @@ -764,10 +764,10 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { } ast::expr_inline_asm(ref inline_asm) => { - for inline_asm.inputs.each |&(_, expr)| { + for inline_asm.inputs.iter().advance |&(_, expr)| { self.walk_expr(expr, in_out, loop_scopes); } - for inline_asm.outputs.each |&(_, expr)| { + for inline_asm.outputs.iter().advance |&(_, expr)| { self.walk_expr(expr, in_out, loop_scopes); } } @@ -835,7 +835,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { exprs: &[@ast::expr], in_out: &mut [uint], loop_scopes: &mut ~[LoopScope]) { - for exprs.each |&expr| { + for exprs.iter().advance |&expr| { self.walk_expr(expr, in_out, loop_scopes); } } @@ -897,7 +897,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { // alternatives, so we must treat this like an N-way select // statement. let initial_state = reslice(in_out).to_owned(); - for pats.each |&pat| { + for pats.iter().advance |&pat| { let mut temp = copy initial_state; self.walk_pat(pat, temp, loop_scopes); join_bits(&self.dfcx.oper, temp, in_out); @@ -993,7 +993,7 @@ fn bits_to_str(words: &[uint]) -> ~str { // Note: this is a little endian printout of bytes. - for words.each |&word| { + for words.iter().advance |&word| { let mut v = word; for uint::range(0, uint::bytes) |_| { result.push_char(sep); diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index a93aea983fbf..06feb9e7ba95 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -138,7 +138,7 @@ fn configure_main(ctxt: @mut EntryContext) { but you have one or more functions named 'main' that are not \ defined at the crate level. Either move the definition or \ attach the `#[main]` attribute to override this behavior."); - for this.non_main_fns.each |&(_, span)| { + for this.non_main_fns.iter().advance |&(_, span)| { this.session.span_note(span, "here is a function named 'main'"); } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 2f66ca0f516c..3a8d369469b1 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -391,7 +391,7 @@ impl LanguageItemCollector { let this: *mut LanguageItemCollector = &mut *self; visit_crate(self.crate, ((), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { - for item.attrs.each |attribute| { + for item.attrs.iter().advance |attribute| { unsafe { (*this).match_and_collect_meta_item( local_def(item.id), diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 054498545b7b..d29c027f3c28 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -288,7 +288,7 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ */ pub fn get_lint_dict() -> LintDict { let mut map = HashMap::new(); - for lint_table.each|&(k, v)| { + for lint_table.iter().advance |&(k, v)| { map.insert(k, v); } return map; @@ -435,7 +435,8 @@ impl Context { // detect doc(hidden) let mut doc_hidden = false; - for attr::find_attrs_by_name(attrs, "doc").each |attr| { + let r = attr::find_attrs_by_name(attrs, "doc"); + for r.iter().advance |attr| { match attr::get_meta_item_list(attr.node.value) { Some(s) => { if attr::find_meta_items_by_name(s, "hidden").len() > 0 { @@ -472,12 +473,12 @@ impl Context { // pair instead of just one visitor. match n { Item(it) => { - for self.visitors.each |&(orig, stopping)| { + for self.visitors.iter().advance |&(orig, stopping)| { (orig.visit_item)(it, (self, stopping)); } } Crate(c) => { - for self.visitors.each |&(_, stopping)| { + for self.visitors.iter().advance |&(_, stopping)| { visit::visit_crate(c, (self, stopping)); } } @@ -486,7 +487,7 @@ impl Context { // to be a no-op, so manually invoke visit_fn. Method(m) => { let fk = visit::fk_method(copy m.ident, &m.generics, m); - for self.visitors.each |&(orig, stopping)| { + for self.visitors.iter().advance |&(orig, stopping)| { (orig.visit_fn)(&fk, &m.decl, &m.body, m.span, m.id, (self, stopping)); } @@ -497,12 +498,12 @@ impl Context { pub fn each_lint(sess: session::Session, attrs: &[ast::attribute], - f: &fn(@ast::meta_item, level, @str) -> bool) -> bool -{ - for [allow, warn, deny, forbid].each |&level| { + f: &fn(@ast::meta_item, level, @str) -> bool) -> bool { + let xs = [allow, warn, deny, forbid]; + for xs.iter().advance |&level| { let level_name = level_to_str(level); let attrs = attr::find_attrs_by_name(attrs, level_name); - for attrs.each |attr| { + for attrs.iter().advance |attr| { let meta = attr.node.value; let metas = match meta.node { ast::meta_list(_, ref metas) => metas, @@ -511,7 +512,7 @@ pub fn each_lint(sess: session::Session, loop; } }; - for metas.each |meta| { + for metas.iter().advance |meta| { match meta.node { ast::meta_word(lintname) => { if !f(*meta, level, lintname) { @@ -525,7 +526,7 @@ pub fn each_lint(sess: session::Session, } } } - return true; + true } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -693,7 +694,7 @@ fn lint_type_limits() -> visit::vt<@mut Context> { fn check_item_default_methods(cx: &Context, item: @ast::item) { match item.node { ast::item_trait(_, _, ref methods) => { - for methods.each |method| { + for methods.iter().advance |method| { match *method { ast::required(*) => {} ast::provided(*) => { @@ -735,7 +736,7 @@ fn check_item_ctypes(cx: &Context, it: @ast::item) { match it.node { ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => { - for nmod.items.each |ni| { + for nmod.items.iter().advance |ni| { match ni.node { ast::foreign_item_fn(ref decl, _, _) => { check_foreign_fn(cx, decl); @@ -777,7 +778,8 @@ fn check_type_for_lint(cx: &Context, lint: lint, span: span, ty: ty::t) { } fn check_type(cx: &Context, span: span, ty: ty::t) { - for [managed_heap_memory, owned_heap_memory, heap_memory].each |lint| { + let xs = [managed_heap_memory, owned_heap_memory, heap_memory]; + for xs.iter().advance |lint| { check_type_for_lint(cx, *lint, span, ty); } } @@ -796,7 +798,7 @@ fn check_item_heap(cx: &Context, it: @ast::item) { // If it's a struct, we also have to check the fields' types match it.node { ast::item_struct(struct_def, _) => { - for struct_def.fields.each |struct_field| { + for struct_def.fields.iter().advance |struct_field| { check_type(cx, struct_field.span, ty::node_id_to_type(cx.tcx, struct_field.node.id)); @@ -860,7 +862,7 @@ fn check_item_non_camel_case_types(cx: &Context, it: @ast::item) { } ast::item_enum(ref enum_definition, _) => { check_case(cx, it.ident, it.span); - for enum_definition.variants.each |variant| { + for enum_definition.variants.iter().advance |variant| { check_case(cx, variant.node.name, variant.span); } } @@ -905,7 +907,7 @@ fn lint_unused_mut() -> visit::vt<@mut Context> { } fn visit_fn_decl(cx: &Context, fd: &ast::fn_decl) { - for fd.inputs.each |arg| { + for fd.inputs.iter().advance |arg| { if arg.is_mutbl { check_pat(cx, arg.pat); } @@ -1052,7 +1054,7 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { ast::item_struct(sdef, _) if it.vis == ast::public => { check_attrs(cx, it.attrs, it.span, "missing documentation for a struct"); - for sdef.fields.each |field| { + for sdef.fields.iter().advance |field| { match field.node.kind { ast::named_field(_, vis) if vis != ast::private => { check_attrs(cx, field.node.attrs, field.span, @@ -1100,7 +1102,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { } // Install command-line options, overriding defaults. - for tcx.sess.opts.lint_opts.each |&(lint, level)| { + for tcx.sess.opts.lint_opts.iter().advance |&(lint, level)| { cx.set_level(lint, level, CommandLine); } @@ -1158,7 +1160,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { // If we missed any lints added to the session, then there's a bug somewhere // in the iteration code. for tcx.sess.lints.each |_, v| { - for v.each |t| { + for v.iter().advance |t| { match *t { (lint, span, ref msg) => tcx.sess.span_bug(span, fmt!("unprocessed lint %?: %s", diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 08cba4d51cd3..d8308c516b05 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -355,7 +355,7 @@ fn visit_fn(fk: &visit::fn_kind, debug!("creating fn_maps: %x", transmute(&*fn_maps)); } - for decl.inputs.each |arg| { + for decl.inputs.iter().advance |arg| { do pat_util::pat_bindings(this.tcx.def_map, arg.pat) |_bm, arg_id, _x, path| { debug!("adding argument %d", arg_id); @@ -431,7 +431,7 @@ fn visit_local(local: @local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { fn visit_arm(arm: &arm, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { let def_map = this.tcx.def_map; - for arm.pats.each |pat| { + for arm.pats.iter().advance |pat| { do pat_util::pat_bindings(def_map, *pat) |bm, p_id, sp, path| { debug!("adding local variable %d from match with bm %?", p_id, bm); @@ -470,7 +470,7 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { // construction site. let cvs = this.capture_map.get(&expr.id); let mut call_caps = ~[]; - for cvs.each |cv| { + for cvs.iter().advance |cv| { match moves::moved_variable_node_id_from_def(cv.def) { Some(rv) => { let cv_ln = this.add_live_node(FreeVarNode(cv.span)); @@ -1075,7 +1075,7 @@ impl Liveness { let ln = self.live_node(expr.id, expr.span); self.init_empty(ln, succ); let mut first_merge = true; - for arms.each |arm| { + for arms.iter().advance |arm| { let body_succ = self.propagate_through_block(&arm.body, succ); let guard_succ = @@ -1453,12 +1453,12 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) { } expr_inline_asm(ref ia) => { - for ia.inputs.each |&(_, in)| { + for ia.inputs.iter().advance |&(_, in)| { (vt.visit_expr)(in, (this, vt)); } // Output operands must be lvalues - for ia.outputs.each |&(_, out)| { + for ia.outputs.iter().advance |&(_, out)| { match out.node { expr_addr_of(_, inner) => { this.check_lvalue(inner, vt); @@ -1594,7 +1594,7 @@ impl Liveness { } pub fn warn_about_unused_args(&self, decl: &fn_decl, entry_ln: LiveNode) { - for decl.inputs.each |arg| { + for decl.inputs.iter().advance |arg| { do pat_util::pat_bindings(self.tcx.def_map, arg.pat) |_bm, p_id, sp, _n| { let var = self.variable(p_id, sp); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ffb7a1daf359..2ced57dc885b 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -895,7 +895,7 @@ impl mem_categorization_ctxt { } } Some(&ast::def_const(*)) => { - for subpats.each |&subpat| { + for subpats.iter().advance |&subpat| { self.cat_pattern(cmt, subpat, op); } } @@ -917,7 +917,7 @@ impl mem_categorization_ctxt { ast::pat_struct(_, ref field_pats, _) => { // {f1: p1, ..., fN: pN} - for field_pats.each |fp| { + for field_pats.iter().advance |fp| { let field_ty = self.pat_ty(fp.pat); // see (*) let cmt_field = self.cat_field(pat, cmt, fp.ident, field_ty); self.cat_pattern(cmt_field, fp.pat, op); @@ -945,7 +945,7 @@ impl mem_categorization_ctxt { ast::pat_vec(ref before, slice, ref after) => { let elt_cmt = self.cat_index(pat, cmt, 0); - for before.each |&before_pat| { + for before.iter().advance |&before_pat| { self.cat_pattern(elt_cmt, before_pat, op); } for slice.iter().advance |&slice_pat| { @@ -953,7 +953,7 @@ impl mem_categorization_ctxt { let slice_cmt = self.cat_rvalue(pat, slice_ty); self.cat_pattern(slice_cmt, slice_pat, op); } - for after.each |&after_pat| { + for after.iter().advance |&after_pat| { self.cat_pattern(elt_cmt, after_pat, op); } } @@ -1041,7 +1041,8 @@ pub fn field_mutbl(tcx: ty::ctxt, // Need to refactor so that struct/enum fields can be treated uniformly. match ty::get(base_ty).sty { ty::ty_struct(did, _) => { - for ty::lookup_struct_fields(tcx, did).each |fld| { + let r = ty::lookup_struct_fields(tcx, did); + for r.iter().advance |fld| { if fld.ident == f_name { return Some(ast::m_imm); } @@ -1050,7 +1051,8 @@ pub fn field_mutbl(tcx: ty::ctxt, ty::ty_enum(*) => { match tcx.def_map.get_copy(&node_id) { ast::def_variant(_, variant_id) => { - for ty::lookup_struct_fields(tcx, variant_id).each |fld| { + let r = ty::lookup_struct_fields(tcx, variant_id); + for r.iter().advance |fld| { if fld.ident == f_name { return Some(ast::m_imm); } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 8a29a026dc2f..0050239e0663 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -232,7 +232,7 @@ fn compute_modes_for_expr(expr: @expr, impl VisitContext { pub fn consume_exprs(&self, exprs: &[@expr], visitor: vt) { - for exprs.each |expr| { + for exprs.iter().advance |expr| { self.consume_expr(*expr, visitor); } } @@ -263,7 +263,7 @@ impl VisitContext { debug!("consume_block(blk.id=%?)", blk.node.id); - for blk.node.stmts.each |stmt| { + for blk.node.stmts.iter().advance |stmt| { (visitor.visit_stmt)(*stmt, (*self, visitor)); } @@ -347,7 +347,7 @@ impl VisitContext { } expr_struct(_, ref fields, opt_with) => { - for fields.each |field| { + for fields.iter().advance |field| { self.consume_expr(field.node.expr, visitor); } @@ -398,7 +398,7 @@ impl VisitContext { expr_match(discr, ref arms) => { // We must do this first so that `arms_have_by_move_bindings` // below knows which bindings are moves. - for arms.each |arm| { + for arms.iter().advance |arm| { self.consume_arm(arm, visitor); } @@ -534,7 +534,7 @@ impl VisitContext { // for overloaded operatrs, we are always passing in a // borrowed pointer, so it's always read mode: - for arg_exprs.each |arg_expr| { + for arg_exprs.iter().advance |arg_expr| { self.use_expr(*arg_expr, Read, visitor); } @@ -591,7 +591,7 @@ impl VisitContext { arg_exprs: &[@expr], visitor: vt) { //! Uses the argument expressions. - for arg_exprs.each |arg_expr| { + for arg_exprs.iter().advance |arg_expr| { self.use_fn_arg(*arg_expr, visitor); } } @@ -605,8 +605,8 @@ impl VisitContext { moves_map: MovesMap, arms: &[arm]) -> Option<@pat> { - for arms.each |arm| { - for arm.pats.each |&pat| { + for arms.iter().advance |arm| { + for arm.pats.iter().advance |&pat| { for ast_util::walk_pat(pat) |p| { if moves_map.contains(&p.id) { return Some(p); diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 5cfe44e1554e..94771b4ed0b3 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -52,7 +52,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, *count += 1; } item_impl(_, _, _, ref methods) => { - for methods.each |method| { + for methods.iter().advance |method| { privileged_items.push(method.id); *count += 1; } @@ -60,7 +60,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, *count += 1; } item_foreign_mod(ref foreign_mod) => { - for foreign_mod.items.each |foreign_item| { + for foreign_mod.items.iter().advance |foreign_item| { privileged_items.push(foreign_item.id); *count += 1; } @@ -72,7 +72,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, // Adds items that are privileged to this scope. let add_privileged_items: @fn(&[@ast::item]) -> uint = |items| { let mut count = 0; - for items.each |&item| { + for items.iter().advance |&item| { add_privileged_item(item, &mut count); } count @@ -231,7 +231,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, let check_field: @fn(span: span, id: ast::def_id, ident: ast::ident) = |span, id, ident| { let fields = ty::lookup_struct_fields(tcx, id); - for fields.each |field| { + for fields.iter().advance |field| { if field.ident != ident { loop; } if field.vis == private { tcx.sess.span_err(span, fmt!("field `%s` is private", @@ -377,7 +377,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, visit_block: |block, (method_map, visitor)| { // Gather up all the privileged items. let mut n_added = 0; - for block.node.stmts.each |stmt| { + for block.node.stmts.iter().advance |stmt| { match stmt.node { stmt_decl(decl, _) => { match decl.node { @@ -450,7 +450,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, ty_struct(id, _) => { if id.crate != local_crate || !privileged_items.iter().any_(|x| x == &(id.node)) { - for (*fields).each |field| { + for (*fields).iter().advance |field| { debug!("(privacy checking) checking \ field in struct literal"); check_field(expr.span, id, @@ -463,7 +463,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, !privileged_items.iter().any_(|x| x == &(id.node)) { match tcx.def_map.get_copy(&expr.id) { def_variant(_, variant_id) => { - for (*fields).each |field| { + for (*fields).iter().advance |field| { debug!("(privacy checking) \ checking field in \ struct variant \ @@ -516,7 +516,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, ty_struct(id, _) => { if id.crate != local_crate || !privileged_items.iter().any_(|x| x == &(id.node)) { - for fields.each |field| { + for fields.iter().advance |field| { debug!("(privacy checking) checking \ struct pattern"); check_field(pattern.span, id, @@ -529,7 +529,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, !privileged_items.iter().any_(|x| x == &enum_id.node) { match tcx.def_map.find(&pattern.id) { Some(&def_variant(_, variant_id)) => { - for fields.each |field| { + for fields.iter().advance |field| { debug!("(privacy checking) \ checking field in \ struct variant pattern"); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index eef43574c14b..4b6cedd114c3 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -197,7 +197,7 @@ impl RegionMaps { while i < queue.len() { match self.free_region_map.find(&queue[i]) { Some(parents) => { - for parents.each |parent| { + for parents.iter().advance |parent| { if *parent == sup { return true; } @@ -732,7 +732,7 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind, visit::vt<@mut DetermineRpCtxt>)) { do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { - for decl.inputs.each |a| { + for decl.inputs.iter().advance |a| { (visitor.visit_ty)(a.ty, (cx, visitor)); } } @@ -843,7 +843,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, ast::ty_path(path, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { - for path.types.each |tp| { + for path.types.iter().advance |tp| { (visitor.visit_ty)(*tp, (cx, visitor)); } } @@ -856,7 +856,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, do cx.with(cx.item_id, false) { // parameters are contravariant do cx.with_ambient_variance(rv_contravariant) { - for decl.inputs.each |a| { + for decl.inputs.iter().advance |a| { (visitor.visit_ty)(a.ty, (cx, visitor)); } } @@ -936,7 +936,7 @@ pub fn determine_rp_in_crate(sess: Session, match cx.dep_map.find(&c_id) { None => {} Some(deps) => { - for deps.each |dep| { + for deps.iter().advance |dep| { let v = add_variance(dep.ambient_variance, c_variance); cx.add_rp(dep.id, v); } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 0248a5f43cce..8a08b3419e2e 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1057,7 +1057,7 @@ impl Resolver { } // Check each statement. - for block.node.stmts.each |statement| { + for block.node.stmts.iter().advance |statement| { match statement.node { stmt_decl(declaration, _) => { match declaration.node { @@ -1178,7 +1178,7 @@ impl Resolver { name_bindings.define_type (privacy, def_ty(local_def(item.id)), sp); - for (*enum_definition).variants.each |variant| { + for (*enum_definition).variants.iter().advance |variant| { self.build_reduced_graph_for_variant( variant, local_def(item.id), @@ -1227,7 +1227,7 @@ impl Resolver { // Bail out early if there are no static methods. let mut methods_seen = HashMap::new(); let mut has_static_methods = false; - for methods.each |method| { + for methods.iter().advance |method| { match method.explicit_self.node { sty_static => has_static_methods = true, _ => { @@ -1282,7 +1282,7 @@ impl Resolver { }; // For each static method... - for methods.each |method| { + for methods.iter().advance |method| { match method.explicit_self.node { sty_static => { // Add the static method to the @@ -1319,7 +1319,7 @@ impl Resolver { // We only need to create the module if the trait has static // methods, so check that first. let mut has_static_methods = false; - for (*methods).each |method| { + for (*methods).iter().advance |method| { let ty_m = trait_method_to_ty_method(method); match ty_m.explicit_self.node { sty_static => { @@ -1347,7 +1347,7 @@ impl Resolver { // Add the names of all the methods to the trait info. let mut method_names = HashMap::new(); - for methods.each |method| { + for methods.iter().advance |method| { let ty_m = trait_method_to_ty_method(method); let ident = ty_m.ident; @@ -1452,7 +1452,7 @@ impl Resolver { let privacy = visibility_to_privacy(view_item.vis); match view_item.node { view_item_use(ref view_paths) => { - for view_paths.each |view_path| { + for view_paths.iter().advance |view_path| { // Extract and intern the module part of the path. For // globs and lists, the path is found directly in the AST; // for simple paths we have to munge the path a little. @@ -1472,7 +1472,7 @@ impl Resolver { view_path_glob(module_ident_path, _) | view_path_list(module_ident_path, _, _) => { - for module_ident_path.idents.each |ident| { + for module_ident_path.idents.iter().advance |ident| { module_path.push(*ident); } } @@ -1493,7 +1493,7 @@ impl Resolver { id); } view_path_list(_, ref source_idents, _) => { - for source_idents.each |source_ident| { + for source_idents.iter().advance |source_ident| { let name = source_ident.node.name; let subclass = @SingleImport(name, name); self.build_import_directive(privacy, @@ -1686,7 +1686,7 @@ impl Resolver { let method_def_ids = get_trait_method_def_ids(self.session.cstore, def_id); let mut interned_method_names = HashSet::new(); - for method_def_ids.each |&method_def_id| { + for method_def_ids.iter().advance |&method_def_id| { let (method_name, explicit_self) = get_method_name_and_explicit_self(self.session.cstore, method_def_id); @@ -1767,7 +1767,7 @@ impl Resolver { // need to. let mut current_module = root; - for pieces.each |ident_str| { + for pieces.iter().advance |ident_str| { let ident = self.session.ident_of(*ident_str); // Create or reuse a graph node for the child. let (child_name_bindings, new_parent) = @@ -1887,8 +1887,7 @@ impl Resolver { // Add each static method to the module. let new_parent = ModuleReducedGraphParent( type_module); - for static_methods.each - |static_method_info| { + for static_methods.iter().advance |static_method_info| { let ident = static_method_info.ident; debug!("(building reduced graph for \ external crate) creating \ @@ -2074,7 +2073,7 @@ impl Resolver { pub fn idents_to_str(@mut self, idents: &[ident]) -> ~str { let mut first = true; let mut result = ~""; - for idents.each |ident| { + for idents.iter().advance |ident| { if first { first = false; } else { result += "::" }; result += self.session.str_of(*ident); }; @@ -3270,7 +3269,8 @@ impl Resolver { self.session.str_of(*ident)); loop; } - for [ TypeNS, ValueNS ].each |ns| { + let xs = [TypeNS, ValueNS]; + for xs.iter().advance |ns| { match importresolution.target_for_namespace(*ns) { Some(target) => { debug!("(computing exports) maybe reexport '%s'", @@ -3517,7 +3517,7 @@ impl Resolver { // enum item: resolve all the variants' discrs, // then resolve the ty params item_enum(ref enum_def, ref generics) => { - for (*enum_def).variants.each() |variant| { + for (*enum_def).variants.iter().advance |variant| { for variant.node.disr_expr.iter().advance |dis_expr| { // resolve the discriminator expr // as a constant @@ -3575,7 +3575,7 @@ impl Resolver { visitor); // Resolve derived traits. - for traits.each |trt| { + for traits.iter().advance |trt| { match self.resolve_path(trt.path, TypeNS, true, visitor) { None => @@ -3595,7 +3595,7 @@ impl Resolver { } } - for (*methods).each |method| { + for (*methods).iter().advance |method| { // Create a new rib for the method-specific type // parameters. // @@ -3615,7 +3615,7 @@ impl Resolver { &ty_m.generics.ty_params, visitor); - for ty_m.decl.inputs.each |argument| { + for ty_m.decl.inputs.iter().advance |argument| { self.resolve_type(argument.ty, visitor); } @@ -3652,7 +3652,7 @@ impl Resolver { item_foreign_mod(ref foreign_module) => { do self.with_scope(Some(item.ident)) { - for foreign_module.items.each |foreign_item| { + for foreign_module.items.iter().advance |foreign_item| { match foreign_item.node { foreign_item_fn(_, _, ref generics) => { self.with_type_parameter_rib( @@ -3799,7 +3799,7 @@ impl Resolver { // Nothing to do. } Some(declaration) => { - for declaration.inputs.each |argument| { + for declaration.inputs.iter().advance |argument| { let binding_mode = ArgumentIrrefutableMode; let mutability = if argument.is_mutbl {Mutable} else {Immutable}; @@ -3878,7 +3878,7 @@ impl Resolver { self.resolve_type_parameters(&generics.ty_params, visitor); // Resolve fields. - for fields.each |field| { + for fields.iter().advance |field| { self.resolve_type(field.node.ty, visitor); } } @@ -3953,7 +3953,7 @@ impl Resolver { // Resolve the self type. self.resolve_type(self_type, visitor); - for methods.each |method| { + for methods.iter().advance |method| { // We also need a new scope for the method-specific // type parameters. self.resolve_method(MethodRibKind( @@ -4073,7 +4073,7 @@ impl Resolver { self.value_ribs.push(@Rib(NormalRibKind)); let bindings_list = @mut HashMap::new(); - for arm.pats.each |pattern| { + for arm.pats.iter().advance |pattern| { self.resolve_pattern(*pattern, RefutableMode, Immutable, Some(bindings_list), visitor); } @@ -4326,7 +4326,7 @@ impl Resolver { } // Check the types in the path pattern. - for path.types.each |ty| { + for path.types.iter().advance |ty| { self.resolve_type(*ty, visitor); } } @@ -4359,7 +4359,7 @@ impl Resolver { } // Check the types in the path pattern. - for path.types.each |ty| { + for path.types.iter().advance |ty| { self.resolve_type(*ty, visitor); } } @@ -4388,7 +4388,7 @@ impl Resolver { } // Check the types in the path pattern. - for path.types.each |ty| { + for path.types.iter().advance |ty| { self.resolve_type(*ty, visitor); } } @@ -4483,7 +4483,7 @@ impl Resolver { visitor: ResolveVisitor) -> Option { // First, resolve the types. - for path.types.each |ty| { + for path.types.iter().advance |ty| { self.resolve_type(*ty, visitor); } @@ -4872,11 +4872,11 @@ impl Resolver { i -= 1; match this.type_ribs[i].kind { MethodRibKind(node_id, _) => - for this.crate.node.module.items.each |item| { + for this.crate.node.module.items.iter().advance |item| { if item.id == node_id { match item.node { item_struct(class_def, _) => { - for class_def.fields.each |field| { + for class_def.fields.iter().advance |field| { match field.node.kind { unnamed_field => {}, named_field(ident, _) => { @@ -5130,7 +5130,7 @@ impl Resolver { // Look for the current trait. match /*bad*/copy self.current_trait_refs { Some(trait_def_ids) => { - for trait_def_ids.each |trait_def_id| { + for trait_def_ids.iter().advance |trait_def_id| { if candidate_traits.contains(trait_def_id) { self.add_trait_info( &mut found_traits, @@ -5281,7 +5281,7 @@ impl Resolver { match vi.node { view_item_extern_mod(*) => {} // ignore view_item_use(ref path) => { - for path.each |p| { + for path.iter().advance |p| { match p.node { view_path_simple(_, _, id) | view_path_glob(_, id) => { if !self.used_imports.contains(&id) { @@ -5292,7 +5292,7 @@ impl Resolver { } view_path_list(_, ref list, _) => { - for list.each |i| { + for list.iter().advance |i| { if !self.used_imports.contains(&i.node.id) { self.session.add_lint(unused_imports, i.node.id, i.span, diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index a6e8cf666dae..ab2f0c84d02e 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -298,7 +298,7 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id) match ccx.tcx.def_map.get_copy(&pat_id) { ast::def_variant(enum_id, var_id) => { let variants = ty::enum_variants(ccx.tcx, enum_id); - for (*variants).each |v| { + for (*variants).iter().advance |v| { if var_id == v.id { return var(v.disr_val, adt::represent_node(bcx, pat_id)) @@ -363,7 +363,7 @@ pub fn matches_to_str(bcx: block, m: &[@Match]) -> ~str { } pub fn has_nested_bindings(m: &[@Match], col: uint) -> bool { - for m.each |br| { + for m.iter().advance |br| { match br.pats[col].node { ast::pat_ident(_, _, Some(_)) => return true, _ => () @@ -432,7 +432,7 @@ pub fn enter_match<'r>(bcx: block, let _indenter = indenter(); let mut result = ~[]; - for m.each |br| { + for m.iter().advance |br| { match e(br.pats[col]) { Some(sub) => { let pats = @@ -579,8 +579,8 @@ pub fn enter_opt<'r>(bcx: block, // specified in the struct definition. Also fill in // unspecified fields with dummy. let mut reordered_patterns = ~[]; - for ty::lookup_struct_fields(tcx, struct_id).each - |field| { + let r = ty::lookup_struct_fields(tcx, struct_id); + for r.iter().advance |field| { match field_pats.iter().find_(|p| p.ident == field.ident) { None => reordered_patterns.push(dummy), Some(fp) => reordered_patterns.push(fp.pat) @@ -640,7 +640,7 @@ pub fn enter_rec_or_struct<'r>(bcx: block, match p.node { ast::pat_struct(_, ref fpats, _) => { let mut pats = ~[]; - for fields.each |fname| { + for fields.iter().advance |fname| { match fpats.iter().find_(|p| p.ident == *fname) { None => pats.push(dummy), Some(pat) => pats.push(pat.pat) @@ -802,7 +802,7 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { } let mut found = ~[]; - for m.each |br| { + for m.iter().advance |br| { let cur = br.pats[col]; match cur.node { ast::pat_lit(l) => { @@ -948,7 +948,7 @@ pub fn collect_record_or_struct_fields(bcx: block, col: uint) -> ~[ast::ident] { let mut fields: ~[ast::ident] = ~[]; - for m.each |br| { + for m.iter().advance |br| { match br.pats[col].node { ast::pat_struct(_, ref fs, _) => { match ty::get(node_id_type(bcx, br.pats[col].id)).sty { @@ -962,7 +962,7 @@ pub fn collect_record_or_struct_fields(bcx: block, return fields; fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) { - for field_pats.each |field_pat| { + for field_pats.iter().advance |field_pat| { let field_ident = field_pat.ident; if !idents.iter().any_(|x| *x == field_ident) { idents.push(field_ident); @@ -987,7 +987,7 @@ pub fn root_pats_as_necessary(mut bcx: block, col: uint, val: ValueRef) -> block { - for m.each |br| { + for m.iter().advance |br| { let pat_id = br.pats[col].id; if pat_id != 0 { let datum = Datum {val: val, ty: node_id_type(bcx, pat_id), @@ -1056,14 +1056,14 @@ pub fn pick_col(m: &[@Match]) -> uint { } } let mut scores = vec::from_elem(m[0].pats.len(), 0u); - for m.each |br| { + for m.iter().advance |br| { let mut i = 0u; - for br.pats.each |p| { scores[i] += score(*p); i += 1u; } + for br.pats.iter().advance |p| { scores[i] += score(*p); i += 1u; } } let mut max_score = 0u; let mut best_col = 0u; let mut i = 0u; - for scores.each |score| { + for scores.iter().advance |score| { let score = *score; // Irrefutable columns always go first, they'd only be duplicated in @@ -1236,7 +1236,7 @@ pub fn compile_guard(bcx: block, let val = bool_to_i1(bcx, val); // Revoke the temp cleanups now that the guard successfully executed. - for temp_cleanups.each |llval| { + for temp_cleanups.iter().advance |llval| { revoke_clean(bcx, *llval); } @@ -1314,7 +1314,7 @@ pub fn compile_submatch(bcx: block, let ccx = bcx.fcx.ccx; let mut pat_id = 0; let mut pat_span = dummy_sp(); - for m.each |br| { + for m.iter().advance |br| { // Find a real id (we're adding placeholder wildcard patterns, but // each column is guaranteed to have at least one real pattern) if pat_id == 0 { @@ -1442,7 +1442,7 @@ pub fn compile_submatch(bcx: block, } } } - for opts.each |o| { + for opts.iter().advance |o| { match *o { range(_, _) => { kind = compare; break } _ => () @@ -1464,7 +1464,7 @@ pub fn compile_submatch(bcx: block, let mut i = 0u; // Compile subtrees for each option - for opts.each |opt| { + for opts.iter().advance |opt| { i += 1u; let mut opt_cx = else_cx; if !exhaustive || i < len { @@ -1680,7 +1680,7 @@ pub fn trans_match_inner(scope_cx: block, arm: arm, bindings_map: bindings_map}; arm_datas.push(arm_data); - for arm.pats.each |p| { + for arm.pats.iter().advance |p| { matches.push(@Match {pats: ~[*p], data: arm_data}); } } @@ -1701,7 +1701,7 @@ pub fn trans_match_inner(scope_cx: block, compile_submatch(bcx, matches, [lldiscr], chk); let mut arm_cxs = ~[]; - for arm_datas.each |arm_data| { + for arm_datas.iter().advance |arm_data| { let mut bcx = arm_data.bodycx; // If this arm has a guard, then the various by-value bindings have @@ -1844,7 +1844,7 @@ pub fn bind_irrefutable_pat(bcx: block, let pat_ty = node_id_type(bcx, pat.id); let pat_repr = adt::represent_type(bcx.ccx(), pat_ty); do expr::with_field_tys(tcx, pat_ty, None) |discr, field_tys| { - for fields.each |f| { + for fields.iter().advance |f| { let ix = ty::field_idx_strict(tcx, f.ident, field_tys); let fldptr = adt::trans_field_ptr(bcx, pat_repr, val, discr, ix); diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 906c9d028ebc..624c6607859e 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -248,7 +248,7 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let mut most_aligned = None; let mut largest_align = 0; let mut largest_size = 0; - for sts.each |st| { + for sts.iter().advance |st| { if largest_size < st.size { largest_size = st.size; } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index dd8b7ebc00b7..3c263b1c01eb 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -64,7 +64,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { }; - for cleanups.each |c| { + for cleanups.iter().advance |c| { revoke_clean(bcx, *c); } cleanups.clear(); @@ -85,7 +85,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { }; - for cleanups.each |c| { + for cleanups.iter().advance |c| { revoke_clean(bcx, *c); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7132af24d45a..ec77fe359b59 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -670,7 +670,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, n_variants); let next_cx = sub_block(cx, "enum-iter-next"); - for (*variants).each |variant| { + for (*variants).iter().advance |variant| { let variant_cx = sub_block(cx, ~"enum-iter-variant-" + int::to_str(variant.disr_val)); @@ -804,7 +804,7 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) debug!("invoking %x at %x", ::core::cast::transmute(llfn), ::core::cast::transmute(bcx.llbb)); - for llargs.each |&llarg| { + for llargs.iter().advance |&llarg| { debug!("arg: %x", ::core::cast::transmute(llarg)); } } @@ -820,7 +820,7 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) debug!("calling %x at %x", ::core::cast::transmute(llfn), ::core::cast::transmute(bcx.llbb)); - for llargs.each |&llarg| { + for llargs.iter().advance |&llarg| { debug!("arg: %x", ::core::cast::transmute(llarg)); } } @@ -849,7 +849,7 @@ pub fn need_invoke(bcx: block) -> bool { match cur.kind { block_scope(inf) => { let inf = &mut *inf; // FIXME(#5074) workaround old borrowck - for inf.cleanups.each |cleanup| { + for inf.cleanups.iter().advance |cleanup| { match *cleanup { clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => { if cleanup_type == normal_exit_and_unwind { @@ -1366,7 +1366,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, } pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { - for b.node.stmts.each |s| { + for b.node.stmts.iter().advance |s| { match s.node { ast::stmt_decl(d, _) => { match d.node { @@ -2046,7 +2046,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def, id: ast::node_id, vi: @~[ty::VariantInfo], i: &mut uint) { - for enum_definition.variants.each |variant| { + for enum_definition.variants.iter().advance |variant| { let disr_val = vi[*i].disr_val; *i += 1; @@ -2097,7 +2097,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { None, item.attrs); } else { - for body.node.stmts.each |stmt| { + for body.node.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_decl(@codemap::spanned { node: ast::decl_item(i), _ }, _) => { @@ -2126,7 +2126,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { consts::trans_const(ccx, expr, item.id); // Do static_assert checking. It can't really be done much earlier because we need to get // the value of the bool out of LLVM - for item.attrs.each |attr| { + for item.attrs.iter().advance |attr| { match attr.node.value.node { ast::meta_word(x) => { if x.slice(0, x.len()) == "static_assert" { @@ -2175,7 +2175,7 @@ pub fn trans_struct_def(ccx: @mut CrateContext, struct_def: @ast::struct_def) { // and control visibility. pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) { let _icx = push_ctxt("trans_mod"); - for m.items.each |item| { + for m.items.iter().advance |item| { trans_item(ccx, *item); } } @@ -2549,7 +2549,7 @@ pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { node: it.id }); let mut i = 0; let path = item_path(ccx, it); - for (*enum_definition).variants.each |variant| { + for (*enum_definition).variants.iter().advance |variant| { let p = vec::append(/*bad*/copy path, [ path_name(variant.node.name), path_name(special_idents::descrim) @@ -2729,7 +2729,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { keys.push(k.to_managed()); } - for keys.each |key| { + for keys.iter().advance |key| { let val = *ccx.module_data.find_equiv(key).get(); let s_const = C_cstr(ccx, *key); let s_ptr = p2i(ccx, s_const); diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 2f4579afe9c1..ac51c7efc6f0 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -133,7 +133,7 @@ impl ABIInfo for ARM_ABIInfo { ret_def: bool) -> FnType { let mut arg_tys = ~[]; let mut attrs = ~[]; - for atys.each |&aty| { + for atys.iter().advance |&aty| { let (ty, attr) = classify_arg_ty(aty); arg_tys.push(ty); attrs.push(attr); diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index ab5296b0c7a0..8604ae37f774 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -189,7 +189,7 @@ impl ABIInfo for MIPS_ABIInfo { let mut attrs = ~[]; let mut offset = if sret { 4 } else { 0 }; - for atys.each() |aty| { + for atys.iter().advance |aty| { let (ty, attr) = classify_arg_ty(*aty, &mut offset); arg_tys.push(ty); attrs.push(attr); diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 4a92b940190a..14ab17f5030d 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -176,7 +176,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { cls: &mut [RegClass], i: uint, off: uint) { let mut field_off = off; - for tys.each |ty| { + for tys.iter().advance |ty| { field_off = align(field_off, *ty); classify(*ty, cls, i, field_off); field_off += ty_size(*ty); @@ -294,7 +294,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { fn llreg_ty(cls: &[RegClass]) -> Type { fn llvec_len(cls: &[RegClass]) -> uint { let mut len = 1u; - for cls.each |c| { + for cls.iter().advance |c| { if *c != SSEUp { break; } @@ -355,7 +355,7 @@ fn x86_64_tys(atys: &[Type], let mut arg_tys = ~[]; let mut attrs = ~[]; - for atys.each |t| { + for atys.iter().advance |t| { let (ty, attr) = x86_64_ty(*t, |cls| cls.is_pass_byval(), ByValAttribute); arg_tys.push(ty); attrs.push(attr); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 0809b1c124e0..6120e1e65810 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -575,7 +575,7 @@ pub fn trans_call_inner(in_cx: block, // Uncomment this to debug calls. /* io::println(fmt!("calling: %s", bcx.val_to_str(llfn))); - for llargs.each |llarg| { + for llargs.iter().advance |llarg| { io::println(fmt!("arg: %s", bcx.val_to_str(*llarg))); } io::println("---"); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 4ab9cd6c9571..6cff996d0d45 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -266,7 +266,7 @@ pub fn build_closure(bcx0: block, // Package up the captured upvars let mut env_vals = ~[]; - for cap_vars.each |cap_var| { + for cap_vars.iter().advance |cap_var| { debug!("Building closure: captured variable %?", *cap_var); let datum = expr::trans_local_var(bcx, cap_var.def); match cap_var.mode { @@ -346,7 +346,7 @@ pub fn load_environment(fcx: fn_ctxt, // Populate the upvars from the environment. let mut i = 0u; - for cap_vars.each |cap_var| { + for cap_vars.iter().advance |cap_var| { let mut upvarptr = GEPi(bcx, llcdata, [0u, i]); match sigil { ast::BorrowedSigil => { upvarptr = Load(bcx, upvarptr); } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 21e173fd0b43..7baa3ec068b8 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -143,7 +143,7 @@ pub struct param_substs { impl param_substs { pub fn validate(&self) { - for self.tys.each |t| { assert!(!ty::type_needs_infer(*t)); } + for self.tys.iter().advance |t| { assert!(!ty::type_needs_infer(*t)); } for self.self_ty.iter().advance |t| { assert!(!ty::type_needs_infer(*t)); } } } @@ -982,7 +982,7 @@ pub fn align_to(cx: block, off: ValueRef, align: ValueRef) -> ValueRef { pub fn path_str(sess: session::Session, p: &[path_elt]) -> ~str { let mut r = ~""; let mut first = true; - for p.each |e| { + for p.iter().advance |e| { match *e { ast_map::path_name(s) | ast_map::path_mod(s) => { if first { first = false; } diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 6be26354db16..f101a8657322 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -40,7 +40,7 @@ pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { do block_locals(b) |local| { bcx = alloc_local(bcx, local); }; - for b.node.stmts.each |s| { + for b.node.stmts.iter().advance |s| { debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); } @@ -113,7 +113,7 @@ pub fn trans_if(bcx: block, pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block { let out = sub_block(parent_bcx, "join"); let mut reachable = false; - for in_cxs.each |bcx| { + for in_cxs.iter().advance |bcx| { if !bcx.unreachable { Br(*bcx, out.llbb); reachable = true; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 269451b13070..2eadad7d8d1b 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -335,7 +335,7 @@ fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: sp let file_md = create_file(cx, loc.file.name); let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line); - for fields.each |field| { + for fields.iter().advance |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); let (size, align) = size_and_align_of(cx, field_t); @@ -362,7 +362,7 @@ fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span let name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned(); let mut scx = StructContext::new(cx, name, file_md, loc.line); - for elements.each |element| { + for elements.iter().advance |element| { let ty_md = create_ty(cx, *element, span); let (size, align) = size_and_align_of(cx, *element); scx.add_member("", loc.line, size, align, ty_md); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 44e571dfb2ff..58f04ab3b2ec 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1221,7 +1221,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, let mut bcx = bcx; let addr = match dest { Ignore => { - for fields.each |&(_i, e)| { + for fields.iter().advance |&(_i, e)| { bcx = trans_into(bcx, e, Ignore); } for optbase.iter().advance |sbi| { @@ -1233,7 +1233,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, }; let mut temp_cleanups = ~[]; adt::trans_start_init(bcx, repr, addr, discr); - for fields.each |&(i, e)| { + for fields.iter().advance |&(i, e)| { let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i); let e_ty = expr_ty(bcx, e); bcx = trans_into(bcx, e, SaveIn(dest)); @@ -1253,7 +1253,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, } } - for temp_cleanups.each |cleanup| { + for temp_cleanups.iter().advance |cleanup| { revoke_clean(bcx, *cleanup); } return bcx; diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 2d23942f601f..10e63e6af777 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -289,7 +289,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, Some(abi) => abi, }; - for foreign_mod.items.each |&foreign_item| { + for foreign_mod.items.iter().advance |&foreign_item| { match foreign_item.node { ast::foreign_item_fn(*) => { let id = foreign_item.id; diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 6fcab95996e8..f55523b28418 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -130,7 +130,7 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { // Compute max(variant sizes). let mut max_size = 0; let variants = ty::enum_variants(cx.tcx, tid); - for variants.each |variant| { + for variants.iter().advance |variant| { if variant.args.len() == 0 { loop; } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 3a8efb55c151..0b68ae5ee171 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -59,7 +59,7 @@ pub fn trans_impl(ccx: @mut CrateContext, if !generics.ty_params.is_empty() { return; } let sub_path = vec::append_one(path, path_name(name)); - for methods.each |method| { + for methods.iter().advance |method| { if method.generics.ty_params.len() == 0u { let llfn = get_item_val(ccx, method.id); let path = vec::append_one(/*bad*/copy sub_path, @@ -175,7 +175,7 @@ pub fn trans_self_arg(bcx: block, // FIXME(#3446)---this is wrong, actually. The temp_cleanups // should be revoked only after all arguments have been passed. - for temp_cleanups.each |c| { + for temp_cleanups.iter().advance |c| { revoke_clean(bcx, *c) } @@ -406,7 +406,7 @@ pub fn method_with_name_or_default(ccx: @mut CrateContext, let pmm = ccx.tcx.provided_methods; match pmm.find(&impl_id) { Some(pmis) => { - for pmis.each |pmi| { + for pmis.iter().advance |pmi| { if pmi.method_info.ident == name { debug!("pmi.method_info.did = %?", pmi.method_info.did); @@ -773,7 +773,7 @@ pub fn make_vtable(ccx: @mut CrateContext, let _icx = push_ctxt("impl::make_vtable"); let mut components = ~[ tydesc.tydesc ]; - for ptrs.each |&ptr| { + for ptrs.iter().advance |&ptr| { components.push(ptr) } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index ac5f53c243ef..fd382a869dfa 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -69,8 +69,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } }); - for real_substs.tps.each() |s| { assert!(!ty::type_has_params(*s)); } - for substs.each() |s| { assert!(!ty::type_has_params(*s)); } + 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, Some(param_uses)); @@ -340,7 +340,7 @@ pub fn make_mono_id(ccx: @mut CrateContext, let mut i = 0; vec::map_zip(*item_ty.generics.type_param_defs, substs, |type_param_def, subst| { let mut v = ~[]; - for type_param_def.bounds.trait_bounds.each |_bound| { + for type_param_def.bounds.trait_bounds.iter().advance |_bound| { v.push(meth::vtable_id(ccx, &vts[i])); i += 1; } diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs index 4641a13604b9..5cb52d2a0579 100644 --- a/src/librustc/middle/trans/reachable.rs +++ b/src/librustc/middle/trans/reachable.rs @@ -59,7 +59,7 @@ fn traverse_exports(cx: @mut ctx, mod_id: node_id) -> bool { let mut found_export = false; match cx.exp_map2.find(&mod_id) { Some(ref exp2s) => { - for (*exp2s).each |e2| { + for (*exp2s).iter().advance |e2| { found_export = true; traverse_def_id(cx, e2.def_id) }; @@ -90,7 +90,7 @@ fn traverse_def_id(cx: @mut ctx, did: def_id) { fn traverse_public_mod(cx: @mut ctx, mod_id: node_id, m: &_mod) { if !traverse_exports(cx, mod_id) { // No exports, so every local item is exported - for m.items.each |item| { + for m.items.iter().advance |item| { traverse_public_item(cx, *item); } } @@ -109,7 +109,7 @@ fn traverse_public_item(cx: @mut ctx, item: @item) { item_mod(ref m) => traverse_public_mod(cx, item.id, m), item_foreign_mod(ref nm) => { if !traverse_exports(cx, item.id) { - for nm.items.each |item| { + for nm.items.iter().advance |item| { let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut cx.rmap.insert(item.id); } @@ -122,7 +122,7 @@ fn traverse_public_item(cx: @mut ctx, item: @item) { } } item_impl(ref generics, _, _, ref ms) => { - for ms.each |m| { + for ms.iter().advance |m| { if generics.ty_params.len() > 0u || m.generics.ty_params.len() > 0u || attr::find_inline_attr(m.attrs) != attr::ia_none @@ -168,7 +168,7 @@ fn traverse_ty<'a>(ty: @Ty, (cx, v): (@mut ctx<'a>, visit::vt<@mut ctx<'a>>)) { Some(&d) => traverse_def_id(cx, def_id_of_def(d)), None => { /* do nothing -- but should we fail here? */ } } - for p.types.each |t| { + for p.types.iter().advance |t| { (v.visit_ty)(*t, (cx, v)); } } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index d543b2cc61c0..df8de7b7cd5a 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -376,7 +376,7 @@ pub fn write_content(bcx: block, ast::expr_vec(ref elements, _) => { match dest { Ignore => { - for elements.each |element| { + for elements.iter().advance |element| { bcx = expr::trans_into(bcx, *element, Ignore); } } @@ -392,7 +392,7 @@ pub fn write_content(bcx: block, add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); temp_cleanups.push(lleltptr); } - for temp_cleanups.each |cleanup| { + for temp_cleanups.iter().advance |cleanup| { revoke_clean(bcx, *cleanup); } } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 4f532885c92f..49cb3bd51ddb 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -78,7 +78,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { - for sig.inputs.each |arg| { + for sig.inputs.iter().advance |arg| { type_needs(cx, use_repr, *arg); } } @@ -214,7 +214,7 @@ pub fn type_needs_inner(cx: Context, if list::find(enums_seen, |id| *id == did).is_none() { let seen = @Cons(did, enums_seen); for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) |v| { - for v.args.each |aty| { + for v.args.iter().advance |aty| { let t = ty::subst(cx.ccx.tcx, &(*substs), *aty); type_needs_inner(cx, use_, t, seen); } @@ -314,7 +314,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) { match ty::ty_closure_sigil(ty::expr_ty(cx.ccx.tcx, e)) { ast::OwnedSigil => {} ast::BorrowedSigil | ast::ManagedSigil => { - for freevars::get_freevars(cx.ccx.tcx, e.id).each |fv| { + for freevars::get_freevars(cx.ccx.tcx, e.id).iter().advance |fv| { let node_id = ast_util::def_id_of_def(fv.def).node; node_type_needs(cx, use_repr, node_id); } @@ -344,7 +344,8 @@ pub fn mark_for_expr(cx: Context, e: @expr) { node_type_needs(cx, use_tydesc, val.id); } expr_call(f, _, _) => { - for ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, f.id)).each |a| { + let r = ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, f.id)); + for r.iter().advance |a| { type_needs(cx, use_repr, *a); } } @@ -352,17 +353,18 @@ pub fn mark_for_expr(cx: Context, e: @expr) { let base_ty = ty::node_id_to_type(cx.ccx.tcx, rcvr.id); type_needs(cx, use_repr, ty::type_autoderef(cx.ccx.tcx, base_ty)); - for ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, callee_id)).each |a| { + let r = ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, callee_id)); + for r.iter().advance |a| { type_needs(cx, use_repr, *a); } mark_for_method_call(cx, e.id, callee_id); } expr_inline_asm(ref ia) => { - for ia.inputs.each |&(_, in)| { + for ia.inputs.iter().advance |&(_, in)| { node_type_needs(cx, use_repr, in.id); } - for ia.outputs.each |&(_, out)| { + for ia.outputs.iter().advance |&(_, out)| { node_type_needs(cx, use_repr, out.id); } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e67955505f6d..a367cf4c430a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1018,7 +1018,7 @@ fn mk_t(cx: ctxt, st: sty) -> t { } fn sflags(substs: &substs) -> uint { let mut f = 0u; - for substs.tps.each |tt| { f |= get(*tt).flags; } + for substs.tps.iter().advance |tt| { f |= get(*tt).flags; } for substs.self_r.iter().advance |r| { f |= rflags(*r) } return f; } @@ -1057,16 +1057,16 @@ fn mk_t(cx: ctxt, st: sty) -> t { flags |= rflags(r); flags |= get(m.ty).flags; } - &ty_tup(ref ts) => for ts.each |tt| { flags |= get(*tt).flags; }, + &ty_tup(ref ts) => for ts.iter().advance |tt| { flags |= get(*tt).flags; }, &ty_bare_fn(ref f) => { - for f.sig.inputs.each |a| { flags |= get(*a).flags; } + for f.sig.inputs.iter().advance |a| { flags |= get(*a).flags; } flags |= get(f.sig.output).flags; // T -> _|_ is *not* _|_ ! flags &= !(has_ty_bot as uint); } &ty_closure(ref f) => { flags |= rflags(f.region); - for f.sig.inputs.each |a| { flags |= get(*a).flags; } + for f.sig.inputs.iter().advance |a| { flags |= get(*a).flags; } flags |= get(f.sig.output).flags; // T -> _|_ is *not* _|_ ! flags &= !(has_ty_bot as uint); @@ -1320,15 +1320,15 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { } ty_enum(_, ref substs) | ty_struct(_, ref substs) | ty_trait(_, ref substs, _, _) => { - for (*substs).tps.each |subty| { maybe_walk_ty(*subty, f); } + for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, f); } } - ty_tup(ref ts) => { for ts.each |tt| { maybe_walk_ty(*tt, f); } } + ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, f); } } ty_bare_fn(ref ft) => { - for ft.sig.inputs.each |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } maybe_walk_ty(ft.sig.output, f); } ty_closure(ref ft) => { - for ft.sig.inputs.each |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } maybe_walk_ty(ft.sig.output, f); } } @@ -1772,8 +1772,8 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t, true } ty_enum(did, ref substs) => { - for (*enum_variants(cx, did)).each |v| { - for v.args.each |aty| { + for (*enum_variants(cx, did)).iter().advance |v| { + for v.args.iter().advance |aty| { let t = subst(cx, substs, *aty); needs_unwind_cleanup |= type_needs_unwind_cleanup_(cx, t, tycache, @@ -2407,8 +2407,8 @@ pub fn type_structurally_contains(cx: ctxt, if test(sty) { return true; } match *sty { ty_enum(did, ref substs) => { - for (*enum_variants(cx, did)).each |variant| { - for variant.args.each |aty| { + for (*enum_variants(cx, did)).iter().advance |variant| { + for variant.args.iter().advance |aty| { let sty = subst(cx, substs, *aty); if type_structurally_contains(cx, sty, test) { return true; } } @@ -2416,7 +2416,8 @@ pub fn type_structurally_contains(cx: ctxt, return false; } ty_struct(did, ref substs) => { - for lookup_struct_fields(cx, did).each |field| { + let r = lookup_struct_fields(cx, did); + for r.iter().advance |field| { let ft = lookup_field_type(cx, did, field.id, substs); if type_structurally_contains(cx, ft, test) { return true; } } @@ -2424,7 +2425,7 @@ pub fn type_structurally_contains(cx: ctxt, } ty_tup(ref ts) => { - for ts.each |tt| { + for ts.iter().advance |tt| { if type_structurally_contains(cx, *tt, test) { return true; } } return false; @@ -2503,7 +2504,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { // Structural types ty_enum(did, ref substs) => { let variants = enum_variants(cx, did); - for (*variants).each |variant| { + for (*variants).iter().advance |variant| { let tup_ty = mk_tup(cx, /*bad*/copy variant.args); // Perform any type parameter substitutions. @@ -2512,7 +2513,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { } } ty_tup(ref elts) => { - for elts.each |elt| { if !type_is_pod(cx, *elt) { result = false; } } + for elts.iter().advance |elt| { if !type_is_pod(cx, *elt) { result = false; } } } ty_estr(vstore_fixed(_)) => result = true, ty_evec(ref mt, vstore_fixed(_)) | ty_unboxed_vec(ref mt) => { @@ -3357,14 +3358,14 @@ pub fn stmt_node_id(s: @ast::stmt) -> ast::node_id { pub fn field_idx(id: ast::ident, fields: &[field]) -> Option { let mut i = 0u; - for fields.each |f| { if f.ident == id { return Some(i); } i += 1u; } + for fields.iter().advance |f| { if f.ident == id { return Some(i); } i += 1u; } return None; } pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field]) -> uint { let mut i = 0u; - for fields.each |f| { if f.ident == id { return i; } i += 1u; } + for fields.iter().advance |f| { if f.ident == id { return i; } i += 1u; } tcx.sess.bug(fmt!( "No field named `%s` found in the list of fields `%?`", tcx.sess.str_of(id), @@ -4383,7 +4384,7 @@ pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id), pub fn each_bound_trait_and_supertraits(tcx: ctxt, bounds: &ParamBounds, f: &fn(@TraitRef) -> bool) -> bool { - for bounds.trait_bounds.each |&bound_trait_ref| { + for bounds.trait_bounds.iter().advance |&bound_trait_ref| { let mut supertrait_set = HashMap::new(); let mut trait_refs = ~[]; let mut i = 0; @@ -4403,7 +4404,7 @@ pub fn each_bound_trait_and_supertraits(tcx: ctxt, // Add supertraits to supertrait_set let supertrait_refs = trait_ref_supertraits(tcx, trait_refs[i]); - for supertrait_refs.each |&supertrait_ref| { + for supertrait_refs.iter().advance |&supertrait_ref| { debug!("each_bound_trait_and_supertraits(supertrait_ref=%s)", supertrait_ref.repr(tcx)); @@ -4424,7 +4425,7 @@ pub fn each_bound_trait_and_supertraits(tcx: ctxt, pub fn count_traits_and_supertraits(tcx: ctxt, type_param_defs: &[TypeParameterDef]) -> uint { let mut total = 0; - for type_param_defs.each |type_param_def| { + for type_param_defs.iter().advance |type_param_def| { for each_bound_trait_and_supertraits(tcx, type_param_def.bounds) |_| { total += 1; } diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 3a661f74239a..de6b792032b1 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -35,7 +35,7 @@ pub fn check_match(fcx: @mut FnCtxt, // Typecheck the patterns first, so that we get types for all the // bindings. - for arms.each |arm| { + for arms.iter().advance |arm| { let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, arm.pats[0]), @@ -43,14 +43,14 @@ pub fn check_match(fcx: @mut FnCtxt, block_region: ty::re_scope(arm.body.node.id) }; - for arm.pats.each |p| { check_pat(&pcx, *p, pattern_ty);} + for arm.pats.iter().advance |p| { check_pat(&pcx, *p, pattern_ty);} } // Now typecheck the blocks. let mut result_ty = fcx.infcx().next_ty_var(); let mut arm_non_bot = false; let mut saw_err = false; - for arms.each |arm| { + for arms.iter().advance |arm| { let mut guard_err = false; let mut guard_bot = false; match arm.guard { @@ -248,7 +248,7 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, if error_happened { for subpats.iter().advance |pats| { - for pats.each |pat| { + for pats.iter().advance |pat| { check_pat(pcx, *pat, ty::mk_err()); } } @@ -280,7 +280,7 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt, // Typecheck each field. let mut found_fields = HashSet::new(); - for fields.each |field| { + for fields.iter().advance |field| { match field_map.find(&field.ident) { Some(&index) => { let class_field = class_fields[index]; @@ -516,7 +516,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { fcx.write_ty(pat.id, expected); } _ => { - for elts.each |elt| { + for elts.iter().advance |elt| { check_pat(pcx, *elt, ty::mk_err()); } // use terr_tuple_size if both types are tuples @@ -565,13 +565,13 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { (mt, default_region_var) }, _ => { - for before.each |&elt| { + for before.iter().advance |&elt| { check_pat(pcx, elt, ty::mk_err()); } for slice.iter().advance |&elt| { check_pat(pcx, elt, ty::mk_err()); } - for after.each |&elt| { + for after.iter().advance |&elt| { check_pat(pcx, elt, ty::mk_err()); } fcx.infcx().type_error_message_str_with_expected( @@ -587,7 +587,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { return; } }; - for before.each |elt| { + for before.iter().advance |elt| { check_pat(pcx, *elt, elt_type.ty); } match slice { @@ -600,7 +600,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { } None => () } - for after.each |elt| { + for after.iter().advance |elt| { check_pat(pcx, *elt, elt_type.ty); } fcx.write_ty(pat.id, expected); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 7e66c99c4fe1..33d1377d000d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -333,14 +333,14 @@ impl<'self> LookupContext<'self> { let trait_map: &mut resolve::TraitMap = &mut self.fcx.ccx.trait_map; let opt_applicable_traits = trait_map.find(&self.expr.id); for opt_applicable_traits.iter().advance |applicable_traits| { - for applicable_traits.each |trait_did| { + for applicable_traits.iter().advance |trait_did| { let coherence_info = self.fcx.ccx.coherence_info; // Look for explicit implementations. let opt_impl_infos = coherence_info.extension_methods.find(trait_did); for opt_impl_infos.iter().advance |impl_infos| { - for impl_infos.each |impl_info| { + for impl_infos.iter().advance |impl_info| { self.push_candidates_from_impl( self.extension_candidates, *impl_info); @@ -486,7 +486,7 @@ impl<'self> LookupContext<'self> { } // No method found yet? Check each supertrait if method_info.is_none() { - for ty::trait_supertraits(tcx, did).each() |trait_ref| { + 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) { @@ -527,7 +527,7 @@ impl<'self> LookupContext<'self> { let opt_impl_infos = self.fcx.ccx.coherence_info.inherent_methods.find(&did); for opt_impl_infos.iter().advance |impl_infos| { - for impl_infos.each |impl_info| { + for impl_infos.iter().advance |impl_info| { self.push_candidates_from_impl( self.inherent_candidates, *impl_info); } @@ -767,7 +767,7 @@ impl<'self> LookupContext<'self> { // This is hokey. We should have mutability inference as a // variable. But for now, try &const, then &, then &mut: let region = self.infcx().next_region_var_nb(self.expr.span); - for mutbls.each |mutbl| { + for mutbls.iter().advance |mutbl| { let autoref_ty = mk_autoref_ty(*mutbl, region); match self.search_for_method(autoref_ty) { None => {} diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a8ae90414826..fa7959c7872b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -550,7 +550,7 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt, fields: ~[(ast::ident, span)]) { let mut field_names = HashMap::new(); - for fields.each |p| { + for fields.iter().advance |p| { let (id, sp) = *p; let orig_sp = field_names.find(&id).map_consume(|x| *x); match orig_sp { @@ -599,12 +599,12 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { let rp = ccx.tcx.region_paramd_items.find(&it.id).map_consume(|x| *x); debug!("item_impl %s with id %d rp %?", ccx.tcx.sess.str_of(it.ident), it.id, rp); - for ms.each |m| { + for ms.iter().advance |m| { check_method(ccx, *m); } } ast::item_trait(_, _, ref trait_methods) => { - for (*trait_methods).each |trait_method| { + for (*trait_methods).iter().advance |trait_method| { match *trait_method { required(*) => { // Nothing to do, since required methods don't have @@ -625,11 +625,11 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { } ast::item_foreign_mod(ref m) => { if m.abis.is_intrinsic() { - for m.items.each |item| { + for m.items.iter().advance |item| { check_intrinsic_type(ccx, *item); } } else { - for m.items.each |item| { + for m.items.iter().advance |item| { let tpt = ty::lookup_item_type(ccx.tcx, local_def(item.id)); if tpt.generics.has_type_params() { ccx.tcx.sess.span_err( @@ -1225,7 +1225,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // functions. This is so that we have more information about the types // of arguments when we typecheck the functions. This isn't really the // right way to do this. - for [false, true].each |check_blocks| { + let xs = [false, true]; + for xs.iter().advance |check_blocks| { let check_blocks = *check_blocks; debug!("check_blocks=%b", check_blocks); @@ -1803,14 +1804,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let mut class_field_map = HashMap::new(); let mut fields_found = 0; - for field_types.each |field| { + for field_types.iter().advance |field| { class_field_map.insert(field.ident, (field.id, false)); } let mut error_happened = false; // Typecheck each field. - for ast_fields.each |field| { + for ast_fields.iter().advance |field| { let mut expected_field_type = ty::mk_err(); let pair = class_field_map.find(&field.node.ident). @@ -1856,7 +1857,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, assert!(fields_found <= field_types.len()); if fields_found < field_types.len() { let mut missing_fields = ~[]; - for field_types.each |class_field| { + for field_types.iter().advance |class_field| { let name = class_field.ident; let (_, seen) = *class_field_map.get(&name); if !seen { @@ -2175,7 +2176,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, _ => mutability = mutbl } let t: ty::t = fcx.infcx().next_ty_var(); - for args.each |e| { + for args.iter().advance |e| { check_expr_has_type(fcx, *e, t); let arg_t = fcx.expr_ty(*e); if ty::type_is_error(arg_t) { @@ -2377,10 +2378,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, ty_param_bounds_and_ty.ty); } ast::expr_inline_asm(ref ia) => { - for ia.inputs.each |&(_, in)| { + for ia.inputs.iter().advance |&(_, in)| { check_expr(fcx, in); } - for ia.outputs.each |&(_, out)| { + for ia.outputs.iter().advance |&(_, out)| { check_expr(fcx, out); } fcx.write_nil(id); @@ -2506,7 +2507,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // We know there's at least one because we already checked // for n=0 as well as all arms being _|_ in the previous // `if`. - for arm_tys.each() |arm_ty| { + for arm_tys.iter().advance |arm_ty| { if !ty::type_is_bot(*arm_ty) { fcx.write_ty(id, *arm_ty); break; @@ -2687,7 +2688,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let t: ty::t = fcx.infcx().next_ty_var(); let mut arg_is_bot = false; let mut arg_is_err = false; - for args.each |e| { + for args.iter().advance |e| { check_expr_has_type(fcx, *e, t); let arg_t = fcx.expr_ty(*e); arg_is_bot |= ty::type_is_bot(arg_t); @@ -2948,7 +2949,7 @@ pub fn check_block_with_expected(fcx: @mut FnCtxt, let mut last_was_bot = false; let mut any_bot = false; let mut any_err = false; - for blk.node.stmts.each |s| { + for blk.node.stmts.iter().advance |s| { check_stmt(fcx, *s); let s_id = ast_util::stmt_id(*s); let s_ty = fcx.node_ty(s_id); @@ -3085,7 +3086,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, disr_val: &mut int, variants: &mut ~[ty::VariantInfo]) { let rty = ty::node_id_to_type(ccx.tcx, id); - for vs.each |v| { + for vs.iter().advance |v| { for v.node.disr_expr.iter().advance |e_ref| { let e = *e_ref; debug!("disr expr, checking %s", diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 2ff8ffdd6b21..ac89c48a29b2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -184,7 +184,7 @@ fn visit_block(b: &ast::blk, (rcx, v): (@mut Rcx, rvt)) { fn visit_arm(arm: &ast::arm, (rcx, v): (@mut Rcx, rvt)) { // see above - for arm.pats.each |&p| { + for arm.pats.iter().advance |&p| { constrain_bindings_in_pat(p, rcx); } @@ -267,7 +267,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { } ast::expr_match(_, ref arms) => { tcx.region_maps.record_cleanup_scope(expr.id); - for arms.each |arm| { + for arms.iter().advance |arm| { for arm.guard.iter().advance |guard| { tcx.region_maps.record_cleanup_scope(guard.id); } @@ -476,7 +476,7 @@ fn constrain_call(rcx: @mut Rcx, let callee_scope = call_expr.id; let callee_region = ty::re_scope(callee_scope); - for arg_exprs.each |&arg_expr| { + for arg_exprs.iter().advance |&arg_expr| { // ensure that any regions appearing in the argument type are // valid for at least the lifetime of the function: constrain_regions_in_type_of_node( @@ -614,7 +614,7 @@ fn constrain_free_variables(rcx: @mut Rcx, let tcx = rcx.fcx.ccx.tcx; debug!("constrain_free_variables(%s, %s)", region.repr(tcx), expr.repr(tcx)); - for get_freevars(tcx, expr.id).each |freevar| { + for get_freevars(tcx, expr.id).iter().advance |freevar| { debug!("freevar def is %?", freevar.def); let def = freevar.def; let en_region = encl_region_of_def(rcx.fcx, def); @@ -824,8 +824,8 @@ pub mod guarantor { debug!("regionck::for_match()"); let discr_guarantor = guarantor(rcx, discr); debug!("discr_guarantor=%s", discr_guarantor.repr(rcx.tcx())); - for arms.each |arm| { - for arm.pats.each |pat| { + for arms.iter().advance |arm| { + for arm.pats.iter().advance |pat| { link_ref_bindings_in_pat(rcx, *pat, discr_guarantor); } } @@ -1217,7 +1217,7 @@ pub mod guarantor { link_ref_bindings_in_pats(rcx, pats, guarantor); } ast::pat_struct(_, ref fpats, _) => { - for fpats.each |fpat| { + for fpats.iter().advance |fpat| { link_ref_bindings_in_pat(rcx, fpat.pat, guarantor); } } @@ -1258,7 +1258,7 @@ pub mod guarantor { fn link_ref_bindings_in_pats(rcx: @mut Rcx, pats: &~[@ast::pat], guarantor: Option) { - for pats.each |pat| { + for pats.iter().advance |pat| { link_ref_bindings_in_pat(rcx, *pat, guarantor); } } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 54b449eeb40f..160737142c8c 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -231,7 +231,7 @@ pub fn relate_nested_regions( r_sub: ty::Region, relate_op: &fn(ty::Region, ty::Region)) { - for the_stack.each |&r| { + for the_stack.iter().advance |&r| { if !r.is_bound() && !r_sub.is_bound() { relate_op(r, r_sub); } @@ -259,14 +259,14 @@ pub fn relate_free_regions( debug!("relate_free_regions >>"); let mut all_tys = ~[]; - for fn_sig.inputs.each |arg| { + for fn_sig.inputs.iter().advance |arg| { all_tys.push(*arg); } for self_ty.iter().advance |&t| { all_tys.push(t); } - for all_tys.each |&t| { + for all_tys.iter().advance |&t| { debug!("relate_free_regions(t=%s)", ppaux::ty_to_str(tcx, t)); relate_nested_regions(tcx, None, t, |a, b| { match (&a, &b) { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index e1b9ebf977f8..5ce95e23e2c7 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -88,7 +88,7 @@ fn lookup_vtables(vcx: &VtableContext, let tcx = vcx.tcx(); let mut result = ~[]; let mut i = 0u; - for substs.tps.each |ty| { + for substs.tps.iter().advance |ty| { // ty is the value supplied for the type parameter A... for ty::each_bound_trait_and_supertraits( diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index a60fa9ee0be1..dd9d68beb1fd 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -175,7 +175,7 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: span, id: ast::node_id) write_ty_to_tcx(tcx, id, t); for fcx.opt_node_ty_substs(id) |substs| { let mut new_tps = ~[]; - for substs.tps.each |subst| { + for substs.tps.iter().advance |subst| { match resolve_type_vars_in_type(fcx, sp, *subst) { Some(t) => new_tps.push(t), None => { wbcx.success = false; return None; } @@ -240,7 +240,7 @@ fn visit_expr(e: @ast::expr, (wbcx, v): (@mut WbCtxt, wb_vt)) { match e.node { ast::expr_fn_block(ref decl, _) => { - for decl.inputs.each |input| { + for decl.inputs.iter().advance |input| { let _ = resolve_type_vars_for_node(wbcx, e.span, input.id); } } @@ -341,7 +341,7 @@ pub fn resolve_type_vars_in_fn(fcx: @mut FnCtxt, self_info.span, self_info.self_id); } - for decl.inputs.each |arg| { + for decl.inputs.iter().advance |arg| { do pat_util::pat_bindings(fcx.tcx().def_map, arg.pat) |_bm, pat_id, span, _path| { resolve_type_vars_for_node(wbcx, span, pat_id); diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index e6a62c8f1b1f..bf935d92c75c 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -270,7 +270,7 @@ impl CoherenceChecker { // We only want to generate one Impl structure. When we generate one, // we store it here so that we don't recreate it. let mut implementation_opt = None; - for associated_traits.each |&associated_trait| { + for associated_traits.iter().advance |&associated_trait| { let trait_ref = ty::node_id_to_trait_ref( self.crate_context.tcx, @@ -536,11 +536,12 @@ impl CoherenceChecker { // XXX: This is horrible. let mut provided_method_idents = HashSet::new(); let tcx = self.crate_context.tcx; - for ty::provided_trait_methods(tcx, trait_did).each |ident| { + let r = ty::provided_trait_methods(tcx, trait_did); + for r.iter().advance |ident| { provided_method_idents.insert(*ident); } - for ty::trait_methods(tcx, trait_did).each |&method| { + for ty::trait_methods(tcx, trait_did).iter().advance |&method| { if provided_method_idents.contains(&method.ident) { if !f(method) { return false; @@ -611,7 +612,8 @@ impl CoherenceChecker { if result.is_ok() { // Check to ensure that each parameter binding respected its // kind bounds. - for [ a, b ].each |result| { + let xs = [a, b]; + for xs.iter().advance |result| { for result.type_variables.iter() .zip(result.type_param_defs.iter()) .advance |(ty_var, type_param_def)| @@ -728,12 +730,14 @@ impl CoherenceChecker { provided_names.insert(all_methods[i].ident); } // Default methods - for ty::provided_trait_methods(tcx, trait_did).each |ident| { + let r = ty::provided_trait_methods(tcx, trait_did); + for r.iter().advance |ident| { debug!("inserting provided method %s", ident.repr(tcx)); provided_names.insert(*ident); } - for (*ty::trait_methods(tcx, trait_did)).each |method| { + let r = ty::trait_methods(tcx, trait_did); + for r.iter().advance |method| { debug!("checking for %s", method.ident.repr(tcx)); if provided_names.contains(&method.ident) { loop; } @@ -802,7 +806,7 @@ impl CoherenceChecker { debug!("(creating impl) trait with node_id `%d` \ has provided methods", trait_did.node); // Add all provided methods. - for all_provided_methods.each |provided_method| { + for all_provided_methods.iter().advance |provided_method| { debug!( "(creating impl) adding provided method \ `%s` to impl", @@ -821,7 +825,7 @@ impl CoherenceChecker { match item.node { item_impl(_, ref trait_refs, _, ref ast_methods) => { let mut methods = ~[]; - for ast_methods.each |ast_method| { + for ast_methods.iter().advance |ast_method| { methods.push(method_to_MethodInfo(*ast_method)); } @@ -882,7 +886,7 @@ impl CoherenceChecker { let implementations = get_impls_for_mod(crate_store, module_def_id, None); - for implementations.each |implementation| { + for implementations.iter().advance |implementation| { debug!("coherence: adding impl from external crate: %s", ty::item_path_str(self.crate_context.tcx, implementation.did)); @@ -1009,7 +1013,7 @@ impl CoherenceChecker { Some(found_impls) => impls = found_impls } - for impls.each |impl_info| { + for impls.iter().advance |impl_info| { if impl_info.methods.len() < 1 { // We'll error out later. For now, just don't ICE. loop; diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index ef456e9a1f90..7f820d11ac61 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -66,13 +66,13 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { // FIXME (#2592): hooking into the "intrinsic" root module is crude. // There ought to be a better approach. Attributes? - for crate.node.module.items.each |crate_item| { + for crate.node.module.items.iter().advance |crate_item| { if crate_item.ident == ::syntax::parse::token::special_idents::intrinsic { match crate_item.node { ast::item_mod(ref m) => { - for m.items.each |intrinsic_item| { + for m.items.iter().advance |intrinsic_item| { let def_id = ast::def_id { crate: ast::local_crate, node: intrinsic_item.id }; let substs = substs { @@ -168,7 +168,7 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt, let tcx = ccx.tcx; // Create a set of parameter types shared among all the variants. - for variants.each |variant| { + for variants.iter().advance |variant| { let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); @@ -233,7 +233,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, // For each method, construct a suitable ty::Method and // store it into the `tcx.methods` table: - for ms.each |m| { + for ms.iter().advance |m| { let ty_method = @match m { &ast::required(ref m) => { ty_method_of_trait_method( @@ -416,7 +416,7 @@ 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.each |&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); @@ -686,7 +686,7 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, // Trait methods we don't implement must be default methods, but if not // we'll catch it in coherence let trait_ms = ty::trait_methods(tcx, trait_ref.def_id); - for impl_ms.each |impl_m| { + for impl_ms.iter().advance |impl_m| { match trait_ms.iter().find_(|trait_m| trait_m.ident == impl_m.mty.ident) { Some(trait_m) => { let num_impl_tps = generics.ty_params.len(); @@ -921,7 +921,7 @@ pub fn convert_struct(ccx: &CrateCtxt, let tcx = ccx.tcx; // Write the type of each of the members - for struct_def.fields.each |f| { + for struct_def.fields.iter().advance |f| { convert_field(ccx, rp, tpt.generics.type_param_defs, *f, generics); } let (_, substs) = mk_item_substs(ccx, generics, rp, None); diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 700a78699b1e..a1e16cfbe838 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -223,7 +223,7 @@ impl Combine for Glb { let mut a_r = None; let mut b_r = None; let mut only_new_vars = true; - for tainted.each |r| { + for tainted.iter().advance |r| { if is_var_in_set(a_vars, *r) { if a_r.is_some() { return fresh_bound_variable(this); diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 529fc48ebdf4..d9add22479cc 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1572,8 +1572,8 @@ impl RegionVarBindings { return; } - for lower_bounds.each |lower_bound| { - for upper_bounds.each |upper_bound| { + for lower_bounds.iter().advance |lower_bound| { + for upper_bounds.iter().advance |upper_bound| { if !self.is_subregion_of(lower_bound.region, upper_bound.region) { @@ -1629,8 +1629,8 @@ impl RegionVarBindings { return; } - for upper_bounds.each |upper_bound_1| { - for upper_bounds.each |upper_bound_2| { + for upper_bounds.iter().advance |upper_bound_1| { + for upper_bounds.iter().advance |upper_bound_2| { match self.glb_concrete_regions(upper_bound_1.region, upper_bound_2.region) { Ok(_) => {} diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index c5e0e2c8f016..4462d43015cf 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -198,7 +198,7 @@ impl Combine for Sub { for list::each(skol_isr) |pair| { let (skol_br, skol) = *pair; let tainted = self.infcx.region_vars.tainted(snapshot, skol); - for tainted.each |tainted_region| { + for tainted.iter().advance |tainted_region| { // Each skolemized should only be relatable to itself // or new variables: match *tainted_region { diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index 0db9d16adf3c..a3d11bedbdc7 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -79,7 +79,7 @@ fn setup_env(test_name: &str, source_string: &str) -> Env { impl Env { pub fn create_region_hierarchy(&self, rh: &RH) { - for rh.sub.each |child_rh| { + for rh.sub.iter().advance |child_rh| { self.create_region_hierarchy(child_rh); self.tcx.region_map.insert(child_rh.id, rh.id); } @@ -109,7 +109,7 @@ impl Env { idx: uint, names: &[~str]) -> Option { assert!(idx < names.len()); - for m.items.each |item| { + for m.items.iter().advance |item| { if self.tcx.sess.str_of(item.ident) == names[idx] { return search(self, *item, idx+1, names); } @@ -227,7 +227,7 @@ impl Env { self.infcx.resolve_regions(); if self.err_messages.len() != exp_count { - for self.err_messages.each |msg| { + for self.err_messages.iter().advance |msg| { debug!("Error encountered: %s", *msg); } fmt!("Resolving regions encountered %u errors but expected %u!", diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index 709d631de117..16b490cd478d 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -75,7 +75,7 @@ impl RegionParamNames { opt_vec::Vec(new_lifetimes.map(|lt| lt.ident))); } opt_vec::Vec(ref mut existing_lifetimes) => { - for new_lifetimes.each |new_lifetime| { + for new_lifetimes.iter().advance |new_lifetime| { existing_lifetimes.push(new_lifetime.ident); } } diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index afa517d99a5b..d59a308beb53 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -184,7 +184,8 @@ Available lint options: pub fn describe_debug_flags() { io::println(fmt!("\nAvailable debug options:\n")); - for session::debugging_opts_map().each |pair| { + let r = session::debugging_opts_map(); + for r.iter().advance |pair| { let (name, desc, _) = /*bad*/copy *pair; io::println(fmt!(" -Z %-20s -- %s", name, desc)); } @@ -344,13 +345,14 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) { diagnostic::ice_msg("unexpected failure"), diagnostic::error); - for [ + let xs = [ ~"the compiler hit an unexpected failure path. \ this is a bug", ~"try running with RUST_LOG=rustc=1,::rt::backtrace \ to get further details and report the results \ to github.com/mozilla/rust/issues" - ].each |note| { + ]; + for xs.iter().advance |note| { diagnostic::emit(None, *note, diagnostic::note) } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 8994c81bfb96..c730e74c9036 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -395,7 +395,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { } // if there is an id, print that instead of the structural type: - /*for ty::type_def_id(typ).each |def_id| { + /*for ty::type_def_id(typ).iter().advance |def_id| { // note that this typedef cannot have type parameters return ast_map::path_to_str(ty::item_path(cx, *def_id), cx.sess.intr()); @@ -573,7 +573,7 @@ impl Repr for ty::ParamBounds { ty::BoundSized => ~"Sized", }); } - for self.trait_bounds.each |t| { + for self.trait_bounds.iter().advance |t| { res.push(t.repr(tcx)); } res.connect("+") diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e6732a05f009..52851b9100a4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -76,7 +76,8 @@ pub fn usage() { println("Usage: rustdoc [options] \n"); println("Options:\n"); - for opts().each |opt| { + let r = opts(); + for r.iter().advance |opt| { println(fmt!(" %s", opt.second())); } println(""); diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index f8c49f544bc2..b6131dce9c85 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -144,7 +144,7 @@ fn nmoddoc_from_mod( module_: ast::foreign_mod ) -> doc::NmodDoc { let mut fns = ~[]; - for module_.items.each |item| { + for module_.items.iter().advance |item| { let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match item.node { ast::foreign_item_fn(*) => { diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 1d024d1f8b40..6622ea1551bf 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -280,7 +280,7 @@ fn write_desc( } fn write_sections(ctxt: &Ctxt, sections: &[doc::Section]) { - for sections.each |section| { + for sections.iter().advance |section| { write_section(ctxt, copy *section); } } @@ -300,7 +300,7 @@ fn write_mod_contents( write_index(ctxt, doc.index.get_ref()); } - for doc.items.each |itemTag| { + for doc.items.iter().advance |itemTag| { write_item(ctxt, copy *itemTag); } } @@ -350,7 +350,7 @@ fn write_index(ctxt: &Ctxt, index: &doc::Index) { ctxt.w.put_line(~"

"); ctxt.w.put_line(~""); - for index.entries.each |entry| { + for index.entries.iter().advance |entry| { let header = header_text_(entry.kind, entry.name); let id = copy entry.link; if entry.brief.is_some() { @@ -371,7 +371,7 @@ fn write_nmod(ctxt: &Ctxt, doc: doc::NmodDoc) { write_index(ctxt, doc.index.get_ref()); } - for doc.fns.each |FnDoc| { + for doc.fns.iter().advance |FnDoc| { write_item_header(ctxt, doc::FnTag(copy *FnDoc)); write_fn(ctxt, copy *FnDoc); } @@ -441,7 +441,7 @@ fn write_variants( write_header_(ctxt, H4, ~"Variants"); - for docs.each |variant| { + for docs.iter().advance |variant| { write_variant(ctxt, copy *variant); } @@ -480,7 +480,7 @@ fn write_trait(ctxt: &Ctxt, doc: doc::TraitDoc) { } fn write_methods(ctxt: &Ctxt, docs: &[doc::MethodDoc]) { - for docs.each |doc| { + for docs.iter().advance |doc| { write_method(ctxt, copy *doc); } } diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 513baa67ac1c..91fde3e21ae0 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -112,7 +112,7 @@ impl Program { None => {} } - for new_locals.each |p| { + for new_locals.iter().advance |p| { code.push_str(fmt!("assert_encodable(&%s);\n", *p.first_ref())); } code.push_str("};}"); @@ -370,7 +370,7 @@ impl Program { // helper functions to perform ast iteration fn each_user_local(blk: &ast::blk, f: &fn(@ast::local)) { do find_user_block(blk) |blk| { - for blk.node.stmts.each |stmt| { + for blk.node.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_decl(d, _) => { match d.node { @@ -385,7 +385,7 @@ impl Program { } fn find_user_block(blk: &ast::blk, f: &fn(&ast::blk)) { - for blk.node.stmts.each |stmt| { + for blk.node.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_semi(e, _) => { match e.node { diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 263f5395e51b..57a2a48a0f63 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -130,7 +130,7 @@ fn run(mut repl: Repl, input: ~str) -> Repl { 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.each |vi| { + for blk.node.view_items.iter().advance |vi| { let s = do with_pp(intr) |pp, _| { pprust::print_view_item(pp, *vi); }; @@ -144,7 +144,7 @@ fn run(mut repl: Repl, input: ~str) -> Repl { // Iterate through all of the block's statements, inserting them into // the correct portions of the program - for blk.node.stmts.each |stmt| { + 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, _) => { @@ -248,7 +248,7 @@ fn run(mut repl: Repl, input: ~str) -> Repl { fn find_main(crate: @ast::crate, sess: session::Session, f: &fn(&ast::blk)) { - for crate.node.module.items.each |item| { + for crate.node.module.items.iter().advance |item| { match item.node { ast::item_fn(_, _, _, _, ref blk) => { if item.ident == sess.ident_of("main") { @@ -365,7 +365,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, } ~"load" => { let mut loaded_crates: ~[~str] = ~[]; - for args.each |arg| { + 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) @@ -377,7 +377,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, None => { } } } - for loaded_crates.each |crate| { + 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)); diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 23fb130941c9..9b727e9d3e05 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -147,7 +147,7 @@ impl PkgSrc { assert!(p.components.len() > prefix); let mut sub = Path(""); for vec::slice(p.components, prefix, - p.components.len()).each |c| { + p.components.len()).iter().advance |c| { sub = sub.push(*c); } debug!("found crate %s", sub.to_str()); @@ -204,7 +204,7 @@ impl PkgSrc { crates: &[Crate], cfgs: &[~str], what: OutputType) { - for crates.each |&crate| { + for crates.iter().advance |&crate| { let path = &src_dir.push_rel(&crate.file).normalize(); note(fmt!("build_crates: compiling %s", path.to_str())); note(fmt!("build_crates: destination dir is %s", dst_dir.to_str())); diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index e68f48c81629..6d146145f36f 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -43,7 +43,8 @@ pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, u_rwx) } /// pkgid's short name pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool { let src_dir = workspace.push("src"); - for os::list_dir(&src_dir).each |&p| { + let dirs = os::list_dir(&src_dir); + for dirs.iter().advance |&p| { let p = Path(p); debug!("=> p = %s", p.to_str()); if !os::path_is_dir(&src_dir.push_rel(&p)) { @@ -93,7 +94,7 @@ pub fn pkgid_src_in_workspace(pkgid: &PkgId, workspace: &Path) -> ~[Path] { /// Returns a src for pkgid that does exist -- None if none of them do pub fn first_pkgid_src_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option { let rs = pkgid_src_in_workspace(pkgid, workspace); - for rs.each |p| { + for rs.iter().advance |p| { if os::path_exists(p) { return Some(copy *p); } @@ -189,7 +190,7 @@ pub fn library_in_workspace(path: &LocalPath, short_name: &str, where: Target, debug!("lib_prefix = %s and lib_filetype = %s", lib_prefix, lib_filetype); let mut result_filename = None; - for dir_contents.each |&p| { + for dir_contents.iter().advance |&p| { let mut which = 0; let mut hash = None; let p_path = Path(p); diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 355cbed9ab55..973b960008be 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -272,7 +272,7 @@ fn touch_source_file(workspace: &Path, short_name: &str) { use conditions::bad_path::cond; let pkg_src_dir = workspace.push("src").push(short_name); let contents = os::list_dir(&pkg_src_dir); - for contents.each() |p| { + for contents.iter().advance |p| { if Path(copy *p).filetype() == Some(~".rs") { // should be able to do this w/o a process if run::process_output("touch", [p.to_str()]).status != 0 { @@ -289,7 +289,7 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId) { let pkg_src_dir = workspace.push("src").push(pkgid.to_str()); let contents = os::list_dir(&pkg_src_dir); let mut maybe_p = None; - for contents.each() |p| { + for contents.iter().advance |p| { if Path(copy *p).filetype() == Some(~".rs") { maybe_p = Some(p); break; diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 7a6384421209..6d39495002a4 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -103,10 +103,10 @@ fn fold_item(ctx: @mut ReadyCtx, if attrs.len() > 0 { let mut cmds = ~[]; - for attrs.each |attr| { + for attrs.iter().advance |attr| { match attr.node.value.node { ast::meta_list(_, ref mis) => { - for mis.each |mi| { + for mis.iter().advance |mi| { match mi.node { ast::meta_word(cmd) => cmds.push(cmd.to_owned()), _ => {} @@ -211,7 +211,7 @@ pub fn compile_input(ctxt: &Ctx, let addl_lib_search_paths = @mut options.addl_lib_search_paths; // Make sure all the library directories actually exist, since the linker will complain // otherwise - for addl_lib_search_paths.each() |p| { + for addl_lib_search_paths.iter().advance |p| { assert!(os::path_is_dir(p)); } @@ -280,7 +280,7 @@ pub fn compile_crate_from_input(input: &driver::input, debug!("Outputs are %? and output type = %?", outputs, sess.opts.output_type); debug!("additional libraries:"); - for sess.opts.addl_lib_search_paths.each |lib| { + for sess.opts.addl_lib_search_paths.iter().advance |lib| { debug!("an additional library: %s", lib.to_str()); } @@ -311,7 +311,7 @@ pub fn compile_crate(ctxt: &Ctx, pkg_id: &PkgId, what: OutputType) -> bool { debug!("compile_crate: crate=%s, dir=%s", crate.to_str(), dir.to_str()); debug!("compile_crate: short_name = %s, flags =...", pkg_id.to_str()); - for flags.each |&fl| { + for flags.iter().advance |&fl| { debug!("+++ %s", fl); } compile_input(ctxt, pkg_id, crate, dir, flags, cfgs, opt, what) diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index 54144f8e31f2..bd576dc44a46 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -25,7 +25,7 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b pkgid.remote_path.to_str(), rust_path().to_str()); } - for workspaces.each |ws| { + for workspaces.iter().advance |ws| { if action(ws) { break; } @@ -36,4 +36,4 @@ 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)) -} \ No newline at end of file +} diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 3875847ff9bb..2b846c923c48 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -12,13 +12,14 @@ use cast::transmute; use container::Container; +use iterator::IteratorUtil; use kinds::Copy; use old_iter; -use old_iter::BaseIter; use option::Option; use sys; use uint; use vec; +use vec::ImmutableVector; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. @@ -107,7 +108,7 @@ pub fn build_sized_opt(size: Option, #[inline] pub fn append(lhs: @[T], rhs: &const [T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { - for lhs.each |x| { push(copy *x); } + for lhs.iter().advance |x| { push(copy *x); } for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); } } } @@ -116,7 +117,7 @@ pub fn append(lhs: @[T], rhs: &const [T]) -> @[T] { /// Apply a function to each element of a vector and return the results pub fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { do build_sized(v.len()) |push| { - for v.each |elem| { + for v.iter().advance |elem| { push(f(elem)); } } diff --git a/src/libstd/either.rs b/src/libstd/either.rs index 681a7fbc821f..b6da93f9d40a 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -15,11 +15,11 @@ use container::Container; use cmp::Eq; use kinds::Copy; -use old_iter::BaseIter; +use iterator::IteratorUtil; use result::Result; use result; use vec; -use vec::OwnedVector; +use vec::{OwnedVector, ImmutableVector}; /// The either type #[deriving(Clone, Eq)] @@ -45,7 +45,7 @@ pub fn either(f_left: &fn(&T) -> V, /// Extracts from a vector of either all the left values pub fn lefts(eithers: &[Either]) -> ~[T] { do vec::build_sized(eithers.len()) |push| { - for eithers.each |elt| { + for eithers.iter().advance |elt| { match *elt { Left(ref l) => { push(copy *l); } _ => { /* fallthrough */ } @@ -57,7 +57,7 @@ pub fn lefts(eithers: &[Either]) -> ~[T] { /// Extracts from a vector of either all the right values pub fn rights(eithers: &[Either]) -> ~[U] { do vec::build_sized(eithers.len()) |push| { - for eithers.each |elt| { + for eithers.iter().advance |elt| { match *elt { Right(ref r) => { push(copy *r); } _ => { /* fallthrough */ } diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index 1967a57e867f..8e88bfb46329 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -22,10 +22,11 @@ #[allow(missing_doc)]; use container::Container; -use old_iter::BaseIter; +use iterator::IteratorUtil; use rt::io::Writer; use to_bytes::IterBytes; use uint; +use vec::ImmutableVector; // Alias `SipState` to `State`. pub use State = hash::SipState; @@ -367,7 +368,7 @@ impl Streaming for SipState { fn result_str(&mut self) -> ~str { let r = self.result_bytes(); let mut s = ~""; - for r.each |b| { + for r.iter().advance |b| { s += uint::to_str_radix(*b as uint, 16u); } s @@ -469,7 +470,7 @@ mod tests { fn to_hex_str(r: &[u8, ..8]) -> ~str { let mut s = ~""; - for (*r).each |b| { + for r.iter().advance |b| { s += uint::to_str_radix(*b as uint, 16u); } s diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index d05fa63a6f9b..02fa2de4b032 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -20,12 +20,13 @@ use cmp::{Eq, Equiv}; use hash::Hash; use old_iter::BaseIter; use old_iter; -use iterator::{IteratorUtil}; +use iterator::IteratorUtil; use option::{None, Option, Some}; use rand::RngUtil; use rand; use uint; use vec; +use vec::ImmutableVector; use kinds::Copy; use util::{replace, unreachable}; @@ -310,7 +311,7 @@ impl Map for HashMap { /// Visit all key-value pairs fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - for self.buckets.each |bucket| { + for self.buckets.iter().advance |bucket| { for bucket.iter().advance |pair| { if !blk(&pair.key, &pair.value) { return false; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 715f2fdabd3b..fc0b4da79bd8 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -57,7 +57,7 @@ use os; use cast; use path::Path; use ops::Drop; -use old_iter::{BaseIter, CopyableIter}; +use iterator::IteratorUtil; use ptr; use result; use str; @@ -65,7 +65,7 @@ use str::StrSlice; use to_str::ToStr; use uint; use vec; -use vec::{OwnedVector, OwnedCopyableVector, CopyableVector}; +use vec::{ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector}; #[allow(non_camel_case_types)] // not sure what to do about this pub type fd_t = c_int; @@ -1261,7 +1261,7 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) fn wb() -> c_int { O_WRONLY as c_int } let mut fflags: c_int = wb(); - for flags.each |f| { + for flags.iter().advance |f| { match *f { Append => fflags |= O_APPEND as c_int, Create => fflags |= O_CREAT as c_int, @@ -2015,7 +2015,7 @@ mod tests { // write the ints to the file { let file = io::file_writer(&path, [io::Create]).get(); - for uints.each |i| { + for uints.iter().advance |i| { file.write_le_u64(*i); } } @@ -2023,7 +2023,7 @@ mod tests { // then read them back and check that they are the same { let file = io::file_reader(&path).get(); - for uints.each |i| { + for uints.iter().advance |i| { assert_eq!(file.read_le_u64(), *i); } } @@ -2037,7 +2037,7 @@ mod tests { // write the ints to the file { let file = io::file_writer(&path, [io::Create]).get(); - for uints.each |i| { + for uints.iter().advance |i| { file.write_be_u64(*i); } } @@ -2045,7 +2045,7 @@ mod tests { // then read them back and check that they are the same { let file = io::file_reader(&path).get(); - for uints.each |i| { + for uints.iter().advance |i| { assert_eq!(file.read_be_u64(), *i); } } @@ -2059,7 +2059,7 @@ mod tests { // write the ints to the file { let file = io::file_writer(&path, [io::Create]).get(); - for ints.each |i| { + for ints.iter().advance |i| { file.write_be_i32(*i); } } @@ -2067,7 +2067,7 @@ mod tests { // then read them back and check that they are the same { let file = io::file_reader(&path).get(); - for ints.each |i| { + for ints.iter().advance |i| { // this tests that the sign extension is working // (comparing the values as i32 would not test this) assert_eq!(file.read_be_int_n(4), *i as i64); diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 7053cbe0df5a..4e598a4aa1cd 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -56,7 +56,7 @@ pub trait FromIter { /// /// ~~~ {.rust} /// let xs = ~[1, 2, 3]; - /// let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) }; + /// 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; @@ -69,8 +69,8 @@ pub trait FromIter { * * ~~~ {.rust} * let xs = ~[1u, 2, 3, 4, 5]; - * assert!(any(|&x: &uint| x > 2, |f| xs.each(f))); - * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f))); + * assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + * assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); * ~~~ */ #[inline] @@ -109,7 +109,7 @@ pub fn all(predicate: &fn(T) -> bool, * * ~~~ {.rust} * let xs = ~[1u, 2, 3, 4, 5, 6]; - * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4); + * assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.iter().advance(f)).unwrap(), 4); * ~~~ */ #[inline] @@ -130,7 +130,7 @@ pub fn find(predicate: &fn(&T) -> bool, * * ~~~ {.rust} * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.each(f)).unwrap(), &15); + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &15); * ~~~ */ #[inline] @@ -156,7 +156,7 @@ pub fn max(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option { * * ~~~ {.rust} * let xs = ~[8, 2, 3, 1, -5, 9, 11, 15]; - * assert_eq!(max(|f| xs.each(f)).unwrap(), &-5); + * assert_eq!(max(|f| xs.iter().advance(f)).unwrap(), &-5); * ~~~ */ #[inline] @@ -223,7 +223,7 @@ pub fn fold_ref(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&m * * ~~~ {.rust} * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do sum |f| { xs.each(f) }, 10); + * assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); * ~~~ */ #[inline] @@ -238,7 +238,7 @@ pub fn sum>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T { * * ~~~ {.rust} * let xs: ~[int] = ~[1, 2, 3, 4]; - * assert_eq!(do product |f| { xs.each(f) }, 24); + * assert_eq!(do product |f| { xs.iter().advance(f) }, 24); * ~~~ */ #[inline] @@ -257,15 +257,15 @@ mod tests { #[test] fn test_from_iter() { let xs = ~[1, 2, 3]; - let ys: ~[int] = do FromIter::from_iter |f| { xs.each(|x| f(*x)) }; + 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.each(f))); - assert!(!any(|&x: &uint| x > 5, |f| xs.each(f))); + assert!(any(|&x: &uint| x > 2, |f| xs.iter().advance(f))); + assert!(!any(|&x: &uint| x > 5, |f| xs.iter().advance(f))); } #[test] @@ -277,19 +277,19 @@ mod tests { #[test] fn test_find() { let xs = ~[1u, 2, 3, 4, 5, 6]; - assert_eq!(*find(|& &x: & &uint| x > 3, |f| xs.each(f)).unwrap(), 4); + 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.each(f)).unwrap(), &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.each(f)).unwrap(), &-5); + assert_eq!(min(|f| xs.iter().advance(f)).unwrap(), &-5); } #[test] @@ -300,24 +300,24 @@ mod tests { #[test] fn test_sum() { let xs: ~[int] = ~[1, 2, 3, 4]; - assert_eq!(do sum |f| { xs.each(f) }, 10); + assert_eq!(do sum |f| { xs.iter().advance(f) }, 10); } #[test] fn test_empty_sum() { let xs: ~[int] = ~[]; - assert_eq!(do sum |f| { xs.each(f) }, 0); + 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.each(f) }, 24); + assert_eq!(do product |f| { xs.iter().advance(f) }, 24); } #[test] fn test_empty_product() { let xs: ~[int] = ~[]; - assert_eq!(do product |f| { xs.each(f) }, 1); + assert_eq!(do product |f| { xs.iter().advance(f) }, 1); } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 59b40b93d4d1..1ceb22b20ca6 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -224,7 +224,7 @@ pub fn env() -> ~[(~str,~str)] { fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] { let mut pairs = ~[]; - for input.each |p| { + for input.iter().advance |p| { let vs: ~[&str] = p.splitn_iter('=', 1).collect(); debug!("splitting: len: %u", vs.len()); @@ -593,7 +593,8 @@ pub fn tmpdir() -> Path { /// Recursively walk a directory structure pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool { - list_dir(p).each(|q| { + let r = list_dir(p); + r.iter().advance(|q| { let path = &p.push(*q); f(path) && (!path_is_dir(path) || walk_dir(path, f)) }) @@ -1528,7 +1529,7 @@ mod tests { fn test_env_getenv() { let e = env(); assert!(e.len() > 0u); - for e.each |p| { + for e.iter().advance |p| { let (n, v) = copy *p; debug!(copy n); let v2 = getenv(n); @@ -1599,8 +1600,8 @@ mod tests { setenv("USERPROFILE", "/home/PaloAlto"); assert_eq!(os::homedir(), Some(Path("/home/MountainView"))); - oldhome.each(|s| { setenv("HOME", *s); true }); - olduserprofile.each(|s| { setenv("USERPROFILE", *s); true }); + oldhome.iter().advance(|s| { setenv("HOME", *s); true }); + olduserprofile.iter().advance(|s| { setenv("USERPROFILE", *s); true }); } #[test] @@ -1620,7 +1621,7 @@ mod tests { // Just assuming that we've got some contents in the current directory assert!(dirs.len() > 0u); - for dirs.each |dir| { + for dirs.iter().advance |dir| { debug!(copy *dir); } } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index d7812bf49c21..700bfff3f5d7 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -25,8 +25,7 @@ use str; use str::{Str, StrSlice, StrVector}; use to_str::ToStr; use ascii::{AsciiCast, AsciiStr}; -use old_iter::BaseIter; -use vec::OwnedVector; +use vec::{OwnedVector, ImmutableVector}; #[cfg(windows)] pub use Path = self::WindowsPath; @@ -596,7 +595,7 @@ impl GenericPath for PosixPath { fn push_many(&self, cs: &[S]) -> PosixPath { let mut v = copy self.components; - for cs.each |e| { + for cs.iter().advance |e| { for e.as_slice().split_iter(windows::is_sep).advance |s| { if !s.is_empty() { v.push(s.to_owned()) @@ -853,7 +852,7 @@ impl GenericPath for WindowsPath { fn push_many(&self, cs: &[S]) -> WindowsPath { let mut v = copy self.components; - for cs.each |e| { + for cs.iter().advance |e| { for e.as_slice().split_iter(windows::is_sep).advance |s| { if !s.is_empty() { v.push(s.to_owned()) @@ -915,7 +914,7 @@ impl GenericPath for WindowsPath { pub fn normalize(components: &[~str]) -> ~[~str] { let mut cs = ~[]; - for components.each |c| { + for components.iter().advance |c| { if *c == ~"." && components.len() > 1 { loop; } if *c == ~"" { loop; } if *c == ~".." && cs.len() != 0 { diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 739e3dfedc7f..c49e2af2f029 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -544,7 +544,7 @@ impl RngUtil for R { fn choose_weighted_option(&mut self, v: &[Weighted]) -> Option { let mut total = 0u; - for v.each |item| { + for v.iter().advance |item| { total += item.weight; } if total == 0u { @@ -552,7 +552,7 @@ impl RngUtil for R { } let chosen = self.gen_uint_range(0u, total); let mut so_far = 0u; - for v.each |item| { + for v.iter().advance |item| { so_far += item.weight; if so_far > chosen { return Some(copy item.item); @@ -567,7 +567,7 @@ impl RngUtil for R { */ fn weighted_vec(&mut self, v: &[Weighted]) -> ~[T] { let mut r = ~[]; - for v.each |item| { + for v.iter().advance |item| { for uint::range(0u, item.weight) |_i| { r.push(copy item.item); } @@ -746,7 +746,8 @@ impl IsaacRng { }} ); - for [(0, midpoint), (midpoint, 0)].each |&(mr_offset, m2_offset)| { + let r = [(0, midpoint), (midpoint, 0)]; + for r.iter().advance |&(mr_offset, m2_offset)| { for uint::range_step(0, midpoint, 4) |base| { rngstep!(0, 13); rngstep!(1, -6); diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 6cef5c33de06..0b099b66ecf0 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -16,10 +16,10 @@ use cmp::Eq; use either; use either::Either; use kinds::Copy; +use iterator::IteratorUtil; use option::{None, Option, Some}; -use old_iter::BaseIter; use vec; -use vec::OwnedVector; +use vec::{OwnedVector, ImmutableVector}; use container::Container; /// The result type @@ -303,7 +303,7 @@ pub fn map_vec( ts: &[T], op: &fn(&T) -> Result) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(ts.len()); - for ts.each |t| { + for ts.iter().advance |t| { match op(t) { Ok(v) => vs.push(v), Err(u) => return Err(u) diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs index 4571747cebf6..ada9aee35a7e 100644 --- a/src/libstd/rt/uv/net.rs +++ b/src/libstd/rt/uv/net.rs @@ -389,7 +389,8 @@ mod test { if status.is_none() { rtdebug!("got %d bytes", nread); let buf = buf.unwrap(); - for buf.slice(0, nread as uint).each |byte| { + let r = buf.slice(0, nread as uint); + for r.iter().advance |byte| { assert!(*byte == count as u8); rtdebug!("%u", *byte as uint); count += 1; diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 060de3f4d5d5..c965af7c10ce 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -582,7 +582,7 @@ pub fn make_command_line(prog: &str, args: &[~str]) -> ~str { let mut cmd = ~""; append_arg(&mut cmd, prog); - for args.each |arg| { + for args.iter().advance |arg| { cmd.push_char(' '); append_arg(&mut cmd, *arg); } @@ -698,7 +698,7 @@ fn with_argv(prog: &str, args: &[~str], cb: &fn(**libc::c_char) -> T) -> T { let mut argptrs = ~[str::as_c_str(prog, |b| b)]; let mut tmps = ~[]; - for args.each |arg| { + for args.iter().advance |arg| { let t = @copy *arg; tmps.push(t); argptrs.push(str::as_c_str(*t, |b| b)); @@ -716,7 +716,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T { let mut tmps = ~[]; let mut ptrs = ~[]; - for es.each |&(k, v)| { + for es.iter().advance |&(k, v)| { let kv = @fmt!("%s=%s", k, v); tmps.push(kv); ptrs.push(str::as_c_str(*kv, |b| b)); @@ -739,7 +739,7 @@ fn with_envp(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T { match env { Some(es) => { let mut blk = ~[]; - for es.each |&(k, v)| { + for es.iter().advance |&(k, v)| { let kv = fmt!("%s=%s", k, v); blk.push_all(kv.as_bytes_with_null_consume()); } @@ -1165,7 +1165,8 @@ mod tests { let mut prog = run_env(None); let output = str::from_bytes(prog.finish_with_output().output); - for os::env().each |&(k, v)| { + let r = os::env(); + for r.iter().advance |&(k, v)| { // don't check windows magical empty-named variables assert!(k.is_empty() || output.contains(fmt!("%s=%s", k, v))); } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index f3226b27d1be..45ba85283754 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -29,7 +29,7 @@ use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIter use libc; use num::Zero; use option::{None, Option, Some}; -use old_iter::{BaseIter, EqIter}; +use old_iter::EqIter; use ptr; use ptr::RawPtr; use to_str::ToStr; @@ -147,7 +147,7 @@ pub fn from_char(ch: char) -> ~str { pub fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; buf.reserve(chs.len()); - for chs.each |ch| { + for chs.iter().advance |ch| { buf.push_char(*ch) } buf @@ -864,7 +864,7 @@ pub mod raw { unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) { let new_len = s.len() + bytes.len(); s.reserve_at_least(new_len); - for bytes.each |byte| { push_byte(&mut *s, *byte); } + for bytes.iter().advance |byte| { push_byte(&mut *s, *byte); } } /// Removes the last byte from a string and returns it. (Not UTF-8 safe). @@ -3080,7 +3080,7 @@ mod tests { 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16, 0x000a_u16 ]) ]; - for pairs.each |p| { + for pairs.iter().advance |p| { let (s, u) = copy *p; assert!(s.to_utf16() == u); assert!(from_utf16(u) == s); @@ -3094,7 +3094,7 @@ mod tests { let s = ~"ศไทย中华Việt Nam"; let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; let mut pos = 0; - for v.each |ch| { + for v.iter().advance |ch| { assert!(s.char_at(pos) == *ch); pos += from_char(*ch).len(); } diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs index c71765f911af..d8b50c96fd8d 100644 --- a/src/libstd/str/ascii.rs +++ b/src/libstd/str/ascii.rs @@ -14,7 +14,6 @@ use to_str::{ToStr,ToStrConsume}; use str; use str::StrSlice; use cast; -use old_iter::BaseIter; use iterator::IteratorUtil; use vec::{CopyableVector, ImmutableVector, OwnedVector}; use to_bytes::IterBytes; @@ -94,7 +93,7 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] { #[inline] fn is_ascii(&self) -> bool { - for self.each |b| { + for self.iter().advance |b| { if !b.is_ascii() { return false; } } true diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 822aab0a0271..6f0c615d007c 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -17,9 +17,10 @@ The `ToBytes` and `IterBytes` traits use cast; use io; use io::Writer; +use iterator::IteratorUtil; use option::{None, Option, Some}; -use old_iter::BaseIter; use str::StrSlice; +use vec::ImmutableVector; pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool; @@ -223,7 +224,7 @@ impl IterBytes for f64 { impl<'self,A:IterBytes> IterBytes for &'self [A] { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { - self.each(|elt| elt.iter_bytes(lsb0, |b| f(b))) + self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b))) } } diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 3e782e728fe3..c6ac2c89f32e 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -17,10 +17,12 @@ The `ToStr` trait for converting to strings use str::OwnedStr; use hashmap::HashMap; use hashmap::HashSet; +use iterator::IteratorUtil; use container::Map; use hash::Hash; use cmp::Eq; use old_iter::BaseIter; +use vec::ImmutableVector; /// A generic trait for converting a value to a string pub trait ToStr { @@ -122,7 +124,7 @@ impl<'self,A:ToStr> ToStr for &'self [A] { #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); - for self.each |elt| { + for self.iter().advance |elt| { if first { first = false; } @@ -140,7 +142,7 @@ impl ToStr for ~[A] { #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); - for self.each |elt| { + for self.iter().advance |elt| { if first { first = false; } @@ -158,7 +160,7 @@ impl ToStr for @[A] { #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"[", true); - for self.each |elt| { + for self.iter().advance |elt| { if first { first = false; } diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index aaeaa489834f..39980ffa5991 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -373,7 +373,7 @@ pub fn check_integrity(trie: &TrieNode) { let mut sum = 0; - for trie.children.each |x| { + for trie.children.iter().advance |x| { match *x { Nothing => (), Internal(ref y) => { diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index 79aa22fabea8..235dfa018493 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -237,7 +237,7 @@ mod tests { } }; - for futures.each |f| { f.recv() } + for futures.iter().advance |f| { f.recv() } do total.with |total| { assert!(**total == num_tasks * count) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 62b42eebfbbd..17eb7e8e82be 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -17,7 +17,6 @@ use cast; use container::{Container, Mutable}; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; -use old_iter::BaseIter; use old_iter; use iterator::{FromIterator, Iterator, IteratorUtil}; use iter::FromIter; @@ -1025,7 +1024,7 @@ impl<'self, T:Copy> VectorVector for &'self [~[T]] { pub fn connect_vec(&self, sep: &T) -> ~[T] { let mut r = ~[]; let mut first = true; - for self.each |&inner| { + for self.iter().advance |&inner| { if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } @@ -1043,7 +1042,7 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { pub fn connect_vec(&self, sep: &T) -> ~[T] { let mut r = ~[]; let mut first = true; - for self.each |&inner| { + for self.iter().advance |&inner| { if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } @@ -1749,7 +1748,7 @@ impl<'self,T:Copy> CopyableVector for &'self [T] { fn to_owned(&self) -> ~[T] { let mut result = ~[]; reserve(&mut result, self.len()); - for self.each |e| { + for self.iter().advance |e| { result.push(copy *e); } result @@ -2399,15 +2398,6 @@ pub mod bytes { } } -impl<'self,A> old_iter::BaseIter for &'self [A] { - #[inline] - fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) -> bool { - each(*self, blk) - } - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } -} - impl Clone for ~[A] { #[inline] fn clone(&self) -> ~[A] { diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 943a38a337ff..f243bcb0abb0 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -87,7 +87,7 @@ fn each_abi(op: &fn(abi: Abi) -> bool) -> bool { * Iterates through each of the defined ABIs. */ - AbiDatas.each(|abi_data| op(abi_data.abi)) + AbiDatas.iter().advance(|abi_data| op(abi_data.abi)) } pub fn lookup(name: &str) -> Option { @@ -213,7 +213,7 @@ impl AbiSet { for abis.iter().enumerate().advance |(i, abi)| { let data = abi.data(); - for abis.slice(0, i).each |other_abi| { + for abis.slice(0, i).iter().advance |other_abi| { let other_data = other_abi.data(); debug!("abis=(%?,%?) datas=(%?,%?)", abi, data.abi_arch, @@ -389,7 +389,7 @@ fn indices_are_correct() { #[cfg(test)] fn check_arch(abis: &[Abi], arch: Architecture, expect: Option) { let mut set = AbiSet::empty(); - for abis.each |&abi| { + for abis.iter().advance |&abi| { set.add(abi); } let r = set.for_arch(arch); diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index a7c29e8a869a..a0e1ec69350c 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -185,7 +185,7 @@ pub fn map_fn( (cx,v): (@mut Ctx, visit::vt<@mut Ctx>) ) { - for decl.inputs.each |a| { + for decl.inputs.iter().advance |a| { cx.map.insert(a.id, node_arg); } visit::visit_fn(fk, decl, body, sp, id, (cx, v)); @@ -220,19 +220,19 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) { match i.node { item_impl(_, _, _, ref ms) => { let impl_did = ast_util::local_def(i.id); - for ms.each |m| { + for ms.iter().advance |m| { map_method(impl_did, extend(cx, i.ident), *m, cx); } } item_enum(ref enum_definition, _) => { - for (*enum_definition).variants.each |v| { + for (*enum_definition).variants.iter().advance |v| { cx.map.insert(v.node.id, node_variant( /* FIXME (#2543) */ copy *v, i, extend(cx, i.ident))); } } item_foreign_mod(ref nm) => { - for nm.items.each |nitem| { + for nm.items.iter().advance |nitem| { // Compute the visibility for this native item. let visibility = match nitem.vis { public => public, @@ -266,10 +266,10 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) { ); } item_trait(_, ref traits, ref methods) => { - for traits.each |p| { + for traits.iter().advance |p| { cx.map.insert(p.ref_id, node_item(i, item_path)); } - for methods.each |tm| { + for methods.iter().advance |tm| { let id = ast_util::trait_method_to_ty_method(tm).id; let d_id = ast_util::local_def(i.id); cx.map.insert( diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index a4ded8fea8c4..34c247662a4e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -281,7 +281,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method]) -> (~[ty_method], ~[@method]) { let mut reqd = ~[]; let mut provd = ~[]; - for trait_methods.each |trt_method| { + for trait_methods.iter().advance |trt_method| { match *trt_method { required(ref tm) => reqd.push(copy *tm), provided(m) => provd.push(m) @@ -411,13 +411,13 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { match vi.node { view_item_extern_mod(_, _, id) => vfn(id, copy t), view_item_use(ref vps) => { - for vps.each |vp| { + for vps.iter().advance |vp| { match vp.node { view_path_simple(_, _, id) => vfn(id, copy t), view_path_glob(_, id) => vfn(id, copy t), view_path_list(_, ref paths, id) => { vfn(id, copy t); - for paths.each |p| { + for paths.iter().advance |p| { vfn(p.node.id, copy t); } } @@ -437,7 +437,7 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { vfn(i.id, copy t); match i.node { item_enum(ref enum_definition, _) => - for (*enum_definition).variants.each |v| { vfn(v.node.id, copy t); }, + for (*enum_definition).variants.iter().advance |v| { vfn(v.node.id, copy t); }, _ => () } visit::visit_item(i, (t, vt)); @@ -500,7 +500,7 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { } } - for d.inputs.each |arg| { + for d.inputs.iter().advance |arg| { vfn(arg.id, copy t) } visit::visit_fn(fk, d, a, b, id, (copy t, vt)); @@ -546,16 +546,16 @@ pub fn walk_pat(pat: @pat, it: &fn(@pat) -> bool) -> bool { match pat.node { pat_ident(_, _, Some(p)) => walk_pat(p, it), pat_struct(_, ref fields, _) => { - fields.each(|f| walk_pat(f.pat, it)) + fields.iter().advance(|f| walk_pat(f.pat, it)) } pat_enum(_, Some(ref s)) | pat_tup(ref s) => { - s.each(|&p| walk_pat(p, it)) + s.iter().advance(|&p| walk_pat(p, it)) } pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } pat_vec(ref before, ref slice, ref after) => { - before.each(|&p| walk_pat(p, it)) && + before.iter().advance(|&p| walk_pat(p, it)) && slice.iter().advance(|&p| walk_pat(p, it)) && after.iter().advance(|&p| walk_pat(p, it)) } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 96e05fd2beb4..d9fb91e6ddd8 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -158,7 +158,7 @@ pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) -> ~[@ast::meta_item] { let mut rs = ~[]; - for metas.each |mi| { + for metas.iter().advance |mi| { if name == get_meta_item_name(*mi) { rs.push(*mi) } @@ -172,7 +172,7 @@ pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) -> */ pub fn contains(haystack: &[@ast::meta_item], needle: @ast::meta_item) -> bool { - for haystack.each |item| { + for haystack.iter().advance |item| { if eq(*item, needle) { return true; } } return false; @@ -193,7 +193,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { ast::meta_list(ref na, ref misa) => match b.node { ast::meta_list(ref nb, ref misb) => { if na != nb { return false; } - for misa.each |mi| { + for misa.iter().advance |mi| { if !misb.iter().any_(|x| x == mi) { return false; } } true @@ -334,7 +334,7 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { pub fn require_unique_names(diagnostic: @span_handler, metas: &[@ast::meta_item]) { let mut set = HashSet::new(); - for metas.each |meta| { + for metas.iter().advance |meta| { let name = get_meta_item_name(*meta); // FIXME: How do I silence the warnings? --pcw (#2619) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 0c09a001d48e..bae5e943a48d 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -422,7 +422,7 @@ impl CodeMap { } pub fn get_filemap(&self, filename: &str) -> @FileMap { - for self.files.each |fm| { if filename == fm.name { return *fm; } } + for self.files.iter().advance |fm| { if filename == fm.name { return *fm; } } //XXjdm the following triggers a mismatched type bug // (or expected function, found _|_) fail!(); // ("asking for " + filename + " which we don't know about"); @@ -508,7 +508,7 @@ impl CodeMap { // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; - for map.multibyte_chars.each |mbc| { + for map.multibyte_chars.iter().advance |mbc| { debug!("codemap: %?-byte char at %?", mbc.bytes, mbc.pos); if mbc.pos < bpos { total_extra_bytes += mbc.bytes; diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index c0a23593f85e..7b4ed19fe7fa 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -256,7 +256,7 @@ fn highlight_lines(cm: @codemap::CodeMap, elided = true; } // Print the offending lines - for display_lines.each |line| { + for display_lines.iter().advance |line| { io::stderr().write_str(fmt!("%s:%u ", fm.name, *line + 1u)); let s = fm.get_line(*line as int) + "\n"; io::stderr().write_str(s); diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs index 59a9ec407b03..3f64654dd802 100644 --- a/src/libsyntax/ext/bytes.rs +++ b/src/libsyntax/ext/bytes.rs @@ -21,7 +21,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> bas let exprs = get_exprs_from_tts(cx, tts); let mut bytes = ~[]; - for exprs.each |expr| { + for exprs.iter().advance |expr| { match expr.node { // expression is a literal ast::expr_lit(lit) => match lit.node { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index d44d46682994..dca1b7bbd593 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -286,7 +286,7 @@ impl<'self> TraitDef<'self> { _mitem: @ast::meta_item, in_items: ~[@ast::item]) -> ~[@ast::item] { let mut result = ~[]; - for in_items.each |item| { + for in_items.iter().advance |item| { result.push(*item); match item.node { ast::item_struct(struct_def, ref generics) => { @@ -740,7 +740,7 @@ impl<'self> MethodDef<'self> { let mut enum_matching_fields = vec::from_elem(self_vec.len(), ~[]); - for matches_so_far.tail().each |&(_, _, other_fields)| { + for matches_so_far.tail().iter().advance |&(_, _, other_fields)| { for other_fields.iter().enumerate().advance |(i, &(_, other_field))| { enum_matching_fields[i].push(other_field); } @@ -870,7 +870,7 @@ fn summarise_struct(cx: @ExtCtxt, span: span, struct_def: &struct_def) -> Either { let mut named_idents = ~[]; let mut unnamed_count = 0; - for struct_def.fields.each |field| { + for struct_def.fields.iter().advance |field| { match field.node.kind { ast::named_field(ident, _) => named_idents.push(ident), ast::unnamed_field => unnamed_count += 1, diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 83cff70d4597..c7949f9a8e31 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -76,7 +76,7 @@ fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @ _ => cx.span_bug(span, "Impossible substructure in `deriving(IterBytes)`") } - for fields.each |&(_, field, _)| { + for fields.iter().advance |&(_, field, _)| { exprs.push(call_iterbytes(field)); } diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 4425d54987cd..4c0a85b665ae 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -70,7 +70,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, fn make_rt_conv_expr(cx: @ExtCtxt, sp: span, cnv: &Conv) -> @ast::expr { fn make_flags(cx: @ExtCtxt, sp: span, flags: &[Flag]) -> @ast::expr { let mut tmp_expr = make_rt_path_expr(cx, sp, "flag_none"); - for flags.each |f| { + for flags.iter().advance |f| { let fstr = match *f { FlagLeftJustify => "flag_left_justify", FlagLeftZeroPad => "flag_left_zero_pad", @@ -156,7 +156,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, option::None => (), _ => cx.span_unimpl(sp, unsupported) } - for cnv.flags.each |f| { + for cnv.flags.iter().advance |f| { match *f { FlagLeftJustify => (), FlagSignAlways => { @@ -205,7 +205,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, Some(p) => { debug!("param: %s", p.to_str()); } _ => debug!("param: none") } - for c.flags.each |f| { + for c.flags.iter().advance |f| { match *f { FlagLeftJustify => debug!("flag: left justify"), FlagLeftZeroPad => debug!("flag: left zero pad"), diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 083386fe720c..8478a827e85d 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -209,7 +209,7 @@ impl to_type_decls for state { let mut items_msg = ~[]; - for self.messages.each |m| { + for self.messages.iter().advance |m| { let message(name, span, tys, this, next) = copy *m; let tys = match next { @@ -372,7 +372,7 @@ impl gen_init for protocol { fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { let mut params: OptVec = opt_vec::Empty; - for (copy self.states).each |s| { + for (copy self.states).iter().advance |s| { for s.generics.ty_params.each |tp| { match params.find(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), @@ -433,7 +433,7 @@ impl gen_init for protocol { let mut client_states = ~[]; let mut server_states = ~[]; - for (copy self.states).each |s| { + for (copy self.states).iter().advance |s| { items += s.to_type_decls(cx); client_states += s.to_endpoint_decls(cx, send); diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 3df19ed0a76e..d00f1fd7746d 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -107,7 +107,7 @@ impl state_ { /// Iterate over the states that can be reached in one message /// from this state. pub fn reachable(&self, f: &fn(state) -> bool) -> bool { - for self.messages.each |m| { + for self.messages.iter().advance |m| { match *m { message(_, _, _, _, Some(next_state { state: ref id, _ })) => { let state = self.proto.get_state((*id)); @@ -165,7 +165,7 @@ impl protocol_ { } pub fn has_ty_params(&self) -> bool { - for self.states.each |s| { + for self.states.iter().advance |s| { if s.generics.ty_params.len() > 0 { return true; } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 44e480dc7df2..742f5a97825f 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -637,7 +637,7 @@ fn mk_tt(cx: @ExtCtxt, sp: span, tt: &ast::token_tree) fn mk_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> ~[@ast::stmt] { let mut ss = ~[]; - for tts.each |tt| { + for tts.iter().advance |tt| { ss.push_all_move(mk_tt(cx, sp, tt)); } ss diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 3fb94bbce380..f2b57db06c15 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -138,7 +138,7 @@ pub fn count_names(ms: &[matcher]) -> uint { pub fn initial_matcher_pos(ms: ~[matcher], sep: Option, lo: BytePos) -> ~MatcherPos { let mut match_idx_hi = 0u; - for ms.each |elt| { + for ms.iter().advance |elt| { match elt.node { match_tok(_) => (), match_seq(_,_,_,_,hi) => { @@ -195,7 +195,7 @@ pub fn nameize(p_s: @mut ParseSess, ms: &[matcher], res: &[@named_match]) match *m { codemap::spanned {node: match_tok(_), _} => (), codemap::spanned {node: match_seq(ref more_ms, _, _, _, _), _} => { - for more_ms.each |next_m| { + for more_ms.iter().advance |next_m| { n_rec(p_s, next_m, res, ret_val) }; } @@ -211,8 +211,8 @@ pub fn nameize(p_s: @mut ParseSess, ms: &[matcher], res: &[@named_match]) } } let mut ret_val = HashMap::new(); - for ms.each |m| { n_rec(p_s, m, res, &mut ret_val) } - return ret_val; + for ms.iter().advance |m| { n_rec(p_s, m, res, &mut ret_val) } + ret_val } pub enum parse_result { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c1bf979cd319..568324bc5996 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -378,7 +378,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 mut stmts = ~[]; - for b.stmts.each |stmt| { + for b.stmts.iter().advance |stmt| { match fld.fold_stmt(*stmt) { None => {} Some(stmt) => stmts.push(stmt) diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 81f540fd69f2..c537a3e8eba3 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -135,7 +135,7 @@ impl BaseIter for OptVec { fn each(&self, blk: &fn(v: &A) -> bool) -> bool { match *self { Empty => true, - Vec(ref v) => v.each(blk) + Vec(ref v) => v.iter().advance(blk) } } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index ccc1cbd0d894..84915b6403a7 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -835,7 +835,7 @@ mod test { // check that the given reader produces the desired stream // of tokens (stop checking after exhausting the expected vec) fn check_tokenization (env: Env, expected: ~[token::Token]) { - for expected.each |expected_tok| { + for expected.iter().advance |expected_tok| { let TokenAndSpan {tok:actual_tok, sp: _} = env.string_reader.next_token(); assert_eq!(&actual_tok,expected_tok); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4e52b6b7367a..753c69b23d6a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2746,7 +2746,7 @@ impl Parser { } = self.parse_items_and_view_items(first_item_attrs, false, false); - for items.each |item| { + for items.iter().advance |item| { let decl = @spanned(item.span.lo, item.span.hi, decl_item(*item)); stmts.push(@spanned(item.span.lo, item.span.hi, stmt_decl(decl, self.get_id()))); @@ -3356,7 +3356,8 @@ impl Parser { is_tuple_like = false; fields = ~[]; while *self.token != token::RBRACE { - for self.parse_struct_decl_field().each |struct_field| { + let r = self.parse_struct_decl_field(); + for r.iter().advance |struct_field| { fields.push(*struct_field) } } @@ -3825,7 +3826,8 @@ impl Parser { fn parse_struct_def(&self) -> @struct_def { let mut fields: ~[@struct_field] = ~[]; while *self.token != token::RBRACE { - for self.parse_struct_decl_field().each |struct_field| { + let r = self.parse_struct_decl_field(); + for r.iter().advance |struct_field| { fields.push(*struct_field); } } @@ -3865,7 +3867,7 @@ impl Parser { seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_ty(false) ); - for arg_tys.each |ty| { + for arg_tys.iter().advance |ty| { args.push(ast::variant_arg { ty: *ty, id: self.get_id(), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d73c5240a1c0..8e47df510108 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -320,7 +320,7 @@ pub fn synth_comment(s: @ps, text: ~str) { pub fn commasep(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN)) { box(s, 0u, b); let mut first = true; - for elts.each |elt| { + for elts.iter().advance |elt| { if first { first = false; } else { word_space(s, ","); } op(s, copy *elt); } @@ -333,7 +333,7 @@ pub fn commasep_cmnt(s: @ps, b: breaks, elts: &[IN], op: &fn(@ps, IN), box(s, 0u, b); let len = elts.len(); let mut i = 0u; - for elts.each |elt| { + for elts.iter().advance |elt| { maybe_print_comment(s, get_span(copy *elt).hi); op(s, copy *elt); i += 1u; @@ -354,19 +354,19 @@ pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::expr]) { pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); - for _mod.view_items.each |vitem| { + for _mod.view_items.iter().advance |vitem| { print_view_item(s, *vitem); } - for _mod.items.each |item| { print_item(s, *item); } + for _mod.items.iter().advance |item| { print_item(s, *item); } } pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, attrs: &[ast::attribute]) { print_inner_attributes(s, attrs); - for nmod.view_items.each |vitem| { + for nmod.view_items.iter().advance |vitem| { print_view_item(s, *vitem); } - for nmod.items.each |item| { print_foreign_item(s, *item); } + for nmod.items.iter().advance |item| { print_foreign_item(s, *item); } } pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { @@ -580,7 +580,7 @@ pub fn print_item(s: @ps, item: @ast::item) { word(s.s, ";"); } else { bopen(s); - for methods.each |meth| { + for methods.iter().advance |meth| { print_method(s, *meth); } bclose(s, item.span); @@ -602,7 +602,7 @@ pub fn print_item(s: @ps, item: @ast::item) { } word(s.s, " "); bopen(s); - for methods.each |meth| { + for methods.iter().advance |meth| { print_trait_method(s, meth); } bclose(s, item.span); @@ -641,7 +641,7 @@ pub fn print_variants(s: @ps, variants: &[ast::variant], span: codemap::span) { bopen(s); - for variants.each |v| { + for variants.iter().advance |v| { space_if_not_bol(s); maybe_print_comment(s, v.span.lo); print_outer_attributes(s, v.node.attrs); @@ -706,7 +706,7 @@ pub fn print_struct(s: @ps, bopen(s); hardbreak_if_not_bol(s); - for struct_def.fields.each |field| { + for struct_def.fields.iter().advance |field| { match field.node.kind { ast::unnamed_field => fail!("unexpected unnamed field"), ast::named_field(ident, visibility) => { @@ -741,7 +741,7 @@ pub fn print_tt(s: @ps, tt: &ast::token_tree) { } ast::tt_seq(_, ref tts, ref sep, zerok) => { word(s.s, "$("); - for (*tts).each() |tt_elt| { print_tt(s, tt_elt); } + for (*tts).iter().advance |tt_elt| { print_tt(s, tt_elt); } word(s.s, ")"); match (*sep) { Some(ref tk) => word(s.s, parse::token::to_str(s.intr, tk)), @@ -827,7 +827,7 @@ pub fn print_method(s: @ps, meth: @ast::method) { pub fn print_outer_attributes(s: @ps, attrs: &[ast::attribute]) { let mut count = 0; - for attrs.each |attr| { + for attrs.iter().advance |attr| { match attr.node.style { ast::attr_outer => { print_attribute(s, *attr); count += 1; } _ => {/* fallthrough */ } @@ -838,7 +838,7 @@ pub fn print_outer_attributes(s: @ps, attrs: &[ast::attribute]) { pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { let mut count = 0; - for attrs.each |attr| { + for attrs.iter().advance |attr| { match attr.node.style { ast::attr_inner => { print_attribute(s, *attr); @@ -944,8 +944,8 @@ pub fn print_possibly_embedded_block_(s: @ps, print_inner_attributes(s, attrs); - for blk.node.view_items.each |vi| { print_view_item(s, *vi); } - for blk.node.stmts.each |st| { + for blk.node.view_items.iter().advance |vi| { print_view_item(s, *vi); } + for blk.node.stmts.iter().advance |st| { print_stmt(s, *st); } match blk.node.expr { @@ -1234,7 +1234,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { cbox(s, indent_unit); ibox(s, 0u); let mut first = true; - for arm.pats.each |p| { + for arm.pats.iter().advance |p| { if first { first = false; } else { space(s.s); word_space(s, "|"); } @@ -1401,7 +1401,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { popen(s); print_string(s, a.asm); word_space(s, ":"); - for a.outputs.each |&(co, o)| { + for a.outputs.iter().advance |&(co, o)| { print_string(s, co); popen(s); print_expr(s, o); @@ -1409,7 +1409,7 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { word_space(s, ","); } word_space(s, ":"); - for a.inputs.each |&(co, o)| { + for a.inputs.iter().advance |&(co, o)| { print_string(s, co); popen(s); print_expr(s, o); @@ -1487,7 +1487,7 @@ pub fn print_path(s: @ps, path: @ast::Path, colons_before_params: bool) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } let mut first = true; - for path.idents.each |id| { + for path.idents.iter().advance |id| { if first { first = false; } else { word(s.s, "::"); } print_ident(s, *id); } @@ -1678,7 +1678,7 @@ pub fn print_fn_args(s: @ps, decl: &ast::fn_decl, first = !print_explicit_self(s, *explicit_self); } - for decl.inputs.each |arg| { + for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } print_arg(s, *arg); } @@ -1924,7 +1924,7 @@ pub fn print_ty_fn(s: @ps, for opt_explicit_self.iter().advance |explicit_self| { first = !print_explicit_self(s, *explicit_self); } - for decl.inputs.each |arg| { + for decl.inputs.iter().advance |arg| { if first { first = false; } else { word_space(s, ","); } print_arg(s, *arg); } @@ -2075,7 +2075,7 @@ pub fn print_comment(s: @ps, cmnt: &comments::cmnt) { } comments::isolated => { pprust::hardbreak_if_not_bol(s); - for cmnt.lines.each |line| { + for cmnt.lines.iter().advance |line| { // Don't print empty lines because they will end up as trailing // whitespace if !line.is_empty() { word(s.s, *line); } @@ -2089,7 +2089,7 @@ pub fn print_comment(s: @ps, cmnt: &comments::cmnt) { hardbreak(s.s); } else { ibox(s, 0u); - for cmnt.lines.each |line| { + for cmnt.lines.iter().advance |line| { if !line.is_empty() { word(s.s, *line); } hardbreak(s.s); } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index bd5c178e7fe7..004ba7762d3a 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -36,7 +36,7 @@ impl Interner { pub fn prefill(init: &[T]) -> Interner { let rv = Interner::new(); - for init.each() |v| { rv.intern(copy *v); } + for init.iter().advance |v| { rv.intern(copy *v); } rv } @@ -94,7 +94,7 @@ impl StrInterner { pub fn prefill(init: &[&str]) -> StrInterner { let rv = StrInterner::new(); - for init.each |&v| { rv.intern(v); } + for init.iter().advance |&v| { rv.intern(v); } rv } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f24c393d7b48..e7afeb12a618 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -127,8 +127,8 @@ 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.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); } - for m.items.each |i| { (v.visit_item)(*i, (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)); } } pub fn visit_view_item(_vi: @view_item, (_e, _v): (E, vt)) { } @@ -170,8 +170,8 @@ 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.each |vi| { (v.visit_view_item)(*vi, (copy e, v)); } - for nm.items.each |ni| { (v.visit_foreign_item)(*ni, (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) => { (v.visit_ty)(t, (copy e, v)); @@ -191,7 +191,7 @@ pub fn visit_item(i: @item, (e, v): (E, vt)) { visit_trait_ref(p, (copy e, v)); } (v.visit_ty)(ty, (copy e, v)); - for methods.each |m| { + for methods.iter().advance |m| { visit_method_helper(*m, (copy e, v)) } } @@ -201,8 +201,8 @@ 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.each |p| { visit_path(p.path, (copy e, v)); } - for methods.each |m| { + 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)); } } @@ -213,10 +213,10 @@ pub fn visit_item(i: @item, (e, v): (E, vt)) { pub fn visit_enum_def(enum_definition: &ast::enum_def, tps: &Generics, (e, v): (E, vt)) { - for enum_definition.variants.each |vr| { + for enum_definition.variants.iter().advance |vr| { match vr.node.kind { tuple_variant_kind(ref variant_args) => { - for variant_args.each |va| { + for variant_args.iter().advance |va| { (v.visit_ty)(va.ty, (copy e, v)); } } @@ -241,16 +241,16 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { (v.visit_ty)(mt.ty, (e, v)); }, ty_tup(ref ts) => { - for ts.each |tt| { + for ts.iter().advance |tt| { (v.visit_ty)(*tt, (copy e, v)); } }, ty_closure(ref f) => { - for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy 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_bare_fn(ref f) => { - for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, (copy 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, _) => visit_path(p, (e, v)), @@ -263,7 +263,7 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { } pub fn visit_path(p: @Path, (e, v): (E, vt)) { - for p.types.each |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)) { @@ -278,12 +278,12 @@ pub fn visit_pat(p: @pat, (e, v): (E, vt)) { } pat_struct(path, ref fields, _) => { visit_path(path, (copy e, v)); - for fields.each |f| { + for fields.iter().advance |f| { (v.visit_pat)(f.pat, (copy e, v)); } } pat_tup(ref elts) => { - for elts.each |elt| { + for elts.iter().advance |elt| { (v.visit_pat)(*elt, (copy e, v)) } }, @@ -303,13 +303,13 @@ pub fn visit_pat(p: @pat, (e, v): (E, vt)) { } pat_wild => (), pat_vec(ref before, ref slice, ref after) => { - for before.each |elt| { + for before.iter().advance |elt| { (v.visit_pat)(*elt, (copy e, v)); } for slice.iter().advance |elt| { (v.visit_pat)(*elt, (copy e, v)); } - for after.each |tail| { + for after.iter().advance |tail| { (v.visit_pat)(*tail, (copy e, v)); } } @@ -345,7 +345,7 @@ pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { } pub fn visit_fn_decl(fd: &fn_decl, (e, v): (E, vt)) { - for fd.inputs.each |a| { + for fd.inputs.iter().advance |a| { (v.visit_pat)(a.pat, (copy e, v)); (v.visit_ty)(a.ty, (copy e, v)); } @@ -380,7 +380,7 @@ 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.each |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)); } @@ -399,7 +399,7 @@ pub fn visit_struct_def( _id: node_id, (e, v): (E, vt) ) { - for sd.fields.each |f| { + for sd.fields.iter().advance |f| { (v.visit_struct_field)(*f, (copy e, v)); } } @@ -413,10 +413,10 @@ pub fn visit_struct_method(m: @method, (e, v): (E, vt)) { } pub fn visit_block(b: &blk, (e, v): (E, vt)) { - for b.node.view_items.each |vi| { + for b.node.view_items.iter().advance |vi| { (v.visit_view_item)(*vi, (copy e, v)); } - for b.node.stmts.each |s| { + for b.node.stmts.iter().advance |s| { (v.visit_stmt)(*s, (copy e, v)); } visit_expr_opt(b.node.expr, (e, v)); @@ -443,7 +443,7 @@ pub fn visit_expr_opt(eo: Option<@expr>, (e, v): (E, vt)) { } pub fn visit_exprs(exprs: &[@expr], (e, v): (E, vt)) { - for exprs.each |ex| { (v.visit_expr)(*ex, (copy e, v)); } + for exprs.iter().advance |ex| { (v.visit_expr)(*ex, (copy e, v)); } } pub fn visit_mac(_m: &mac, (_e, _v): (E, vt)) { @@ -460,13 +460,13 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { } expr_struct(p, ref flds, base) => { visit_path(p, (copy e, v)); - for flds.each |f| { + for flds.iter().advance |f| { (v.visit_expr)(f.node.expr, (copy e, v)); } visit_expr_opt(base, (copy e, v)); } expr_tup(ref elts) => { - for elts.each |el| { (v.visit_expr)(*el, (copy e, v)) } + for elts.iter().advance |el| { (v.visit_expr)(*el, (copy e, v)) } } expr_call(callee, ref args, _) => { visit_exprs(*args, (copy e, v)); @@ -474,7 +474,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.each |tp| { + for tys.iter().advance |tp| { (v.visit_ty)(*tp, (copy e, v)); } (v.visit_expr)(callee, (copy e, v)); @@ -502,7 +502,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_loop(ref b, _) => (v.visit_block)(b, (copy e, v)), expr_match(x, ref arms) => { (v.visit_expr)(x, (copy e, v)); - for arms.each |a| { (v.visit_arm)(a, (copy e, v)); } + for arms.iter().advance |a| { (v.visit_arm)(a, (copy e, v)); } } expr_fn_block(ref decl, ref body) => { (v.visit_fn)( @@ -526,7 +526,7 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { } expr_field(x, _, ref tys) => { (v.visit_expr)(x, (copy e, v)); - for tys.each |tp| { + for tys.iter().advance |tp| { (v.visit_ty)(*tp, (copy e, v)); } } @@ -546,10 +546,10 @@ pub fn visit_expr(ex: @expr, (e, v): (E, vt)) { expr_mac(ref mac) => visit_mac(mac, (copy e, v)), expr_paren(x) => (v.visit_expr)(x, (copy e, v)), expr_inline_asm(ref a) => { - for a.inputs.each |&(_, in)| { + for a.inputs.iter().advance |&(_, in)| { (v.visit_expr)(in, (copy e, v)); } - for a.outputs.each |&(_, out)| { + for a.outputs.iter().advance |&(_, out)| { (v.visit_expr)(out, (copy e, v)); } } diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/auxiliary/cci_nested_lib.rs index c0b98f2af07c..2c9b28e62826 100644 --- a/src/test/auxiliary/cci_nested_lib.rs +++ b/src/test/auxiliary/cci_nested_lib.rs @@ -24,7 +24,7 @@ pub fn alist_add(lst: &alist, k: A, v: B) { pub fn alist_get(lst: &alist, k: A) -> B { let eq_fn = lst.eq_fn; - for lst.data.each |entry| { + for lst.data.iter().advance |entry| { if eq_fn(copy entry.key, copy k) { return copy entry.value; } } fail!(); diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index a2edc1efa66a..14aa65219cd2 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -141,7 +141,7 @@ fn bfs(graph: graph, key: node_id) -> bfs_result { while !q.is_empty() { let t = q.pop_front(); - do graph[t].each() |k| { + do graph[t].iter().advance |k| { if marks[*k] == -1i64 { marks[*k] = t; q.add_back(*k); @@ -201,7 +201,7 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { let mut color = white; - do neighbors.each() |k| { + do neighbors.iter().advance |k| { if is_gray(&colors[*k]) { color = gray(*k); false @@ -286,7 +286,7 @@ fn pbfs(graph: &arc::ARC, key: node_id) -> bfs_result { let mut color = white; - do neighbors.each() |k| { + do neighbors.iter().advance |k| { if is_gray(&colors[*k]) { color = gray(*k); false diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index 8c8b26afa08b..670e77bc3a0e 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -59,7 +59,7 @@ static HOMO_SAPIENS: [AminoAcid, ..4] = [ fn sum_and_scale(a: &'static [AminoAcid]) -> ~[AminoAcid] { let mut result = ~[]; let mut p = 0f32; - for a.each |a_i| { + for a.iter().advance |a_i| { let mut a_i = *a_i; p += a_i.p; a_i.p = p * LOOKUP_SCALE; @@ -151,7 +151,7 @@ impl RandomFasta { fn nextc(&mut self) -> u8 { let r = self.rng(1.0); - for self.lookup.each |a| { + for self.lookup.iter().advance |a| { if a.p >= r { return a.c; } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 5c77e698bec8..38c8d1903e98 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -47,11 +47,11 @@ struct AminoAcids { fn make_cumulative(aa: ~[AminoAcids]) -> ~[AminoAcids] { let mut cp: u32 = 0u32; let mut ans: ~[AminoAcids] = ~[]; - for aa.each |a| { + for aa.iter().advance |a| { cp += a.prob; ans += [AminoAcids {ch: a.ch, prob: cp}]; } - return ans; + ans } fn select_random(r: u32, genelist: ~[AminoAcids]) -> char { @@ -64,7 +64,7 @@ fn select_random(r: u32, genelist: ~[AminoAcids]) -> char { } else { return bisect(v, mid, hi, target); } } else { return v[hi].ch; } } - return bisect(copy genelist, 0, genelist.len() - 1, r); + bisect(copy genelist, 0, genelist.len() - 1, r) } fn make_random_fasta(wr: @io::Writer, @@ -106,7 +106,7 @@ fn make_repeat_fasta(wr: @io::Writer, id: ~str, desc: ~str, s: ~str, n: int) { } fn acid(ch: char, prob: u32) -> AminoAcids { - return AminoAcids {ch: ch, prob: prob}; + AminoAcids {ch: ch, prob: prob} } fn main() { diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 81a3482b4f88..c33c2258864f 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -64,7 +64,7 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { let mut buffer = ~""; - for pairs_sorted.each |kv| { + for pairs_sorted.iter().advance |kv| { let (k,v) = copy *kv; unsafe { let b = str::raw::from_bytes(k); diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index b869aa0e342c..01425d82db29 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -91,7 +91,7 @@ fn stress(num_tasks: int) { stress_task(i); } } - for results.each |r| { + for results.iter().advance |r| { r.recv(); } } diff --git a/src/test/compile-fail/borrowck-mut-boxed-vec.rs b/src/test/compile-fail/borrowck-mut-boxed-vec.rs index 716f70b29139..dd72a71b215b 100644 --- a/src/test/compile-fail/borrowck-mut-boxed-vec.rs +++ b/src/test/compile-fail/borrowck-mut-boxed-vec.rs @@ -10,7 +10,7 @@ fn main() { let v = @mut [ 1, 2, 3 ]; - for v.each |_x| { + for v.iter().advance |_x| { v[1] = 4; //~ ERROR cannot assign } } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index cdc8d546dd84..f7b9371df573 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -15,7 +15,7 @@ trait vec_monad { impl vec_monad for ~[A] { fn bind(&self, f: &fn(A) -> ~[B]) { let mut r = fail!(); - for self.each |elt| { r += f(*elt); } + for self.iter().advance |elt| { r += f(*elt); } //~^ WARNING unreachable expression //~^^ ERROR the type of this value must be known } diff --git a/src/test/compile-fail/issue-2150.rs b/src/test/compile-fail/issue-2150.rs index 0b35104841e6..59789223bf25 100644 --- a/src/test/compile-fail/issue-2150.rs +++ b/src/test/compile-fail/issue-2150.rs @@ -14,7 +14,7 @@ fn fail_len(v: ~[int]) -> uint { let mut i = 3; fail!(); - for v.each |x| { i += 1u; } + for v.iter().advance |x| { i += 1u; } //~^ ERROR: unreachable statement return i; } diff --git a/src/test/compile-fail/issue-5100.rs b/src/test/compile-fail/issue-5100.rs index 8cc047230dc9..7a6b8c5606ba 100644 --- a/src/test/compile-fail/issue-5100.rs +++ b/src/test/compile-fail/issue-5100.rs @@ -37,7 +37,7 @@ fn main() { ('c', 'd'), ('e', 'f')]; - for v.each |&(x,y)| {} // should be OK + for v.iter().advance |&(x,y)| {} // should be OK // Make sure none of the errors above were fatal let x: char = true; //~ ERROR expected `char` but found `bool` diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp index 911de166e8fc..dbf28caecf29 100644 --- a/src/test/pretty/block-comment-wchar.pp +++ b/src/test/pretty/block-comment-wchar.pp @@ -109,7 +109,7 @@ fn main() { '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; // <= bugs in pretty-printer? - for chars.each |c| { + 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 d8a820542a72..148b50d9c912 100644 --- a/src/test/pretty/block-comment-wchar.rs +++ b/src/test/pretty/block-comment-wchar.rs @@ -102,7 +102,7 @@ fn main() { '\xA0', '\u1680', '\u180E', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006', '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F', '\u205F', '\u3000']; - for chars.each |c| { + for chars.iter().advance |c| { let ws = c.is_whitespace(); println(fmt!("%? %?", c , ws)); // <= bugs in pretty-printer? } diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs index 34b77b4a844a..6da1f9131a50 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/run-pass/block-iter-1.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.iter().advance |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5, 6, 7]; diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs index dc4ff5a054fb..3092cd5338c0 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/run-pass/block-iter-2.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.iter().advance |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5]; diff --git a/src/test/run-pass/borrowck-borrow-from-at-vec.rs b/src/test/run-pass/borrowck-borrow-from-at-vec.rs index fb91e9a787e3..21ea875b2f4b 100644 --- a/src/test/run-pass/borrowck-borrow-from-at-vec.rs +++ b/src/test/run-pass/borrowck-borrow-from-at-vec.rs @@ -10,7 +10,7 @@ fn sum_slice(x: &[int]) -> int { let mut sum = 0; - for x.each |i| { sum += *i; } + for x.iter().advance |i| { sum += *i; } return sum; } diff --git a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs b/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs index 284db7af66be..612a472cde58 100644 --- a/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs +++ b/src/test/run-pass/borrowck-wg-borrow-mut-to-imm-3.rs @@ -4,7 +4,7 @@ struct Wizard { impl Wizard { pub fn cast(&mut self) { - for self.spells.each |&spell| { + for self.spells.iter().advance |&spell| { println(spell); } } diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index deb1a0769f73..9fc68cd11275 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-fast + /*! * Try to double-check that static fns have the right size (with or * without dummy env ptr, as appropriate) by iterating a size-2 array. @@ -21,6 +23,6 @@ struct S<'self>(&'self fn()); static closures: &'static [S<'static>] = &[S(f), S(f)]; pub fn main() { - for bare_fns.each |&bare_fn| { bare_fn() } - for closures.each |&closure| { (*closure)() } + for std::vec::each(bare_fns) |&bare_fn| { bare_fn() } + for std::vec::each(closures) |&closure| { (*closure)() } } diff --git a/src/test/run-pass/explicit-self-closures.rs b/src/test/run-pass/explicit-self-closures.rs index eb62c8a91d24..1b87c16b4b90 100644 --- a/src/test/run-pass/explicit-self-closures.rs +++ b/src/test/run-pass/explicit-self-closures.rs @@ -16,10 +16,10 @@ struct Box { impl Box { pub fn set_many(&mut self, xs: &[uint]) { - for xs.each |x| { self.x = *x; } + for xs.iter().advance |x| { self.x = *x; } } pub fn set_many2(@mut self, xs: &[uint]) { - for xs.each |x| { self.x = *x; } + for xs.iter().advance |x| { self.x = *x; } } } diff --git a/src/test/run-pass/fn-pattern-expected-type-2.rs b/src/test/run-pass/fn-pattern-expected-type-2.rs index ee1e73110243..bb8df4bb33f0 100644 --- a/src/test/run-pass/fn-pattern-expected-type-2.rs +++ b/src/test/run-pass/fn-pattern-expected-type-2.rs @@ -10,7 +10,7 @@ pub fn main() { let v : &[(int,int)] = &[ (1, 2), (3, 4), (5, 6) ]; - for v.each |&(x, y)| { + for v.iter().advance |&(x, y)| { println(y.to_str()); println(x.to_str()); } diff --git a/src/test/run-pass/for-loop-fail.rs b/src/test/run-pass/for-loop-fail.rs index cf69d754f37a..bf916dfa2bd2 100644 --- a/src/test/run-pass/for-loop-fail.rs +++ b/src/test/run-pass/for-loop-fail.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub fn main() { let x: ~[int] = ~[]; for x.each |_i| { fail!("moop"); } } +pub fn main() { let x: ~[int] = ~[]; for x.iter().advance |_| { fail!("moop"); } } diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index eae2f507c519..ecf6546e741e 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -31,7 +31,7 @@ mod map_reduce { enum ctrl_proto { find_reducer(~[u8], Chan), mapper_done, } fn start_mappers(ctrl: SharedChan, inputs: ~[~str]) { - for inputs.each |i| { + for inputs.iter().advance |i| { let ctrl = ctrl.clone(); let i = i.clone(); task::spawn(|| map_task(ctrl.clone(), i.clone()) ); diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 6af191880489..bd4e3f84719f 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -73,7 +73,7 @@ fn read_board_grid(in: rdr) -> ~[~[square]] { grid.push(row) } let width = grid[0].len(); - for grid.each |row| { assert!(row.len() == width) } + for grid.iter().advance |row| { assert!(row.len() == width) } grid } diff --git a/src/test/run-pass/issue-3389.rs b/src/test/run-pass/issue-3389.rs index d9919b1695d7..8dcf4ed4a486 100644 --- a/src/test/run-pass/issue-3389.rs +++ b/src/test/run-pass/issue-3389.rs @@ -14,7 +14,7 @@ struct trie_node { } fn print_str_vector(vector: ~[~str]) { - for vector.each() |string| { + for vector.iter().advance |string| { println(*string); } } diff --git a/src/test/run-pass/issue-3563-2.rs b/src/test/run-pass/issue-3563-2.rs index 52d6792f4014..7d0ba866faf3 100644 --- a/src/test/run-pass/issue-3563-2.rs +++ b/src/test/run-pass/issue-3563-2.rs @@ -12,7 +12,7 @@ trait Canvas { fn add_point(&self, point: &int); fn add_points(&self, shapes: &[int]) { - for shapes.each |pt| { + for shapes.iter().advance |pt| { self.add_point(pt) } } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 368725607160..012e70988ad1 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -34,14 +34,12 @@ struct Point { // Represents an offset on a canvas. (This has the same structure as a Point. // but different semantics). -struct Size -{ +struct Size { width: int, height: int, } -struct Rect -{ +struct Rect { top_left: Point, size: Size, } @@ -49,8 +47,7 @@ struct Rect // TODO: operators // Contains the information needed to do shape rendering via ASCII art. -struct AsciiArt -{ +struct AsciiArt { width: uint, height: uint, priv fill: char, @@ -67,15 +64,11 @@ impl Drop for AsciiArt { // It's common to define a constructor sort of function to create struct instances. // If there is a canonical constructor it is typically named the same as the type. // Other constructor sort of functions are typically named from_foo, from_bar, etc. -fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt -{ +fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt { // Use an anonymous function to build a vector of vectors containing // blank characters for each position in our canvas. - let mut lines = do vec::build_sized(height) - |push| - { - for height.times - { + let mut lines = do vec::build_sized(height) |push| { + for height.times { let mut line = ~[]; vec::grow_set(&mut line, width-1, &'.', '.'); push(line); @@ -88,14 +81,10 @@ fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt } // Methods particular to the AsciiArt struct. -impl AsciiArt -{ - fn add_pt(&mut self, x: int, y: int) - { - if x >= 0 && x < self.width as int - { - if y >= 0 && y < self.height as int - { +impl AsciiArt { + fn add_pt(&mut self, x: int, y: int) { + if x >= 0 && x < self.width as int { + if y >= 0 && y < self.height as int { // Note that numeric types don't implicitly convert to each other. let v = y as uint; let h = x as uint; @@ -127,16 +116,14 @@ impl ToStr for AsciiArt { // This is similar to an interface in other languages: it defines a protocol which // developers can implement for arbitrary concrete types. #[allow(default_methods)] -trait Canvas -{ +trait Canvas { fn add_point(&mut self, shape: Point); fn add_rect(&mut self, shape: Rect); // Unlike interfaces traits support default implementations. // Got an ICE as soon as I added this method. - fn add_points(&mut self, shapes: &[Point]) - { - for shapes.each |pt| {self.add_point(*pt)}; + fn add_points(&mut self, shapes: &[Point]) { + for shapes.iter().advance |pt| {self.add_point(*pt)}; } } @@ -144,25 +131,19 @@ trait Canvas // Other implementations could also be provided (e.g. for PDF or Apple's Quartz) // and code can use them polymorphically via the Canvas trait. impl Canvas for AsciiArt { - fn add_point(&mut self, shape: Point) - { + fn add_point(&mut self, shape: Point) { self.add_pt(shape.x, shape.y); } - fn add_rect(&mut self, shape: Rect) - { + fn add_rect(&mut self, shape: Rect) { // Add the top and bottom lines. - for int::range(shape.top_left.x, shape.top_left.x + shape.size.width) - |x| - { + for int::range(shape.top_left.x, shape.top_left.x + shape.size.width) |x| { self.add_pt(x, shape.top_left.y); self.add_pt(x, shape.top_left.y + shape.size.height - 1); } // Add the left and right lines. - for int::range(shape.top_left.y, shape.top_left.y + shape.size.height) - |y| - { + for int::range(shape.top_left.y, shape.top_left.y + shape.size.height) |y|{ self.add_pt(shape.top_left.x, y); self.add_pt(shape.top_left.x + shape.size.width - 1, y); } @@ -171,10 +152,8 @@ impl Canvas for AsciiArt { // Rust's unit testing framework is currently a bit under-developed so we'll use // this little helper. -pub fn check_strs(actual: &str, expected: &str) -> bool -{ - if actual != expected - { +pub fn check_strs(actual: &str, expected: &str) -> bool { + if actual != expected { io::stderr().write_line(fmt!("Found:\n%s\nbut expected\n%s", actual, expected)); return false; } @@ -182,15 +161,13 @@ pub fn check_strs(actual: &str, expected: &str) -> bool } -fn test_ascii_art_ctor() -{ +fn test_ascii_art_ctor() { let art = AsciiArt(3, 3, '*'); assert!(check_strs(art.to_str(), "...\n...\n...")); } -fn test_add_pt() -{ +fn test_add_pt() { let mut art = AsciiArt(3, 3, '*'); art.add_pt(0, 0); art.add_pt(0, -10); @@ -199,8 +176,7 @@ fn test_add_pt() } -fn test_shapes() -{ +fn test_shapes() { let mut art = AsciiArt(4, 4, '*'); art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}}); art.add_point(Point {x: 2, y: 2}); diff --git a/src/test/run-pass/linear-for-loop.rs b/src/test/run-pass/linear-for-loop.rs index 6d157b38a3f7..71b87b3311ba 100644 --- a/src/test/run-pass/linear-for-loop.rs +++ b/src/test/run-pass/linear-for-loop.rs @@ -11,7 +11,7 @@ pub fn main() { let x = ~[1, 2, 3]; let mut y = 0; - for x.each |i| { debug!(*i); y += *i; } + for x.iter().advance |i| { debug!(*i); y += *i; } debug!(y); assert_eq!(y, 6); let s = ~"hello there"; diff --git a/src/test/run-pass/loop-scope.rs b/src/test/run-pass/loop-scope.rs index 07be3bd6c81f..aec16e2d47bd 100644 --- a/src/test/run-pass/loop-scope.rs +++ b/src/test/run-pass/loop-scope.rs @@ -11,6 +11,6 @@ pub fn main() { let x = ~[10, 20, 30]; let mut sum = 0; - for x.each |x| { sum += *x; } + for x.iter().advance |x| { sum += *x; } assert_eq!(sum, 60); } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 69545238db40..3f3cf5e5aaa0 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -19,7 +19,7 @@ trait vec_monad { impl vec_monad for ~[A] { fn bind(&self, f: &fn(&A) -> ~[B]) -> ~[B] { let mut r = ~[]; - for self.each |elt| { r += f(elt); } + for self.iter().advance |elt| { r += f(elt); } r } } diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 1dc8503aeb22..1a670960f39c 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -68,7 +68,7 @@ pub fn main() { calllink10 ]; let mut rng = rand::rng(); - for fns.each |f| { + for fns.iter().advance |f| { let f = *f; let sz = rng.next() % 256u32 + 256u32; let frame_backoff = rng.next() % 10u32 + 1u32; diff --git a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs index 06d3736849d5..b0ce6556cb6a 100644 --- a/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs +++ b/src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs @@ -17,7 +17,7 @@ fn test1() { fn test2() { let mut ints = [0, ..32]; for ints.mut_iter().advance |i| { *i += 22; } - for ints.each |i| { assert!(*i == 22); } + for ints.iter().advance |i| { assert!(*i == 22); } } pub fn main() { diff --git a/src/test/run-pass/overload-index-operator.rs b/src/test/run-pass/overload-index-operator.rs index 1838cfe25198..b995e9c9ed2e 100644 --- a/src/test/run-pass/overload-index-operator.rs +++ b/src/test/run-pass/overload-index-operator.rs @@ -30,7 +30,7 @@ impl AssociationList { impl Index for AssociationList { fn index(&self, index: &K) -> V { - for self.pairs.each |pair| { + for self.pairs.iter().advance |pair| { if pair.key == *index { return copy pair.value; } diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs index 1f3d4c26bd23..de34d589afc7 100644 --- a/src/test/run-pass/packed-struct-vec.rs +++ b/src/test/run-pass/packed-struct-vec.rs @@ -27,7 +27,7 @@ fn main() { assert_eq!(foos[i], Foo { bar: 1, baz: 2}); } - for foos.each |&foo| { + for foos.iter().advance |&foo| { assert_eq!(foo, Foo { bar: 1, baz: 2 }); } } diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index e091554a3572..a8571ab73254 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -656,7 +656,8 @@ pub fn main() { let v = @v as @TyVisitor; visit_tydesc(td, v); - for (u.vals.clone()).each |s| { + let r = u.vals.clone(); + for r.iter().advance |s| { println(fmt!("val: %s", *s)); } error!("%?", u.vals.clone()); diff --git a/src/test/run-pass/shadow.rs b/src/test/run-pass/shadow.rs index 99553cfcf79b..85575b2ea8bb 100644 --- a/src/test/run-pass/shadow.rs +++ b/src/test/run-pass/shadow.rs @@ -15,14 +15,14 @@ fn foo(c: ~[int]) { match none:: { - some::(_) => { - for c.each |i| { - debug!(a); - let a = 17; - b += ~[a]; + some::(_) => { + for c.iter().advance |i| { + debug!(a); + let a = 17; + b += ~[a]; + } } - } - _ => { } + _ => { } } } diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 3d3f1404dc2a..421cd1d4d0bb 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -48,10 +48,10 @@ trait vec_utils { impl vec_utils for ~[T] { fn length_(&self) -> uint { self.len() } - fn iter_(&self, f: &fn(&T)) { for self.each |x| { f(x); } } + fn iter_(&self, f: &fn(&T)) { for self.iter().advance |x| { f(x); } } fn map_(&self, f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for self.each |elt| { r += ~[f(elt)]; } + for self.iter().advance |elt| { r += ~[f(elt)]; } r } } diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs deleted file mode 100644 index 2d6b2141c5c7..000000000000 --- a/src/test/run-pass/static-method-test.rs +++ /dev/null @@ -1,94 +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. - -// xfail-fast - -use std::at_vec; -use std::uint; -use std::vec; - -// A trait for objects that can be used to do an if-then-else -// (No actual need for this to be static, but it is a simple test.) -trait bool_like { - fn select(b: Self, x1: A, x2: A) -> A; -} - -fn andand(x1: T, x2: T) -> T { - bool_like::select(copy x1, x2, x1) -} - -impl bool_like for bool { - fn select(b: bool, x1: A, x2: A) -> A { - if b { x1 } else { x2 } - } -} - -impl bool_like for int { - fn select(b: int, x1: A, x2: A) -> A { - if b != 0 { x1 } else { x2 } - } -} - -// A trait for sequences that can be constructed imperatively. -trait buildable { - fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> Self; -} - - -impl buildable for @[A] { - #[inline(always)] - fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] { - at_vec::build_sized(size, builder) - } -} -impl buildable for ~[A] { - #[inline(always)] - fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] { - vec::build_sized(size, builder) - } -} - -#[inline(always)] -fn build>(builder: &fn(push: &fn(v: A))) -> B { - buildable::build_sized(4, builder) -} - -/// Apply a function to each element of an iterable and return the results -fn map, U, BU: buildable> - (v: IT, f: &fn(&T) -> U) -> BU { - do build |push| { - for v.each() |elem| { - push(f(elem)); - } - } -} - -fn seq_range>(lo: uint, hi: uint) -> BT { - do buildable::build_sized(hi-lo) |push| { - for uint::range(lo, hi) |i| { - push(i as int); - } - } -} - -pub fn main() { - let v: @[int] = seq_range(0, 10); - assert_eq!(v, @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - - let v: @[int] = map(&[1,2,3], |&x| 1+x); - assert_eq!(v, @[2, 3, 4]); - let v: ~[int] = map(&[1,2,3], |&x| 1+x); - assert_eq!(v, ~[2, 3, 4]); - - assert_eq!(bool_like::select(true, 9, 14), 9); - assert!(!andand(true, false)); - assert_eq!(andand(7, 12), 12); - assert_eq!(andand(0, 12), 0); -} diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index dd8168ff947b..f94b54873749 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -54,7 +54,7 @@ fn test00() { // Read from spawned tasks... let mut sum = 0; - for results.each |r| { + for results.iter().advance |r| { i = 0; while i < number_of_messages { let value = po.recv(); @@ -64,7 +64,7 @@ fn test00() { } // Join spawned tasks... - for results.each |r| { r.recv(); } + for results.iter().advance |r| { r.recv(); } debug!("Completed: Final number is: "); error!(sum); diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index 3aa30aab7c26..c25cdc85cb6a 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -31,7 +31,7 @@ trait map { impl map for ~[T] { fn map(&self, f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for self.each |x| { r += ~[f(x)]; } + for std::vec::each(*self) |x| { r += ~[f(x)]; } r } } From 080d498af224ac4b60efe6e92aed08db3f247bc5 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 21 Jun 2013 17:05:05 +0200 Subject: [PATCH 063/336] std::hashmap: Implement external iterator for HashMap and HashSet --- src/libstd/hashmap.rs | 91 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 02fa2de4b032..c275e8a99ff5 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -20,13 +20,13 @@ use cmp::{Eq, Equiv}; use hash::Hash; use old_iter::BaseIter; use old_iter; -use iterator::IteratorUtil; +use iterator::{Iterator, IteratorUtil}; use option::{None, Option, Some}; use rand::RngUtil; use rand; use uint; use vec; -use vec::ImmutableVector; +use vec::{ImmutableVector, MutableVector}; use kinds::Copy; use util::{replace, unreachable}; @@ -311,24 +311,17 @@ impl Map for HashMap { /// Visit all key-value pairs fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - for self.buckets.iter().advance |bucket| { - for bucket.iter().advance |pair| { - if !blk(&pair.key, &pair.value) { - return false; - } - } - } - return true; + self.iter().advance(|(k, v)| blk(k, v)) } /// Visit all keys fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { - self.each(|k, _| blk(k)) + self.iter().advance(|(k, _)| blk(k)) } /// Visit all values fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { - self.each(|_, v| blk(v)) + self.iter().advance(|(_, v)| blk(v)) } /// Iterate over the map and mutate the contained values @@ -524,6 +517,19 @@ impl HashMap { TableFull | FoundHole(_) => None, } } + + /// An iterator visiting all key-value pairs in arbitrary order. + /// Iterator element type is (&'a K, &'a V). + pub fn iter<'a>(&'a self) -> HashMapIterator<'a, K, V> { + HashMapIterator { iter: self.buckets.iter() } + } + + /// An iterator visiting all key-value pairs in arbitrary order, + /// with mutable references to the values. + /// Iterator element type is (&'a K, &'a mut V). + pub fn mut_iter<'a>(&'a mut self) -> HashMapMutIterator<'a, K, V> { + HashMapMutIterator { iter: self.buckets.mut_iter() } + } } impl HashMap { @@ -555,6 +561,61 @@ impl Eq for HashMap { fn ne(&self, other: &HashMap) -> bool { !self.eq(other) } } +/// HashMap iterator +pub struct HashMapIterator<'self, K, V> { + priv iter: vec::VecIterator<'self, Option>>, +} + +/// HashMap mutable values iterator +pub struct HashMapMutIterator<'self, K, V> { + priv iter: vec::VecMutIterator<'self, Option>>, +} + +/// HashSet iterator +pub struct HashSetIterator<'self, K> { + priv iter: vec::VecIterator<'self, Option>>, +} + +impl<'self, K, V> Iterator<(&'self K, &'self V)> for HashMapIterator<'self, K, V> { + #[inline] + fn next(&mut self) -> Option<(&'self K, &'self V)> { + for self.iter.advance |elt| { + match elt { + &Some(ref bucket) => return Some((&bucket.key, &bucket.value)), + &None => {}, + } + } + None + } +} + +impl<'self, K, V> Iterator<(&'self K, &'self mut V)> for HashMapMutIterator<'self, K, V> { + #[inline] + fn next(&mut self) -> Option<(&'self K, &'self mut V)> { + for self.iter.advance |elt| { + match elt { + &Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)), + &None => {}, + } + } + None + } +} + +impl<'self, K> Iterator<&'self K> for HashSetIterator<'self, K> { + #[inline] + fn next(&mut self) -> Option<&'self K> { + for self.iter.advance |elt| { + match elt { + &Some(ref bucket) => return Some(&bucket.key), + &None => {}, + } + } + None + } +} + + /// An implementation of a hash set using the underlying representation of a /// HashMap where the value is (). As with the `HashMap` type, a `HashSet` /// requires that the elements implement the `Eq` and `Hash` traits. @@ -664,6 +725,12 @@ impl HashSet { pub fn contains_equiv>(&self, value: &Q) -> bool { self.map.contains_key_equiv(value) } + + /// An iterator visiting all elements in arbitrary order. + /// Iterator element type is &'a T. + pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> { + HashSetIterator { iter: self.map.buckets.iter() } + } } #[cfg(test)] From 3af1d20bea80faaf5fe14a56c94e8e7337691e0d Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 21 Jun 2013 17:05:16 +0200 Subject: [PATCH 064/336] std::hashmap: Add test_iterate for HashSet --- src/libstd/hashmap.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index c275e8a99ff5..1c74901b94de 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -952,6 +952,7 @@ mod test_set { use super::*; use container::{Container, Map, Set}; use vec; + use uint; #[test] fn test_disjoint() { @@ -1004,6 +1005,19 @@ mod test_set { assert!(b.is_superset(&a)); } + #[test] + fn test_iterate() { + let mut a = HashSet::new(); + for uint::range(0, 32) |i| { + assert!(a.insert(i)); + } + let mut observed = 0; + for a.iter().advance |k| { + observed |= (1 << *k); + } + assert_eq!(observed, 0xFFFF_FFFF); + } + #[test] fn test_intersection() { let mut a = HashSet::new(); From f045210857a8936c7d6ce36a3029eac906dedc4e Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 21 Jun 2013 17:05:26 +0200 Subject: [PATCH 065/336] std::hashmap: Use .iter() instead of .each and similar --- src/libstd/hashmap.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 1c74901b94de..dddda60702aa 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -19,7 +19,6 @@ use container::{Container, Mutable, Map, Set}; use cmp::{Eq, Equiv}; use hash::Hash; use old_iter::BaseIter; -use old_iter; use iterator::{Iterator, IteratorUtil}; use option::{None, Option, Some}; use rand::RngUtil; @@ -548,7 +547,7 @@ impl Eq for HashMap { fn eq(&self, other: &HashMap) -> bool { if self.len() != other.len() { return false; } - for self.each |key, value| { + for self.iter().advance |(key, value)| { match other.find(key) { None => return false, Some(v) => if value != v { return false }, @@ -662,12 +661,12 @@ impl Set for HashSet { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. fn is_disjoint(&self, other: &HashSet) -> bool { - old_iter::all(self, |v| !other.contains(v)) + self.iter().all(|v| !other.contains(v)) } /// Return true if the set is a subset of another fn is_subset(&self, other: &HashSet) -> bool { - old_iter::all(self, |v| other.contains(v)) + self.iter().all(|v| other.contains(v)) } /// Return true if the set is a superset of another @@ -677,7 +676,7 @@ impl Set for HashSet { /// Visit the values representing the difference fn difference(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.each(|v| other.contains(v) || f(v)) + self.iter().advance(|v| other.contains(v) || f(v)) } /// Visit the values representing the symmetric difference @@ -689,12 +688,12 @@ impl Set for HashSet { /// Visit the values representing the intersection fn intersection(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.each(|v| !other.contains(v) || f(v)) + self.iter().advance(|v| !other.contains(v) || f(v)) } /// Visit the values representing the union fn union(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.each(f) && other.each(|v| self.contains(v) || f(v)) + self.iter().advance(f) && other.iter().advance(|v| self.contains(v) || f(v)) } } @@ -875,7 +874,7 @@ mod test_map { assert!(m.insert(i, i*2)); } let mut observed = 0; - for m.each |k, v| { + for m.iter().advance |(k, v)| { assert_eq!(*v, *k * 2); observed |= (1 << *k); } From 13f666a72468ad20d5145ff5d618ef31c479c1a2 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 21 Jun 2013 17:05:29 +0200 Subject: [PATCH 066/336] std::hashmap: Remove BaseIter impl for HashSet Remove the BaseIter impl, while keeping the .each method until callers are converted. --- src/libstd/hashmap.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index dddda60702aa..0b6bf339d7ef 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -18,7 +18,6 @@ use container::{Container, Mutable, Map, Set}; use cmp::{Eq, Equiv}; use hash::Hash; -use old_iter::BaseIter; use iterator::{Iterator, IteratorUtil}; use option::{None, Option, Some}; use rand::RngUtil; @@ -622,12 +621,6 @@ pub struct HashSet { priv map: HashMap } -impl BaseIter for HashSet { - /// Visit all values in order - fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } - fn size_hint(&self) -> Option { Some(self.len()) } -} - impl Eq for HashSet { fn eq(&self, other: &HashSet) -> bool { self.map == other.map } fn ne(&self, other: &HashSet) -> bool { self.map != other.map } @@ -725,6 +718,12 @@ impl HashSet { self.map.contains_key_equiv(value) } + /// Visit all elements in arbitrary order + /// FIXME: Remove when all callers are converted + pub fn each(&self, f: &fn(&T) -> bool) -> bool { + self.iter().advance(f) + } + /// An iterator visiting all elements in arbitrary order. /// Iterator element type is &'a T. pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> { From 8baefec013876a46c084cf88d48c760a659e713f Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 21 Jun 2013 17:05:32 +0200 Subject: [PATCH 067/336] std::to_str: Use .iter() for HashMap and HashSet --- src/libstd/to_str.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index c6ac2c89f32e..56078a69f28f 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -23,6 +23,7 @@ use hash::Hash; use cmp::Eq; use old_iter::BaseIter; use vec::ImmutableVector; +use iterator::IteratorUtil; /// A generic trait for converting a value to a string pub trait ToStr { @@ -56,7 +57,7 @@ impl ToStr for HashMap { #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"{", true); - for self.each |key, value| { + for self.iter().advance |(key, value)| { if first { first = false; } @@ -76,7 +77,7 @@ impl ToStr for HashSet { #[inline] fn to_str(&self) -> ~str { let mut (acc, first) = (~"{", true); - for self.each |element| { + for self.iter().advance |element| { if first { first = false; } From ac2e167e7ed73cdb8863075d09633bb91ca0028f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 23 Jun 2013 05:13:13 -0400 Subject: [PATCH 068/336] hashmap: add FIXME number --- src/libstd/hashmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 0b6bf339d7ef..7d55947e8188 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -719,7 +719,7 @@ impl HashSet { } /// Visit all elements in arbitrary order - /// FIXME: Remove when all callers are converted + /// FIXME: #6978: Remove when all callers are converted pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.iter().advance(f) } From f2c5642d134df70755e0aede94074767cd3958eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Wed, 19 Jun 2013 19:54:54 +0200 Subject: [PATCH 069/336] Fix get_tydesc() return type This fixes part of #3730, but not all. Also changes the TyDesc struct to be equivalent with the generated code, with the hope that the above issue may one day be closed for good, i.e. that the TyDesc type can completely be specified in the Rust sources and not be generated. --- src/librustc/front/intrinsic.rs | 16 ++++++++++++---- src/librustc/middle/trans/foreign.rs | 9 ++++++--- src/librustc/middle/trans/glue.rs | 5 ++--- src/librustc/middle/trans/type_.rs | 11 ++++++++--- src/librustc/middle/typeck/check/mod.rs | 10 ++++++++-- src/libstd/unstable/intrinsics.rs | 3 +++ 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs index fcb08180a5ea..f19e37062535 100644 --- a/src/librustc/front/intrinsic.rs +++ b/src/librustc/front/intrinsic.rs @@ -20,14 +20,22 @@ pub mod intrinsic { // version in sys is no longer present. pub fn get_tydesc() -> *TyDesc { unsafe { - rusti::get_tydesc::() as *TyDesc + rusti::get_tydesc::() } } + pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); + + // NB: this has to be kept in sync with the Rust ABI. pub struct TyDesc { size: uint, - align: uint - // Remaining fields not listed + align: uint, + take_glue: GlueFn, + drop_glue: GlueFn, + free_glue: GlueFn, + visit_glue: GlueFn, + shape: *i8, + shape_tables: *i8 } pub enum Opaque { } @@ -133,7 +141,7 @@ pub mod intrinsic { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn get_tydesc() -> *(); + pub fn get_tydesc() -> *TyDesc; pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 10e63e6af777..855610510bd9 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -681,9 +681,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); - // FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the - // core::sys copy of the get_tydesc interface dies off. - let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to()); + // FIXME (#3730): ideally this shouldn't need a cast, + // but there's a circularity between translating rust types to llvm + // types and having a tydesc type available. So I can't directly access + // the llvm type of intrinsic::TyDesc struct. + let userland_tydesc_ty = type_of::type_of(ccx, output_type); + let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty); Store(bcx, td, fcx.llretptr.get()); } "init" => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index e9febb51005c..0930d3550353 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -789,7 +789,6 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { }; } -fn type_of_glue_fn(ccx: &CrateContext) -> Type { - let tydescpp = ccx.tydesc_type.ptr_to().ptr_to(); - Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void()) +pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { + Type::glue_fn(ccx.tydesc_type) } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 34a150331091..764bdb026f47 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -189,18 +189,23 @@ impl Type { None => () } + // Bit of a kludge: pick the fn typeref out of the tydesc.. let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); cx.tn.associate_type("glue_fn", &ty); return ty; } + pub fn glue_fn(tydesc: Type) -> Type { + let tydescpp = tydesc.ptr_to().ptr_to(); + Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], + &Type::void()) + } + pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); - let tydescpp = tydesc.ptr_to().ptr_to(); let pvoid = Type::i8p(); - let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ], - &Type::void()).ptr_to(); + let glue_fn_ty = Type::glue_fn(tydesc).ptr_to(); let int_ty = Type::int(arch); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872b..4c074ce197ed 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,8 +3506,14 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + let tydesc_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, + mutbl: ast::m_imm + }); + (1u, ~[], td_ptr) } "visit_tydesc" => { let tydesc_name = special_idents::tydesc; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index c38b013a75aa..08fc90fa908c 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -209,6 +209,9 @@ pub extern "rust-intrinsic" { pub fn pref_align_of() -> uint; /// Get a static pointer to a type descriptor. + #[cfg(not(stage0))] + pub fn get_tydesc() -> *::intrinsic::TyDesc; + #[cfg(stage0)] pub fn get_tydesc() -> *(); /// Create a value initialized to zero. From 469f394b251feebfb16090303da59206ba25acc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 11:39:49 +0200 Subject: [PATCH 070/336] Remove intrinsic module To achieve this, the following changes were made: * Move TyDesc, TyVisitor and Opaque to std::unstable::intrinsics * Convert TyDesc, TyVisitor and Opaque to lang items instead of specially handling the intrinsics module * Removed TypeDesc, FreeGlue and get_type_desc() from sys Fixes #3475. --- src/libextra/arena.rs | 29 +++-- src/libextra/dbg.rs | 34 +++--- src/librustc/driver/driver.rs | 3 - src/librustc/front/intrinsic.rs | 148 ------------------------ src/librustc/front/intrinsic_inject.rs | 47 -------- src/librustc/middle/lang_items.rs | 24 +++- src/librustc/middle/trans/reflect.rs | 8 +- src/librustc/middle/ty.rs | 27 +++-- src/librustc/middle/typeck/check/mod.rs | 8 +- src/librustc/middle/typeck/collect.rs | 55 ++------- src/librustc/rustc.rc | 1 - src/libstd/at_vec.rs | 13 ++- src/libstd/cleanup.rs | 28 +++-- src/libstd/managed.rs | 2 +- src/libstd/reflect.rs | 6 +- src/libstd/repr.rs | 20 +++- src/libstd/rt/global_heap.rs | 10 +- src/libstd/sys.rs | 12 +- src/libstd/unstable/exchange_alloc.rs | 10 +- src/libstd/unstable/intrinsics.rs | 129 ++++++++++++++++++++- src/libstd/vec.rs | 15 ++- src/test/run-pass/extern-pub.rs | 6 +- src/test/run-pass/reflect-visit-data.rs | 20 ++-- 23 files changed, 298 insertions(+), 357 deletions(-) delete mode 100644 src/librustc/front/intrinsic.rs delete mode 100644 src/librustc/front/intrinsic_inject.rs diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index db4cf564babc..a7d5660cd2e4 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -43,20 +43,27 @@ use core::cast::{transmute, transmute_mut_region}; use core::cast; use core::libc::size_t; use core::ptr; -use core::sys::TypeDesc; use core::sys; use core::uint; use core::vec; use core::unstable::intrinsics; +#[cfg(stage0)] +use intrinsic::{get_tydesc, TyDesc}; +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc, TyDesc}; + pub mod rustrt { use core::libc::size_t; - use core::sys::TypeDesc; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use core::unstable::intrinsics::{TyDesc}; pub extern { #[rust_stack] unsafe fn rust_call_tydesc_glue(root: *u8, - tydesc: *TypeDesc, + tydesc: *TyDesc, field: size_t); } } @@ -136,7 +143,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data); let (size, align) = ((*tydesc).size, (*tydesc).align); - let after_tydesc = idx + sys::size_of::<*TypeDesc>(); + let after_tydesc = idx + sys::size_of::<*TyDesc>(); let start = round_up_to(after_tydesc, align); @@ -148,7 +155,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { } // Find where the next tydesc lives - idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>()); + idx = round_up_to(start + size, sys::pref_align_of::<*TyDesc>()); } } @@ -157,12 +164,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) { // is necessary in order to properly do cleanup if a failure occurs // during an initializer. #[inline] -unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint { +unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint { let p_bits: uint = transmute(p); p_bits | (is_done as uint) } #[inline] -unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) { +unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) { (transmute(p & !1), p & 1 == 1) } @@ -202,7 +209,7 @@ impl Arena { #[inline] fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { - let tydesc = sys::get_type_desc::(); + let tydesc = get_tydesc::(); let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); let ptr: *mut T = transmute(ptr); intrinsics::move_val_init(&mut (*ptr), op()); @@ -230,13 +237,13 @@ impl Arena { let head = transmute_mut_region(&mut self.head); let tydesc_start = head.fill; - let after_tydesc = head.fill + sys::size_of::<*TypeDesc>(); + let after_tydesc = head.fill + sys::size_of::<*TyDesc>(); let start = round_up_to(after_tydesc, align); let end = start + n_bytes; if end > at_vec::capacity(head.data) { return self.alloc_nonpod_grow(n_bytes, align); } - head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>()); + head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>()); //debug!("idx = %u, size = %u, align = %u, fill = %u", // start, n_bytes, align, head.fill); @@ -249,7 +256,7 @@ impl Arena { #[inline] fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { unsafe { - let tydesc = sys::get_type_desc::(); + let tydesc = get_tydesc::(); let (ty_ptr, ptr) = self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align); let ty_ptr: *mut uint = transmute(ty_ptr); diff --git a/src/libextra/dbg.rs b/src/libextra/dbg.rs index cbd7cb5e3c08..43c4aecdd27f 100644 --- a/src/libextra/dbg.rs +++ b/src/libextra/dbg.rs @@ -13,56 +13,62 @@ #[allow(missing_doc)]; use core::cast::transmute; -use core::sys; +#[cfg(stage0)] +use intrinsic::{get_tydesc}; +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc}; pub mod rustrt { - use core::sys; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use core::unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] pub extern { - pub unsafe fn debug_tydesc(td: *sys::TypeDesc); - pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_box(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *()); - pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *(); + pub unsafe fn debug_tydesc(td: *TyDesc); + pub unsafe fn debug_opaque(td: *TyDesc, x: *()); + pub unsafe fn debug_box(td: *TyDesc, x: *()); + pub unsafe fn debug_tag(td: *TyDesc, x: *()); + pub unsafe fn debug_fn(td: *TyDesc, x: *()); + pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *(); pub unsafe fn rust_dbg_breakpoint(); } } pub fn debug_tydesc() { unsafe { - rustrt::debug_tydesc(sys::get_type_desc::()); + rustrt::debug_tydesc(get_tydesc::()); } } pub fn debug_opaque(x: T) { unsafe { - rustrt::debug_opaque(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_opaque(get_tydesc::(), transmute(&x)); } } pub fn debug_box(x: @T) { unsafe { - rustrt::debug_box(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_box(get_tydesc::(), transmute(&x)); } } pub fn debug_tag(x: T) { unsafe { - rustrt::debug_tag(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_tag(get_tydesc::(), transmute(&x)); } } pub fn debug_fn(x: T) { unsafe { - rustrt::debug_fn(sys::get_type_desc::(), transmute(&x)); + rustrt::debug_fn(get_tydesc::(), transmute(&x)); } } pub unsafe fn ptr_cast(x: @T) -> @U { transmute( - rustrt::debug_ptrcast(sys::get_type_desc::(), transmute(x))) + rustrt::debug_ptrcast(get_tydesc::(), transmute(x))) } /// Triggers a debugger breakpoint diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 1a7041c08840..fbb273450df2 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -206,9 +206,6 @@ pub fn compile_rest(sess: Session, let mut crate = crate_opt.unwrap(); let (llcx, llmod, link_meta) = { - crate = time(time_passes, ~"intrinsic injection", || - front::intrinsic_inject::inject_intrinsic(sess, crate)); - crate = time(time_passes, ~"extra injection", || front::std_inject::maybe_inject_libstd_ref(sess, crate)); diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs deleted file mode 100644 index f19e37062535..000000000000 --- a/src/librustc/front/intrinsic.rs +++ /dev/null @@ -1,148 +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. - -// NB: this file is include_str!'ed into the compiler, re-parsed -// and injected into each crate the compiler builds. Keep it small. - -pub mod intrinsic { - #[allow(missing_doc)]; - - pub use intrinsic::rusti::visit_tydesc; - - // FIXME (#3727): remove this when the interface has settled and the - // version in sys is no longer present. - pub fn get_tydesc() -> *TyDesc { - unsafe { - rusti::get_tydesc::() - } - } - - pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); - - // NB: this has to be kept in sync with the Rust ABI. - pub struct TyDesc { - size: uint, - align: uint, - take_glue: GlueFn, - drop_glue: GlueFn, - free_glue: GlueFn, - visit_glue: GlueFn, - shape: *i8, - shape_tables: *i8 - } - - pub enum Opaque { } - - pub trait TyVisitor { - fn visit_bot(&self) -> bool; - fn visit_nil(&self) -> bool; - fn visit_bool(&self) -> bool; - - fn visit_int(&self) -> bool; - fn visit_i8(&self) -> bool; - fn visit_i16(&self) -> bool; - fn visit_i32(&self) -> bool; - fn visit_i64(&self) -> bool; - - fn visit_uint(&self) -> bool; - fn visit_u8(&self) -> bool; - fn visit_u16(&self) -> bool; - fn visit_u32(&self) -> bool; - fn visit_u64(&self) -> bool; - - fn visit_float(&self) -> bool; - fn visit_f32(&self) -> bool; - fn visit_f64(&self) -> bool; - - fn visit_char(&self) -> bool; - fn visit_str(&self) -> bool; - - fn visit_estr_box(&self) -> bool; - fn visit_estr_uniq(&self) -> bool; - fn visit_estr_slice(&self) -> bool; - fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool; - - fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool; - - fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool; - fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, - mtbl: uint, inner: *TyDesc) -> bool; - - fn visit_enter_rec(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - fn visit_rec_field(&self, i: uint, name: &str, - mtbl: uint, inner: *TyDesc) -> bool; - fn visit_leave_rec(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - - fn visit_enter_class(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - fn visit_class_field(&self, i: uint, name: &str, - mtbl: uint, inner: *TyDesc) -> bool; - fn visit_leave_class(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - - fn visit_enter_tup(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool; - fn visit_leave_tup(&self, n_fields: uint, - sz: uint, align: uint) -> bool; - - fn visit_enter_enum(&self, n_variants: uint, - get_disr: extern unsafe fn(ptr: *Opaque) -> int, - sz: uint, align: uint) -> bool; - fn visit_enter_enum_variant(&self, variant: uint, - disr_val: int, - n_fields: uint, - name: &str) -> bool; - fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool; - fn visit_leave_enum_variant(&self, variant: uint, - disr_val: int, - n_fields: uint, - name: &str) -> bool; - fn visit_leave_enum(&self, n_variants: uint, - get_disr: extern unsafe fn(ptr: *Opaque) -> int, - sz: uint, align: uint) -> bool; - - fn visit_enter_fn(&self, purity: uint, proto: uint, - n_inputs: uint, retstyle: uint) -> bool; - fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool; - fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool; - fn visit_leave_fn(&self, purity: uint, proto: uint, - n_inputs: uint, retstyle: uint) -> bool; - - fn visit_trait(&self) -> bool; - fn visit_var(&self) -> bool; - fn visit_var_integral(&self) -> bool; - fn visit_param(&self, i: uint) -> bool; - fn visit_self(&self) -> bool; - fn visit_type(&self) -> bool; - fn visit_opaque_box(&self) -> bool; - fn visit_constr(&self, inner: *TyDesc) -> bool; - fn visit_closure_ptr(&self, ck: uint) -> bool; - } - - pub mod rusti { - use super::{TyDesc, TyVisitor}; - - #[abi = "rust-intrinsic"] - pub extern "rust-intrinsic" { - pub fn get_tydesc() -> *TyDesc; - pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); - } - } -} diff --git a/src/librustc/front/intrinsic_inject.rs b/src/librustc/front/intrinsic_inject.rs deleted file mode 100644 index 0caadc8572e9..000000000000 --- a/src/librustc/front/intrinsic_inject.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::prelude::*; - -use core::vec; -use driver::session::Session; -use syntax::parse; -use syntax::ast; -use syntax::codemap::spanned; - -pub fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate { - let intrinsic_module = include_str!("intrinsic.rs").to_managed(); - - let item = parse::parse_item_from_source_str(@"", - intrinsic_module, - /*bad*/copy sess.opts.cfg, - ~[], - sess.parse_sess); - let item = - match item { - Some(i) => i, - None => { - sess.fatal("no item found in intrinsic module"); - } - }; - - let items = vec::append(~[item], crate.node.module.items); - - @spanned { - node: ast::crate_ { - module: ast::_mod { - items: items, - .. /*bad*/copy crate.node.module - }, - .. /*bad*/copy crate.node - }, - .. /*bad*/copy *crate - } -} diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 3a8d369469b1..d73b019c1ea7 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -76,16 +76,20 @@ pub enum LangItem { UnrecordBorrowFnLangItem, // 36 StartFnLangItem, // 37 + + TyDescStructLangItem, // 38 + TyVisitorTraitLangItem, // 39 + OpaqueStructLangItem, // 40 } pub struct LanguageItems { - items: [Option, ..38] + items: [Option, ..41] } impl LanguageItems { pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..38 ] + items: [ None, ..41 ] } } @@ -138,6 +142,10 @@ impl LanguageItems { 37 => "start", + 38 => "ty_desc", + 39 => "ty_visitor", + 40 => "opaque", + _ => "???" } } @@ -262,6 +270,15 @@ impl LanguageItems { pub fn start_fn(&const self) -> def_id { self.items[StartFnLangItem as uint].get() } + pub fn ty_desc(&const self) -> def_id { + self.items[TyDescStructLangItem as uint].get() + } + pub fn ty_visitor(&const self) -> def_id { + self.items[TyVisitorTraitLangItem as uint].get() + } + pub fn opaque(&const self) -> def_id { + self.items[OpaqueStructLangItem as uint].get() + } } fn LanguageItemCollector(crate: @crate, @@ -313,6 +330,9 @@ fn LanguageItemCollector(crate: @crate, item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint); item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint); item_refs.insert(@"start", StartFnLangItem as uint); + item_refs.insert(@"ty_desc", TyDescStructLangItem as uint); + item_refs.insert(@"ty_visitor", TyVisitorTraitLangItem as uint); + item_refs.insert(@"opaque", OpaqueStructLangItem as uint); LanguageItemCollector { crate: crate, diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index cb68a2af92bb..9e5510fc6058 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -274,9 +274,7 @@ impl Reflector { let repr = adt::represent_type(bcx.ccx(), t); let variants = ty::substd_enum_variants(ccx.tcx, did, substs); let llptrty = type_of(ccx, t).ptr_to(); - let (_, opaquety) = - ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque")) - .expect("Failed to resolve intrinsic::Opaque"); + let opaquety = ty::get_opaque_ty(ccx.tcx); let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm }); let make_get_disr = || { @@ -373,10 +371,8 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block, visitor_val: ValueRef, visitor_trait_id: def_id) -> block { - use syntax::parse::token::special_idents::tydesc; let final = sub_block(bcx, "final"); - assert!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc)); - let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get_copy(&tydesc); + let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); let mut r = Reflector { visitor_val: visitor_val, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a367cf4c430a..f12ecebc6d5c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -44,7 +44,6 @@ use syntax::attr; use syntax::codemap::span; use syntax::codemap; use syntax::parse::token; -use syntax::parse::token::special_idents; use syntax::{ast, ast_map}; use syntax::opt_vec::OptVec; use syntax::opt_vec; @@ -276,8 +275,7 @@ struct ctxt_ { trait_defs: @mut HashMap, items: ast_map::map, - intrinsic_defs: @mut HashMap, - intrinsic_traits: @mut HashMap, + intrinsic_defs: @mut HashMap, freevars: freevars::freevar_map, tcache: type_cache, rcache: creader_cache, @@ -953,7 +951,6 @@ pub fn mk_ctxt(s: session::Session, node_type_substs: @mut HashMap::new(), trait_refs: @mut HashMap::new(), trait_defs: @mut HashMap::new(), - intrinsic_traits: @mut HashMap::new(), items: amap, intrinsic_defs: @mut HashMap::new(), freevars: freevars, @@ -4449,10 +4446,26 @@ pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id { } } +pub fn get_tydesc_ty(tcx: ctxt) -> t { + let tydesc_lang_item = tcx.lang_items.ty_desc(); + tcx.intrinsic_defs.find_copy(&tydesc_lang_item) + .expect("Failed to resolve TyDesc") +} + +pub fn get_opaque_ty(tcx: ctxt) -> t { + let tydesc_lang_item = tcx.lang_items.opaque(); + tcx.intrinsic_defs.find_copy(&tydesc_lang_item) + .expect("Failed to resolve Opaque") +} + pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) { - let ty_visitor_name = special_idents::ty_visitor; - assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name)); - let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name); + let substs = substs { + self_r: None, + self_ty: None, + tps: ~[] + }; + let trait_lang_item = tcx.lang_items.ty_visitor(); + let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs }; (trait_ref, mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm)) } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 4c074ce197ed..821daee8bfbf 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,9 +3506,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } "get_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let tydesc_ty = ty::get_tydesc_ty(ccx.tcx); let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, mutbl: ast::m_imm @@ -3516,9 +3514,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { (1u, ~[], td_ptr) } "visit_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let tydesc_ty = ty::get_tydesc_ty(ccx.tcx); let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { ty: tydesc_ty, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 7f820d11ac61..756bb4d1bb92 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -62,55 +62,16 @@ use syntax::opt_vec::OptVec; use syntax::opt_vec; pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { - - // FIXME (#2592): hooking into the "intrinsic" root module is crude. - // There ought to be a better approach. Attributes? - - for crate.node.module.items.iter().advance |crate_item| { - if crate_item.ident - == ::syntax::parse::token::special_idents::intrinsic { - - match crate_item.node { - ast::item_mod(ref m) => { - for m.items.iter().advance |intrinsic_item| { - let def_id = ast::def_id { crate: ast::local_crate, - node: intrinsic_item.id }; - let substs = substs { - self_r: None, - self_ty: None, - tps: ~[] - }; - - match intrinsic_item.node { - ast::item_trait(*) => { - let tref = @ty::TraitRef {def_id: def_id, - substs: substs}; - ccx.tcx.intrinsic_traits.insert - (intrinsic_item.ident, tref); - } - - ast::item_enum(*) => { - let ty = ty::mk_enum(ccx.tcx, def_id, substs); - ccx.tcx.intrinsic_defs.insert - (intrinsic_item.ident, (def_id, ty)); - } - - ast::item_struct(*) => { - let ty = ty::mk_struct(ccx.tcx, def_id, substs); - ccx.tcx.intrinsic_defs.insert - (intrinsic_item.ident, (def_id, ty)); - } - - _ => {} - } - } - } - _ => { } - } - break; - } + fn collect_intrinsic_type(ccx: @mut CrateCtxt, + lang_item: ast::def_id) { + let ty::ty_param_bounds_and_ty { ty: ty, _ } = + ccx.get_item_ty(lang_item); + ccx.tcx.intrinsic_defs.insert(lang_item, ty); } + collect_intrinsic_type(ccx, ccx.tcx.lang_items.ty_desc()); + collect_intrinsic_type(ccx, ccx.tcx.lang_items.opaque()); + visit::visit_crate( crate, ((), visit::mk_simple_visitor(@visit::SimpleVisitor { diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index d59a308beb53..20705b3d7975 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -86,7 +86,6 @@ pub mod front { pub mod config; pub mod test; pub mod std_inject; - pub mod intrinsic_inject; } pub mod back { diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 2b846c923c48..52115692dbce 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -26,13 +26,16 @@ use vec::ImmutableVector; pub mod rustrt { use libc; - use sys; use vec; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] #[link_name = "rustrt"] pub extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + pub unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **vec::raw::VecRepr, n: libc::size_t); } @@ -198,6 +201,10 @@ pub mod raw { use uint; use unstable::intrinsics::{move_val_init}; use vec; + #[cfg(stage0)] + use intrinsic::{get_tydesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{get_tydesc}; pub type VecRepr = vec::raw::VecRepr; pub type SliceRepr = vec::raw::SliceRepr; @@ -259,7 +266,7 @@ pub mod raw { // Only make the (slow) call into the runtime if we have to if capacity(*v) < n { let ptr: **VecRepr = transmute(v); - rustrt::vec_reserve_shared_actual(sys::get_type_desc::(), + rustrt::vec_reserve_shared_actual(get_tydesc::(), ptr, n as libc::size_t); } } diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index d1460b7a3c96..28aab9adad2c 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -10,24 +10,18 @@ #[doc(hidden)]; -use libc::{c_char, c_void, intptr_t, uintptr_t}; -use ptr::mut_null; +use libc::{c_char, intptr_t, uintptr_t}; +use ptr::{mut_null, to_unsafe_ptr}; use repr::BoxRepr; -use sys::TypeDesc; use cast::transmute; #[cfg(not(test))] use unstable::lang::clear_task_borrow_list; -#[cfg(not(test))] use ptr::to_unsafe_ptr; - /** * Runtime structures * * NB: These must match the representation in the C++ runtime. */ -type DropGlue<'self> = &'self fn(**TypeDesc, *c_void); -type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void); - type TaskID = uintptr_t; struct StackSegment { priv opaque: () } @@ -164,6 +158,20 @@ fn debug_mem() -> bool { false } +#[cfg(stage0)] +unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { + use sys::TypeDesc; + + let tydesc: *TypeDesc = transmute(tydesc); + let drop_glue: extern "Rust" fn(**TypeDesc, *i8) = transmute((*tydesc).drop_glue); + drop_glue(to_unsafe_ptr(&tydesc), data); +} + +#[cfg(not(stage0))] +unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { + ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); +} + /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -205,9 +213,7 @@ pub unsafe fn annihilate() { // callback, as the original value may have been freed. for each_live_alloc(false) |box, uniq| { if !uniq { - let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc); - let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0)); - drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data)); + call_drop_glue((*box).header.type_desc, transmute(&(*box).data)); } } diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index d514612b5afd..b71b3b503c2a 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -15,7 +15,7 @@ use ptr::to_unsafe_ptr; #[cfg(not(test))] use cmp::{Eq, Ord}; pub mod raw { - use intrinsic::TyDesc; + use std::unstable::intrinsics::TyDesc; pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint; pub static RC_MANAGED_UNIQUE : uint = (-2) as uint; diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index d276abf0c8b3..16ab4771d0de 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -16,8 +16,10 @@ Runtime type reflection #[allow(missing_doc)]; -use intrinsic::{TyDesc, TyVisitor}; -use intrinsic::Opaque; +#[cfg(stage0)] +use intrinsic::{Opaque, TyDesc, TyVisitor}; +#[cfg(not(stage0))] +use unstable::intrinsics::{Opaque, TyDesc, TyVisitor}; use libc::c_void; use sys; use vec; diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index ab3f83d34d59..f39b5a00ed05 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -19,9 +19,6 @@ More runtime type reflection use cast::transmute; use char; use container::Container; -use intrinsic; -use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; -use intrinsic::Opaque; use io::{Writer, WriterUtil}; use iterator::IteratorUtil; use libc::c_void; @@ -34,6 +31,10 @@ use to_str::ToStr; use vec::raw::{VecRepr, SliceRepr}; use vec; use vec::{OwnedVector, UnboxedVecRepr}; +#[cfg(stage0)] +use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc}; +#[cfg(not(stage0))] +use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc}; #[cfg(test)] use io; @@ -564,6 +565,7 @@ impl TyVisitor for ReprVisitor { fn visit_self(&self) -> bool { true } fn visit_type(&self) -> bool { true } + #[cfg(not(stage0))] fn visit_opaque_box(&self) -> bool { self.writer.write_char('@'); do self.get::<&managed::raw::BoxRepr> |b| { @@ -571,6 +573,16 @@ impl TyVisitor for ReprVisitor { self.visit_ptr_inner(p, b.header.type_desc); } } + #[cfg(stage0)] + fn visit_opaque_box(&self) -> bool { + self.writer.write_char('@'); + do self.get::<&managed::raw::BoxRepr> |b| { + let p = ptr::to_unsafe_ptr(&b.data) as *c_void; + unsafe { + self.visit_ptr_inner(p, transmute(b.header.type_desc)); + } + } + } // Type no longer exists, vestigial function. fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); } @@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor { pub fn write_repr(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; - let tydesc = intrinsic::get_tydesc::(); + let tydesc = get_tydesc::(); let u = ReprVisitor(ptr, writer); let v = reflect::MovePtrAdaptor(u); visit_tydesc(tydesc, @v as @TyVisitor) diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index ce7ff87b4458..1e9f9aab8345 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -8,26 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::{size_of}; use libc::{c_void, size_t, uintptr_t}; use c_malloc = libc::malloc; use c_free = libc::free; use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; -use unstable::intrinsics::{atomic_xadd,atomic_xsub}; +use unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc}; use ptr::null; -use intrinsic::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { assert!(td.is_not_null()); let total_size = get_box_size(size, (*td).align); let p = c_malloc(total_size as size_t); assert!(p.is_not_null()); - // FIXME #3475: Converting between our two different tydesc types - let td: *TyDesc = transmute(td); - let box: &mut BoxRepr = transmute(p); box.header.ref_count = -1; // Exchange values not ref counted box.header.type_desc = td; diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 79ea60cc2240..7f80375c2f6a 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -17,14 +17,13 @@ use cast; use gc; use io; use libc; -use libc::{c_void, c_char, size_t}; +use libc::{c_char, size_t}; use repr; use str; use unstable::intrinsics; -pub type FreeGlue<'self> = &'self fn(*TypeDesc, *c_void); - // Corresponds to runtime type_desc type +#[cfg(stage0)] pub struct TypeDesc { size: uint, align: uint, @@ -58,16 +57,11 @@ pub mod rustrt { * performing dark magick. */ #[inline] +#[cfg(stage0)] pub fn get_type_desc() -> *TypeDesc { unsafe { intrinsics::get_tydesc::() as *TypeDesc } } -/// Returns a pointer to a type descriptor. -#[inline] -pub fn get_type_desc_val(_val: &T) -> *TypeDesc { - get_type_desc::() -} - /// Returns the size of a type #[inline] pub fn size_of() -> uint { diff --git a/src/libstd/unstable/exchange_alloc.rs b/src/libstd/unstable/exchange_alloc.rs index 3b35c2fb8047..5c47901df480 100644 --- a/src/libstd/unstable/exchange_alloc.rs +++ b/src/libstd/unstable/exchange_alloc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{TypeDesc, size_of}; +use sys::size_of; use libc::{c_void, size_t}; use c_malloc = libc::malloc; use c_free = libc::free; @@ -16,18 +16,18 @@ use managed::raw::{BoxHeaderRepr, BoxRepr}; use cast::transmute; use unstable::intrinsics::{atomic_xadd,atomic_xsub}; use ptr::null; +#[cfg(stage0)] use intrinsic::TyDesc; +#[cfg(not(stage0))] +use unstable::intrinsics::TyDesc; -pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { +pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { assert!(td.is_not_null()); let total_size = get_box_size(size, (*td).align); let p = c_malloc(total_size as size_t); assert!(p.is_not_null()); - // FIXME #3475: Converting between our two different tydesc types - let td: *TyDesc = transmute(td); - let box: &mut BoxRepr = transmute(p); box.header.ref_count = -1; // Exchange values not ref counted box.header.type_desc = td; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 08fc90fa908c..a51ba05710b1 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -32,6 +32,128 @@ A quick refresher on memory ordering: */ +// This is needed to prevent duplicate lang item definitions. +#[cfg(test)] +pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor}; + +pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); + +// NB: this has to be kept in sync with the Rust ABI. +#[lang="ty_desc"] +#[cfg(not(test))] +pub struct TyDesc { + size: uint, + align: uint, + take_glue: GlueFn, + drop_glue: GlueFn, + free_glue: GlueFn, + visit_glue: GlueFn, + shape: *i8, + shape_tables: *i8 +} + +#[lang="opaque"] +#[cfg(not(test))] +pub enum Opaque { } + +#[lang="ty_visitor"] +#[cfg(not(test))] +pub trait TyVisitor { + fn visit_bot(&self) -> bool; + fn visit_nil(&self) -> bool; + fn visit_bool(&self) -> bool; + + fn visit_int(&self) -> bool; + fn visit_i8(&self) -> bool; + fn visit_i16(&self) -> bool; + fn visit_i32(&self) -> bool; + fn visit_i64(&self) -> bool; + + fn visit_uint(&self) -> bool; + fn visit_u8(&self) -> bool; + fn visit_u16(&self) -> bool; + fn visit_u32(&self) -> bool; + fn visit_u64(&self) -> bool; + + fn visit_float(&self) -> bool; + fn visit_f32(&self) -> bool; + fn visit_f64(&self) -> bool; + + fn visit_char(&self) -> bool; + fn visit_str(&self) -> bool; + + fn visit_estr_box(&self) -> bool; + fn visit_estr_uniq(&self) -> bool; + fn visit_estr_slice(&self) -> bool; + fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool; + + fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool; + + fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool; + fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, + mtbl: uint, inner: *TyDesc) -> bool; + + fn visit_enter_rec(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + fn visit_rec_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool; + fn visit_leave_rec(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + + fn visit_enter_class(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + fn visit_class_field(&self, i: uint, name: &str, + mtbl: uint, inner: *TyDesc) -> bool; + fn visit_leave_class(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + + fn visit_enter_tup(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool; + fn visit_leave_tup(&self, n_fields: uint, + sz: uint, align: uint) -> bool; + + fn visit_enter_enum(&self, n_variants: uint, + get_disr: extern unsafe fn(ptr: *Opaque) -> int, + sz: uint, align: uint) -> bool; + fn visit_enter_enum_variant(&self, variant: uint, + disr_val: int, + n_fields: uint, + name: &str) -> bool; + fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool; + fn visit_leave_enum_variant(&self, variant: uint, + disr_val: int, + n_fields: uint, + name: &str) -> bool; + fn visit_leave_enum(&self, n_variants: uint, + get_disr: extern unsafe fn(ptr: *Opaque) -> int, + sz: uint, align: uint) -> bool; + + fn visit_enter_fn(&self, purity: uint, proto: uint, + n_inputs: uint, retstyle: uint) -> bool; + fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool; + fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool; + fn visit_leave_fn(&self, purity: uint, proto: uint, + n_inputs: uint, retstyle: uint) -> bool; + + fn visit_trait(&self) -> bool; + fn visit_var(&self) -> bool; + fn visit_var_integral(&self) -> bool; + fn visit_param(&self, i: uint) -> bool; + fn visit_self(&self) -> bool; + fn visit_type(&self) -> bool; + fn visit_opaque_box(&self) -> bool; + fn visit_constr(&self, inner: *TyDesc) -> bool; + fn visit_closure_ptr(&self, ck: uint) -> bool; +} + #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { @@ -210,7 +332,7 @@ pub extern "rust-intrinsic" { /// Get a static pointer to a type descriptor. #[cfg(not(stage0))] - pub fn get_tydesc() -> *::intrinsic::TyDesc; + pub fn get_tydesc() -> *TyDesc; #[cfg(stage0)] pub fn get_tydesc() -> *(); @@ -234,9 +356,8 @@ pub extern "rust-intrinsic" { /// Returns `true` if a type requires drop glue. pub fn needs_drop() -> bool; - // XXX: intrinsic uses legacy modes and has reference to TyDesc - // and TyVisitor which are in librustc - //fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> (); + #[cfg(not(stage0))] + pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); pub fn frame_address(f: &once fn(*u8)); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 17eb7e8e82be..fdf33df3a8a1 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -31,6 +31,10 @@ use sys; use sys::size_of; use uint; use unstable::intrinsics; +#[cfg(stage0)] +use intrinsic::{get_tydesc}; +#[cfg(not(stage0))] +use unstable::intrinsics::{get_tydesc}; use vec; use util; @@ -38,19 +42,22 @@ use util; pub mod rustrt { use libc; - use sys; use vec::raw; + #[cfg(stage0)] + use intrinsic::{TyDesc}; + #[cfg(not(stage0))] + use unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] pub extern { // These names are terrible. reserve_shared applies // to ~[] and reserve_shared_actual applies to @[]. #[fast_ffi] - unsafe fn vec_reserve_shared(t: *sys::TypeDesc, + unsafe fn vec_reserve_shared(t: *TyDesc, v: **raw::VecRepr, n: libc::size_t); #[fast_ffi] - unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, + unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **raw::VecRepr, n: libc::size_t); } @@ -79,7 +86,7 @@ pub fn reserve(v: &mut ~[T], n: uint) { if capacity(v) < n { unsafe { let ptr: **raw::VecRepr = cast::transmute(v); - let td = sys::get_type_desc::(); + let td = get_tydesc::(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 29b0457fc050..2d6cc2c78deb 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,11 +1,7 @@ use std::libc; -use std::sys; -use std::vec; extern { - pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc, - v: **vec::raw::VecRepr, - n: libc::size_t); + pub unsafe fn free(p: *libc::c_void); } pub fn main() { diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index a8571ab73254..176e49e0ea19 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -10,15 +10,14 @@ // xfail-fast -use std::bool; use std::int; use std::libc::c_void; use std::ptr; use std::sys; use std::vec::UnboxedVecRepr; -use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque}; +use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque}; -#[doc = "High-level interfaces to `intrinsic::visit_ty` reflection system."] +#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."] /// Trait for visitor that wishes to reflect on data. trait movable_ptr { @@ -637,7 +636,9 @@ impl TyVisitor for my_visitor { } fn get_tydesc_for(_t: T) -> *TyDesc { - get_tydesc::() + unsafe { + get_tydesc::() + } } struct Triple { x: int, y: int, z: int } @@ -651,8 +652,8 @@ pub fn main() { vals: ~[]}); let v = ptr_visit_adaptor(Inner {inner: u}); let td = get_tydesc_for(r); - unsafe { error!("tydesc sz: %u, align: %u", - (*td).size, (*td).align); } + error!("tydesc sz: %u, align: %u", + (*td).size, (*td).align); let v = @v as @TyVisitor; visit_tydesc(td, v); @@ -661,8 +662,7 @@ pub fn main() { println(fmt!("val: %s", *s)); } error!("%?", u.vals.clone()); - assert!(u.vals == ~[ - ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12" - ]); + assert_eq!(u.vals.clone(), + ~[ ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"]); } - } +} From 179ce398ea9e09920ace2264144422bb7e9efc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 11:40:17 +0200 Subject: [PATCH 071/336] Fix and reenable the reflect-visit-type test --- src/test/run-pass/reflect-visit-type.rs | 171 +++++++++++++----------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 8a7fef956144..3b51abbd489b 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -8,141 +8,153 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test -use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; -struct my_visitor(@mut { types: ~[str] }); +use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque}; -impl TyVisitor for my_visitor { - fn visit_bot() -> bool { - self.types += ~["bot"]; +struct MyVisitor { + types: @mut ~[~str], +} + +impl TyVisitor for MyVisitor { + fn visit_bot(&self) -> bool { + self.types.push(~"bot"); error!("visited bot type"); true } - fn visit_nil() -> bool { - self.types += ~["nil"]; + fn visit_nil(&self) -> bool { + self.types.push(~"nil"); error!("visited nil type"); true } - fn visit_bool() -> bool { - self.types += ~["bool"]; + fn visit_bool(&self) -> bool { + self.types.push(~"bool"); error!("visited bool type"); true } - fn visit_int() -> bool { - self.types += ~["int"]; + fn visit_int(&self) -> bool { + self.types.push(~"int"); error!("visited int type"); true } - fn visit_i8() -> bool { - self.types += ~["i8"]; + fn visit_i8(&self) -> bool { + self.types.push(~"i8"); error!("visited i8 type"); true } - fn visit_i16() -> bool { - self.types += ~["i16"]; + fn visit_i16(&self) -> bool { + self.types.push(~"i16"); error!("visited i16 type"); true } - fn visit_i32() -> bool { true } - fn visit_i64() -> bool { true } + fn visit_i32(&self) -> bool { true } + fn visit_i64(&self) -> bool { true } - fn visit_uint() -> bool { true } - fn visit_u8() -> bool { true } - fn visit_u16() -> bool { true } - fn visit_u32() -> bool { true } - fn visit_u64() -> bool { true } + fn visit_uint(&self) -> bool { true } + fn visit_u8(&self) -> bool { true } + fn visit_u16(&self) -> bool { true } + fn visit_u32(&self) -> bool { true } + fn visit_u64(&self) -> bool { true } - fn visit_float() -> bool { true } - fn visit_f32() -> bool { true } - fn visit_f64() -> bool { true } + fn visit_float(&self) -> bool { true } + fn visit_f32(&self) -> bool { true } + fn visit_f64(&self) -> bool { true } - fn visit_char() -> bool { true } - fn visit_str() -> bool { true } + fn visit_char(&self) -> bool { true } + fn visit_str(&self) -> bool { true } - fn visit_estr_box() -> bool { true } - fn visit_estr_uniq() -> bool { true } - fn visit_estr_slice() -> bool { true } - fn visit_estr_fixed(_sz: uint, _sz: uint, + fn visit_estr_box(&self) -> bool { true } + fn visit_estr_uniq(&self) -> bool { true } + fn visit_estr_slice(&self) -> bool { true } + fn visit_estr_fixed(&self, + _sz: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_ptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_rptr(_mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_uniq(&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 } - fn visit_vec(_mtbl: uint, inner: *TyDesc) -> bool { - self.types += ~["["]; - visit_tydesc(inner, my_visitor(*self) as TyVisitor); - self.types += ~["]"]; + fn visit_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_uniq(&self, _mtbl: uint, inner: *TyDesc) -> bool { + self.types.push(~"["); + unsafe { + visit_tydesc(inner, (@*self) as @TyVisitor); + } + self.types.push(~"]"); true } - fn visit_unboxed_vec(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_box(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_uniq(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_slice(_mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_evec_fixed(_n: uint, _sz: uint, _align: uint, + fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } + fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint, _mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_enter_rec(_n_fields: uint, + fn visit_enter_rec(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_rec_field(_i: uint, _name: &str, + fn visit_rec_field(&self, _i: uint, _name: &str, _mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_rec(_n_fields: uint, + fn visit_leave_rec(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_class(_n_fields: uint, + fn visit_enter_class(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_class_field(_i: uint, _name: &str, + fn visit_class_field(&self, _i: uint, _name: &str, _mtbl: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_class(_n_fields: uint, + fn visit_leave_class(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_tup(_n_fields: uint, + fn visit_enter_tup(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_tup_field(_i: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_tup(_n_fields: uint, + fn visit_tup_field(&self, _i: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_tup(&self, _n_fields: uint, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_enum(_n_variants: uint, + fn visit_enter_enum(&self, _n_variants: uint, + _get_disr: extern unsafe fn(ptr: *Opaque) -> int, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_enum_variant(_variant: uint, + fn visit_enter_enum_variant(&self, + _variant: uint, _disr_val: int, _n_fields: uint, _name: &str) -> bool { true } - fn visit_enum_variant_field(_i: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_enum_variant(_variant: uint, + fn visit_enum_variant_field(&self, _i: uint, _offset: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_enum_variant(&self, + _variant: uint, _disr_val: int, _n_fields: uint, _name: &str) -> bool { true } - fn visit_leave_enum(_n_variants: uint, + fn visit_leave_enum(&self, + _n_variants: uint, + _get_disr: extern unsafe fn(ptr: *Opaque) -> int, _sz: uint, _align: uint) -> bool { true } - fn visit_enter_fn(_purity: uint, _proto: uint, + fn visit_enter_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_fn_input(_i: uint, _mode: uint, _inner: *TyDesc) -> bool { true } - fn visit_fn_output(_retstyle: uint, _inner: *TyDesc) -> bool { true } - fn visit_leave_fn(_purity: uint, _proto: uint, + fn visit_fn_input(&self, _i: uint, _mode: uint, _inner: *TyDesc) -> bool { true } + fn visit_fn_output(&self, _retstyle: uint, _inner: *TyDesc) -> bool { true } + fn visit_leave_fn(&self, _purity: uint, _proto: uint, _n_inputs: uint, _retstyle: uint) -> bool { true } - fn visit_trait() -> bool { true } - fn visit_var() -> bool { true } - fn visit_var_integral() -> bool { true } - fn visit_param(_i: uint) -> bool { true } - fn visit_self() -> bool { true } - fn visit_type() -> bool { true } - fn visit_opaque_box() -> bool { true } - fn visit_constr(_inner: *TyDesc) -> bool { true } - fn visit_closure_ptr(_ck: uint) -> bool { true } + fn visit_trait(&self) -> bool { true } + fn visit_var(&self) -> bool { true } + fn visit_var_integral(&self) -> bool { true } + fn visit_param(&self, _i: uint) -> bool { true } + fn visit_self(&self) -> bool { true } + fn visit_type(&self) -> bool { true } + fn visit_opaque_box(&self) -> bool { true } + fn visit_constr(&self, _inner: *TyDesc) -> bool { true } + fn visit_closure_ptr(&self, _ck: uint) -> bool { true } } -fn visit_ty(v: TyVisitor) { - visit_tydesc(get_tydesc::(), v); +fn visit_ty(v: @TyVisitor) { + unsafe { + visit_tydesc(get_tydesc::(), v); + } } pub fn main() { - let v = my_visitor(@mut {types: ~[]}); - let vv = v as TyVisitor; + let v = @MyVisitor {types: @mut ~[]}; + let vv = v as @TyVisitor; visit_ty::(vv); visit_ty::(vv); @@ -150,9 +162,8 @@ pub fn main() { visit_ty::(vv); visit_ty::<~[int]>(vv); - for (v.types.clone()).each {|s| - io::println(fmt!("type: %s", s)); + for v.types.each |&s| { + println(fmt!("type: %s", s)); } - assert!(v.types == ["bool", "int", "i8", "i16", - "[", "int", "]"]); + assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); } From 8bf00333455a572bc4c48f947777ed2e7b57af09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 14:45:10 +0200 Subject: [PATCH 072/336] Remove unused shape fields from typedescs --- src/librustc/back/abi.rs | 4 +--- src/librustc/middle/trans/glue.rs | 18 ++++++------------ src/librustc/middle/trans/type_.rs | 3 +-- src/libstd/unstable/intrinsics.rs | 2 -- src/rt/rust_builtin.cpp | 7 +++---- src/rt/rust_type.h | 2 -- src/rt/rust_util.cpp | 2 -- 7 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 004170dea7fe..8f15c74ed0ec 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -49,9 +49,7 @@ pub static tydesc_field_take_glue: uint = 2u; pub static tydesc_field_drop_glue: uint = 3u; pub static tydesc_field_free_glue: uint = 4u; pub static tydesc_field_visit_glue: uint = 5u; -pub static tydesc_field_shape: uint = 6u; -pub static tydesc_field_shape_tables: uint = 7u; -pub static n_tydesc_fields: uint = 8u; +pub static n_tydesc_fields: uint = 6u; // The two halves of a closure: code and environment. pub static fn_field_code: uint = 0u; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0930d3550353..f9bffb4a36ec 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -765,19 +765,13 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { } }; - - let shape = C_null(Type::i8p()); - let shape_tables = C_null(Type::i8p()); - let tydesc = C_named_struct(ccx.tydesc_type, - [ti.size, // size - ti.align, // align - take_glue, // take_glue - drop_glue, // drop_glue - free_glue, // free_glue - visit_glue, // visit_glue - shape, // shape - shape_tables]); // shape_tables + [ti.size, // size + ti.align, // align + take_glue, // take_glue + drop_glue, // drop_glue + free_glue, // free_glue + visit_glue]); // visit_glue unsafe { let gvar = ti.tydesc; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 764bdb026f47..fda8fb4a9016 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -211,8 +211,7 @@ impl Type { let elems = [ int_ty, int_ty, - glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, - pvoid, pvoid + glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty ]; tydesc.set_struct_body(elems, false); diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index a51ba05710b1..84bb2a952f2d 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -48,8 +48,6 @@ pub struct TyDesc { drop_glue: GlueFn, free_glue: GlueFn, visit_glue: GlueFn, - shape: *i8, - shape_tables: *i8 } #[lang="opaque"] diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index e476fa0ad5e0..1a84325c7a93 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -732,10 +732,9 @@ rust_task_deref(rust_task *task) { // Must call on rust stack. extern "C" CDECL void rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) { - void (*glue_fn)(void *, void *, void *) = - (void (*)(void *, void *, void *))tydesc[glue_index]; - if (glue_fn) - glue_fn(0, 0, root); + glue_fn *fn = (glue_fn*) tydesc[glue_index]; + if (fn) + fn(0, 0, root); } // Don't run on the Rust stack! diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index 6d36d2c960a2..70b5c1dc6bea 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -57,8 +57,6 @@ struct type_desc { glue_fn *drop_glue; glue_fn *free_glue; glue_fn *visit_glue; - const uint8_t *unused; - const uint8_t *unused2; }; extern "C" type_desc *rust_clone_type_desc(type_desc*); diff --git a/src/rt/rust_util.cpp b/src/rt/rust_util.cpp index 8d80a344063f..4a15830e529a 100644 --- a/src/rt/rust_util.cpp +++ b/src/rt/rust_util.cpp @@ -21,8 +21,6 @@ struct type_desc str_body_tydesc = { NULL, // drop_glue NULL, // free_glue NULL, // visit_glue - NULL, // shape - NULL, // shape_tables }; // From 273f90566c26309c13ebe10278f8745e978250b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 20 Jun 2013 15:13:20 +0200 Subject: [PATCH 073/336] Small cleanups --- src/librustc/middle/trans/type_.rs | 7 +------ src/librustc/middle/ty.rs | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index fda8fb4a9016..7b02030078c5 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -189,8 +189,7 @@ impl Type { None => () } - // Bit of a kludge: pick the fn typeref out of the tydesc.. - let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); + let ty = Type::glue_fn(cx.tydesc_type).ptr_to(); cx.tn.associate_type("glue_fn", &ty); return ty; @@ -269,10 +268,6 @@ impl Type { cx.int_type } - pub fn captured_tydescs(ctx: &CrateContext, num: uint) -> Type { - Type::struct_(vec::from_elem(num, ctx.tydesc_type.ptr_to()), false) - } - pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { let tydesc_ptr = ctx.tydesc_type.ptr_to(); match store { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f12ecebc6d5c..9e1a0def2eef 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4453,8 +4453,8 @@ pub fn get_tydesc_ty(tcx: ctxt) -> t { } pub fn get_opaque_ty(tcx: ctxt) -> t { - let tydesc_lang_item = tcx.lang_items.opaque(); - tcx.intrinsic_defs.find_copy(&tydesc_lang_item) + let opaque_lang_item = tcx.lang_items.opaque(); + tcx.intrinsic_defs.find_copy(&opaque_lang_item) .expect("Failed to resolve Opaque") } From 976c0b3dfb6a0da8a70958f157507b5dcf7c5ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Fri, 21 Jun 2013 10:00:49 +0200 Subject: [PATCH 074/336] Remove rust_call_tydesc_glue Towards #4812. Also includes some minor cleanups. --- src/libextra/arena.rs | 32 ++++++++------------------------ src/libstd/cleanup.rs | 18 +++--------------- src/libstd/gc.rs | 15 +++++---------- src/libstd/sys.rs | 23 ----------------------- src/rt/rust_builtin.cpp | 8 -------- src/rt/rustrt.def.in | 3 +-- 6 files changed, 17 insertions(+), 82 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index a7d5660cd2e4..3766af046563 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -41,37 +41,21 @@ use list::{MutList, MutCons, MutNil}; use core::at_vec; use core::cast::{transmute, transmute_mut_region}; use core::cast; -use core::libc::size_t; use core::ptr; use core::sys; use core::uint; use core::vec; use core::unstable::intrinsics; +use core::unstable::intrinsics::{TyDesc}; + +#[cfg(not(stage0))] +use core::unstable::intrinsics::{get_tydesc}; #[cfg(stage0)] -use intrinsic::{get_tydesc, TyDesc}; -#[cfg(not(stage0))] -use core::unstable::intrinsics::{get_tydesc, TyDesc}; - -pub mod rustrt { - use core::libc::size_t; - #[cfg(stage0)] - use intrinsic::{TyDesc}; - #[cfg(not(stage0))] - use core::unstable::intrinsics::{TyDesc}; - - pub extern { - #[rust_stack] - unsafe fn rust_call_tydesc_glue(root: *u8, - tydesc: *TyDesc, - field: size_t); - } +unsafe fn get_tydesc() -> *TyDesc { + intrinsics::get_tydesc::() as *TyDesc } -// This probably belongs somewhere else. Needs to be kept in sync with -// changes to glue... -static tydesc_drop_glue_index: size_t = 3 as size_t; - // The way arena uses arrays is really deeply awful. The arrays are // allocated, and have capacities reserved, but the fill for the array // will always stay at 0. @@ -150,8 +134,8 @@ unsafe fn destroy_chunk(chunk: &Chunk) { //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b", // start, size, align, is_done); if is_done { - rustrt::rust_call_tydesc_glue( - ptr::offset(buf, start), tydesc, tydesc_drop_glue_index); + ((*tydesc).drop_glue)(&tydesc as **TyDesc, + ptr::offset(buf, start) as *i8); } // Find where the next tydesc lives diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 28aab9adad2c..557a2fbc4aef 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -158,20 +158,6 @@ fn debug_mem() -> bool { false } -#[cfg(stage0)] -unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { - use sys::TypeDesc; - - let tydesc: *TypeDesc = transmute(tydesc); - let drop_glue: extern "Rust" fn(**TypeDesc, *i8) = transmute((*tydesc).drop_glue); - drop_glue(to_unsafe_ptr(&tydesc), data); -} - -#[cfg(not(stage0))] -unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) { - ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); -} - /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -213,7 +199,9 @@ pub unsafe fn annihilate() { // callback, as the original value may have been freed. for each_live_alloc(false) |box, uniq| { if !uniq { - call_drop_glue((*box).header.type_desc, transmute(&(*box).data)); + let tydesc = (*box).header.type_desc; + let data = transmute(&(*box).data); + ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); } } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 611b95a7745e..2a211484e736 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -40,12 +40,13 @@ with destructors. use cast; use container::{Map, Set}; use io; -use libc::{size_t, uintptr_t}; +use libc::{uintptr_t}; use option::{None, Option, Some}; use ptr; use hashmap::HashSet; use stackwalk::walk_stack; use sys; +use unstable::intrinsics::{TyDesc}; pub use stackwalk::Word; @@ -58,17 +59,11 @@ pub struct StackSegment { } pub mod rustrt { - use libc::size_t; use stackwalk::Word; use super::StackSegment; #[link_name = "rustrt"] pub extern { - #[rust_stack] - pub unsafe fn rust_call_tydesc_glue(root: *Word, - tydesc: *Word, - field: size_t); - #[rust_stack] pub unsafe fn rust_gc_metadata() -> *Word; @@ -125,7 +120,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option { return None; } -type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool; +type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool; // Walks the list of roots for the given safe point, and calls visitor // on each root. @@ -139,7 +134,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool { let stack_roots: *u32 = bump(sp_meta, 2); let reg_roots: *u8 = bump(stack_roots, num_stack_roots); let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_roots)); - let tydescs: ***Word = bump(addrspaces, num_stack_roots); + let tydescs: ***TyDesc = bump(addrspaces, num_stack_roots); // Stack roots let mut sri = 0; @@ -364,7 +359,7 @@ pub fn cleanup_stack_for_failure() { // FIXME #4420: Destroy this box // FIXME #4330: Destroy this box } else { - rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t); + ((*tydesc).drop_glue)(&tydesc as **TyDesc, *root as *i8); } } } diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs index 7f80375c2f6a..a1d6342323c6 100644 --- a/src/libstd/sys.rs +++ b/src/libstd/sys.rs @@ -22,17 +22,6 @@ use repr; use str; use unstable::intrinsics; -// Corresponds to runtime type_desc type -#[cfg(stage0)] -pub struct TypeDesc { - size: uint, - align: uint, - take_glue: uint, - drop_glue: uint, - free_glue: uint - // Remaining fields not listed -} - /// The representation of a Rust closure pub struct Closure { code: *(), @@ -50,18 +39,6 @@ pub mod rustrt { } } -/** - * Returns a pointer to a type descriptor. - * - * Useful for calling certain function in the Rust runtime or otherwise - * performing dark magick. - */ -#[inline] -#[cfg(stage0)] -pub fn get_type_desc() -> *TypeDesc { - unsafe { intrinsics::get_tydesc::() as *TypeDesc } -} - /// Returns the size of a type #[inline] pub fn size_of() -> uint { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1a84325c7a93..8d771da32fc2 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -729,14 +729,6 @@ rust_task_deref(rust_task *task) { task->deref(); } -// Must call on rust stack. -extern "C" CDECL void -rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) { - glue_fn *fn = (glue_fn*) tydesc[glue_index]; - if (fn) - fn(0, 0, root); -} - // Don't run on the Rust stack! extern "C" void rust_log_str(uint32_t level, const char *str, size_t size) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ba7ada04a275..7fd948d2cd94 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -174,7 +174,6 @@ rust_set_task_local_data rust_task_local_data_atexit rust_task_ref rust_task_deref -rust_call_tydesc_glue tdefl_compress_mem_to_heap tinfl_decompress_mem_to_heap rust_gc_metadata @@ -239,4 +238,4 @@ rust_valgrind_stack_deregister rust_take_env_lock rust_drop_env_lock rust_update_log_settings -rust_running_on_valgrind \ No newline at end of file +rust_running_on_valgrind From 1b76bac41de9f52295a99db21abdd1ad5b0fc231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Fri, 21 Jun 2013 13:01:15 +0200 Subject: [PATCH 075/336] syntax: Remove unused tokens TyDesc, TyVisitor and intrinsic are not used anymore. --- src/libsyntax/parse/token.rs | 200 +++++++++++++++++------------------ 1 file changed, 97 insertions(+), 103 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 273a59f0a3de..d40b96f077bb 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -331,21 +331,18 @@ pub mod special_idents { pub static str : ident = ident { name: 19, ctxt: 0}; // for the type /* outside of libsyntax */ - pub static ty_visitor : ident = ident { name: 20, ctxt: 0}; - pub static arg : ident = ident { name: 21, ctxt: 0}; - pub static descrim : ident = ident { name: 22, ctxt: 0}; - pub static clownshoe_abi : ident = ident { name: 23, ctxt: 0}; - pub static clownshoe_stack_shim : ident = ident { name: 24, ctxt: 0}; - pub static tydesc : ident = ident { name: 25, ctxt: 0}; - pub static main : ident = ident { name: 26, ctxt: 0}; - pub static opaque : ident = ident { name: 27, ctxt: 0}; - pub static blk : ident = ident { name: 28, ctxt: 0}; - pub static statik : ident = ident { name: 29, ctxt: 0}; - pub static intrinsic : ident = ident { name: 30, ctxt: 0}; - pub static clownshoes_foreign_mod: ident = ident { name: 31, ctxt: 0}; - pub static unnamed_field: ident = ident { name: 32, ctxt: 0}; - pub static c_abi: ident = ident { name: 33, ctxt: 0}; - pub static type_self: ident = ident { name: 34, ctxt: 0}; // `Self` + pub static arg : ident = ident { name: 20, ctxt: 0}; + pub static descrim : ident = ident { name: 21, ctxt: 0}; + pub static clownshoe_abi : ident = ident { name: 22, ctxt: 0}; + pub static clownshoe_stack_shim : ident = ident { name: 23, ctxt: 0}; + pub static main : ident = ident { name: 24, ctxt: 0}; + pub static opaque : ident = ident { name: 25, ctxt: 0}; + pub static blk : ident = ident { name: 26, ctxt: 0}; + pub static statik : ident = ident { name: 27, ctxt: 0}; + pub static clownshoes_foreign_mod: ident = ident { name: 28, ctxt: 0}; + pub static unnamed_field: ident = ident { name: 29, ctxt: 0}; + pub static c_abi: ident = ident { name: 30, ctxt: 0}; + pub static type_self: ident = ident { name: 31, ctxt: 0}; // `Self` } /** @@ -426,59 +423,56 @@ fn mk_fresh_ident_interner() -> @ident_interner { "tt", // 17 "matchers", // 18 "str", // 19 - "TyVisitor", // 20 - "arg", // 21 - "descrim", // 22 - "__rust_abi", // 23 - "__rust_stack_shim", // 24 - "TyDesc", // 25 - "main", // 26 - "", // 27 - "blk", // 28 - "static", // 29 - "intrinsic", // 30 - "__foreign_mod__", // 31 - "__field__", // 32 - "C", // 33 - "Self", // 34 + "arg", // 20 + "descrim", // 21 + "__rust_abi", // 22 + "__rust_stack_shim", // 23 + "main", // 24 + "", // 25 + "blk", // 26 + "static", // 27 + "__foreign_mod__", // 28 + "__field__", // 29 + "C", // 30 + "Self", // 31 - "as", // 35 - "break", // 36 - "const", // 37 - "copy", // 38 - "do", // 39 - "else", // 40 - "enum", // 41 - "extern", // 42 - "false", // 43 - "fn", // 44 - "for", // 45 - "if", // 46 - "impl", // 47 - "let", // 48 - "__log", // 49 - "loop", // 50 - "match", // 51 - "mod", // 52 - "mut", // 53 - "once", // 54 - "priv", // 55 - "pub", // 56 - "pure", // 57 - "ref", // 58 - "return", // 59 - "static", // 29 -- also a special ident + "as", // 32 + "break", // 33 + "const", // 34 + "copy", // 35 + "do", // 36 + "else", // 37 + "enum", // 38 + "extern", // 39 + "false", // 40 + "fn", // 41 + "for", // 42 + "if", // 43 + "impl", // 44 + "let", // 45 + "__log", // 46 + "loop", // 47 + "match", // 48 + "mod", // 49 + "mut", // 50 + "once", // 51 + "priv", // 52 + "pub", // 53 + "pure", // 54 + "ref", // 55 + "return", // 56 + "static", // 27 -- also a special ident "self", // 8 -- also a special ident - "struct", // 60 - "super", // 61 - "true", // 62 - "trait", // 63 - "type", // 64 - "unsafe", // 65 - "use", // 66 - "while", // 67 + "struct", // 57 + "super", // 58 + "true", // 59 + "trait", // 60 + "type", // 61 + "unsafe", // 62 + "use", // 63 + "while", // 64 - "be", // 68 + "be", // 65 ]; @ident_interner { @@ -612,42 +606,42 @@ pub mod keywords { impl Keyword { pub fn to_ident(&self) -> ident { match *self { - As => ident { name: 35, ctxt: 0 }, - Break => ident { name: 36, ctxt: 0 }, - Const => ident { name: 37, ctxt: 0 }, - Copy => ident { name: 38, ctxt: 0 }, - Do => ident { name: 39, ctxt: 0 }, - Else => ident { name: 40, ctxt: 0 }, - Enum => ident { name: 41, ctxt: 0 }, - Extern => ident { name: 42, ctxt: 0 }, - False => ident { name: 43, ctxt: 0 }, - Fn => ident { name: 44, ctxt: 0 }, - For => ident { name: 45, ctxt: 0 }, - If => ident { name: 46, ctxt: 0 }, - Impl => ident { name: 47, ctxt: 0 }, - Let => ident { name: 48, ctxt: 0 }, - __Log => ident { name: 49, ctxt: 0 }, - Loop => ident { name: 50, ctxt: 0 }, - Match => ident { name: 51, ctxt: 0 }, - Mod => ident { name: 52, ctxt: 0 }, - Mut => ident { name: 53, ctxt: 0 }, - Once => ident { name: 54, ctxt: 0 }, - Priv => ident { name: 55, ctxt: 0 }, - Pub => ident { name: 56, ctxt: 0 }, - Pure => ident { name: 57, ctxt: 0 }, - Ref => ident { name: 58, ctxt: 0 }, - Return => ident { name: 59, ctxt: 0 }, - Static => ident { name: 29, ctxt: 0 }, + As => ident { name: 32, ctxt: 0 }, + Break => ident { name: 33, ctxt: 0 }, + Const => ident { name: 34, ctxt: 0 }, + Copy => ident { name: 35, ctxt: 0 }, + Do => ident { name: 36, ctxt: 0 }, + Else => ident { name: 37, ctxt: 0 }, + Enum => ident { name: 38, ctxt: 0 }, + Extern => ident { name: 39, ctxt: 0 }, + False => ident { name: 40, ctxt: 0 }, + Fn => ident { name: 41, ctxt: 0 }, + For => ident { name: 42, ctxt: 0 }, + If => ident { name: 43, ctxt: 0 }, + Impl => ident { name: 44, ctxt: 0 }, + Let => ident { name: 45, ctxt: 0 }, + __Log => ident { name: 46, ctxt: 0 }, + Loop => ident { name: 47, ctxt: 0 }, + Match => ident { name: 48, ctxt: 0 }, + Mod => ident { name: 49, ctxt: 0 }, + Mut => ident { name: 50, ctxt: 0 }, + Once => ident { name: 51, ctxt: 0 }, + Priv => ident { name: 52, ctxt: 0 }, + Pub => ident { name: 53, ctxt: 0 }, + Pure => ident { name: 54, ctxt: 0 }, + Ref => ident { name: 55, ctxt: 0 }, + Return => ident { name: 56, ctxt: 0 }, + Static => ident { name: 27, ctxt: 0 }, Self => ident { name: 8, ctxt: 0 }, - Struct => ident { name: 60, ctxt: 0 }, - Super => ident { name: 61, ctxt: 0 }, - True => ident { name: 62, ctxt: 0 }, - Trait => ident { name: 63, ctxt: 0 }, - Type => ident { name: 64, ctxt: 0 }, - Unsafe => ident { name: 65, ctxt: 0 }, - Use => ident { name: 66, ctxt: 0 }, - While => ident { name: 67, ctxt: 0 }, - Be => ident { name: 68, ctxt: 0 }, + Struct => ident { name: 57, ctxt: 0 }, + Super => ident { name: 58, ctxt: 0 }, + True => ident { name: 59, ctxt: 0 }, + Trait => ident { name: 60, ctxt: 0 }, + Type => ident { name: 61, ctxt: 0 }, + Unsafe => ident { name: 62, ctxt: 0 }, + Use => ident { name: 63, ctxt: 0 }, + While => ident { name: 64, ctxt: 0 }, + Be => ident { name: 65, ctxt: 0 }, } } } @@ -663,7 +657,7 @@ pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool { pub fn is_any_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 68 => true, + 8 | 27 | 32 .. 65 => true, _ => false, }, _ => false @@ -673,7 +667,7 @@ pub fn is_any_keyword(tok: &Token) -> bool { pub fn is_strict_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { - 8 | 29 | 35 .. 67 => true, + 8 | 27 | 32 .. 64 => true, _ => false, }, _ => false, @@ -683,7 +677,7 @@ pub fn is_strict_keyword(tok: &Token) -> bool { pub fn is_reserved_keyword(tok: &Token) -> bool { match *tok { token::IDENT(sid, false) => match sid.name { - 68 => true, + 65 => true, _ => false, }, _ => false, From e2f1049bd5f041f1f219d683e4e29e32ca30cd1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sat, 22 Jun 2013 21:36:00 +0200 Subject: [PATCH 076/336] Remove unused TyDesc parameter from the glue functions To remove the environment pointer, support for function pointers without an environment argument is needed (i.e. a fixed version of #6661). --- src/libextra/arena.rs | 16 ++++++++++++++-- src/librustc/back/abi.rs | 13 ------------- src/librustc/middle/trans/glue.rs | 14 ++++---------- src/librustc/middle/trans/type_.rs | 11 ++++------- src/libstd/cleanup.rs | 18 ++++++++++++++++-- src/libstd/gc.rs | 15 ++++++++++++++- src/libstd/unstable/intrinsics.rs | 4 ++++ src/rt/rust_task.cpp | 6 +++++- src/rt/rust_type.h | 6 +++++- 9 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 3766af046563..cec3a2c1e952 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -115,6 +115,19 @@ fn round_up_to(base: uint, align: uint) -> uint { (base + (align - 1)) & !(align - 1) } +#[inline] +#[cfg(not(stage0))] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + // This function should be inlined when stage0 is gone + ((*tydesc).drop_glue)(data); +} + +#[inline] +#[cfg(stage0)] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + ((*tydesc).drop_glue)(0 as **TyDesc, data); +} + // Walk down a chunk, running the destructors for any objects stored // in it. unsafe fn destroy_chunk(chunk: &Chunk) { @@ -134,8 +147,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b", // start, size, align, is_done); if is_done { - ((*tydesc).drop_glue)(&tydesc as **TyDesc, - ptr::offset(buf, start) as *i8); + call_drop_glue(tydesc, ptr::offset(buf, start) as *i8); } // Find where the next tydesc lives diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 8f15c74ed0ec..05b6e90c682f 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - - pub static rc_base_field_refcnt: uint = 0u; pub static task_field_refcnt: uint = 0u; @@ -69,14 +66,4 @@ pub static vec_elt_elems: uint = 2u; pub static slice_elt_base: uint = 0u; pub static slice_elt_len: uint = 1u; -pub static worst_case_glue_call_args: uint = 7u; - pub static abi_version: uint = 1u; - -pub fn memcpy_glue_name() -> ~str { return ~"rust_memcpy_glue"; } - -pub fn bzero_glue_name() -> ~str { return ~"rust_bzero_glue"; } - -pub fn yield_glue_name() -> ~str { return ~"rust_yield_glue"; } - -pub fn no_op_type_glue_name() -> ~str { return ~"rust_no_op_type_glue"; } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index f9bffb4a36ec..75a1221cca52 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -232,7 +232,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) { let _icx = push_ctxt("lazily_emit_tydesc_glue"); - let llfnty = type_of_glue_fn(ccx); + let llfnty = Type::glue_fn(); if lazily_emit_simplified_tydesc_glue(ccx, field, ti) { return; @@ -338,9 +338,7 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - Call(bcx, llfn, [C_null(Type::nil().ptr_to()), - C_null(bcx.ccx().tydesc_type.ptr_to().ptr_to()), - llrawptr]); + Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr]); } // See [Note-arg-mode] @@ -680,7 +678,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, let bcx = top_scope_block(fcx, None); let lltop = bcx.llbb; - let rawptr0_arg = fcx.arg_pos(1u); + let rawptr0_arg = fcx.arg_pos(0u); let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; let llty = type_of(ccx, t); let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to()); @@ -715,7 +713,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { let _icx = push_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - let glue_fn_ty = Type::generic_glue_fn(ccx); + let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to(); let tyds = &mut ccx.tydescs; for tyds.each_value |&val| { let ti = val; @@ -782,7 +780,3 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { } }; } - -pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { - Type::glue_fn(ccx.tydesc_type) -} diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 7b02030078c5..64688ac41342 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -20,7 +20,6 @@ use middle::trans::base; use syntax::ast; use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; -use back::abi; use core::vec; use core::cast; @@ -189,22 +188,20 @@ impl Type { None => () } - let ty = Type::glue_fn(cx.tydesc_type).ptr_to(); + let ty = Type::glue_fn(); cx.tn.associate_type("glue_fn", &ty); return ty; } - pub fn glue_fn(tydesc: Type) -> Type { - let tydescpp = tydesc.ptr_to().ptr_to(); - Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], + pub fn glue_fn() -> Type { + Type::func([ Type::nil().ptr_to(), Type::i8p() ], &Type::void()) } pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); - let pvoid = Type::i8p(); - let glue_fn_ty = Type::glue_fn(tydesc).ptr_to(); + let glue_fn_ty = Type::glue_fn().ptr_to(); let int_ty = Type::int(arch); diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 557a2fbc4aef..ee9fdd3c6200 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -11,9 +11,10 @@ #[doc(hidden)]; use libc::{c_char, intptr_t, uintptr_t}; -use ptr::{mut_null, to_unsafe_ptr}; +use ptr::{mut_null}; use repr::BoxRepr; use cast::transmute; +use unstable::intrinsics::TyDesc; #[cfg(not(test))] use unstable::lang::clear_task_borrow_list; /** @@ -158,6 +159,19 @@ fn debug_mem() -> bool { false } +#[inline] +#[cfg(not(stage0))] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + // This function should be inlined when stage0 is gone + ((*tydesc).drop_glue)(data); +} + +#[inline] +#[cfg(stage0)] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + ((*tydesc).drop_glue)(0 as **TyDesc, data); +} + /// Destroys all managed memory (i.e. @ boxes) held by the current task. #[cfg(not(test))] #[lang="annihilate"] @@ -201,7 +215,7 @@ pub unsafe fn annihilate() { if !uniq { let tydesc = (*box).header.type_desc; let data = transmute(&(*box).data); - ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data); + call_drop_glue(tydesc, data); } } diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs index 2a211484e736..c9e33219fa50 100644 --- a/src/libstd/gc.rs +++ b/src/libstd/gc.rs @@ -316,6 +316,19 @@ fn expect_sentinel() -> bool { true } #[cfg(nogc)] fn expect_sentinel() -> bool { false } +#[inline] +#[cfg(not(stage0))] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + // This function should be inlined when stage0 is gone + ((*tydesc).drop_glue)(data); +} + +#[inline] +#[cfg(stage0)] +unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) { + ((*tydesc).drop_glue)(0 as **TyDesc, data); +} + // Entry point for GC-based cleanup. Walks stack looking for exchange // heap and stack allocations requiring drop, and runs all // destructors. @@ -359,7 +372,7 @@ pub fn cleanup_stack_for_failure() { // FIXME #4420: Destroy this box // FIXME #4330: Destroy this box } else { - ((*tydesc).drop_glue)(&tydesc as **TyDesc, *root as *i8); + call_drop_glue(tydesc, *root as *i8); } } } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 84bb2a952f2d..bd34574c3b7a 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -36,6 +36,10 @@ A quick refresher on memory ordering: #[cfg(test)] pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor}; +#[cfg(not(stage0))] +pub type GlueFn = extern "Rust" fn(*i8); + +#[cfg(stage0)] pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); // NB: this has to be kept in sync with the Rust ABI. diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index fe1b4622137e..81ae991623f8 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -183,7 +183,11 @@ void task_start_wrapper(spawn_args *a) if(env) { // free the environment (which should be a unique closure). const type_desc *td = env->td; - td->drop_glue(NULL, NULL, box_body(env)); + td->drop_glue(NULL, +#ifdef _RUST_STAGE0 + NULL, +#endif + box_body(env)); task->kernel->region()->free(env); } diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h index 70b5c1dc6bea..30ff5f1fa54e 100644 --- a/src/rt/rust_type.h +++ b/src/rt/rust_type.h @@ -25,7 +25,11 @@ typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *); struct type_desc; -typedef void CDECL (glue_fn)(void *, const type_desc **, void *); +typedef void CDECL (glue_fn)(void *, +#ifdef _RUST_STAGE0 + const type_desc **, +#endif + void *); // Corresponds to the boxed data in the @ region. The body follows the // header; you can obtain a ptr via box_body() below. From ce888a505524937ca9aa91370e204bb28fe6ef7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Sun, 23 Jun 2013 17:15:37 +0200 Subject: [PATCH 077/336] Fix reflect-visit-type for iterator changes --- src/test/run-pass/reflect-visit-type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 3b51abbd489b..bb1c92dfa8a7 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -162,7 +162,7 @@ pub fn main() { visit_ty::(vv); visit_ty::<~[int]>(vv); - for v.types.each |&s| { + for v.types.iter().advance |&s| { println(fmt!("type: %s", s)); } assert_eq!((*v.types).clone(), ~[~"bool", ~"int", ~"i8", ~"i16", ~"[", ~"int", ~"]"]); From fcf361745fa2dd2931595265a9f2e8837c2b0fb8 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 14 Jun 2013 15:57:58 -0400 Subject: [PATCH 078/336] Add rules for assert, fail, and deriving to vim syntax file. Also highlight the mod path in "use module;" properly. --- src/etc/vim/syntax/rust.vim | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 5c08fdfecca5..625424ac8709 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -2,7 +2,7 @@ " Language: Rust " Maintainer: Patrick Walton " Maintainer: Ben Blum -" Last Change: 2012 Dec 25 +" Last Change: 2012 Jun 14 if version < 600 syntax clear @@ -13,13 +13,16 @@ endif syn keyword rustConditional match if else syn keyword rustOperator as +syn match rustAssert "\(); -syn match rustMacro '\w\(\w\)*!' -syn match rustMacro '#\w\(\w\)*' +syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustFail +syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustFail syn match rustFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn?]\|\[\^\=.[^]]*\]\)" contained syn match rustFormat display "%%" contained syn region rustString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=rustTodo,rustFormat -syn region rustAttribute start="#\[" end="\]" contains=rustString +syn region rustAttribute start="#\[" end="\]" contains=rustString,rustDeriving +syn region rustDeriving start="deriving(" end=")" contains=rustTrait " Number literals syn match rustNumber display "\<[0-9][0-9_]*\>" @@ -143,11 +149,17 @@ hi def link rustMacro Macro hi def link rustType Type hi def link rustTodo Todo hi def link rustAttribute PreProc +hi def link rustDeriving PreProc hi def link rustStorage StorageClass hi def link rustLifetime Special " Other Suggestions: +" hi rustAttribute ctermfg=cyan +" hi rustDeriving ctermfg=cyan +" hi rustAssert ctermfg=yellow +" hi rustFail ctermfg=red " hi rustMacro ctermfg=magenta +" hi rustModPathSep ctermfg=grey syn sync minlines=200 syn sync maxlines=500 From 394f455b5edfe96b51bc713ccc65ad3db6bed92f Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Sun, 23 Jun 2013 02:44:51 -0400 Subject: [PATCH 079/336] Fix error messages in test cases, since fns/traits now pretty-print with a bounds list --- src/test/compile-fail/class-cast-to-trait.rs | 2 +- src/test/compile-fail/extern-wrong-value-type.rs | 2 +- src/test/compile-fail/issue-4523.rs | 2 +- src/test/compile-fail/issue-4972.rs | 4 ++-- src/test/compile-fail/map-types.rs | 2 +- src/test/compile-fail/missing-do.rs | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/compile-fail/class-cast-to-trait.rs b/src/test/compile-fail/class-cast-to-trait.rs index 7f7c58a60df0..0d1582bf8571 100644 --- a/src/test/compile-fail/class-cast-to-trait.rs +++ b/src/test/compile-fail/class-cast-to-trait.rs @@ -58,5 +58,5 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { fn main() { let nyan : @noisy = @cat(0, 2, ~"nyan") as @noisy; - nyan.eat(); //~ ERROR type `@noisy` does not implement any method in scope named `eat` + nyan.eat(); //~ ERROR does not implement any method in scope named `eat` } diff --git a/src/test/compile-fail/extern-wrong-value-type.rs b/src/test/compile-fail/extern-wrong-value-type.rs index 4daa7f71adf2..fbb0f6e46a1c 100644 --- a/src/test/compile-fail/extern-wrong-value-type.rs +++ b/src/test/compile-fail/extern-wrong-value-type.rs @@ -13,5 +13,5 @@ extern fn f() { fn main() { // extern functions are *u8 types - let _x: &fn() = f; //~ ERROR mismatched types: expected `&fn()` but found `*u8` + let _x: &fn() = f; //~ ERROR found `*u8` } diff --git a/src/test/compile-fail/issue-4523.rs b/src/test/compile-fail/issue-4523.rs index 6d072ce210e2..332db60c836f 100644 --- a/src/test/compile-fail/issue-4523.rs +++ b/src/test/compile-fail/issue-4523.rs @@ -10,7 +10,7 @@ fn foopy() {} -static f: &'static fn() = foopy; //~ ERROR mismatched types: expected `&'static fn()` +static f: &'static fn() = foopy; //~ ERROR found extern fn fn main () { f(); diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs index bd74199dabd8..fcd15a212193 100644 --- a/src/test/compile-fail/issue-4972.rs +++ b/src/test/compile-fail/issue-4972.rs @@ -16,8 +16,8 @@ pub enum TraitWrapper { fn get_tw_map<'lt>(tw: &'lt TraitWrapper) -> &'lt MyTrait { match *tw { - A(~ref map) => map, //~ ERROR mismatched types: expected `~MyTrait` but found a ~-box pattern + A(~ref map) => map, //~ ERROR found a ~-box pattern } } -pub fn main() {} \ No newline at end of file +pub fn main() {} diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index f5d6e95fe2f4..f6fd8e29a4f4 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -17,5 +17,5 @@ fn main() { let x: @Map<~str, ~str> = @HashMap::new::<~str, ~str>() as @Map<~str, ~str>; let y: @Map = @x; - //~^ ERROR mismatched types: expected `@std::container::Map` + //~^ ERROR expected trait std::container::Map but found @-ptr } diff --git a/src/test/compile-fail/missing-do.rs b/src/test/compile-fail/missing-do.rs index b5789d737716..e6a7698d0f07 100644 --- a/src/test/compile-fail/missing-do.rs +++ b/src/test/compile-fail/missing-do.rs @@ -13,7 +13,7 @@ fn foo(f: &fn()) { f() } fn main() { - ~"" || 42; //~ ERROR binary operation || cannot be applied to type `~str` - foo || {}; //~ ERROR binary operation || cannot be applied to type `extern "Rust" fn(&fn())` + ~"" || 42; //~ ERROR binary operation || cannot be applied to type + foo || {}; //~ ERROR binary operation || cannot be applied to type //~^ NOTE did you forget the `do` keyword for the call? } From 8cadca4e41f2aad72391b834f295ae01f9c29551 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 24 Jun 2013 00:03:29 +0530 Subject: [PATCH 080/336] abi: remove dead code Signed-off-by: Ramkumar Ramachandra --- src/librustc/back/abi.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 004170dea7fe..65db2d4701c0 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -74,11 +74,3 @@ pub static slice_elt_len: uint = 1u; pub static worst_case_glue_call_args: uint = 7u; pub static abi_version: uint = 1u; - -pub fn memcpy_glue_name() -> ~str { return ~"rust_memcpy_glue"; } - -pub fn bzero_glue_name() -> ~str { return ~"rust_bzero_glue"; } - -pub fn yield_glue_name() -> ~str { return ~"rust_yield_glue"; } - -pub fn no_op_type_glue_name() -> ~str { return ~"rust_no_op_type_glue"; } From ce857e3d60da1b5eff5d830dbd03f32a8890ad16 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 17 Jun 2013 15:16:30 -0400 Subject: [PATCH 081/336] Parse and typecheck (not kindcheck) bounds on trait paths. --- src/librustc/metadata/encoder.rs | 3 +- src/librustc/metadata/tydecode.rs | 3 +- src/librustc/metadata/tyencode.rs | 5 +- src/librustc/middle/kind.rs | 8 ++- src/librustc/middle/lint.rs | 2 +- src/librustc/middle/region.rs | 4 +- src/librustc/middle/resolve.rs | 8 ++- src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/glue.rs | 8 +-- src/librustc/middle/trans/monomorphize.rs | 2 +- src/librustc/middle/trans/reachable.rs | 2 +- src/librustc/middle/trans/reflect.rs | 2 +- src/librustc/middle/trans/type_of.rs | 4 +- src/librustc/middle/trans/type_use.rs | 2 +- src/librustc/middle/ty.rs | 48 ++++++++------- src/librustc/middle/typeck/astconv.rs | 20 ++++++- src/librustc/middle/typeck/check/method.rs | 2 +- src/librustc/middle/typeck/check/regionck.rs | 2 +- src/librustc/middle/typeck/check/vtable.rs | 9 ++- src/librustc/middle/typeck/coherence.rs | 6 +- src/librustc/middle/typeck/infer/combine.rs | 8 ++- src/librustc/middle/typeck/infer/mod.rs | 5 +- src/librustc/util/ppaux.rs | 8 ++- src/libsyntax/ast.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/build.rs | 16 +++-- src/libsyntax/ext/deriving/generic.rs | 3 +- src/libsyntax/ext/deriving/ty.rs | 5 +- src/libsyntax/ext/pipes/pipec.rs | 19 +++--- src/libsyntax/ext/pipes/proto.rs | 3 +- src/libsyntax/fold.rs | 4 +- src/libsyntax/parse/mod.rs | 4 +- src/libsyntax/parse/obsolete.rs | 5 -- src/libsyntax/parse/parser.rs | 63 ++++++++++++-------- src/libsyntax/print/pprust.rs | 17 +++++- src/libsyntax/visit.rs | 10 +++- 37 files changed, 197 insertions(+), 121 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 826b64b9a64b..94cad18ece2c 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -954,7 +954,8 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); match ty.node { - ast::ty_path(path, _) if path.idents.len() == 1 => { + ast::ty_path(path, bounds, _) if path.idents.len() == 1 => { + assert!(bounds.is_empty()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index cf2a92b291f2..b53bdcc9bbe0 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -311,8 +311,9 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { let substs = parse_substs(st, conv); let store = parse_trait_store(st); let mt = parse_mutability(st); + let bounds = parse_bounds(st, conv); assert_eq!(next(st), ']'); - return ty::mk_trait(st.tcx, def, substs, store, mt); + return ty::mk_trait(st.tcx, def, substs, store, mt, bounds.builtin_bounds); } 'p' => { let did = parse_def(st, TypeParameter, conv); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5f854b1f24e0..dd62a8e11cb7 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -261,13 +261,16 @@ fn enc_sty(w: @io::Writer, cx: @ctxt, st: ty::sty) { enc_substs(w, cx, substs); w.write_char(']'); } - ty::ty_trait(def, ref substs, store, mt) => { + ty::ty_trait(def, ref substs, store, mt, bounds) => { w.write_str(&"x["); w.write_str((cx.ds)(def)); w.write_char('|'); enc_substs(w, cx, substs); enc_trait_store(w, cx, store); enc_mutability(w, mt); + let bounds = ty::ParamBounds {builtin_bounds: bounds, + trait_bounds: ~[]}; + enc_bounds(w, cx, &bounds); w.write_char(']'); } ty::ty_tup(ts) => { diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 6492850b6685..1768852bb303 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -129,7 +129,8 @@ 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(_, path_node_id) => { + ty_path(_, bounds, path_node_id) => { + assert!(bounds.is_empty()); let struct_def = cx.tcx.def_map.get_copy( &path_node_id); let struct_did = @@ -307,7 +308,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { match aty.node { - ty_path(_, id) => { + ty_path(_, _, id) => { let r = cx.tcx.node_type_substs.find(&id); for r.iter().advance |ts| { let did = ast_util::def_id_of_def(cx.tcx.def_map.get_copy(&id)); @@ -533,7 +534,8 @@ pub fn check_cast_for_escaping_regions( pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) { let target_ty = ty::expr_ty(cx.tcx, target); match ty::get(target_ty).sty { - ty::ty_trait(_, _, ty::UniqTraitStore, _) => { + // FIXME(#3569) kind check bounds here + ty::ty_trait(_, _, ty::UniqTraitStore, _, _bounds) => { let source_ty = ty::expr_ty(cx.tcx, source); if !ty::type_is_owned(cx.tcx, source_ty) { cx.tcx.sess.span_err( diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index d29c027f3c28..821aed731c22 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -714,7 +714,7 @@ fn check_item_ctypes(cx: &Context, it: @ast::item) { let tys = vec::map(decl.inputs, |a| a.ty ); for vec::each(vec::append_one(tys, decl.output)) |ty| { match ty.node { - ast::ty_path(_, id) => { + ast::ty_path(_, _, id) => { match cx.tcx.def_map.get_copy(&id) { ast::def_prim_ty(ast::ty_int(ast::ty_i)) => { cx.span_lint(ctypes, ty.span, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 4b6cedd114c3..0e6d8617ba42 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -804,7 +804,7 @@ pub 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, id) => { + ast::ty_path(path, _bounds, id) => { match cx.def_map.find(&id) { Some(&ast::def_ty(did)) | Some(&ast::def_trait(did)) | @@ -840,7 +840,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, visit_mt(mt, (cx, visitor)); } - ast::ty_path(path, _) => { + ast::ty_path(path, _bounds, _) => { // type parameters are---for now, anyway---always invariant do cx.with_ambient_variance(rv_invariant) { for path.types.iter().advance |tp| { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index fbea5d4adf2a..eed0b12b9e12 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1250,7 +1250,7 @@ impl Resolver { // If there are static methods, then create the module // and add them. match (trait_ref_opt, ty) { - (None, @Ty { node: ty_path(path, _), _ }) if + (None, @Ty { node: ty_path(path, _, _), _ }) if has_static_methods && path.idents.len() == 1 => { let name = path_to_ident(path); @@ -4120,7 +4120,7 @@ impl Resolver { // Like path expressions, the interpretation of path types depends // on whether the path has multiple elements in it or not. - ty_path(path, path_id) => { + ty_path(path, bounds, path_id) => { // This is a path in the type namespace. Walk through scopes // scopes looking for it. let mut result_def = None; @@ -4179,6 +4179,10 @@ impl Resolver { self.idents_to_str(path.idents))); } } + + for bounds.each |bound| { + self.resolve_type_parameter_bound(bound, visitor); + } } ty_closure(c) => { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 2eadad7d8d1b..11eecf82baca 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -561,7 +561,7 @@ fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { cx.sess.span_note(span, "debuginfo for closure NYI"); create_unimpl_ty(cx, t) }, - ty::ty_trait(_did, ref _substs, ref _vstore, _) => { + ty::ty_trait(_did, ref _substs, ref _vstore, _, _bounds) => { cx.sess.span_note(span, "debuginfo for trait NYI"); create_unimpl_ty(cx, t) }, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 58f04ab3b2ec..7d86f743a8e4 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -683,7 +683,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, } ast::expr_cast(val, _) => { match ty::get(node_id_type(bcx, expr.id)).sty { - ty::ty_trait(_, _, store, _) => { + ty::ty_trait(_, _, store, _, _) => { return meth::trans_trait_cast(bcx, val, expr.id, dest, store); } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index e9febb51005c..d8ba524b2bd1 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -486,13 +486,13 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { ty::ty_closure(_) => { closure::make_closure_glue(bcx, v0, t, drop_ty) } - ty::ty_trait(_, _, ty::BoxTraitStore, _) => { + ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]); let llbox = Load(bcx, llbox_ptr); decr_refcnt_maybe_free(bcx, llbox, Some(llbox_ptr), ty::mk_opaque_box(ccx.tcx)) } - ty::ty_trait(_, _, ty::UniqTraitStore, _) => { + ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => { let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]); // Only drop the value when it is non-null do with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue))) |bcx| { @@ -571,12 +571,12 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_closure(_) => { closure::make_closure_glue(bcx, v, t, take_ty) } - ty::ty_trait(_, _, ty::BoxTraitStore, _) => { + ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box])); incr_refcnt_of_boxed(bcx, llbox); bcx } - ty::ty_trait(_, _, ty::UniqTraitStore, _) => { + ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => { let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]); let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable])); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index fd382a869dfa..4f4bbf84a72b 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -293,7 +293,7 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt, ty::ty_closure(ref fty) => { Some(normalized_closure_ty(tcx, fty.sigil)) } - ty::ty_trait(_, _, ref store, _) => { + ty::ty_trait(_, _, ref store, _, _) => { let sigil = match *store { ty::UniqTraitStore => ast::OwnedSigil, ty::BoxTraitStore => ast::ManagedSigil, diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs index 5cb52d2a0579..6a40c1f75e9e 100644 --- a/src/librustc/middle/trans/reachable.rs +++ b/src/librustc/middle/trans/reachable.rs @@ -160,7 +160,7 @@ fn traverse_ty<'a>(ty: @Ty, (cx, v): (@mut ctx<'a>, visit::vt<@mut ctx<'a>>)) { } match ty.node { - ty_path(p, p_id) => { + ty_path(p, _bounds, p_id) => { match cx.tcx.def_map.find(&p_id) { // Kind of a hack to check this here, but I'm not sure what else // to do diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index cb68a2af92bb..316eb6893f25 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -335,7 +335,7 @@ impl Reflector { } // Miscallaneous extra types - ty::ty_trait(_, _, _, _) => self.leaf(~"trait"), + ty::ty_trait(_, _, _, _, _) => self.leaf(~"trait"), ty::ty_infer(_) => self.leaf(~"infer"), ty::ty_err => self.leaf(~"err"), ty::ty_param(ref p) => { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 448ded6b70f2..3699314a1d2c 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -140,7 +140,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { ty::ty_bare_fn(*) => Type::i8p(), ty::ty_closure(*) => Type::struct_([Type::i8p(), Type::i8p()], false), - ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), + ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store), ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), ty::ty_evec(mt, ty::vstore_fixed(size)) => { @@ -271,7 +271,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { let ty = type_of_fn_from_ty(cx, t); Type::func_pair(cx, &ty) } - ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), + ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store), ty::ty_type => cx.tydesc_type.ptr_to(), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 49cb3bd51ddb..f2446d1a1153 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -208,7 +208,7 @@ pub fn type_needs_inner(cx: Context, ty::ty_bare_fn(*) | ty::ty_ptr(_) | ty::ty_rptr(_, _) | - ty::ty_trait(_, _, _, _) => false, + ty::ty_trait(*) => false, ty::ty_enum(did, ref substs) => { if list::find(enums_seen, |id| *id == did).is_none() { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a367cf4c430a..b76f30a70410 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -419,7 +419,8 @@ impl to_bytes::IterBytes for ClosureTy { self.sigil.iter_bytes(lsb0, f) && self.onceness.iter_bytes(lsb0, f) && self.region.iter_bytes(lsb0, f) && - self.sig.iter_bytes(lsb0, f) + self.sig.iter_bytes(lsb0, f) && + self.bounds.iter_bytes(lsb0, f) } } @@ -600,7 +601,7 @@ pub enum sty { ty_rptr(Region, mt), ty_bare_fn(BareFnTy), ty_closure(ClosureTy), - ty_trait(def_id, substs, TraitStore, ast::mutability), + ty_trait(def_id, substs, TraitStore, ast::mutability, BuiltinBounds), ty_struct(def_id, substs), ty_tup(~[t]), @@ -1046,7 +1047,7 @@ fn mk_t(cx: ctxt, st: sty) -> t { &ty_infer(_) => flags |= needs_infer as uint, &ty_self(_) => flags |= has_self as uint, &ty_enum(_, ref substs) | &ty_struct(_, ref substs) | - &ty_trait(_, ref substs, _, _) => { + &ty_trait(_, ref substs, _, _, _) => { flags |= sflags(substs); } &ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) | @@ -1268,10 +1269,11 @@ pub fn mk_trait(cx: ctxt, did: ast::def_id, substs: substs, store: TraitStore, - mutability: ast::mutability) + mutability: ast::mutability, + bounds: BuiltinBounds) -> t { // take a copy of substs so that we own the vectors inside - mk_t(cx, ty_trait(did, substs, store, mutability)) + mk_t(cx, ty_trait(did, substs, store, mutability, bounds)) } pub fn mk_struct(cx: ctxt, struct_id: ast::def_id, substs: substs) -> t { @@ -1319,7 +1321,7 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { maybe_walk_ty(tm.ty, f); } ty_enum(_, ref substs) | ty_struct(_, ref substs) | - ty_trait(_, ref substs, _, _) => { + ty_trait(_, ref substs, _, _, _) => { for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, f); } } ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, f); } } @@ -1380,8 +1382,8 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty { ty_enum(tid, ref substs) => { ty_enum(tid, fold_substs(substs, fldop)) } - ty_trait(did, ref substs, st, mutbl) => { - ty_trait(did, fold_substs(substs, fldop), st, mutbl) + ty_trait(did, ref substs, st, mutbl, bounds) => { + ty_trait(did, fold_substs(substs, fldop), st, mutbl, bounds) } ty_tup(ref ts) => { let new_ts = ts.map(|tt| fldop(*tt)); @@ -1470,8 +1472,12 @@ pub fn fold_regions_and_ty( ty_struct(def_id, ref substs) => { ty::mk_struct(cx, def_id, fold_substs(substs, fldr, fldt)) } - ty_trait(def_id, ref substs, st, mutbl) => { - ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl) + ty_trait(def_id, ref substs, st, mutbl, bounds) => { + let st = match st { + RegionTraitStore(region) => RegionTraitStore(fldr(region)), + st => st, + }; + ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), st, mutbl, bounds) } ty_bare_fn(ref f) => { ty::mk_bare_fn(cx, BareFnTy {sig: fold_sig(&f.sig, fldfnt), @@ -2054,18 +2060,18 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache))) } - ty_trait(_, _, UniqTraitStore, _) => { + ty_trait(_, _, UniqTraitStore, _, _bounds) => { TC_OWNED_CLOSURE } - ty_trait(_, _, BoxTraitStore, mutbl) => { + ty_trait(_, _, BoxTraitStore, mutbl, _bounds) => { match mutbl { ast::m_mutbl => TC_MANAGED + TC_MUTABLE, _ => TC_MANAGED } } - ty_trait(_, _, RegionTraitStore(r), mutbl) => { + ty_trait(_, _, RegionTraitStore(r), mutbl, _bounds) => { borrowed_contents(r, mutbl) } @@ -2347,7 +2353,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { false // unsafe ptrs can always be NULL } - ty_trait(_, _, _, _) => { + ty_trait(_, _, _, _, _) => { false } @@ -2500,7 +2506,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool { ty_box(_) | ty_uniq(_) | ty_closure(_) | ty_estr(vstore_uniq) | ty_estr(vstore_box) | ty_evec(_, vstore_uniq) | ty_evec(_, vstore_box) | - ty_trait(_, _, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false, + ty_trait(_, _, _, _, _) | ty_rptr(_,_) | ty_opaque_box => result = false, // Structural types ty_enum(did, ref substs) => { let variants = enum_variants(cx, did); @@ -2791,12 +2797,13 @@ impl to_bytes::IterBytes for sty { ty_uniq(ref mt) => 19u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - ty_trait(ref did, ref substs, ref v, ref mutbl) => { + ty_trait(ref did, ref substs, ref v, ref mutbl, bounds) => { 20u8.iter_bytes(lsb0, f) && did.iter_bytes(lsb0, f) && substs.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f) && - mutbl.iter_bytes(lsb0, f) + mutbl.iter_bytes(lsb0, f) && + bounds.iter_bytes(lsb0, f) } ty_opaque_closure_ptr(ref ck) => 21u8.iter_bytes(lsb0, f) && ck.iter_bytes(lsb0, f), @@ -3440,7 +3447,7 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str { ty_rptr(_, _) => ~"&-ptr", ty_bare_fn(_) => ~"extern fn", ty_closure(_) => ~"fn", - ty_trait(id, _, _, _) => fmt!("trait %s", item_path_str(cx, id)), + ty_trait(id, _, _, _, _) => fmt!("trait %s", item_path_str(cx, id)), ty_struct(id, _) => fmt!("struct %s", item_path_str(cx, id)), ty_tup(_) => ~"tuple", ty_infer(TyVar(_)) => ~"inferred type", @@ -3774,7 +3781,7 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> { pub fn ty_to_def_id(ty: t) -> Option { match get(ty).sty { - ty_trait(id, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id), + ty_trait(id, _, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id), _ => None } } @@ -4454,5 +4461,6 @@ pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) { assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name)); let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name); (trait_ref, - mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm)) + mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, + BoxTraitStore, ast::m_imm, EmptyBuiltinBounds())) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 660ff83b5b3e..3b651451db84 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -277,7 +277,10 @@ pub fn ast_ty_to_ty( } return ty::mk_evec(tcx, mt, vst); } - ast::ty_path(path, id) => { + ast::ty_path(path, 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. match tcx.def_map.find(&id) { Some(&ast::def_prim_ty(ast::ty_str)) if a_seq_ty.mutbl == ast::m_imm => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); @@ -300,11 +303,13 @@ pub fn ast_ty_to_ty( ty::BoxTraitStore } }; + let bounds = conv_builtin_bounds(this.tcx(), bounds); return ty::mk_trait(tcx, result.def_id, copy result.substs, trait_store, - a_seq_ty.mutbl); + a_seq_ty.mutbl, + bounds); } _ => {} } @@ -395,13 +400,22 @@ pub fn ast_ty_to_ty( ast_ty.span); ty::mk_closure(tcx, fn_decl) } - ast::ty_path(path, id) => { + ast::ty_path(path, bounds, id) => { let a_def = match tcx.def_map.find(&id) { None => tcx.sess.span_fatal( ast_ty.span, fmt!("unbound path %s", path_to_str(path, tcx.sess.intr()))), Some(&d) => d }; + // Kind bounds on path types are only supported for traits. + match a_def { + // But don't emit the error if the user meant to do a trait anyway. + ast::def_trait(*) => { }, + _ if !bounds.is_empty() => + tcx.sess.span_err(ast_ty.span, + "kind bounds can only be used on trait types"), + _ => { }, + } match a_def { ast::def_trait(_) => { let path_str = path_to_str(path, tcx.sess.intr()); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 33d1377d000d..60855e6cd969 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -292,7 +292,7 @@ impl<'self> LookupContext<'self> { ty_param(p) => { self.push_inherent_candidates_from_param(self_ty, p); } - ty_trait(did, ref substs, store, _) => { + ty_trait(did, ref substs, store, _, _) => { self.push_inherent_candidates_from_trait( self_ty, did, substs, store); self.push_inherent_impl_candidates_for_type(did); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index ac89c48a29b2..69d4d82d15f2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -360,7 +360,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { // explaining how it goes about doing that. let target_ty = rcx.resolve_node_type(expr.id); match ty::get(target_ty).sty { - ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _) => { + ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _, _) => { let source_ty = rcx.fcx.expr_ty(source); constrain_regions_in_type(rcx, trait_region, expr.span, source_ty); diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 5ce95e23e2c7..bd78e9cc5fb4 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -139,10 +139,11 @@ fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo, let t = ty::mk_trait(tcx, id, substs, ty::RegionTraitStore(ty::re_static), - ast::m_imm); + ast::m_imm, + ty::EmptyBuiltinBounds()); do fixup_ty(vcx, location_info, t, is_early).map |t_f| { match ty::get(*t_f).sty { - ty::ty_trait(_, ref substs_f, _, _) => (/*bad*/copy *substs_f), + ty::ty_trait(_, ref substs_f, _, _, _) => (/*bad*/copy *substs_f), _ => fail!("t_f should be a trait") } } @@ -530,7 +531,9 @@ pub fn early_resolve_expr(ex: @ast::expr, debug!("vtable resolution on expr %s", ex.repr(fcx.tcx())); let target_ty = fcx.expr_ty(ex); match ty::get(target_ty).sty { - ty::ty_trait(target_def_id, ref target_substs, store, target_mutbl) => { + // Bounds of type's contents are not checked here, but in kind.rs. + ty::ty_trait(target_def_id, ref target_substs, store, + target_mutbl, _bounds) => { fn mutability_allowed(a_mutbl: ast::mutability, b_mutbl: ast::mutability) -> bool { a_mutbl == b_mutbl || diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index bf935d92c75c..7ad27077cd86 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -114,7 +114,7 @@ pub fn type_is_defined_in_local_crate(original_type: t) -> bool { do ty::walk_ty(original_type) |t| { match get(t).sty { ty_enum(def_id, _) | - ty_trait(def_id, _, _, _) | + ty_trait(def_id, _, _, _, _) | ty_struct(def_id, _) => { if def_id.crate == ast::local_crate { found_nominal = true; @@ -140,7 +140,7 @@ pub fn get_base_type_def_id(inference_context: @mut InferCtxt, match get(base_type).sty { ty_enum(def_id, _) | ty_struct(def_id, _) | - ty_trait(def_id, _, _, _) => { + ty_trait(def_id, _, _, _, _) => { return Some(def_id); } _ => { @@ -753,7 +753,7 @@ impl CoherenceChecker { pub fn ast_type_is_defined_in_local_crate(&self, original_type: @ast::Ty) -> bool { match original_type.node { - ty_path(_, path_id) => { + ty_path(_, _, path_id) => { match self.crate_context.tcx.def_map.get_copy(&path_id) { def_ty(def_id) | def_struct(def_id) => { if def_id.crate != local_crate { diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 773860ffc64b..884f72b57f08 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -508,13 +508,15 @@ pub fn super_tys( } } - (&ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl), - &ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl)) + (&ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl, a_bounds), + &ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl, b_bounds)) if a_id == b_id && a_mutbl == b_mutbl => { let trait_def = ty::lookup_trait_def(tcx, a_id); do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| { do this.trait_stores(ty::terr_trait, a_store, b_store).chain |s| { - Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl)) + do this.bounds(a_bounds, b_bounds).chain |bounds| { + Ok(ty::mk_trait(tcx, a_id, /*bad*/copy substs, s, a_mutbl, bounds)) + } } } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 2e83acfa9f4b..1bfe452f25e0 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -717,10 +717,11 @@ impl InferCtxt { trait_ref.def_id, copy trait_ref.substs, ty::UniqTraitStore, - ast::m_imm); + ast::m_imm, + ty::EmptyBuiltinBounds()); let dummy1 = self.resolve_type_vars_if_possible(dummy0); match ty::get(dummy1).sty { - ty::ty_trait(ref def_id, ref substs, _, _) => { + ty::ty_trait(ref def_id, ref substs, _, _, _) => { ty::TraitRef {def_id: *def_id, substs: copy *substs} } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c730e74c9036..2a0b97d4cb1b 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -365,6 +365,8 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { s.push_str("fn"); + s.push_str(cty.bounds.repr(cx)); + push_sig_to_str(cx, &mut s, &cty.sig); return s; @@ -451,11 +453,13 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { let base = ast_map::path_to_str(path, cx.sess.intr()); parameterized(cx, base, substs.self_r, substs.tps) } - ty_trait(did, ref substs, s, mutbl) => { + ty_trait(did, ref substs, s, mutbl, ref bounds) => { let path = ty::item_path(cx, did); let base = ast_map::path_to_str(path, cx.sess.intr()); let ty = parameterized(cx, base, substs.self_r, substs.tps); - fmt!("%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty) + let bound_str = bounds.repr(cx); + fmt!("%s%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty, + bound_str) } ty_evec(ref mt, vs) => { vstore_ty_to_str(cx, mt, vs) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1758433aa737..2e3d557daa90 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -797,7 +797,7 @@ pub enum ty_ { ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), - ty_path(@Path, node_id), + ty_path(@Path, @OptVec, node_id), 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 diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 34c247662a4e..24cf5662a36b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -473,7 +473,7 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { visit_ty: |ty, (t, vt)| { match ty.node { - ty_path(_, id) => vfn(id, copy t), + ty_path(_, _, id) => vfn(id, copy t), _ => { /* fall through */ } } visit::visit_ty(ty, (t, vt)); diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index dc31a248065d..b63997944774 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -48,7 +48,7 @@ pub trait AstBuilder { 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) -> @ast::Ty; + fn ty_path(&self, @ast::Path, @OptVec) -> @ast::Ty; fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty; fn ty_rptr(&self, span: span, @@ -267,14 +267,17 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_path(&self, path: @ast::Path) -> @ast::Ty { + fn ty_path(&self, path: @ast::Path, bounds: @OptVec) + -> @ast::Ty { self.ty(path.span, - ast::ty_path(path, self.next_id())) + ast::ty_path(path, bounds, self.next_id())) } + // 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)) + self.ty_path(self.path_ident(span, ident), @opt_vec::Empty) } fn ty_rptr(&self, @@ -304,7 +307,8 @@ impl AstBuilder for @ExtCtxt { self.ident_of("Option") ], None, - ~[ ty ])) + ~[ ty ]), + @opt_vec::Empty) } fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { @@ -342,7 +346,7 @@ impl AstBuilder for @ExtCtxt { 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])))) + self.path_global(dummy_sp(), ~[p.ident]), @opt_vec::Empty))) } fn strip_bounds(&self, generics: &Generics) -> Generics { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index dca1b7bbd593..981b28afd022 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -358,7 +358,8 @@ impl<'self> TraitDef<'self> { // 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))); + opt_vec::take_vec(self_ty_params)), + @opt_vec::Empty); let doc_attr = cx.attribute( span, diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 3b39cb691a62..d28613f52faf 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -65,7 +65,7 @@ impl<'self> Path<'self> { self_generics: &Generics) -> @ast::Ty { cx.ty_path(self.to_path(cx, span, - self_ty, self_generics)) + self_ty, self_generics), @opt_vec::Empty) } pub fn to_path(&self, cx: @ExtCtxt, @@ -144,7 +144,8 @@ 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)) + cx.ty_path(self.to_path(cx, span, self_ty, self_generics), + @opt_vec::Empty) } Tuple(ref fields) => { let ty = if fields.is_empty() { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 8478a827e85d..a20528082ab5 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -61,7 +61,7 @@ impl gen_send for message { let pipe_ty = cx.ty_path( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params))); + .add_tys(cx.ty_vars(&this.generics.ty_params)), @opt_vec::Empty); 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)); + .add_tys(copy next_state.tys), @opt_vec::Empty); if try { rty = cx.ty_option(rty); } @@ -146,7 +146,7 @@ impl gen_send for message { cx.ty_path( path(~[this.data_name()], span) .add_tys(cx.ty_vars( - &this.generics.ty_params))))], + &this.generics.ty_params)), @opt_vec::Empty))], args_ast); let message_args = if arg_names.len() == 0 { @@ -192,7 +192,7 @@ impl gen_send for message { 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))) + .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @opt_vec::Empty) } } @@ -226,7 +226,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))) + .add_tys(copy next_state.tys), @opt_vec::Empty)) } None => tys }; @@ -279,7 +279,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars( - &self.generics.ty_params))))), + &self.generics.ty_params)), @opt_vec::Empty)), + @opt_vec::Empty), cx.strip_bounds(&self.generics))); } else { @@ -298,8 +299,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global( - &self.generics.ty_params))), - self.proto.buffer_ty_path(cx)])), + &self.generics.ty_params)), @opt_vec::Empty), + self.proto.buffer_ty_path(cx)]), @opt_vec::Empty), cx.strip_bounds(&self.generics))); }; items @@ -384,7 +385,7 @@ 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))) + .add_tys(cx.ty_vars_global(¶ms)), @opt_vec::Empty) } fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index d00f1fd7746d..87aaf7781fae 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -15,6 +15,7 @@ use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::pipes::ast_builder::{append_types, path}; +use opt_vec; #[deriving(Eq)] pub enum direction { send, recv } @@ -101,7 +102,7 @@ impl state_ { 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))) + cx.ty_vars(&self.generics.ty_params)), @opt_vec::Empty) } /// Iterate over the states that can be reached in one message diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 568324bc5996..4bd2c0a3de1f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -680,7 +680,9 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { }) } ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), - ty_path(path, id) => ty_path(fld.fold_path(path), fld.new_id(id)), + ty_path(path, bounds, id) => + ty_path(fld.fold_path(path), + @bounds.map(|x| fold_ty_param_bound(x, fld)), fld.new_id(id)), ty_fixed_length_vec(ref mt, e) => { ty_fixed_length_vec( fold_mt(mt, fld), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 5edd2ec4d479..0c5731c8b29b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -494,7 +494,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - 2), + @opt_vec::Empty, 2), span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, @@ -530,7 +530,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - 2), + @opt_vec::Empty, 2), span:sp(10,13)}, pat: @ast::pat{id:1, // fixme node: ast::pat_ident( diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index bb315bf29339..19b4d2545808 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -46,7 +46,6 @@ pub enum ObsoleteSyntax { ObsoleteUnsafeBlock, ObsoleteUnenforcedBound, ObsoleteImplSyntax, - ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer, ObsoleteMutVector, ObsoleteImplVisibility, @@ -143,10 +142,6 @@ impl Parser { "colon-separated impl syntax", "write `impl Trait for Type`" ), - ObsoleteTraitBoundSeparator => ( - "space-separated trait bounds", - "write `+` between trait bounds" - ), ObsoleteMutOwnedPointer => ( "const or mutable owned pointer", "mutability inherits through `~` pointers; place the `~` box diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 753c69b23d6a..f2443f9e5335 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -75,7 +75,7 @@ use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator}; use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove, ObsoleteSwap}; use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds}; use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; -use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; +use parse::obsolete::{ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; use parse::obsolete::{ObsoletePostFnTySigil}; @@ -710,8 +710,8 @@ impl Parser { } else if *self.token == token::MOD_SEP || is_ident_or_path(self.token) { // NAMED TYPE - let path = self.parse_path_with_tps(false); - ty_path(path, self.get_id()) + let (path, bounds) = self.parse_type_path(); + ty_path(path, @bounds, self.get_id()) } else { self.fatal(fmt!("expected type, found token %?", *self.token)); @@ -974,10 +974,8 @@ impl Parser { types: ~[] } } - // 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_bounded_path_with_tps(&self, colons: bool, + before_tps: Option<&fn()>) -> @ast::Path { debug!("parse_path_with_tps(colons=%b)", colons); maybe_whole!(self, nt_path); @@ -987,6 +985,10 @@ impl Parser { return path; } + // If the path might have bounds on it, they should be parsed before + // the parameters, e.g. module::TraitName:B1+B2 + before_tps.map_consume(|callback| callback()); + // Parse the (obsolete) trailing region parameter, if any, which will // be written "foo/&x" let rp_slash = { @@ -1038,6 +1040,25 @@ impl Parser { .. copy *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 { + 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, OptVec) { + let mut bounds = opt_vec::Empty; + let path = self.parse_bounded_path_with_tps(false, Some(|| { + // Note: this closure might not even get called in the case of a + // macro-generated path. But that's the macro parser's job. + bounds = self.parse_optional_ty_param_bounds(); + })); + (path, bounds) + } + /// parses 0 or 1 lifetime pub fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { match *self.token { @@ -2847,16 +2868,6 @@ impl Parser { spanned(lo, hi, bloc) } - fn mk_ty_path(&self, i: ident) -> @Ty { - @Ty { - id: self.get_id(), - node: ty_path( - ident_to_path(*self.last_span, i), - self.get_id()), - span: *self.last_span, - } - } - fn parse_optional_purity(&self) -> ast::purity { if self.eat_keyword(keywords::Pure) { self.obsolete(*self.last_span, ObsoletePurity); @@ -2921,13 +2932,8 @@ impl Parser { _ => break, } - if self.eat(&token::BINOP(token::PLUS)) { - loop; - } - - if is_ident_or_path(self.token) { - self.obsolete(*self.span, - ObsoleteTraitBoundSeparator); + if !self.eat(&token::BINOP(token::PLUS)) { + break; } } @@ -3284,14 +3290,19 @@ 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, node_id) => { + ty_path(path, @opt_vec::Empty, node_id) => { Some(@trait_ref { path: path, ref_id: node_id }) } + ty_path(*) => { + self.span_err(ty.span, + "bounded traits are only valid in type position"); + None + } _ => { - self.span_err(*self.span, "not a trait"); + self.span_err(ty.span, "not a trait"); None } }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8e47df510108..fa22b7ceb710 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -422,7 +422,7 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { f.purity, f.onceness, &f.decl, None, Some(&generics), None); } - ast::ty_path(path, _) => print_path(s, path, false), + ast::ty_path(path, bounds, _) => print_bounded_path(s, path, bounds), ast::ty_fixed_length_vec(ref mt, v) => { word(s.s, "["); match mt.mutbl { @@ -1483,7 +1483,8 @@ pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { print_expr(s, coll); } -pub 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<@OptVec>) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } let mut first = true; @@ -1491,6 +1492,9 @@ pub fn print_path(s: @ps, path: @ast::Path, colons_before_params: bool) { if first { first = false; } else { word(s.s, "::"); } print_ident(s, *id); } + do opt_bounds.map_consume |bounds| { + print_bounds(s, bounds); + }; if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, "::"); } @@ -1511,6 +1515,15 @@ 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, + bounds: @OptVec) { + print_path_(s, path, false, Some(bounds)) +} + pub fn print_irrefutable_pat(s: @ps, pat: @ast::pat) { print_pat(s, pat, false) } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index e7afeb12a618..5aa38c0348c0 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -247,13 +247,17 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { }, 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, (e, v)); + (v.visit_ty)(f.decl.output, (copy e, v)); + visit_ty_param_bounds(&f.bounds, (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)); }, - ty_path(p, _) => visit_path(p, (e, v)), + ty_path(p, bounds, _) => { + visit_path(p, (copy e, v)); + visit_ty_param_bounds(bounds, (e, v)); + }, ty_fixed_length_vec(ref mt, ex) => { (v.visit_ty)(mt.ty, (copy e, v)); (v.visit_expr)(ex, (copy e, v)); @@ -328,7 +332,7 @@ pub fn visit_foreign_item(ni: @foreign_item, (e, v): (E, vt)) { } } -pub fn visit_ty_param_bounds(bounds: @OptVec, +pub fn visit_ty_param_bounds(bounds: &OptVec, (e, v): (E, vt)) { for bounds.each |bound| { match *bound { From f4ccb2fa85124dc90667ac61f829c46f9a5c2dc7 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 13:55:30 -0400 Subject: [PATCH 082/336] Add tests for not-kind-checked trait bounds. --- .../compile-fail/trait-bounds-cant-coerce.rs | 28 +++++++++++++++++++ .../trait-bounds-not-on-bare-trait.rs | 19 +++++++++++++ .../compile-fail/trait-bounds-not-on-impl.rs | 19 +++++++++++++ .../trait-bounds-not-on-struct.rs | 15 ++++++++++ src/test/run-pass/trait-bounds-basic.rs | 28 +++++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 src/test/compile-fail/trait-bounds-cant-coerce.rs create mode 100644 src/test/compile-fail/trait-bounds-not-on-bare-trait.rs create mode 100644 src/test/compile-fail/trait-bounds-not-on-impl.rs create mode 100644 src/test/compile-fail/trait-bounds-not-on-struct.rs create mode 100644 src/test/run-pass/trait-bounds-basic.rs diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs new file mode 100644 index 000000000000..88c2d4917473 --- /dev/null +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -0,0 +1,28 @@ +// 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 Foo { +} + +fn a(_x: ~Foo:Owned) { +} + +fn b(_x: ~Foo:Owned+Copy) { +} + +fn c(x: ~Foo:Const+Owned) { + b(x); //~ ERROR expected bounds `Copy+Owned` +} + +fn d(x: ~Foo) { + a(x); //~ ERROR found no bounds +} + +fn main() { } diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs new file mode 100644 index 000000000000..e9cc9575003d --- /dev/null +++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.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. + +trait Foo { +} + +// This should emit the less confusing error, not the more confusing one. + +fn foo(_x: Foo:Owned) { //~ERROR reference to trait `Foo` where a type is expected +} + +fn main() { } diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/compile-fail/trait-bounds-not-on-impl.rs new file mode 100644 index 000000000000..ac88b21b456e --- /dev/null +++ b/src/test/compile-fail/trait-bounds-not-on-impl.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. + +trait Foo { +} + +struct Bar; + +impl Foo:Owned for Bar { //~ ERROR bounded traits are only valid in type position +} + +fn main() { } diff --git a/src/test/compile-fail/trait-bounds-not-on-struct.rs b/src/test/compile-fail/trait-bounds-not-on-struct.rs new file mode 100644 index 000000000000..45bb5e29a884 --- /dev/null +++ b/src/test/compile-fail/trait-bounds-not-on-struct.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. + +struct Foo; + +fn foo(_x: ~Foo:Owned) { } //~ ERROR kind bounds can only be used on trait types + +fn main() { } diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs new file mode 100644 index 000000000000..b9251c038afa --- /dev/null +++ b/src/test/run-pass/trait-bounds-basic.rs @@ -0,0 +1,28 @@ +// 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 Foo { +} + +fn a(_x: ~Foo) { +} + +fn b(_x: ~Foo:Owned) { +} + +fn c(x: ~Foo:Const+Owned) { + a(x); +} + +fn d(x: ~Foo:Owned+Copy) { + b(x); +} + +fn main() { } From 7c0a0404d591958b8c31deab8d08ad6f82f8c15b Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 13 Jun 2013 19:37:18 -0400 Subject: [PATCH 083/336] Check closure freevar kinds against destination environment bounds (#3569) --- src/librustc/middle/kind.rs | 81 ++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 1768852bb303..2e69e5efd8dd 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -81,8 +81,6 @@ pub fn check_crate(tcx: ty::ctxt, tcx.sess.abort_if_errors(); } -type check_fn = @fn(Context, @freevar_entry); - fn check_struct_safe_for_destructor(cx: Context, span: span, struct_did: def_id) { @@ -163,30 +161,43 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // Yields the appropriate function to check the kind of closed over // variables. `id` is the node_id for some expression that creates the // closure. -fn with_appropriate_checker(cx: Context, id: node_id, b: &fn(check_fn)) { - fn check_for_uniq(cx: Context, fv: @freevar_entry) { +fn with_appropriate_checker(cx: Context, id: node_id, + b: &fn(checker: &fn(Context, @freevar_entry))) { + fn check_for_uniq(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned, regardless of whether it is // moved in or copied in. let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); + + // FIXME(#3569): Once closure capabilities are restricted based on their + // incoming bounds, make this check conditional based on the bounds. if !check_owned(cx, var_t, fv.span) { return; } // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); + + check_freevar_bounds(cx, fv.span, var_t, bounds); } - fn check_for_box(cx: Context, fv: @freevar_entry) { + fn check_for_box(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); + + // FIXME(#3569): Once closure capabilities are restricted based on their + // incoming bounds, make this check conditional based on the bounds. if !check_durable(cx.tcx, var_t, fv.span) { return; } // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); + + check_freevar_bounds(cx, fv.span, var_t, bounds); } - fn check_for_block(_cx: Context, _fv: @freevar_entry) { - // no restrictions + fn check_for_block(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { + let id = ast_util::def_id_of_def(fv.def).node; + let var_t = ty::node_id_to_type(cx.tcx, id); + check_freevar_bounds(cx, fv.span, var_t, bounds); } fn check_for_bare(cx: Context, fv: @freevar_entry) { @@ -197,14 +208,14 @@ fn with_appropriate_checker(cx: Context, id: node_id, b: &fn(check_fn)) { let fty = ty::node_id_to_type(cx.tcx, id); match ty::get(fty).sty { - ty::ty_closure(ty::ClosureTy {sigil: OwnedSigil, _}) => { - b(check_for_uniq) + ty::ty_closure(ty::ClosureTy {sigil: OwnedSigil, bounds: bounds, _}) => { + b(|cx, fv| check_for_uniq(cx, fv, bounds)) } - ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, _}) => { - b(check_for_box) + ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, bounds: bounds, _}) => { + b(|cx, fv| check_for_box(cx, fv, bounds)) } - ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, _}) => { - b(check_for_block) + ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, _}) => { + b(|cx, fv| check_for_block(cx, fv, bounds)) } ty::ty_bare_fn(_) => { b(check_for_bare) @@ -272,7 +283,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { type_param_defs.repr(cx.tcx)); } for ts.iter().zip(type_param_defs.iter()).advance |(&ty, type_param_def)| { - check_bounds(cx, type_parameter_id, e.span, ty, type_param_def) + check_typaram_bounds(cx, type_parameter_id, e.span, ty, type_param_def) } } } @@ -315,7 +326,7 @@ fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { let type_param_defs = ty::lookup_item_type(cx.tcx, did).generics.type_param_defs; for ts.iter().zip(type_param_defs.iter()).advance |(&ty, type_param_def)| { - check_bounds(cx, aty.id, aty.span, ty, type_param_def) + check_typaram_bounds(cx, aty.id, aty.span, ty, type_param_def) } } } @@ -324,19 +335,26 @@ fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { visit::visit_ty(aty, (cx, v)); } -pub fn check_bounds(cx: Context, +pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds) + -> ty::BuiltinBounds // returns the missing bounds +{ + let kind = ty::type_contents(cx.tcx, ty); + let mut missing = ty::EmptyBuiltinBounds(); + for bounds.each |bound| { + if !kind.meets_bound(cx.tcx, bound) { + missing.add(bound); + } + } + missing +} + +pub fn check_typaram_bounds(cx: Context, _type_parameter_id: node_id, sp: span, ty: ty::t, type_param_def: &ty::TypeParameterDef) { - let kind = ty::type_contents(cx.tcx, ty); - let mut missing = ty::EmptyBuiltinBounds(); - for type_param_def.bounds.builtin_bounds.each |bound| { - if !kind.meets_bound(cx.tcx, bound) { - missing.add(bound); - } - } + let missing = check_builtin_bounds(cx, ty, type_param_def.bounds.builtin_bounds); if !missing.is_empty() { cx.tcx.sess.span_err( sp, @@ -347,6 +365,23 @@ pub fn check_bounds(cx: Context, } } +pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, + bounds: ty::BuiltinBounds) +{ + let missing = check_builtin_bounds(cx, ty, bounds); + if !missing.is_empty() { + cx.tcx.sess.span_err( + sp, + fmt!("cannot capture variable of type `%s`, which does not fulfill \ + `%s`, in a bounded closure", + ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx))); + cx.tcx.sess.span_note( + sp, + fmt!("this closure's environment must satisfy `%s`", + bounds.user_string(cx.tcx))); + } +} + fn is_nullary_variant(cx: Context, ex: @expr) -> bool { match ex.node { expr_path(_) => { From c454e95fac0c7e68b3298ea87bd402ef954394bf Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 13 Jun 2013 19:38:36 -0400 Subject: [PATCH 084/336] Add basic test cases for closure bounds. (#3569) --- ...bounds-cant-promote-superkind-in-struct.rs | 20 ++++++++++++++ ...re-bounds-copy-cant-capture-noncopyable.rs | 26 +++++++++++++++++++ ...ure-bounds-static-cant-capture-borrowed.rs | 21 +++++++++++++++ .../compile-fail/closure-bounds-subtype.rs | 7 ++++- .../closure-bounds-can-capture-chan.rs | 23 ++++++++++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs create mode 100644 src/test/compile-fail/closure-bounds-copy-cant-capture-noncopyable.rs create mode 100644 src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs create mode 100644 src/test/run-pass/closure-bounds-can-capture-chan.rs diff --git a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs new file mode 100644 index 000000000000..c3c8467233c4 --- /dev/null +++ b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.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. + +struct X { + field: @fn:Copy(), +} + +fn foo(blk: @fn()) -> X { + return X { field: blk }; //~ ERROR expected bounds `Copy` but found no bounds +} + +fn main() { +} diff --git a/src/test/compile-fail/closure-bounds-copy-cant-capture-noncopyable.rs b/src/test/compile-fail/closure-bounds-copy-cant-capture-noncopyable.rs new file mode 100644 index 000000000000..0b11da14e71a --- /dev/null +++ b/src/test/compile-fail/closure-bounds-copy-cant-capture-noncopyable.rs @@ -0,0 +1,26 @@ +// 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. + +use std::comm; + +// If this were legal you could use it to copy captured noncopyables. +// Issue (#2828) + +fn foo(blk: ~fn:Copy()) { + blk(); +} + +fn main() { + let (p,c) = comm::stream(); + do foo { + c.send(()); //~ ERROR does not fulfill `Copy` + } + p.recv(); +} diff --git a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs new file mode 100644 index 000000000000..cac1244a5609 --- /dev/null +++ b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.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. + +fn bar(blk: &fn:'static()) { +} + +fn foo(x: &()) { + do bar { + let _ = x; //~ ERROR does not fulfill `'static` + } +} + +fn main() { +} diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs index ebec113cedc5..a975349e7302 100644 --- a/src/test/compile-fail/closure-bounds-subtype.rs +++ b/src/test/compile-fail/closure-bounds-subtype.rs @@ -1,3 +1,4 @@ + fn take_any(_: &fn()) { } @@ -7,6 +8,9 @@ fn take_copyable(_: &fn:Copy()) { fn take_copyable_owned(_: &fn:Copy+Owned()) { } +fn take_const_owned(_: &fn:Const+Owned()) { +} + fn give_any(f: &fn()) { take_any(f); take_copyable(f); //~ ERROR expected bounds `Copy` but found no bounds @@ -29,6 +33,7 @@ fn give_copyable_owned(f: &fn:Copy+Owned()) { take_any(f); take_copyable(f); take_copyable_owned(f); + take_const_owned(f); //~ ERROR expected bounds `Owned+Const` but found bounds `Copy+Owned` } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs new file mode 100644 index 000000000000..26bea0e51415 --- /dev/null +++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs @@ -0,0 +1,23 @@ +// 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. + +use std::comm; + +fn foo(blk: ~fn:Owned()) { + blk(); +} + +fn main() { + let (p,c) = comm::stream(); + do foo { + c.send(()); + } + p.recv(); +} From 3da7c8f7e11952df0737a1578b87b626a5f4b05a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 23 Jun 2013 01:27:34 -0700 Subject: [PATCH 085/336] compiletest: Shorten test names --- src/compiletest/compiletest.rc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index e832534b227a..7594a3739df9 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -253,9 +253,17 @@ pub fn make_test(config: &config, testfile: &Path) -> test::TestDescAndFn { } pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { + + // Try to elide redundant long paths + fn shorten(path: &Path) -> ~str { + let filename = path.filename(); + let dir = path.pop().filename(); + fmt!("%s/%s", dir.get_or_default(~""), filename.get_or_default(~"")) + } + test::DynTestName(fmt!("[%s] %s", mode_str(config.mode), - testfile.to_str())) + shorten(testfile))) } pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn { From a4a8a4ac277f686a4d771f1a8ce5a55b27eddf5c Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 17:08:34 +0200 Subject: [PATCH 086/336] Fixed os:: and int:: not being in scope, changed io::println to println --- src/test/bench/shootout-binarytrees.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index e7aed911cb0a..391dd5136664 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -41,7 +41,9 @@ fn bottom_up_tree<'r>(arena: &'r mut arena::Arena, item: int, depth: int) } fn main() { - let args = os::args(); + use std::os; + use std::int; + let args = std::os::args(); let args = if os::getenv(~"RUST_BENCH").is_some() { ~[~"", ~"17"] } else if args.len() <= 1u { @@ -63,7 +65,7 @@ fn main() { let stretch_depth = max_depth + 1; let stretch_tree = bottom_up_tree(&mut stretch_arena, 0, stretch_depth); - io::println(fmt!("stretch tree of depth %d\t check: %d", + println(fmt!("stretch tree of depth %d\t check: %d", stretch_depth, item_check(stretch_tree))); @@ -81,12 +83,12 @@ fn main() { chk += item_check(temp_tree); i += 1; } - io::println(fmt!("%d\t trees of depth %d\t check: %d", + println(fmt!("%d\t trees of depth %d\t check: %d", iterations * 2, depth, chk)); depth += 2; } - io::println(fmt!("long lived trees of depth %d\t check: %d", + println(fmt!("long lived tree of depth %d\t check: %d", max_depth, item_check(long_lived_tree))); } From 3b1ace9f9b07d59804fab1abc02ddf20b1496666 Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 22:22:53 +0200 Subject: [PATCH 087/336] Updated copyright year on shootout-binarytrees.rs --- src/test/bench/shootout-binarytrees.rs | 38 ++++++++++++-------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs index 391dd5136664..76ef4c12380e 100644 --- a/src/test/bench/shootout-binarytrees.rs +++ b/src/test/bench/shootout-binarytrees.rs @@ -1,8 +1,4 @@ -// xfail-test - -// Broken due to arena API problems. - -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -15,29 +11,29 @@ extern mod extra; use extra::arena; -enum tree<'self> { - nil, - node(&'self tree<'self>, &'self tree<'self>, int), +enum Tree<'self> { + Nil, + Node(&'self Tree<'self>, &'self Tree<'self>, int), } -fn item_check(t: &tree) -> int { +fn item_check(t: &Tree) -> int { match *t { - nil => { return 0; } - node(left, right, item) => { + Nil => { return 0; } + Node(left, right, item) => { return item + item_check(left) - item_check(right); } } } -fn bottom_up_tree<'r>(arena: &'r mut arena::Arena, item: int, depth: int) - -> &'r tree<'r> { +fn bottom_up_tree<'r>(arena: &'r arena::Arena, item: int, depth: int) + -> &'r Tree<'r> { if depth > 0 { return arena.alloc( - || node(bottom_up_tree(arena, 2 * item - 1, depth - 1), + || Node(bottom_up_tree(arena, 2 * item - 1, depth - 1), bottom_up_tree(arena, 2 * item, depth - 1), item)); } - return arena.alloc(|| nil); + return arena.alloc(|| Nil); } fn main() { @@ -61,25 +57,25 @@ fn main() { max_depth = n; } - let mut stretch_arena = arena::Arena(); + let stretch_arena = arena::Arena(); let stretch_depth = max_depth + 1; - let stretch_tree = bottom_up_tree(&mut stretch_arena, 0, stretch_depth); + let stretch_tree = bottom_up_tree(&stretch_arena, 0, stretch_depth); println(fmt!("stretch tree of depth %d\t check: %d", stretch_depth, item_check(stretch_tree))); - let mut long_lived_arena = arena::Arena(); - let long_lived_tree = bottom_up_tree(&mut long_lived_arena, 0, max_depth); + let long_lived_arena = arena::Arena(); + let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth); let mut depth = min_depth; while depth <= max_depth { let iterations = int::pow(2, (max_depth - depth + min_depth) as uint); let mut chk = 0; let mut i = 1; while i <= iterations { - let mut temp_tree = bottom_up_tree(&mut long_lived_arena, i, depth); + let mut temp_tree = bottom_up_tree(&long_lived_arena, i, depth); chk += item_check(temp_tree); - temp_tree = bottom_up_tree(&mut long_lived_arena, -i, depth); + temp_tree = bottom_up_tree(&long_lived_arena, -i, depth); chk += item_check(temp_tree); i += 1; } From b306f9fa404cc8a23648c2d992071a27c88666f1 Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 22:23:45 +0200 Subject: [PATCH 088/336] Changed shootout-chameneos-redux output to conform to the 'official' output format. --- src/test/bench/shootout-chameneos-redux.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 2a9ea783c149..3ff123b027ab 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -85,7 +85,7 @@ fn show_number(nn: uint) -> ~str { out = show_digit(dig) + " " + out; } - return out; + return ~" " + out; } fn transform(aa: color, bb: color) -> color { From de64ff20ab5f8c961ffda10c3bf168b52a8e4196 Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 22:54:08 +0200 Subject: [PATCH 089/336] Added missing copyright notice to shootout-spectralnorm. --- src/test/bench/shootout-spectralnorm.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 534df512a481..35a37e553320 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -1,3 +1,13 @@ +// 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. + use std::f64; use std::from_str::FromStr; use std::os; From 66fd3c9e5dd8c9b44237b57f455ba60ef607958b Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 23:46:31 +0200 Subject: [PATCH 090/336] Fixed shootout-fasta.rs output --- src/test/bench/shootout-fasta.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 38c8d1903e98..a69284611a27 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -28,7 +28,9 @@ use std::str; use std::uint; use std::vec; -fn LINE_LENGTH() -> uint { return 60u; } +static LINE_LENGTH: uint = 60u; + +//fn LINE_LENGTH() -> uint { return 60u; } struct MyRandom { last: u32 @@ -81,7 +83,7 @@ fn make_random_fasta(wr: @io::Writer, for uint::range(0u, n as uint) |_i| { op.push_char(select_random(myrandom_next(rng, 100u32), copy genelist)); - if op.len() >= LINE_LENGTH() { + if op.len() >= LINE_LENGTH { wr.write_line(op); op = ~""; } @@ -90,18 +92,20 @@ fn make_random_fasta(wr: @io::Writer, } fn make_repeat_fasta(wr: @io::Writer, id: ~str, desc: ~str, s: ~str, n: int) { + wr.write_line(~">" + id + " " + desc); + let mut op = str::with_capacity( LINE_LENGTH ); + let sl = s.len(); unsafe { - wr.write_line(~">" + id + " " + desc); - let mut op: ~str = ~""; - let sl: uint = s.len(); for uint::range(0u, n as uint) |i| { - str::raw::push_byte(&mut op, s[i % sl]); - if op.len() >= LINE_LENGTH() { - wr.write_line(op); - op = ~""; + if (op.len() >= LINE_LENGTH) { + wr.write_line( op ); + op = str::with_capacity( LINE_LENGTH ); } + op.push_char( s[i % sl] as char ); + } + if op.len() > 0 { + wr.write_line(op) } - if op.len() > 0u { wr.write_line(op); } } } From 6762754d5b718d2d3f938963d2a4d82eb20eb9fd Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 23:48:46 +0200 Subject: [PATCH 091/336] Updated shootout-fasta.rs copyright years, removed stuff that caused lint to complain. --- src/test/bench/shootout-fasta.rs | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index a69284611a27..f3efcc21ea9b 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -19,19 +19,15 @@ extern mod extra; use std::int; use std::io; -use std::option; use std::os; use std::rand::Rng; use std::rand; use std::result; use std::str; use std::uint; -use std::vec; static LINE_LENGTH: uint = 60u; -//fn LINE_LENGTH() -> uint { return 60u; } - struct MyRandom { last: u32 } @@ -95,17 +91,15 @@ fn make_repeat_fasta(wr: @io::Writer, id: ~str, desc: ~str, s: ~str, n: int) { wr.write_line(~">" + id + " " + desc); let mut op = str::with_capacity( LINE_LENGTH ); let sl = s.len(); - unsafe { - for uint::range(0u, n as uint) |i| { - if (op.len() >= LINE_LENGTH) { - wr.write_line( op ); - op = str::with_capacity( LINE_LENGTH ); - } - op.push_char( s[i % sl] as char ); - } - if op.len() > 0 { - wr.write_line(op) + for uint::range(0u, n as uint) |i| { + if (op.len() >= LINE_LENGTH) { + wr.write_line( op ); + op = str::with_capacity( LINE_LENGTH ); } + op.push_char( s[i % sl] as char ); + } + if op.len() > 0 { + wr.write_line(op) } } @@ -115,7 +109,7 @@ fn acid(ch: char, prob: u32) -> AminoAcids { fn main() { let args = os::args(); - let args = if os::getenv(~"RUST_BENCH").is_some() { + let args = if os::getenv("RUST_BENCH").is_some() { // alioth tests k-nucleotide with this data at 25,000,000 ~[~"", ~"5000000"] } else if args.len() <= 1u { @@ -124,9 +118,9 @@ fn main() { args }; - let writer = if os::getenv(~"RUST_BENCH").is_some() { + let writer = if os::getenv("RUST_BENCH").is_some() { result::get(&io::file_writer(&Path("./shootout-fasta.data"), - ~[io::Truncate, io::Create])) + [io::Truncate, io::Create])) } else { io::stdout() }; From 1ffcc6fc82caae4e6d17f1156c815998a0b5e080 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 13 Jun 2013 20:57:23 -0400 Subject: [PATCH 092/336] Allow ~fn:Copy() to be copied. --- src/librustc/middle/ty.rs | 27 +++++++++++++----- ...losure-bounds-copyable-squiggle-closure.rs | 25 +++++++++++++++++ ...ds-squiggle-closure-as-copyable-typaram.rs | 28 +++++++++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs create mode 100644 src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b76f30a70410..90cd8a8665ea 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1856,7 +1856,7 @@ impl TypeContents { } pub fn noncopyable(_cx: ctxt) -> TypeContents { - TC_DTOR + TC_BORROWED_MUT + TC_ONCE_CLOSURE + TC_OWNED_CLOSURE + + TC_DTOR + TC_BORROWED_MUT + TC_ONCE_CLOSURE + TC_NONCOPY_TRAIT + TC_EMPTY_ENUM } @@ -1905,13 +1905,19 @@ impl TypeContents { } pub fn needs_drop(&self, cx: ctxt) -> bool { + if self.intersects(TC_NONCOPY_TRAIT) { + // Currently all noncopyable existentials are 2nd-class types + // behind owned pointers. With dynamically-sized types, remove + // this assertion. + assert!(self.intersects(TC_OWNED_POINTER)); + } let tc = TC_MANAGED + TC_DTOR + TypeContents::owned(cx); self.intersects(tc) } pub fn owned(_cx: ctxt) -> TypeContents { //! Any kind of owned contents. - TC_OWNED_CLOSURE + TC_OWNED_POINTER + TC_OWNED_VEC + TC_OWNED_POINTER + TC_OWNED_VEC } } @@ -1945,8 +1951,8 @@ static TC_OWNED_POINTER: TypeContents = TypeContents{bits: 0b0000_0000_0010}; /// Contains an owned vector ~[] or owned string ~str static TC_OWNED_VEC: TypeContents = TypeContents{bits: 0b0000_0000_0100}; -/// Contains a ~fn() or a ~Trait, which is non-copyable. -static TC_OWNED_CLOSURE: TypeContents = TypeContents{bits: 0b0000_0000_1000}; +/// Contains a non-copyable ~fn() or a ~Trait (NOT a ~fn:Copy() or ~Trait:Copy). +static TC_NONCOPY_TRAIT: TypeContents = TypeContents{bits: 0b0000_0000_1000}; /// Type with a destructor static TC_DTOR: TypeContents = TypeContents{bits: 0b0000_0001_0000}; @@ -2061,7 +2067,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } ty_trait(_, _, UniqTraitStore, _, _bounds) => { - TC_OWNED_CLOSURE + // FIXME(#3569): Make this conditional on the trait's bounds. + TC_NONCOPY_TRAIT + TC_OWNED_POINTER } ty_trait(_, _, BoxTraitStore, mutbl, _bounds) => { @@ -2184,7 +2191,9 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { match sigil { ast::BorrowedSigil => TC_BORROWED_POINTER, ast::ManagedSigil => TC_MANAGED, - ast::OwnedSigil => TC_OWNED_CLOSURE + // FIXME(#3569): Looks like noncopyability should depend + // on the bounds, but I don't think this case ever comes up. + ast::OwnedSigil => TC_NONCOPY_TRAIT + TC_OWNED_POINTER, } } @@ -2258,7 +2267,11 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { let st = match cty.sigil { ast::BorrowedSigil => TC_BORROWED_POINTER, ast::ManagedSigil => TC_MANAGED, - ast::OwnedSigil => TC_OWNED_CLOSURE + ast::OwnedSigil => if cty.bounds.contains_elem(BoundCopy) { + TC_OWNED_POINTER + } else { + TC_OWNED_POINTER + TC_NONCOPY_TRAIT + } }; let rt = borrowed_contents(cty.region, m_imm); let ot = match cty.onceness { diff --git a/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs new file mode 100644 index 000000000000..f39c914916ff --- /dev/null +++ b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs @@ -0,0 +1,25 @@ +// 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-pretty + +// Tests correct copying of heap closures' environments. + +fn foo(x: ~fn:Copy()) -> (~fn(), ~fn()) { + (copy x, x) +} +fn main() { + let v = ~[~[1,2,3],~[4,5,6]]; // shouldn't get double-freed + let (f1,f2) = do foo { + assert!(v.len() == 2); + }; + f1(); + f2(); +} diff --git a/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs new file mode 100644 index 000000000000..2fdce4e5c7cd --- /dev/null +++ b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs @@ -0,0 +1,28 @@ +// 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-pretty + +// Tests correct copying of heap closures' environments. + +fn bar(x: T) -> (T, T) { + (copy x, x) +} +fn foo(x: ~fn:Copy()) -> (~fn(), ~fn()) { + bar(x) +} +fn main() { + let v = ~[~[1,2,3],~[4,5,6]]; // shouldn't get double-freed + let (f1,f2) = do foo { + assert!(v.len() == 2); + }; + f1(); + f2(); +} From 1d2b20ee2c4b6a0f71a4c2f85e4b10157d616c0f Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 17:58:04 -0400 Subject: [PATCH 093/336] Check existential type contents against destination trait bounds. --- src/librustc/middle/kind.rs | 56 ++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 2e69e5efd8dd..7f7a81fa974a 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -291,7 +291,13 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { match e.node { expr_cast(source, _) => { check_cast_for_escaping_regions(cx, source, e); - check_kind_bounds_of_cast(cx, source, e); + match ty::get(ty::expr_ty(cx.tcx, e)).sty { + ty::ty_trait(_, _, store, _, bounds) => { + let source_ty = ty::expr_ty(cx.tcx, source); + check_trait_cast_bounds(cx, e.span, source_ty, bounds, store) + } + _ => { } + } } expr_copy(expr) => { // Note: This is the only place where we must check whether the @@ -335,8 +341,9 @@ fn check_ty(aty: @Ty, (cx, v): (Context, visit::vt)) { visit::visit_ty(aty, (cx, v)); } -pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds) - -> ty::BuiltinBounds // returns the missing bounds +// Calls "any_missing" if any bounds were missing. +pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds, + any_missing: &fn(ty::BuiltinBounds)) { let kind = ty::type_contents(cx.tcx, ty); let mut missing = ty::EmptyBuiltinBounds(); @@ -345,7 +352,9 @@ pub fn check_builtin_bounds(cx: Context, ty: ty::t, bounds: ty::BuiltinBounds) missing.add(bound); } } - missing + if !missing.is_empty() { + any_missing(missing); + } } pub fn check_typaram_bounds(cx: Context, @@ -354,8 +363,7 @@ pub fn check_typaram_bounds(cx: Context, ty: ty::t, type_param_def: &ty::TypeParameterDef) { - let missing = check_builtin_bounds(cx, ty, type_param_def.bounds.builtin_bounds); - if !missing.is_empty() { + do check_builtin_bounds(cx, ty, type_param_def.bounds.builtin_bounds) |missing| { cx.tcx.sess.span_err( sp, fmt!("instantiating a type parameter with an incompatible type \ @@ -368,8 +376,7 @@ pub fn check_typaram_bounds(cx: Context, pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, bounds: ty::BuiltinBounds) { - let missing = check_builtin_bounds(cx, ty, bounds); - if !missing.is_empty() { + do check_builtin_bounds(cx, ty, bounds) |missing| { cx.tcx.sess.span_err( sp, fmt!("cannot capture variable of type `%s`, which does not fulfill \ @@ -382,6 +389,22 @@ pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, } } +pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t, + bounds: ty::BuiltinBounds, store: ty::TraitStore) { + do check_builtin_bounds(cx, ty, bounds) |missing| { + cx.tcx.sess.span_err(sp, + fmt!("cannot pack type `%s`, which does not fulfill \ + `%s`, as a trait bounded by %s", + ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx), + bounds.user_string(cx.tcx))); + } + // FIXME(#3569): Remove this check when the corresponding restriction + // is made with type contents. + if store == ty::UniqTraitStore && !ty::type_is_owned(cx.tcx, ty) { + cx.tcx.sess.span_err(sp, "uniquely-owned trait objects must be sendable"); + } +} + fn is_nullary_variant(cx: Context, ex: @expr) -> bool { match ex.node { expr_path(_) => { @@ -564,20 +587,3 @@ pub fn check_cast_for_escaping_regions( cx.tcx.region_maps.is_subregion_of(r_sub, r_sup) } } - -/// Ensures that values placed into a ~Trait are copyable and sendable. -pub fn check_kind_bounds_of_cast(cx: Context, source: @expr, target: @expr) { - let target_ty = ty::expr_ty(cx.tcx, target); - match ty::get(target_ty).sty { - // FIXME(#3569) kind check bounds here - ty::ty_trait(_, _, ty::UniqTraitStore, _, _bounds) => { - let source_ty = ty::expr_ty(cx.tcx, source); - if !ty::type_is_owned(cx.tcx, source_ty) { - cx.tcx.sess.span_err( - target.span, - "uniquely-owned trait objects must be sendable"); - } - } - _ => {} // Nothing to do. - } -} From ba3f43e506de97109788e4a96df438b3c89f5e49 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 22:27:06 -0400 Subject: [PATCH 094/336] Fix pretty-printing builtin bounds on closures and traits --- src/librustc/util/ppaux.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2a0b97d4cb1b..e25267f44412 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -365,6 +365,9 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { s.push_str("fn"); + if !cty.bounds.is_empty() { + s.push_str(":"); + } s.push_str(cty.bounds.repr(cx)); push_sig_to_str(cx, &mut s, &cty.sig); @@ -457,9 +460,10 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { let path = ty::item_path(cx, did); let base = ast_map::path_to_str(path, cx.sess.intr()); let ty = parameterized(cx, base, substs.self_r, substs.tps); + let bound_sep = if bounds.is_empty() { "" } else { ":" }; let bound_str = bounds.repr(cx); - fmt!("%s%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty, - bound_str) + fmt!("%s%s%s%s%s", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty, + bound_sep, bound_str) } ty_evec(ref mt, vs) => { vstore_ty_to_str(cx, mt, vs) From 7ba1a239a4fc54f101434128e76b370b926cb8ef Mon Sep 17 00:00:00 2001 From: Matthijs Hofstra Date: Sun, 16 Jun 2013 17:50:16 +0200 Subject: [PATCH 095/336] Changed Arena API to make it usable once more. --- src/libextra/arena.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index db4cf564babc..302f1fbeb04a 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -39,7 +39,7 @@ use core::prelude::*; use list::{MutList, MutCons, MutNil}; use core::at_vec; -use core::cast::{transmute, transmute_mut_region}; +use core::cast::{transmute, transmute_mut, transmute_mut_region}; use core::cast; use core::libc::size_t; use core::ptr; @@ -74,6 +74,7 @@ struct Chunk { is_pod: bool, } +#[mutable] pub struct Arena { // The head is separated out from the list as a unbenchmarked // microoptimization, to avoid needing to case on the list to @@ -269,23 +270,22 @@ impl Arena { // The external interface #[inline] - pub fn alloc<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T { + pub fn alloc<'a, T>(&'a self, op: &fn() -> T) -> &'a T { unsafe { // XXX: Borrow check - let this = transmute_mut_region(self); - if !intrinsics::needs_drop::() { - return this.alloc_pod(op); + let this = transmute_mut(self); + if intrinsics::needs_drop::() { + this.alloc_nonpod(op) + } else { + this.alloc_pod(op) } - // XXX: Borrow check - let this = transmute_mut_region(self); - this.alloc_nonpod(op) } } } #[test] fn test_arena_destructors() { - let mut arena = Arena(); + let arena = Arena(); for uint::range(0, 10) |i| { // Arena allocate something with drop glue to make sure it // doesn't leak. @@ -300,7 +300,7 @@ fn test_arena_destructors() { #[should_fail] #[ignore(cfg(windows))] fn test_arena_destructors_fail() { - let mut arena = Arena(); + let arena = Arena(); // Put some stuff in the arena. for uint::range(0, 10) |i| { // Arena allocate something with drop glue to make sure it From 1841b31c61c2cca9c54264edd2a78b994b9638e9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Jun 2013 18:46:34 -0700 Subject: [PATCH 096/336] Add 'static mut' items to the language --- src/librustc/metadata/decoder.rs | 16 ++++--- src/librustc/metadata/encoder.rs | 10 ++-- src/librustc/middle/astencode.rs | 2 +- src/librustc/middle/check_const.rs | 6 +-- src/librustc/middle/check_match.rs | 10 ++-- src/librustc/middle/const_eval.rs | 6 +-- src/librustc/middle/effect.rs | 10 +++- src/librustc/middle/mem_categorization.rs | 28 +++++++---- src/librustc/middle/pat_util.rs | 2 +- src/librustc/middle/resolve.rs | 17 +++---- src/librustc/middle/trans/_match.rs | 9 ++-- src/librustc/middle/trans/base.rs | 12 +++-- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/consts.rs | 12 +++-- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/reachable.rs | 2 +- src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 4 +- src/librustc/middle/typeck/collect.rs | 2 +- src/librustdoc/extract.rs | 2 +- src/librustdoc/tystr_pass.rs | 2 +- src/libsyntax/ast.rs | 4 +- src/libsyntax/ast_map.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/parser.rs | 5 +- src/libsyntax/print/pprust.rs | 5 +- src/libsyntax/visit.rs | 2 +- src/test/auxiliary/static_mut_xc.rs | 1 + src/test/compile-fail/static-mut-bad-types.rs | 17 +++++++ .../compile-fail/static-mut-not-constant.rs | 13 ++++++ src/test/compile-fail/static-mut-not-pat.rs | 26 +++++++++++ .../static-mut-requires-unsafe.rs | 17 +++++++ src/test/run-pass/static-mut-xc.rs | 46 +++++++++++++++++++ 34 files changed, 230 insertions(+), 70 deletions(-) create mode 100644 src/test/auxiliary/static_mut_xc.rs create mode 100644 src/test/compile-fail/static-mut-bad-types.rs create mode 100644 src/test/compile-fail/static-mut-not-constant.rs create mode 100644 src/test/compile-fail/static-mut-not-pat.rs create mode 100644 src/test/compile-fail/static-mut-requires-unsafe.rs create mode 100644 src/test/run-pass/static-mut-xc.rs diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 9ace8677dab7..83e59d980856 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -97,7 +97,8 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc { #[deriving(Eq)] enum Family { - Const, // c + ImmStatic, // c + MutStatic, // b Fn, // f UnsafeFn, // u PureFn, // p @@ -122,7 +123,8 @@ enum Family { fn item_family(item: ebml::Doc) -> Family { let fam = reader::get_doc(item, tag_items_data_item_family); match reader::doc_as_u8(fam) as char { - 'c' => Const, + 'c' => ImmStatic, + 'b' => MutStatic, 'f' => Fn, 'u' => UnsafeFn, 'p' => PureFn, @@ -321,7 +323,8 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) -> def_like { let fam = item_family(item); match fam { - Const => dl_def(ast::def_const(did)), + ImmStatic => dl_def(ast::def_static(did, false)), + MutStatic => dl_def(ast::def_static(did, true)), Struct => dl_def(ast::def_struct(did)), UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)), Fn => dl_def(ast::def_fn(did, ast::impure_fn)), @@ -900,8 +903,8 @@ pub fn get_item_visibility(cdata: cmd, id: ast::node_id) fn family_has_type_params(fam: Family) -> bool { match fam { - Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField - | ForeignFn => false, + ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField + | ForeignFn | MutStatic => false, _ => true } } @@ -931,7 +934,8 @@ fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str { fn item_family_to_str(fam: Family) -> ~str { match fam { - Const => ~"const", + ImmStatic => ~"static", + MutStatic => ~"static mut", Fn => ~"fn", UnsafeFn => ~"unsafe fn", PureFn => ~"pure fn", diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 94cad18ece2c..96cf7284169d 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -785,7 +785,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let must_write = match item.node { item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) | - item_mod(*) | item_foreign_mod(*) | item_const(*) => true, + item_mod(*) | item_foreign_mod(*) | item_static(*) => true, _ => false }; if !must_write && !reachable(ecx, item.id) { return; } @@ -800,11 +800,15 @@ fn encode_info_for_item(ecx: &EncodeContext, ecx.tcx.sess.codemap.span_to_str(item.span)); match item.node { - item_const(_, _) => { + item_static(_, m, _) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_family(ebml_w, 'c'); + if m == ast::m_mutbl { + encode_family(ebml_w, 'b'); + } else { + encode_family(ebml_w, 'c'); + } encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 925b1f506d75..5aad0d894da4 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -384,7 +384,7 @@ impl tr for ast::def { ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) } ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) } ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) } - ast::def_const(did) => { ast::def_const(did.tr(xcx)) } + ast::def_static(did, m) => { ast::def_static(did.tr(xcx), m) } ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) } ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) } ast::def_variant(e_did, v_did) => { diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 126d2db6879d..c1906820883c 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -43,7 +43,7 @@ pub fn check_item(sess: Session, (_is_const, v): (bool, visit::vt)) { match it.node { - item_const(_, ex) => { + item_static(_, _, ex) => { (v.visit_expr)(ex, (true, v)); check_item_recursion(sess, ast_map, def_map, it); } @@ -124,7 +124,7 @@ pub fn check_expr(sess: Session, items without type parameters"); } match def_map.find(&e.id) { - Some(&def_const(_)) | + Some(&def_static(*)) | Some(&def_fn(_, _)) | Some(&def_variant(_, _)) | Some(&def_struct(_)) => { } @@ -237,7 +237,7 @@ pub fn check_item_recursion(sess: Session, match e.node { expr_path(*) => { match env.def_map.find(&e.id) { - Some(&def_const(def_id)) => { + Some(&def_static(def_id, _)) => { if ast_util::is_local(def_id) { match env.ast_map.get_copy(&def_id.node) { ast_map::node_item(it, _) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a25324058707..b4c8a6b19c29 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -304,7 +304,7 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option { pat_ident(_, _, _) | pat_enum(_, _) => { match cx.tcx.def_map.find(&pat.id) { Some(&def_variant(_, id)) => Some(variant(id)), - Some(&def_const(did)) => { + Some(&def_static(did, false)) => { let const_expr = lookup_const_by_id(cx.tcx, did).get(); Some(val(eval_const_expr(cx.tcx, const_expr))) } @@ -339,7 +339,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool { pat_wild => { true } pat_ident(_, _, _) => { match cx.tcx.def_map.find(&pat.id) { - Some(&def_variant(_, _)) | Some(&def_const(*)) => { false } + Some(&def_variant(_, _)) | Some(&def_static(*)) => { false } _ => { true } } } @@ -499,7 +499,7 @@ pub fn specialize(cx: @MatchCheckCtxt, None } } - Some(&def_const(did)) => { + Some(&def_static(did, _)) => { let const_expr = lookup_const_by_id(cx.tcx, did).get(); let e_v = eval_const_expr(cx.tcx, const_expr); @@ -549,7 +549,7 @@ pub fn specialize(cx: @MatchCheckCtxt, } pat_enum(_, args) => { match cx.tcx.def_map.get_copy(&pat_id) { - def_const(did) => { + def_static(did, _) => { let const_expr = lookup_const_by_id(cx.tcx, did).get(); let e_v = eval_const_expr(cx.tcx, const_expr); @@ -790,7 +790,7 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool { return true; } } - Some(&def_const(*)) => return true, + Some(&def_static(*)) => return true, _ => () } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 988ad519f42b..1a7cd856bede 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -166,7 +166,7 @@ pub fn classify(e: @expr, pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> { match tcx.def_map.find(&e.id) { - Some(&ast::def_const(def_id)) => lookup_const_by_id(tcx, def_id), + Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id), _ => None } } @@ -178,7 +178,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, match tcx.items.find(&def_id.node) { None => None, Some(&ast_map::node_item(it, _)) => match it.node { - item_const(_, const_expr) => Some(const_expr), + item_static(_, ast::m_imm, const_expr) => Some(const_expr), _ => None }, Some(_) => None @@ -195,7 +195,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, match csearch::maybe_get_item_ast(tcx, def_id, |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) { csearch::found(ast::ii_item(item)) => match item.node { - item_const(_, const_expr) => Some(const_expr), + item_static(_, ast::m_imm, const_expr) => Some(const_expr), _ => None }, _ => None diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index d9481c26dad0..513b2015a834 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -17,7 +17,7 @@ use middle::typeck::method_map; use util::ppaux; use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call}; -use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn}; +use syntax::ast::{expr_unary, node_id, unsafe_blk, unsafe_fn, expr_path}; use syntax::ast; use syntax::codemap::span; use syntax::visit::{fk_item_fn, fk_method}; @@ -143,6 +143,14 @@ pub fn check_crate(tcx: ty::ctxt, expr_inline_asm(*) => { require_unsafe(expr.span, "use of inline assembly") } + expr_path(*) => { + match ty::resolve_expr(tcx, expr) { + ast::def_static(_, true) => { + require_unsafe(expr.span, "use of mutable static") + } + _ => {} + } + } _ => {} } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 2ced57dc885b..f93cb265d785 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -447,19 +447,29 @@ impl mem_categorization_ctxt { -> cmt { match def { ast::def_fn(*) | ast::def_static_method(*) | ast::def_mod(_) | - ast::def_foreign_mod(_) | ast::def_const(_) | + ast::def_foreign_mod(_) | ast::def_static(_, false) | ast::def_use(_) | ast::def_variant(*) | ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) | ast::def_ty_param(*) | ast::def_struct(*) | ast::def_typaram_binder(*) | ast::def_region(_) | ast::def_label(_) | ast::def_self_ty(*) => { - @cmt_ { - id:id, - span:span, - cat:cat_static_item, - mutbl: McImmutable, - ty:expr_ty - } + @cmt_ { + id:id, + span:span, + cat:cat_static_item, + mutbl: McImmutable, + ty:expr_ty + } + } + + ast::def_static(_, true) => { + @cmt_ { + id:id, + span:span, + cat:cat_static_item, + mutbl: McDeclared, + ty:expr_ty + } } ast::def_arg(vid, mutbl) => { @@ -894,7 +904,7 @@ impl mem_categorization_ctxt { self.cat_pattern(cmt_field, subpat, op); } } - Some(&ast::def_const(*)) => { + Some(&ast::def_static(*)) => { for subpats.iter().advance |&subpat| { self.cat_pattern(cmt, subpat, op); } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 1237e9fb4a26..5bd39e858637 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -45,7 +45,7 @@ pub fn pat_is_const(dm: resolve::DefMap, pat: &pat) -> bool { match pat.node { pat_ident(_, _, None) | pat_enum(*) => { match dm.find(&pat.id) { - Some(&def_const(*)) => true, + Some(&def_static(_, false)) => true, _ => false } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index eed0b12b9e12..7f9086be81d5 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1146,12 +1146,13 @@ impl Resolver { } // These items live in the value namespace. - item_const(*) => { + item_static(_, m, _) => { let (name_bindings, _) = self.add_child(ident, parent, ForbidDuplicateValues, sp); + let mutbl = m == ast::m_mutbl; name_bindings.define_value - (privacy, def_const(local_def(item.id)), sp); + (privacy, def_static(local_def(item.id), mutbl), sp); } item_fn(_, purity, _, _, _) => { let (name_bindings, new_parent) = @@ -1566,7 +1567,7 @@ impl Resolver { } } foreign_item_const(*) => { - let def = def_const(local_def(foreign_item.id)); + let def = def_static(local_def(foreign_item.id), false); name_bindings.define_value(Public, def, foreign_item.span); visit_foreign_item(foreign_item, (new_parent, visitor)); @@ -1673,7 +1674,7 @@ impl Resolver { let privacy = variant_visibility_to_privacy(visibility, true); child_name_bindings.define_value(privacy, def, dummy_sp()); } - def_fn(*) | def_static_method(*) | def_const(*) => { + def_fn(*) | def_static_method(*) | def_static(*) => { debug!("(building reduced graph for external \ crate) building value %s", final_ident); child_name_bindings.define_value(privacy, def, dummy_sp()); @@ -3686,7 +3687,7 @@ impl Resolver { visitor); } - item_const(*) => { + item_static(*) => { self.with_constant_rib(|| { visit_item(item, ((), visitor)); }); @@ -4344,7 +4345,7 @@ impl Resolver { Some(def @ def_struct(*)) => { self.record_def(pattern.id, def); } - Some(def @ def_const(*)) => { + Some(def @ def_static(*)) => { self.enforce_default_binding_mode( pattern, binding_mode, @@ -4376,7 +4377,7 @@ impl Resolver { Some(def @ def_fn(*)) | Some(def @ def_variant(*)) | Some(def @ def_struct(*)) | - Some(def @ def_const(*)) => { + Some(def @ def_static(*)) => { self.record_def(pattern.id, def); } Some(_) => { @@ -4459,7 +4460,7 @@ impl Resolver { def @ def_variant(*) | def @ def_struct(*) => { return FoundStructOrEnumVariant(def); } - def @ def_const(*) => { + def @ def_static(_, false) => { return FoundConst(def); } _ => { diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index ab2f0c84d02e..71b416ffe85f 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -820,7 +820,7 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { add_to_set(ccx.tcx, &mut found, lit(UnitLikeStructLit(cur.id))); } - Some(&ast::def_const(const_did)) => { + Some(&ast::def_static(const_did, false)) => { add_to_set(ccx.tcx, &mut found, lit(ConstLit(const_did))); } @@ -836,7 +836,7 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { add_to_set(ccx.tcx, &mut found, variant_opt(bcx, cur.id)); } - Some(&ast::def_const(const_did)) => { + Some(&ast::def_static(const_did, false)) => { add_to_set(ccx.tcx, &mut found, lit(ConstLit(const_did))); } @@ -1831,8 +1831,9 @@ pub fn bind_irrefutable_pat(bcx: block, } } } - Some(&ast::def_const(*)) => { - bcx = bind_irrefutable_pat(bcx, pat, val, make_copy, binding_mode); + Some(&ast::def_static(_, false)) => { + bcx = bind_irrefutable_pat(bcx, pat, val, make_copy, + binding_mode); } _ => { // Nothing to do here. diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index ec77fe359b59..0f6c7dbe7543 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2122,14 +2122,19 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { trans_enum_def(ccx, enum_definition, item.id, vi, &mut i); } } - ast::item_const(_, expr) => { - consts::trans_const(ccx, expr, item.id); + ast::item_static(_, m, expr) => { + consts::trans_const(ccx, m, item.id); // Do static_assert checking. It can't really be done much earlier because we need to get // the value of the bool out of LLVM for item.attrs.iter().advance |attr| { match attr.node.value.node { ast::meta_word(x) => { if x.slice(0, x.len()) == "static_assert" { + if m == ast::m_mutbl { + ccx.sess.span_fatal(expr.span, + "cannot have static_assert \ + on a mutable static"); + } let v = ccx.const_values.get_copy(&item.id); unsafe { if !(llvm::LLVMConstIntGetZExtValue(v) as bool) { @@ -2398,13 +2403,14 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { let my_path = vec::append(/*bad*/copy *pth, [path_name(i.ident)]); match i.node { - ast::item_const(_, expr) => { + ast::item_static(_, m, expr) => { let typ = ty::node_id_to_type(ccx.tcx, i.id); let s = mangle_exported_name(ccx, my_path, typ); // We need the translated value here, because for enums the // LLVM type is not fully determined by the Rust type. let v = consts::const_expr(ccx, expr); ccx.const_values.insert(id, v); + exprt = m == ast::m_mutbl; unsafe { let llty = llvm::LLVMTypeOf(v); let g = str::as_c_str(s, |buf| { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 6120e1e65810..593d0beb88c7 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -143,7 +143,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee { datum_callee(bcx, ref_expr) } ast::def_mod(*) | ast::def_foreign_mod(*) | ast::def_trait(*) | - ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) | + ast::def_static(*) | ast::def_ty(*) | ast::def_prim_ty(*) | ast::def_use(*) | ast::def_typaram_binder(*) | ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) | ast::def_self_ty(*) => { diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index e40534773c2d..98eb858be55f 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -164,9 +164,9 @@ pub fn get_const_val(cx: @mut CrateContext, mut def_id: ast::def_id) -> ValueRef } match cx.tcx.items.get_copy(&def_id.node) { ast_map::node_item(@ast::item { - node: ast::item_const(_, subexpr), _ + node: ast::item_static(_, ast::m_imm, _), _ }, _) => { - trans_const(cx, subexpr, def_id.node); + trans_const(cx, ast::m_imm, def_id.node); } _ => cx.tcx.sess.bug("expected a const to be an item") } @@ -538,7 +538,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { base::get_item_val(cx, def_id.node) } } - Some(&ast::def_const(def_id)) => { + Some(&ast::def_static(def_id, false)) => { get_const_val(cx, def_id) } Some(&ast::def_variant(enum_did, variant_did)) => { @@ -587,7 +587,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { } } -pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) { +pub fn trans_const(ccx: @mut CrateContext, m: ast::mutability, id: ast::node_id) { unsafe { let _icx = push_ctxt("trans_const"); let g = base::get_item_val(ccx, id); @@ -595,6 +595,8 @@ pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) { // constant's initializer to determine its LLVM type. let v = ccx.const_values.get_copy(&id); llvm::LLVMSetInitializer(g, v); - llvm::LLVMSetGlobalConstant(g, True); + if m != ast::m_mutbl { + llvm::LLVMSetGlobalConstant(g, True); + } } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 7d86f743a8e4..1aebf73b81a8 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -945,7 +945,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let _icx = push_ctxt("trans_def_lvalue"); let ccx = bcx.ccx(); match def { - ast::def_const(did) => { + ast::def_static(did, _) => { let const_ty = expr_ty(bcx, ref_expr); fn get_did(ccx: @mut CrateContext, did: ast::def_id) diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs index 6a40c1f75e9e..e950c24c49e8 100644 --- a/src/librustc/middle/trans/reachable.rs +++ b/src/librustc/middle/trans/reachable.rs @@ -146,7 +146,7 @@ fn traverse_public_item(cx: @mut ctx, item: @item) { visit::mk_vt(@visit::Visitor {visit_ty: traverse_ty, ..*visit::default_visitor()}))) } - item_const(*) | + item_static(*) | item_enum(*) | item_trait(*) => (), item_mac(*) => fail!("item macros unimplemented") } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 90cd8a8665ea..f3c0d4bd8f46 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3269,7 +3269,7 @@ pub fn expr_kind(tcx: ctxt, // Note: there is actually a good case to be made that // def_args, particularly those of immediate type, ought to // considered rvalues. - ast::def_const(*) | + ast::def_static(*) | ast::def_binding(*) | ast::def_upvar(*) | ast::def_arg(*) | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872b..1acf806f21e9 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -585,7 +585,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { let _indenter = indenter(); match it.node { - ast::item_const(_, e) => check_const(ccx, it.span, e, it.id), + ast::item_static(_, _, e) => check_const(ccx, it.span, e, it.id), ast::item_enum(ref enum_definition, _) => { check_enum_variants(ccx, it.span, @@ -3216,7 +3216,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, } ast::def_fn(id, _) | ast::def_static_method(id, _, _) | - ast::def_const(id) | ast::def_variant(_, id) | + ast::def_static(id, _) | ast::def_variant(_, id) | ast::def_struct(id) => { return ty::lookup_item_type(fcx.ccx.tcx, id); } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 7f820d11ac61..aef148830a99 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1060,7 +1060,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_const(t, _) => { + ast::item_static(t, _, _) => { let typ = ccx.to_ty(&empty_rscope, t); let tpt = no_params(typ); tcx.tcache.insert(local_def(it.id), tpt); diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index b6131dce9c85..f12f612b036b 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -102,7 +102,7 @@ fn moddoc_from_mod( fndoc_from_fn(ItemDoc) )) } - ast::item_const(_, _) => { + ast::item_static(*) => { Some(doc::ConstTag( constdoc_from_const(ItemDoc) )) diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index e3abe6e926a5..459daaa468f9 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -96,7 +96,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_const(ty, _), _ + node: ast::item_static(ty, _, _), _ }, _) => { pprust::ty_to_str(ty, extract::interner()) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2e3d557daa90..012a1e76228a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -190,7 +190,7 @@ pub enum def { def_self_ty(/* trait id */ node_id), def_mod(def_id), def_foreign_mod(def_id), - def_const(def_id), + def_static(def_id, bool /* is_mutbl */), def_arg(node_id, bool /* is_mutbl */), def_local(node_id, bool /* is_mutbl */), def_variant(def_id /* enum */, def_id /* variant */), @@ -1095,7 +1095,7 @@ pub struct item { #[deriving(Eq, Encodable, Decodable)] pub enum item_ { - item_const(@Ty, @expr), + item_static(@Ty, mutability, @expr), item_fn(fn_decl, purity, AbiSet, Generics, blk), item_mod(_mod), item_foreign_mod(foreign_mod), diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index a0e1ec69350c..421c4c566b56 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -339,7 +339,7 @@ pub fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { Some(&node_item(item, path)) => { let path_str = path_ident_to_str(path, item.ident, itr); let item_str = match item.node { - item_const(*) => ~"const", + item_static(*) => ~"static", item_fn(*) => ~"fn", item_mod(*) => ~"mod", item_foreign_mod(*) => ~"foreign mod", diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 24cf5662a36b..227d700452b6 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -59,7 +59,7 @@ pub fn variant_def_ids(d: def) -> Option<(def_id, def_id)> { pub fn def_id_of_def(d: def) -> def_id { match d { def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) | - def_foreign_mod(id) | def_const(id) | + def_foreign_mod(id) | def_static(id, _) | def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | def_use(id) | def_struct(id) | def_trait(id) => { id diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4bd2c0a3de1f..8a22dbe9178c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -270,7 +270,7 @@ fn noop_fold_struct_field(sf: @struct_field, fld: @ast_fold) pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { match *i { - item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)), + item_static(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), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f2443f9e5335..a726b3b27d2e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -34,7 +34,7 @@ use ast::{expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; use ast::{expr_vstore_uniq, Onceness, Once, Many}; use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod}; -use ast::{ident, impure_fn, inherited, item, item_, item_const}; +use ast::{ident, impure_fn, inherited, item, item_, item_static}; use ast::{item_enum, item_fn, item_foreign_mod, item_impl}; use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_}; use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int}; @@ -3556,13 +3556,14 @@ impl Parser { } fn parse_item_const(&self) -> item_info { + let m = if self.eat_keyword(keywords::Mut) {m_mutbl} else {m_imm}; let id = self.parse_ident(); self.expect(&token::COLON); let ty = self.parse_ty(false); self.expect(&token::EQ); let e = self.parse_expr(); self.expect(&token::SEMI); - (id, item_const(ty, e), None) + (id, item_static(ty, m, e), None) } // parse a mod { ...} item diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index fa22b7ceb710..c21c0a0afeed 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -477,8 +477,11 @@ pub fn print_item(s: @ps, item: @ast::item) { let ann_node = node_item(s, item); (s.ann.pre)(ann_node); match item.node { - ast::item_const(ty, expr) => { + ast::item_static(ty, m, expr) => { head(s, visibility_qualified(item.vis, "static")); + if m == ast::m_mutbl { + word_space(s, "mut"); + } print_ident(s, item.ident); word_space(s, ":"); print_type(s, ty); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 5aa38c0348c0..fd9350e00051 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -148,7 +148,7 @@ fn visit_trait_ref(tref: @ast::trait_ref, (e, v): (E, vt)) { pub fn visit_item(i: @item, (e, v): (E, vt)) { match i.node { - item_const(t, ex) => { + item_static(t, _, ex) => { (v.visit_ty)(t, (copy e, v)); (v.visit_expr)(ex, (copy e, v)); } diff --git a/src/test/auxiliary/static_mut_xc.rs b/src/test/auxiliary/static_mut_xc.rs new file mode 100644 index 000000000000..8dc45c681bfe --- /dev/null +++ b/src/test/auxiliary/static_mut_xc.rs @@ -0,0 +1 @@ +pub static mut a: int = 3; diff --git a/src/test/compile-fail/static-mut-bad-types.rs b/src/test/compile-fail/static-mut-bad-types.rs new file mode 100644 index 000000000000..7aed3ce30bc5 --- /dev/null +++ b/src/test/compile-fail/static-mut-bad-types.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. + +static mut a: int = 3; + +fn main() { + unsafe { + a = true; //~ ERROR: mismatched types + } +} diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs new file mode 100644 index 000000000000..61d3ed7fd18e --- /dev/null +++ b/src/test/compile-fail/static-mut-not-constant.rs @@ -0,0 +1,13 @@ +// 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. + +static mut a: ~int = ~3; //~ ERROR: disallowed operator in constant + +fn main() {} diff --git a/src/test/compile-fail/static-mut-not-pat.rs b/src/test/compile-fail/static-mut-not-pat.rs new file mode 100644 index 000000000000..997003a28d42 --- /dev/null +++ b/src/test/compile-fail/static-mut-not-pat.rs @@ -0,0 +1,26 @@ +// 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. + +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +static mut a: int = 3; + +fn main() { + // If they can't be matched against, then it's possible to capture the same + // name as a variable, hence this should be an unreachable pattern situation + // instead of spitting out a custom error about some identifier collisions + // (we should allow shadowing) + match 4 { + a => {} + _ => {} //~ ERROR: unreachable pattern + } +} diff --git a/src/test/compile-fail/static-mut-requires-unsafe.rs b/src/test/compile-fail/static-mut-requires-unsafe.rs new file mode 100644 index 000000000000..7337920cce68 --- /dev/null +++ b/src/test/compile-fail/static-mut-requires-unsafe.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. + +static mut a: int = 3; + +fn main() { + a += 3; //~ ERROR: requires unsafe + a = 4; //~ ERROR: requires unsafe + let _b = a; //~ ERROR: requires unsafe +} diff --git a/src/test/run-pass/static-mut-xc.rs b/src/test/run-pass/static-mut-xc.rs new file mode 100644 index 000000000000..72f44fcd5010 --- /dev/null +++ b/src/test/run-pass/static-mut-xc.rs @@ -0,0 +1,46 @@ +// 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. + +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +// xfail-fast +// aux-build:static_mut_xc.rs + +extern mod static_mut_xc; + +unsafe fn static_bound(_: &'static int) {} + +fn static_bound_set(a: &'static mut int) { + *a = 3; +} + +unsafe fn run() { + assert!(static_mut_xc::a == 3); + static_mut_xc::a = 4; + assert!(static_mut_xc::a == 4); + static_mut_xc::a += 1; + assert!(static_mut_xc::a == 5); + static_mut_xc::a *= 3; + assert!(static_mut_xc::a == 15); + static_mut_xc::a = -3; + assert!(static_mut_xc::a == -3); + static_bound(&static_mut_xc::a); + static_bound_set(&mut static_mut_xc::a); +} + +fn main() { + unsafe { run() } +} + +pub mod inner { + pub static mut a: int = 4; +} From 8fdc8f392c3f5d1bdf601756bfe442b7698e6315 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Jun 2013 22:46:27 -0700 Subject: [PATCH 097/336] Support foreign 'static mut' variables as well --- src/librustc/metadata/encoder.rs | 8 +++- src/librustc/middle/lint.rs | 48 ++++++++++--------- src/librustc/middle/resolve.rs | 6 +-- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/foreign.rs | 2 +- src/librustc/middle/typeck/collect.rs | 2 +- src/librustdoc/extract.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/fold.rs | 4 +- src/libsyntax/parse/parser.rs | 5 +- src/libsyntax/print/pprust.rs | 5 +- src/libsyntax/visit.rs | 2 +- src/rt/rust_builtin.cpp | 10 ++++ src/rt/rustrt.def.in | 4 +- .../static-mut-foreign-requires-unsafe.rs | 21 ++++++++ src/test/run-pass/static-mut-foreign.rs | 46 ++++++++++++++++++ 16 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 src/test/compile-fail/static-mut-foreign-requires-unsafe.rs create mode 100644 src/test/run-pass/static-mut-foreign.rs diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 96cf7284169d..7d18bdb77efe 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1111,9 +1111,13 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident)); } - foreign_item_const(*) => { + foreign_item_static(_, mutbl) => { encode_def_id(ebml_w, local_def(nitem.id)); - encode_family(ebml_w, 'c'); + if mutbl { + encode_family(ebml_w, 'b'); + } else { + encode_family(ebml_w, 'c'); + } encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident)); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 821aed731c22..17ff5930078d 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -709,28 +709,31 @@ fn check_item_default_methods(cx: &Context, item: @ast::item) { } fn check_item_ctypes(cx: &Context, it: @ast::item) { + fn check_ty(cx: &Context, ty: @ast::Ty) { + match ty.node { + ast::ty_path(_, _, id) => { + match cx.tcx.def_map.get_copy(&id) { + ast::def_prim_ty(ast::ty_int(ast::ty_i)) => { + cx.span_lint(ctypes, ty.span, + "found rust type `int` in foreign module, while \ + libc::c_int or libc::c_long should be used"); + } + ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => { + cx.span_lint(ctypes, ty.span, + "found rust type `uint` in foreign module, while \ + libc::c_uint or libc::c_ulong should be used"); + } + _ => () + } + } + _ => () + } + } fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { let tys = vec::map(decl.inputs, |a| a.ty ); for vec::each(vec::append_one(tys, decl.output)) |ty| { - match ty.node { - ast::ty_path(_, _, id) => { - match cx.tcx.def_map.get_copy(&id) { - ast::def_prim_ty(ast::ty_int(ast::ty_i)) => { - cx.span_lint(ctypes, ty.span, - "found rust type `int` in foreign module, while \ - libc::c_int or libc::c_long should be used"); - } - ast::def_prim_ty(ast::ty_uint(ast::ty_u)) => { - cx.span_lint(ctypes, ty.span, - "found rust type `uint` in foreign module, while \ - libc::c_uint or libc::c_ulong should be used"); - } - _ => () - } - } - _ => () - } + check_ty(cx, *ty); } } @@ -738,11 +741,10 @@ fn check_item_ctypes(cx: &Context, it: @ast::item) { ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => { for nmod.items.iter().advance |ni| { match ni.node { - ast::foreign_item_fn(ref decl, _, _) => { - check_foreign_fn(cx, decl); - } - // FIXME #4622: Not implemented. - ast::foreign_item_const(*) => {} + ast::foreign_item_fn(ref decl, _, _) => { + check_foreign_fn(cx, decl); + } + ast::foreign_item_static(t, _) => { check_ty(cx, t); } } } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 7f9086be81d5..ed385ae54215 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1566,8 +1566,8 @@ impl Resolver { visit_foreign_item(foreign_item, (new_parent, visitor)); } } - foreign_item_const(*) => { - let def = def_static(local_def(foreign_item.id), false); + foreign_item_static(_, m) => { + let def = def_static(local_def(foreign_item.id), m); name_bindings.define_value(Public, def, foreign_item.span); visit_foreign_item(foreign_item, (new_parent, visitor)); @@ -3665,7 +3665,7 @@ impl Resolver { || visit_foreign_item(*foreign_item, ((), visitor))); } - foreign_item_const(_) => { + foreign_item_static(*) => { visit_foreign_item(*foreign_item, ((), visitor)); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0f6c7dbe7543..0e322c187af2 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2463,7 +2463,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { ni.id, ni.attrs) } - ast::foreign_item_const(*) => { + ast::foreign_item_static(*) => { let typ = ty::node_id_to_type(ccx.tcx, ni.id); let ident = token::ident_to_str(&ni.ident); let g = do str::as_c_str(ident) |buf| { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 10e63e6af777..54bfc25244f0 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -332,7 +332,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, } } } - ast::foreign_item_const(*) => { + ast::foreign_item_static(*) => { let ident = token::ident_to_str(&foreign_item.ident); ccx.item_symbols.insert(foreign_item.id, /* bad */ident.to_owned()); } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index aef148830a99..33e483e552a7 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1153,7 +1153,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, generics, abis) } - ast::foreign_item_const(t) => { + ast::foreign_item_static(t, _) => { ty::ty_param_bounds_and_ty { generics: ty::Generics { type_param_defs: @~[], diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index f12f612b036b..b7b2b70769bb 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -150,7 +150,7 @@ fn nmoddoc_from_mod( ast::foreign_item_fn(*) => { fns.push(fndoc_from_fn(ItemDoc)); } - ast::foreign_item_const(*) => {} // XXX: Not implemented. + ast::foreign_item_static(*) => {} // XXX: Not implemented. } } doc::NmodDoc { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 012a1e76228a..c7f3b41475f0 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1124,7 +1124,7 @@ pub struct foreign_item { #[deriving(Eq, Encodable, Decodable)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), - foreign_item_const(@Ty) + 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/fold.rs b/src/libsyntax/fold.rs index 8a22dbe9178c..25839fb46339 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -236,8 +236,8 @@ fn noop_fold_foreign_item(ni: @foreign_item, fld: @ast_fold) purity, fold_generics(generics, fld)) } - foreign_item_const(t) => { - foreign_item_const(fld.fold_ty(t)) + foreign_item_static(t, m) => { + foreign_item_static(fld.fold_ty(t), m) } }, id: fld.new_id(ni.id), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a726b3b27d2e..cc4a1f457226 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -33,7 +33,7 @@ use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; use ast::{expr_vstore_uniq, Onceness, Once, Many}; -use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod}; +use ast::{foreign_item, foreign_item_static, foreign_item_fn, foreign_mod}; use ast::{ident, impure_fn, inherited, item, item_, item_static}; use ast::{item_enum, item_fn, item_foreign_mod, item_impl}; use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_}; @@ -3684,6 +3684,7 @@ impl Parser { } else { self.expect_keyword(keywords::Static); } + let mutbl = self.eat_keyword(keywords::Mut); let ident = self.parse_ident(); self.expect(&token::COLON); @@ -3692,7 +3693,7 @@ impl Parser { self.expect(&token::SEMI); @ast::foreign_item { ident: ident, attrs: attrs, - node: foreign_item_const(ty), + node: foreign_item_static(ty, mutbl), id: self.get_id(), span: mk_sp(lo, hi), vis: vis } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c21c0a0afeed..1a3155337a5e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -458,8 +458,11 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { word(s.s, ";"); end(s); // end the outer fn box } - ast::foreign_item_const(t) => { + ast::foreign_item_static(t, m) => { head(s, "static"); + if m { + word_space(s, "mut"); + } print_ident(s, item.ident); word_space(s, ":"); print_type(s, t); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index fd9350e00051..d7914832835a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -326,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_const(t) => { + foreign_item_static(t, _) => { (v.visit_ty)(t, (e, v)); } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index e476fa0ad5e0..6ae5e978106e 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -154,6 +154,16 @@ debug_abi_2(floats f) { return ff; } +extern "C" int +debug_static_mut; + +int debug_static_mut = 3; + +extern "C" void +debug_static_mut_check_four() { + assert(debug_static_mut == 4); +} + /* Debug builtins for std::dbg. */ static void diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ba7ada04a275..505de6e20b70 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -7,6 +7,8 @@ debug_tydesc debug_get_stk_seg debug_abi_1 debug_abi_2 +debug_static_mut +debug_static_mut_check_four get_task_id get_time rust_tzset @@ -239,4 +241,4 @@ rust_valgrind_stack_deregister rust_take_env_lock rust_drop_env_lock rust_update_log_settings -rust_running_on_valgrind \ No newline at end of file +rust_running_on_valgrind diff --git a/src/test/compile-fail/static-mut-foreign-requires-unsafe.rs b/src/test/compile-fail/static-mut-foreign-requires-unsafe.rs new file mode 100644 index 000000000000..7b371cf708dc --- /dev/null +++ b/src/test/compile-fail/static-mut-foreign-requires-unsafe.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. + +use std::libc; + +extern { + static mut a: libc::c_int; +} + +fn main() { + a += 3; //~ ERROR: requires unsafe + a = 4; //~ ERROR: requires unsafe + let _b = a; //~ ERROR: requires unsafe +} diff --git a/src/test/run-pass/static-mut-foreign.rs b/src/test/run-pass/static-mut-foreign.rs new file mode 100644 index 000000000000..66d34c7e454d --- /dev/null +++ b/src/test/run-pass/static-mut-foreign.rs @@ -0,0 +1,46 @@ +// 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. + +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +use std::libc; + +#[nolink] +extern { + static mut debug_static_mut: libc::c_int; + pub fn debug_static_mut_check_four(); +} + +unsafe fn static_bound(_: &'static libc::c_int) {} + +fn static_bound_set(a: &'static mut libc::c_int) { + *a = 3; +} + +unsafe fn run() { + assert!(debug_static_mut == 3); + debug_static_mut = 4; + assert!(debug_static_mut == 4); + debug_static_mut_check_four(); + debug_static_mut += 1; + assert!(debug_static_mut == 5); + debug_static_mut *= 3; + assert!(debug_static_mut == 15); + debug_static_mut = -3; + assert!(debug_static_mut == -3); + static_bound(&debug_static_mut); + static_bound_set(&mut debug_static_mut); +} + +fn main() { + unsafe { run() } +} From c5400a8830c0115af06c1a5fe4d04f6ba5f6751d Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Sun, 23 Jun 2013 18:54:44 -0400 Subject: [PATCH 098/336] Create a crypto submodule and move the SHA-1 implementation into it. --- src/libextra/{ => crypto}/sha1.rs | 0 src/libextra/std.rc | 5 ++++- 2 files changed, 4 insertions(+), 1 deletion(-) rename src/libextra/{ => crypto}/sha1.rs (100%) diff --git a/src/libextra/sha1.rs b/src/libextra/crypto/sha1.rs similarity index 100% rename from src/libextra/sha1.rs rename to src/libextra/crypto/sha1.rs diff --git a/src/libextra/std.rc b/src/libextra/std.rc index d4c85ef51362..98305e2766a0 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -86,13 +86,16 @@ pub mod sort; pub mod dlist; pub mod treemap; +// Crypto +#[path="crypto/sha1.rs"] +pub mod sha1; + // And ... other stuff pub mod ebml; pub mod dbg; pub mod getopts; pub mod json; -pub mod sha1; pub mod md4; pub mod tempfile; pub mod term; From e1b8c6758099b634ea9033f97ddcd3fa88b5abeb Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Sun, 23 Jun 2013 18:57:59 -0400 Subject: [PATCH 099/336] Improve the SHA-1 implementation * Rename struct Sha1State to Sha1 * Remove all use of @ types * Use fixed length vectors * Move all of the inner functions from inside sha1() to top level, private functions * Sha1 instances are now created via Sha1::new() * Update all constant names to uppercase * Remove unecessary assert_eq!s * Remove check_vec_eq() helper function; use vec::eq() instead --- src/libextra/crypto/sha1.rs | 447 +++++++++++++++++------------------- src/libextra/workcache.rs | 6 +- 2 files changed, 211 insertions(+), 242 deletions(-) diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 84b48c87890b..01e210803cf3 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -25,7 +25,6 @@ use core::prelude::*; use core::uint; -use core::vec; /* * A SHA-1 implementation derived from Paul E. Jones's reference @@ -33,250 +32,230 @@ use core::vec; * point this will want to be rewritten. */ -/// The SHA-1 interface -trait Sha1 { - /// Provide message input as bytes - fn input(&mut self, &[u8]); - /// Provide message input as string - fn input_str(&mut self, &str); - /** - * Read the digest as a vector of 20 bytes. After calling this no further - * input may be provided until reset is called. - */ - fn result(&mut self) -> ~[u8]; - /** - * Read the digest as a hex string. After calling this no further - * input may be provided until reset is called. - */ - fn result_str(&mut self) -> ~str; - /// Reset the SHA-1 state for reuse - fn reset(&mut self); +// Some unexported constants +static DIGEST_BUF_LEN: uint = 5u; +static MSG_BLOCK_LEN: uint = 64u; +static WORK_BUF_LEN: uint = 80u; +static K0: u32 = 0x5A827999u32; +static K1: u32 = 0x6ED9EBA1u32; +static K2: u32 = 0x8F1BBCDCu32; +static K3: u32 = 0xCA62C1D6u32; + +/// Structure representing the state of a Sha1 computation +pub struct Sha1 { + priv h: [u32, ..DIGEST_BUF_LEN], + priv len_low: u32, + priv len_high: u32, + priv msg_block: [u8, ..MSG_BLOCK_LEN], + priv msg_block_idx: uint, + priv computed: bool, + priv work_buf: [u32, ..WORK_BUF_LEN] } -// Some unexported constants -static digest_buf_len: uint = 5u; -static msg_block_len: uint = 64u; -static work_buf_len: uint = 80u; -static k0: u32 = 0x5A827999u32; -static k1: u32 = 0x6ED9EBA1u32; -static k2: u32 = 0x8F1BBCDCu32; -static k3: u32 = 0xCA62C1D6u32; - - -/// Construct a `sha` object -pub fn sha1() -> @Sha1 { - struct Sha1State - { h: ~[u32], - len_low: u32, - len_high: u32, - msg_block: ~[u8], - msg_block_idx: uint, - computed: bool, - work_buf: @mut ~[u32]}; - - fn add_input(st: &mut Sha1State, msg: &[u8]) { - assert!((!st.computed)); - for msg.iter().advance |element| { - st.msg_block[st.msg_block_idx] = *element; - st.msg_block_idx += 1u; - st.len_low += 8u32; - if st.len_low == 0u32 { - st.len_high += 1u32; - if st.len_high == 0u32 { - // FIXME: Need better failure mode (#2346) - fail!(); - } +fn add_input(st: &mut Sha1, msg: &[u8]) { + assert!((!st.computed)); + for msg.iter().advance |element| { + st.msg_block[st.msg_block_idx] = *element; + st.msg_block_idx += 1; + st.len_low += 8; + if st.len_low == 0 { + st.len_high += 1; + if st.len_high == 0 { + // FIXME: Need better failure mode (#2346) + fail!(); } - if st.msg_block_idx == msg_block_len { process_msg_block(st); } } + if st.msg_block_idx == MSG_BLOCK_LEN { process_msg_block(st); } } - fn process_msg_block(st: &mut Sha1State) { - assert_eq!(st.h.len(), digest_buf_len); - assert_eq!(st.work_buf.len(), work_buf_len); - let mut t: int; // Loop counter - let w = st.work_buf; +} - // Initialize the first 16 words of the vector w - t = 0; - while t < 16 { - let mut tmp; - tmp = (st.msg_block[t * 4] as u32) << 24u32; - tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32; - tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32; - tmp = tmp | (st.msg_block[t * 4 + 3] as u32); - w[t] = tmp; - t += 1; - } +fn process_msg_block(st: &mut Sha1) { + let mut t: int; // Loop counter + let mut w = st.work_buf; - // Initialize the rest of vector w - while t < 80 { - let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; - w[t] = circular_shift(1u32, val); - t += 1; - } - let mut a = st.h[0]; - let mut b = st.h[1]; - let mut c = st.h[2]; - let mut d = st.h[3]; - let mut e = st.h[4]; - let mut temp: u32; - t = 0; - while t < 20 { - temp = circular_shift(5u32, a) + (b & c | !b & d) + e + w[t] + k0; - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - while t < 40 { - temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k1; - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - while t < 60 { - temp = - circular_shift(5u32, a) + (b & c | b & d | c & d) + e + w[t] + - k2; - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - while t < 80 { - temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k3; - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - st.h[0] = st.h[0] + a; - st.h[1] = st.h[1] + b; - st.h[2] = st.h[2] + c; - st.h[3] = st.h[3] + d; - st.h[4] = st.h[4] + e; - st.msg_block_idx = 0u; - } - fn circular_shift(bits: u32, word: u32) -> u32 { - return word << bits | word >> 32u32 - bits; - } - fn mk_result(st: &mut Sha1State) -> ~[u8] { - if !(*st).computed { pad_msg(st); (*st).computed = true; } - let mut rs: ~[u8] = ~[]; - for st.h.mut_iter().advance |ptr_hpart| { - let hpart = *ptr_hpart; - let a = (hpart >> 24u32 & 0xFFu32) as u8; - let b = (hpart >> 16u32 & 0xFFu32) as u8; - let c = (hpart >> 8u32 & 0xFFu32) as u8; - let d = (hpart & 0xFFu32) as u8; - rs = vec::append(copy rs, [a, b, c, d]); - } - return rs; + // Initialize the first 16 words of the vector w + t = 0; + while t < 16 { + let mut tmp; + tmp = (st.msg_block[t * 4] as u32) << 24u32; + tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32; + tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32; + tmp = tmp | (st.msg_block[t * 4 + 3] as u32); + w[t] = tmp; + t += 1; } + // Initialize the rest of vector w + while t < 80 { + let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; + w[t] = circular_shift(1, val); + t += 1; + } + let mut a = st.h[0]; + let mut b = st.h[1]; + let mut c = st.h[2]; + let mut d = st.h[3]; + let mut e = st.h[4]; + let mut temp: u32; + t = 0; + while t < 20 { + temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0; + e = d; + d = c; + c = circular_shift(30, b); + b = a; + a = temp; + t += 1; + } + while t < 40 { + temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1; + e = d; + d = c; + c = circular_shift(30, b); + b = a; + a = temp; + t += 1; + } + while t < 60 { + temp = + circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] + + K2; + e = d; + d = c; + c = circular_shift(30, b); + b = a; + a = temp; + t += 1; + } + while t < 80 { + temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3; + e = d; + d = c; + c = circular_shift(30, b); + b = a; + a = temp; + t += 1; + } + st.h[0] = st.h[0] + a; + st.h[1] = st.h[1] + b; + st.h[2] = st.h[2] + c; + st.h[3] = st.h[3] + d; + st.h[4] = st.h[4] + e; + st.msg_block_idx = 0; +} + +fn circular_shift(bits: u32, word: u32) -> u32 { + return word << bits | word >> 32u32 - bits; +} + +fn mk_result(st: &mut Sha1) -> ~[u8] { + if !st.computed { pad_msg(st); st.computed = true; } + let mut rs: ~[u8] = ~[]; + for st.h.mut_iter().advance |ptr_hpart| { + let hpart = *ptr_hpart; + let a = (hpart >> 24u32 & 0xFFu32) as u8; + let b = (hpart >> 16u32 & 0xFFu32) as u8; + let c = (hpart >> 8u32 & 0xFFu32) as u8; + let d = (hpart & 0xFFu32) as u8; + rs = vec::append(copy rs, [a, b, c, d]); + } + return rs; +} + +/* + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 bits + * represent the length of the original message. All bits in between + * should be 0. This function will pad the message according to those + * rules by filling the msg_block vector accordingly. It will also + * call process_msg_block() appropriately. When it returns, it + * can be assumed that the message digest has been computed. + */ +fn pad_msg(st: &mut Sha1) { /* - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 bits - * represent the length of the original message. All bits in between - * should be 0. This function will pad the message according to those - * rules by filling the msg_block vector accordingly. It will also - * call process_msg_block() appropriately. When it returns, it - * can be assumed that the message digest has been computed. + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second block. */ - fn pad_msg(st: &mut Sha1State) { - assert_eq!((*st).msg_block.len(), msg_block_len); - - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second block. - */ - if (*st).msg_block_idx > 55u { - (*st).msg_block[(*st).msg_block_idx] = 0x80u8; - (*st).msg_block_idx += 1u; - while (*st).msg_block_idx < msg_block_len { - (*st).msg_block[(*st).msg_block_idx] = 0u8; - (*st).msg_block_idx += 1u; - } - process_msg_block(st); - } else { - (*st).msg_block[(*st).msg_block_idx] = 0x80u8; - (*st).msg_block_idx += 1u; + if st.msg_block_idx > 55 { + st.msg_block[st.msg_block_idx] = 0x80; + st.msg_block_idx += 1; + while st.msg_block_idx < MSG_BLOCK_LEN { + st.msg_block[st.msg_block_idx] = 0; + st.msg_block_idx += 1; } - while (*st).msg_block_idx < 56u { - (*st).msg_block[(*st).msg_block_idx] = 0u8; - (*st).msg_block_idx += 1u; - } - - // Store the message length as the last 8 octets - (*st).msg_block[56] = ((*st).len_high >> 24u32 & 0xFFu32) as u8; - (*st).msg_block[57] = ((*st).len_high >> 16u32 & 0xFFu32) as u8; - (*st).msg_block[58] = ((*st).len_high >> 8u32 & 0xFFu32) as u8; - (*st).msg_block[59] = ((*st).len_high & 0xFFu32) as u8; - (*st).msg_block[60] = ((*st).len_low >> 24u32 & 0xFFu32) as u8; - (*st).msg_block[61] = ((*st).len_low >> 16u32 & 0xFFu32) as u8; - (*st).msg_block[62] = ((*st).len_low >> 8u32 & 0xFFu32) as u8; - (*st).msg_block[63] = ((*st).len_low & 0xFFu32) as u8; process_msg_block(st); + } else { + st.msg_block[st.msg_block_idx] = 0x80; + st.msg_block_idx += 1; + } + while st.msg_block_idx < 56 { + st.msg_block[st.msg_block_idx] = 0u8; + st.msg_block_idx += 1; } - impl Sha1 for Sha1State { - fn reset(&mut self) { - assert_eq!(self.h.len(), digest_buf_len); - self.len_low = 0u32; - self.len_high = 0u32; - self.msg_block_idx = 0u; - self.h[0] = 0x67452301u32; - self.h[1] = 0xEFCDAB89u32; - self.h[2] = 0x98BADCFEu32; - self.h[3] = 0x10325476u32; - self.h[4] = 0xC3D2E1F0u32; - self.computed = false; - } - fn input(&mut self, msg: &[u8]) { add_input(self, msg); } - fn input_str(&mut self, msg: &str) { - add_input(self, msg.as_bytes()); - } - fn result(&mut self) -> ~[u8] { return mk_result(self); } - fn result_str(&mut self) -> ~str { - let rr = mk_result(self); - let mut s = ~""; - for rr.iter().advance |b| { - let hex = uint::to_str_radix(*b as uint, 16u); - if hex.len() == 1 { - s += "0"; - } - s += hex; - } - return s; - } + // Store the message length as the last 8 octets + st.msg_block[56] = (st.len_high >> 24u32 & 0xFFu32) as u8; + st.msg_block[57] = (st.len_high >> 16u32 & 0xFFu32) as u8; + st.msg_block[58] = (st.len_high >> 8u32 & 0xFFu32) as u8; + st.msg_block[59] = (st.len_high & 0xFFu32) as u8; + st.msg_block[60] = (st.len_low >> 24u32 & 0xFFu32) as u8; + st.msg_block[61] = (st.len_low >> 16u32 & 0xFFu32) as u8; + st.msg_block[62] = (st.len_low >> 8u32 & 0xFFu32) as u8; + st.msg_block[63] = (st.len_low & 0xFFu32) as u8; + process_msg_block(st); +} + +impl Sha1 { + /// Construct a `sha` object + pub fn new() -> Sha1 { + let mut st = Sha1 { + h: [0u32, ..DIGEST_BUF_LEN], + len_low: 0u32, + len_high: 0u32, + msg_block: [0u8, ..MSG_BLOCK_LEN], + msg_block_idx: 0, + computed: false, + work_buf: [0u32, ..WORK_BUF_LEN] + }; + st.reset(); + return st; + } + pub fn reset(&mut self) { + self.len_low = 0; + self.len_high = 0; + self.msg_block_idx = 0; + self.h[0] = 0x67452301u32; + self.h[1] = 0xEFCDAB89u32; + self.h[2] = 0x98BADCFEu32; + self.h[3] = 0x10325476u32; + self.h[4] = 0xC3D2E1F0u32; + self.computed = false; + } + pub fn input(&mut self, msg: &[u8]) { add_input(self, msg); } + pub fn input_str(&mut self, msg: &str) { + add_input(self, msg.as_bytes()); + } + pub fn result(&mut self) -> ~[u8] { return mk_result(self); } + pub fn result_str(&mut self) -> ~str { + let rr = mk_result(self); + let mut s = ~""; + for rr.iter().advance() |b| { + let hex = uint::to_str_radix(*b as uint, 16u); + if hex.len() == 1 { + s += "0"; + } + s += hex; + } + return s; } - let st = Sha1State { - h: vec::from_elem(digest_buf_len, 0u32), - len_low: 0u32, - len_high: 0u32, - msg_block: vec::from_elem(msg_block_len, 0u8), - msg_block_idx: 0u, - computed: false, - work_buf: @mut vec::from_elem(work_buf_len, 0u32) - }; - let mut sh = @st as @Sha1; - sh.reset(); - return sh; } #[cfg(test)] mod tests { - use sha1; + use core::vec; + + use sha1::Sha1; #[test] fn test() { @@ -361,24 +340,14 @@ mod tests { }, ]; let tests = fips_180_1_tests + wikipedia_tests; - fn check_vec_eq(v0: ~[u8], v1: ~[u8]) { - assert_eq!(v0.len(), v1.len()); - let len = v0.len(); - let mut i = 0u; - while i < len { - let a = v0[i]; - let b = v1[i]; - assert_eq!(a, b); - i += 1u; - } - } + // Test that it works when accepting the message all at once - let mut sh = sha1::sha1(); + let mut sh = ~Sha1::new(); for tests.iter().advance |t| { sh.input_str(t.input); let out = sh.result(); - check_vec_eq(copy t.output, out); + assert!(vec::eq(t.output, out)); let out_str = sh.result_str(); assert_eq!(out_str.len(), 40); @@ -398,7 +367,7 @@ mod tests { left = left - take; } let out = sh.result(); - check_vec_eq(copy t.output, out); + assert!(vec::eq(t.output, out)); let out_str = sh.result_str(); assert_eq!(out_str.len(), 40); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 63c89ebf5865..2ebf00c485ef 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -13,7 +13,7 @@ use core::prelude::*; use json; -use sha1; +use sha1::Sha1; use serialize::{Encoder, Encodable, Decoder, Decodable}; use sort; @@ -248,13 +248,13 @@ fn json_decode>(s: &str) -> T { } fn digest>(t: &T) -> ~str { - let mut sha = sha1::sha1(); + let mut sha = Sha1::new(); sha.input_str(json_encode(t)); sha.result_str() } fn digest_file(path: &Path) -> ~str { - let mut sha = sha1::sha1(); + let mut sha = Sha1::new(); let s = io::read_whole_file_str(path); sha.input_str(*s.get_ref()); sha.result_str() From 89eef0b139f0d16844155429a65fc1ac2ea4cd9f Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Sun, 23 Jun 2013 19:03:59 -0400 Subject: [PATCH 100/336] Create a Digest trait for common methods on digests and convert the SHA-1 implementation to use it. The DigestUtil trait was created for helper methods since default methods still have issues. --- src/libextra/crypto/digest.rs | 88 +++++++++++++++++++++++++++++++++++ src/libextra/crypto/sha1.rs | 53 +++++++++------------ src/libextra/std.rc | 2 + src/libextra/workcache.rs | 13 +++--- 4 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 src/libextra/crypto/digest.rs diff --git a/src/libextra/crypto/digest.rs b/src/libextra/crypto/digest.rs new file mode 100644 index 000000000000..8fd44bfc9abc --- /dev/null +++ b/src/libextra/crypto/digest.rs @@ -0,0 +1,88 @@ +// 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. + +use core::prelude::*; + +use core::uint; +use core::vec; + +/** + * The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2 + * family of digest functions. + */ +pub trait Digest { + /** + * Provide message data. + * + * # Arguments + * + * * input - A vector of message data + */ + fn input(&mut self, input: &[u8]); + + /** + * Retrieve the digest result. This method may be called multiple times. + */ + fn result(&mut self, out: &mut [u8]); + + /** + * Reset the digest. This method must be called after result() and before supplying more + * data. + */ + fn reset(&mut self); + + /** + * Get the output size in bits. + */ + fn output_bits(&self) -> uint; +} + +fn to_hex(rr: &[u8]) -> ~str { + let mut s = ~""; + for rr.iter().advance() |b| { + let hex = uint::to_str_radix(*b as uint, 16u); + if hex.len() == 1 { + s += "0"; + } + s += hex; + } + return s; +} + +/// Contains utility methods for Digests. +/// FIXME: #7339: Convert to default methods when issues with them are resolved. +pub trait DigestUtil { + /** + * Convenience functon that feeds a string into a digest + * + * # Arguments + * + * * in The string to feed into the digest + */ + fn input_str(&mut self, in: &str); + + /** + * Convenience functon that retrieves the result of a digest as a + * ~str in hexadecimal format. + */ + fn result_str(&mut self) -> ~str; +} + +impl DigestUtil for D { + fn input_str(&mut self, in: &str) { + self.input(in.as_bytes()); + } + + fn result_str(&mut self) -> ~str { + let mut buf = vec::from_elem((self.output_bits()+7)/8, 0u8); + self.result(buf); + return to_hex(buf); + } +} diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 01e210803cf3..5a67e08c1900 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -24,7 +24,7 @@ use core::prelude::*; -use core::uint; +use digest::Digest; /* * A SHA-1 implementation derived from Paul E. Jones's reference @@ -148,18 +148,17 @@ fn circular_shift(bits: u32, word: u32) -> u32 { return word << bits | word >> 32u32 - bits; } -fn mk_result(st: &mut Sha1) -> ~[u8] { +fn mk_result(st: &mut Sha1, rs: &mut [u8]) { if !st.computed { pad_msg(st); st.computed = true; } - let mut rs: ~[u8] = ~[]; + let mut i = 0; for st.h.mut_iter().advance |ptr_hpart| { let hpart = *ptr_hpart; - let a = (hpart >> 24u32 & 0xFFu32) as u8; - let b = (hpart >> 16u32 & 0xFFu32) as u8; - let c = (hpart >> 8u32 & 0xFFu32) as u8; - let d = (hpart & 0xFFu32) as u8; - rs = vec::append(copy rs, [a, b, c, d]); + rs[i] = (hpart >> 24u32 & 0xFFu32) as u8; + rs[i+1] = (hpart >> 16u32 & 0xFFu32) as u8; + rs[i+2] = (hpart >> 8u32 & 0xFFu32) as u8; + rs[i+3] = (hpart & 0xFFu32) as u8; + i += 4; } - return rs; } /* @@ -221,6 +220,9 @@ impl Sha1 { st.reset(); return st; } +} + +impl Digest for Sha1 { pub fn reset(&mut self) { self.len_low = 0; self.len_high = 0; @@ -233,28 +235,15 @@ impl Sha1 { self.computed = false; } pub fn input(&mut self, msg: &[u8]) { add_input(self, msg); } - pub fn input_str(&mut self, msg: &str) { - add_input(self, msg.as_bytes()); - } - pub fn result(&mut self) -> ~[u8] { return mk_result(self); } - pub fn result_str(&mut self) -> ~str { - let rr = mk_result(self); - let mut s = ~""; - for rr.iter().advance() |b| { - let hex = uint::to_str_radix(*b as uint, 16u); - if hex.len() == 1 { - s += "0"; - } - s += hex; - } - return s; - } + pub fn result(&mut self, out: &mut [u8]) { return mk_result(self, out); } + pub fn output_bits(&self) -> uint { 160 } } #[cfg(test)] mod tests { use core::vec; + use digest::{Digest, DigestUtil}; use sha1::Sha1; #[test] @@ -343,13 +332,15 @@ mod tests { // Test that it works when accepting the message all at once + let mut out = [0u8, ..20]; + let mut sh = ~Sha1::new(); for tests.iter().advance |t| { - sh.input_str(t.input); - let out = sh.result(); + (*sh).input_str(t.input); + sh.result(out); assert!(vec::eq(t.output, out)); - let out_str = sh.result_str(); + let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); assert!(out_str == t.output_str); @@ -363,13 +354,13 @@ mod tests { let mut left = len; while left > 0u { let take = (left + 1u) / 2u; - sh.input_str(t.input.slice(len - left, take + len - left)); + (*sh).input_str(t.input.slice(len - left, take + len - left)); left = left - take; } - let out = sh.result(); + sh.result(out); assert!(vec::eq(t.output, out)); - let out_str = sh.result_str(); + let out_str = (*sh).result_str(); assert_eq!(out_str.len(), 40); assert!(out_str == t.output_str); diff --git a/src/libextra/std.rc b/src/libextra/std.rc index 98305e2766a0..dbc3095ae275 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -87,6 +87,8 @@ pub mod dlist; pub mod treemap; // Crypto +#[path="crypto/digest.rs"] +pub mod digest; #[path="crypto/sha1.rs"] pub mod sha1; diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 2ebf00c485ef..ed675bf99e9d 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -12,6 +12,7 @@ use core::prelude::*; +use digest::DigestUtil; use json; use sha1::Sha1; use serialize::{Encoder, Encodable, Decoder, Decodable}; @@ -248,16 +249,16 @@ fn json_decode>(s: &str) -> T { } fn digest>(t: &T) -> ~str { - let mut sha = Sha1::new(); - sha.input_str(json_encode(t)); - sha.result_str() + let mut sha = ~Sha1::new(); + (*sha).input_str(json_encode(t)); + (*sha).result_str() } fn digest_file(path: &Path) -> ~str { - let mut sha = Sha1::new(); + let mut sha = ~Sha1::new(); let s = io::read_whole_file_str(path); - sha.input_str(*s.get_ref()); - sha.result_str() + (*sha).input_str(*s.get_ref()); + (*sha).result_str() } impl Context { From 711273f5b49bacb843d672884522cd6961037669 Mon Sep 17 00:00:00 2001 From: Palmer Cox Date: Sun, 23 Jun 2013 19:16:57 -0400 Subject: [PATCH 101/336] Implement the fixed output size versions of the SHA-2 digest functions. --- RELEASES.txt | 1 + src/libextra/crypto/sha2.rs | 1125 +++++++++++++++++++++++++++++++++++ src/libextra/std.rc | 2 + 3 files changed, 1128 insertions(+) create mode 100644 src/libextra/crypto/sha2.rs diff --git a/RELEASES.txt b/RELEASES.txt index 9777245e40c9..60169b347ad8 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -78,6 +78,7 @@ Version 0.7 (July 2013) * extra: `BigInt`, `BigUint` implement numeric and comparison traits. * extra: `term` uses terminfo now, is more correct. * extra: `arc` functions converted to methods. + * extra: Implementation of fixed output size variations of SHA-2. * Tooling * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks. diff --git a/src/libextra/crypto/sha2.rs b/src/libextra/crypto/sha2.rs new file mode 100644 index 000000000000..dd179fde70f5 --- /dev/null +++ b/src/libextra/crypto/sha2.rs @@ -0,0 +1,1125 @@ +// 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. + +use core::prelude::*; + +use core::uint; +use core::vec; + +use digest::Digest; + +// BitCounter is a specialized structure intended simply for counting the +// number of bits that have been processed by the SHA-2 512 family of functions. +// It does very little overflow checking since such checking is not necessary +// for how it is used. A more generic structure would have to do this checking. +// So, don't copy this structure and use it elsewhere! +struct BitCounter { + high_bit_count: u64, + low_byte_count: u64 +} + +impl BitCounter { + fn add_bytes(&mut self, bytes: uint) { + self.low_byte_count += bytes as u64; + if(self.low_byte_count > 0x1fffffffffffffffu64) { + self.high_bit_count += (self.low_byte_count >> 61); + self.low_byte_count &= 0x1fffffffffffffffu64; + } + } + + fn reset(&mut self) { + self.low_byte_count = 0; + self.high_bit_count = 0; + } + + fn get_low_bit_count(&self) -> u64 { + self.low_byte_count << 3 + } + + fn get_high_bit_count(&self) -> u64 { + self.high_bit_count + } +} + +// A structure that represents that state of a digest computation +// for the SHA-2 512 family of digest functions +struct Engine512 { + input_buffer: [u8, ..8], + input_buffer_idx: uint, + bit_counter: BitCounter, + H0: u64, + H1: u64, + H2: u64, + H3: u64, + H4: u64, + H5: u64, + H6: u64, + H7: u64, + W: [u64, ..80], + W_idx: uint, + finished: bool, +} + +// Convert a [u8] to a u64 in big-endian format +fn to_u64(in: &[u8]) -> u64 { + (in[0] as u64) << 56 | + (in[1] as u64) << 48 | + (in[2] as u64) << 40 | + (in[3] as u64) << 32 | + (in[4] as u64) << 24 | + (in[5] as u64) << 16 | + (in[6] as u64) << 8 | + (in[7] as u64) +} + +// Convert a u64 to a [u8] in big endian format +fn from_u64(in: u64, out: &mut [u8]) { + out[0] = (in >> 56) as u8; + out[1] = (in >> 48) as u8; + out[2] = (in >> 40) as u8; + out[3] = (in >> 32) as u8; + out[4] = (in >> 24) as u8; + out[5] = (in >> 16) as u8; + out[6] = (in >> 8) as u8; + out[7] = in as u8; +} + +impl Engine512 { + fn input_byte(&mut self, in: u8) { + assert!(!self.finished) + + self.input_buffer[self.input_buffer_idx] = in; + self.input_buffer_idx += 1; + + if (self.input_buffer_idx == 8) { + self.input_buffer_idx = 0; + let w = to_u64(self.input_buffer); + self.process_word(w); + } + + self.bit_counter.add_bytes(1); + } + + fn input_vec(&mut self, in: &[u8]) { + assert!(!self.finished) + + let mut i = 0; + + while i < in.len() && self.input_buffer_idx != 0 { + self.input_byte(in[i]); + i += 1; + } + + while in.len() - i >= 8 { + let w = to_u64(vec::slice(in, i, i + 8)); + self.process_word(w); + self.bit_counter.add_bytes(8); + i += 8; + } + + while i < in.len() { + self.input_byte(in[i]); + i += 1; + } + } + + fn reset(&mut self) { + self.bit_counter.reset(); + self.finished = false; + self.input_buffer_idx = 0; + self.W_idx = 0; + } + + fn process_word(&mut self, in: u64) { + self.W[self.W_idx] = in; + self.W_idx += 1; + if (self.W_idx == 16) { + self.W_idx = 0; + self.process_block(); + } + } + + fn process_block(&mut self) { + fn ch(x: u64, y: u64, z: u64) -> u64 { + ((x & y) ^ ((!x) & z)) + } + + fn maj(x: u64, y: u64, z: u64) -> u64 { + ((x & y) ^ (x & z) ^ (y & z)) + } + + fn sum0(x: u64) -> u64 { + ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39)) + } + + fn sum1(x: u64) -> u64 { + ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41)) + } + + fn sigma0(x: u64) -> u64 { + ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7) + } + + fn sigma1(x: u64) -> u64 { + ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6) + } + + for uint::range(16, 80) |t| { + self.W[t] = sigma1(self.W[t - 2]) + self.W[t - 7] + sigma0(self.W[t - 15]) + + self.W[t - 16]; + } + + let mut a = self.H0; + let mut b = self.H1; + let mut c = self.H2; + let mut d = self.H3; + let mut e = self.H4; + let mut f = self.H5; + let mut g = self.H6; + let mut h = self.H7; + + let mut t = 0; + for uint::range(0, 10) |_| { + h += sum1(e) + ch(e, f, g) + K64[t] + self.W[t]; + d += h; + h += sum0(a) + maj(a, b, c); + t += 1; + + g += sum1(d) + ch(d, e, f) + K64[t] + self.W[t]; + c += g; + g += sum0(h) + maj(h, a, b); + t += 1; + + f += sum1(c) + ch(c, d, e) + K64[t] + self.W[t]; + b += f; + f += sum0(g) + maj(g, h, a); + t += 1; + + e += sum1(b) + ch(b, c, d) + K64[t] + self.W[t]; + a += e; + e += sum0(f) + maj(f, g, h); + t += 1; + + d += sum1(a) + ch(a, b, c) + K64[t] + self.W[t]; + h += d; + d += sum0(e) + maj(e, f, g); + t += 1; + + c += sum1(h) + ch(h, a, b) + K64[t] + self.W[t]; + g += c; + c += sum0(d) + maj(d, e, f); + t += 1; + + b += sum1(g) + ch(g, h, a) + K64[t] + self.W[t]; + f += b; + b += sum0(c) + maj(c, d, e); + t += 1; + + a += sum1(f) + ch(f, g, h) + K64[t] + self.W[t]; + e += a; + a += sum0(b) + maj(b, c, d); + t += 1; + } + + self.H0 += a; + self.H1 += b; + self.H2 += c; + self.H3 += d; + self.H4 += e; + self.H5 += f; + self.H6 += g; + self.H7 += h; + } + + fn finish(&mut self) { + if (self.finished) { + return; + } + + // must get message length before padding is added + let high_bit_count = self.bit_counter.get_high_bit_count(); + let low_bit_count = self.bit_counter.get_low_bit_count(); + + // add padding + self.input_byte(128u8); + + while self.input_buffer_idx != 0 { + self.input_byte(0u8); + } + + // add length + if (self.W_idx > 14) { + for uint::range(self.W_idx, 16) |_| { + self.process_word(0); + } + } + + while self.W_idx < 14 { + self.process_word(0); + } + + self.process_word(high_bit_count); + self.process_word(low_bit_count); + + self.finished = true; + } + + fn result_512(&mut self, out: &mut [u8]) { + self.finish(); + + from_u64(self.H0, vec::mut_slice(out, 0, 8)); + from_u64(self.H1, vec::mut_slice(out, 8, 16)); + from_u64(self.H2, vec::mut_slice(out, 16, 24)); + from_u64(self.H3, vec::mut_slice(out, 24, 32)); + from_u64(self.H4, vec::mut_slice(out, 32, 40)); + from_u64(self.H5, vec::mut_slice(out, 40, 48)); + from_u64(self.H6, vec::mut_slice(out, 48, 56)); + from_u64(self.H7, vec::mut_slice(out, 56, 64)); + } + + fn result_384(&mut self, out: &mut [u8]) { + self.finish(); + + from_u64(self.H0, vec::mut_slice(out, 0, 8)); + from_u64(self.H1, vec::mut_slice(out, 8, 16)); + from_u64(self.H2, vec::mut_slice(out, 16, 24)); + from_u64(self.H3, vec::mut_slice(out, 24, 32)); + from_u64(self.H4, vec::mut_slice(out, 32, 40)); + from_u64(self.H5, vec::mut_slice(out, 40, 48)); + } + + fn result_256(&mut self, out: &mut [u8]) { + self.finish(); + + from_u64(self.H0, vec::mut_slice(out, 0, 8)); + from_u64(self.H1, vec::mut_slice(out, 8, 16)); + from_u64(self.H2, vec::mut_slice(out, 16, 24)); + from_u64(self.H3, vec::mut_slice(out, 24, 32)); + } + + fn result_224(&mut self, out: &mut [u8]) { + self.finish(); + + from_u64(self.H0, vec::mut_slice(out, 0, 8)); + from_u64(self.H1, vec::mut_slice(out, 8, 16)); + from_u64(self.H2, vec::mut_slice(out, 16, 24)); + from_u32((self.H3 >> 32) as u32, vec::mut_slice(out, 24, 28)); + } +} + +// Constants necessary for SHA-2 512 family of digests. +static K64: [u64, ..80] = [ + 0x428a2f98d728ae22u64, 0x7137449123ef65cdu64, 0xb5c0fbcfec4d3b2fu64, 0xe9b5dba58189dbbcu64, + 0x3956c25bf348b538u64, 0x59f111f1b605d019u64, 0x923f82a4af194f9bu64, 0xab1c5ed5da6d8118u64, + 0xd807aa98a3030242u64, 0x12835b0145706fbeu64, 0x243185be4ee4b28cu64, 0x550c7dc3d5ffb4e2u64, + 0x72be5d74f27b896fu64, 0x80deb1fe3b1696b1u64, 0x9bdc06a725c71235u64, 0xc19bf174cf692694u64, + 0xe49b69c19ef14ad2u64, 0xefbe4786384f25e3u64, 0x0fc19dc68b8cd5b5u64, 0x240ca1cc77ac9c65u64, + 0x2de92c6f592b0275u64, 0x4a7484aa6ea6e483u64, 0x5cb0a9dcbd41fbd4u64, 0x76f988da831153b5u64, + 0x983e5152ee66dfabu64, 0xa831c66d2db43210u64, 0xb00327c898fb213fu64, 0xbf597fc7beef0ee4u64, + 0xc6e00bf33da88fc2u64, 0xd5a79147930aa725u64, 0x06ca6351e003826fu64, 0x142929670a0e6e70u64, + 0x27b70a8546d22ffcu64, 0x2e1b21385c26c926u64, 0x4d2c6dfc5ac42aedu64, 0x53380d139d95b3dfu64, + 0x650a73548baf63deu64, 0x766a0abb3c77b2a8u64, 0x81c2c92e47edaee6u64, 0x92722c851482353bu64, + 0xa2bfe8a14cf10364u64, 0xa81a664bbc423001u64, 0xc24b8b70d0f89791u64, 0xc76c51a30654be30u64, + 0xd192e819d6ef5218u64, 0xd69906245565a910u64, 0xf40e35855771202au64, 0x106aa07032bbd1b8u64, + 0x19a4c116b8d2d0c8u64, 0x1e376c085141ab53u64, 0x2748774cdf8eeb99u64, 0x34b0bcb5e19b48a8u64, + 0x391c0cb3c5c95a63u64, 0x4ed8aa4ae3418acbu64, 0x5b9cca4f7763e373u64, 0x682e6ff3d6b2b8a3u64, + 0x748f82ee5defb2fcu64, 0x78a5636f43172f60u64, 0x84c87814a1f0ab72u64, 0x8cc702081a6439ecu64, + 0x90befffa23631e28u64, 0xa4506cebde82bde9u64, 0xbef9a3f7b2c67915u64, 0xc67178f2e372532bu64, + 0xca273eceea26619cu64, 0xd186b8c721c0c207u64, 0xeada7dd6cde0eb1eu64, 0xf57d4f7fee6ed178u64, + 0x06f067aa72176fbau64, 0x0a637dc5a2c898a6u64, 0x113f9804bef90daeu64, 0x1b710b35131c471bu64, + 0x28db77f523047d84u64, 0x32caab7b40c72493u64, 0x3c9ebe0a15c9bebcu64, 0x431d67c49c100d4cu64, + 0x4cc5d4becb3e42b6u64, 0x597f299cfc657e2au64, 0x5fcb6fab3ad6faecu64, 0x6c44198c4a475817u64 +]; + +// A structure that represents that state of a digest computation +// for the SHA-2 256 family of digest functions +struct Engine256 { + input_buffer: [u8, ..4], + input_buffer_idx: uint, + length_bytes: u64, + H0: u32, + H1: u32, + H2: u32, + H3: u32, + H4: u32, + H5: u32, + H6: u32, + H7: u32, + W: [u32, ..64], + W_idx: uint, + finished: bool +} + +// Convert a [u8] to a u32 in big endian format +fn to_u32(in: &[u8]) -> u32 { + (in[0] as u32) << 24 | + (in[1] as u32) << 16 | + (in[2] as u32) << 8 | + (in[3] as u32) +} + +// Convert a u32 to a [u8] in big endian format +fn from_u32(in: u32, out: &mut [u8]) { + out[0] = (in >> 24) as u8; + out[1] = (in >> 16) as u8; + out[2] = (in >> 8) as u8; + out[3] = in as u8; +} + +impl Engine256 { + fn input_byte(&mut self, in: u8) { + assert!(!self.finished) + + self.input_buffer[self.input_buffer_idx] = in; + self.input_buffer_idx += 1; + + if (self.input_buffer_idx == 4) { + self.input_buffer_idx = 0; + let w = to_u32(self.input_buffer); + self.process_word(w); + } + + self.length_bytes += 1; + } + + fn input_vec(&mut self, in: &[u8]) { + assert!(!self.finished) + + let mut i = 0; + + while i < in.len() && self.input_buffer_idx != 0 { + self.input_byte(in[i]); + i += 1; + } + + while in.len() - i >= 4 { + let w = to_u32(vec::slice(in, i, i + 4)); + self.process_word(w); + self.length_bytes += 4; + i += 4; + } + + while i < in.len() { + self.input_byte(in[i]); + i += 1; + } + + } + + fn reset(&mut self) { + self.length_bytes = 0; + self.finished = false; + self.input_buffer_idx = 0; + self.W_idx = 0; + } + + fn process_word(&mut self, in: u32) { + self.W[self.W_idx] = in; + self.W_idx += 1; + if (self.W_idx == 16) { + self.W_idx = 0; + self.process_block(); + } + } + + fn process_block(&mut self) { + fn ch(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ ((!x) & z)) + } + + fn maj(x: u32, y: u32, z: u32) -> u32 { + ((x & y) ^ (x & z) ^ (y & z)) + } + + fn sum0(x: u32) -> u32 { + ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)) + } + + fn sum1(x: u32) -> u32 { + ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)) + } + + fn sigma0(x: u32) -> u32 { + ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3) + } + + fn sigma1(x: u32) -> u32 { + ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10) + } + + for uint::range(16, 64) |t| { + self.W[t] = sigma1(self.W[t - 2]) + self.W[t - 7] + sigma0(self.W[t - 15]) + + self.W[t - 16]; + } + + let mut a = self.H0; + let mut b = self.H1; + let mut c = self.H2; + let mut d = self.H3; + let mut e = self.H4; + let mut f = self.H5; + let mut g = self.H6; + let mut h = self.H7; + + let mut t = 0; + for uint::range(0, 8) |_| { + h += sum1(e) + ch(e, f, g) + K32[t] + self.W[t]; + d += h; + h += sum0(a) + maj(a, b, c); + t += 1; + + g += sum1(d) + ch(d, e, f) + K32[t] + self.W[t]; + c += g; + g += sum0(h) + maj(h, a, b); + t += 1; + + f += sum1(c) + ch(c, d, e) + K32[t] + self.W[t]; + b += f; + f += sum0(g) + maj(g, h, a); + t += 1; + + e += sum1(b) + ch(b, c, d) + K32[t] + self.W[t]; + a += e; + e += sum0(f) + maj(f, g, h); + t += 1; + + d += sum1(a) + ch(a, b, c) + K32[t] + self.W[t]; + h += d; + d += sum0(e) + maj(e, f, g); + t += 1; + + c += sum1(h) + ch(h, a, b) + K32[t] + self.W[t]; + g += c; + c += sum0(d) + maj(d, e, f); + t += 1; + + b += sum1(g) + ch(g, h, a) + K32[t] + self.W[t]; + f += b; + b += sum0(c) + maj(c, d, e); + t += 1; + + a += sum1(f) + ch(f, g, h) + K32[t] + self.W[t]; + e += a; + a += sum0(b) + maj(b, c, d); + t += 1; + } + + self.H0 += a; + self.H1 += b; + self.H2 += c; + self.H3 += d; + self.H4 += e; + self.H5 += f; + self.H6 += g; + self.H7 += h; + } + + fn finish(&mut self) { + if (self.finished) { + return; + } + + // must get length before adding padding + let bit_length = self.length_bytes << 3; + + // add padding + self.input_byte(128u8); + + while self.input_buffer_idx != 0 { + self.input_byte(0u8); + } + + // add length + if (self.W_idx > 14) { + for uint::range(self.W_idx, 16) |_| { + self.process_word(0); + } + } + + while self.W_idx < 14 { + self.process_word(0); + } + + self.process_word((bit_length >> 32) as u32); + self.process_word(bit_length as u32); + + self.finished = true; + } + + fn result_256(&mut self, out: &mut [u8]) { + self.finish(); + + from_u32(self.H0, vec::mut_slice(out, 0, 4)); + from_u32(self.H1, vec::mut_slice(out, 4, 8)); + from_u32(self.H2, vec::mut_slice(out, 8, 12)); + from_u32(self.H3, vec::mut_slice(out, 12, 16)); + from_u32(self.H4, vec::mut_slice(out, 16, 20)); + from_u32(self.H5, vec::mut_slice(out, 20, 24)); + from_u32(self.H6, vec::mut_slice(out, 24, 28)); + from_u32(self.H7, vec::mut_slice(out, 28, 32)); + } + + fn result_224(&mut self, out: &mut [u8]) { + self.finish(); + + from_u32(self.H0, vec::mut_slice(out, 0, 4)); + from_u32(self.H1, vec::mut_slice(out, 4, 8)); + from_u32(self.H2, vec::mut_slice(out, 8, 12)); + from_u32(self.H3, vec::mut_slice(out, 12, 16)); + from_u32(self.H4, vec::mut_slice(out, 16, 20)); + from_u32(self.H5, vec::mut_slice(out, 20, 24)); + from_u32(self.H6, vec::mut_slice(out, 24, 28)); + } +} + +static K32: [u32, ..64] = [ + 0x428a2f98u32, 0x71374491u32, 0xb5c0fbcfu32, 0xe9b5dba5u32, + 0x3956c25bu32, 0x59f111f1u32, 0x923f82a4u32, 0xab1c5ed5u32, + 0xd807aa98u32, 0x12835b01u32, 0x243185beu32, 0x550c7dc3u32, + 0x72be5d74u32, 0x80deb1feu32, 0x9bdc06a7u32, 0xc19bf174u32, + 0xe49b69c1u32, 0xefbe4786u32, 0x0fc19dc6u32, 0x240ca1ccu32, + 0x2de92c6fu32, 0x4a7484aau32, 0x5cb0a9dcu32, 0x76f988dau32, + 0x983e5152u32, 0xa831c66du32, 0xb00327c8u32, 0xbf597fc7u32, + 0xc6e00bf3u32, 0xd5a79147u32, 0x06ca6351u32, 0x14292967u32, + 0x27b70a85u32, 0x2e1b2138u32, 0x4d2c6dfcu32, 0x53380d13u32, + 0x650a7354u32, 0x766a0abbu32, 0x81c2c92eu32, 0x92722c85u32, + 0xa2bfe8a1u32, 0xa81a664bu32, 0xc24b8b70u32, 0xc76c51a3u32, + 0xd192e819u32, 0xd6990624u32, 0xf40e3585u32, 0x106aa070u32, + 0x19a4c116u32, 0x1e376c08u32, 0x2748774cu32, 0x34b0bcb5u32, + 0x391c0cb3u32, 0x4ed8aa4au32, 0x5b9cca4fu32, 0x682e6ff3u32, + 0x748f82eeu32, 0x78a5636fu32, 0x84c87814u32, 0x8cc70208u32, + 0x90befffau32, 0xa4506cebu32, 0xbef9a3f7u32, 0xc67178f2u32 +]; + +struct Sha512 { + priv engine: Engine512 +} + +struct Sha384 { + priv engine: Engine512 +} + +struct Sha512Trunc256 { + priv engine: Engine512 +} + +struct Sha512Trunc224 { + priv engine: Engine512 +} + +struct Sha256 { + priv engine: Engine256 +} + +struct Sha224 { + priv engine: Engine256 +} + +impl Sha512 { + /** + * Construct an new instance of a SHA-512 digest. + */ + pub fn new() -> Sha512 { + Sha512 { + engine: Engine512 { + input_buffer: [0u8, ..8], + input_buffer_idx: 0, + bit_counter: BitCounter { high_bit_count: 0, low_byte_count: 0 }, + H0: 0x6a09e667f3bcc908u64, + H1: 0xbb67ae8584caa73bu64, + H2: 0x3c6ef372fe94f82bu64, + H3: 0xa54ff53a5f1d36f1u64, + H4: 0x510e527fade682d1u64, + H5: 0x9b05688c2b3e6c1fu64, + H6: 0x1f83d9abfb41bd6bu64, + H7: 0x5be0cd19137e2179u64, + W: [0u64, ..80], + W_idx: 0, + finished: false, + } + } + } +} + +impl Sha384 { + /** + * Construct an new instance of a SHA-384 digest. + */ + pub fn new() -> Sha384 { + Sha384 { + engine: Engine512 { + input_buffer: [0u8, ..8], + input_buffer_idx: 0, + bit_counter: BitCounter { high_bit_count: 0, low_byte_count: 0 }, + H0: 0xcbbb9d5dc1059ed8u64, + H1: 0x629a292a367cd507u64, + H2: 0x9159015a3070dd17u64, + H3: 0x152fecd8f70e5939u64, + H4: 0x67332667ffc00b31u64, + H5: 0x8eb44a8768581511u64, + H6: 0xdb0c2e0d64f98fa7u64, + H7: 0x47b5481dbefa4fa4u64, + W: [0u64, ..80], + W_idx: 0, + finished: false, + } + } + } +} + +impl Sha512Trunc256 { + /** + * Construct an new instance of a SHA-512/256 digest. + */ + pub fn new() -> Sha512Trunc256 { + Sha512Trunc256 { + engine: Engine512 { + input_buffer: [0u8, ..8], + input_buffer_idx: 0, + bit_counter: BitCounter { high_bit_count: 0, low_byte_count: 0 }, + H0: 0x22312194fc2bf72cu64, + H1: 0x9f555fa3c84c64c2u64, + H2: 0x2393b86b6f53b151u64, + H3: 0x963877195940eabdu64, + H4: 0x96283ee2a88effe3u64, + H5: 0xbe5e1e2553863992u64, + H6: 0x2b0199fc2c85b8aau64, + H7: 0x0eb72ddc81c52ca2u64, + W: [0u64, ..80], + W_idx: 0, + finished: false, + } + } + } +} + +impl Sha512Trunc224 { + /** + * Construct an new instance of a SHA-512/224 digest. + */ + pub fn new() -> Sha512Trunc224 { + Sha512Trunc224 { + engine: Engine512 { + input_buffer: [0u8, ..8], + input_buffer_idx: 0, + bit_counter: BitCounter { high_bit_count: 0, low_byte_count: 0 }, + H0: 0x8c3d37c819544da2u64, + H1: 0x73e1996689dcd4d6u64, + H2: 0x1dfab7ae32ff9c82u64, + H3: 0x679dd514582f9fcfu64, + H4: 0x0f6d2b697bd44da8u64, + H5: 0x77e36f7304c48942u64, + H6: 0x3f9d85a86a1d36c8u64, + H7: 0x1112e6ad91d692a1u64, + W: [0u64, ..80], + W_idx: 0, + finished: false, + } + } + } +} + +impl Sha256 { + /** + * Construct an new instance of a SHA-256 digest. + */ + pub fn new() -> Sha256 { + Sha256 { + engine: Engine256 { + input_buffer: [0u8, ..4], + input_buffer_idx: 0, + length_bytes: 0, + H0: 0x6a09e667u32, + H1: 0xbb67ae85u32, + H2: 0x3c6ef372u32, + H3: 0xa54ff53au32, + H4: 0x510e527fu32, + H5: 0x9b05688cu32, + H6: 0x1f83d9abu32, + H7: 0x5be0cd19u32, + W: [0u32, ..64], + W_idx: 0, + finished: false, + } + } + } +} + +impl Sha224 { + /** + * Construct an new instance of a SHA-224 digest. + */ + pub fn new() -> Sha224 { + Sha224 { + engine: Engine256 { + input_buffer: [0u8, ..4], + input_buffer_idx: 0, + length_bytes: 0, + H0: 0xc1059ed8u32, + H1: 0x367cd507u32, + H2: 0x3070dd17u32, + H3: 0xf70e5939u32, + H4: 0xffc00b31u32, + H5: 0x68581511u32, + H6: 0x64f98fa7u32, + H7: 0xbefa4fa4u32, + W: [0u32, ..64], + W_idx: 0, + finished: false, + } + } + } +} + +impl Digest for Sha512 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_512(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0x6a09e667f3bcc908u64; + self.engine.H1 = 0xbb67ae8584caa73bu64; + self.engine.H2 = 0x3c6ef372fe94f82bu64; + self.engine.H3 = 0xa54ff53a5f1d36f1u64; + self.engine.H4 = 0x510e527fade682d1u64; + self.engine.H5 = 0x9b05688c2b3e6c1fu64; + self.engine.H6 = 0x1f83d9abfb41bd6bu64; + self.engine.H7 = 0x5be0cd19137e2179u64; + } + + fn output_bits(&self) -> uint { 512 } +} + +impl Digest for Sha384 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_384(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0xcbbb9d5dc1059ed8u64; + self.engine.H1 = 0x629a292a367cd507u64; + self.engine.H2 = 0x9159015a3070dd17u64; + self.engine.H3 = 0x152fecd8f70e5939u64; + self.engine.H4 = 0x67332667ffc00b31u64; + self.engine.H5 = 0x8eb44a8768581511u64; + self.engine.H6 = 0xdb0c2e0d64f98fa7u64; + self.engine.H7 = 0x47b5481dbefa4fa4u64; + } + + fn output_bits(&self) -> uint { 384 } +} + +impl Digest for Sha512Trunc256 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_256(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0x22312194fc2bf72cu64; + self.engine.H1 = 0x9f555fa3c84c64c2u64; + self.engine.H2 = 0x2393b86b6f53b151u64; + self.engine.H3 = 0x963877195940eabdu64; + self.engine.H4 = 0x96283ee2a88effe3u64; + self.engine.H5 = 0xbe5e1e2553863992u64; + self.engine.H6 = 0x2b0199fc2c85b8aau64; + self.engine.H7 = 0x0eb72ddc81c52ca2u64; + } + + fn output_bits(&self) -> uint { 256 } +} + +impl Digest for Sha512Trunc224 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_224(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0x8c3d37c819544da2u64; + self.engine.H1 = 0x73e1996689dcd4d6u64; + self.engine.H2 = 0x1dfab7ae32ff9c82u64; + self.engine.H3 = 0x679dd514582f9fcfu64; + self.engine.H4 = 0x0f6d2b697bd44da8u64; + self.engine.H5 = 0x77e36f7304c48942u64; + self.engine.H6 = 0x3f9d85a86a1d36c8u64; + self.engine.H7 = 0x1112e6ad91d692a1u64; + } + + fn output_bits(&self) -> uint { 224 } +} + +impl Digest for Sha256 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_256(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0x6a09e667u32; + self.engine.H1 = 0xbb67ae85u32; + self.engine.H2 = 0x3c6ef372u32; + self.engine.H3 = 0xa54ff53au32; + self.engine.H4 = 0x510e527fu32; + self.engine.H5 = 0x9b05688cu32; + self.engine.H6 = 0x1f83d9abu32; + self.engine.H7 = 0x5be0cd19u32; + } + + fn output_bits(&self) -> uint { 256 } +} + +impl Digest for Sha224 { + fn input(&mut self, d: &[u8]) { + self.engine.input_vec(d); + } + + fn result(&mut self, out: &mut [u8]) { + self.engine.result_224(out) + } + + fn reset(&mut self) { + self.engine.reset(); + + self.engine.H0 = 0xc1059ed8u32; + self.engine.H1 = 0x367cd507u32; + self.engine.H2 = 0x3070dd17u32; + self.engine.H3 = 0xf70e5939u32; + self.engine.H4 = 0xffc00b31u32; + self.engine.H5 = 0x68581511u32; + self.engine.H6 = 0x64f98fa7u32; + self.engine.H7 = 0xbefa4fa4u32; + } + + fn output_bits(&self) -> uint { 224 } +} + + +#[cfg(test)] +mod tests { + use digest::{Digest, DigestUtil}; + use sha2::{Sha512, Sha384, Sha512Trunc256, Sha512Trunc224, Sha256, Sha224}; + + struct Test { + input: ~str, + output_str: ~str, + } + + fn test_hash(sh: &mut D, tests: &[Test]) { + // Test that it works when accepting the message all at once + for tests.iter().advance() |t| { + sh.input_str(t.input); + + let out_str = sh.result_str(); + assert!(out_str == t.output_str); + + sh.reset(); + } + + // Test that it works when accepting the message in pieces + for tests.iter().advance() |t| { + let len = t.input.len(); + let mut left = len; + while left > 0u { + let take = (left + 1u) / 2u; + sh.input_str(t.input.slice(len - left, take + len - left)); + left = left - take; + } + + let out_str = sh.result_str(); + assert!(out_str == t.output_str); + + sh.reset(); + } + } + + #[test] + fn test_sha512() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" + + "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64" + + "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" + + "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha512::new(); + + test_hash(sh, tests); + } + + #[test] + fn test_sha384() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743" + + "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c49" + + "4011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6" + + "c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha384::new(); + + test_hash(sh, tests); + } + + #[test] + fn test_sha512_256() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"1546741840f8a492b959d9b8b2344b9b0eb51b004bba35c0aebaac86d45264c3" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha512Trunc256::new(); + + test_hash(sh, tests); + } + + #[test] + fn test_sha512_224() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"6d6a9279495ec4061769752e7ff9c68b6b0b3c5a281b7917ce0572de" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha512Trunc224::new(); + + test_hash(sh, tests); + } + + #[test] + fn test_sha256() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha256::new(); + + test_hash(sh, tests); + } + + #[test] + fn test_sha224() { + // Examples from wikipedia + let wikipedia_tests = ~[ + Test { + input: ~"", + output_str: ~"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog", + output_str: ~"730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525" + }, + Test { + input: ~"The quick brown fox jumps over the lazy dog.", + output_str: ~"619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c" + }, + ]; + + let tests = wikipedia_tests; + + let mut sh = ~Sha224::new(); + + test_hash(sh, tests); + } +} diff --git a/src/libextra/std.rc b/src/libextra/std.rc index dbc3095ae275..11aebdf467ff 100644 --- a/src/libextra/std.rc +++ b/src/libextra/std.rc @@ -91,6 +91,8 @@ pub mod treemap; pub mod digest; #[path="crypto/sha1.rs"] pub mod sha1; +#[path="crypto/sha2.rs"] +pub mod sha2; // And ... other stuff From e2e39234cc5509fb461b8805eeb32c5ce538ee6e Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 23 Jun 2013 17:57:39 -0400 Subject: [PATCH 102/336] remove old_iter the `test/run-pass/class-trait-bounded-param.rs` test was xfailed and written in an ancient dialect of Rust so I've just removed it this also removes `to_vec` from DList because it's provided by `std::iter::to_vec` an Iterator implementation is added for OptVec but some transitional internal iterator methods are still left --- src/libextra/bitv.rs | 6 +- src/libextra/dlist.rs | 94 +++--- src/libextra/priority_queue.rs | 17 +- src/libextra/smallintmap.rs | 17 +- src/libextra/treemap.rs | 26 +- src/librustc/metadata/encoder.rs | 4 +- src/librustc/middle/borrowck/move_data.rs | 4 +- src/librustc/middle/resolve.rs | 2 +- src/libstd/at_vec.rs | 3 +- src/libstd/core.rc | 1 - src/libstd/old_iter.rs | 296 ------------------ src/libstd/prelude.rs | 2 - src/libstd/rt/uvio.rs | 1 - src/libstd/str.rs | 2 - src/libstd/to_str.rs | 1 - src/libstd/trie.rs | 26 +- src/libstd/vec.rs | 9 +- src/libsyntax/ext/pipes/pipec.rs | 4 +- src/libsyntax/opt_vec.rs | 121 +++---- src/test/run-fail/extern-fail.rs | 1 - .../class-impl-very-parameterized-trait.rs | 1 - .../run-pass/class-trait-bounded-param.rs | 35 --- 22 files changed, 122 insertions(+), 551 deletions(-) delete mode 100644 src/libstd/old_iter.rs delete mode 100644 src/test/run-pass/class-trait-bounded-param.rs diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 940c89bb0c68..6e4507d4277a 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -666,12 +666,8 @@ impl BitvSet { pub fn symmetric_difference_with(&mut self, other: &BitvSet) { self.other_op(other, |w1, w2| w1 ^ w2); } -} -impl BaseIter for BitvSet { - fn size_hint(&self) -> Option { Some(self.len()) } - - fn each(&self, blk: &fn(v: &uint) -> bool) -> bool { + pub fn each(&self, blk: &fn(v: &uint) -> bool) -> bool { for self.bitv.storage.iter().enumerate().advance |(i, &w)| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { return false; diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 953803c6843f..1767aa8c3972 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -21,8 +21,6 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. use core::prelude::*; use core::managed; -use core::old_iter; -use core::vec; pub type DListLink = Option<@mut DListNode>; @@ -213,6 +211,42 @@ impl DList { } impl DList { + /** + * Iterates through the current contents. + * + * Attempts to access this dlist during iteration are allowed (to + * allow for e.g. breadth-first search with in-place enqueues), but + * removing the current node is forbidden. + */ + pub fn each(@mut self, f: &fn(v: &T) -> bool) -> bool { + let mut link = self.peek_n(); + while link.is_some() { + let nobe = link.get(); + assert!(nobe.linked); + + { + let frozen_nobe = &*nobe; + if !f(&frozen_nobe.data) { return false; } + } + + // Check (weakly) that the user didn't do a remove. + if self.size == 0 { + fail!("The dlist became empty during iteration??") + } + if !nobe.linked || + (!((nobe.prev.is_some() + || managed::mut_ptr_eq(self.hd.expect("headless dlist?"), + nobe)) + && (nobe.next.is_some() + || managed::mut_ptr_eq(self.tl.expect("tailless dlist?"), + nobe)))) { + fail!("Removing a dlist node during iteration is forbidden!") + } + link = nobe.next_link(); + } + return true; + } + /// Get the size of the list. O(1). pub fn len(@mut self) -> uint { self.size } /// Returns true if the list is empty. O(1). @@ -484,56 +518,6 @@ impl DList { /// Get data at the list's tail, failing if empty. O(1). pub fn tail(@mut self) -> T { copy self.tail_n().data } - - /// Get the elements of the list as a vector. O(n). - pub fn to_vec(@mut self) -> ~[T] { - let mut v = vec::with_capacity(self.size); - for old_iter::eachi(&self) |index,data| { - v[index] = copy *data; - } - v - } -} - -impl BaseIter for @mut DList { - /** - * Iterates through the current contents. - * - * Attempts to access this dlist during iteration are allowed (to - * allow for e.g. breadth-first search with in-place enqueues), but - * removing the current node is forbidden. - */ - fn each(&self, f: &fn(v: &T) -> bool) -> bool { - let mut link = self.peek_n(); - while link.is_some() { - let nobe = link.get(); - assert!(nobe.linked); - - { - let frozen_nobe = &*nobe; - if !f(&frozen_nobe.data) { return false; } - } - - // Check (weakly) that the user didn't do a remove. - if self.size == 0 { - fail!("The dlist became empty during iteration??") - } - if !nobe.linked || - (!((nobe.prev.is_some() - || managed::mut_ptr_eq(self.hd.expect("headless dlist?"), - nobe)) - && (nobe.next.is_some() - || managed::mut_ptr_eq(self.tl.expect("tailless dlist?"), - nobe)))) { - fail!("Removing a dlist node during iteration is forbidden!") - } - link = nobe.next_link(); - } - return true; - } - - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } } #[cfg(test)] @@ -542,7 +526,6 @@ mod tests { use super::*; - use core::old_iter; use core::vec; #[test] @@ -759,11 +742,6 @@ mod tests { assert_eq!(l.len(), 3); } #[test] - fn test_dlist_foldl() { - let l = from_vec(vec::from_fn(101, |x|x)); - assert_eq!(old_iter::foldl(&l, 0, |accum,elem| *accum+*elem), 5050); - } - #[test] fn test_dlist_break_early() { let l = from_vec([1,2,3,4,5]); let mut x = 0; diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 31c9acbbd54d..4e201a6538ba 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -14,25 +14,15 @@ use core::prelude::*; -use core::old_iter::BaseIter; use core::unstable::intrinsics::{move_val_init, init}; use core::util::{replace, swap}; use core::vec; -#[allow(missing_doc)] +/// A priority queue implemented with a binary heap pub struct PriorityQueue { priv data: ~[T], } -impl BaseIter for PriorityQueue { - /// Visit all values in the underlying vector. - /// - /// The values are **not** visited in order. - fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.iter().advance(f) } - - fn size_hint(&self) -> Option { Some(self.data.len()) } -} - impl Container for PriorityQueue { /// Returns the length of the queue fn len(&self) -> uint { self.data.len() } @@ -47,6 +37,11 @@ impl Mutable for PriorityQueue { } impl PriorityQueue { + /// Visit all values in the underlying vector. + /// + /// The values are **not** visited in order. + pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.iter().advance(f) } + /// Returns the greatest item in the queue - fails if empty pub fn top<'a>(&'a self) -> &'a T { &self.data[0] } diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index aee087d3764d..17126f0d32b5 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -19,8 +19,6 @@ use core::prelude::*; use core::cmp; use core::container::{Container, Mutable, Map, Set}; -use core::old_iter::BaseIter; -use core::old_iter; use core::uint; use core::util::replace; use core::vec; @@ -212,12 +210,6 @@ impl Mutable for SmallIntSet { fn clear(&mut self) { self.map.clear() } } -impl BaseIter for SmallIntSet { - /// Visit all values in order - fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } - fn size_hint(&self) -> Option { Some(self.len()) } -} - impl Set for SmallIntSet { /// Return true if the set contains a value fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) } @@ -233,12 +225,14 @@ impl Set for SmallIntSet { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty uintersection. fn is_disjoint(&self, other: &SmallIntSet) -> bool { - old_iter::all(self, |v| !other.contains(v)) + for self.each |v| { if other.contains(v) { return false } } + true } /// Return true if the set is a subset of another fn is_subset(&self, other: &SmallIntSet) -> bool { - old_iter::all(self, |v| other.contains(v)) + for self.each |v| { if !other.contains(v) { return false } } + true } /// Return true if the set is a superset of another @@ -286,6 +280,9 @@ impl Set for SmallIntSet { impl SmallIntSet { /// Create an empty SmallIntSet pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} } + + /// Visit all values in order + pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } } #[cfg(test)] diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 87932c25cda1..4929dea9045b 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -249,22 +249,6 @@ pub struct TreeSet { priv map: TreeMap } -impl BaseIter for TreeSet { - /// Visit all values in order - #[inline] - fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } -} - -impl ReverseIter for TreeSet { - /// Visit all values in reverse order - #[inline] - fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { - self.map.each_key_reverse(f) - } -} - impl Eq for TreeSet { #[inline] fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } @@ -499,6 +483,16 @@ impl TreeSet { pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { TreeSetIterator{iter: self.map.iter()} } + + /// Visit all values in order + #[inline] + pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } + + /// Visit all values in reverse order + #[inline] + pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { + self.map.each_key_reverse(f) + } } /// Lazy forward iterator over a set diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 94cad18ece2c..1f2ede670fa1 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -731,8 +731,8 @@ fn encode_info_for_method(ecx: &EncodeContext, } let mut combined_ty_params = opt_vec::Empty; - combined_ty_params.push_all(&owner_generics.ty_params); - combined_ty_params.push_all(&method_generics.ty_params); + for owner_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } + for method_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } let len = combined_ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &combined_ty_params); diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 0b94eeecba87..7396dc1bd7bf 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -507,7 +507,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.contains(&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) { @@ -536,7 +536,7 @@ impl FlowedMoveData { -> bool { //! True if `id` is the id of the LHS of an assignment - self.move_data.assignee_ids.contains(&id) + self.move_data.assignee_ids.iter().any_(|x| x == &id) } pub fn each_assignment_of(&self, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index eed0b12b9e12..562bbca69297 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3710,7 +3710,7 @@ impl Resolver { let function_type_rib = @Rib(rib_kind); self.type_ribs.push(function_type_rib); - for generics.ty_params.eachi |index, type_parameter| { + for generics.ty_params.iter().enumerate().advance |(index, type_parameter)| { let name = type_parameter.ident; debug!("with_type_parameter_rib: %d %d", node_id, type_parameter.id); diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 2b846c923c48..b871ed3d57af 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -14,7 +14,6 @@ use cast::transmute; use container::Container; use iterator::IteratorUtil; use kinds::Copy; -use old_iter; use option::Option; use sys; use uint; @@ -129,7 +128,7 @@ pub fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pub fn from_fn(n_elts: uint, op: old_iter::InitOp) -> @[T] { +pub fn from_fn(n_elts: uint, op: &fn(uint) -> T) -> @[T] { do build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(op(i)); i += 1u; } diff --git a/src/libstd/core.rc b/src/libstd/core.rc index 6911c00e55ba..13c54799fac4 100644 --- a/src/libstd/core.rc +++ b/src/libstd/core.rc @@ -138,7 +138,6 @@ pub mod from_str; #[path = "num/num.rs"] pub mod num; pub mod iter; -pub mod old_iter; pub mod iterator; pub mod to_str; pub mod to_bytes; diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs deleted file mode 100644 index 9b87d76a309d..000000000000 --- a/src/libstd/old_iter.rs +++ /dev/null @@ -1,296 +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. - -/*! - -**Deprecated** iteration traits and common implementations. - -*/ - -#[allow(missing_doc)]; - -use cmp::Eq; -use kinds::Copy; -use option::{None, Option, Some}; -use vec; - -/// A function used to initialize the elements of a sequence -pub type InitOp<'self,T> = &'self fn(uint) -> T; - -pub trait BaseIter { - fn each(&self, blk: &fn(v: &A) -> bool) -> bool; - fn size_hint(&self) -> Option; -} - -pub trait ReverseIter: BaseIter { - fn each_reverse(&self, blk: &fn(&A) -> bool) -> bool; -} - -pub trait ExtendedIter { - fn eachi(&self, blk: &fn(uint, v: &A) -> bool) -> bool; - fn all(&self, blk: &fn(&A) -> bool) -> bool; - fn any(&self, blk: &fn(&A) -> bool) -> bool; - fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; - fn position(&self, f: &fn(&A) -> bool) -> Option; - fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B]; - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; -} - -pub trait EqIter { - fn contains(&self, x: &A) -> bool; - fn count(&self, x: &A) -> uint; -} - -pub trait CopyableIter { - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; - fn to_vec(&self) -> ~[A]; - fn find(&self, p: &fn(&A) -> bool) -> Option; -} - -// A trait for sequences that can be built by imperatively pushing elements -// onto them. -pub trait Buildable { - /** - * Builds a buildable sequence by calling a provided function with - * an argument function that pushes an element onto the back of - * the sequence. - * This version takes an initial size for the sequence. - * - * # Arguments - * - * * size - A hint for an initial size of the sequence - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. - */ - fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self; -} - -#[inline] -pub fn _eachi>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool { - let mut i = 0; - for this.each |a| { - if !blk(i, a) { - return false; - } - i += 1; - } - return true; -} - -pub fn eachi>(this: &IA, blk: &fn(uint, &A) -> bool) -> bool { - _eachi(this, blk) -} - -#[inline] -pub fn all>(this: &IA, blk: &fn(&A) -> bool) -> bool { - for this.each |a| { - if !blk(a) { - return false; - } - } - return true; -} - -#[inline] -pub fn any>(this: &IA, blk: &fn(&A) -> bool) -> bool { - for this.each |a| { - if blk(a) { - return true; - } - } - return false; -} - -#[inline] -pub fn filter_to_vec>(this: &IA, - prd: &fn(&A) -> bool) - -> ~[A] { - do vec::build_sized_opt(this.size_hint()) |push| { - for this.each |a| { - if prd(a) { push(copy *a); } - } - } -} - -#[inline] -pub fn map_to_vec>(this: &IA, op: &fn(&A) -> B) -> ~[B] { - do vec::build_sized_opt(this.size_hint()) |push| { - for this.each |a| { - push(op(a)); - } - } -} - -#[inline] -pub fn flat_map_to_vec,IB:BaseIter>(this: &IA, - op: &fn(&A) -> IB) - -> ~[B] { - do vec::build |push| { - for this.each |a| { - for op(a).each |&b| { - push(b); - } - } - } -} - -#[inline] -pub fn foldl>(this: &IA, b0: B, blk: &fn(&B, &A) -> B) - -> B { - let mut b = b0; - for this.each |a| { - b = blk(&b, a); - } - b -} - -#[inline] -pub fn to_vec>(this: &IA) -> ~[A] { - map_to_vec(this, |&x| x) -} - -#[inline] -pub fn contains>(this: &IA, x: &A) -> bool { - for this.each |a| { - if *a == *x { return true; } - } - return false; -} - -#[inline] -pub fn count>(this: &IA, x: &A) -> uint { - do foldl(this, 0) |count, value| { - if *value == *x { - *count + 1 - } else { - *count - } - } -} - -#[inline] -pub fn position>(this: &IA, f: &fn(&A) -> bool) - -> Option { - let mut i = 0; - for this.each |a| { - if f(a) { return Some(i); } - i += 1; - } - return None; -} - -#[inline] -pub fn find>(this: &IA, f: &fn(&A) -> bool) - -> Option { - for this.each |i| { - if f(i) { return Some(copy *i) } - } - return None; -} - -// Some functions for just building - -/** - * Builds a sequence by calling a provided function with an argument - * function that pushes an element to the back of a sequence. - * - * # Arguments - * - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. - */ -#[inline] -pub fn build>(builder: &fn(push: &fn(A))) -> B { - Buildable::build_sized(4, builder) -} - -/** - * Builds a sequence by calling a provided function with an argument - * function that pushes an element to the back of the sequence. - * This version takes an initial size for the sequence. - * - * # Arguments - * - * * size - An option, maybe containing initial size of the sequence - * to reserve. - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. - */ -#[inline] -pub fn build_sized_opt>(size: Option, - builder: &fn(push: &fn(A))) -> B { - Buildable::build_sized(size.get_or_default(4), builder) -} - -// Functions that combine iteration and building - -/// Applies a function to each element of an iterable and returns the results -/// in a sequence built via `BU`. See also `map_to_vec`. -#[inline] -pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) - -> BU { - do build_sized_opt(v.size_hint()) |push| { - for v.each() |elem| { - push(f(elem)); - } - } -} - -/** - * Creates and initializes a generic sequence from a function. - * - * Creates a generic sequence of size `n_elts` and initializes the elements - * to the value returned by the function `op`. - */ -#[inline] -pub fn from_fn>(n_elts: uint, op: InitOp) -> BT { - do Buildable::build_sized(n_elts) |push| { - let mut i: uint = 0u; - while i < n_elts { push(op(i)); i += 1u; } - } -} - -/** - * Creates and initializes a generic sequence with some elements. - * - * Creates an immutable vector of size `n_elts` and initializes the elements - * to the value `t`. - */ -#[inline] -pub fn from_elem>(n_elts: uint, t: T) -> BT { - do Buildable::build_sized(n_elts) |push| { - let mut i: uint = 0; - while i < n_elts { push(copy t); i += 1; } - } -} - -/// Appends two generic sequences. -#[inline] -pub fn append,BT:Buildable>(lhs: &IT, rhs: &IT) - -> BT { - let size_opt = lhs.size_hint().chain_ref( - |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); - do build_sized_opt(size_opt) |push| { - for lhs.each |x| { push(copy *x); } - for rhs.each |x| { push(copy *x); } - } -} - -/// Copies a generic sequence, possibly converting it to a different -/// type of sequence. -#[inline] -pub fn copy_seq,BT:Buildable>(v: &IT) -> BT { - do build_sized_opt(v.size_hint()) |push| { - for v.each |x| { push(copy *x); } - } -} diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 309df27e151d..6d7cb2a28a88 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -46,8 +46,6 @@ 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 old_iter::{BaseIter, ReverseIter, ExtendedIter, EqIter}; -pub use old_iter::CopyableIter; pub use iter::{Times, FromIter}; pub use iterator::{Iterator, IteratorUtil, OrdIterator}; pub use num::{Num, NumCast}; diff --git a/src/libstd/rt/uvio.rs b/src/libstd/rt/uvio.rs index 070ccf7fb446..f4a79934e7e4 100644 --- a/src/libstd/rt/uvio.rs +++ b/src/libstd/rt/uvio.rs @@ -15,7 +15,6 @@ use super::io::net::ip::IpAddr; use super::uv::*; use super::rtio::*; use ops::Drop; -use old_iter::CopyableIter; use cell::Cell; use cast::transmute; use super::sched::{Scheduler, local_sched}; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 45ba85283754..16c287c1da82 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -29,7 +29,6 @@ use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIter use libc; use num::Zero; use option::{None, Option, Some}; -use old_iter::EqIter; use ptr; use ptr::RawPtr; use to_str::ToStr; @@ -2225,7 +2224,6 @@ mod tests { use option::Some; use libc::c_char; use libc; - use old_iter::BaseIter; use ptr; use str::*; use vec; diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 56078a69f28f..9f8122886213 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -21,7 +21,6 @@ use iterator::IteratorUtil; use container::Map; use hash::Hash; use cmp::Eq; -use old_iter::BaseIter; use vec::ImmutableVector; use iterator::IteratorUtil; diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 39980ffa5991..e6449ef49229 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -176,22 +176,6 @@ pub struct TrieSet { priv map: TrieMap<()> } -impl BaseIter for TrieSet { - /// Visit all values in order - #[inline] - fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } - #[inline] - fn size_hint(&self) -> Option { Some(self.len()) } -} - -impl ReverseIter for TrieSet { - /// Visit all values in reverse order - #[inline] - fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool { - self.map.each_key_reverse(f) - } -} - impl Container for TrieSet { /// Return the number of elements in the set #[inline] @@ -234,6 +218,16 @@ impl TrieSet { pub fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) } + + /// Visit all values in order + #[inline] + pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) } + + /// Visit all values in reverse order + #[inline] + pub fn each_reverse(&self, f: &fn(&uint) -> bool) -> bool { + self.map.each_key_reverse(f) + } } struct TrieNode { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 17eb7e8e82be..aeb5b000747f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -17,7 +17,6 @@ use cast; use container::{Container, Mutable}; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; -use old_iter; use iterator::{FromIterator, Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; @@ -124,7 +123,7 @@ pub fn capacity(v: &const ~[T]) -> uint { * Creates an owned vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pub fn from_fn(n_elts: uint, op: old_iter::InitOp) -> ~[T] { +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| { @@ -815,7 +814,7 @@ pub fn grow(v: &mut ~[T], n: uint, initval: &T) { * * init_op - A function to call to retreive each appended element's * value */ -pub fn grow_fn(v: &mut ~[T], n: uint, op: old_iter::InitOp) { +pub fn grow_fn(v: &mut ~[T], n: uint, op: &fn(uint) -> T) { let new_len = v.len() + n; reserve_at_least(&mut *v, new_len); let mut i: uint = 0u; @@ -1985,7 +1984,7 @@ pub trait OwnedVector { 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: old_iter::InitOp); + fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T); } impl OwnedVector for ~[T] { @@ -2064,7 +2063,7 @@ impl OwnedVector for ~[T] { } #[inline] - fn grow_fn(&mut self, n: uint, op: old_iter::InitOp) { + fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T) { grow_fn(self, n, op); } } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index a20528082ab5..55ac9c5ec1c8 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -375,7 +375,7 @@ impl gen_init for protocol { let mut params: OptVec = opt_vec::Empty; for (copy self.states).iter().advance |s| { for s.generics.ty_params.each |tp| { - match params.find(|tpp| tp.ident == tpp.ident) { + match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () } @@ -393,7 +393,7 @@ impl gen_init for protocol { let mut params: OptVec = opt_vec::Empty; let fields = do (copy self.states).iter().transform |s| { for s.generics.ty_params.each |tp| { - match params.find(|tpp| tp.ident == tpp.ident) { + match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () } diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index c537a3e8eba3..8917b481dc72 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -17,9 +17,7 @@ */ use core::prelude::*; - -use core::old_iter; -use core::old_iter::BaseIter; +use core::vec::VecIterator; #[deriving(Encodable, Decodable)] pub enum OptVec { @@ -40,6 +38,13 @@ pub fn from(t: ~[T]) -> OptVec { } impl OptVec { + fn each(&self, blk: &fn(v: &T) -> bool) -> bool { + match *self { + Empty => true, + Vec(ref v) => v.iter().advance(blk) + } + } + fn push(&mut self, t: T) { match *self { Vec(ref mut v) => { @@ -78,6 +83,28 @@ impl OptVec { Vec(ref v) => v.len() } } + + #[inline] + fn iter<'r>(&'r self) -> OptVecIterator<'r, T> { + match *self { + Empty => OptVecIterator{iter: None}, + Vec(ref v) => OptVecIterator{iter: Some(v.iter())} + } + } + + #[inline] + fn map_to_vec(&self, op: &fn(&T) -> B) -> ~[B] { + self.iter().transform(op).collect() + } + + fn mapi_to_vec(&self, op: &fn(uint, &T) -> B) -> ~[B] { + let mut index = 0; + self.map_to_vec(|a| { + let i = index; + index += 1; + op(i, a) + }) + } } pub fn take_vec(v: OptVec) -> ~[T] { @@ -96,22 +123,6 @@ impl OptVec { } return Vec(v0); } - - fn push_all>(&mut self, from: &I) { - for from.each |e| { - self.push(copy *e); - } - } - - #[inline] - fn mapi_to_vec(&self, op: &fn(uint, &T) -> B) -> ~[B] { - let mut index = 0; - old_iter::map_to_vec(self, |a| { - let i = index; - index += 1; - op(i, a) - }) - } } impl Eq for OptVec { @@ -131,68 +142,16 @@ impl Eq for OptVec { } } -impl BaseIter for OptVec { - fn each(&self, blk: &fn(v: &A) -> bool) -> bool { - match *self { - Empty => true, - Vec(ref v) => v.iter().advance(blk) +pub struct OptVecIterator<'self, T> { + priv iter: Option> +} + +impl<'self, T> Iterator<&'self T> for OptVecIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self T> { + match self.iter { + Some(ref mut x) => x.next(), + None => None } } - - fn size_hint(&self) -> Option { - Some(self.len()) - } -} - -impl old_iter::ExtendedIter for OptVec { - #[inline] - fn eachi(&self, blk: &fn(v: uint, v: &A) -> bool) -> bool { - old_iter::eachi(self, blk) - } - #[inline] - fn all(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::all(self, blk) - } - #[inline] - fn any(&self, blk: &fn(&A) -> bool) -> bool { - old_iter::any(self, blk) - } - #[inline] - fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - old_iter::foldl(self, b0, blk) - } - #[inline] - fn position(&self, f: &fn(&A) -> bool) -> Option { - old_iter::position(self, f) - } - #[inline] - fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { - old_iter::map_to_vec(self, op) - } - #[inline] - fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) - -> ~[B] { - old_iter::flat_map_to_vec(self, op) - } - -} - -impl old_iter::EqIter for OptVec { - #[inline] - fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } - #[inline] - fn count(&self, x: &A) -> uint { old_iter::count(self, x) } -} - -impl old_iter::CopyableIter for OptVec { - #[inline] - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - old_iter::filter_to_vec(self, pred) - } - #[inline] - fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } - #[inline] - fn find(&self, f: &fn(&A) -> bool) -> Option { - old_iter::find(self, f) - } } diff --git a/src/test/run-fail/extern-fail.rs b/src/test/run-fail/extern-fail.rs index 2be41d3bed00..3d15ea16241f 100644 --- a/src/test/run-fail/extern-fail.rs +++ b/src/test/run-fail/extern-fail.rs @@ -13,7 +13,6 @@ // Instead the failure will be delivered after the callbacks return. use std::libc; -use std::old_iter; use std::task; mod rustrt { diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index 88686bcdbfa3..c54b8db46c88 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -13,7 +13,6 @@ use std::cmp; use std::container::{Container, Mutable, Map}; use std::int; -use std::old_iter::BaseIter; use std::uint; enum cat_type { tuxedo, tabby, tortoiseshell } diff --git a/src/test/run-pass/class-trait-bounded-param.rs b/src/test/run-pass/class-trait-bounded-param.rs deleted file mode 100644 index 75c62abcb0d5..000000000000 --- a/src/test/run-pass/class-trait-bounded-param.rs +++ /dev/null @@ -1,35 +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. - -// xfail-test - -extern mod extra; -use extra::oldmap::{map, hashmap, int_hash}; - -class keys> - : old_iter::base_iter { - - let map: M; - - new(map: M) { - self.map = map; - } - - fn each(blk: &fn(K) -> bool) { self.map.each(|k, _v| blk(k) ) } - fn size_hint() -> Option { Some(self.map.size()) } - fn eachi(blk: &fn(uint, K) -> bool) { old_iter::eachi(self, blk) } -} - -pub fn main() { - let m = int_hash(); - m.insert(1, 2); - m.insert(3, 4); - assert_eq!(old_iter::to_vec(keys(m)), ~[1, 3]); -} From adb8ac41620b42c1a27c8c013628e49701fb3b27 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Sat, 22 Jun 2013 14:43:15 -0400 Subject: [PATCH 103/336] Fix/annotate a variety of xfails --- .../run-pass/autoderef-method-priority.rs | 4 +- .../class-cast-to-trait-cross-crate.rs | 60 ------------------- .../class-impl-parameterized-trait.rs | 2 +- .../class-implements-multiple-traits.rs | 2 +- .../run-pass/coerce-reborrow-imm-vec-arg.rs | 6 +- .../run-pass/coerce-reborrow-imm-vec-rcvr.rs | 18 +++--- src/test/run-pass/deriving-global.rs | 2 +- src/test/run-pass/extern-mod-url.rs | 4 +- src/test/run-pass/fn-bare-size.rs | 7 +-- src/test/run-pass/foreign-mod.rc | 2 +- src/test/run-pass/issue-1866.rs | 4 +- src/test/run-pass/issue-2101.rs | 30 ---------- src/test/run-pass/issue-2190-2.rs | 20 +++---- src/test/run-pass/issue-3290.rs | 2 +- src/test/run-pass/issue-3796.rs | 2 +- src/test/run-pass/issue-3874.rs | 2 +- src/test/run-pass/issue-3979-2.rs | 7 ++- src/test/run-pass/issue-3979-generics.rs | 2 +- src/test/run-pass/issue-4241.rs | 8 ++- src/test/run-pass/issue-4541.rs | 3 +- src/test/run-pass/issue-4542.rs | 6 +- src/test/run-pass/issue_3882.rs | 3 +- src/test/run-pass/labeled-break.rs | 3 - src/test/run-pass/match-borrowed_str.rs | 6 +- src/test/run-pass/pipe-select-macro.rs | 2 +- src/test/run-pass/preempt.rs | 23 ++++--- src/test/run-pass/rcvr-borrowed-to-region.rs | 13 ++-- src/test/run-pass/regions-borrow-evec-at.rs | 2 - src/test/run-pass/resolve-issue-2428.rs | 2 - src/test/run-pass/tag-align-dyn-variants.rs | 2 +- src/test/run-pass/tag-align-u64.rs | 2 +- src/test/run-pass/trait-cast.rs | 28 ++++----- src/test/run-pass/traits.rs | 55 ----------------- src/test/run-pass/unconstrained-region.rs | 10 ++-- 34 files changed, 98 insertions(+), 246 deletions(-) delete mode 100644 src/test/run-pass/class-cast-to-trait-cross-crate.rs delete mode 100644 src/test/run-pass/issue-2101.rs delete mode 100644 src/test/run-pass/traits.rs diff --git a/src/test/run-pass/autoderef-method-priority.rs b/src/test/run-pass/autoderef-method-priority.rs index 9cfdac0a330b..0fe30059ef65 100644 --- a/src/test/run-pass/autoderef-method-priority.rs +++ b/src/test/run-pass/autoderef-method-priority.rs @@ -1,6 +1,4 @@ -// xfail-test -// xfail'd because of a problem with by-value self. - +// xfail-test #5321 // 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. diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate.rs b/src/test/run-pass/class-cast-to-trait-cross-crate.rs deleted file mode 100644 index 6674147e1476..000000000000 --- a/src/test/run-pass/class-cast-to-trait-cross-crate.rs +++ /dev/null @@ -1,60 +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. - -// xfail-test - -use to_str::*; -use to_str::to_str; - -class cat : to_str { - priv { - let mut meows : uint; - fn meow() { - error!("Meow"); - self.meows += 1u; - if self.meows % 5u == 0u { - self.how_hungry += 1; - } - } - } - - let mut how_hungry : int; - let name : str; - - new(in_x : uint, in_y : int, in_name: str) - { self.meows = in_x; self.how_hungry = in_y; self.name = in_name; } - - fn speak() { self.meow(); } - - fn eat() -> bool { - if self.how_hungry > 0 { - error!("OM NOM NOM"); - self.how_hungry -= 2; - return true; - } - else { - error!("Not hungry!"); - return false; - } - } - - fn to_str() -> str { self.name } -} - -fn print_out(thing: T, expected: str) { - let actual = thing.to_str(); - debug!("%s", actual); - assert_eq!(actual, expected); -} - -pub fn main() { - let nyan : to_str = cat(0u, 2, "nyan") as to_str; - print_out(nyan, "nyan"); -} diff --git a/src/test/run-pass/class-impl-parameterized-trait.rs b/src/test/run-pass/class-impl-parameterized-trait.rs index 09967f0ab361..655a9d4a0c07 100644 --- a/src/test/run-pass/class-impl-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-parameterized-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #7307 // xfail-fast extern mod extra; diff --git a/src/test/run-pass/class-implements-multiple-traits.rs b/src/test/run-pass/class-implements-multiple-traits.rs index 7a3045db91f1..8565ab038413 100644 --- a/src/test/run-pass/class-implements-multiple-traits.rs +++ b/src/test/run-pass/class-implements-multiple-traits.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #7305 extern mod extra; use extra::oldmap::*; diff --git a/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs b/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs index 3f12c0d63531..f0c5b58d1559 100644 --- a/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs +++ b/src/test/run-pass/coerce-reborrow-imm-vec-arg.rs @@ -1,8 +1,6 @@ -// xfail-test - fn sum(x: &[int]) -> int { let mut sum = 0; - for x.each |y| { sum += *y; } + for x.iter().advance |y| { sum += *y; } return sum; } @@ -14,8 +12,10 @@ fn sum_imm(y: &[int]) -> int { sum(y) } +/* FIXME #7304 fn sum_const(y: &const [int]) -> int { sum(y) } +*/ pub fn main() {} diff --git a/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs b/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs index 7ab80920849b..590cd8250208 100644 --- a/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs @@ -1,20 +1,20 @@ -// xfail-test - +/* FIXME #7302 fn foo(v: &const [uint]) -> ~[uint] { - v.to_vec() + v.to_owned() } +*/ fn bar(v: &mut [uint]) -> ~[uint] { - v.to_vec() + v.to_owned() } fn bip(v: &[uint]) -> ~[uint] { - v.to_vec() + v.to_owned() } pub fn main() { - let mut the_vec = ~[1, 2, 3, 100]; - assert_eq!(the_vec, foo(the_vec)); - assert_eq!(the_vec, bar(the_vec)); - assert_eq!(the_vec, bip(the_vec)); + let mut the_vec = ~[1u, 2, 3, 100]; +// assert_eq!(the_vec.clone(), foo(the_vec)); + assert_eq!(the_vec.clone(), bar(the_vec)); + assert_eq!(the_vec.clone(), bip(the_vec)); } diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs index 3d5bacee71c6..409c31f1fa5e 100644 --- a/src/test/run-pass/deriving-global.rs +++ b/src/test/run-pass/deriving-global.rs @@ -1,4 +1,4 @@ -// xfail-test #7103 `extern mod` does not work on windows +// xfail-fast #7103 `extern mod` does not work on windows // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at diff --git a/src/test/run-pass/extern-mod-url.rs b/src/test/run-pass/extern-mod-url.rs index 457c61067e3c..363c54f68129 100644 --- a/src/test/run-pass/extern-mod-url.rs +++ b/src/test/run-pass/extern-mod-url.rs @@ -10,7 +10,7 @@ // Just a test that new-style extern mods parse -// xfail-test +// xfail-test FIXME #6407 extern mod test = "github.com/catamorphism/test-pkg"; -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/test/run-pass/fn-bare-size.rs b/src/test/run-pass/fn-bare-size.rs index dc47dda420ce..144cc7c1e287 100644 --- a/src/test/run-pass/fn-bare-size.rs +++ b/src/test/run-pass/fn-bare-size.rs @@ -8,12 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test - -extern mod extra; +use std::sys; pub fn main() { // Bare functions should just be a pointer - assert!(sys::rustrt::size_of::() == - sys::rustrt::size_of::()); + assert_eq!(sys::size_of::(), sys::size_of::()); } diff --git a/src/test/run-pass/foreign-mod.rc b/src/test/run-pass/foreign-mod.rc index 390de8276573..a11e89f37be1 100644 --- a/src/test/run-pass/foreign-mod.rc +++ b/src/test/run-pass/foreign-mod.rc @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #7308 // -*- rust -*- native mod libc = target_libc { diff --git a/src/test/run-pass/issue-1866.rs b/src/test/run-pass/issue-1866.rs index cb5e9b111660..530f40c6a83d 100644 --- a/src/test/run-pass/issue-1866.rs +++ b/src/test/run-pass/issue-1866.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #1866 mod a { pub type rust_task = uint; pub mod rustrt { + use super::rust_task; pub extern { pub fn rust_task_is_unwinding(rt: *rust_task) -> bool; } @@ -21,6 +22,7 @@ mod a { mod b { pub type rust_task = bool; pub mod rustrt { + use super::rust_task; pub extern { pub fn rust_task_is_unwinding(rt: *rust_task) -> bool; } diff --git a/src/test/run-pass/issue-2101.rs b/src/test/run-pass/issue-2101.rs deleted file mode 100644 index 423888c1cf5b..000000000000 --- a/src/test/run-pass/issue-2101.rs +++ /dev/null @@ -1,30 +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. - -// xfail-test -extern mod extra; -use extra::arena; -use extra::arena::Arena; - -enum hold { s(str) } - -fn init(ar: &a.arena::Arena, str: str) -> &a.hold { - new(*ar) s(str) -} - -pub fn main(args: ~[str]) { - let ar = arena::Arena(); - let leak = init(&ar, args[0]); - match *leak { - s(astr) { - io::println(fmt!("%?", astr)); - } - }; -} diff --git a/src/test/run-pass/issue-2190-2.rs b/src/test/run-pass/issue-2190-2.rs index 3842e073faf1..d5ee712d412b 100644 --- a/src/test/run-pass/issue-2190-2.rs +++ b/src/test/run-pass/issue-2190-2.rs @@ -8,23 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #2190 mod a { -fn foo(f: &fn()) { f() } -fn bar() {} -pub fn main() { foo(||bar()); } + fn foo(f: &fn()) { f() } + fn bar() {} + pub fn main() { foo(||bar()); } } mod b { -fn foo(f: Option<&fn()>) { f.iter(|x|x()) } -fn bar() {} -pub fn main() { foo(Some(bar)); } + fn foo(f: Option<&fn()>) { f.iter(|x|x()) } + fn bar() {} + pub fn main() { foo(Some(bar)); } } mod c { -fn foo(f: Option<&fn()>) { f.iter(|x|x()) } -fn bar() {} -pub fn main() { foo(Some(||bar())); } + fn foo(f: Option<&fn()>) { f.iter(|x|x()) } + fn bar() {} + pub fn main() { foo(Some(||bar())); } } pub fn main() { diff --git a/src/test/run-pass/issue-3290.rs b/src/test/run-pass/issue-3290.rs index 3f8ce032d0d9..5cdc4238eafb 100644 --- a/src/test/run-pass/issue-3290.rs +++ b/src/test/run-pass/issue-3290.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #3290 fn main() { let mut x = ~3; x = x; diff --git a/src/test/run-pass/issue-3796.rs b/src/test/run-pass/issue-3796.rs index 0091c0962558..5f4409391396 100644 --- a/src/test/run-pass/issue-3796.rs +++ b/src/test/run-pass/issue-3796.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #3796 #[deny(dead_assignment)]; fn main() { let mut x = 1; diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs index f54d2f9fafc4..e293e40ac690 100644 --- a/src/test/run-pass/issue-3874.rs +++ b/src/test/run-pass/issue-3874.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #3874 enum PureCounter { PureCounter(uint) } fn each(self: PureCounter, blk: &fn(v: &uint)) { diff --git a/src/test/run-pass/issue-3979-2.rs b/src/test/run-pass/issue-3979-2.rs index a04e35108028..9a8b90db185b 100644 --- a/src/test/run-pass/issue-3979-2.rs +++ b/src/test/run-pass/issue-3979-2.rs @@ -9,16 +9,17 @@ // except according to those terms. // xfail-test + trait A { - fn a_method(); + fn a_method(&self); } trait B: A { - fn b_method(); + fn b_method(&self); } trait C: B { - fn c_method() { + fn c_method(&self) { self.a_method(); } } diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs index b91ec5711cf2..5884a35a1a10 100644 --- a/src/test/run-pass/issue-3979-generics.rs +++ b/src/test/run-pass/issue-3979-generics.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// xfail-test FIXME #5946 trait Positioned { fn SetX(&mut self, S); fn X(&self) -> S; diff --git a/src/test/run-pass/issue-4241.rs b/src/test/run-pass/issue-4241.rs index 23e5f3945b12..720ce7a2c27f 100644 --- a/src/test/run-pass/issue-4241.rs +++ b/src/test/run-pass/issue-4241.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test extern mod extra; use extra::net::tcp::TcpSocketBuf; +use std::io; +use std::int; + use std::io::{ReaderUtil,WriterUtil}; enum Result { @@ -97,9 +99,9 @@ priv fn cmd_to_str(cmd: ~[~str]) -> ~str { let mut res = ~"*"; res.push_str(cmd.len().to_str()); res.push_str("\r\n"); - for cmd.each |s| { + for cmd.iter().advance |s| { res.push_str([~"$", s.len().to_str(), ~"\r\n", - copy *s, ~"\r\n"].concat())); + copy *s, ~"\r\n"].concat() ); } res } diff --git a/src/test/run-pass/issue-4541.rs b/src/test/run-pass/issue-4541.rs index 24a8adfcb1a5..4d59ea0fba32 100644 --- a/src/test/run-pass/issue-4541.rs +++ b/src/test/run-pass/issue-4541.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +use std::io; + fn parse_args() -> ~str { let args = std::os::args(); let mut n = 0; diff --git a/src/test/run-pass/issue-4542.rs b/src/test/run-pass/issue-4542.rs index a5e5b10d0764..4aa83b853de4 100644 --- a/src/test/run-pass/issue-4542.rs +++ b/src/test/run-pass/issue-4542.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +use std::os; + pub fn main() { - for os::args().each |arg| { + let x = os::args(); + for x.iter().advance |arg| { match arg.clone() { s => { } } diff --git a/src/test/run-pass/issue_3882.rs b/src/test/run-pass/issue_3882.rs index 7b1af0d151f7..202385681ce6 100644 --- a/src/test/run-pass/issue_3882.rs +++ b/src/test/run-pass/issue_3882.rs @@ -1,5 +1,3 @@ -// xfail-test - // 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. @@ -10,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test // aux-build:issue_3882.rc extern mod linenoise; use linenoise::issue_3882::*; diff --git a/src/test/run-pass/labeled-break.rs b/src/test/run-pass/labeled-break.rs index 32cd7f0c7f8a..b6b6e0e14379 100644 --- a/src/test/run-pass/labeled-break.rs +++ b/src/test/run-pass/labeled-break.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-fast -// xfail-test - pub fn main() { 'foo: loop { loop { diff --git a/src/test/run-pass/match-borrowed_str.rs b/src/test/run-pass/match-borrowed_str.rs index 1a58174a3fbc..99e1ae6ec56e 100644 --- a/src/test/run-pass/match-borrowed_str.rs +++ b/src/test/run-pass/match-borrowed_str.rs @@ -1,6 +1,8 @@ -// xfail-test +// FIXME #7306 // xfail-fast -// -*- rust -*- + +use std::io; + fn f1(ref_string: &str) { match ref_string { "a" => io::println("found a"), diff --git a/src/test/run-pass/pipe-select-macro.rs b/src/test/run-pass/pipe-select-macro.rs index a77e6acbb250..2db660541450 100644 --- a/src/test/run-pass/pipe-select-macro.rs +++ b/src/test/run-pass/pipe-select-macro.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +// FIXME #7303: xfail-test // Protocols proto! foo ( diff --git a/src/test/run-pass/preempt.rs b/src/test/run-pass/preempt.rs index 3d3e178f064a..aa750c21d458 100644 --- a/src/test/run-pass/preempt.rs +++ b/src/test/run-pass/preempt.rs @@ -11,23 +11,30 @@ // xfail-test // This checks that preemption works. -fn starve_main(alive: chan) { +// note: halfway done porting to modern rust +extern mod extra; + +use std::comm; +use extra::comm; + +fn starve_main(alive: Port) { debug!("signalling main"); - alive.recv(1); + alive.recv(); debug!("starving main"); - let i: int = 0; + let mut i: int = 0; loop { i += 1; } } pub fn main() { - let alive: port = port(); + let (port, chan) = stream(); + debug!("main started"); - let s: task = do task::spawn { - starve_main(chan(alive)); + do spawn { + starve_main(port); }; - let i: int; + let mut i: int = 0; debug!("main waiting for alive signal"); - alive.send(i); + chan.send(i); debug!("main got alive signal"); while i < 50 { debug!("main iterated"); i += 1; } debug!("main completed"); diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs index fbd7d851fa37..c8e87af9ec0a 100644 --- a/src/test/run-pass/rcvr-borrowed-to-region.rs +++ b/src/test/run-pass/rcvr-borrowed-to-region.rs @@ -1,6 +1,3 @@ -// xfail-test -// xfail'd due to segfaults with by-value self. - // 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. @@ -15,26 +12,24 @@ trait get { fn get(self) -> int; } -// Note: impl on a slice -impl get for &'self int { +// FIXME #7302: Note: impl on a slice +impl<'self> get for &'self int { fn get(self) -> int { - return **self; + return *self; } } pub fn main() { - /* let x = @mut 6; let y = x.get(); assert_eq!(y, 6); - */ let x = @6; let y = x.get(); debug!("y=%d", y); assert_eq!(y, 6); - let mut x = ~6; + let x = ~6; let y = x.get(); debug!("y=%d", y); assert_eq!(y, 6); diff --git a/src/test/run-pass/regions-borrow-evec-at.rs b/src/test/run-pass/regions-borrow-evec-at.rs index a018dad64b36..45e5b1ad9c94 100644 --- a/src/test/run-pass/regions-borrow-evec-at.rs +++ b/src/test/run-pass/regions-borrow-evec-at.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test - fn foo(x: &[uint]) -> uint { x[0] } diff --git a/src/test/run-pass/resolve-issue-2428.rs b/src/test/run-pass/resolve-issue-2428.rs index 6d00210898bd..57f6596d1d72 100644 --- a/src/test/run-pass/resolve-issue-2428.rs +++ b/src/test/run-pass/resolve-issue-2428.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test - static foo: int = 4 >> 1; enum bs { thing = foo } pub fn main() { assert!((thing as int == foo)); } diff --git a/src/test/run-pass/tag-align-dyn-variants.rs b/src/test/run-pass/tag-align-dyn-variants.rs index cd94bd30c21e..c360b6134551 100644 --- a/src/test/run-pass/tag-align-dyn-variants.rs +++ b/src/test/run-pass/tag-align-dyn-variants.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +use std::ptr; enum a_tag { varA(A), diff --git a/src/test/run-pass/tag-align-u64.rs b/src/test/run-pass/tag-align-u64.rs index ea60f389663c..776c7d9ca448 100644 --- a/src/test/run-pass/tag-align-u64.rs +++ b/src/test/run-pass/tag-align-u64.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test +use std::ptr; enum a_tag { a_tag(u64) diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs index f21ea06697d8..637fc7a70f58 100644 --- a/src/test/run-pass/trait-cast.rs +++ b/src/test/run-pass/trait-cast.rs @@ -1,4 +1,4 @@ -// xfail-test +// xfail-test FIXME #5882 // Weird borrow check bug // Copyright 2012 The Rust Project Developers. See the COPYRIGHT @@ -17,45 +17,45 @@ struct Tree(@mut TreeR); struct TreeR { left: Option, right: Option, - val: to_str + val: ~to_str } trait to_str { - fn to_str(&self) -> ~str; + fn to_str_(&self) -> ~str; } impl to_str for Option { - fn to_str(&self) -> ~str { + fn to_str_(&self) -> ~str { match *self { None => { ~"none" } - Some(ref t) => { ~"some(" + t.to_str() + ~")" } + Some(ref t) => { ~"some(" + t.to_str_() + ~")" } } } } impl to_str for int { - fn to_str(&self) -> ~str { int::str(*self) } + fn to_str_(&self) -> ~str { self.to_str() } } impl to_str for Tree { - fn to_str(&self) -> ~str { - let l = self.left, r = self.right; + fn to_str_(&self) -> ~str { + let (l, r) = (self.left, self.right); let val = &self.val; - fmt!("[%s, %s, %s]", val.to_str(), l.to_str(), r.to_str()) + fmt!("[%s, %s, %s]", val.to_str_(), l.to_str_(), r.to_str_()) } } -fn foo(x: T) -> ~str { x.to_str() } +fn foo(x: T) -> ~str { x.to_str_() } pub fn main() { let t1 = Tree(@mut TreeR{left: None, right: None, - val: 1 as to_str }); + val: ~1 as ~to_str }); let t2 = Tree(@mut TreeR{left: Some(t1), right: Some(t1), - val: 2 as to_str }); + val: ~2 as ~to_str }); let expected = ~"[2, some([1, none, none]), some([1, none, none])]"; - assert_eq!(t2.to_str(), expected); - assert_eq!(foo(t2 as to_str), expected); + assert!(t2.to_str_() == expected); + assert!(foo(t2) == expected); t1.left = Some(t2); // create cycle } diff --git a/src/test/run-pass/traits.rs b/src/test/run-pass/traits.rs deleted file mode 100644 index ba3e8e082b34..000000000000 --- a/src/test/run-pass/traits.rs +++ /dev/null @@ -1,55 +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. - -//xfail-test - -// Sketching traits. - -// methods with no implementation are required; methods with an -// implementation are provided. No "req" keyword necessary. -trait Eq { - fn eq(a: self) -> bool; - - fn neq(a: self) -> bool { - !self.eq(a) - } -} - -// The `<` is pronounced `extends`. Also under consideration is `<:`. -// Just using `:` is frowned upon, because (paraphrasing dherman) `:` -// is supposed to separate things from different universes. -trait Ord < Eq { - - fn lt(a: self) -> bool; - - fn lte(a: self) -> bool { - self.lt(a) || self.eq(a) - } - - fn gt(a: self) -> bool { - !self.lt(a) && !self.eq(a) - } - - fn gte(a: self) -> bool { - !self.lt(a) - } -} - -// pronounced "impl of Ord for int" -- not sold on this yet -impl Ord for int { - fn lt(a: &int) -> bool { - self < (*a) - } - - // is this the place to put this? - fn eq(a: &int) -> bool { - self == (*a) - } -} diff --git a/src/test/run-pass/unconstrained-region.rs b/src/test/run-pass/unconstrained-region.rs index b6e2ba553df4..4882baceaa81 100644 --- a/src/test/run-pass/unconstrained-region.rs +++ b/src/test/run-pass/unconstrained-region.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test -// See #3283 -fn foo(blk: &fn(p: &'a fn() -> &'a fn())) { - let mut state = 0; - let statep = &mut state; +fn foo<'a>(blk: &fn(p: &'a fn() -> &'a fn())) { + let mut state = 0; + let statep = &mut state; do blk { || { *statep = 1; } } } fn main() { do foo |p| { p()() } -} \ No newline at end of file +} From 369b0a56e8db535272596eada65717c0e3fc35e8 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 23 Jun 2013 21:28:20 -0400 Subject: [PATCH 104/336] xfail tests again for now (issues #7336, #7340) --- src/test/run-pass/tag-align-dyn-variants.rs | 2 ++ src/test/run-pass/tag-align-u64.rs | 2 ++ src/test/run-pass/unconstrained-region.rs | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/test/run-pass/tag-align-dyn-variants.rs b/src/test/run-pass/tag-align-dyn-variants.rs index c360b6134551..85a4f98d198c 100644 --- a/src/test/run-pass/tag-align-dyn-variants.rs +++ b/src/test/run-pass/tag-align-dyn-variants.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test + use std::ptr; enum a_tag { diff --git a/src/test/run-pass/tag-align-u64.rs b/src/test/run-pass/tag-align-u64.rs index 776c7d9ca448..28088aa571eb 100644 --- a/src/test/run-pass/tag-align-u64.rs +++ b/src/test/run-pass/tag-align-u64.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test + use std::ptr; enum a_tag { diff --git a/src/test/run-pass/unconstrained-region.rs b/src/test/run-pass/unconstrained-region.rs index 4882baceaa81..2341ee8d100c 100644 --- a/src/test/run-pass/unconstrained-region.rs +++ b/src/test/run-pass/unconstrained-region.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test +// FIXME: #7336: codegen bug makes this segfault on Linux x86_64 + fn foo<'a>(blk: &fn(p: &'a fn() -> &'a fn())) { let mut state = 0; let statep = &mut state; From 60ed6596204a614e50caf9e01dabca017e275476 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 23 Jun 2013 21:58:45 -0400 Subject: [PATCH 105/336] deal with windows --- src/test/run-pass/deriving-meta-empty-trait-list.rs | 2 ++ src/test/run-pass/issue-4241.rs | 2 ++ src/test/run-pass/issue-4541.rs | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/deriving-meta-empty-trait-list.rs b/src/test/run-pass/deriving-meta-empty-trait-list.rs index 8e7afffaf0db..955e02d4d2d8 100644 --- a/src/test/run-pass/deriving-meta-empty-trait-list.rs +++ b/src/test/run-pass/deriving-meta-empty-trait-list.rs @@ -10,6 +10,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-fast + #[deriving] //~ WARNING empty trait list in `deriving` struct Foo; diff --git a/src/test/run-pass/issue-4241.rs b/src/test/run-pass/issue-4241.rs index 720ce7a2c27f..5b668d710dde 100644 --- a/src/test/run-pass/issue-4241.rs +++ b/src/test/run-pass/issue-4241.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-fast + extern mod extra; use extra::net::tcp::TcpSocketBuf; diff --git a/src/test/run-pass/issue-4541.rs b/src/test/run-pass/issue-4541.rs index 4d59ea0fba32..7b80974313e3 100644 --- a/src/test/run-pass/issue-4541.rs +++ b/src/test/run-pass/issue-4541.rs @@ -11,7 +11,7 @@ use std::io; fn parse_args() -> ~str { - let args = std::os::args(); + let args = ::std::os::args(); let mut n = 0; while n < args.len() { From 8779be39e1a6e064d75cc32ad3610fad9a4fa9a6 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 23 Jun 2013 22:16:19 -0400 Subject: [PATCH 106/336] implement Clone for slices --- src/libstd/clone.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index 5ec594cef7ee..046693632c60 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -56,6 +56,18 @@ impl<'self, T> Clone for &'self T { fn clone(&self) -> &'self T { *self } } +impl<'self, T> Clone for &'self [T] { + /// Return a shallow copy of the slice. + #[inline] + fn clone(&self) -> &'self [T] { *self } +} + +impl<'self> Clone for &'self str { + /// Return a shallow copy of the slice. + #[inline] + fn clone(&self) -> &'self str { *self } +} + macro_rules! clone_impl( ($t:ty) => { impl Clone for $t { From 3ab5ec4b7c854290ad1bc5192c70cbc0856a5fa7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 01:21:32 -0400 Subject: [PATCH 107/336] iterator: implement `collect` with FromIterator This makes it take advantage of the size hint for pre-allocation. --- src/libstd/iterator.rs | 10 +++++----- src/libstd/vec.rs | 11 +++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 46e059355941..d96191f296d7 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -20,7 +20,7 @@ implementing the `Iterator` trait. #[allow(default_methods)]; // solid enough for the use case here use cmp; -use iter::{FromIter, Times}; +use iter::Times; use num::{Zero, One}; use option::{Option, Some, None}; use ops::{Add, Mul}; @@ -240,7 +240,7 @@ pub trait IteratorUtil { fn advance(&mut self, f: &fn(A) -> bool) -> bool; /// Loops through the entire iterator, collecting all of the elements into - /// a container implementing `FromIter`. + /// a container implementing `FromIterator`. /// /// # Example /// @@ -249,7 +249,7 @@ pub trait IteratorUtil { /// let b: ~[int] = a.iter().transform(|&x| x).collect(); /// assert!(a == b); /// ~~~ - fn collect>(&mut self) -> B; + fn collect>(&mut self) -> B; /// Loops through `n` iterations, returning the `n`th element of the /// iterator. @@ -411,8 +411,8 @@ impl> IteratorUtil for T { } #[inline] - fn collect>(&mut self) -> B { - FromIter::from_iter::(|f| self.advance(f)) + fn collect>(&mut self) -> B { + FromIterator::from_iterator(self) } /// Return the `n`th item yielded by an iterator. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index aeb5b000747f..dd3c23d1084e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2500,6 +2500,17 @@ impl FromIter for ~[T]{ } } +#[cfg(stage0)] +impl> FromIterator for ~[A] { + pub fn from_iterator(iterator: &mut T) -> ~[A] { + let mut xs = ~[]; + for iterator.advance |x| { + xs.push(x); + } + xs + } +} + #[cfg(not(stage0))] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { From 1e7ca8dd24f4ea7e2aefa46dbf75f8695d139375 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 01:45:06 -0400 Subject: [PATCH 108/336] xfail-pretty on un-xfailed test --- src/test/run-pass/deriving-global.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs index 409c31f1fa5e..7804ce48c705 100644 --- a/src/test/run-pass/deriving-global.rs +++ b/src/test/run-pass/deriving-global.rs @@ -1,4 +1,5 @@ // xfail-fast #7103 `extern mod` does not work on windows +// xfail-pretty - does not converge // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at From da1a9a30fd647dee99713b3ae3b65f006641c14e Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 01:57:08 -0400 Subject: [PATCH 109/336] work around ICE from default method issue #7341 --- src/libstd/vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index dd3c23d1084e..7b7a3020b939 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2500,7 +2500,6 @@ impl FromIter for ~[T]{ } } -#[cfg(stage0)] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let mut xs = ~[]; @@ -2511,7 +2510,7 @@ impl> FromIterator for ~[A] { } } -#[cfg(not(stage0))] +/* FIXME: #7341 - ICE impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let (lower, _) = iterator.size_hint(); @@ -2522,6 +2521,7 @@ impl> FromIterator for ~[A] { xs } } +*/ #[cfg(test)] mod tests { From 6291702cf334f4b1fe41662bc3b0d996ca7ced19 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Mon, 24 Jun 2013 02:34:38 +0200 Subject: [PATCH 110/336] iterator: Add `IteratorUtil::flat_map_` method flat_map_ produces an iterator that maps each element to an iterator, and yields the elements of the produced iterators. This is the monadic bind :: M a -> (a -> M b) -> M b for iterators. Named just like the vec method, but with a trailing underline until the method resolution bug is resolved. --- src/libstd/iterator.rs | 67 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index d96191f296d7..5e866f25b6a3 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -226,6 +226,26 @@ pub trait IteratorUtil { fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option) -> ScanIterator<'r, A, B, Self, St>; + /// Creates an iterator that maps each element to an iterator, + /// and yields the elements of the produced iterators + /// + /// # Example + /// + /// ~~~ {.rust} + /// let xs = [2u, 3]; + /// let ys = [0u, 1, 0, 1, 2]; + /// let mut it = xs.iter().flat_map_(|&x| Counter::new(0u, 1).take_(x)); + /// // Check that `it` has the same elements as `ys` + /// let mut i = 0; + /// for it.advance |x: uint| { + /// assert_eq!(x, ys[i]); + /// i += 1; + /// } + /// ~~~ + // FIXME: #5898: should be called `flat_map` + fn flat_map_<'r, B, U: Iterator>(self, f: &'r fn(A) -> U) + -> FlatMapIterator<'r, A, B, Self, U>; + /// An adaptation of an external iterator to the for-loop protocol of rust. /// /// # Example @@ -397,6 +417,12 @@ impl> IteratorUtil for T { ScanIterator{iter: self, f: f, state: initial_state} } + #[inline] + fn flat_map_<'r, B, U: Iterator>(self, f: &'r fn(A) -> U) + -> FlatMapIterator<'r, A, B, T, U> { + FlatMapIterator{iter: self, f: f, subiter: None } + } + /// A shim implementing the `for` loop iteration protocol for iterator objects #[inline] fn advance(&mut self, f: &fn(A) -> bool) -> bool { @@ -873,6 +899,34 @@ impl<'self, A, B, T: Iterator, St> Iterator for ScanIterator<'self, A, B, } } +/// An iterator that maps each element to an iterator, +/// and yields the elements of the produced iterators +/// +// FIXME #6967: Dummy B parameter to get around type inference bug +pub struct FlatMapIterator<'self, A, B, T, U> { + priv iter: T, + priv f: &'self fn(A) -> U, + priv subiter: Option, +} + +impl<'self, A, T: Iterator, B, U: Iterator> Iterator for + FlatMapIterator<'self, A, B, T, U> { + #[inline] + fn next(&mut self) -> Option { + loop { + for self.subiter.mut_iter().advance |inner| { + for inner.advance |x| { + return Some(x) + } + } + match self.iter.next().map_consume(self.f) { + None => return None, + next => self.subiter = next, + } + } + } +} + /// An iterator which just modifies the contained state throughout iteration. pub struct UnfoldrIterator<'self, A, St> { priv f: &'self fn(&mut St) -> Option, @@ -1051,6 +1105,19 @@ mod tests { assert_eq!(i, ys.len()); } + #[test] + fn test_iterator_flat_map() { + let xs = [0u, 3, 6]; + let ys = [0u, 1, 2, 3, 4, 5, 6, 7, 8]; + let mut it = xs.iter().flat_map_(|&x| Counter::new(x, 1).take_(3)); + let mut i = 0; + for it.advance |x: uint| { + assert_eq!(x, ys[i]); + i += 1; + } + assert_eq!(i, ys.len()); + } + #[test] fn test_unfoldr() { fn count(st: &mut uint) -> Option { From fe6a4fd74a0a640fa9291f7cd4d31778da85e39b Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Mon, 24 Jun 2013 08:05:41 -0400 Subject: [PATCH 111/336] Un-xfail working test --- src/test/run-pass/newlambdas-ret-infer2.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/run-pass/newlambdas-ret-infer2.rs b/src/test/run-pass/newlambdas-ret-infer2.rs index 4b580e7fa797..4dfe3575eb59 100644 --- a/src/test/run-pass/newlambdas-ret-infer2.rs +++ b/src/test/run-pass/newlambdas-ret-infer2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test ~fn is not inferred // Test that the lambda kind is inferred correctly as a return // expression From b94f89fffc0c31a2e9048a824a66ff121c908818 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Jun 2013 07:42:22 -0700 Subject: [PATCH 112/336] Fix 'static mut' tests --- src/test/run-pass/static-mut-foreign.rs | 2 +- src/test/run-pass/static-mut-xc.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/run-pass/static-mut-foreign.rs b/src/test/run-pass/static-mut-foreign.rs index 66d34c7e454d..7af143a15292 100644 --- a/src/test/run-pass/static-mut-foreign.rs +++ b/src/test/run-pass/static-mut-foreign.rs @@ -41,6 +41,6 @@ unsafe fn run() { static_bound_set(&mut debug_static_mut); } -fn main() { +pub fn main() { unsafe { run() } } diff --git a/src/test/run-pass/static-mut-xc.rs b/src/test/run-pass/static-mut-xc.rs index 72f44fcd5010..ab6bdc20c491 100644 --- a/src/test/run-pass/static-mut-xc.rs +++ b/src/test/run-pass/static-mut-xc.rs @@ -37,7 +37,7 @@ unsafe fn run() { static_bound_set(&mut static_mut_xc::a); } -fn main() { +pub fn main() { unsafe { run() } } From 0a74ffcf042cfd6d4b1890e2c2b46e3e0ebaacfd Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 24 Jun 2013 18:35:43 +0200 Subject: [PATCH 113/336] vim/syntax/rust.vim: fix date header The last change was made in 2013 not 2012. --- src/etc/vim/syntax/rust.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 625424ac8709..2c3e09a3e179 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -2,7 +2,7 @@ " Language: Rust " Maintainer: Patrick Walton " Maintainer: Ben Blum -" Last Change: 2012 Jun 14 +" Last Change: 2013 Jun 14 if version < 600 syntax clear From 079b07df55636533db6d135f22cc235eb2e2b869 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 20 Jun 2013 13:44:42 +0200 Subject: [PATCH 114/336] libc: support functions from sys/mman.h Because its part of POSIX. Values are taken from FreeBSD, linux and OSX header files. --- src/libstd/libc.rs | 271 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 269 insertions(+), 2 deletions(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 988fb5cc9b15..2aaeda69326b 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -102,10 +102,12 @@ pub use libc::funcs::posix88::stdio::*; pub use libc::funcs::posix88::fcntl::*; pub use libc::funcs::posix88::dirent::*; pub use libc::funcs::posix88::unistd::*; +pub use libc::funcs::posix88::mman::*; pub use libc::funcs::posix01::stat_::*; pub use libc::funcs::posix01::unistd::*; pub use libc::funcs::posix01::glob::*; +pub use libc::funcs::posix01::mman::*; pub use libc::funcs::posix08::unistd::*; pub use libc::funcs::bsd44::*; @@ -1043,6 +1045,8 @@ pub mod consts { #[cfg(target_arch = "x86_64")] #[cfg(target_arch = "arm")] pub mod posix88 { + use libc::types::common::c95::c_void; + pub static O_RDONLY : int = 0; pub static O_WRONLY : int = 1; pub static O_RDWR : int = 2; @@ -1085,9 +1089,31 @@ pub mod consts { pub static SIGPIPE : int = 13; pub static SIGALRM : int = 14; pub static SIGTERM : int = 15; + + pub static PROT_NONE : int = 0; + pub static PROT_READ : int = 1; + pub static PROT_WRITE : int = 2; + pub static PROT_EXEC : int = 4; + + pub static MAP_FILE : int = 0x0000; + pub static MAP_SHARED : int = 0x0001; + pub static MAP_PRIVATE : int = 0x0002; + pub static MAP_FIXED : int = 0x0010; + pub static MAP_ANON : int = 0x1000; + + pub static MAP_FAILED : *c_void = -1 as *c_void; + + pub static MCL_CURRENT : int = 0x0001; + pub static MCL_FUTURE : int = 0x0002; + + pub static MS_ASYNC : int = 0x0001; + pub static MS_INVALIDATE : int = 0x0002; + pub static MS_SYNC : int = 0x0004; } #[cfg(target_arch = "mips")] pub mod posix88 { + use libc::types::common::c95::c_void; + pub static O_RDONLY : int = 0; pub static O_WRONLY : int = 1; pub static O_RDWR : int = 2; @@ -1130,6 +1156,26 @@ pub mod consts { pub static SIGPIPE : int = 13; pub static SIGALRM : int = 14; pub static SIGTERM : int = 15; + + pub static PROT_NONE : int = 0; + pub static PROT_READ : int = 1; + pub static PROT_WRITE : int = 2; + pub static PROT_EXEC : int = 4; + + pub static MAP_FILE : int = 0x0000; + pub static MAP_SHARED : int = 0x0001; + pub static MAP_PRIVATE : int = 0x0002; + pub static MAP_FIXED : int = 0x0010; + pub static MAP_ANON : int = 0x1000; + + pub static MAP_FAILED : *c_void = -1 as *c_void; + + pub static MCL_CURRENT : int = 0x0001; + pub static MCL_FUTURE : int = 0x0002; + + pub static MS_ASYNC : int = 0x0001; + pub static MS_INVALIDATE : int = 0x0002; + pub static MS_SYNC : int = 0x0004; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1145,10 +1191,27 @@ pub mod consts { pub static GLOB_NOSPACE : int = 1; pub static GLOB_ABORTED : int = 2; pub static GLOB_NOMATCH : int = 3; + + pub static POSIX_MADV_NORMAL : int = 0; + pub static POSIX_MADV_RANDOM : int = 1; + pub static POSIX_MADV_SEQUENTIAL : int = 2; + pub static POSIX_MADV_WILLNEED : int = 3; + pub static POSIX_MADV_DONTNEED : int = 4; } pub mod posix08 { } pub mod bsd44 { + pub static MADV_NORMAL : int = 0; + pub static MADV_RANDOM : int = 1; + pub static MADV_SEQUENTIAL : int = 2; + pub static MADV_WILLNEED : int = 3; + pub static MADV_DONTNEED : int = 4; + pub static MADV_REMOVE : int = 9; + pub static MADV_DONTFORK : int = 10; + pub static MADV_DOFORK : int = 11; + pub static MADV_MERGEABLE : int = 12; + pub static MADV_UNMERGEABLE : int = 13; + pub static MADV_HWPOISON : int = 100; } #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] @@ -1157,12 +1220,42 @@ pub mod consts { pub static O_RSYNC : int = 1052672; pub static O_DSYNC : int = 4096; pub static O_SYNC : int = 1052672; + + pub static PROT_GROWSDOWN : int = 0x010000000; + pub static PROT_GROWSUP : int = 0x020000000; + + pub static MAP_TYPE : int = 0x000f; + pub static MAP_ANONONYMOUS : int = 0x1000; + pub static MAP_32BIT : int = 0x0040; + pub static MAP_GROWSDOWN : int = 0x0100; + pub static MAP_DENYWRITE : int = 0x0800; + pub static MAP_EXECUTABLE : int = 0x01000; + pub static MAP_LOCKED : int = 0x02000; + pub static MAP_NONRESERVE : int = 0x04000; + pub static MAP_POPULATE : int = 0x08000; + pub static MAP_NONBLOCK : int = 0x010000; + pub static MAP_STACK : int = 0x020000; } #[cfg(target_arch = "mips")] pub mod extra { pub static O_RSYNC : int = 16400; pub static O_DSYNC : int = 16; pub static O_SYNC : int = 16400; + + pub static PROT_GROWSDOWN : int = 0x010000000; + pub static PROT_GROWSUP : int = 0x020000000; + + pub static MAP_TYPE : int = 0x000f; + pub static MAP_ANONONYMOUS : int = 0x1000; + pub static MAP_32BIT : int = 0x0040; + pub static MAP_GROWSDOWN : int = 0x0100; + pub static MAP_DENYWRITE : int = 0x0800; + pub static MAP_EXECUTABLE : int = 0x01000; + pub static MAP_LOCKED : int = 0x02000; + pub static MAP_NONRESERVE : int = 0x04000; + pub static MAP_POPULATE : int = 0x08000; + pub static MAP_NONBLOCK : int = 0x010000; + pub static MAP_STACK : int = 0x020000; } } @@ -1188,6 +1281,8 @@ pub mod consts { pub mod c99 { } pub mod posix88 { + use libc::types::common::c95::c_void; + pub static O_RDONLY : int = 0; pub static O_WRONLY : int = 1; pub static O_RDWR : int = 2; @@ -1230,6 +1325,26 @@ pub mod consts { pub static SIGPIPE : int = 13; pub static SIGALRM : int = 14; pub static SIGTERM : int = 15; + + pub static PROT_NONE : int = 0; + pub static PROT_READ : int = 1; + pub static PROT_WRITE : int = 2; + pub static PROT_EXEC : int = 4; + + pub static MAP_FILE : int = 0x0000; + pub static MAP_SHARED : int = 0x0001; + pub static MAP_PRIVATE : int = 0x0002; + pub static MAP_FIXED : int = 0x0010; + pub static MAP_ANON : int = 0x1000; + + pub static MAP_FAILED : *c_void = -1 as *c_void; + + pub static MCL_CURRENT : int = 0x0001; + pub static MCL_FUTURE : int = 0x0002; + + pub static MS_SYNC : int = 0x0000; + pub static MS_ASYNC : int = 0x0001; + pub static MS_INVALIDATE : int = 0x0002; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1245,16 +1360,48 @@ pub mod consts { pub static GLOB_NOSPACE : int = -1; pub static GLOB_ABORTED : int = -2; pub static GLOB_NOMATCH : int = -3; + + pub static POSIX_MADV_NORMAL : int = 0; + pub static POSIX_MADV_RANDOM : int = 1; + pub static POSIX_MADV_SEQUENTIAL : int = 2; + pub static POSIX_MADV_WILLNEED : int = 3; + pub static POSIX_MADV_DONTNEED : int = 4; } pub mod posix08 { } pub mod bsd44 { + pub static MADV_NORMAL : int = 0; + pub static MADV_RANDOM : int = 1; + pub static MADV_SEQUENTIAL : int = 2; + pub static MADV_WILLNEED : int = 3; + pub static MADV_DONTNEED : int = 4; + pub static MADV_FREE : int = 5; + pub static MADV_NOSYNC : int = 6; + pub static MADV_AUTOSYNC : int = 7; + pub static MADV_NOCORE : int = 8; + pub static MADV_CORE : int = 9; + pub static MADV_PROTECT : int = 10; + + pub static MINCORE_INCORE : int = 0x1; + pub static MINCORE_REFERENCED : int = 0x2; + pub static MINCORE_MODIFIED : int = 0x4; + pub static MINCORE_REFERENCED_OTHER : int = 0x8; + pub static MINCORE_MODIFIED_OTHER : int = 0x10; + pub static MINCORE_SUPER : int = 0x20; } pub mod extra { pub static O_SYNC : int = 128; pub static CTL_KERN: int = 1; pub static KERN_PROC: int = 14; pub static KERN_PROC_PATHNAME: int = 12; + + pub static MAP_COPY : int = 0x0002; + pub static MAP_RENAME : int = 0x0020; + pub static MAP_NORESERVE : int = 0x0040; + pub static MAP_HASSEMAPHORE : int = 0x0200; + pub static MAP_STACK : int = 0x0400; + pub static MAP_NOSYNC : int = 0x0800; + pub static MAP_NOCORE : int = 0x020000; } } @@ -1280,6 +1427,8 @@ pub mod consts { pub mod c99 { } pub mod posix88 { + use libc::types::common::c95::c_void; + pub static O_RDONLY : int = 0; pub static O_WRONLY : int = 1; pub static O_RDWR : int = 2; @@ -1322,6 +1471,29 @@ pub mod consts { pub static SIGPIPE : int = 13; pub static SIGALRM : int = 14; pub static SIGTERM : int = 15; + + pub static PROT_NONE : int = 0; + pub static PROT_READ : int = 1; + pub static PROT_WRITE : int = 2; + pub static PROT_EXEC : int = 4; + + pub static MAP_FILE : int = 0x0000; + pub static MAP_SHARED : int = 0x0001; + pub static MAP_PRIVATE : int = 0x0002; + pub static MAP_FIXED : int = 0x0010; + pub static MAP_ANON : int = 0x1000; + + pub static MAP_FAILED : *c_void = -1 as *c_void; + + pub static MCL_CURRENT : int = 0x0001; + pub static MCL_FUTURE : int = 0x0002; + + pub static MS_ASYNC : int = 0x0001; + pub static MS_INVALIDATE : int = 0x0002; + pub static MS_SYNC : int = 0x0010; + + pub static MS_KILLPAGES : int = 0x0004; + pub static MS_DEACTIVATE : int = 0x0008; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1337,15 +1509,45 @@ pub mod consts { pub static GLOB_NOSPACE : int = -1; pub static GLOB_ABORTED : int = -2; pub static GLOB_NOMATCH : int = -3; + + pub static POSIX_MADV_NORMAL : int = 0; + pub static POSIX_MADV_RANDOM : int = 1; + pub static POSIX_MADV_SEQUENTIAL : int = 2; + pub static POSIX_MADV_WILLNEED : int = 3; + pub static POSIX_MADV_DONTNEED : int = 4; } pub mod posix08 { } pub mod bsd44 { + pub static MADV_NORMAL : int = 0; + pub static MADV_RANDOM : int = 1; + pub static MADV_SEQUENTIAL : int = 2; + pub static MADV_WILLNEED : int = 3; + pub static MADV_DONTNEED : int = 4; + pub static MADV_FREE : int = 5; + pub static MADV_ZERO_WIRED_PAGES : int = 6; + pub static MADV_FREE_REUSABLE : int = 7; + pub static MADV_FREE_REUSE : int = 8; + pub static MADV_CAN_REUSE : int = 9; + + pub static MINCORE_INCORE : int = 0x1; + pub static MINCORE_REFERENCED : int = 0x2; + pub static MINCORE_MODIFIED : int = 0x4; + pub static MINCORE_REFERENCED_OTHER : int = 0x8; + pub static MINCORE_MODIFIED_OTHER : int = 0x10; } pub mod extra { pub static O_DSYNC : int = 4194304; pub static O_SYNC : int = 128; pub static F_FULLFSYNC : int = 51; + + pub static MAP_COPY : int = 0x0002; + pub static MAP_RENAME : int = 0x0020; + pub static MAP_NORESERVE : int = 0x0040; + pub static MAP_NOEXTEND : int = 0x0100; + pub static MAP_HASSEMAPHORE : int = 0x0200; + pub static MAP_NOCACHE : int = 0x0400; + pub static MAP_JIT : int = 0x0800; } } } @@ -1658,6 +1860,9 @@ pub mod funcs { -> c_int; } } + + pub mod mman { + } } @@ -1835,6 +2040,38 @@ pub mod funcs { unsafe fn kill(pid: pid_t, sig: c_int) -> c_int; } } + + #[nolink] + #[abi = "cdecl"] + pub mod mman { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{size_t, c_int, c_char}; + use libc::types::os::arch::posix88::{mode_t, off_t}; + + pub extern { + unsafe fn mlock(addr: *c_void, len: size_t) -> c_int; + unsafe fn munlock(addr: *c_void, len: size_t) -> c_int; + unsafe fn mlockall(flags: c_int) -> c_int; + unsafe fn munlockall() -> c_int; + + unsafe fn mmap(addr: *c_void, + len: size_t, + prot: c_int, + flags: c_int, + fd: c_int, + offset: off_t) -> *mut c_void; + unsafe fn munmap(addr: *c_void, len: size_t) -> c_int; + + unsafe fn mprotect(addr: *c_void, len: size_t, prot: c_int) + -> c_int; + + unsafe fn msync(addr: *c_void, len: size_t, flags: c_int) + -> c_int; + unsafe fn shm_open(name: *c_char, oflag: c_int, mode: mode_t) + -> c_int; + unsafe fn shm_unlink(name: *c_char) -> c_int; + } + } } #[cfg(target_os = "linux")] @@ -1913,6 +2150,19 @@ pub mod funcs { unsafe fn globfree(pglob: *mut glob_t); } } + + #[nolink] + #[abi = "cdecl"] + pub mod mman { + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_int, size_t}; + + pub extern { + unsafe fn posix_madvise(addr: *c_void, + len: size_t, + advice: c_int) -> c_int; + } + } } #[cfg(target_os = "win32")] @@ -1925,6 +2175,9 @@ pub mod funcs { pub mod glob { } + + pub mod mman { + } } @@ -1943,7 +2196,8 @@ pub mod funcs { #[cfg(target_os = "freebsd")] pub mod bsd44 { use libc::types::common::c95::{c_void}; - use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t}; + use libc::types::os::arch::c95::{c_char, c_uchar, c_int, c_uint, + size_t}; #[abi = "cdecl"] pub extern { @@ -1959,6 +2213,12 @@ pub mod funcs { sizep: *mut size_t) -> c_int; unsafe fn getdtablesize() -> c_int; + + unsafe fn madvise(addr: *c_void, len: size_t, advice: c_int) + -> c_int; + + unsafe fn mincore(addr: *c_void, len: size_t, vec: *c_uchar) + -> c_int; } } @@ -1966,11 +2226,18 @@ pub mod funcs { #[cfg(target_os = "linux")] #[cfg(target_os = "android")] pub mod bsd44 { - use libc::types::os::arch::c95::{c_int}; + use libc::types::common::c95::{c_void}; + use libc::types::os::arch::c95::{c_uchar, c_int, size_t}; #[abi = "cdecl"] pub extern { unsafe fn getdtablesize() -> c_int; + + unsafe fn madvise(addr: *c_void, len: size_t, advice: c_int) + -> c_int; + + unsafe fn mincore(addr: *c_void, len: size_t, vec: *c_uchar) + -> c_int; } } From ddd6f5928395c67b249ce3ec76a1ff4be303208d Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 20 Jun 2013 16:41:50 +0200 Subject: [PATCH 115/336] libc: add POSIX-compatible sysconf consts Because its part of POSIX. Values are taken from FreeBSD, linux and OSX header files. --- src/libstd/libc.rs | 254 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 2aaeda69326b..9d6755fc22d3 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -1176,6 +1176,63 @@ pub mod consts { pub static MS_ASYNC : int = 0x0001; pub static MS_INVALIDATE : int = 0x0002; pub static MS_SYNC : int = 0x0004; + + pub static _SC_ARG_MAX : int = 0; + pub static _SC_CHILD_MAX : int = 1; + pub static _SC_CLK_TCK : int = 2; + pub static _SC_NGROUPS_MAX : int = 3; + pub static _SC_OPEN_MAX : int = 4; + pub static _SC_STREAM_MAX : int = 5; + pub static _SC_TZNAME_MAX : int = 6; + pub static _SC_JOB_CONTROL : int = 7; + pub static _SC_SAVED_IDS : int = 8; + pub static _SC_REALTIME_SIGNALS : int = 9; + pub static _SC_PRIORITY_SCHEDULING : int = 10; + pub static _SC_TIMERS : int = 11; + pub static _SC_ASYNCHRONOUS_IO : int = 12; + pub static _SC_PRIORITIZED_IO : int = 13; + pub static _SC_SYNCHRONIZED_IO : int = 14; + pub static _SC_FSYNC : int = 15; + pub static _SC_MAPPED_FILES : int = 16; + pub static _SC_MEMLOCK : int = 17; + pub static _SC_MEMLOCK_RANGE : int = 18; + pub static _SC_MEMORY_PROTECTION : int = 19; + pub static _SC_MESSAGE_PASSING : int = 20; + pub static _SC_SEMAPHORES : int = 21; + pub static _SC_SHARED_MEMORY_OBJECTS : int = 22; + pub static _SC_AIO_LISTIO_MAX : int = 23; + pub static _SC_AIO_MAX : int = 24; + pub static _SC_AIO_PRIO_DELTA_MAX : int = 25; + pub static _SC_DELAYTIMER_MAX : int = 26; + pub static _SC_MQ_OPEN_MAX : int = 27; + pub static _SC_VERSION : int = 29; + pub static _SC_PAGESIZE : int = 30; + pub static _SC_RTSIG_MAX : int = 31; + pub static _SC_SEM_NSEMS_MAX : int = 32; + pub static _SC_SEM_VALUE_MAX : int = 33; + pub static _SC_SIGQUEUE_MAX : int = 34; + pub static _SC_TIMER_MAX : int = 35; + pub static _SC_BC_BASE_MAX : int = 36; + pub static _SC_BC_DIM_MAX : int = 37; + pub static _SC_BC_SCALE_MAX : int = 38; + pub static _SC_BC_STRING_MAX : int = 39; + pub static _SC_COLL_WEIGHTS_MAX : int = 40; + pub static _SC_EXPR_NEST_MAX : int = 42; + pub static _SC_LINE_MAX : int = 43; + pub static _SC_RE_DUP_MAX : int = 44; + pub static _SC_2_VERSION : int = 46; + pub static _SC_2_C_BIND : int = 47; + pub static _SC_2_C_DEV : int = 48; + pub static _SC_2_FORT_DEV : int = 49; + pub static _SC_2_FORT_RUN : int = 50; + pub static _SC_2_SW_DEV : int = 51; + pub static _SC_2_LOCALEDEF : int = 52; + pub static _SC_2_CHAR_TERM : int = 95; + pub static _SC_2_C_VERSION : int = 96; + pub static _SC_2_UPE : int = 97; + pub static _SC_XBS5_ILP32_OFF32 : int = 125; + pub static _SC_XBS5_ILP32_OFFBIG : int = 126; + pub static _SC_XBS5_LPBIG_OFFBIG : int = 128; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1197,6 +1254,35 @@ pub mod consts { pub static POSIX_MADV_SEQUENTIAL : int = 2; pub static POSIX_MADV_WILLNEED : int = 3; pub static POSIX_MADV_DONTNEED : int = 4; + + pub static _SC_MQ_PRIO_MAX : int = 28; + pub static _SC_IOV_MAX : int = 60; + pub static _SC_GETGR_R_SIZE_MAX : int = 69; + pub static _SC_GETPW_R_SIZE_MAX : int = 70; + pub static _SC_LOGIN_NAME_MAX : int = 71; + pub static _SC_TTY_NAME_MAX : int = 72; + pub static _SC_THREADS : int = 67; + pub static _SC_THREAD_SAFE_FUNCTIONS : int = 68; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 73; + pub static _SC_THREAD_KEYS_MAX : int = 74; + pub static _SC_THREAD_STACK_MIN : int = 75; + pub static _SC_THREAD_THREADS_MAX : int = 76; + pub static _SC_THREAD_ATTR_STACKADDR : int = 77; + pub static _SC_THREAD_ATTR_STACKSIZE : int = 78; + pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 79; + pub static _SC_THREAD_PRIO_INHERIT : int = 80; + pub static _SC_THREAD_PRIO_PROTECT : int = 81; + pub static _SC_THREAD_PROCESS_SHARED : int = 82; + pub static _SC_ATEXIT_MAX : int = 87; + pub static _SC_XOPEN_VERSION : int = 89; + pub static _SC_XOPEN_XCU_VERSION : int = 90; + pub static _SC_XOPEN_UNIX : int = 91; + pub static _SC_XOPEN_CRYPT : int = 92; + pub static _SC_XOPEN_ENH_I18N : int = 93; + pub static _SC_XOPEN_SHM : int = 94; + pub static _SC_XOPEN_LEGACY : int = 129; + pub static _SC_XOPEN_REALTIME : int = 130; + pub static _SC_XOPEN_REALTIME_THREADS : int = 131; } pub mod posix08 { } @@ -1345,6 +1431,59 @@ pub mod consts { pub static MS_SYNC : int = 0x0000; pub static MS_ASYNC : int = 0x0001; pub static MS_INVALIDATE : int = 0x0002; + + pub static _SC_ARG_MAX : int = 1; + pub static _SC_CHILD_MAX : int = 2; + pub static _SC_CLK_TCK : int = 3; + pub static _SC_NGROUPS_MAX : int = 4; + pub static _SC_OPEN_MAX : int = 5; + pub static _SC_JOB_CONTROL : int = 6; + pub static _SC_SAVED_IDS : int = 7; + pub static _SC_VERSION : int = 8; + pub static _SC_BC_BASE_MAX : int = 9; + pub static _SC_BC_DIM_MAX : int = 10; + pub static _SC_BC_SCALE_MAX : int = 11; + pub static _SC_BC_STRING_MAX : int = 12; + pub static _SC_COLL_WEIGHTS_MAX : int = 13; + pub static _SC_EXPR_NEST_MAX : int = 14; + pub static _SC_LINE_MAX : int = 15; + pub static _SC_RE_DUP_MAX : int = 16; + pub static _SC_2_VERSION : int = 17; + pub static _SC_2_C_BIND : int = 18; + pub static _SC_2_C_DEV : int = 19; + pub static _SC_2_CHAR_TERM : int = 20; + pub static _SC_2_FORT_DEV : int = 21; + pub static _SC_2_FORT_RUN : int = 22; + pub static _SC_2_LOCALEDEF : int = 23; + pub static _SC_2_SW_DEV : int = 24; + pub static _SC_2_UPE : int = 25; + pub static _SC_STREAM_MAX : int = 26; + pub static _SC_TZNAME_MAX : int = 27; + pub static _SC_ASYNCHRONOUS_IO : int = 28; + pub static _SC_MAPPED_FILES : int = 29; + pub static _SC_MEMLOCK : int = 30; + pub static _SC_MEMLOCK_RANGE : int = 31; + pub static _SC_MEMORY_PROTECTION : int = 32; + pub static _SC_MESSAGE_PASSING : int = 33; + pub static _SC_PRIORITIZED_IO : int = 34; + pub static _SC_PRIORITY_SCHEDULING : int = 35; + pub static _SC_REALTIME_SIGNALS : int = 36; + pub static _SC_SEMAPHORES : int = 37; + pub static _SC_FSYNC : int = 38; + pub static _SC_SHARED_MEMORY_OBJECTS : int = 39; + pub static _SC_SYNCHRONIZED_IO : int = 40; + pub static _SC_TIMERS : int = 41; + pub static _SC_AIO_LISTIO_MAX : int = 42; + pub static _SC_AIO_MAX : int = 43; + pub static _SC_AIO_PRIO_DELTA_MAX : int = 44; + pub static _SC_DELAYTIMER_MAX : int = 45; + pub static _SC_MQ_OPEN_MAX : int = 46; + pub static _SC_PAGESIZE : int = 47; + pub static _SC_RTSIG_MAX : int = 48; + pub static _SC_SEM_NSEMS_MAX : int = 49; + pub static _SC_SEM_VALUE_MAX : int = 50; + pub static _SC_SIGQUEUE_MAX : int = 51; + pub static _SC_TIMER_MAX : int = 52; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1366,6 +1505,35 @@ pub mod consts { pub static POSIX_MADV_SEQUENTIAL : int = 2; pub static POSIX_MADV_WILLNEED : int = 3; pub static POSIX_MADV_DONTNEED : int = 4; + + pub static _SC_IOV_MAX : int = 56; + pub static _SC_GETGR_R_SIZE_MAX : int = 70; + pub static _SC_GETPW_R_SIZE_MAX : int = 71; + pub static _SC_LOGIN_NAME_MAX : int = 73; + pub static _SC_MQ_PRIO_MAX : int = 75; + pub static _SC_THREAD_ATTR_STACKADDR : int = 82; + pub static _SC_THREAD_ATTR_STACKSIZE : int = 83; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 85; + pub static _SC_THREAD_KEYS_MAX : int = 86; + pub static _SC_THREAD_PRIO_INHERIT : int = 87; + pub static _SC_THREAD_PRIO_PROTECT : int = 88; + pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 89; + pub static _SC_THREAD_PROCESS_SHARED : int = 90; + pub static _SC_THREAD_SAFE_FUNCTIONS : int = 91; + pub static _SC_THREAD_STACK_MIN : int = 93; + pub static _SC_THREAD_THREADS_MAX : int = 94; + pub static _SC_THREADS : int = 96; + pub static _SC_TTY_NAME_MAX : int = 101; + pub static _SC_ATEXIT_MAX : int = 107; + pub static _SC_XOPEN_CRYPT : int = 108; + pub static _SC_XOPEN_ENH_I18N : int = 109; + pub static _SC_XOPEN_LEGACY : int = 110; + pub static _SC_XOPEN_REALTIME : int = 111; + pub static _SC_XOPEN_REALTIME_THREADS : int = 112; + pub static _SC_XOPEN_SHM : int = 113; + pub static _SC_XOPEN_UNIX : int = 115; + pub static _SC_XOPEN_VERSION : int = 116; + pub static _SC_XOPEN_XCU_VERSION : int = 117; } pub mod posix08 { } @@ -1494,6 +1662,63 @@ pub mod consts { pub static MS_KILLPAGES : int = 0x0004; pub static MS_DEACTIVATE : int = 0x0008; + + pub static _SC_ARG_MAX : int = 1; + pub static _SC_CHILD_MAX : int = 2; + pub static _SC_CLK_TCK : int = 3; + pub static _SC_NGROUPS_MAX : int = 4; + pub static _SC_OPEN_MAX : int = 5; + pub static _SC_JOB_CONTROL : int = 6; + pub static _SC_SAVED_IDS : int = 7; + pub static _SC_VERSION : int = 8; + pub static _SC_BC_BASE_MAX : int = 9; + pub static _SC_BC_DIM_MAX : int = 10; + pub static _SC_BC_SCALE_MAX : int = 11; + pub static _SC_BC_STRING_MAX : int = 12; + pub static _SC_COLL_WEIGHTS_MAX : int = 13; + pub static _SC_EXPR_NEST_MAX : int = 14; + pub static _SC_LINE_MAX : int = 15; + pub static _SC_RE_DUP_MAX : int = 16; + pub static _SC_2_VERSION : int = 17; + pub static _SC_2_C_BIND : int = 18; + pub static _SC_2_C_DEV : int = 19; + pub static _SC_2_CHAR_TERM : int = 20; + pub static _SC_2_FORT_DEV : int = 21; + pub static _SC_2_FORT_RUN : int = 22; + pub static _SC_2_LOCALEDEF : int = 23; + pub static _SC_2_SW_DEV : int = 24; + pub static _SC_2_UPE : int = 25; + pub static _SC_STREAM_MAX : int = 26; + pub static _SC_TZNAME_MAX : int = 27; + pub static _SC_ASYNCHRONOUS_IO : int = 28; + pub static _SC_PAGESIZE : int = 29; + pub static _SC_MEMLOCK : int = 30; + pub static _SC_MEMLOCK_RANGE : int = 31; + pub static _SC_MEMORY_PROTECTION : int = 32; + pub static _SC_MESSAGE_PASSING : int = 33; + pub static _SC_PRIORITIZED_IO : int = 34; + pub static _SC_PRIORITY_SCHEDULING : int = 35; + pub static _SC_REALTIME_SIGNALS : int = 36; + pub static _SC_SEMAPHORES : int = 37; + pub static _SC_FSYNC : int = 38; + pub static _SC_SHARED_MEMORY_OBJECTS : int = 39; + pub static _SC_SYNCHRONIZED_IO : int = 40; + pub static _SC_TIMERS : int = 41; + pub static _SC_AIO_LISTIO_MAX : int = 42; + pub static _SC_AIO_MAX : int = 43; + pub static _SC_AIO_PRIO_DELTA_MAX : int = 44; + pub static _SC_DELAYTIMER_MAX : int = 45; + pub static _SC_MQ_OPEN_MAX : int = 46; + pub static _SC_MAPPED_FILES : int = 47; + pub static _SC_RTSIG_MAX : int = 48; + pub static _SC_SEM_NSEMS_MAX : int = 49; + pub static _SC_SEM_VALUE_MAX : int = 50; + pub static _SC_SIGQUEUE_MAX : int = 51; + pub static _SC_TIMER_MAX : int = 52; + pub static _SC_XBS5_ILP32_OFF32 : int = 122; + pub static _SC_XBS5_ILP32_OFFBIG : int = 123; + pub static _SC_XBS5_LP64_OFF64 : int = 124; + pub static _SC_XBS5_LPBIG_OFFBIG : int = 125; } pub mod posix01 { pub static SIGTRAP : int = 5; @@ -1515,6 +1740,35 @@ pub mod consts { pub static POSIX_MADV_SEQUENTIAL : int = 2; pub static POSIX_MADV_WILLNEED : int = 3; pub static POSIX_MADV_DONTNEED : int = 4; + + pub static _SC_IOV_MAX : int = 56; + pub static _SC_GETGR_R_SIZE_MAX : int = 70; + pub static _SC_GETPW_R_SIZE_MAX : int = 71; + pub static _SC_LOGIN_NAME_MAX : int = 73; + pub static _SC_MQ_PRIO_MAX : int = 75; + pub static _SC_THREAD_ATTR_STACKADDR : int = 82; + pub static _SC_THREAD_ATTR_STACKSIZE : int = 83; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 85; + pub static _SC_THREAD_KEYS_MAX : int = 86; + pub static _SC_THREAD_PRIO_INHERIT : int = 87; + pub static _SC_THREAD_PRIO_PROTECT : int = 88; + pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 89; + pub static _SC_THREAD_PROCESS_SHARED : int = 90; + pub static _SC_THREAD_SAFE_FUNCTIONS : int = 91; + pub static _SC_THREAD_STACK_MIN : int = 93; + pub static _SC_THREAD_THREADS_MAX : int = 94; + pub static _SC_THREADS : int = 96; + pub static _SC_TTY_NAME_MAX : int = 101; + pub static _SC_ATEXIT_MAX : int = 107; + pub static _SC_XOPEN_CRYPT : int = 108; + pub static _SC_XOPEN_ENH_I18N : int = 109; + pub static _SC_XOPEN_LEGACY : int = 110; + pub static _SC_XOPEN_REALTIME : int = 111; + pub static _SC_XOPEN_REALTIME_THREADS : int = 112; + pub static _SC_XOPEN_SHM : int = 113; + pub static _SC_XOPEN_UNIX : int = 115; + pub static _SC_XOPEN_VERSION : int = 116; + pub static _SC_XOPEN_XCU_VERSION : int = 121; } pub mod posix08 { } From f8ae3cdcaacb29c7b56e546a9ddab1396b615f8f Mon Sep 17 00:00:00 2001 From: Philipp Brueschweiler Date: Mon, 24 Jun 2013 19:14:20 +0200 Subject: [PATCH 116/336] Fix test failure on windows This patch ensures that the multiple extern definitions of `free` in the run-pass tests have the same declaration, working around #7352. --- src/test/run-pass/extern-pub.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs index 2d6cc2c78deb..27c45893930c 100644 --- a/src/test/run-pass/extern-pub.rs +++ b/src/test/run-pass/extern-pub.rs @@ -1,7 +1,5 @@ -use std::libc; - extern { - pub unsafe fn free(p: *libc::c_void); + pub unsafe fn free(p: *u8); } pub fn main() { From bc70edbb25487e539386c68bd6e821eedd704194 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 21 Jun 2013 16:39:37 +0200 Subject: [PATCH 117/336] libc: (u)int => c_(u)int for consts --- src/libstd/libc.rs | 1459 +++++++++++++++++++++++--------------------- src/libstd/os.rs | 2 +- 2 files changed, 748 insertions(+), 713 deletions(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 9d6755fc22d3..523645e69a52 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -287,7 +287,7 @@ pub mod types { #[cfg(target_arch = "x86")] #[cfg(target_arch = "mips")] pub mod posix01 { - use libc::types::os::arch::c95::{c_short, c_long, c_ulong, time_t}; + use libc::types::os::arch::c95::{c_short, c_long, time_t}; use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t}; use libc::types::os::arch::posix88::{mode_t, off_t}; use libc::types::os::arch::posix88::{uid_t}; @@ -905,52 +905,56 @@ pub mod consts { #[cfg(target_os = "win32")] pub mod os { pub mod c95 { - pub static EXIT_FAILURE : int = 1; - pub static EXIT_SUCCESS : int = 0; - pub static RAND_MAX : int = 32767; - pub static EOF : int = -1; - pub static SEEK_SET : int = 0; - pub static SEEK_CUR : int = 1; - pub static SEEK_END : int = 2; - pub static _IOFBF : int = 0; - pub static _IONBF : int = 4; - pub static _IOLBF : int = 64; - pub static BUFSIZ : uint = 512_u; - pub static FOPEN_MAX : uint = 20_u; - pub static FILENAME_MAX : uint = 260_u; - pub static L_tmpnam : uint = 16_u; - pub static TMP_MAX : uint = 32767_u; + use libc::types::os::arch::c95::{c_int, c_uint}; + + pub static EXIT_FAILURE : c_int = 1; + pub static EXIT_SUCCESS : c_int = 0; + pub static RAND_MAX : c_int = 32767; + pub static EOF : c_int = -1; + pub static SEEK_SET : c_int = 0; + pub static SEEK_CUR : c_int = 1; + pub static SEEK_END : c_int = 2; + pub static _IOFBF : c_int = 0; + pub static _IONBF : c_int = 4; + pub static _IOLBF : c_int = 64; + pub static BUFSIZ : c_uint = 512_u32; + pub static FOPEN_MAX : c_uint = 20_u32; + pub static FILENAME_MAX : c_uint = 260_u32; + pub static L_tmpnam : c_uint = 16_u32; + pub static TMP_MAX : c_uint = 32767_u32; } pub mod c99 { } pub mod posix88 { - pub static O_RDONLY : int = 0; - pub static O_WRONLY : int = 1; - pub static O_RDWR : int = 2; - pub static O_APPEND : int = 8; - pub static O_CREAT : int = 256; - pub static O_EXCL : int = 1024; - pub static O_TRUNC : int = 512; - pub static S_IFIFO : int = 4096; - pub static S_IFCHR : int = 8192; - pub static S_IFBLK : int = 12288; - pub static S_IFDIR : int = 16384; - pub static S_IFREG : int = 32768; - pub static S_IFMT : int = 61440; - pub static S_IEXEC : int = 64; - pub static S_IWRITE : int = 128; - pub static S_IREAD : int = 256; - pub static S_IRWXU : int = 448; - pub static S_IXUSR : int = 64; - pub static S_IWUSR : int = 128; - pub static S_IRUSR : int = 256; - pub static F_OK : int = 0; - pub static R_OK : int = 4; - pub static W_OK : int = 2; - pub static X_OK : int = 1; - pub static STDIN_FILENO : int = 0; - pub static STDOUT_FILENO : int = 1; - pub static STDERR_FILENO : int = 2; + use libc::types::os::arch::c95::c_int; + + pub static O_RDONLY : c_int = 0; + pub static O_WRONLY : c_int = 1; + pub static O_RDWR : c_int = 2; + pub static O_APPEND : c_int = 8; + pub static O_CREAT : c_int = 256; + pub static O_EXCL : c_int = 1024; + pub static O_TRUNC : c_int = 512; + pub static S_IFIFO : c_int = 4096; + pub static S_IFCHR : c_int = 8192; + pub static S_IFBLK : c_int = 12288; + pub static S_IFDIR : c_int = 16384; + pub static S_IFREG : c_int = 32768; + pub static S_IFMT : c_int = 61440; + pub static S_IEXEC : c_int = 64; + pub static S_IWRITE : c_int = 128; + pub static S_IREAD : c_int = 256; + pub static S_IRWXU : c_int = 448; + pub static S_IXUSR : c_int = 64; + pub static S_IWUSR : c_int = 128; + pub static S_IRUSR : c_int = 256; + pub static F_OK : c_int = 0; + pub static R_OK : c_int = 4; + pub static W_OK : c_int = 2; + pub static X_OK : c_int = 1; + pub static STDIN_FILENO : c_int = 0; + pub static STDOUT_FILENO : c_int = 1; + pub static STDERR_FILENO : c_int = 2; } pub mod posix01 { } @@ -959,18 +963,19 @@ pub mod consts { pub mod bsd44 { } pub mod extra { + use libc::types::os::arch::c95::c_int; use libc::types::os::arch::extra::{DWORD, BOOL}; pub static TRUE : BOOL = 1; pub static FALSE : BOOL = 0; - pub static O_TEXT : int = 16384; - pub static O_BINARY : int = 32768; - pub static O_NOINHERIT: int = 128; + pub static O_TEXT : c_int = 16384; + pub static O_BINARY : c_int = 32768; + pub static O_NOINHERIT: c_int = 128; - pub static ERROR_SUCCESS : int = 0; - pub static ERROR_INSUFFICIENT_BUFFER : int = 122; - pub static INVALID_HANDLE_VALUE: int = -1; + pub static ERROR_SUCCESS : c_int = 0; + pub static ERROR_INSUFFICIENT_BUFFER : c_int = 122; + pub static INVALID_HANDLE_VALUE: c_int = -1; pub static DELETE : DWORD = 0x00010000; pub static READ_CONTROL : DWORD = 0x00020000; @@ -1023,21 +1028,23 @@ pub mod consts { #[cfg(target_os = "android")] pub mod os { pub mod c95 { - pub static EXIT_FAILURE : int = 1; - pub static EXIT_SUCCESS : int = 0; - pub static RAND_MAX : int = 2147483647; - pub static EOF : int = -1; - pub static SEEK_SET : int = 0; - pub static SEEK_CUR : int = 1; - pub static SEEK_END : int = 2; - pub static _IOFBF : int = 0; - pub static _IONBF : int = 2; - pub static _IOLBF : int = 1; - pub static BUFSIZ : uint = 8192_u; - pub static FOPEN_MAX : uint = 16_u; - pub static FILENAME_MAX : uint = 4096_u; - pub static L_tmpnam : uint = 20_u; - pub static TMP_MAX : uint = 238328_u; + use libc::types::os::arch::c95::{c_int, c_uint}; + + pub static EXIT_FAILURE : c_int = 1; + pub static EXIT_SUCCESS : c_int = 0; + pub static RAND_MAX : c_int = 2147483647; + pub static EOF : c_int = -1; + pub static SEEK_SET : c_int = 0; + pub static SEEK_CUR : c_int = 1; + pub static SEEK_END : c_int = 2; + pub static _IOFBF : c_int = 0; + pub static _IONBF : c_int = 2; + pub static _IOLBF : c_int = 1; + pub static BUFSIZ : c_uint = 8192_u32; + pub static FOPEN_MAX : c_uint = 16_u32; + pub static FILENAME_MAX : c_uint = 4096_u32; + pub static L_tmpnam : c_uint = 20_u32; + pub static TMP_MAX : c_uint = 238328_u32; } pub mod c99 { } @@ -1045,763 +1052,791 @@ pub mod consts { #[cfg(target_arch = "x86_64")] #[cfg(target_arch = "arm")] pub mod posix88 { + use libc::types::os::arch::c95::c_int; use libc::types::common::c95::c_void; - pub static O_RDONLY : int = 0; - pub static O_WRONLY : int = 1; - pub static O_RDWR : int = 2; - pub static O_APPEND : int = 1024; - pub static O_CREAT : int = 64; - pub static O_EXCL : int = 128; - pub static O_TRUNC : int = 512; - pub static S_IFIFO : int = 4096; - pub static S_IFCHR : int = 8192; - pub static S_IFBLK : int = 24576; - pub static S_IFDIR : int = 16384; - pub static S_IFREG : int = 32768; - pub static S_IFMT : int = 61440; - pub static S_IEXEC : int = 64; - pub static S_IWRITE : int = 128; - pub static S_IREAD : int = 256; - pub static S_IRWXU : int = 448; - pub static S_IXUSR : int = 64; - pub static S_IWUSR : int = 128; - pub static S_IRUSR : int = 256; - pub static F_OK : int = 0; - pub static R_OK : int = 4; - pub static W_OK : int = 2; - pub static X_OK : int = 1; - pub static STDIN_FILENO : int = 0; - pub static STDOUT_FILENO : int = 1; - pub static STDERR_FILENO : int = 2; - pub static F_LOCK : int = 1; - pub static F_TEST : int = 3; - pub static F_TLOCK : int = 2; - pub static F_ULOCK : int = 0; - pub static SIGHUP : int = 1; - pub static SIGINT : int = 2; - pub static SIGQUIT : int = 3; - pub static SIGILL : int = 4; - pub static SIGABRT : int = 6; - pub static SIGFPE : int = 8; - pub static SIGKILL : int = 9; - pub static SIGSEGV : int = 11; - pub static SIGPIPE : int = 13; - pub static SIGALRM : int = 14; - pub static SIGTERM : int = 15; + pub static O_RDONLY : c_int = 0; + pub static O_WRONLY : c_int = 1; + pub static O_RDWR : c_int = 2; + pub static O_APPEND : c_int = 1024; + pub static O_CREAT : c_int = 64; + pub static O_EXCL : c_int = 128; + pub static O_TRUNC : c_int = 512; + pub static S_IFIFO : c_int = 4096; + pub static S_IFCHR : c_int = 8192; + pub static S_IFBLK : c_int = 24576; + pub static S_IFDIR : c_int = 16384; + pub static S_IFREG : c_int = 32768; + pub static S_IFMT : c_int = 61440; + pub static S_IEXEC : c_int = 64; + pub static S_IWRITE : c_int = 128; + pub static S_IREAD : c_int = 256; + pub static S_IRWXU : c_int = 448; + pub static S_IXUSR : c_int = 64; + pub static S_IWUSR : c_int = 128; + pub static S_IRUSR : c_int = 256; + pub static F_OK : c_int = 0; + pub static R_OK : c_int = 4; + pub static W_OK : c_int = 2; + pub static X_OK : c_int = 1; + pub static STDIN_FILENO : c_int = 0; + pub static STDOUT_FILENO : c_int = 1; + pub static STDERR_FILENO : c_int = 2; + pub static F_LOCK : c_int = 1; + pub static F_TEST : c_int = 3; + pub static F_TLOCK : c_int = 2; + pub static F_ULOCK : c_int = 0; + pub static SIGHUP : c_int = 1; + pub static SIGINT : c_int = 2; + pub static SIGQUIT : c_int = 3; + pub static SIGILL : c_int = 4; + pub static SIGABRT : c_int = 6; + pub static SIGFPE : c_int = 8; + pub static SIGKILL : c_int = 9; + pub static SIGSEGV : c_int = 11; + pub static SIGPIPE : c_int = 13; + pub static SIGALRM : c_int = 14; + pub static SIGTERM : c_int = 15; - pub static PROT_NONE : int = 0; - pub static PROT_READ : int = 1; - pub static PROT_WRITE : int = 2; - pub static PROT_EXEC : int = 4; + pub static PROT_NONE : c_int = 0; + pub static PROT_READ : c_int = 1; + pub static PROT_WRITE : c_int = 2; + pub static PROT_EXEC : c_int = 4; - pub static MAP_FILE : int = 0x0000; - pub static MAP_SHARED : int = 0x0001; - pub static MAP_PRIVATE : int = 0x0002; - pub static MAP_FIXED : int = 0x0010; - pub static MAP_ANON : int = 0x1000; + pub static MAP_FILE : c_int = 0x0000; + pub static MAP_SHARED : c_int = 0x0001; + pub static MAP_PRIVATE : c_int = 0x0002; + pub static MAP_FIXED : c_int = 0x0010; + pub static MAP_ANON : c_int = 0x1000; pub static MAP_FAILED : *c_void = -1 as *c_void; - pub static MCL_CURRENT : int = 0x0001; - pub static MCL_FUTURE : int = 0x0002; + pub static MCL_CURRENT : c_int = 0x0001; + pub static MCL_FUTURE : c_int = 0x0002; - pub static MS_ASYNC : int = 0x0001; - pub static MS_INVALIDATE : int = 0x0002; - pub static MS_SYNC : int = 0x0004; + pub static MS_ASYNC : c_int = 0x0001; + pub static MS_INVALIDATE : c_int = 0x0002; + pub static MS_SYNC : c_int = 0x0004; } #[cfg(target_arch = "mips")] pub mod posix88 { + use libc::types::os::arch::c95::c_int; use libc::types::common::c95::c_void; - pub static O_RDONLY : int = 0; - pub static O_WRONLY : int = 1; - pub static O_RDWR : int = 2; - pub static O_APPEND : int = 8; - pub static O_CREAT : int = 256; - pub static O_EXCL : int = 1024; - pub static O_TRUNC : int = 512; - pub static S_IFIFO : int = 4096; - pub static S_IFCHR : int = 8192; - pub static S_IFBLK : int = 24576; - pub static S_IFDIR : int = 16384; - pub static S_IFREG : int = 32768; - pub static S_IFMT : int = 61440; - pub static S_IEXEC : int = 64; - pub static S_IWRITE : int = 128; - pub static S_IREAD : int = 256; - pub static S_IRWXU : int = 448; - pub static S_IXUSR : int = 64; - pub static S_IWUSR : int = 128; - pub static S_IRUSR : int = 256; - pub static F_OK : int = 0; - pub static R_OK : int = 4; - pub static W_OK : int = 2; - pub static X_OK : int = 1; - pub static STDIN_FILENO : int = 0; - pub static STDOUT_FILENO : int = 1; - pub static STDERR_FILENO : int = 2; - pub static F_LOCK : int = 1; - pub static F_TEST : int = 3; - pub static F_TLOCK : int = 2; - pub static F_ULOCK : int = 0; - pub static SIGHUP : int = 1; - pub static SIGINT : int = 2; - pub static SIGQUIT : int = 3; - pub static SIGILL : int = 4; - pub static SIGABRT : int = 6; - pub static SIGFPE : int = 8; - pub static SIGKILL : int = 9; - pub static SIGSEGV : int = 11; - pub static SIGPIPE : int = 13; - pub static SIGALRM : int = 14; - pub static SIGTERM : int = 15; + pub static O_RDONLY : c_int = 0; + pub static O_WRONLY : c_int = 1; + pub static O_RDWR : c_int = 2; + pub static O_APPEND : c_int = 8; + pub static O_CREAT : c_int = 256; + pub static O_EXCL : c_int = 1024; + pub static O_TRUNC : c_int = 512; + pub static S_IFIFO : c_int = 4096; + pub static S_IFCHR : c_int = 8192; + pub static S_IFBLK : c_int = 24576; + pub static S_IFDIR : c_int = 16384; + pub static S_IFREG : c_int = 32768; + pub static S_IFMT : c_int = 61440; + pub static S_IEXEC : c_int = 64; + pub static S_IWRITE : c_int = 128; + pub static S_IREAD : c_int = 256; + pub static S_IRWXU : c_int = 448; + pub static S_IXUSR : c_int = 64; + pub static S_IWUSR : c_int = 128; + pub static S_IRUSR : c_int = 256; + pub static F_OK : c_int = 0; + pub static R_OK : c_int = 4; + pub static W_OK : c_int = 2; + pub static X_OK : c_int = 1; + pub static STDIN_FILENO : c_int = 0; + pub static STDOUT_FILENO : c_int = 1; + pub static STDERR_FILENO : c_int = 2; + pub static F_LOCK : c_int = 1; + pub static F_TEST : c_int = 3; + pub static F_TLOCK : c_int = 2; + pub static F_ULOCK : c_int = 0; + pub static SIGHUP : c_int = 1; + pub static SIGINT : c_int = 2; + pub static SIGQUIT : c_int = 3; + pub static SIGILL : c_int = 4; + pub static SIGABRT : c_int = 6; + pub static SIGFPE : c_int = 8; + pub static SIGKILL : c_int = 9; + pub static SIGSEGV : c_int = 11; + pub static SIGPIPE : c_int = 13; + pub static SIGALRM : c_int = 14; + pub static SIGTERM : c_int = 15; - pub static PROT_NONE : int = 0; - pub static PROT_READ : int = 1; - pub static PROT_WRITE : int = 2; - pub static PROT_EXEC : int = 4; + pub static PROT_NONE : c_int = 0; + pub static PROT_READ : c_int = 1; + pub static PROT_WRITE : c_int = 2; + pub static PROT_EXEC : c_int = 4; - pub static MAP_FILE : int = 0x0000; - pub static MAP_SHARED : int = 0x0001; - pub static MAP_PRIVATE : int = 0x0002; - pub static MAP_FIXED : int = 0x0010; - pub static MAP_ANON : int = 0x1000; + pub static MAP_FILE : c_int = 0x0000; + pub static MAP_SHARED : c_int = 0x0001; + pub static MAP_PRIVATE : c_int = 0x0002; + pub static MAP_FIXED : c_int = 0x0010; + pub static MAP_ANON : c_int = 0x1000; pub static MAP_FAILED : *c_void = -1 as *c_void; - pub static MCL_CURRENT : int = 0x0001; - pub static MCL_FUTURE : int = 0x0002; + pub static MCL_CURRENT : c_int = 0x0001; + pub static MCL_FUTURE : c_int = 0x0002; - pub static MS_ASYNC : int = 0x0001; - pub static MS_INVALIDATE : int = 0x0002; - pub static MS_SYNC : int = 0x0004; + pub static MS_ASYNC : c_int = 0x0001; + pub static MS_INVALIDATE : c_int = 0x0002; + pub static MS_SYNC : c_int = 0x0004; - pub static _SC_ARG_MAX : int = 0; - pub static _SC_CHILD_MAX : int = 1; - pub static _SC_CLK_TCK : int = 2; - pub static _SC_NGROUPS_MAX : int = 3; - pub static _SC_OPEN_MAX : int = 4; - pub static _SC_STREAM_MAX : int = 5; - pub static _SC_TZNAME_MAX : int = 6; - pub static _SC_JOB_CONTROL : int = 7; - pub static _SC_SAVED_IDS : int = 8; - pub static _SC_REALTIME_SIGNALS : int = 9; - pub static _SC_PRIORITY_SCHEDULING : int = 10; - pub static _SC_TIMERS : int = 11; - pub static _SC_ASYNCHRONOUS_IO : int = 12; - pub static _SC_PRIORITIZED_IO : int = 13; - pub static _SC_SYNCHRONIZED_IO : int = 14; - pub static _SC_FSYNC : int = 15; - pub static _SC_MAPPED_FILES : int = 16; - pub static _SC_MEMLOCK : int = 17; - pub static _SC_MEMLOCK_RANGE : int = 18; - pub static _SC_MEMORY_PROTECTION : int = 19; - pub static _SC_MESSAGE_PASSING : int = 20; - pub static _SC_SEMAPHORES : int = 21; - pub static _SC_SHARED_MEMORY_OBJECTS : int = 22; - pub static _SC_AIO_LISTIO_MAX : int = 23; - pub static _SC_AIO_MAX : int = 24; - pub static _SC_AIO_PRIO_DELTA_MAX : int = 25; - pub static _SC_DELAYTIMER_MAX : int = 26; - pub static _SC_MQ_OPEN_MAX : int = 27; - pub static _SC_VERSION : int = 29; - pub static _SC_PAGESIZE : int = 30; - pub static _SC_RTSIG_MAX : int = 31; - pub static _SC_SEM_NSEMS_MAX : int = 32; - pub static _SC_SEM_VALUE_MAX : int = 33; - pub static _SC_SIGQUEUE_MAX : int = 34; - pub static _SC_TIMER_MAX : int = 35; - pub static _SC_BC_BASE_MAX : int = 36; - pub static _SC_BC_DIM_MAX : int = 37; - pub static _SC_BC_SCALE_MAX : int = 38; - pub static _SC_BC_STRING_MAX : int = 39; - pub static _SC_COLL_WEIGHTS_MAX : int = 40; - pub static _SC_EXPR_NEST_MAX : int = 42; - pub static _SC_LINE_MAX : int = 43; - pub static _SC_RE_DUP_MAX : int = 44; - pub static _SC_2_VERSION : int = 46; - pub static _SC_2_C_BIND : int = 47; - pub static _SC_2_C_DEV : int = 48; - pub static _SC_2_FORT_DEV : int = 49; - pub static _SC_2_FORT_RUN : int = 50; - pub static _SC_2_SW_DEV : int = 51; - pub static _SC_2_LOCALEDEF : int = 52; - pub static _SC_2_CHAR_TERM : int = 95; - pub static _SC_2_C_VERSION : int = 96; - pub static _SC_2_UPE : int = 97; - pub static _SC_XBS5_ILP32_OFF32 : int = 125; - pub static _SC_XBS5_ILP32_OFFBIG : int = 126; - pub static _SC_XBS5_LPBIG_OFFBIG : int = 128; + pub static _SC_ARG_MAX : c_int = 0; + pub static _SC_CHILD_MAX : c_int = 1; + pub static _SC_CLK_TCK : c_int = 2; + pub static _SC_NGROUPS_MAX : c_int = 3; + pub static _SC_OPEN_MAX : c_int = 4; + pub static _SC_STREAM_MAX : c_int = 5; + pub static _SC_TZNAME_MAX : c_int = 6; + pub static _SC_JOB_CONTROL : c_int = 7; + pub static _SC_SAVED_IDS : c_int = 8; + pub static _SC_REALTIME_SIGNALS : c_int = 9; + pub static _SC_PRIORITY_SCHEDULING : c_int = 10; + pub static _SC_TIMERS : c_int = 11; + pub static _SC_ASYNCHRONOUS_IO : c_int = 12; + pub static _SC_PRIORITIZED_IO : c_int = 13; + pub static _SC_SYNCHRONIZED_IO : c_int = 14; + pub static _SC_FSYNC : c_int = 15; + pub static _SC_MAPPED_FILES : c_int = 16; + pub static _SC_MEMLOCK : c_int = 17; + pub static _SC_MEMLOCK_RANGE : c_int = 18; + pub static _SC_MEMORY_PROTECTION : c_int = 19; + pub static _SC_MESSAGE_PASSING : c_int = 20; + pub static _SC_SEMAPHORES : c_int = 21; + pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 22; + pub static _SC_AIO_LISTIO_MAX : c_int = 23; + pub static _SC_AIO_MAX : c_int = 24; + pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 25; + pub static _SC_DELAYTIMER_MAX : c_int = 26; + pub static _SC_MQ_OPEN_MAX : c_int = 27; + pub static _SC_VERSION : c_int = 29; + pub static _SC_PAGESIZE : c_int = 30; + pub static _SC_RTSIG_MAX : c_int = 31; + pub static _SC_SEM_NSEMS_MAX : c_int = 32; + pub static _SC_SEM_VALUE_MAX : c_int = 33; + pub static _SC_SIGQUEUE_MAX : c_int = 34; + pub static _SC_TIMER_MAX : c_int = 35; + pub static _SC_BC_BASE_MAX : c_int = 36; + pub static _SC_BC_DIM_MAX : c_int = 37; + pub static _SC_BC_SCALE_MAX : c_int = 38; + pub static _SC_BC_STRING_MAX : c_int = 39; + pub static _SC_COLL_WEIGHTS_MAX : c_int = 40; + pub static _SC_EXPR_NEST_MAX : c_int = 42; + pub static _SC_LINE_MAX : c_int = 43; + pub static _SC_RE_DUP_MAX : c_int = 44; + pub static _SC_2_VERSION : c_int = 46; + pub static _SC_2_C_BIND : c_int = 47; + pub static _SC_2_C_DEV : c_int = 48; + pub static _SC_2_FORT_DEV : c_int = 49; + pub static _SC_2_FORT_RUN : c_int = 50; + pub static _SC_2_SW_DEV : c_int = 51; + pub static _SC_2_LOCALEDEF : c_int = 52; + pub static _SC_2_CHAR_TERM : c_int = 95; + pub static _SC_2_C_VERSION : c_int = 96; + pub static _SC_2_UPE : c_int = 97; + pub static _SC_XBS5_ILP32_OFF32 : c_int = 125; + pub static _SC_XBS5_ILP32_OFFBIG : c_int = 126; + pub static _SC_XBS5_LPBIG_OFFBIG : c_int = 128; } pub mod posix01 { - pub static SIGTRAP : int = 5; + use libc::types::os::arch::c95::c_int; - pub static GLOB_ERR : int = 1 << 0; - pub static GLOB_MARK : int = 1 << 1; - pub static GLOB_NOSORT : int = 1 << 2; - pub static GLOB_DOOFFS : int = 1 << 3; - pub static GLOB_NOCHECK : int = 1 << 4; - pub static GLOB_APPEND : int = 1 << 5; - pub static GLOB_NOESCAPE : int = 1 << 6; + pub static SIGTRAP : c_int = 5; - pub static GLOB_NOSPACE : int = 1; - pub static GLOB_ABORTED : int = 2; - pub static GLOB_NOMATCH : int = 3; + pub static GLOB_ERR : c_int = 1 << 0; + pub static GLOB_MARK : c_int = 1 << 1; + pub static GLOB_NOSORT : c_int = 1 << 2; + pub static GLOB_DOOFFS : c_int = 1 << 3; + pub static GLOB_NOCHECK : c_int = 1 << 4; + pub static GLOB_APPEND : c_int = 1 << 5; + pub static GLOB_NOESCAPE : c_int = 1 << 6; - pub static POSIX_MADV_NORMAL : int = 0; - pub static POSIX_MADV_RANDOM : int = 1; - pub static POSIX_MADV_SEQUENTIAL : int = 2; - pub static POSIX_MADV_WILLNEED : int = 3; - pub static POSIX_MADV_DONTNEED : int = 4; + pub static GLOB_NOSPACE : c_int = 1; + pub static GLOB_ABORTED : c_int = 2; + pub static GLOB_NOMATCH : c_int = 3; - pub static _SC_MQ_PRIO_MAX : int = 28; - pub static _SC_IOV_MAX : int = 60; - pub static _SC_GETGR_R_SIZE_MAX : int = 69; - pub static _SC_GETPW_R_SIZE_MAX : int = 70; - pub static _SC_LOGIN_NAME_MAX : int = 71; - pub static _SC_TTY_NAME_MAX : int = 72; - pub static _SC_THREADS : int = 67; - pub static _SC_THREAD_SAFE_FUNCTIONS : int = 68; - pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 73; - pub static _SC_THREAD_KEYS_MAX : int = 74; - pub static _SC_THREAD_STACK_MIN : int = 75; - pub static _SC_THREAD_THREADS_MAX : int = 76; - pub static _SC_THREAD_ATTR_STACKADDR : int = 77; - pub static _SC_THREAD_ATTR_STACKSIZE : int = 78; - pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 79; - pub static _SC_THREAD_PRIO_INHERIT : int = 80; - pub static _SC_THREAD_PRIO_PROTECT : int = 81; - pub static _SC_THREAD_PROCESS_SHARED : int = 82; - pub static _SC_ATEXIT_MAX : int = 87; - pub static _SC_XOPEN_VERSION : int = 89; - pub static _SC_XOPEN_XCU_VERSION : int = 90; - pub static _SC_XOPEN_UNIX : int = 91; - pub static _SC_XOPEN_CRYPT : int = 92; - pub static _SC_XOPEN_ENH_I18N : int = 93; - pub static _SC_XOPEN_SHM : int = 94; - pub static _SC_XOPEN_LEGACY : int = 129; - pub static _SC_XOPEN_REALTIME : int = 130; - pub static _SC_XOPEN_REALTIME_THREADS : int = 131; + pub static POSIX_MADV_NORMAL : c_int = 0; + pub static POSIX_MADV_RANDOM : c_int = 1; + pub static POSIX_MADV_SEQUENTIAL : c_int = 2; + pub static POSIX_MADV_WILLNEED : c_int = 3; + pub static POSIX_MADV_DONTNEED : c_int = 4; + + pub static _SC_MQ_PRIO_MAX : c_int = 28; + pub static _SC_IOV_MAX : c_int = 60; + pub static _SC_GETGR_R_SIZE_MAX : c_int = 69; + pub static _SC_GETPW_R_SIZE_MAX : c_int = 70; + pub static _SC_LOGIN_NAME_MAX : c_int = 71; + pub static _SC_TTY_NAME_MAX : c_int = 72; + pub static _SC_THREADS : c_int = 67; + pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 68; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 73; + pub static _SC_THREAD_KEYS_MAX : c_int = 74; + pub static _SC_THREAD_STACK_MIN : c_int = 75; + pub static _SC_THREAD_THREADS_MAX : c_int = 76; + pub static _SC_THREAD_ATTR_STACKADDR : c_int = 77; + pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 78; + pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 79; + pub static _SC_THREAD_PRIO_INHERIT : c_int = 80; + pub static _SC_THREAD_PRIO_PROTECT : c_int = 81; + pub static _SC_THREAD_PROCESS_SHARED : c_int = 82; + pub static _SC_ATEXIT_MAX : c_int = 87; + pub static _SC_XOPEN_VERSION : c_int = 89; + pub static _SC_XOPEN_XCU_VERSION : c_int = 90; + pub static _SC_XOPEN_UNIX : c_int = 91; + pub static _SC_XOPEN_CRYPT : c_int = 92; + pub static _SC_XOPEN_ENH_I18N : c_int = 93; + pub static _SC_XOPEN_SHM : c_int = 94; + pub static _SC_XOPEN_LEGACY : c_int = 129; + pub static _SC_XOPEN_REALTIME : c_int = 130; + pub static _SC_XOPEN_REALTIME_THREADS : c_int = 131; } pub mod posix08 { } pub mod bsd44 { - pub static MADV_NORMAL : int = 0; - pub static MADV_RANDOM : int = 1; - pub static MADV_SEQUENTIAL : int = 2; - pub static MADV_WILLNEED : int = 3; - pub static MADV_DONTNEED : int = 4; - pub static MADV_REMOVE : int = 9; - pub static MADV_DONTFORK : int = 10; - pub static MADV_DOFORK : int = 11; - pub static MADV_MERGEABLE : int = 12; - pub static MADV_UNMERGEABLE : int = 13; - pub static MADV_HWPOISON : int = 100; + use libc::types::os::arch::c95::c_int; + + pub static MADV_NORMAL : c_int = 0; + pub static MADV_RANDOM : c_int = 1; + pub static MADV_SEQUENTIAL : c_int = 2; + pub static MADV_WILLNEED : c_int = 3; + pub static MADV_DONTNEED : c_int = 4; + pub static MADV_REMOVE : c_int = 9; + pub static MADV_DONTFORK : c_int = 10; + pub static MADV_DOFORK : c_int = 11; + pub static MADV_MERGEABLE : c_int = 12; + pub static MADV_UNMERGEABLE : c_int = 13; + pub static MADV_HWPOISON : c_int = 100; } #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] #[cfg(target_arch = "arm")] pub mod extra { - pub static O_RSYNC : int = 1052672; - pub static O_DSYNC : int = 4096; - pub static O_SYNC : int = 1052672; + use libc::types::os::arch::c95::c_int; - pub static PROT_GROWSDOWN : int = 0x010000000; - pub static PROT_GROWSUP : int = 0x020000000; + pub static O_RSYNC : c_int = 1052672; + pub static O_DSYNC : c_int = 4096; + pub static O_SYNC : c_int = 1052672; - pub static MAP_TYPE : int = 0x000f; - pub static MAP_ANONONYMOUS : int = 0x1000; - pub static MAP_32BIT : int = 0x0040; - pub static MAP_GROWSDOWN : int = 0x0100; - pub static MAP_DENYWRITE : int = 0x0800; - pub static MAP_EXECUTABLE : int = 0x01000; - pub static MAP_LOCKED : int = 0x02000; - pub static MAP_NONRESERVE : int = 0x04000; - pub static MAP_POPULATE : int = 0x08000; - pub static MAP_NONBLOCK : int = 0x010000; - pub static MAP_STACK : int = 0x020000; + pub static PROT_GROWSDOWN : c_int = 0x010000000; + pub static PROT_GROWSUP : c_int = 0x020000000; + + pub static MAP_TYPE : c_int = 0x000f; + pub static MAP_ANONONYMOUS : c_int = 0x1000; + pub static MAP_32BIT : c_int = 0x0040; + pub static MAP_GROWSDOWN : c_int = 0x0100; + pub static MAP_DENYWRITE : c_int = 0x0800; + pub static MAP_EXECUTABLE : c_int = 0x01000; + pub static MAP_LOCKED : c_int = 0x02000; + pub static MAP_NONRESERVE : c_int = 0x04000; + pub static MAP_POPULATE : c_int = 0x08000; + pub static MAP_NONBLOCK : c_int = 0x010000; + pub static MAP_STACK : c_int = 0x020000; } #[cfg(target_arch = "mips")] pub mod extra { - pub static O_RSYNC : int = 16400; - pub static O_DSYNC : int = 16; - pub static O_SYNC : int = 16400; + use libc::types::os::arch::c95::c_int; - pub static PROT_GROWSDOWN : int = 0x010000000; - pub static PROT_GROWSUP : int = 0x020000000; + pub static O_RSYNC : c_int = 16400; + pub static O_DSYNC : c_int = 16; + pub static O_SYNC : c_int = 16400; - pub static MAP_TYPE : int = 0x000f; - pub static MAP_ANONONYMOUS : int = 0x1000; - pub static MAP_32BIT : int = 0x0040; - pub static MAP_GROWSDOWN : int = 0x0100; - pub static MAP_DENYWRITE : int = 0x0800; - pub static MAP_EXECUTABLE : int = 0x01000; - pub static MAP_LOCKED : int = 0x02000; - pub static MAP_NONRESERVE : int = 0x04000; - pub static MAP_POPULATE : int = 0x08000; - pub static MAP_NONBLOCK : int = 0x010000; - pub static MAP_STACK : int = 0x020000; + pub static PROT_GROWSDOWN : c_int = 0x010000000; + pub static PROT_GROWSUP : c_int = 0x020000000; + + pub static MAP_TYPE : c_int = 0x000f; + pub static MAP_ANONONYMOUS : c_int = 0x1000; + pub static MAP_32BIT : c_int = 0x0040; + pub static MAP_GROWSDOWN : c_int = 0x0100; + pub static MAP_DENYWRITE : c_int = 0x0800; + pub static MAP_EXECUTABLE : c_int = 0x01000; + pub static MAP_LOCKED : c_int = 0x02000; + pub static MAP_NONRESERVE : c_int = 0x04000; + pub static MAP_POPULATE : c_int = 0x08000; + pub static MAP_NONBLOCK : c_int = 0x010000; + pub static MAP_STACK : c_int = 0x020000; } } #[cfg(target_os = "freebsd")] pub mod os { pub mod c95 { - pub static EXIT_FAILURE : int = 1; - pub static EXIT_SUCCESS : int = 0; - pub static RAND_MAX : int = 2147483647; - pub static EOF : int = -1; - pub static SEEK_SET : int = 0; - pub static SEEK_CUR : int = 1; - pub static SEEK_END : int = 2; - pub static _IOFBF : int = 0; - pub static _IONBF : int = 2; - pub static _IOLBF : int = 1; - pub static BUFSIZ : uint = 1024_u; - pub static FOPEN_MAX : uint = 20_u; - pub static FILENAME_MAX : uint = 1024_u; - pub static L_tmpnam : uint = 1024_u; - pub static TMP_MAX : uint = 308915776_u; + use libc::types::os::arch::c95::{c_int, c_uint}; + + pub static EXIT_FAILURE : c_int = 1; + pub static EXIT_SUCCESS : c_int = 0; + pub static RAND_MAX : c_int = 2147483647; + pub static EOF : c_int = -1; + pub static SEEK_SET : c_int = 0; + pub static SEEK_CUR : c_int = 1; + pub static SEEK_END : c_int = 2; + pub static _IOFBF : c_int = 0; + pub static _IONBF : c_int = 2; + pub static _IOLBF : c_int = 1; + pub static BUFSIZ : c_uint = 1024_u32; + pub static FOPEN_MAX : c_uint = 20_u32; + pub static FILENAME_MAX : c_uint = 1024_u32; + pub static L_tmpnam : c_uint = 1024_u32; + pub static TMP_MAX : c_uint = 308915776_u32; } pub mod c99 { } pub mod posix88 { use libc::types::common::c95::c_void; + use libc::types::os::arch::c95::c_int; - pub static O_RDONLY : int = 0; - pub static O_WRONLY : int = 1; - pub static O_RDWR : int = 2; - pub static O_APPEND : int = 8; - pub static O_CREAT : int = 512; - pub static O_EXCL : int = 2048; - pub static O_TRUNC : int = 1024; - pub static S_IFIFO : int = 4096; - pub static S_IFCHR : int = 8192; - pub static S_IFBLK : int = 24576; - pub static S_IFDIR : int = 16384; - pub static S_IFREG : int = 32768; - pub static S_IFMT : int = 61440; - pub static S_IEXEC : int = 64; - pub static S_IWRITE : int = 128; - pub static S_IREAD : int = 256; - pub static S_IRWXU : int = 448; - pub static S_IXUSR : int = 64; - pub static S_IWUSR : int = 128; - pub static S_IRUSR : int = 256; - pub static F_OK : int = 0; - pub static R_OK : int = 4; - pub static W_OK : int = 2; - pub static X_OK : int = 1; - pub static STDIN_FILENO : int = 0; - pub static STDOUT_FILENO : int = 1; - pub static STDERR_FILENO : int = 2; - pub static F_LOCK : int = 1; - pub static F_TEST : int = 3; - pub static F_TLOCK : int = 2; - pub static F_ULOCK : int = 0; - pub static SIGHUP : int = 1; - pub static SIGINT : int = 2; - pub static SIGQUIT : int = 3; - pub static SIGILL : int = 4; - pub static SIGABRT : int = 6; - pub static SIGFPE : int = 8; - pub static SIGKILL : int = 9; - pub static SIGSEGV : int = 11; - pub static SIGPIPE : int = 13; - pub static SIGALRM : int = 14; - pub static SIGTERM : int = 15; + pub static O_RDONLY : c_int = 0; + pub static O_WRONLY : c_int = 1; + pub static O_RDWR : c_int = 2; + pub static O_APPEND : c_int = 8; + pub static O_CREAT : c_int = 512; + pub static O_EXCL : c_int = 2048; + pub static O_TRUNC : c_int = 1024; + pub static S_IFIFO : c_int = 4096; + pub static S_IFCHR : c_int = 8192; + pub static S_IFBLK : c_int = 24576; + pub static S_IFDIR : c_int = 16384; + pub static S_IFREG : c_int = 32768; + pub static S_IFMT : c_int = 61440; + pub static S_IEXEC : c_int = 64; + pub static S_IWRITE : c_int = 128; + pub static S_IREAD : c_int = 256; + pub static S_IRWXU : c_int = 448; + pub static S_IXUSR : c_int = 64; + pub static S_IWUSR : c_int = 128; + pub static S_IRUSR : c_int = 256; + pub static F_OK : c_int = 0; + pub static R_OK : c_int = 4; + pub static W_OK : c_int = 2; + pub static X_OK : c_int = 1; + pub static STDIN_FILENO : c_int = 0; + pub static STDOUT_FILENO : c_int = 1; + pub static STDERR_FILENO : c_int = 2; + pub static F_LOCK : c_int = 1; + pub static F_TEST : c_int = 3; + pub static F_TLOCK : c_int = 2; + pub static F_ULOCK : c_int = 0; + pub static SIGHUP : c_int = 1; + pub static SIGINT : c_int = 2; + pub static SIGQUIT : c_int = 3; + pub static SIGILL : c_int = 4; + pub static SIGABRT : c_int = 6; + pub static SIGFPE : c_int = 8; + pub static SIGKILL : c_int = 9; + pub static SIGSEGV : c_int = 11; + pub static SIGPIPE : c_int = 13; + pub static SIGALRM : c_int = 14; + pub static SIGTERM : c_int = 15; - pub static PROT_NONE : int = 0; - pub static PROT_READ : int = 1; - pub static PROT_WRITE : int = 2; - pub static PROT_EXEC : int = 4; + pub static PROT_NONE : c_int = 0; + pub static PROT_READ : c_int = 1; + pub static PROT_WRITE : c_int = 2; + pub static PROT_EXEC : c_int = 4; - pub static MAP_FILE : int = 0x0000; - pub static MAP_SHARED : int = 0x0001; - pub static MAP_PRIVATE : int = 0x0002; - pub static MAP_FIXED : int = 0x0010; - pub static MAP_ANON : int = 0x1000; + pub static MAP_FILE : c_int = 0x0000; + pub static MAP_SHARED : c_int = 0x0001; + pub static MAP_PRIVATE : c_int = 0x0002; + pub static MAP_FIXED : c_int = 0x0010; + pub static MAP_ANON : c_int = 0x1000; pub static MAP_FAILED : *c_void = -1 as *c_void; - pub static MCL_CURRENT : int = 0x0001; - pub static MCL_FUTURE : int = 0x0002; + pub static MCL_CURRENT : c_int = 0x0001; + pub static MCL_FUTURE : c_int = 0x0002; - pub static MS_SYNC : int = 0x0000; - pub static MS_ASYNC : int = 0x0001; - pub static MS_INVALIDATE : int = 0x0002; + pub static MS_SYNC : c_int = 0x0000; + pub static MS_ASYNC : c_int = 0x0001; + pub static MS_INVALIDATE : c_int = 0x0002; - pub static _SC_ARG_MAX : int = 1; - pub static _SC_CHILD_MAX : int = 2; - pub static _SC_CLK_TCK : int = 3; - pub static _SC_NGROUPS_MAX : int = 4; - pub static _SC_OPEN_MAX : int = 5; - pub static _SC_JOB_CONTROL : int = 6; - pub static _SC_SAVED_IDS : int = 7; - pub static _SC_VERSION : int = 8; - pub static _SC_BC_BASE_MAX : int = 9; - pub static _SC_BC_DIM_MAX : int = 10; - pub static _SC_BC_SCALE_MAX : int = 11; - pub static _SC_BC_STRING_MAX : int = 12; - pub static _SC_COLL_WEIGHTS_MAX : int = 13; - pub static _SC_EXPR_NEST_MAX : int = 14; - pub static _SC_LINE_MAX : int = 15; - pub static _SC_RE_DUP_MAX : int = 16; - pub static _SC_2_VERSION : int = 17; - pub static _SC_2_C_BIND : int = 18; - pub static _SC_2_C_DEV : int = 19; - pub static _SC_2_CHAR_TERM : int = 20; - pub static _SC_2_FORT_DEV : int = 21; - pub static _SC_2_FORT_RUN : int = 22; - pub static _SC_2_LOCALEDEF : int = 23; - pub static _SC_2_SW_DEV : int = 24; - pub static _SC_2_UPE : int = 25; - pub static _SC_STREAM_MAX : int = 26; - pub static _SC_TZNAME_MAX : int = 27; - pub static _SC_ASYNCHRONOUS_IO : int = 28; - pub static _SC_MAPPED_FILES : int = 29; - pub static _SC_MEMLOCK : int = 30; - pub static _SC_MEMLOCK_RANGE : int = 31; - pub static _SC_MEMORY_PROTECTION : int = 32; - pub static _SC_MESSAGE_PASSING : int = 33; - pub static _SC_PRIORITIZED_IO : int = 34; - pub static _SC_PRIORITY_SCHEDULING : int = 35; - pub static _SC_REALTIME_SIGNALS : int = 36; - pub static _SC_SEMAPHORES : int = 37; - pub static _SC_FSYNC : int = 38; - pub static _SC_SHARED_MEMORY_OBJECTS : int = 39; - pub static _SC_SYNCHRONIZED_IO : int = 40; - pub static _SC_TIMERS : int = 41; - pub static _SC_AIO_LISTIO_MAX : int = 42; - pub static _SC_AIO_MAX : int = 43; - pub static _SC_AIO_PRIO_DELTA_MAX : int = 44; - pub static _SC_DELAYTIMER_MAX : int = 45; - pub static _SC_MQ_OPEN_MAX : int = 46; - pub static _SC_PAGESIZE : int = 47; - pub static _SC_RTSIG_MAX : int = 48; - pub static _SC_SEM_NSEMS_MAX : int = 49; - pub static _SC_SEM_VALUE_MAX : int = 50; - pub static _SC_SIGQUEUE_MAX : int = 51; - pub static _SC_TIMER_MAX : int = 52; + pub static _SC_ARG_MAX : c_int = 1; + pub static _SC_CHILD_MAX : c_int = 2; + pub static _SC_CLK_TCK : c_int = 3; + pub static _SC_NGROUPS_MAX : c_int = 4; + pub static _SC_OPEN_MAX : c_int = 5; + pub static _SC_JOB_CONTROL : c_int = 6; + pub static _SC_SAVED_IDS : c_int = 7; + pub static _SC_VERSION : c_int = 8; + pub static _SC_BC_BASE_MAX : c_int = 9; + pub static _SC_BC_DIM_MAX : c_int = 10; + pub static _SC_BC_SCALE_MAX : c_int = 11; + pub static _SC_BC_STRING_MAX : c_int = 12; + pub static _SC_COLL_WEIGHTS_MAX : c_int = 13; + pub static _SC_EXPR_NEST_MAX : c_int = 14; + pub static _SC_LINE_MAX : c_int = 15; + pub static _SC_RE_DUP_MAX : c_int = 16; + pub static _SC_2_VERSION : c_int = 17; + pub static _SC_2_C_BIND : c_int = 18; + pub static _SC_2_C_DEV : c_int = 19; + pub static _SC_2_CHAR_TERM : c_int = 20; + pub static _SC_2_FORT_DEV : c_int = 21; + pub static _SC_2_FORT_RUN : c_int = 22; + pub static _SC_2_LOCALEDEF : c_int = 23; + pub static _SC_2_SW_DEV : c_int = 24; + pub static _SC_2_UPE : c_int = 25; + pub static _SC_STREAM_MAX : c_int = 26; + pub static _SC_TZNAME_MAX : c_int = 27; + pub static _SC_ASYNCHRONOUS_IO : c_int = 28; + pub static _SC_MAPPED_FILES : c_int = 29; + pub static _SC_MEMLOCK : c_int = 30; + pub static _SC_MEMLOCK_RANGE : c_int = 31; + pub static _SC_MEMORY_PROTECTION : c_int = 32; + pub static _SC_MESSAGE_PASSING : c_int = 33; + pub static _SC_PRIORITIZED_IO : c_int = 34; + pub static _SC_PRIORITY_SCHEDULING : c_int = 35; + pub static _SC_REALTIME_SIGNALS : c_int = 36; + pub static _SC_SEMAPHORES : c_int = 37; + pub static _SC_FSYNC : c_int = 38; + pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 39; + pub static _SC_SYNCHRONIZED_IO : c_int = 40; + pub static _SC_TIMERS : c_int = 41; + pub static _SC_AIO_LISTIO_MAX : c_int = 42; + pub static _SC_AIO_MAX : c_int = 43; + pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 44; + pub static _SC_DELAYTIMER_MAX : c_int = 45; + pub static _SC_MQ_OPEN_MAX : c_int = 46; + pub static _SC_PAGESIZE : c_int = 47; + pub static _SC_RTSIG_MAX : c_int = 48; + pub static _SC_SEM_NSEMS_MAX : c_int = 49; + pub static _SC_SEM_VALUE_MAX : c_int = 50; + pub static _SC_SIGQUEUE_MAX : c_int = 51; + pub static _SC_TIMER_MAX : c_int = 52; } pub mod posix01 { - pub static SIGTRAP : int = 5; + use libc::types::os::arch::c95::c_int; - pub static GLOB_APPEND : int = 0x0001; - pub static GLOB_DOOFFS : int = 0x0002; - pub static GLOB_ERR : int = 0x0004; - pub static GLOB_MARK : int = 0x0008; - pub static GLOB_NOCHECK : int = 0x0010; - pub static GLOB_NOSORT : int = 0x0020; - pub static GLOB_NOESCAPE : int = 0x2000; + pub static SIGTRAP : c_int = 5; - pub static GLOB_NOSPACE : int = -1; - pub static GLOB_ABORTED : int = -2; - pub static GLOB_NOMATCH : int = -3; + pub static GLOB_APPEND : c_int = 0x0001; + pub static GLOB_DOOFFS : c_int = 0x0002; + pub static GLOB_ERR : c_int = 0x0004; + pub static GLOB_MARK : c_int = 0x0008; + pub static GLOB_NOCHECK : c_int = 0x0010; + pub static GLOB_NOSORT : c_int = 0x0020; + pub static GLOB_NOESCAPE : c_int = 0x2000; - pub static POSIX_MADV_NORMAL : int = 0; - pub static POSIX_MADV_RANDOM : int = 1; - pub static POSIX_MADV_SEQUENTIAL : int = 2; - pub static POSIX_MADV_WILLNEED : int = 3; - pub static POSIX_MADV_DONTNEED : int = 4; + pub static GLOB_NOSPACE : c_int = -1; + pub static GLOB_ABORTED : c_int = -2; + pub static GLOB_NOMATCH : c_int = -3; - pub static _SC_IOV_MAX : int = 56; - pub static _SC_GETGR_R_SIZE_MAX : int = 70; - pub static _SC_GETPW_R_SIZE_MAX : int = 71; - pub static _SC_LOGIN_NAME_MAX : int = 73; - pub static _SC_MQ_PRIO_MAX : int = 75; - pub static _SC_THREAD_ATTR_STACKADDR : int = 82; - pub static _SC_THREAD_ATTR_STACKSIZE : int = 83; - pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 85; - pub static _SC_THREAD_KEYS_MAX : int = 86; - pub static _SC_THREAD_PRIO_INHERIT : int = 87; - pub static _SC_THREAD_PRIO_PROTECT : int = 88; - pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 89; - pub static _SC_THREAD_PROCESS_SHARED : int = 90; - pub static _SC_THREAD_SAFE_FUNCTIONS : int = 91; - pub static _SC_THREAD_STACK_MIN : int = 93; - pub static _SC_THREAD_THREADS_MAX : int = 94; - pub static _SC_THREADS : int = 96; - pub static _SC_TTY_NAME_MAX : int = 101; - pub static _SC_ATEXIT_MAX : int = 107; - pub static _SC_XOPEN_CRYPT : int = 108; - pub static _SC_XOPEN_ENH_I18N : int = 109; - pub static _SC_XOPEN_LEGACY : int = 110; - pub static _SC_XOPEN_REALTIME : int = 111; - pub static _SC_XOPEN_REALTIME_THREADS : int = 112; - pub static _SC_XOPEN_SHM : int = 113; - pub static _SC_XOPEN_UNIX : int = 115; - pub static _SC_XOPEN_VERSION : int = 116; - pub static _SC_XOPEN_XCU_VERSION : int = 117; + pub static POSIX_MADV_NORMAL : c_int = 0; + pub static POSIX_MADV_RANDOM : c_int = 1; + pub static POSIX_MADV_SEQUENTIAL : c_int = 2; + pub static POSIX_MADV_WILLNEED : c_int = 3; + pub static POSIX_MADV_DONTNEED : c_int = 4; + + pub static _SC_IOV_MAX : c_int = 56; + pub static _SC_GETGR_R_SIZE_MAX : c_int = 70; + pub static _SC_GETPW_R_SIZE_MAX : c_int = 71; + pub static _SC_LOGIN_NAME_MAX : c_int = 73; + pub static _SC_MQ_PRIO_MAX : c_int = 75; + pub static _SC_THREAD_ATTR_STACKADDR : c_int = 82; + pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 83; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 85; + pub static _SC_THREAD_KEYS_MAX : c_int = 86; + pub static _SC_THREAD_PRIO_INHERIT : c_int = 87; + pub static _SC_THREAD_PRIO_PROTECT : c_int = 88; + pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 89; + pub static _SC_THREAD_PROCESS_SHARED : c_int = 90; + pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 91; + pub static _SC_THREAD_STACK_MIN : c_int = 93; + pub static _SC_THREAD_THREADS_MAX : c_int = 94; + pub static _SC_THREADS : c_int = 96; + pub static _SC_TTY_NAME_MAX : c_int = 101; + pub static _SC_ATEXIT_MAX : c_int = 107; + pub static _SC_XOPEN_CRYPT : c_int = 108; + pub static _SC_XOPEN_ENH_I18N : c_int = 109; + pub static _SC_XOPEN_LEGACY : c_int = 110; + pub static _SC_XOPEN_REALTIME : c_int = 111; + pub static _SC_XOPEN_REALTIME_THREADS : c_int = 112; + pub static _SC_XOPEN_SHM : c_int = 113; + pub static _SC_XOPEN_UNIX : c_int = 115; + pub static _SC_XOPEN_VERSION : c_int = 116; + pub static _SC_XOPEN_XCU_VERSION : c_int = 117; } pub mod posix08 { } pub mod bsd44 { - pub static MADV_NORMAL : int = 0; - pub static MADV_RANDOM : int = 1; - pub static MADV_SEQUENTIAL : int = 2; - pub static MADV_WILLNEED : int = 3; - pub static MADV_DONTNEED : int = 4; - pub static MADV_FREE : int = 5; - pub static MADV_NOSYNC : int = 6; - pub static MADV_AUTOSYNC : int = 7; - pub static MADV_NOCORE : int = 8; - pub static MADV_CORE : int = 9; - pub static MADV_PROTECT : int = 10; + use libc::types::os::arch::c95::c_int; - pub static MINCORE_INCORE : int = 0x1; - pub static MINCORE_REFERENCED : int = 0x2; - pub static MINCORE_MODIFIED : int = 0x4; - pub static MINCORE_REFERENCED_OTHER : int = 0x8; - pub static MINCORE_MODIFIED_OTHER : int = 0x10; - pub static MINCORE_SUPER : int = 0x20; + pub static MADV_NORMAL : c_int = 0; + pub static MADV_RANDOM : c_int = 1; + pub static MADV_SEQUENTIAL : c_int = 2; + pub static MADV_WILLNEED : c_int = 3; + pub static MADV_DONTNEED : c_int = 4; + pub static MADV_FREE : c_int = 5; + pub static MADV_NOSYNC : c_int = 6; + pub static MADV_AUTOSYNC : c_int = 7; + pub static MADV_NOCORE : c_int = 8; + pub static MADV_CORE : c_int = 9; + pub static MADV_PROTECT : c_int = 10; + + pub static MINCORE_INCORE : c_int = 0x1; + pub static MINCORE_REFERENCED : c_int = 0x2; + pub static MINCORE_MODIFIED : c_int = 0x4; + pub static MINCORE_REFERENCED_OTHER : c_int = 0x8; + pub static MINCORE_MODIFIED_OTHER : c_int = 0x10; + pub static MINCORE_SUPER : c_int = 0x20; } pub mod extra { - pub static O_SYNC : int = 128; - pub static CTL_KERN: int = 1; - pub static KERN_PROC: int = 14; - pub static KERN_PROC_PATHNAME: int = 12; + use libc::types::os::arch::c95::c_int; - pub static MAP_COPY : int = 0x0002; - pub static MAP_RENAME : int = 0x0020; - pub static MAP_NORESERVE : int = 0x0040; - pub static MAP_HASSEMAPHORE : int = 0x0200; - pub static MAP_STACK : int = 0x0400; - pub static MAP_NOSYNC : int = 0x0800; - pub static MAP_NOCORE : int = 0x020000; + pub static O_SYNC : c_int = 128; + pub static CTL_KERN: c_int = 1; + pub static KERN_PROC: c_int = 14; + pub static KERN_PROC_PATHNAME: c_int = 12; + + pub static MAP_COPY : c_int = 0x0002; + pub static MAP_RENAME : c_int = 0x0020; + pub static MAP_NORESERVE : c_int = 0x0040; + pub static MAP_HASSEMAPHORE : c_int = 0x0200; + pub static MAP_STACK : c_int = 0x0400; + pub static MAP_NOSYNC : c_int = 0x0800; + pub static MAP_NOCORE : c_int = 0x020000; } } #[cfg(target_os = "macos")] pub mod os { pub mod c95 { - pub static EXIT_FAILURE : int = 1; - pub static EXIT_SUCCESS : int = 0; - pub static RAND_MAX : int = 2147483647; - pub static EOF : int = -1; - pub static SEEK_SET : int = 0; - pub static SEEK_CUR : int = 1; - pub static SEEK_END : int = 2; - pub static _IOFBF : int = 0; - pub static _IONBF : int = 2; - pub static _IOLBF : int = 1; - pub static BUFSIZ : uint = 1024_u; - pub static FOPEN_MAX : uint = 20_u; - pub static FILENAME_MAX : uint = 1024_u; - pub static L_tmpnam : uint = 1024_u; - pub static TMP_MAX : uint = 308915776_u; + use libc::types::os::arch::c95::{c_int, c_uint}; + + pub static EXIT_FAILURE : c_int = 1; + pub static EXIT_SUCCESS : c_int = 0; + pub static RAND_MAX : c_int = 2147483647; + pub static EOF : c_int = -1; + pub static SEEK_SET : c_int = 0; + pub static SEEK_CUR : c_int = 1; + pub static SEEK_END : c_int = 2; + pub static _IOFBF : c_int = 0; + pub static _IONBF : c_int = 2; + pub static _IOLBF : c_int = 1; + pub static BUFSIZ : c_uint = 1024_u32; + pub static FOPEN_MAX : c_uint = 20_u32; + pub static FILENAME_MAX : c_uint = 1024_u32; + pub static L_tmpnam : c_uint = 1024_u32; + pub static TMP_MAX : c_uint = 308915776_u32; } pub mod c99 { } pub mod posix88 { use libc::types::common::c95::c_void; + use libc::types::os::arch::c95::c_int; - pub static O_RDONLY : int = 0; - pub static O_WRONLY : int = 1; - pub static O_RDWR : int = 2; - pub static O_APPEND : int = 8; - pub static O_CREAT : int = 512; - pub static O_EXCL : int = 2048; - pub static O_TRUNC : int = 1024; - pub static S_IFIFO : int = 4096; - pub static S_IFCHR : int = 8192; - pub static S_IFBLK : int = 24576; - pub static S_IFDIR : int = 16384; - pub static S_IFREG : int = 32768; - pub static S_IFMT : int = 61440; - pub static S_IEXEC : int = 64; - pub static S_IWRITE : int = 128; - pub static S_IREAD : int = 256; - pub static S_IRWXU : int = 448; - pub static S_IXUSR : int = 64; - pub static S_IWUSR : int = 128; - pub static S_IRUSR : int = 256; - pub static F_OK : int = 0; - pub static R_OK : int = 4; - pub static W_OK : int = 2; - pub static X_OK : int = 1; - pub static STDIN_FILENO : int = 0; - pub static STDOUT_FILENO : int = 1; - pub static STDERR_FILENO : int = 2; - pub static F_LOCK : int = 1; - pub static F_TEST : int = 3; - pub static F_TLOCK : int = 2; - pub static F_ULOCK : int = 0; - pub static SIGHUP : int = 1; - pub static SIGINT : int = 2; - pub static SIGQUIT : int = 3; - pub static SIGILL : int = 4; - pub static SIGABRT : int = 6; - pub static SIGFPE : int = 8; - pub static SIGKILL : int = 9; - pub static SIGSEGV : int = 11; - pub static SIGPIPE : int = 13; - pub static SIGALRM : int = 14; - pub static SIGTERM : int = 15; + pub static O_RDONLY : c_int = 0; + pub static O_WRONLY : c_int = 1; + pub static O_RDWR : c_int = 2; + pub static O_APPEND : c_int = 8; + pub static O_CREAT : c_int = 512; + pub static O_EXCL : c_int = 2048; + pub static O_TRUNC : c_int = 1024; + pub static S_IFIFO : c_int = 4096; + pub static S_IFCHR : c_int = 8192; + pub static S_IFBLK : c_int = 24576; + pub static S_IFDIR : c_int = 16384; + pub static S_IFREG : c_int = 32768; + pub static S_IFMT : c_int = 61440; + pub static S_IEXEC : c_int = 64; + pub static S_IWRITE : c_int = 128; + pub static S_IREAD : c_int = 256; + pub static S_IRWXU : c_int = 448; + pub static S_IXUSR : c_int = 64; + pub static S_IWUSR : c_int = 128; + pub static S_IRUSR : c_int = 256; + pub static F_OK : c_int = 0; + pub static R_OK : c_int = 4; + pub static W_OK : c_int = 2; + pub static X_OK : c_int = 1; + pub static STDIN_FILENO : c_int = 0; + pub static STDOUT_FILENO : c_int = 1; + pub static STDERR_FILENO : c_int = 2; + pub static F_LOCK : c_int = 1; + pub static F_TEST : c_int = 3; + pub static F_TLOCK : c_int = 2; + pub static F_ULOCK : c_int = 0; + pub static SIGHUP : c_int = 1; + pub static SIGINT : c_int = 2; + pub static SIGQUIT : c_int = 3; + pub static SIGILL : c_int = 4; + pub static SIGABRT : c_int = 6; + pub static SIGFPE : c_int = 8; + pub static SIGKILL : c_int = 9; + pub static SIGSEGV : c_int = 11; + pub static SIGPIPE : c_int = 13; + pub static SIGALRM : c_int = 14; + pub static SIGTERM : c_int = 15; - pub static PROT_NONE : int = 0; - pub static PROT_READ : int = 1; - pub static PROT_WRITE : int = 2; - pub static PROT_EXEC : int = 4; + pub static PROT_NONE : c_int = 0; + pub static PROT_READ : c_int = 1; + pub static PROT_WRITE : c_int = 2; + pub static PROT_EXEC : c_int = 4; - pub static MAP_FILE : int = 0x0000; - pub static MAP_SHARED : int = 0x0001; - pub static MAP_PRIVATE : int = 0x0002; - pub static MAP_FIXED : int = 0x0010; - pub static MAP_ANON : int = 0x1000; + pub static MAP_FILE : c_int = 0x0000; + pub static MAP_SHARED : c_int = 0x0001; + pub static MAP_PRIVATE : c_int = 0x0002; + pub static MAP_FIXED : c_int = 0x0010; + pub static MAP_ANON : c_int = 0x1000; pub static MAP_FAILED : *c_void = -1 as *c_void; - pub static MCL_CURRENT : int = 0x0001; - pub static MCL_FUTURE : int = 0x0002; + pub static MCL_CURRENT : c_int = 0x0001; + pub static MCL_FUTURE : c_int = 0x0002; - pub static MS_ASYNC : int = 0x0001; - pub static MS_INVALIDATE : int = 0x0002; - pub static MS_SYNC : int = 0x0010; + pub static MS_ASYNC : c_int = 0x0001; + pub static MS_INVALIDATE : c_int = 0x0002; + pub static MS_SYNC : c_int = 0x0010; - pub static MS_KILLPAGES : int = 0x0004; - pub static MS_DEACTIVATE : int = 0x0008; + pub static MS_KILLPAGES : c_int = 0x0004; + pub static MS_DEACTIVATE : c_int = 0x0008; - pub static _SC_ARG_MAX : int = 1; - pub static _SC_CHILD_MAX : int = 2; - pub static _SC_CLK_TCK : int = 3; - pub static _SC_NGROUPS_MAX : int = 4; - pub static _SC_OPEN_MAX : int = 5; - pub static _SC_JOB_CONTROL : int = 6; - pub static _SC_SAVED_IDS : int = 7; - pub static _SC_VERSION : int = 8; - pub static _SC_BC_BASE_MAX : int = 9; - pub static _SC_BC_DIM_MAX : int = 10; - pub static _SC_BC_SCALE_MAX : int = 11; - pub static _SC_BC_STRING_MAX : int = 12; - pub static _SC_COLL_WEIGHTS_MAX : int = 13; - pub static _SC_EXPR_NEST_MAX : int = 14; - pub static _SC_LINE_MAX : int = 15; - pub static _SC_RE_DUP_MAX : int = 16; - pub static _SC_2_VERSION : int = 17; - pub static _SC_2_C_BIND : int = 18; - pub static _SC_2_C_DEV : int = 19; - pub static _SC_2_CHAR_TERM : int = 20; - pub static _SC_2_FORT_DEV : int = 21; - pub static _SC_2_FORT_RUN : int = 22; - pub static _SC_2_LOCALEDEF : int = 23; - pub static _SC_2_SW_DEV : int = 24; - pub static _SC_2_UPE : int = 25; - pub static _SC_STREAM_MAX : int = 26; - pub static _SC_TZNAME_MAX : int = 27; - pub static _SC_ASYNCHRONOUS_IO : int = 28; - pub static _SC_PAGESIZE : int = 29; - pub static _SC_MEMLOCK : int = 30; - pub static _SC_MEMLOCK_RANGE : int = 31; - pub static _SC_MEMORY_PROTECTION : int = 32; - pub static _SC_MESSAGE_PASSING : int = 33; - pub static _SC_PRIORITIZED_IO : int = 34; - pub static _SC_PRIORITY_SCHEDULING : int = 35; - pub static _SC_REALTIME_SIGNALS : int = 36; - pub static _SC_SEMAPHORES : int = 37; - pub static _SC_FSYNC : int = 38; - pub static _SC_SHARED_MEMORY_OBJECTS : int = 39; - pub static _SC_SYNCHRONIZED_IO : int = 40; - pub static _SC_TIMERS : int = 41; - pub static _SC_AIO_LISTIO_MAX : int = 42; - pub static _SC_AIO_MAX : int = 43; - pub static _SC_AIO_PRIO_DELTA_MAX : int = 44; - pub static _SC_DELAYTIMER_MAX : int = 45; - pub static _SC_MQ_OPEN_MAX : int = 46; - pub static _SC_MAPPED_FILES : int = 47; - pub static _SC_RTSIG_MAX : int = 48; - pub static _SC_SEM_NSEMS_MAX : int = 49; - pub static _SC_SEM_VALUE_MAX : int = 50; - pub static _SC_SIGQUEUE_MAX : int = 51; - pub static _SC_TIMER_MAX : int = 52; - pub static _SC_XBS5_ILP32_OFF32 : int = 122; - pub static _SC_XBS5_ILP32_OFFBIG : int = 123; - pub static _SC_XBS5_LP64_OFF64 : int = 124; - pub static _SC_XBS5_LPBIG_OFFBIG : int = 125; + pub static _SC_ARG_MAX : c_int = 1; + pub static _SC_CHILD_MAX : c_int = 2; + pub static _SC_CLK_TCK : c_int = 3; + pub static _SC_NGROUPS_MAX : c_int = 4; + pub static _SC_OPEN_MAX : c_int = 5; + pub static _SC_JOB_CONTROL : c_int = 6; + pub static _SC_SAVED_IDS : c_int = 7; + pub static _SC_VERSION : c_int = 8; + pub static _SC_BC_BASE_MAX : c_int = 9; + pub static _SC_BC_DIM_MAX : c_int = 10; + pub static _SC_BC_SCALE_MAX : c_int = 11; + pub static _SC_BC_STRING_MAX : c_int = 12; + pub static _SC_COLL_WEIGHTS_MAX : c_int = 13; + pub static _SC_EXPR_NEST_MAX : c_int = 14; + pub static _SC_LINE_MAX : c_int = 15; + pub static _SC_RE_DUP_MAX : c_int = 16; + pub static _SC_2_VERSION : c_int = 17; + pub static _SC_2_C_BIND : c_int = 18; + pub static _SC_2_C_DEV : c_int = 19; + pub static _SC_2_CHAR_TERM : c_int = 20; + pub static _SC_2_FORT_DEV : c_int = 21; + pub static _SC_2_FORT_RUN : c_int = 22; + pub static _SC_2_LOCALEDEF : c_int = 23; + pub static _SC_2_SW_DEV : c_int = 24; + pub static _SC_2_UPE : c_int = 25; + pub static _SC_STREAM_MAX : c_int = 26; + pub static _SC_TZNAME_MAX : c_int = 27; + pub static _SC_ASYNCHRONOUS_IO : c_int = 28; + pub static _SC_PAGESIZE : c_int = 29; + pub static _SC_MEMLOCK : c_int = 30; + pub static _SC_MEMLOCK_RANGE : c_int = 31; + pub static _SC_MEMORY_PROTECTION : c_int = 32; + pub static _SC_MESSAGE_PASSING : c_int = 33; + pub static _SC_PRIORITIZED_IO : c_int = 34; + pub static _SC_PRIORITY_SCHEDULING : c_int = 35; + pub static _SC_REALTIME_SIGNALS : c_int = 36; + pub static _SC_SEMAPHORES : c_int = 37; + pub static _SC_FSYNC : c_int = 38; + pub static _SC_SHARED_MEMORY_OBJECTS : c_int = 39; + pub static _SC_SYNCHRONIZED_IO : c_int = 40; + pub static _SC_TIMERS : c_int = 41; + pub static _SC_AIO_LISTIO_MAX : c_int = 42; + pub static _SC_AIO_MAX : c_int = 43; + pub static _SC_AIO_PRIO_DELTA_MAX : c_int = 44; + pub static _SC_DELAYTIMER_MAX : c_int = 45; + pub static _SC_MQ_OPEN_MAX : c_int = 46; + pub static _SC_MAPPED_FILES : c_int = 47; + pub static _SC_RTSIG_MAX : c_int = 48; + pub static _SC_SEM_NSEMS_MAX : c_int = 49; + pub static _SC_SEM_VALUE_MAX : c_int = 50; + pub static _SC_SIGQUEUE_MAX : c_int = 51; + pub static _SC_TIMER_MAX : c_int = 52; + pub static _SC_XBS5_ILP32_OFF32 : c_int = 122; + pub static _SC_XBS5_ILP32_OFFBIG : c_int = 123; + pub static _SC_XBS5_LP64_OFF64 : c_int = 124; + pub static _SC_XBS5_LPBIG_OFFBIG : c_int = 125; } pub mod posix01 { - pub static SIGTRAP : int = 5; + use libc::types::os::arch::c95::c_int; - pub static GLOB_APPEND : int = 0x0001; - pub static GLOB_DOOFFS : int = 0x0002; - pub static GLOB_ERR : int = 0x0004; - pub static GLOB_MARK : int = 0x0008; - pub static GLOB_NOCHECK : int = 0x0010; - pub static GLOB_NOSORT : int = 0x0020; - pub static GLOB_NOESCAPE : int = 0x2000; + pub static SIGTRAP : c_int = 5; - pub static GLOB_NOSPACE : int = -1; - pub static GLOB_ABORTED : int = -2; - pub static GLOB_NOMATCH : int = -3; + pub static GLOB_APPEND : c_int = 0x0001; + pub static GLOB_DOOFFS : c_int = 0x0002; + pub static GLOB_ERR : c_int = 0x0004; + pub static GLOB_MARK : c_int = 0x0008; + pub static GLOB_NOCHECK : c_int = 0x0010; + pub static GLOB_NOSORT : c_int = 0x0020; + pub static GLOB_NOESCAPE : c_int = 0x2000; - pub static POSIX_MADV_NORMAL : int = 0; - pub static POSIX_MADV_RANDOM : int = 1; - pub static POSIX_MADV_SEQUENTIAL : int = 2; - pub static POSIX_MADV_WILLNEED : int = 3; - pub static POSIX_MADV_DONTNEED : int = 4; + pub static GLOB_NOSPACE : c_int = -1; + pub static GLOB_ABORTED : c_int = -2; + pub static GLOB_NOMATCH : c_int = -3; - pub static _SC_IOV_MAX : int = 56; - pub static _SC_GETGR_R_SIZE_MAX : int = 70; - pub static _SC_GETPW_R_SIZE_MAX : int = 71; - pub static _SC_LOGIN_NAME_MAX : int = 73; - pub static _SC_MQ_PRIO_MAX : int = 75; - pub static _SC_THREAD_ATTR_STACKADDR : int = 82; - pub static _SC_THREAD_ATTR_STACKSIZE : int = 83; - pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : int = 85; - pub static _SC_THREAD_KEYS_MAX : int = 86; - pub static _SC_THREAD_PRIO_INHERIT : int = 87; - pub static _SC_THREAD_PRIO_PROTECT : int = 88; - pub static _SC_THREAD_PRIORITY_SCHEDULING : int = 89; - pub static _SC_THREAD_PROCESS_SHARED : int = 90; - pub static _SC_THREAD_SAFE_FUNCTIONS : int = 91; - pub static _SC_THREAD_STACK_MIN : int = 93; - pub static _SC_THREAD_THREADS_MAX : int = 94; - pub static _SC_THREADS : int = 96; - pub static _SC_TTY_NAME_MAX : int = 101; - pub static _SC_ATEXIT_MAX : int = 107; - pub static _SC_XOPEN_CRYPT : int = 108; - pub static _SC_XOPEN_ENH_I18N : int = 109; - pub static _SC_XOPEN_LEGACY : int = 110; - pub static _SC_XOPEN_REALTIME : int = 111; - pub static _SC_XOPEN_REALTIME_THREADS : int = 112; - pub static _SC_XOPEN_SHM : int = 113; - pub static _SC_XOPEN_UNIX : int = 115; - pub static _SC_XOPEN_VERSION : int = 116; - pub static _SC_XOPEN_XCU_VERSION : int = 121; + pub static POSIX_MADV_NORMAL : c_int = 0; + pub static POSIX_MADV_RANDOM : c_int = 1; + pub static POSIX_MADV_SEQUENTIAL : c_int = 2; + pub static POSIX_MADV_WILLNEED : c_int = 3; + pub static POSIX_MADV_DONTNEED : c_int = 4; + + pub static _SC_IOV_MAX : c_int = 56; + pub static _SC_GETGR_R_SIZE_MAX : c_int = 70; + pub static _SC_GETPW_R_SIZE_MAX : c_int = 71; + pub static _SC_LOGIN_NAME_MAX : c_int = 73; + pub static _SC_MQ_PRIO_MAX : c_int = 75; + pub static _SC_THREAD_ATTR_STACKADDR : c_int = 82; + pub static _SC_THREAD_ATTR_STACKSIZE : c_int = 83; + pub static _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 85; + pub static _SC_THREAD_KEYS_MAX : c_int = 86; + pub static _SC_THREAD_PRIO_INHERIT : c_int = 87; + pub static _SC_THREAD_PRIO_PROTECT : c_int = 88; + pub static _SC_THREAD_PRIORITY_SCHEDULING : c_int = 89; + pub static _SC_THREAD_PROCESS_SHARED : c_int = 90; + pub static _SC_THREAD_SAFE_FUNCTIONS : c_int = 91; + pub static _SC_THREAD_STACK_MIN : c_int = 93; + pub static _SC_THREAD_THREADS_MAX : c_int = 94; + pub static _SC_THREADS : c_int = 96; + pub static _SC_TTY_NAME_MAX : c_int = 101; + pub static _SC_ATEXIT_MAX : c_int = 107; + pub static _SC_XOPEN_CRYPT : c_int = 108; + pub static _SC_XOPEN_ENH_I18N : c_int = 109; + pub static _SC_XOPEN_LEGACY : c_int = 110; + pub static _SC_XOPEN_REALTIME : c_int = 111; + pub static _SC_XOPEN_REALTIME_THREADS : c_int = 112; + pub static _SC_XOPEN_SHM : c_int = 113; + pub static _SC_XOPEN_UNIX : c_int = 115; + pub static _SC_XOPEN_VERSION : c_int = 116; + pub static _SC_XOPEN_XCU_VERSION : c_int = 121; } pub mod posix08 { } pub mod bsd44 { - pub static MADV_NORMAL : int = 0; - pub static MADV_RANDOM : int = 1; - pub static MADV_SEQUENTIAL : int = 2; - pub static MADV_WILLNEED : int = 3; - pub static MADV_DONTNEED : int = 4; - pub static MADV_FREE : int = 5; - pub static MADV_ZERO_WIRED_PAGES : int = 6; - pub static MADV_FREE_REUSABLE : int = 7; - pub static MADV_FREE_REUSE : int = 8; - pub static MADV_CAN_REUSE : int = 9; + use libc::types::os::arch::c95::c_int; - pub static MINCORE_INCORE : int = 0x1; - pub static MINCORE_REFERENCED : int = 0x2; - pub static MINCORE_MODIFIED : int = 0x4; - pub static MINCORE_REFERENCED_OTHER : int = 0x8; - pub static MINCORE_MODIFIED_OTHER : int = 0x10; + pub static MADV_NORMAL : c_int = 0; + pub static MADV_RANDOM : c_int = 1; + pub static MADV_SEQUENTIAL : c_int = 2; + pub static MADV_WILLNEED : c_int = 3; + pub static MADV_DONTNEED : c_int = 4; + pub static MADV_FREE : c_int = 5; + pub static MADV_ZERO_WIRED_PAGES : c_int = 6; + pub static MADV_FREE_REUSABLE : c_int = 7; + pub static MADV_FREE_REUSE : c_int = 8; + pub static MADV_CAN_REUSE : c_int = 9; + + pub static MINCORE_INCORE : c_int = 0x1; + pub static MINCORE_REFERENCED : c_int = 0x2; + pub static MINCORE_MODIFIED : c_int = 0x4; + pub static MINCORE_REFERENCED_OTHER : c_int = 0x8; + pub static MINCORE_MODIFIED_OTHER : c_int = 0x10; } pub mod extra { - pub static O_DSYNC : int = 4194304; - pub static O_SYNC : int = 128; - pub static F_FULLFSYNC : int = 51; + use libc::types::os::arch::c95::c_int; - pub static MAP_COPY : int = 0x0002; - pub static MAP_RENAME : int = 0x0020; - pub static MAP_NORESERVE : int = 0x0040; - pub static MAP_NOEXTEND : int = 0x0100; - pub static MAP_HASSEMAPHORE : int = 0x0200; - pub static MAP_NOCACHE : int = 0x0400; - pub static MAP_JIT : int = 0x0800; + pub static O_DSYNC : c_int = 4194304; + pub static O_SYNC : c_int = 128; + pub static F_FULLFSYNC : c_int = 51; + + pub static MAP_COPY : c_int = 0x0002; + pub static MAP_RENAME : c_int = 0x0020; + pub static MAP_NORESERVE : c_int = 0x0040; + pub static MAP_NOEXTEND : c_int = 0x0100; + pub static MAP_HASSEMAPHORE : c_int = 0x0200; + pub static MAP_NOCACHE : c_int = 0x0400; + pub static MAP_JIT : c_int = 0x0800; } } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 1ceb22b20ca6..e6b92c0ccc3f 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -758,7 +758,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { FindFirstFileW( path_ptr, ::cast::transmute(wfd_ptr)); - if find_handle as int != INVALID_HANDLE_VALUE { + if find_handle as libc::c_int != INVALID_HANDLE_VALUE { let mut more_files = 1 as libc::c_int; while more_files != 0 { let fp_buf = rust_list_dir_wfd_fp_buf(wfd_ptr); From 0cca08a21a33b60f9a27a4bab119b5ec8261be56 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 23 Jun 2013 14:41:45 +1200 Subject: [PATCH 118/336] Add support for #[no_drop_flag] attribute --- src/librustc/middle/trans/adt.rs | 2 +- src/librustc/middle/trans/glue.rs | 57 ++++++++++++++++++++++++++----- src/librustc/middle/ty.rs | 15 ++++++-- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 624c6607859e..9b7c7037f42a 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -135,7 +135,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { 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).is_present(); + let dtor = ty::ty_dtor(cx.tcx, def_id).has_drop_flag(); let ftys = if dtor { ftys + [ty::mk_bool()] } else { ftys }; return Univariant(mk_struct(cx, ftys, packed), dtor) diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index d8ba524b2bd1..056e5b8cdf79 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -406,13 +406,8 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { build_return(bcx); } -pub fn trans_struct_drop(bcx: block, - t: ty::t, - v0: ValueRef, - dtor_did: ast::def_id, - class_did: ast::def_id, - substs: &ty::substs) - -> block { +pub fn trans_struct_drop_flag(bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id, + class_did: ast::def_id, substs: &ty::substs) -> block { let repr = adt::represent_type(bcx.ccx(), t); let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0); do with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) |cx| { @@ -454,6 +449,49 @@ pub fn trans_struct_drop(bcx: block, } } +pub fn trans_struct_drop(mut bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast::def_id, + class_did: ast::def_id, substs: &ty::substs) -> block { + let repr = adt::represent_type(bcx.ccx(), t); + + // Find and call the actual destructor + let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, + class_did, /*bad*/copy substs.tps); + + // The second argument is the "self" argument for drop + let params = unsafe { + let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr)); + ty.element_type().func_params() + }; + + // Class dtors have no explicit args, so the params should + // just consist of the environment (self) + assert_eq!(params.len(), 1); + + // Take a reference to the class (because it's using the Drop trait), + // do so now. + let llval = alloca(bcx, val_ty(v0)); + Store(bcx, v0, llval); + + let self_arg = PointerCast(bcx, llval, params[0]); + let args = ~[self_arg]; + + Call(bcx, dtor_addr, args); + + // Drop the fields + let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs); + for field_tys.iter().enumerate().advance |(i, fld)| { + let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i); + bcx = drop_ty(bcx, llfld_a, fld.mt.ty); + } + + // Zero out the struct + unsafe { + let ty = Type::from_ref(llvm::LLVMTypeOf(v0)); + memzero(bcx, v0, ty); + } + + bcx +} pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. @@ -474,7 +512,10 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { ty::ty_struct(did, ref substs) => { let tcx = bcx.tcx(); match ty::ty_dtor(tcx, did) { - ty::TraitDtor(dtor) => { + ty::TraitDtor(dtor, true) => { + trans_struct_drop_flag(bcx, t, v0, dtor, did, substs) + } + ty::TraitDtor(dtor, false) => { trans_struct_drop(bcx, t, v0, dtor, did, substs) } ty::NoDtor => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 90cd8a8665ea..424307502f21 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3855,7 +3855,7 @@ pub fn item_path_str(cx: ctxt, id: ast::def_id) -> ~str { pub enum DtorKind { NoDtor, - TraitDtor(def_id) + TraitDtor(def_id, bool) } impl DtorKind { @@ -3869,13 +3869,24 @@ impl DtorKind { pub fn is_present(&const self) -> bool { !self.is_not_present() } + + pub fn has_drop_flag(&self) -> bool { + match self { + &NoDtor => false, + &TraitDtor(_, flag) => flag + } + } } /* If struct_id names a struct with a dtor, return Some(the dtor's id). Otherwise return none. */ pub fn ty_dtor(cx: ctxt, struct_id: def_id) -> DtorKind { match cx.destructor_for_type.find(&struct_id) { - Some(&method_def_id) => TraitDtor(method_def_id), + Some(&method_def_id) => { + let flag = has_attr(cx, struct_id, "no_drop_flag"); + + TraitDtor(method_def_id, flag) + } None => NoDtor, } } From d9f6dd263c16a21108c27dbf15a3d59a43a5b490 Mon Sep 17 00:00:00 2001 From: James Miller Date: Sun, 23 Jun 2013 16:13:29 +1200 Subject: [PATCH 119/336] Set #[no_drop_flag] on Rc and AtomicOption. Add Test --- src/libextra/rc.rs | 20 ++++++++++------- src/librustc/middle/ty.rs | 2 +- src/libstd/unstable/atomics.rs | 1 + src/test/run-pass/attr-no-drop-flag-size.rs | 25 +++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 src/test/run-pass/attr-no-drop-flag-size.rs diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index b90b0983dc24..555cceb5b44b 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -70,10 +70,12 @@ impl Rc { impl Drop for Rc { fn finalize(&self) { unsafe { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - ptr::replace_ptr(self.ptr, intrinsics::uninit()); - free(self.ptr as *c_void) + if self.ptr.is_not_null() { + (*self.ptr).count -= 1; + if (*self.ptr).count == 0 { + ptr::replace_ptr(self.ptr, intrinsics::uninit()); + free(self.ptr as *c_void) + } } } } @@ -220,10 +222,12 @@ impl RcMut { impl Drop for RcMut { fn finalize(&self) { unsafe { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - ptr::replace_ptr(self.ptr, uninit()); - free(self.ptr as *c_void) + if self.ptr.is_not_null() { + (*self.ptr).count -= 1; + if (*self.ptr).count == 0 { + ptr::replace_ptr(self.ptr, uninit()); + free(self.ptr as *c_void) + } } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 424307502f21..d5a2ed7dbd0b 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3883,7 +3883,7 @@ impl DtorKind { pub fn ty_dtor(cx: ctxt, struct_id: def_id) -> DtorKind { match cx.destructor_for_type.find(&struct_id) { Some(&method_def_id) => { - let flag = has_attr(cx, struct_id, "no_drop_flag"); + let flag = !has_attr(cx, struct_id, "no_drop_flag"); TraitDtor(method_def_id, flag) } diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index 6e7a7e2b129c..7a3a5f51d356 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -62,6 +62,7 @@ pub struct AtomicPtr { /** * An owned atomic pointer. Ensures that only a single reference to the data is held at any time. */ +#[no_drop_flag] pub struct AtomicOption { priv p: *mut c_void } diff --git a/src/test/run-pass/attr-no-drop-flag-size.rs b/src/test/run-pass/attr-no-drop-flag-size.rs new file mode 100644 index 000000000000..e6f05970cced --- /dev/null +++ b/src/test/run-pass/attr-no-drop-flag-size.rs @@ -0,0 +1,25 @@ +// 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. + +use std::sys::size_of; + +#[no_drop_flag] +struct Test { + a: T +} + +#[unsafe_destructor] +impl Drop for Test { + fn finalize(&self) { } +} + +fn main() { + assert_eq!(size_of::(), size_of::>()); +} From 721164d5ec0c8b617bd72df36830fe1861e6362b Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 25 Jun 2013 16:39:56 +1200 Subject: [PATCH 120/336] Zero the struct in the take glue, not the drop glue --- src/librustc/middle/trans/glue.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 056e5b8cdf79..8ed3112b5206 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -484,12 +484,6 @@ pub fn trans_struct_drop(mut bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast:: bcx = drop_ty(bcx, llfld_a, fld.mt.ty); } - // Zero out the struct - unsafe { - let ty = Type::from_ref(llvm::LLVMTypeOf(v0)); - memzero(bcx, v0, ty); - } - bcx } @@ -635,6 +629,23 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_take_glue(bcx, ck, v) } + ty::ty_struct(did, ref substs) => { + let tcx = bcx.tcx(); + let bcx = iter_structural_ty(bcx, v, t, take_ty); + + match ty::ty_dtor(tcx, did) { + ty::TraitDtor(dtor, false) => { + // Zero out the struct + unsafe { + let ty = Type::from_ref(llvm::LLVMTypeOf(v)); + memzero(bcx, v, ty); + } + + } + _ => { } + } + bcx + } _ if ty::type_is_structural(t) => { iter_structural_ty(bcx, v, t, take_ty) } From 2afdf0d6a18bd0fb3369088eff1f8d9c707ad43d Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 25 Jun 2013 16:43:58 +1200 Subject: [PATCH 121/336] Update snapshots file --- src/snapshots.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/snapshots.txt b/src/snapshots.txt index 1aaf5fee26ab..910de5f66b7f 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2013-06-23 f827561 + macos-i386 63ffbcf99b6853d7840bdfe01380068518d0e466 + macos-x86_64 b34fdf3845f8ef4760817007d8ef820cd32f2e07 + winnt-i386 6602150074ec442fd376fddb2eaf63f5da6fdff9 + freebsd-x86_64 a05bdda2d9ec0e66336d81b98bee8a95442a501f + linux-i386 b8f4a0f0c2250aa4d76ec1eb57c83bfae5725f93 + linux-x86_64 caea3402663334d0a3967c21f58a860c060d5474 + S 2013-06-21 6759ce4 macos-i386 6e5395d2fda1db356f64af28ba525031bf9871c7 macos-x86_64 7b8ded4e1ba1e999a5614eea3a4acacb2c7cef1d From caa50ce15d8ed8f0d50c9049053a5e2cd5a0d701 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 25 Jun 2013 17:08:26 +1200 Subject: [PATCH 122/336] Remove stage0 cfgs --- src/libstd/iterator.rs | 5 ---- src/libstd/unstable/intrinsics.rs | 50 ------------------------------- src/libstd/vec.rs | 2 -- 3 files changed, 57 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index d96191f296d7..9177ecabed6a 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -43,7 +43,6 @@ 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. - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { (None, None) } } @@ -610,7 +609,6 @@ impl, U: Iterator> Iterator for ChainIterator { } #[inline] - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { let (a_lower, a_upper) = self.a.size_hint(); let (b_lower, b_upper) = self.b.size_hint(); @@ -664,7 +662,6 @@ impl<'self, A, B, T: Iterator> Iterator for MapIterator<'self, A, B, T> { } #[inline] - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { self.iter.size_hint() } @@ -690,7 +687,6 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } #[inline] - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { let (_, upper) = self.iter.size_hint(); (None, upper) // can't know a lower bound, due to the predicate @@ -716,7 +712,6 @@ impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, } #[inline] - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { let (_, upper) = self.iter.size_hint(); (None, upper) // can't know a lower bound, due to the predicate diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index c38b013a75aa..109f665e41d7 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -42,9 +42,7 @@ pub extern "rust-intrinsic" { /// Atomic compare and exchange, release ordering. pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int; @@ -53,7 +51,6 @@ pub extern "rust-intrinsic" { /// Atomic load, acquire ordering. pub fn atomic_load_acq(src: &int) -> int; - #[cfg(not(stage0))] pub fn atomic_load_relaxed(src: &int) -> int; /// Atomic store, sequentially consistent. @@ -61,7 +58,6 @@ pub extern "rust-intrinsic" { /// Atomic store, release ordering. pub fn atomic_store_rel(dst: &mut int, val: int); - #[cfg(not(stage0))] pub fn atomic_store_relaxed(dst: &mut int, val: int); /// Atomic exchange, sequentially consistent. @@ -70,9 +66,7 @@ pub extern "rust-intrinsic" { pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int; /// Atomic exchange, release ordering. pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int; /// Atomic addition, sequentially consistent. @@ -81,9 +75,7 @@ pub extern "rust-intrinsic" { pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; /// Atomic addition, release ordering. pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int; /// Atomic subtraction, sequentially consistent. @@ -92,97 +84,55 @@ pub extern "rust-intrinsic" { pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; /// Atomic subtraction, release ordering. pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_and(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_and_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_and_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_nand(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_nand_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_nand_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_or(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_or_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_or_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xor(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xor_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xor_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_max(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_max_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_max_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_min(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_min_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_min_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umin(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umax(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umax_acq(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umax_rel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int; - #[cfg(not(stage0))] pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 7b7a3020b939..e39dd262cd90 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2446,7 +2446,6 @@ macro_rules! iterator { } #[inline] - #[cfg(not(stage0))] fn size_hint(&self) -> (Option, Option) { let exact = Some(((self.end as uint) - (self.ptr as uint)) / size_of::<$elem>()); (exact, exact) @@ -3929,7 +3928,6 @@ mod tests { } #[test] - #[cfg(not(stage0))] fn test_iterator() { use iterator::*; let xs = [1, 2, 5, 10, 11]; From 6ad31ffb53f9620f9063cb441de9c7338dfbb4de Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 25 Jun 2013 17:13:22 +1200 Subject: [PATCH 123/336] Warning police --- src/librustc/metadata/decoder.rs | 1 - src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 2 +- src/librustc/middle/typeck/coherence.rs | 4 +--- src/librustc/util/ppaux.rs | 1 - src/libstd/to_str.rs | 2 -- src/libsyntax/parse/parser.rs | 2 +- 7 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 9ace8677dab7..db44ac5e4421 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -35,7 +35,6 @@ use extra::ebml; use extra::serialize::Decodable; use syntax::ast_map; use syntax::attr; -use syntax::diagnostic::span_handler; use syntax::parse::token::{ident_interner, special_idents}; use syntax::print::pprust; use syntax::{ast, ast_util}; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 90cd8a8665ea..632874025e77 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -21,7 +21,7 @@ use middle::ty; use middle::subst::Subst; use middle::typeck; use middle; -use util::ppaux::{note_and_explain_region, bound_region_to_str, bound_region_ptr_to_str}; +use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str}; use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str}; use util::ppaux::{Repr, UserString}; use util::common::{indenter}; diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872b..76b7e651ff12 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -107,7 +107,7 @@ use middle::typeck::{isr_alist, lookup_def_ccx}; use middle::typeck::no_params; use middle::typeck::{require_same_types, method_map, vtable_map}; use util::common::{block_query, indenter, loop_query}; -use util::ppaux::{bound_region_to_str,bound_region_ptr_to_str}; +use util::ppaux::{bound_region_ptr_to_str}; use util::ppaux; diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 7ad27077cd86..ae62e768ea2b 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -16,10 +16,8 @@ use core::prelude::*; -use driver; use metadata::csearch::{each_path, get_impl_trait}; use metadata::csearch::{get_impls_for_mod}; -use metadata::csearch; use metadata::cstore::{CStore, iter_crate_data}; use metadata::decoder::{dl_def, dl_field, dl_impl}; use middle::resolve::{Impl, MethodInfo}; @@ -39,7 +37,7 @@ use middle::typeck::infer::combine::Combine; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::{new_infer_ctxt, resolve_ivar}; use middle::typeck::infer::{resolve_nested_tvar, resolve_type}; -use syntax::ast::{crate, def_id, def_mod, def_struct, def_trait, def_ty}; +use syntax::ast::{crate, def_id, def_mod, def_struct, def_ty}; use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct}; use syntax::ast::{local_crate, method, trait_ref, ty_path}; use syntax::ast; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index e25267f44412..3194df269c0e 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -32,7 +32,6 @@ use syntax::parse::token; use syntax::print::pprust; use syntax::{ast, ast_util}; -use core::str; use core::vec; /// Produces a string suitable for debugging output. diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 9f8122886213..2e5c3c01adf4 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -18,11 +18,9 @@ use str::OwnedStr; use hashmap::HashMap; use hashmap::HashSet; use iterator::IteratorUtil; -use container::Map; use hash::Hash; use cmp::Eq; use vec::ImmutableVector; -use iterator::IteratorUtil; /// A generic trait for converting a value to a string pub trait ToStr { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f2443f9e5335..c9ef1a7a33c0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -60,7 +60,7 @@ use ast::{view_item_, view_item_extern_mod, view_item_use}; use ast::{view_path, view_path_glob, view_path_list, view_path_simple}; use ast::visibility; use ast; -use ast_util::{as_prec, ident_to_path, operator_prec}; +use ast_util::{as_prec, operator_prec}; use ast_util; use codemap::{span, BytePos, spanned, mk_sp}; use codemap; From 122f25dd5e1dae124bdc8d3beeac55474d7a8ce5 Mon Sep 17 00:00:00 2001 From: James Miller Date: Tue, 25 Jun 2013 18:02:56 +1200 Subject: [PATCH 124/336] Add missing import to tests --- src/libstd/to_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 2e5c3c01adf4..4d5bc0f8842f 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -177,7 +177,7 @@ impl ToStr for @[A] { mod tests { use hashmap::HashMap; use hashmap::HashSet; - use container::Set; + use container::{Set,Map}; #[test] fn test_simple_types() { assert_eq!(1i.to_str(), ~"1"); From 41f11d642861ff5b7a85f1fcdab2d5e14692fb6d Mon Sep 17 00:00:00 2001 From: Jeaye Date: Mon, 24 Jun 2013 23:35:16 -0700 Subject: [PATCH 125/336] rust.vim: Links previously unused rustFuncCall This allows for highlighting of function calls for free floating, member, and static functions. --- src/etc/vim/syntax/rust.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 625424ac8709..b2cdcc5e0ec9 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -143,6 +143,7 @@ hi def link rustConditional Conditional hi def link rustIdentifier Identifier hi def link rustModPath Include hi def link rustFuncName Function +hi def link rustFuncCall Function hi def link rustCommentDoc SpecialComment hi def link rustComment Comment hi def link rustMacro Macro From 42b44b21b11ded0a7dbbe196b1c9d338ef33b614 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Jun 2013 13:00:38 -0700 Subject: [PATCH 126/336] Rename all files with the 'rc' extension --- Makefile.in | 16 ++++++++-------- mk/tools.mk | 14 +++++++------- .../{compiletest.rc => compiletest.rs} | 0 src/libextra/{std.rc => extra.rs} | 0 src/librust/{rust.rc => rust.rs} | 0 src/librustc/{rustc.rc => rustc.rs} | 0 src/librustdoc/{rustdoc.rc => rustdoc.rs} | 0 src/librusti/{rusti.rc => rusti.rs} | 0 src/librustpkg/{rustpkg.rc => rustpkg.rs} | 0 src/libstd/{core.rc => std.rs} | 0 src/libsyntax/{syntax.rc => syntax.rs} | 0 11 files changed, 15 insertions(+), 15 deletions(-) rename src/compiletest/{compiletest.rc => compiletest.rs} (100%) rename src/libextra/{std.rc => extra.rs} (100%) rename src/librust/{rust.rc => rust.rs} (100%) rename src/librustc/{rustc.rc => rustc.rs} (100%) rename src/librustdoc/{rustdoc.rc => rustdoc.rs} (100%) rename src/librusti/{rusti.rc => rusti.rs} (100%) rename src/librustpkg/{rustpkg.rc => rustpkg.rs} (100%) rename src/libstd/{core.rc => std.rs} (100%) rename src/libsyntax/{syntax.rc => syntax.rs} (100%) diff --git a/Makefile.in b/Makefile.in index baae56c4f409..fa6c78065813 100644 --- a/Makefile.in +++ b/Makefile.in @@ -239,29 +239,29 @@ $(foreach target,$(CFG_TARGET_TRIPLES),\ # Standard library variables ###################################################################### -STDLIB_CRATE := $(S)src/libstd/core.rc +STDLIB_CRATE := $(S)src/libstd/std.rs STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \ - core.rc *.rs */*.rs */*/*rs */*/*/*rs)) + *.rs */*.rs */*/*rs */*/*/*rs)) ###################################################################### # Extra library variables ###################################################################### -EXTRALIB_CRATE := $(S)src/libextra/std.rc +EXTRALIB_CRATE := $(S)src/libextra/extra.rs EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/, \ - std.rc *.rs */*.rs)) + *.rs */*.rs)) ###################################################################### # rustc crate variables ###################################################################### -COMPILER_CRATE := $(S)src/librustc/rustc.rc +COMPILER_CRATE := $(S)src/librustc/rustc.rs COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/, \ - rustc.rc *.rs */*.rs */*/*.rs */*/*/*.rs)) + *.rs */*.rs */*/*.rs */*/*/*.rs)) -LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rc +LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rs LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \ - syntax.rc *.rs */*.rs */*/*.rs)) + *.rs */*.rs */*/*.rs)) DRIVER_CRATE := $(S)src/driver/driver.rs diff --git a/mk/tools.mk b/mk/tools.mk index 8319d8d4e483..7b50441b3c7f 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -12,23 +12,23 @@ # and host architectures # The test runner that runs the cfail/rfail/rpass and bxench tests -COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rc -COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*rs) +COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rs +COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*.rs) # Rustpkg, the package manager and build system -RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rc -RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*rs) +RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rs +RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs) # Rustdoc, the documentation tool -RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rc +RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rs RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs) # Rusti, the JIT REPL -RUSTI_LIB := $(S)src/librusti/rusti.rc +RUSTI_LIB := $(S)src/librusti/rusti.rs RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs) # Rust, the convenience tool -RUST_LIB := $(S)src/librust/rust.rc +RUST_LIB := $(S)src/librust/rust.rs RUST_INPUTS := $(wildcard $(S)src/librust/*.rs) # FIXME: These are only built for the host arch. Eventually we'll diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rs similarity index 100% rename from src/compiletest/compiletest.rc rename to src/compiletest/compiletest.rs diff --git a/src/libextra/std.rc b/src/libextra/extra.rs similarity index 100% rename from src/libextra/std.rc rename to src/libextra/extra.rs diff --git a/src/librust/rust.rc b/src/librust/rust.rs similarity index 100% rename from src/librust/rust.rc rename to src/librust/rust.rs diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rs similarity index 100% rename from src/librustc/rustc.rc rename to src/librustc/rustc.rs diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rs similarity index 100% rename from src/librustdoc/rustdoc.rc rename to src/librustdoc/rustdoc.rs diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rs similarity index 100% rename from src/librusti/rusti.rc rename to src/librusti/rusti.rs diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rs similarity index 100% rename from src/librustpkg/rustpkg.rc rename to src/librustpkg/rustpkg.rs diff --git a/src/libstd/core.rc b/src/libstd/std.rs similarity index 100% rename from src/libstd/core.rc rename to src/libstd/std.rs diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rs similarity index 100% rename from src/libsyntax/syntax.rc rename to src/libsyntax/syntax.rs From 92424f0670723e417a96a96310a6ad871994c6b7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 15 Jun 2013 20:58:11 -0700 Subject: [PATCH 127/336] Add the `warnings` lint attribute --- src/librustc/middle/lint.rs | 14 +++++++-- src/test/compile-fail/lint-change-warnings.rs | 30 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/lint-change-warnings.rs diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 17ff5930078d..5c36ab7750c8 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -96,6 +96,8 @@ pub enum lint { missing_doc, unreachable_code, + + warnings, } pub fn level_to_str(lv: level) -> &'static str { @@ -280,6 +282,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ desc: "detects unreachable code", default: warn }), + + ("warnings", + LintSpec { + lint: warnings, + desc: "mass-change the level for lints which produce warnings", + default: warn + }), ]; /* @@ -362,10 +371,11 @@ impl Context { fn span_lint(&self, lint: lint, span: span, msg: &str) { let (level, src) = match self.curr.find(&(lint as uint)) { + None => { return } + Some(&(warn, src)) => (self.get_level(warnings), src), Some(&pair) => pair, - None => { return; } }; - if level == allow { return; } + if level == allow { return } let mut note = None; let msg = match src { diff --git a/src/test/compile-fail/lint-change-warnings.rs b/src/test/compile-fail/lint-change-warnings.rs new file mode 100644 index 000000000000..977abc4dc0d1 --- /dev/null +++ b/src/test/compile-fail/lint-change-warnings.rs @@ -0,0 +1,30 @@ +// 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. + +#[deny(warnings)]; + +fn main() { + while true {} //~ ERROR: infinite +} + +#[allow(warnings)] +fn foo() { + while true {} +} + +#[warn(warnings)] +fn bar() { + while true {} //~ WARNING: infinite +} + +#[forbid(warnings)] +fn baz() { + while true {} //~ ERROR: warnings +} From 5e26808141592354a4c9ab28a7e2190e9acf8942 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Wed, 19 Jun 2013 12:50:12 -0700 Subject: [PATCH 128/336] Get rid of terrible way for iterating over provided methods. --- src/librustc/metadata/csearch.rs | 7 +---- src/librustc/metadata/decoder.rs | 13 +++------- src/librustc/middle/ty.rs | 6 ++--- src/librustc/middle/typeck/coherence.rs | 34 +++++-------------------- 4 files changed, 14 insertions(+), 46 deletions(-) diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index e1cd7caa19c1..bfc5d512b370 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -24,11 +24,6 @@ use syntax::ast; use syntax::ast_map; use syntax::diagnostic::expect; -pub struct ProvidedTraitMethodInfo { - ty: ty::Method, - def_id: ast::def_id -} - pub struct StaticMethodInfo { ident: ast::ident, def_id: ast::def_id, @@ -134,7 +129,7 @@ pub fn get_trait_method_def_ids(cstore: @mut cstore::CStore, pub fn get_provided_trait_methods(tcx: ty::ctxt, def: ast::def_id) - -> ~[ProvidedTraitMethodInfo] { + -> ~[@ty::Method] { let cstore = tcx.cstore; let cdata = cstore::get_crate_data(cstore, def.crate); decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 714164d6a120..824f67b074c2 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -14,7 +14,7 @@ use core::prelude::*; use metadata::cstore::crate_metadata; use metadata::common::*; -use metadata::csearch::{ProvidedTraitMethodInfo, StaticMethodInfo}; +use metadata::csearch::StaticMethodInfo; use metadata::csearch; use metadata::cstore; use metadata::decoder; @@ -752,7 +752,7 @@ pub fn get_trait_method_def_ids(cdata: cmd, pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> - ~[ProvidedTraitMethodInfo] { + ~[@ty::Method] { let data = cdata.data; let item = lookup_item(id, data); let mut result = ~[]; @@ -763,13 +763,8 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, if item_method_sort(mth) != 'p' { loop; } - let ty_method = get_method(intr, cdata, did.node, tcx); - let provided_trait_method_info = ProvidedTraitMethodInfo { - ty: ty_method, - def_id: did - }; - - vec::push(&mut result, provided_trait_method_info); + vec::push(&mut result, + @get_method(intr, cdata, did.node, tcx)); } return result; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 328b331ea63e..a7a69d51de26 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3649,7 +3649,7 @@ pub fn def_has_ty_params(def: ast::def) -> bool { } } -pub fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[ast::ident] { +pub fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[@Method] { if is_local(id) { match cx.items.find(&id.node) { Some(&ast_map::node_item(@ast::item { @@ -3657,13 +3657,13 @@ pub fn provided_trait_methods(cx: ctxt, id: ast::def_id) -> ~[ast::ident] { _ }, _)) => match ast_util::split_trait_methods(*ms) { - (_, p) => p.map(|method| method.ident) + (_, p) => p.map(|m| method(cx, ast_util::local_def(m.id))) }, _ => cx.sess.bug(fmt!("provided_trait_methods: %? is not a trait", id)) } } else { - csearch::get_provided_trait_methods(cx, id).map(|ifo| ifo.ty.ident) + csearch::get_provided_trait_methods(cx, id) } } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index ae62e768ea2b..bd99a8e150b7 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -333,7 +333,8 @@ impl CoherenceChecker { let impl_poly_type = ty::lookup_item_type(tcx, impl_id); - for self.each_provided_trait_method(trait_ref.def_id) |trait_method| { + let provided = ty::provided_trait_methods(tcx, trait_ref.def_id); + for provided.iter().advance |trait_method| { // Synthesize an ID. let new_id = parse::next_node_id(tcx.sess.parse_sess); let new_did = local_def(new_id); @@ -347,7 +348,7 @@ impl CoherenceChecker { impl_id, trait_ref, new_did, - trait_method); + *trait_method); debug!("new_method_ty=%s", new_method_ty.repr(tcx)); @@ -526,29 +527,6 @@ impl CoherenceChecker { } } - pub fn each_provided_trait_method(&self, - trait_did: ast::def_id, - f: &fn(x: @ty::Method) -> bool) - -> bool { - // Make a list of all the names of the provided methods. - // XXX: This is horrible. - let mut provided_method_idents = HashSet::new(); - let tcx = self.crate_context.tcx; - let r = ty::provided_trait_methods(tcx, trait_did); - for r.iter().advance |ident| { - provided_method_idents.insert(*ident); - } - - for ty::trait_methods(tcx, trait_did).iter().advance |&method| { - if provided_method_idents.contains(&method.ident) { - if !f(method) { - return false; - } - } - } - return true; - } - pub fn polytypes_unify(&self, polytype_a: ty_param_bounds_and_ty, polytype_b: ty_param_bounds_and_ty) @@ -729,9 +707,9 @@ impl CoherenceChecker { } // Default methods let r = ty::provided_trait_methods(tcx, trait_did); - for r.iter().advance |ident| { - debug!("inserting provided method %s", ident.repr(tcx)); - provided_names.insert(*ident); + for r.iter().advance |method| { + debug!("inserting provided method %s", method.ident.repr(tcx)); + provided_names.insert(method.ident); } let r = ty::trait_methods(tcx, trait_did); From 13e5f0ebdfa7305e8449a585aa8e9837703f1f96 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Wed, 19 Jun 2013 18:03:02 -0700 Subject: [PATCH 129/336] Remove some essentially dead code in method handling. --- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/meth.rs | 33 ++++------------------- src/librustc/middle/trans/monomorphize.rs | 4 +-- 3 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0e322c187af2..526e4859415b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2110,7 +2110,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { } ast::item_impl(ref generics, _, _, ref ms) => { meth::trans_impl(ccx, /*bad*/copy *path, item.ident, *ms, - generics, None, item.id); + generics, item.id); } ast::item_mod(ref m) => { trans_mod(ccx, m); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 0b68ae5ee171..92a588700bb7 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -49,13 +49,12 @@ pub fn trans_impl(ccx: @mut CrateContext, name: ast::ident, methods: &[@ast::method], generics: &ast::Generics, - self_ty: Option, id: ast::node_id) { let _icx = push_ctxt("impl::trans_impl"); let tcx = ccx.tcx; - debug!("trans_impl(path=%s, name=%s, self_ty=%s, id=%?)", - path.repr(tcx), name.repr(tcx), self_ty.repr(tcx), id); + debug!("trans_impl(path=%s, name=%s, id=%?)", + path.repr(tcx), name.repr(tcx), id); if !generics.ty_params.is_empty() { return; } let sub_path = vec::append_one(path, path_name(name)); @@ -65,24 +64,10 @@ pub fn trans_impl(ccx: @mut CrateContext, let path = vec::append_one(/*bad*/copy sub_path, path_name(method.ident)); - let param_substs_opt; - match self_ty { - None => param_substs_opt = None, - Some(self_ty) => { - param_substs_opt = Some(@param_substs { - tys: ~[], - vtables: None, - type_param_defs: @~[], - self_ty: Some(self_ty) - }); - } - } - trans_method(ccx, path, *method, - param_substs_opt, - self_ty, + None, llfn, ast_util::local_def(id)); } @@ -98,9 +83,6 @@ Translates a (possibly monomorphized) method body. - `method`: the AST node for the method - `param_substs`: if this is a generic method, the current values for type parameters and so forth, else none -- `base_self_ty`: optionally, the explicit self type for this method. This - will be none if this is not a default method and must always be present - if this is a default method. - `llfn`: the LLVM ValueRef for the method - `impl_id`: the node ID of the impl this method is inside */ @@ -108,7 +90,6 @@ pub fn trans_method(ccx: @mut CrateContext, path: path, method: &ast::method, param_substs: Option<@param_substs>, - base_self_ty: Option, llfn: ValueRef, impl_id: ast::def_id) { // figure out how self is being passed @@ -119,18 +100,14 @@ pub fn trans_method(ccx: @mut CrateContext, _ => { // determine the (monomorphized) type that `self` maps to for // this method - let self_ty = match base_self_ty { - None => ty::node_id_to_type(ccx.tcx, method.self_id), - Some(provided_self_ty) => provided_self_ty, - }; + let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id); let self_ty = match param_substs { None => self_ty, Some(@param_substs {tys: ref tys, _}) => { ty::subst_tps(ccx.tcx, *tys, None, self_ty) } }; - debug!("calling trans_fn with base_self_ty %s, self_ty %s", - base_self_ty.repr(ccx.tcx), + debug!("calling trans_fn with self_ty %s", self_ty.repr(ccx.tcx)); match method.explicit_self.node { ast::sty_value => { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 4f4bbf84a72b..1ffe26e3affe 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -233,14 +233,14 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, Some(override_impl_did) => impl_did = override_impl_did } - meth::trans_method(ccx, pt, mth, psubsts, None, d, impl_did); + meth::trans_method(ccx, pt, mth, psubsts, d, impl_did); d } ast_map::node_trait_method(@ast::provided(mth), _, pt) => { let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); debug!("monomorphic_fn impl_did_opt is %?", impl_did_opt); - meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, None, d, + meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, d, impl_did_opt.get()); d } From 3c867114525068275bd403ba5b1918d507a38933 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Fri, 21 Jun 2013 12:38:10 -0700 Subject: [PATCH 130/336] Fix some tests in rustpkg to not pollute the build directory. Closes #7278. --- src/librustpkg/tests.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 973b960008be..19293e31167a 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -268,12 +268,12 @@ fn output_file_name(workspace: &Path, short_name: &str) -> Path { workspace.push(fmt!("%s%s", short_name, os::EXE_SUFFIX)) } -fn touch_source_file(workspace: &Path, short_name: &str) { +fn touch_source_file(workspace: &Path, pkgid: &PkgId) { use conditions::bad_path::cond; - let pkg_src_dir = workspace.push("src").push(short_name); - let contents = os::list_dir(&pkg_src_dir); + let pkg_src_dir = workspace.push("src").push(pkgid.to_str()); + let contents = os::list_dir_path(&pkg_src_dir); for contents.iter().advance |p| { - if Path(copy *p).filetype() == Some(~".rs") { + if p.filetype() == Some(~".rs") { // should be able to do this w/o a process if run::process_output("touch", [p.to_str()]).status != 0 { let _ = cond.raise((copy pkg_src_dir, ~"Bad path")); @@ -287,20 +287,19 @@ fn touch_source_file(workspace: &Path, short_name: &str) { fn frob_source_file(workspace: &Path, pkgid: &PkgId) { use conditions::bad_path::cond; let pkg_src_dir = workspace.push("src").push(pkgid.to_str()); - let contents = os::list_dir(&pkg_src_dir); + let contents = os::list_dir_path(&pkg_src_dir); let mut maybe_p = None; for contents.iter().advance |p| { - if Path(copy *p).filetype() == Some(~".rs") { + if p.filetype() == Some(~".rs") { maybe_p = Some(p); break; } } match maybe_p { Some(p) => { - let p = Path(copy *p); - let w = io::buffered_file_writer(&p); + let w = io::file_writer(*p, &[io::Append]); match w { - Err(s) => { let _ = cond.raise((p, fmt!("Bad path: %s", s))); } + Err(s) => { let _ = cond.raise((copy **p, fmt!("Bad path: %s", s))); } Ok(w) => w.write_line("") } } @@ -615,7 +614,7 @@ fn do_rebuild_dep_dates_change() { let workspace = create_local_package_with_dep(&p_id, &dep_id); command_line_test([~"build", ~"foo"], &workspace); let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar")); - touch_source_file(&workspace, "bar"); + touch_source_file(&workspace, &dep_id); command_line_test([~"build", ~"foo"], &workspace); let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar")); assert!(new_bar_date > bar_date); From 663f29818310c7aad3b1501fe8eac6ca2379e037 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Mon, 24 Jun 2013 10:34:18 -0700 Subject: [PATCH 131/336] Get rid of cast on every self reference. --- src/librustc/middle/trans/base.rs | 27 +++++++++++++-------------- src/librustc/middle/trans/expr.rs | 8 +------- src/librustc/middle/trans/meth.rs | 4 ++-- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 526e4859415b..ddf12f0df035 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1683,21 +1683,20 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, match fcx.llself { Some(slf) => { - // We really should do this regardless of whether self is owned, but - // it doesn't work right with default method impls yet. (FIXME: #2794) - if slf.is_owned { - let self_val = if datum::appropriate_mode(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); - alloc - } else { - PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) - }; + let self_val = if slf.is_owned + && datum::appropriate_mode(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); + alloc + } else { + PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) + }; - fcx.llself = Some(ValSelfData {v: self_val, ..slf}); - add_clean(bcx, self_val, slf.t); - } + fcx.llself = Some(ValSelfData {v: self_val, ..slf}); + if slf.is_owned { + add_clean(bcx, self_val, slf.t); + } } _ => {} } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 1aebf73b81a8..0e64d7582ac5 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1051,14 +1051,8 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { debug!("def_self() reference, self_info.t=%s", self_info.t.repr(bcx.tcx())); - // This cast should not be necessary. We should cast self *once*, - // but right now this conflicts with default methods. - let real_self_ty = monomorphize_type(bcx, self_info.t); - let llselfty = type_of::type_of(bcx.ccx(), real_self_ty).ptr_to(); - - let casted_val = PointerCast(bcx, self_info.v, llselfty); Datum { - val: casted_val, + val: self_info.v, ty: self_info.t, mode: ByRef(ZeroMem) } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 92a588700bb7..96f8a1976a68 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -103,8 +103,8 @@ pub fn trans_method(ccx: @mut CrateContext, let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id); let self_ty = match param_substs { None => self_ty, - Some(@param_substs {tys: ref tys, _}) => { - ty::subst_tps(ccx.tcx, *tys, None, self_ty) + Some(@param_substs {tys: ref tys, self_ty: ref self_sub, _}) => { + ty::subst_tps(ccx.tcx, *tys, *self_sub, self_ty) } }; debug!("calling trans_fn with self_ty %s", From 276463f06416e54d83f1ba628f82b1f014142426 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Thu, 20 Jun 2013 16:20:31 -0700 Subject: [PATCH 132/336] Fix another generics bug with default methods. Closes #7295. --- src/librustc/middle/typeck/check/method.rs | 23 +++++++++------------- src/test/run-pass/bug-7295.rs | 22 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 src/test/run-pass/bug-7295.rs diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 60855e6cd969..338342f9307d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -300,13 +300,8 @@ impl<'self> LookupContext<'self> { ty_self(self_did) => { // Call is of the form "self.foo()" and appears in one // of a trait's default method implementations. - let substs = substs { - self_r: None, - self_ty: None, - tps: ~[] - }; self.push_inherent_candidates_from_self( - self_ty, self_did, &substs); + self_ty, self_did); } ty_enum(did, _) | ty_struct(did, _) => { if self.check_traits == CheckTraitsAndInherentMethods { @@ -462,12 +457,12 @@ impl<'self> LookupContext<'self> { pub fn push_inherent_candidates_from_self(&self, self_ty: ty::t, - did: def_id, - substs: &ty::substs) { + did: def_id) { struct MethodInfo { method_ty: @ty::Method, trait_def_id: ast::def_id, - index: uint + index: uint, + trait_ref: @ty::TraitRef } let tcx = self.tcx(); @@ -479,7 +474,8 @@ impl<'self> LookupContext<'self> { method_info = Some(MethodInfo { method_ty: methods[i], index: i, - trait_def_id: did + trait_def_id: did, + trait_ref: ty::lookup_trait_def(tcx, did).trait_ref }); } None => () @@ -494,7 +490,8 @@ impl<'self> LookupContext<'self> { method_info = Some(MethodInfo { method_ty: supertrait_methods[i], index: i, - trait_def_id: trait_ref.def_id + trait_def_id: trait_ref.def_id, + trait_ref: *trait_ref }); break; } @@ -505,8 +502,6 @@ impl<'self> LookupContext<'self> { match method_info { Some(ref info) => { // We've found a method -- return it - let rcvr_substs = substs {self_ty: Some(self_ty), - ..copy *substs }; let origin = if did == info.trait_def_id { method_self(info.trait_def_id, info.index) } else { @@ -514,7 +509,7 @@ impl<'self> LookupContext<'self> { }; self.inherent_candidates.push(Candidate { rcvr_ty: self_ty, - rcvr_substs: rcvr_substs, + rcvr_substs: copy info.trait_ref.substs, method_ty: info.method_ty, origin: origin }); diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs new file mode 100644 index 000000000000..080a0dbd91a7 --- /dev/null +++ b/src/test/run-pass/bug-7295.rs @@ -0,0 +1,22 @@ +// 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. + +#[allow(default_methods)]; +pub trait Foo { + pub fn func1(&self, t: U); + + pub fn func2(&self, t: U) { + self.func1(t); + } +} + +pub fn main() { + +} From 9f80591d84790a9571707a85cf4bc5d8f6df114d Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Sun, 23 Jun 2013 22:18:43 +0530 Subject: [PATCH 133/336] resolve: report duplicate module definitions add_child() is responsible for reporting errors about type, value, and module duplicate definitions. Although it checks for all three, it uses namespace_to_str() to convert a Namespace value into a string before printing an error like: error: duplicate definition of type `foo` ^^^^ note: first definition of type foo here: ^^^^ Unfortunately, this string can only be one of "type" or "value" (corresponding to TypeNS and ValueNS respectively), and it reports duplicate modules as duplicate types. To alleviate the problem, define a special NamespaceError enum to define more specialized errors, and use it instead of attempting to reuse the Namespace enum. Reported-by: Corey Richardson Signed-off-by: Ramkumar Ramachandra --- src/librustc/middle/resolve.rs | 38 ++++++++++++++++++--------- src/test/compile-fail/issue-3099-b.rs | 2 +- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8a08b3419e2e..5fb7cc9b9bda 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -101,6 +101,14 @@ pub enum Namespace { ValueNS } +#[deriving(Eq)] +pub enum NamespaceError { + NoError, + ModuleError, + TypeError, + ValueError +} + /// A NamespaceResult represents the result of resolving an import in /// a particular namespace. The result is either definitely-resolved, /// definitely- unresolved, or unknown. @@ -759,10 +767,12 @@ pub fn PrimitiveTypeTable() -> PrimitiveTypeTable { } -pub fn namespace_to_str(ns: Namespace) -> ~str { +pub fn namespace_error_to_str(ns: NamespaceError) -> &'static str { match ns { - TypeNS => ~"type", - ValueNS => ~"value", + NoError => "", + ModuleError => "module", + TypeError => "type", + ValueError => "value", } } @@ -993,21 +1003,25 @@ impl Resolver { // * If no duplicate checking was requested at all, do // nothing. - let mut is_duplicate = false; + let mut duplicate_type = NoError; let ns = match duplicate_checking_mode { ForbidDuplicateModules => { - is_duplicate = child.get_module_if_available().is_some(); + if (child.get_module_if_available().is_some()) { + duplicate_type = ModuleError; + } Some(TypeNS) } ForbidDuplicateTypes => { match child.def_for_namespace(TypeNS) { Some(def_mod(_)) | None => {} - Some(_) => is_duplicate = true + Some(_) => duplicate_type = TypeError } Some(TypeNS) } ForbidDuplicateValues => { - is_duplicate = child.defined_in_namespace(ValueNS); + if child.defined_in_namespace(ValueNS) { + duplicate_type = ValueError; + } Some(ValueNS) } ForbidDuplicateTypesAndValues => { @@ -1016,31 +1030,31 @@ impl Resolver { Some(def_mod(_)) | None => {} Some(_) => { n = Some(TypeNS); - is_duplicate = true; + duplicate_type = TypeError; } }; if child.defined_in_namespace(ValueNS) { - is_duplicate = true; + duplicate_type = ValueError; n = Some(ValueNS); } n } OverwriteDuplicates => None }; - if is_duplicate { + if (duplicate_type != NoError) { // Return an error here by looking up the namespace that // had the duplicate. let ns = ns.unwrap(); self.session.span_err(sp, fmt!("duplicate definition of %s `%s`", - namespace_to_str(ns), + namespace_error_to_str(duplicate_type), self.session.str_of(name))); { let r = child.span_for_namespace(ns); for r.iter().advance |sp| { self.session.span_note(*sp, fmt!("first definition of %s %s here:", - namespace_to_str(ns), + namespace_error_to_str(duplicate_type), self.session.str_of(name))); } } diff --git a/src/test/compile-fail/issue-3099-b.rs b/src/test/compile-fail/issue-3099-b.rs index 3d22a59d6bd4..5502b18f0941 100644 --- a/src/test/compile-fail/issue-3099-b.rs +++ b/src/test/compile-fail/issue-3099-b.rs @@ -10,6 +10,6 @@ pub mod a {} -pub mod a {} //~ ERROR duplicate definition of type `a` +pub mod a {} //~ ERROR duplicate definition of module `a` fn main() {} From f982f42f3c1c45ed1be4c0fd5a90e639e43e3f95 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Sun, 23 Jun 2013 22:20:00 +0530 Subject: [PATCH 134/336] resolve: make error message strings more consistent The "first definition of ..." error string reported by add_child() looks different from similar messages reported by other functions. Fix this. Signed-off-by: Ramkumar Ramachandra --- src/librustc/middle/resolve.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 5fb7cc9b9bda..f39889b5e2f9 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1053,7 +1053,7 @@ impl Resolver { let r = child.span_for_namespace(ns); for r.iter().advance |sp| { self.session.span_note(*sp, - fmt!("first definition of %s %s here:", + fmt!("first definition of %s `%s` here", namespace_error_to_str(duplicate_type), self.session.str_of(name))); } From 0d471d310ded00283338ae28350b304e0f36e562 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Mon, 24 Jun 2013 20:40:33 -0400 Subject: [PATCH 135/336] great renaming propagation: syntax --- src/libsyntax/abi.rs | 4 +--- src/libsyntax/ast.rs | 12 +++++------- src/libsyntax/ast_map.rs | 8 +++----- src/libsyntax/ast_util.rs | 16 +++++++--------- src/libsyntax/attr.rs | 8 +++----- src/libsyntax/codemap.rs | 8 +++----- src/libsyntax/diagnostic.rs | 8 +++----- src/libsyntax/ext/asm.rs | 5 ++--- src/libsyntax/ext/base.rs | 8 +++----- src/libsyntax/ext/build.rs | 2 -- src/libsyntax/ext/concat_idents.rs | 2 -- src/libsyntax/ext/deriving/clone.rs | 2 -- src/libsyntax/ext/deriving/cmp/eq.rs | 2 -- src/libsyntax/ext/deriving/cmp/ord.rs | 2 -- src/libsyntax/ext/deriving/cmp/totaleq.rs | 2 +- src/libsyntax/ext/deriving/cmp/totalord.rs | 4 +--- src/libsyntax/ext/deriving/decodable.rs | 5 ++--- src/libsyntax/ext/deriving/encodable.rs | 2 -- src/libsyntax/ext/deriving/generic.rs | 8 +++----- src/libsyntax/ext/deriving/iter_bytes.rs | 2 -- src/libsyntax/ext/deriving/mod.rs | 2 -- src/libsyntax/ext/deriving/rand.rs | 4 +--- src/libsyntax/ext/deriving/to_str.rs | 2 -- src/libsyntax/ext/deriving/ty.rs | 4 +--- src/libsyntax/ext/deriving/zero.rs | 4 +--- src/libsyntax/ext/env.rs | 4 +--- src/libsyntax/ext/expand.rs | 6 +----- src/libsyntax/ext/fmt.rs | 10 ++++------ src/libsyntax/ext/log_syntax.rs | 6 ++---- src/libsyntax/ext/pipes/ast_builder.rs | 4 +--- src/libsyntax/ext/pipes/check.rs | 2 -- src/libsyntax/ext/pipes/liveness.rs | 2 -- src/libsyntax/ext/pipes/mod.rs | 1 - src/libsyntax/ext/pipes/parse_proto.rs | 2 -- src/libsyntax/ext/pipes/pipec.rs | 4 +--- src/libsyntax/ext/pipes/proto.rs | 2 -- src/libsyntax/ext/quote.rs | 7 ++----- src/libsyntax/ext/source_util.rs | 8 +++----- src/libsyntax/ext/trace_macros.rs | 5 ++--- src/libsyntax/ext/tt/macro_parser.rs | 8 +++----- src/libsyntax/ext/tt/macro_rules.rs | 6 ++---- src/libsyntax/ext/tt/transcribe.rs | 6 ++---- src/libsyntax/fold.rs | 5 +---- src/libsyntax/opt_vec.rs | 3 +-- src/libsyntax/parse/comments.rs | 8 +++----- src/libsyntax/parse/common.rs | 2 -- src/libsyntax/parse/lexer.rs | 9 +++------ src/libsyntax/parse/mod.rs | 10 +++------- src/libsyntax/parse/obsolete.rs | 8 +++----- src/libsyntax/parse/parser.rs | 10 ++++------ src/libsyntax/parse/token.rs | 14 ++++++-------- src/libsyntax/print/pp.rs | 6 ++---- src/libsyntax/print/pprust.rs | 12 ++++-------- src/libsyntax/syntax.rs | 11 +---------- src/libsyntax/util/interner.rs | 9 ++------- src/libsyntax/util/parser_testing.rs | 1 - src/libsyntax/visit.rs | 2 -- 57 files changed, 97 insertions(+), 222 deletions(-) diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index f243bcb0abb0..fadd2faf0eb5 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.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::to_bytes; +use std::to_bytes; #[deriving(Eq)] pub enum Abi { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c7f3b41475f0..90b2f131b00e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,18 +10,16 @@ // The Rust abstract syntax tree. -use core::prelude::*; - use codemap::{span, spanned}; use abi::AbiSet; use opt_vec::OptVec; use parse::token::{interner_get, str_to_ident}; -use core::hashmap::HashMap; -use core::option::Option; -use core::to_bytes::IterBytes; -use core::to_bytes; -use core::to_str::ToStr; +use std::hashmap::HashMap; +use std::option::Option; +use std::to_bytes::IterBytes; +use std::to_bytes; +use std::to_str::ToStr; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 421c4c566b56..d381f934d9ad 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use abi::AbiSet; use ast::*; use ast; @@ -22,9 +20,9 @@ use print::pprust; use visit; use syntax::parse::token::special_idents; -use core::cmp; -use core::hashmap::HashMap; -use core::vec; +use std::cmp; +use std::hashmap::HashMap; +use std::vec; pub enum path_elt { path_mod(ident), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 227d700452b6..57e690e7ef80 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -8,22 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::*; use ast; use ast_util; use codemap::{span, spanned}; -use core::cast; -use core::local_data; use opt_vec; use parse::token; use visit; -use core::hashmap::HashMap; -use core::int; -use core::option; -use core::to_bytes; +use std::hashmap::HashMap; +use std::int; +use std::option; +use std::to_bytes; +use std::cast; +use std::local_data; pub fn path_name_i(idents: &[ident]) -> ~str { // FIXME: Bad copies (#2543 -- same for everything else that says "bad") @@ -793,7 +791,7 @@ pub fn getLast(arr: &~[Mrk]) -> uint { mod test { use ast::*; use super::*; - use core::io; + use std::io; #[test] fn xorpush_test () { let mut s = ~[]; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index d9fb91e6ddd8..446641faf6ea 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -10,7 +10,7 @@ // Functions dealing with attributes and meta_items -use core::prelude::*; +extern mod extra; use ast; use codemap::{spanned, dummy_spanned}; @@ -19,10 +19,8 @@ use codemap::BytePos; use diagnostic::span_handler; use parse::comments::{doc_comment_style, strip_doc_comment_decoration}; -use core::hashmap::HashSet; -use core::vec; -use extra; - +use std::hashmap::HashSet; +use std::vec; /* Constructors */ pub fn mk_name_value_item_str(name: @str, value: @str) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index bae5e943a48d..5efc96e16b53 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -21,11 +21,9 @@ source code snippets, etc. */ -use core::prelude::*; - -use core::cmp; -use core::to_bytes; -use core::uint; +use std::cmp; +use std::to_bytes; +use std::uint; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; pub trait Pos { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 7b4ed19fe7fa..13fa01c96e12 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use codemap::{Pos, span}; use codemap; -use core::io; -use core::uint; -use core::vec; +use std::io; +use std::uint; +use std::vec; use extra::term; pub type Emitter = @fn(cmsp: Option<(@codemap::CodeMap, span)>, diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index febb6b324b9f..532757346d0a 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -12,9 +12,6 @@ * Inline assembly support. */ -use core::prelude::*; - -use core::vec; use ast; use codemap::span; use ext::base; @@ -22,6 +19,8 @@ use ext::base::*; use parse; use parse::token; +use std::vec; + enum State { Asm, Outputs, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 997f4e2621fc..282a28ff9e07 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::vec; use ast; use ast::Name; use codemap; @@ -22,7 +19,8 @@ use parse; use parse::token; use parse::token::{ident_to_str, intern, str_to_ident}; -use core::hashmap::HashMap; +use std::vec; +use std::hashmap::HashMap; // new-style macro! tt code: // @@ -535,7 +533,7 @@ fn satisfies_pred(map : &mut HashMap, #[cfg(test)] mod test { use super::MapChain; - use core::hashmap::HashMap; + use std::hashmap::HashMap; #[test] fn testenv () { let mut a = HashMap::new(); diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b63997944774..02d5991e1a7b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use abi::AbiSet; use ast::ident; use ast; diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index e7fb15fbd51c..80ab54b7e2cf 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap::span; use ext::base::*; diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 4fc67f2f52e7..edaf2b8cae67 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 5fc75511e57b..cea88bb7bbb7 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index c60b589dfc38..3b9691cd42c0 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use ast::{meta_item, item, expr}; use codemap::span; diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index acd2073b2734..ccfb34a3a2f5 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; +use std::prelude::*; use ast::{meta_item, item, expr}; use codemap::span; diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 94407cd6e729..84d7320fe1c1 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -8,14 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -use core::cmp::{Ordering, Equal, Less, Greater}; +use std::cmp::{Ordering, Equal, Less, Greater}; pub fn expand_deriving_totalord(cx: @ExtCtxt, span: span, diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 7d17f436a41d..77dbd96255d1 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -13,9 +13,8 @@ The compiler code necessary for #[deriving(Decodable)]. See encodable.rs for more. */ -use core::prelude::*; -use core::vec; -use core::uint; +use std::vec; +use std::uint; use ast::{meta_item, item, expr, m_mutbl}; use codemap::span; diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 2b73dc24d33a..5514fd0b6ab5 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -75,8 +75,6 @@ would yield functions like: } */ -use core::prelude::*; - use ast::{meta_item, item, expr, m_imm, m_mutbl}; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 981b28afd022..9da246eabe97 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -162,8 +162,6 @@ StaticEnum(, ~[(, Left(1)), */ -use core::prelude::*; - use ast; use ast::{enum_def, expr, ident, Generics, struct_def}; @@ -172,8 +170,8 @@ use ext::build::AstBuilder; use codemap::{span,respan}; use opt_vec; -use core::uint; -use core::vec; +use std::uint; +use std::vec; pub use self::ty::*; mod ty; @@ -195,7 +193,7 @@ pub struct TraitDef<'self> { pub struct MethodDef<'self> { /// name of the method name: &'self str, - /// List of generics, e.g. `R: core::rand::Rng` + /// List of generics, e.g. `R: std::rand::Rng` generics: LifetimeBounds<'self>, /// Whether there is a self argument (outer Option) i.e. whether diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index c7949f9a8e31..8403234f8925 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{meta_item, item, expr, and}; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index f5170d284c60..537d9efbb26d 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -18,8 +18,6 @@ library. */ -use core::prelude::*; - use ast::{enum_def, ident, item, Generics, meta_item, struct_def}; use ext::base::ExtCtxt; use ext::build::AstBuilder; diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index b890623b9638..dfbc028ddf6a 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use ast::{meta_item, item, expr, ident}; use codemap::span; @@ -17,7 +15,7 @@ use ext::base::ExtCtxt; use ext::build::{AstBuilder, Duplicate}; use ext::deriving::generic::*; -use core::vec; +use std::vec; pub fn expand_deriving_rand(cx: @ExtCtxt, span: span, diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index 4cd168b12c0c..d1d4d173a3f3 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use ast::{meta_item, item, expr}; use codemap::span; diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index d28613f52faf..9da6bf27eada 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -13,8 +13,6 @@ A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use when specifying impls to be derived. */ -use core::prelude::*; - use ast; use ast::{expr,Generics,ident}; use ext::base::ExtCtxt; @@ -29,7 +27,7 @@ pub enum PtrTy<'self> { Borrowed(Option<&'self str>, ast::mutability), // &['lifetime] [mut] } -/// A path, e.g. `::core::option::Option::` (global). Has support +/// A path, e.g. `::std::option::Option::` (global). Has support /// for type parameters and a lifetime. pub struct Path<'self> { path: ~[&'self str], diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 121d8351ee47..471e72123524 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; -use core::vec; +use std::vec; pub fn expand_deriving_zero(cx: @ExtCtxt, span: span, diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index 34be6fc81432..a6cb61558787 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -14,15 +14,13 @@ * interface. */ -use core::prelude::*; - use ast; use codemap::span; use ext::base::*; use ext::base; use ext::build::AstBuilder; -use core::os; +use std::os; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f6504e85b43b..7fc784320ac1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::{blk_, attribute_, attr_outer, meta_word}; use ast::{crate, expr_, expr_mac, mac_invoc_tt}; use ast::{item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; @@ -27,7 +25,7 @@ use parse::token::{ident_to_str, intern}; use visit; use visit::Visitor; -use core::vec; +use std::vec; pub fn expand_expr(extsbox: @mut SyntaxEnv, cx: @ExtCtxt, @@ -758,8 +756,6 @@ mod test { use util::parser_testing::{string_to_item, string_to_pat, strs_to_idents}; use visit::{mk_vt}; - use core::option::{None, Some}; - // make sure that fail! is present #[test] fn fail_exists_test () { let src = @"fn main() { fail!(\"something appropriately gloomy\");}"; diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 4c0a85b665ae..76073199f645 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -14,17 +14,15 @@ * compiler syntax extension plugin interface. */ -use core::prelude::*; - use ast; use codemap::span; use ext::base::*; use ext::base; use ext::build::AstBuilder; -use core::option; -use core::unstable::extfmt::ct::*; -use core::vec; +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]) @@ -267,7 +265,7 @@ fn pieces_to_expr(cx: @ExtCtxt, sp: span, let mut stms = ~[]; /* Translate each piece (portion of the fmt expression) by invoking the - corresponding function in core::unstable::extfmt. Each function takes a + 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| { diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 4b61d4da218a..5b789cbc26c1 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::vec; use ast; use codemap; use ext::base::*; @@ -18,7 +15,8 @@ use ext::base; use print; use parse::token::{get_ident_interner}; -use core::io; +use std::vec; +use std::io; pub fn expand_syntax_ext(cx: @ExtCtxt, sp: codemap::span, diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 99ffd78d7baf..1af6e7810a57 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -13,13 +13,11 @@ // To start with, it will be use dummy spans, but it might someday do // something smarter. -use core::prelude::*; - use ast::ident; use ast; use codemap::span; -use core::vec; +use std::vec; // Transitional reexports so qquote can find the paths it is looking for mod syntax { diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs index c1b9b051ec9e..8c2898737a35 100644 --- a/src/libsyntax/ext/pipes/check.rs +++ b/src/libsyntax/ext/pipes/check.rs @@ -29,8 +29,6 @@ that. */ -use core::prelude::*; - use ast; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 8b044bd14e11..b1f98d78fb39 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -37,8 +37,6 @@ updating the states using rule (2) until there are no changes. */ -use core::prelude::*; - use ext::base::ExtCtxt; use ext::pipes::proto::{protocol_}; diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs index 3f4b5ee54f19..165d3c39c6b9 100644 --- a/src/libsyntax/ext/pipes/mod.rs +++ b/src/libsyntax/ext/pipes/mod.rs @@ -52,7 +52,6 @@ use ext::pipes::pipec::gen_init; use ext::pipes::proto::visit; use parse::lexer::{new_tt_reader, reader}; use parse::parser::Parser; -use core::option::None; pub mod ast_builder; pub mod parse_proto; diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs index 11db1a5da297..21bb82662394 100644 --- a/src/libsyntax/ext/pipes/parse_proto.rs +++ b/src/libsyntax/ext/pipes/parse_proto.rs @@ -10,8 +10,6 @@ // Parsing pipes protocols from token trees. -use core::prelude::*; - use ast_util; use ext::pipes::proto::*; use parse::common::SeqSep; diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 55ac9c5ec1c8..49729261de65 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -10,8 +10,6 @@ // A protocol compiler for Rust. -use core::prelude::*; - use ast; use codemap::{dummy_sp, spanned}; use ext::base::ExtCtxt; @@ -23,7 +21,7 @@ use ext::quote::rt::*; use opt_vec; use opt_vec::OptVec; -use core::vec; +use std::vec; pub trait gen_send { fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item; diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 87aaf7781fae..e86ced847d74 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 742f5a97825f..db1902753a38 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::vec; use ast; use codemap::{BytePos, Pos, span}; use ext::base::ExtCtxt; @@ -20,6 +17,8 @@ use parse::token::*; use parse::token; use parse; +use std::vec; + /** * * Quasiquoting works via token trees. @@ -32,8 +31,6 @@ use parse; */ pub mod rt { - use core::prelude::*; - use ast; use ext::base::ExtCtxt; use parse; diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index d92f4e8458bf..71dc82be4143 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap; use codemap::{Pos, ExpandedFrom, span}; @@ -21,9 +19,9 @@ use parse; use parse::token::{get_ident_interner}; use print::pprust; -use core::io; -use core::result; -use core::vec; +use std::io; +use std::result; +use std::vec; // These macros all relate to the file system; they either return // the column/row/filename of the expression, or they include diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index 09965b921c1e..299706b2d40b 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::vec; use ast; use codemap::span; use ext::base::ExtCtxt; @@ -19,6 +16,8 @@ use parse::lexer::{new_tt_reader, reader}; use parse::parser::Parser; use parse::token::keywords; +use std::vec; + pub fn expand_trace_macros(cx: @ExtCtxt, sp: span, tt: &[ast::token_tree]) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index f2b57db06c15..7c69bdd01c81 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -10,8 +10,6 @@ // Earley-like parser for macros. -use core::prelude::*; - use ast; use ast::{matcher, match_tok, match_seq, match_nonterminal, ident}; use codemap::{BytePos, mk_sp}; @@ -22,9 +20,9 @@ use parse::parser::Parser; use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str}; use parse::token; -use core::hashmap::HashMap; -use core::uint; -use core::vec; +use std::hashmap::HashMap; +use std::uint; +use std::vec; /* This is an Earley-like parser, without support for in-grammar nonterminals, only by calling out to the main rust parser for named nonterminals (which it diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 2b65e6599f66..80dd0c7247b4 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - -use core::vec; use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq}; use ast::{tt_delim}; use ast; @@ -26,7 +23,8 @@ use parse::token::{get_ident_interner, special_idents, gensym_ident, ident_to_st use parse::token::{FAT_ARROW, SEMI, nt_matchers, nt_tt}; use print; -use core::io; +use std::vec; +use std::io; pub fn add_new_extension(cx: @ExtCtxt, sp: span, diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index abefbedaff0a..92feaa154fed 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident}; use codemap::{span, dummy_sp}; @@ -19,8 +17,8 @@ use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident}; use parse::token::{ident_to_str}; use parse::lexer::TokenAndSpan; -use core::hashmap::HashMap; -use core::option; +use std::hashmap::HashMap; +use std::option; ///an unzipping of `token_tree`s struct TtFrame { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 25839fb46339..2c7c335a8410 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -8,15 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast::*; use ast; use codemap::{span, spanned}; use parse::token; use opt_vec::OptVec; -use core::vec; +use std::vec; pub trait ast_fold { fn fold_crate(@self, &crate) -> crate; @@ -1011,5 +1009,4 @@ mod test { 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 8917b481dc72..34c526a7d13f 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -16,8 +16,7 @@ * other useful things like `push()` and `len()`. */ -use core::prelude::*; -use core::vec::VecIterator; +use std::vec::VecIterator; #[deriving(Encodable, Decodable)] pub enum OptVec { diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 472f807cd8b6..2baf08b68f1c 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap::{BytePos, CharPos, CodeMap, Pos}; use diagnostic; @@ -20,9 +18,9 @@ use parse::lexer; use parse::token; use parse::token::{get_ident_interner}; -use core::io; -use core::str; -use core::uint; +use std::io; +use std::str; +use std::uint; #[deriving(Eq)] pub enum cmnt_style { diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 0956fa7225f2..cde4c754d560 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap::{BytePos, spanned}; use parse::lexer::reader; diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 84915b6403a7..2092f0fa5fac 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use codemap::{BytePos, CharPos, CodeMap, Pos, span}; use codemap; @@ -19,9 +17,9 @@ use ext::tt::transcribe::{dup_tt_reader}; use parse::token; use parse::token::{str_to_ident}; -use core::char; -use core::either; -use core::u64; +use std::char; +use std::either; +use std::u64; pub use ext::tt::transcribe::{TtReader, new_tt_reader}; @@ -789,7 +787,6 @@ mod test { use ast; use codemap::{BytePos, CodeMap, span}; - use core::option::None; use diagnostic; use parse::token; use parse::token::{str_to_ident}; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0c5731c8b29b..d54c64e7ee60 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -20,10 +20,8 @@ use parse::attr::parser_attr; use parse::lexer::reader; use parse::parser::Parser; -use core::io; -use core::option::{None, Option, Some}; -use core::path::Path; -use core::result::{Err, Ok}; +use std::io; +use std::path::Path; pub mod lexer; pub mod parser; @@ -335,9 +333,7 @@ mod test { use super::*; use extra::serialize::Encodable; use extra; - use core::io; - use core::option::Some; - use core::option::None; + use std::io; use codemap::{span, BytePos, spanned}; use opt_vec; use ast; diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 19b4d2545808..32508f3b477a 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -17,8 +17,6 @@ Obsolete syntax that becomes too hard to parse can be removed. */ -use core::prelude::*; - use ast::{expr, expr_lit, lit_nil, attribute}; use ast; use codemap::{span, respan}; @@ -26,8 +24,8 @@ use parse::parser::Parser; use parse::token::{keywords, Token}; use parse::token; -use core::str; -use core::to_bytes; +use std::str; +use std::to_bytes; /// The specific types of unsupported syntax #[deriving(Eq)] @@ -127,7 +125,7 @@ impl Parser { ), ObsoleteSwap => ( "swap", - "Use core::util::{swap, replace} instead" + "Use std::util::{swap, replace} instead" ), ObsoleteUnsafeBlock => ( "non-standalone unsafe block", diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d8aab1f68eea..35c09ff1b56a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use abi; use abi::AbiSet; use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil}; @@ -92,10 +90,10 @@ use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; use opt_vec; use opt_vec::OptVec; -use core::either::Either; -use core::either; -use core::hashmap::HashSet; -use core::vec; +use std::either::Either; +use std::either; +use std::hashmap::HashSet; +use std::vec; #[deriving(Eq)] enum restriction { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index d40b96f077bb..2ddae73a3fcd 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use ast; use ast::Name; use ast_util; @@ -17,12 +15,12 @@ use parse::token; use util::interner::StrInterner; use util::interner; -use core::cast; -use core::char; -use core::cmp::Equiv; -use core::local_data; -use core::rand; -use core::rand::RngUtil; +use std::cast; +use std::char; +use std::cmp::Equiv; +use std::local_data; +use std::rand; +use std::rand::RngUtil; #[deriving(Encodable, Decodable, Eq)] pub enum binop { diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 7853e7e312d4..4e03d9bac704 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -61,10 +61,8 @@ * avoid combining it with other lines and making matters even worse. */ -use core::prelude::*; - -use core::io; -use core::vec; +use std::io; +use std::vec; #[deriving(Eq)] pub enum breaks { consistent, inconsistent, } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1a3155337a5e..1b9019985b89 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use abi::AbiSet; use ast::{RegionTyParamBound, TraitTyParamBound, required, provided}; use ast; @@ -29,10 +27,10 @@ use print::pp::{breaks, consistent, inconsistent, eof}; use print::pp; use print::pprust; -use core::char; -use core::io; -use core::u64; -use core::uint; +use std::char; +use std::io; +use std::u64; +use std::uint; // The @ps is stored here to prevent recursive type. pub enum ann_node<'self> { @@ -2251,8 +2249,6 @@ mod test { use ast; use ast_util; use codemap; - use core::cmp::Eq; - use core::option::None; use parse::token; fn string_check (given : &T, expected: &T) { diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 278600bc0394..395017cef3b7 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -23,16 +23,7 @@ #[allow(non_camel_case_types)]; #[deny(deprecated_pattern)]; -#[no_core]; -#[no_std]; - -extern mod core(name = "std"); -extern mod extra(name = "extra"); - -// For deriving(Encodable) purposes... -extern mod std(name = "std"); - -use core::prelude::*; +extern mod extra; pub mod util { pub mod interner; diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 004ba7762d3a..af37c1d27d82 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -12,13 +12,8 @@ // allows bidirectional lookup; i.e. given a value, one can easily find the // type, and vice versa. -// allow the interner_key macro to escape this module: -#[macro_escape]; - -use core::prelude::*; - -use core::cmp::Equiv; -use core::hashmap::HashMap; +use std::cmp::Equiv; +use std::hashmap::HashMap; pub struct Interner { priv map: @mut HashMap, diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index d0961ddbc70f..4340d6bb6a2d 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::option::{Option,None}; use ast; use parse::{new_parse_sess}; use parse::{ParseSess,string_to_filemap,filemap_to_tts}; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d7914832835a..da20eb1e098e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; - use abi::AbiSet; use ast::*; use ast; From 5242e8d2bad01beec7c841d20952cb230bc9fd84 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 17:19:28 -0400 Subject: [PATCH 136/336] remove the redundant `each` method from OptVec --- src/librustc/metadata/encoder.rs | 4 ++-- src/librustc/middle/resolve.rs | 8 ++++---- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/collect.rs | 4 ++-- src/librustc/middle/typeck/rscope.rs | 2 +- src/libsyntax/ast_util.rs | 4 ++-- src/libsyntax/ext/deriving/generic.rs | 4 ++-- src/libsyntax/ext/pipes/pipec.rs | 4 ++-- src/libsyntax/opt_vec.rs | 7 ------- src/libsyntax/print/pprust.rs | 2 +- src/libsyntax/visit.rs | 4 ++-- 11 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d08342d8687d..9c28da10e40d 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -731,8 +731,8 @@ fn encode_info_for_method(ecx: &EncodeContext, } let mut combined_ty_params = opt_vec::Empty; - for owner_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } - for method_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } + for owner_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } + for method_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } let len = combined_ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &combined_ty_params); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index a8b837d869d3..3a54c224b523 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3834,8 +3834,8 @@ impl Resolver { pub fn resolve_type_parameters(@mut self, type_parameters: &OptVec, visitor: ResolveVisitor) { - for type_parameters.each |type_parameter| { - for type_parameter.bounds.each |bound| { + for type_parameters.iter().advance |type_parameter| { + for type_parameter.bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } } @@ -4181,13 +4181,13 @@ impl Resolver { } } - for bounds.each |bound| { + for bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } } ty_closure(c) => { - for c.bounds.each |bound| { + for c.bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } visit_ty(ty, ((), visitor)); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 3b651451db84..5e6574850f1b 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -752,7 +752,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, //! legal. let mut builtin_bounds = ty::EmptyBuiltinBounds(); - for ast_bounds.each |ast_bound| { + for ast_bounds.iter().advance |ast_bound| { match *ast_bound { ast::TraitTyParamBound(b) => { match lookup_def_tcx(tcx, b.path.span, b.ref_id) { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 3554376902cb..7812a0ed0eba 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -775,7 +775,7 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, span: span, generics: &ast::Generics, thing: &'static str) { - for generics.ty_params.each |ty_param| { + for generics.ty_params.iter().advance |ty_param| { if ty_param.bounds.len() > 0 { ccx.tcx.sess.span_err( span, @@ -1172,7 +1172,7 @@ pub fn ty_generics(ccx: &CrateCtxt, builtin_bounds: ty::EmptyBuiltinBounds(), trait_bounds: ~[] }; - for ast_bounds.each |ast_bound| { + for ast_bounds.iter().advance |ast_bound| { match *ast_bound { TraitTyParamBound(b) => { let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id); diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index 16b490cd478d..dc9fc264f85d 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -57,7 +57,7 @@ impl RegionParamNames { } fn has_ident(&self, ident: ast::ident) -> bool { - for self.each |region_param_name| { + for self.iter().advance |region_param_name| { if *region_param_name == ident { return true; } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 227d700452b6..a233c330b64d 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -394,10 +394,10 @@ impl id_range { pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { let visit_generics: @fn(&Generics, T) = |generics, t| { - for generics.ty_params.each |p| { + for generics.ty_params.iter().advance |p| { vfn(p.id, copy t); } - for generics.lifetimes.each |p| { + for generics.lifetimes.iter().advance |p| { vfn(p.id, copy t); } }; diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 981b28afd022..83e446fa4c68 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -324,11 +324,11 @@ impl<'self> TraitDef<'self> { let mut trait_generics = self.generics.to_generics(cx, span, type_ident, generics); // Copy the lifetimes - for generics.lifetimes.each |l| { + for generics.lifetimes.iter().advance |l| { trait_generics.lifetimes.push(copy *l) }; // Create the type parameters. - for generics.ty_params.each |ty_param| { + for generics.ty_params.iter().advance |ty_param| { // I don't think this can be moved out of the loop, since // a TyParamBound requires an ast id let mut bounds = opt_vec::from( diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 55ac9c5ec1c8..da5455d43327 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -374,7 +374,7 @@ impl gen_init for protocol { fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { let mut params: OptVec = opt_vec::Empty; for (copy self.states).iter().advance |s| { - for s.generics.ty_params.each |tp| { + for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () @@ -392,7 +392,7 @@ impl gen_init for protocol { let ext_cx = cx; let mut params: OptVec = opt_vec::Empty; let fields = do (copy self.states).iter().transform |s| { - for s.generics.ty_params.each |tp| { + for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 8917b481dc72..22b1d040d42e 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -38,13 +38,6 @@ pub fn from(t: ~[T]) -> OptVec { } impl OptVec { - fn each(&self, blk: &fn(v: &T) -> bool) -> bool { - match *self { - Empty => true, - Vec(ref v) => v.iter().advance(blk) - } - } - fn push(&mut self, t: T) { match *self { Vec(ref mut v) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1a3155337a5e..d7b5e57a57f0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1743,7 +1743,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { if !bounds.is_empty() { word(s.s, ":"); let mut first = true; - for bounds.each |bound| { + for bounds.iter().advance |bound| { nbsp(s); if first { first = false; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d7914832835a..5e409be3e6cc 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -334,7 +334,7 @@ pub fn visit_foreign_item(ni: @foreign_item, (e, v): (E, vt)) { pub fn visit_ty_param_bounds(bounds: &OptVec, (e, v): (E, vt)) { - for bounds.each |bound| { + for bounds.iter().advance |bound| { match *bound { TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)), RegionTyParamBound => {} @@ -343,7 +343,7 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, } pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { - for generics.ty_params.each |tp| { + for generics.ty_params.iter().advance |tp| { visit_ty_param_bounds(tp.bounds, (copy e, v)); } } From 64ee9668a2e3d4d75b859fd3bca1466a97fae2d8 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 17:45:00 -0400 Subject: [PATCH 137/336] container: remove internal iterators from Map the maps are being migrated to external iterators --- src/libextra/smallintmap.rs | 64 +++++++++---------- src/libextra/treemap.rs | 40 ++++++------ src/libstd/container.rs | 12 ---- src/libstd/hashmap.rs | 56 ++++++++-------- src/libstd/trie.rs | 48 +++++++------- .../class-impl-very-parameterized-trait.rs | 21 ------ 6 files changed, 104 insertions(+), 137 deletions(-) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 17126f0d32b5..1d163922955d 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -56,38 +56,6 @@ impl Map for SmallIntMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref elt) => if !it(&i, elt) { return false; }, - None => () - } - } - return true; - } - - /// Visit all keys in order - fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { - self.each(|k, _| blk(k)) - } - - /// Visit all values in order - fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { - self.each(|_, v| blk(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref mut elt) => if !it(&i, elt) { return false; }, - None => () - } - } - return true; - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { if *key < self.v.len() { @@ -156,6 +124,38 @@ impl SmallIntMap { /// Create an empty SmallIntMap pub fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } + /// Visit all key-value pairs in order + pub fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } + + /// Visit all keys in order + pub fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { + self.each(|k, _| blk(k)) + } + + /// Visit all values in order + pub fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { + self.each(|_, v| blk(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref mut elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } + /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 4929dea9045b..fd83fd199167 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -107,26 +107,6 @@ impl Map for TreeMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { - each(&self.root, f) - } - - /// Visit all keys in order - fn each_key(&self, f: &fn(&K) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - /// Visit all values in order - fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { - mutate_values(&mut self.root, f) - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V> { let mut current: &'a Option<~TreeNode> = &self.root; @@ -184,6 +164,26 @@ impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } + /// Visit all key-value pairs in order + pub fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { + each(&self.root, f) + } + + /// Visit all keys in order + pub fn each_key(&self, f: &fn(&K) -> bool) -> bool { + self.each(|k, _| f(k)) + } + + /// Visit all values in order + pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { + self.each(|_, v| f(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { + mutate_values(&mut self.root, f) + } + /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { each_reverse(&self.root, f) diff --git a/src/libstd/container.rs b/src/libstd/container.rs index c1b656f1cd9e..d6f4c26715a4 100644 --- a/src/libstd/container.rs +++ b/src/libstd/container.rs @@ -34,18 +34,6 @@ pub trait Map: Mutable { /// Return true if the map contains a value for the specified key fn contains_key(&self, key: &K) -> bool; - /// Visits all keys and values - fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool; - - /// Visit all keys - fn each_key(&self, f: &fn(&K) -> bool) -> bool; - - /// Visit all values - fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool; - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool; - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V>; diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 7d55947e8188..962025915d24 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -307,34 +307,6 @@ impl Map for HashMap { } } - /// Visit all key-value pairs - fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - self.iter().advance(|(k, v)| blk(k, v)) - } - - /// Visit all keys - fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { - self.iter().advance(|(k, _)| blk(k)) - } - - /// Visit all values - fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { - self.iter().advance(|(_, v)| blk(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { - for uint::range(0, self.buckets.len()) |i| { - match self.buckets[i] { - Some(Bucket{key: ref key, value: ref mut value, _}) => { - if !blk(key, value) { return false; } - } - None => () - } - } - return true; - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, k: &K) -> Option<&'a V> { match self.bucket_for_key(k) { @@ -516,6 +488,34 @@ impl HashMap { } } + /// Visit all key-value pairs + pub fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { + self.iter().advance(|(k, v)| blk(k, v)) + } + + /// Visit all keys + pub fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { + self.iter().advance(|(k, _)| blk(k)) + } + + /// Visit all values + pub fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { + self.iter().advance(|(_, v)| blk(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + match self.buckets[i] { + Some(Bucket{key: ref key, value: ref mut value, _}) => { + if !blk(key, value) { return false; } + } + None => () + } + } + return true; + } + /// An iterator visiting all key-value pairs in arbitrary order. /// Iterator element type is (&'a K, &'a V). pub fn iter<'a>(&'a self) -> HashMapIterator<'a, K, V> { diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index e6449ef49229..8f70c75439a0 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -58,30 +58,6 @@ impl Map for TrieMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - #[inline] - fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { - self.root.each(f) - } - - /// Visit all keys in order - #[inline] - fn each_key(&self, f: &fn(&uint) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - /// Visit all values in order - #[inline] - fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - /// Iterate over the map and mutate the contained values - #[inline] - fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { - self.root.mutate_values(f) - } - /// Return a reference to the value corresponding to the key #[inline] fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { @@ -158,6 +134,30 @@ impl TrieMap { self.root.each_reverse(f) } + /// Visit all key-value pairs in order + #[inline] + pub fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each(f) + } + + /// Visit all keys in order + #[inline] + pub fn each_key(&self, f: &fn(&uint) -> bool) -> bool { + self.each(|k, _| f(k)) + } + + /// Visit all values in order + #[inline] + pub fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { + self.each(|_, v| f(v)) + } + + /// Iterate over the map and mutate the contained values + #[inline] + pub fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { + self.root.mutate_values(f) + } + /// Visit all keys in reverse order #[inline] pub fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool { diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index c54b8db46c88..2805fec6fce2 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -61,29 +61,8 @@ impl Mutable for cat { } impl Map for cat { - fn each<'a>(&'a self, f: &fn(&int, &'a T) -> bool) -> bool { - let mut n = int::abs(self.meows); - while n > 0 { - if !f(&n, &self.name) { return false; } - n -= 1; - } - return true; - } - fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - fn each_key(&self, f: &fn(v: &int) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - fn each_value<'a>(&'a self, f: &fn(v: &'a T) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - fn mutate_values(&mut self, _f: &fn(&int, &mut T) -> bool) -> bool { - fail!("nope") - } - fn insert(&mut self, k: int, _: T) -> bool { self.meows += k; true From e67c48a5912b85c286113e0d039aae85f18da1d7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 18:34:20 -0400 Subject: [PATCH 138/336] remove `each` from vec, HashMap and HashSet --- doc/tutorial.md | 57 ++++++-- src/compiletest/runtest.rs | 2 +- src/libextra/arc.rs | 11 +- src/libextra/getopts.rs | 5 +- src/libextra/json.rs | 8 +- src/libextra/net_url.rs | 2 +- src/libextra/serialize.rs | 4 +- src/libextra/sync.rs | 3 +- src/libextra/workcache.rs | 4 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/middle/kind.rs | 3 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/lint.rs | 7 +- src/librustc/middle/region.rs | 2 +- src/librustc/middle/resolve.rs | 24 ++-- src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/callee.rs | 4 +- src/librustc/middle/trans/type_use.rs | 3 +- .../middle/typeck/infer/region_inference.rs | 2 +- src/librustc/rustc.rs | 2 +- src/librusti/program.rs | 8 +- src/libstd/hashmap.rs | 11 -- src/libstd/task/spawn.rs | 2 +- src/libstd/vec.rs | 122 +----------------- src/test/bench/graph500-bfs.rs | 4 +- src/test/bench/msgsend-pipes-shared.rs | 2 +- src/test/bench/msgsend-pipes.rs | 2 +- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- .../block-must-not-have-result-for.rs | 4 +- .../borrowck-insert-during-each.rs | 2 +- src/test/compile-fail/issue-2151.rs | 7 +- src/test/compile-fail/liveness-issue-2163.rs | 2 +- src/test/run-pass/assignability-trait.rs | 6 +- src/test/run-pass/auto-loop.rs | 5 +- src/test/run-pass/block-arg.rs | 2 +- .../run-pass/borrowck-mut-vec-as-imm-slice.rs | 6 +- src/test/run-pass/break.rs | 6 +- src/test/run-pass/const-vec-of-fns.rs | 4 +- src/test/run-pass/for-destruct.rs | 3 +- src/test/run-pass/rcvr-borrowed-to-slice.rs | 2 +- src/test/run-pass/trait-generic.rs | 5 +- 43 files changed, 139 insertions(+), 223 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 9c61a04930ac..9e54622688b0 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1552,13 +1552,6 @@ fn each(v: &[int], op: &fn(v: &int)) { } ~~~~ -As an aside, the reason we pass in a *pointer* to an integer rather -than the integer itself is that this is how the actual `each()` -function for vectors works. `vec::each` though is a -[generic](#generics) function, so must be efficient to use for all -types. Passing the elements by pointer avoids copying potentially -large objects. - As a caller, if we use a closure to provide the final operator argument, we can write it in a way that has a pleasant, block-like structure. @@ -1616,6 +1609,9 @@ To enable `debug!` logging, set the RUST_LOG environment variable to the name of ## For loops +> ***Note:*** The closure-based protocol used `for` loop is on the way out. The `for` loop will +> use iterator objects in the future instead. + The most common way to express iteration in Rust is with a `for` loop. Like `do`, `for` is a nice syntax for describing control flow with closures. Additionally, within a `for` loop, `break`, `loop`, @@ -1640,7 +1636,16 @@ fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { And using this function to iterate over a vector: ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } each([2, 4, 8, 5, 16], |n| { if *n % 2 != 0 { println("found odd number!"); @@ -1656,7 +1661,16 @@ out of the loop, you just write `break`. To skip ahead to the next iteration, write `loop`. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } for each([2, 4, 8, 5, 16]) |n| { if *n % 2 != 0 { println("found odd number!"); @@ -1671,7 +1685,16 @@ normally allowed in closures, in a block that appears as the body of a the enclosing function, not just the loop body. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } fn contains(v: &[int], elt: int) -> bool { for each(v) |x| { if (*x == elt) { return true; } @@ -1686,7 +1709,16 @@ In these situations it can be convenient to lean on Rust's argument patterns to bind `x` to the actual value, not the pointer. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } # fn contains(v: &[int], elt: int) -> bool { for each(v) |&x| { if (x == elt) { return true; } @@ -1841,10 +1873,9 @@ vector consisting of the result of applying `function` to each element of `vector`: ~~~~ -# use std::vec; fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { let mut accumulator = ~[]; - for vec::each(vector) |element| { + for vector.iter().advance |element| { accumulator.push(function(element)); } return accumulator; diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index fd56031ccf94..3e2f484ee53d 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -529,7 +529,7 @@ fn compose_and_run_compiler( let extra_link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()]; - for vec::each(props.aux_builds) |rel_ab| { + for props.aux_builds.iter().advance |rel_ab| { let abs_ab = config.aux_base.push_rel(&Path(*rel_ab)); let aux_args = make_compile_args(config, props, ~[~"--lib"] + extra_link_args, diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 32114f4037ec..c5fe07f21875 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -521,6 +521,7 @@ mod tests { use core::cell::Cell; use core::comm; use core::task; + use core::uint; #[test] fn manually_share_arc() { @@ -790,18 +791,20 @@ mod tests { } assert_eq!(*state, 42); *state = 31337; + // FIXME: #7372: hits type inference bug with iterators // send to other readers - for vec::each(reader_convos) |x| { - match *x { + for uint::range(0, reader_convos.len()) |i| { + match reader_convos[i] { (ref rc, _) => rc.send(()), } } } let read_mode = arc.downgrade(write_mode); do (&read_mode).read |state| { + // FIXME: #7372: hits type inference bug with iterators // complete handshake with other readers - for vec::each(reader_convos) |x| { - match *x { + for uint::range(0, reader_convos.len()) |i| { + match reader_convos[i] { (_, ref rp) => rp.recv(), } } diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index d97804722f25..9c416550eb78 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -418,10 +418,11 @@ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str { */ pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] { let mut acc: ~[~str] = ~[]; - for vec::each(opt_vals(mm, nm)) |v| { + let r = opt_vals(mm, nm); + for r.iter().advance |v| { match *v { Val(ref s) => acc.push(copy *s), _ => () } } - return acc; + acc } /// Returns the string argument supplied to a matching option or none diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 24c4c5b27c49..15553b035f65 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -1123,7 +1123,7 @@ impl Eq for Json { &Object(ref d1) => { if d0.len() == d1.len() { let mut equal = true; - for d0.each |k, v0| { + for d0.iter().advance |(k, v0)| { match d1.find(k) { Some(v1) if v0 == v1 => { }, _ => { equal = false; break } @@ -1186,12 +1186,12 @@ impl Ord for Json { let mut d1_flat = ~[]; // FIXME #4430: this is horribly inefficient... - for d0.each |k, v| { + for d0.iter().advance |(k, v)| { d0_flat.push((@copy *k, @copy *v)); } d0_flat.qsort(); - for d1.each |k, v| { + for d1.iter().advance |(k, v)| { d1_flat.push((@copy *k, @copy *v)); } d1_flat.qsort(); @@ -1326,7 +1326,7 @@ impl ToJson for ~[A] { impl ToJson for HashMap<~str, A> { fn to_json(&self) -> Json { let mut d = HashMap::new(); - for self.each |key, value| { + for self.iter().advance |(key, value)| { d.insert(copy *key, value.to_json()); } Object(~d) diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index dda4b85df4bf..5d3d31fdec47 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -207,7 +207,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str { let mut out = ~""; let mut first = true; - for m.each |key, values| { + for m.iter().advance |(key, values)| { let key = encode_plus(*key); for values.iter().advance |value| { diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 34fd7e9f1ec1..345b217871cc 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -710,7 +710,7 @@ impl< fn encode(&self, e: &mut E) { do e.emit_map(self.len()) |e| { let mut i = 0; - for self.each |key, val| { + for self.iter().advance |(key, val)| { e.emit_map_elt_key(i, |e| key.encode(e)); e.emit_map_elt_val(i, |e| val.encode(e)); i += 1; @@ -744,7 +744,7 @@ impl< fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { let mut i = 0; - for self.each |e| { + for self.iter().advance |e| { s.emit_seq_elt(i, |s| e.encode(s)); i += 1; } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 6990d35f0613..5cb52a7b9dfb 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -1094,7 +1094,8 @@ mod tests { }; assert!(result.is_err()); // child task must have finished by the time try returns - for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings + let r = p.recv(); + for r.iter().advance |p| { p.recv(); } // wait on all its siblings do m.lock_cond |cond| { let woken = cond.broadcast(); assert_eq!(woken, 0); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index ed675bf99e9d..a014293f0630 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -146,7 +146,7 @@ impl WorkMap { impl Encodable for WorkMap { fn encode(&self, s: &mut S) { let mut d = ~[]; - for self.each |k, v| { + for self.iter().advance |(k, v)| { d.push((copy *k, copy *v)) } sort::tim_sort(d); @@ -320,7 +320,7 @@ impl TPrep for Prep { } fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool { - for map.each |k, v| { + for map.iter().advance |(k, v)| { if ! self.is_fresh(cat, k.kind, k.name, *v) { return false; } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index c6c1ac720e8e..b0a955fef8f7 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -86,7 +86,7 @@ pub fn have_crate_data(cstore: &CStore, cnum: ast::crate_num) -> bool { pub fn iter_crate_data(cstore: &CStore, i: &fn(ast::crate_num, @crate_metadata)) { - for cstore.metas.each |&k, &v| { + for cstore.metas.iter().advance |(&k, &v)| { i(k, v); } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 7f7a81fa974a..b0b2a16cf893 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -240,7 +240,8 @@ fn check_fn( // Check kinds on free variables: do with_appropriate_checker(cx, fn_id) |chk| { - for vec::each(*freevars::get_freevars(cx.tcx, fn_id)) |fv| { + let r = freevars::get_freevars(cx.tcx, fn_id); + for r.iter().advance |fv| { chk(cx, *fv); } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index d73b019c1ea7..9d4064e99bdb 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -436,7 +436,7 @@ impl LanguageItemCollector { } pub fn check_completeness(&self) { - for self.item_refs.each |&key, &item_ref| { + for self.item_refs.iter().advance |(&key, &item_ref)| { match self.items.items[item_ref] { None => { self.session.err(fmt!("no item found for `%s`", key)); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 5c36ab7750c8..6da10b7c2774 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -361,7 +361,7 @@ impl Context { } fn lint_to_str(&self, lint: lint) -> &'static str { - for self.dict.each |k, v| { + for self.dict.iter().advance |(k, v)| { if v.lint == lint { return *k; } @@ -742,7 +742,8 @@ fn check_item_ctypes(cx: &Context, it: @ast::item) { fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { let tys = vec::map(decl.inputs, |a| a.ty ); - for vec::each(vec::append_one(tys, decl.output)) |ty| { + let r = vec::append_one(tys, decl.output); + for r.iter().advance |ty| { check_ty(cx, *ty); } } @@ -1171,7 +1172,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { // If we missed any lints added to the session, then there's a bug somewhere // in the iteration code. - for tcx.sess.lints.each |_, v| { + for tcx.sess.lints.iter().advance |(_, v)| { for v.iter().advance |t| { match *t { (lint, span, ref msg) => diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0e6d8617ba42..7d3e895a0edd 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -948,7 +948,7 @@ pub fn determine_rp_in_crate(sess: Session, debug!("%s", { debug!("Region variance results:"); let region_paramd_items = cx.region_paramd_items; - for region_paramd_items.each |&key, &value| { + for region_paramd_items.iter().advance |(&key, &value)| { debug!("item %? (%s) is parameterized with variance %?", key, ast_map::node_id_to_str(ast_map, key, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 3a54c224b523..096ab71e4246 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1386,7 +1386,7 @@ impl Resolver { } let def_id = local_def(item.id); - for method_names.each |name, _| { + for method_names.iter().advance |(name, _)| { if !self.method_map.contains_key(name) { self.method_map.insert(*name, HashSet::new()); } @@ -1704,7 +1704,7 @@ impl Resolver { interned_method_names.insert(method_name); } } - for interned_method_names.each |name| { + for interned_method_names.iter().advance |name| { if !self.method_map.contains_key(name) { self.method_map.insert(*name, HashSet::new()); } @@ -2470,8 +2470,8 @@ impl Resolver { assert_eq!(containing_module.glob_count, 0); // Add all resolved imports from the containing module. - for containing_module.import_resolutions.each - |ident, target_import_resolution| { + for containing_module.import_resolutions.iter().advance + |(ident, target_import_resolution)| { debug!("(resolving glob import) writing module resolution \ %? into `%s`", @@ -2555,13 +2555,13 @@ impl Resolver { }; // Add all children from the containing module. - for containing_module.children.each |&ident, name_bindings| { + for containing_module.children.iter().advance |(&ident, name_bindings)| { merge_import_resolution(ident, *name_bindings); } // Add external module children from the containing module. - for containing_module.external_module_children.each - |&ident, module| { + for containing_module.external_module_children.iter().advance + |(&ident, module)| { let name_bindings = @mut Resolver::create_name_bindings_from_module(*module); merge_import_resolution(ident, name_bindings); @@ -3251,7 +3251,7 @@ impl Resolver { pub fn add_exports_for_module(@mut self, exports2: &mut ~[Export2], module_: @mut Module) { - for module_.children.each |ident, namebindings| { + for module_.children.iter().advance |(ident, namebindings)| { debug!("(computing exports) maybe export '%s'", self.session.str_of(*ident)); self.add_exports_of_namebindings(&mut *exports2, @@ -3266,7 +3266,7 @@ impl Resolver { false); } - for module_.import_resolutions.each |ident, importresolution| { + for module_.import_resolutions.iter().advance |(ident, importresolution)| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", self.session.str_of(*ident)); @@ -4039,7 +4039,7 @@ impl Resolver { for arm.pats.iter().enumerate().advance |(i, p)| { let map_i = self.binding_mode_map(*p); - for map_0.each |&key, &binding_0| { + for map_0.iter().advance |(&key, &binding_0)| { match map_i.find(&key) { None => { self.session.span_err( @@ -4060,7 +4060,7 @@ impl Resolver { } } - for map_i.each |&key, &binding| { + for map_i.iter().advance |(&key, &binding)| { if !map_0.contains_key(&key) { self.session.span_err( binding.span, @@ -5355,7 +5355,7 @@ impl Resolver { } debug!("Import resolutions:"); - for module_.import_resolutions.each |name, import_resolution| { + for module_.import_resolutions.iter().advance |(name, import_resolution)| { let value_repr; match import_resolution.target_for_namespace(ValueNS) { None => { value_repr = ~""; } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 71b416ffe85f..63b39b8fe763 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1673,7 +1673,7 @@ pub fn trans_match_inner(scope_cx: block, let mut arm_datas = ~[]; let mut matches = ~[]; - for vec::each(arms) |arm| { + for arms.iter().advance |arm| { let body = scope_block(bcx, arm.body.info(), "case_body"); let bindings_map = create_bindings_map(bcx, arm.pats[0]); let arm_data = @ArmData {bodycx: body, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0e322c187af2..5bf0e596ca05 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2945,7 +2945,7 @@ pub fn trans_crate(sess: session::Session, } if ccx.sess.count_llvm_insns() { - for ccx.stats.llvm_insns.each |&k, &v| { + for ccx.stats.llvm_insns.iter().advance |(&k, &v)| { io::println(fmt!("%-7u %s", v, k)); } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 593d0beb88c7..cb4755506384 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -704,11 +704,11 @@ pub fn trans_args(cx: block, // now that all arguments have been successfully built, we can revoke any // temporary cleanups, as they are only needed if argument construction // should fail (for example, cleanup of copy mode args). - for vec::each(temp_cleanups) |c| { + for temp_cleanups.iter().advance |c| { revoke_clean(bcx, *c) } - return bcx; + bcx } pub enum AutorefArg { diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index f2446d1a1153..8cd776c99d69 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -213,7 +213,8 @@ pub fn type_needs_inner(cx: Context, ty::ty_enum(did, ref substs) => { if list::find(enums_seen, |id| *id == did).is_none() { let seen = @Cons(did, enums_seen); - for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) |v| { + let r = ty::enum_variants(cx.ccx.tcx, did); + for r.iter().advance |v| { for v.args.iter().advance |aty| { let t = ty::subst(cx.ccx.tcx, &(*substs), *aty); type_needs_inner(cx, use_, t, seen); diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index d9add22479cc..0aad161a6788 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1285,7 +1285,7 @@ impl RegionVarBindings { // It would be nice to write this using map(): let mut edges = vec::with_capacity(num_edges); - for self.constraints.each |constraint, span| { + for self.constraints.iter().advance |(constraint, span)| { edges.push(GraphEdge { next_edge: [uint::max_value, uint::max_value], constraint: *constraint, diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 20705b3d7975..ca49d143d480 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -166,7 +166,7 @@ Available lint options: padded(max_key, "name"), "default", "meaning")); io::println(fmt!(" %s %7.7s %s\n", padded(max_key, "----"), "-------", "-------")); - for lint_dict.each |k, v| { + for lint_dict.iter().advance |(k, v)| { let k = k.replace("_", "-"); io::println(fmt!(" %s %7.7s %s", padded(max_key, k), diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 91fde3e21ae0..f17777559deb 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -96,7 +96,7 @@ impl Program { code.push_str("fn main() {\n"); // It's easy to initialize things if we don't run things... - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { let mt = var.mt(); code.push_str(fmt!("let%s %s: %s = fail!();\n", mt, *name, var.ty)); var.alter(*name, &mut code); @@ -149,7 +149,7 @@ impl Program { // Using this __tls_map handle, deserialize each variable binding that // we know about - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { let mt = var.mt(); code.push_str(fmt!("let%s %s: %s = { let data = __tls_map.get_copy(&~\"%s\"); @@ -175,7 +175,7 @@ impl Program { // After the input code is run, we can re-serialize everything back out // into tls map (to be read later on by this task) - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { code.push_str(fmt!("{ let local: %s = %s; let bytes = do ::std::io::with_bytes_writer |io| { @@ -237,7 +237,7 @@ impl Program { /// program starts pub fn set_cache(&self) { let map = @mut HashMap::new(); - for self.local_vars.each |name, value| { + for self.local_vars.iter().advance |(name, value)| { map.insert(copy *name, @copy value.data); } unsafe { diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 962025915d24..bfa0f2fa124d 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -488,11 +488,6 @@ impl HashMap { } } - /// Visit all key-value pairs - pub fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - self.iter().advance(|(k, v)| blk(k, v)) - } - /// Visit all keys pub fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { self.iter().advance(|(k, _)| blk(k)) @@ -718,12 +713,6 @@ impl HashSet { self.map.contains_key_equiv(value) } - /// Visit all elements in arbitrary order - /// FIXME: #6978: Remove when all callers are converted - pub fn each(&self, f: &fn(&T) -> bool) -> bool { - self.iter().advance(f) - } - /// An iterator visiting all elements in arbitrary order. /// Iterator element type is &'a T. pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> { diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 77053f396779..04c0dd79deda 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -111,7 +111,7 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { assert!(was_present); } pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) -> bool { - tasks.each(|k| blk(*k)) + tasks.iter().advance(|k| blk(*k)) } // One of these per group of linked-failure tasks. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 72b583078496..2e18a588fae3 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -444,7 +444,7 @@ pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; - for each(v) |elt| { + for v.iter().advance |elt| { if f(elt) { lefts.push(copy *elt); } else { @@ -850,7 +850,7 @@ pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { /// Apply a function to each element of a vector and return the results pub fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(v.len()); - for each(v) |elem| { + for v.iter().advance |elem| { result.push(f(elem)); } result @@ -886,7 +886,7 @@ pub fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { */ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; - for each(v) |elem| { result.push_all_move(f(elem)); } + for v.iter().advance |elem| { result.push_all_move(f(elem)); } result } @@ -939,7 +939,7 @@ pub fn filter_mapped( */ let mut result = ~[]; - for each(v) |elem| { + for v.iter().advance |elem| { match f(elem) { None => {/* no-op */ } Some(result_elem) => { result.push(result_elem); } @@ -974,7 +974,7 @@ pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { */ pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; - for each(v) |elem| { + for v.iter().advance |elem| { if f(elem) { result.push(copy *elem); } } result @@ -1058,7 +1058,7 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { /// Return true if a vector contains an element with the given value pub fn contains(v: &[T], x: &T) -> bool { - for each(v) |elt| { if *x == *elt { return true; } } + for v.iter().advance |elt| { if *x == *elt { return true; } } false } @@ -1209,7 +1209,7 @@ pub fn bsearch_elem(v: &[T], x: &T) -> Option { */ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { let mut (ts, us) = (~[], ~[]); - for each(v) |p| { + for v.iter().advance |p| { let (t, u) = copy *p; ts.push(t); us.push(u); @@ -1347,69 +1347,6 @@ pub fn reversed(v: &const [T]) -> ~[T] { rs } -/** - * Iterates over a vector, yielding each element to a closure. - * - * # Arguments - * - * * `v` - A vector, to be iterated over - * * `f` - A closure to do the iterating. Within this closure, return true to - * * continue iterating, false to break. - * - * # Examples - * - * ~~~ {.rust} - * [1,2,3].each(|&i| { - * io::println(int::str(i)); - * true - * }); - * ~~~ - * - * ~~~ {.rust} - * [1,2,3,4,5].each(|&i| { - * if i < 4 { - * io::println(int::str(i)); - * true - * } - * else { - * false - * } - * }); - * ~~~ - * - * You probably will want to use each with a `for`/`do` expression, depending - * on your iteration needs: - * - * ~~~ {.rust} - * for [1,2,3].each |&i| { - * io::println(int::str(i)); - * } - * ~~~ - */ -#[inline] -pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { - // ^^^^ - // NB---this CANNOT be &const [T]! The reason - // is that you are passing it to `f()` using - // an immutable. - - let mut broke = false; - do as_imm_buf(v) |p, n| { - let mut n = n; - let mut p = p; - while n > 0u { - unsafe { - let q = cast::copy_lifetime_vec(v, &*p); - if !f(q) { break; } - p = ptr::offset(p, 1u); - } - n -= 1u; - } - broke = n > 0; - } - return !broke; -} - /** * Iterate over all permutations of vector `v`. * @@ -3069,36 +3006,6 @@ mod tests { assert_eq!(v, ~[1, 3, 5]); } - #[test] - fn test_each_empty() { - for each::([]) |_v| { - fail!(); // should never be executed - } - } - - #[test] - fn test_each_nonempty() { - let mut i = 0; - for each([1, 2, 3]) |v| { - i += *v; - } - assert_eq!(i, 6); - } - - #[test] - fn test_each_ret_len0() { - let a0 : [int, .. 0] = []; - assert_eq!(each(a0, |_p| fail!()), true); - } - - #[test] - fn test_each_ret_len1() { - let a1 = [17]; - assert_eq!(each(a1, |_p| true), true); - assert_eq!(each(a1, |_p| false), false); - } - - #[test] fn test_each_permutation() { let mut results: ~[~[int]]; @@ -3854,21 +3761,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_each_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do each(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - false - }; - } - #[test] #[ignore(windows)] #[should_fail] diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 14aa65219cd2..d21888f12ec6 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -86,7 +86,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { HashSet::new() }; - for vec::each(edges) |e| { + for edges.iter().advance |e| { match *e { (i, j) => { graph[i].insert(j); @@ -441,7 +441,7 @@ fn main() { let stop = time::precise_time_s(); let mut total_edges = 0; - vec::each(graph, |edges| { total_edges += edges.len(); true }); + for graph.iter().advance |edges| { total_edges += edges.len(); } io::stdout().write_line(fmt!("Generated graph with %? edges in %? seconds.", total_edges / 2, diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 7a9be7548849..102f7f170659 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -83,7 +83,7 @@ fn run(args: &[~str]) { server(&from_parent, &to_parent); } - for vec::each(worker_results) |r| { + for worker_results.iter().advance |r| { r.recv(); } diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 796072c84858..b8d91bb93e2e 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -79,7 +79,7 @@ fn run(args: &[~str]) { server(&from_parent, &to_parent); } - for vec::each(worker_results) |r| { + for worker_results.iter().advance |r| { r.recv(); } diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 3ff123b027ab..96c7e4e9b375 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -188,7 +188,7 @@ fn rendezvous(nn: uint, set: ~[color]) { // save each creature's meeting stats let mut report = ~[]; - for vec::each(to_creature) |_to_one| { + for to_creature.iter().advance |_to_one| { report.push(from_creatures_log.recv()); } @@ -196,7 +196,7 @@ fn rendezvous(nn: uint, set: ~[color]) { io::println(show_color_list(set)); // print each creature's stats - for vec::each(report) |rep| { + for report.iter().advance |rep| { io::println(*rep); } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index c33c2258864f..20042aa0e918 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -56,7 +56,7 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { let mut pairs = ~[]; // map -> [(k,%)] - for mm.each |&key, &val| { + for mm.iter().advance |(&key, &val)| { pairs.push((key, pct(val, total))); } diff --git a/src/test/compile-fail/block-must-not-have-result-for.rs b/src/test/compile-fail/block-must-not-have-result-for.rs index 778309122cba..1aa05a9477de 100644 --- a/src/test/compile-fail/block-must-not-have-result-for.rs +++ b/src/test/compile-fail/block-must-not-have-result-for.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn main() { - for vec::each(~[0]) |_i| { //~ ERROR A for-loop body must return (), but + for 2.times { //~ ERROR A for-loop body must return (), but true } } diff --git a/src/test/compile-fail/borrowck-insert-during-each.rs b/src/test/compile-fail/borrowck-insert-during-each.rs index 1a0bec7d723b..189a0ef9d700 100644 --- a/src/test/compile-fail/borrowck-insert-during-each.rs +++ b/src/test/compile-fail/borrowck-insert-during-each.rs @@ -16,7 +16,7 @@ struct Foo { impl Foo { pub fn foo(&mut self, fun: &fn(&int)) { - for self.n.each |f| { + for self.n.iter().advance |f| { fun(f); } } diff --git a/src/test/compile-fail/issue-2151.rs b/src/test/compile-fail/issue-2151.rs index 8f4bbe4eabc7..5559ba344ed1 100644 --- a/src/test/compile-fail/issue-2151.rs +++ b/src/test/compile-fail/issue-2151.rs @@ -8,10 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn main() { - for vec::each(fail!()) |i| { - let _ = i * 2; //~ ERROR the type of this value must be known - }; + let x = fail!(); + x.clone(); //~ ERROR the type of this value must be known in this context } diff --git a/src/test/compile-fail/liveness-issue-2163.rs b/src/test/compile-fail/liveness-issue-2163.rs index ec4f3f9a3fdb..fbb6d03b2200 100644 --- a/src/test/compile-fail/liveness-issue-2163.rs +++ b/src/test/compile-fail/liveness-issue-2163.rs @@ -12,7 +12,7 @@ use std::vec; fn main() { let a: ~[int] = ~[]; - vec::each(a, |_| -> bool { + a.iter().advance(|_| -> bool { //~^ ERROR mismatched types }); } diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index 5d2341ae42d3..b65b18e1ab3a 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -12,21 +12,19 @@ // making method calls, but only if there aren't any matches without // it. -use std::vec; - trait iterable { fn iterate(&self, blk: &fn(x: &A) -> bool) -> bool; } impl<'self,A> iterable for &'self [A] { fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { - vec::each(*self, f) + self.iter().advance(f) } } impl iterable for ~[A] { fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { - vec::each(*self, f) + self.iter().advance(f) } } diff --git a/src/test/run-pass/auto-loop.rs b/src/test/run-pass/auto-loop.rs index f148c509d4d0..185a5a6407c7 100644 --- a/src/test/run-pass/auto-loop.rs +++ b/src/test/run-pass/auto-loop.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - pub fn main() { let mut sum = 0; - for vec::each(~[1, 2, 3, 4, 5]) |x| { + let xs = ~[1, 2, 3, 4, 5]; + for xs.iter().advance |x| { sum += *x; } assert_eq!(sum, 15); diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index d860c84dfcec..ff5d0e9f05c6 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -15,7 +15,7 @@ pub fn main() { let v = ~[-1f, 0f, 1f, 2f, 3f]; // Statement form does not require parentheses: - for vec::each(v) |i| { + for v.iter().advance |i| { info!("%?", *i); } diff --git a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs index d63ebf7d24d4..8f74e6cdc299 100644 --- a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs +++ b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn want_slice(v: &[int]) -> int { let mut sum = 0; - for vec::each(v) |i| { sum += *i; } - return sum; + for v.iter().advance |i| { sum += *i; } + sum } fn has_mut_vec(v: ~[int]) -> int { diff --git a/src/test/run-pass/break.rs b/src/test/run-pass/break.rs index 2edb270762cc..85c6f90a742b 100644 --- a/src/test/run-pass/break.rs +++ b/src/test/run-pass/break.rs @@ -16,7 +16,8 @@ pub fn main() { assert_eq!(i, 10); loop { i += 1; if i == 20 { break; } } assert_eq!(i, 20); - for vec::each(~[1, 2, 3, 4, 5, 6]) |x| { + let xs = [1, 2, 3, 4, 5, 6]; + for xs.iter().advance |x| { if *x == 3 { break; } assert!((*x <= 3)); } i = 0; @@ -26,7 +27,8 @@ pub fn main() { i += 1; if i % 2 == 0 { loop; } assert!((i % 2 != 0)); if i >= 10 { break; } } - for vec::each(~[1, 2, 3, 4, 5, 6]) |x| { + let ys = ~[1, 2, 3, 4, 5, 6]; + for ys.iter().advance |x| { if *x % 2 == 0 { loop; } assert!((*x % 2 != 0)); } diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index 9fc68cd11275..a87d8f30e3ac 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -23,6 +23,6 @@ struct S<'self>(&'self fn()); static closures: &'static [S<'static>] = &[S(f), S(f)]; pub fn main() { - for std::vec::each(bare_fns) |&bare_fn| { bare_fn() } - for std::vec::each(closures) |&closure| { (*closure)() } + for bare_fns.iter().advance |&bare_fn| { bare_fn() } + for closures.iter().advance |&closure| { (*closure)() } } diff --git a/src/test/run-pass/for-destruct.rs b/src/test/run-pass/for-destruct.rs index 4926dbd00867..dd1cda22e653 100644 --- a/src/test/run-pass/for-destruct.rs +++ b/src/test/run-pass/for-destruct.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test: #3511: does not currently compile, due to rvalue issues + use std::vec; struct Pair { x: int, y: int } - pub fn main() { for vec::each(~[Pair {x: 10, y: 20}, Pair {x: 30, y: 0}]) |elt| { assert_eq!(elt.x + elt.y, 30); diff --git a/src/test/run-pass/rcvr-borrowed-to-slice.rs b/src/test/run-pass/rcvr-borrowed-to-slice.rs index 5eaf12f6a518..b62475ded54f 100644 --- a/src/test/run-pass/rcvr-borrowed-to-slice.rs +++ b/src/test/run-pass/rcvr-borrowed-to-slice.rs @@ -18,7 +18,7 @@ trait sum { impl<'self> sum for &'self [int] { fn sum(self) -> int { let mut sum = 0; - for vec::each(self) |e| { sum += *e; } + for self.iter().advance |e| { sum += *e; } return sum; } } diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index c25cdc85cb6a..dc6bdbf5c1a5 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -31,7 +31,10 @@ trait map { impl map for ~[T] { fn map(&self, f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for std::vec::each(*self) |x| { r += ~[f(x)]; } + // FIXME: #7355 generates bad code with Iterator + for std::uint::range(0, self.len()) |i| { + r += ~[f(&self[i])]; + } r } } From e44e33dfa999f4e3ce0b1811bc2ccdd5907b4a42 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 25 Jun 2013 16:31:17 -0400 Subject: [PATCH 139/336] xfail test hitting a codegen bug (issue #7385) --- src/test/run-pass/const-vec-of-fns.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index a87d8f30e3ac..45302363c380 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-fast +// xfail-test +// FIXME: #7385: hits a codegen bug on OS X x86_64 /*! * Try to double-check that static fns have the right size (with or From a616531ebbfa4403c024bcb895818980c33687e0 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Tue, 25 Jun 2013 20:25:56 -0400 Subject: [PATCH 140/336] Remove extra --- src/libsyntax/attr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 446641faf6ea..a1a0c7006288 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -10,7 +10,7 @@ // Functions dealing with attributes and meta_items -extern mod extra; +use extra; use ast; use codemap::{spanned, dummy_spanned}; From c109bed15b79c81fed4277abd0f4a71a221224c1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 25 Jun 2013 17:02:03 -0700 Subject: [PATCH 141/336] Deny common lints by default for lib{std,extra} --- mk/target.mk | 13 +++++++++++-- src/libextra/term.rs | 14 +++++++------- src/libstd/libc.rs | 2 +- src/libstd/os.rs | 21 ++++++++------------- src/libstd/rt/thread_local_storage.rs | 4 ++-- src/libstd/run.rs | 5 ++--- src/libstd/task/spawn.rs | 2 +- src/libstd/to_str.rs | 4 ++-- src/libstd/unstable/dynamic_lib.rs | 3 +-- 9 files changed, 35 insertions(+), 33 deletions(-) diff --git a/mk/target.mk b/mk/target.mk index 737b3b82c00d..47ab7c867282 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -13,6 +13,15 @@ # this exists can be found on issue #2400 export CFG_COMPILER_TRIPLE +# The standard libraries should be held up to a higher standard than any old +# code, make sure that these common warnings are denied by default. These can +# be overridden during development temporarily. For stage0, we allow all these +# to suppress warnings which may be bugs in stage0 (should be fixed in stage1+) +# NOTE: add "-A warnings" after snapshot to WFLAGS_ST0 +WFLAGS_ST0 = -A unrecognized-lint +WFLAGS_ST1 = -D warnings +WFLAGS_ST2 = -D warnings + # TARGET_STAGE_N template: This defines how target artifacts are built # for all stage/target architecture combinations. The arguments: # $(1) is the stage @@ -39,7 +48,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ | $$(TLIB$(1)_T_$(2)_H_$(3))/ @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \ $$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \ @@ -47,7 +56,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \ $$(TSREQ$(1)_T_$(2)_H_$(3)) \ | $$(TLIB$(1)_T_$(2)_H_$(3))/ @$$(call E, compile_and_link: $$@) - $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@ + $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \ $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \ diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 17d80ded47f8..782a73deadf9 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -15,12 +15,12 @@ use core::prelude::*; use core::io; -use core::os; -use terminfo::*; -use terminfo::searcher::open; -use terminfo::parser::compiled::parse; -use terminfo::parm::{expand, Number, Variables}; +#[cfg(not(target_os = "win32"))] use core::os; +#[cfg(not(target_os = "win32"))] use terminfo::*; +#[cfg(not(target_os = "win32"))] use terminfo::searcher::open; +#[cfg(not(target_os = "win32"))] use terminfo::parser::compiled::parse; +#[cfg(not(target_os = "win32"))] use terminfo::parm::{expand, Number, Variables}; // FIXME (#2807): Windows support. @@ -122,10 +122,10 @@ impl Terminal { return Ok(Terminal {out: out, color_supported: false}); } - pub fn fg(&self, color: u8) { + pub fn fg(&self, _color: u8) { } - pub fn bg(&self, color: u8) { + pub fn bg(&self, _color: u8) { } pub fn reset(&self) { diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 523645e69a52..3c2ae93b6563 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -568,7 +568,7 @@ pub mod types { pub mod os { pub mod common { pub mod posix01 { - use libc::types::os::arch::c95::{c_int, c_short}; + use libc::types::os::arch::c95::c_short; use libc::types::os::arch::extra::{int64, time64_t}; use libc::types::os::arch::posix88::{dev_t, ino_t}; use libc::types::os::arch::posix88::mode_t; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index e6b92c0ccc3f..112540c405da 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -33,9 +33,8 @@ use io; use iterator::IteratorUtil; use libc; use libc::{c_char, c_void, c_int, size_t}; -use libc::{mode_t, FILE}; +use libc::FILE; use local_data; -use option; use option::{Some, None}; use os; use prelude::*; @@ -181,7 +180,6 @@ pub fn env() -> ~[(~str,~str)] { unsafe { #[cfg(windows)] unsafe fn get_env_pairs() -> ~[~str] { - use libc::types::os::arch::extra::LPTCH; use libc::funcs::extra::kernel32::{ GetEnvironmentStringsA, FreeEnvironmentStringsA @@ -248,10 +246,10 @@ pub fn getenv(n: &str) -> Option<~str> { do with_env_lock { let s = str::as_c_str(n, |s| libc::getenv(s)); if ptr::null::() == cast::transmute(s) { - option::None::<~str> + None::<~str> } else { let s = cast::transmute(s); - option::Some::<~str>(str::raw::from_buf(s)) + Some::<~str>(str::raw::from_buf(s)) } } } @@ -540,7 +538,7 @@ pub fn homedir() -> Option { #[cfg(windows)] fn secondary() -> Option { - do getenv(~"USERPROFILE").chain |p| { + do getenv("USERPROFILE").chain |p| { if !p.is_empty() { Some(Path(p)) } else { @@ -647,9 +645,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { use os::win32::as_utf16_p; // FIXME: turn mode into something useful? #2623 do as_utf16_p(p.to_str()) |buf| { - libc::CreateDirectoryW(buf, unsafe { - cast::transmute(0) - }) + libc::CreateDirectoryW(buf, cast::transmute(0)) != (0 as libc::BOOL) } } @@ -659,7 +655,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { fn mkdir(p: &Path, mode: c_int) -> bool { unsafe { do as_c_charp(p.to_str()) |c| { - libc::mkdir(c, mode as mode_t) == (0 as c_int) + libc::mkdir(c, mode as libc::mode_t) == (0 as c_int) } } } @@ -732,7 +728,6 @@ pub fn list_dir(p: &Path) -> ~[~str] { } #[cfg(windows)] unsafe fn get_list(p: &Path) -> ~[~str] { - use libc::types::os::arch::extra::{LPCTSTR, HANDLE, BOOL}; use libc::consts::os::extra::INVALID_HANDLE_VALUE; use libc::wcslen; use libc::funcs::extra::kernel32::{ @@ -961,7 +956,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool { // Give the new file the old file's permissions if do str::as_c_str(to.to_str()) |to_buf| { - libc::chmod(to_buf, from_mode as mode_t) + libc::chmod(to_buf, from_mode as libc::mode_t) } != 0 { return false; // should be a condition... } @@ -1329,7 +1324,7 @@ pub fn glob(pattern: &str) -> ~[Path] { /// Returns a vector of Path objects that match the given glob pattern #[cfg(target_os = "win32")] -pub fn glob(pattern: &str) -> ~[Path] { +pub fn glob(_pattern: &str) -> ~[Path] { fail!("glob() is unimplemented on Windows") } diff --git a/src/libstd/rt/thread_local_storage.rs b/src/libstd/rt/thread_local_storage.rs index 7187d2db41ca..5041b559ecbf 100644 --- a/src/libstd/rt/thread_local_storage.rs +++ b/src/libstd/rt/thread_local_storage.rs @@ -60,13 +60,13 @@ pub type Key = DWORD; #[cfg(windows)] pub unsafe fn create(key: &mut Key) { static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; - *key = unsafe { TlsAlloc() }; + *key = TlsAlloc(); assert!(*key != TLS_OUT_OF_INDEXES); } #[cfg(windows)] pub unsafe fn set(key: Key, value: *mut c_void) { - unsafe { assert!(0 != TlsSetValue(key, value)) } + assert!(0 != TlsSetValue(key, value)) } #[cfg(windows)] diff --git a/src/libstd/run.rs b/src/libstd/run.rs index c965af7c10ce..32368312e159 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -12,11 +12,10 @@ #[allow(missing_doc)]; -use iterator::IteratorUtil; use cast; use comm::{stream, SharedChan, GenericChan, GenericPort}; -use int; use io; +use iterator::IteratorUtil; use libc::{pid_t, c_void, c_int}; use libc; use option::{Some, None}; @@ -465,7 +464,6 @@ fn spawn_process_os(prog: &str, args: &[~str], use libc::funcs::extra::msvcrt::get_osfhandle; use sys; - use uint; unsafe { @@ -638,6 +636,7 @@ fn spawn_process_os(prog: &str, args: &[~str], use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; use libc::funcs::bsd44::getdtablesize; + use int; mod rustrt { use libc::c_void; diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 77053f396779..94349c75af91 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -91,7 +91,7 @@ use uint; use util; use unstable::sync::{Exclusive, exclusive}; use rt::local::Local; -use iterator::{IteratorUtil}; +use iterator::IteratorUtil; #[cfg(test)] use task::default_task_opts; #[cfg(test)] use comm; diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index 4d5bc0f8842f..ea0e212b14f7 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -17,8 +17,8 @@ The `ToStr` trait for converting to strings use str::OwnedStr; use hashmap::HashMap; use hashmap::HashSet; -use iterator::IteratorUtil; use hash::Hash; +use iterator::IteratorUtil; use cmp::Eq; use vec::ImmutableVector; @@ -177,7 +177,7 @@ impl ToStr for @[A] { mod tests { use hashmap::HashMap; use hashmap::HashSet; - use container::{Set,Map}; + use container::{Set, Map}; #[test] fn test_simple_types() { assert_eq!(1i.to_str(), ~"1"); diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 64dd5bba6bcf..61793977e7a8 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -164,7 +164,6 @@ mod dl { use libc; use path; use ptr; - use str; use task; use result::*; @@ -175,7 +174,7 @@ mod dl { } pub unsafe fn open_internal() -> *libc::c_void { - let mut handle = ptr::null(); + let handle = ptr::null(); GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &handle as **libc::c_void); handle } From 7f61b31f5f7aed3e6a4582a8a792df8378e1c6f0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 25 Jun 2013 17:42:28 -0700 Subject: [PATCH 142/336] Stop passing --disable-threads to LLVM --- configure | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure b/configure index 1c658af9feed..d0a98fbfa75c 100755 --- a/configure +++ b/configure @@ -834,9 +834,7 @@ do LLVM_TARGET="--target=$t" # Disable unused LLVM features - LLVM_OPTS="$LLVM_DBG_OPTS --disable-docs \ - --enable-bindings=none --disable-threads \ - --disable-pthreads" + LLVM_OPTS="$LLVM_DBG_OPTS --disable-docs --enable-bindings=none" case "$CFG_C_COMPILER" in ("ccache clang") From ca2966c6d04958241f13e61310298a5ff69061e2 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 20 Jun 2013 21:06:13 -0400 Subject: [PATCH 143/336] Change finalize -> drop. --- doc/tutorial-ffi.md | 2 +- doc/tutorial.md | 6 +++--- src/etc/vim/syntax/rust.vim | 2 +- src/libextra/arc.rs | 2 +- src/libextra/arena.rs | 2 +- src/libextra/c_vec.rs | 2 +- src/libextra/future.rs | 2 +- src/libextra/net_tcp.rs | 2 +- src/libextra/rc.rs | 4 ++-- src/libextra/sort.rs | 2 +- src/libextra/sync.rs | 16 ++++++++-------- src/libextra/task_pool.rs | 2 +- src/librustc/back/passes.rs | 2 +- src/librustc/lib/llvm.rs | 8 ++++---- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/common.rs | 2 +- src/librustc/middle/trans/context.rs | 2 +- src/librustc/rustc.rs | 2 +- src/librustc/util/common.rs | 2 +- src/librustdoc/demo.rs | 2 +- src/libstd/condition.rs | 2 +- src/libstd/io.rs | 6 +++--- src/libstd/ops.rs | 2 +- src/libstd/option.rs | 2 +- src/libstd/pipes.rs | 6 +++--- src/libstd/rt/comm.rs | 4 ++-- src/libstd/rt/local_heap.rs | 2 +- src/libstd/rt/rc.rs | 2 +- src/libstd/rt/stack.rs | 2 +- src/libstd/rt/task.rs | 2 +- src/libstd/rt/thread.rs | 2 +- src/libstd/rt/uv/uvio.rs | 6 +++--- src/libstd/rt/uvio.rs | 6 +++--- src/libstd/run.rs | 2 +- src/libstd/task/spawn.rs | 4 ++-- src/libstd/unstable/atomics.rs | 2 +- src/libstd/unstable/dynamic_lib.rs | 2 +- src/libstd/unstable/finally.rs | 2 +- src/libstd/unstable/global.rs | 2 +- src/libstd/unstable/sync.rs | 4 ++-- src/libstd/util.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/test/auxiliary/issue-2526.rs | 4 ++-- src/test/auxiliary/issue-3012-1.rs | 2 +- src/test/auxiliary/issue2170lib.rs | 2 +- src/test/auxiliary/moves_based_on_type_lib.rs | 2 +- src/test/bench/task-perf-alloc-unwind.rs | 2 +- ...either-can-live-while-the-other-survives-1.rs | 2 +- ...either-can-live-while-the-other-survives-2.rs | 2 +- ...either-can-live-while-the-other-survives-3.rs | 2 +- ...either-can-live-while-the-other-survives-4.rs | 2 +- .../compile-fail/bind-by-move-no-lvalues-1.rs | 2 +- .../compile-fail/bind-by-move-no-lvalues-2.rs | 2 +- .../compile-fail/bind-by-move-no-sub-bindings.rs | 2 +- .../block-must-not-have-result-res.rs | 2 +- .../borrowck-borrowed-uniq-rvalue-2.rs | 2 +- src/test/compile-fail/copy-a-resource.rs | 2 +- ...owed-deconstructing-destructing-struct-let.rs | 2 +- ...ed-deconstructing-destructing-struct-match.rs | 2 +- src/test/compile-fail/drop-on-non-struct.rs | 2 +- src/test/compile-fail/explicit-call-to-dtor.rs | 4 ++-- .../explicit-call-to-supertrait-dtor.rs | 4 ++-- src/test/compile-fail/issue-2548.rs | 2 +- src/test/compile-fail/issue-2823.rs | 2 +- src/test/compile-fail/issue-3214.rs | 2 +- src/test/compile-fail/kindck-destructor-owned.rs | 2 +- src/test/compile-fail/no-send-res-ports.rs | 2 +- src/test/compile-fail/noncopyable-class.rs | 2 +- src/test/compile-fail/pinned-deep-copy.rs | 2 +- .../compile-fail/repeat-to-run-dtor-twice.rs | 2 +- .../compile-fail/unique-object-noncopyable.rs | 2 +- src/test/compile-fail/unique-pinned-nocopy.rs | 2 +- src/test/compile-fail/unique-vec-res.rs | 2 +- .../use-after-move-self-based-on-type.rs | 2 +- src/test/compile-fail/vec-res-add.rs | 2 +- src/test/run-fail/issue-2061.rs | 2 +- src/test/run-fail/morestack2.rs | 2 +- src/test/run-fail/morestack3.rs | 2 +- src/test/run-fail/morestack4.rs | 2 +- src/test/run-fail/rt-set-exit-status-fail2.rs | 2 +- .../run-fail/too-much-recursion-unwinding.rs | 2 +- src/test/run-fail/unwind-box-res.rs | 2 +- src/test/run-fail/unwind-resource-fail.rs | 2 +- src/test/run-fail/unwind-resource-fail2.rs | 2 +- src/test/run-fail/unwind-resource-fail3.rs | 2 +- src/test/run-pass/attr-no-drop-flag-size.rs | 2 +- src/test/run-pass/borrowck-unary-move-2.rs | 2 +- src/test/run-pass/class-attributes-1.rs | 2 +- src/test/run-pass/class-attributes-2.rs | 2 +- src/test/run-pass/class-dtor.rs | 2 +- src/test/run-pass/drop-trait-generic.rs | 2 +- src/test/run-pass/drop-trait.rs | 2 +- src/test/run-pass/init-res-into-things.rs | 2 +- src/test/run-pass/issue-2487-a.rs | 2 +- src/test/run-pass/issue-2708.rs | 2 +- src/test/run-pass/issue-2718.rs | 4 ++-- src/test/run-pass/issue-2735-2.rs | 2 +- src/test/run-pass/issue-2735-3.rs | 2 +- src/test/run-pass/issue-2895.rs | 2 +- src/test/run-pass/issue-3220.rs | 2 +- src/test/run-pass/issue-3563-3.rs | 2 +- src/test/run-pass/issue-4252.rs | 2 +- src/test/run-pass/issue-4735.rs | 2 +- src/test/run-pass/issue-6341.rs | 2 +- src/test/run-pass/issue-6344-let.rs | 2 +- src/test/run-pass/issue-6344-match.rs | 2 +- src/test/run-pass/issue-979.rs | 2 +- src/test/run-pass/newtype-struct-drop-run.rs | 2 +- src/test/run-pass/newtype-struct-with-dtor.rs | 2 +- src/test/run-pass/option-unwrap.rs | 2 +- src/test/run-pass/pipe-presentation-examples.rs | 2 +- src/test/run-pass/resource-assign-is-not-copy.rs | 2 +- src/test/run-pass/resource-cycle.rs | 2 +- src/test/run-pass/resource-cycle2.rs | 2 +- src/test/run-pass/resource-cycle3.rs | 2 +- src/test/run-pass/resource-destruct.rs | 2 +- src/test/run-pass/resource-generic.rs | 2 +- src/test/run-pass/resource-in-struct.rs | 2 +- src/test/run-pass/send-resource.rs | 2 +- src/test/run-pass/struct-literal-dtor.rs | 2 +- src/test/run-pass/task-killjoin-rsrc.rs | 2 +- src/test/run-pass/type-param-constraints.rs | 2 +- src/test/run-pass/unique-pinned-nocopy-2.rs | 2 +- src/test/run-pass/unit-like-struct-drop-run.rs | 2 +- src/test/run-pass/unwind-resource.rs | 2 +- src/test/run-pass/unwind-resource2.rs | 2 +- src/test/run-pass/vec-slice-drop.rs | 2 +- 127 files changed, 155 insertions(+), 155 deletions(-) diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index d3c682ce1adc..346112e655ba 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -183,7 +183,7 @@ impl Unique { #[unsafe_destructor] impl Drop for Unique { - fn finalize(&self) { + fn drop(&self) { unsafe { let x = intrinsics::init(); // dummy value to swap in // moving the object out is needed to call the destructor diff --git a/doc/tutorial.md b/doc/tutorial.md index 9c61a04930ac..c18cca8d5a22 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1979,7 +1979,7 @@ types by the compiler, and may not be overridden: > iterations of the language, and often still are. Additionally, the `Drop` trait is used to define destructors. This -trait defines one method called `finalize`, which is automatically +trait defines one method called `drop`, which is automatically called when a value of the type that implements this trait is destroyed, either because the value went out of scope or because the garbage collector reclaimed it. @@ -1990,7 +1990,7 @@ struct TimeBomb { } impl Drop for TimeBomb { - fn finalize(&self) { + fn drop(&self) { for self.explosivity.times { println("blam!"); } @@ -1998,7 +1998,7 @@ impl Drop for TimeBomb { } ~~~ -It is illegal to call `finalize` directly. Only code inserted by the compiler +It is illegal to call `drop` directly. Only code inserted by the compiler may call it. ## Declaring and implementing traits diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 625424ac8709..db64e0eb719b 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -15,7 +15,7 @@ syn keyword rustOperator as syn match rustAssert "\ (), option::Some(f) => f() diff --git a/src/libextra/future.rs b/src/libextra/future.rs index 4652e1d64770..19e4d221d330 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -44,7 +44,7 @@ pub struct Future { // over ~fn's that have pipes and so forth within! #[unsafe_destructor] impl Drop for Future { - fn finalize(&self) {} + fn drop(&self) {} } priv enum FutureState { diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index d44340121789..6ad51931c676 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -57,7 +57,7 @@ pub struct TcpSocket { #[unsafe_destructor] impl Drop for TcpSocket { - fn finalize(&self) { + fn drop(&self) { tear_down_socket_data(self.socket_data) } } diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 555cceb5b44b..8ef58a188d93 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -68,7 +68,7 @@ impl Rc { #[unsafe_destructor] impl Drop for Rc { - fn finalize(&self) { + fn drop(&self) { unsafe { if self.ptr.is_not_null() { (*self.ptr).count -= 1; @@ -220,7 +220,7 @@ impl RcMut { #[unsafe_destructor] impl Drop for RcMut { - fn finalize(&self) { + fn drop(&self) { unsafe { if self.ptr.is_not_null() { (*self.ptr).count -= 1; diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index ae2a5c01993d..3c872d64ca05 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -1207,7 +1207,7 @@ mod big_tests { #[unsafe_destructor] impl<'self> Drop for LVal<'self> { - fn finalize(&self) { + fn drop(&self) { let x = unsafe { local_data::local_data_get(self.key) }; match x { Some(@y) => { diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 6990d35f0613..63fde546047f 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -176,7 +176,7 @@ struct SemReleaseGeneric<'self, Q> { sem: &'self Sem } #[doc(hidden)] #[unsafe_destructor] impl<'self, Q:Owned> Drop for SemReleaseGeneric<'self, Q> { - fn finalize(&self) { + fn drop(&self) { self.sem.release(); } } @@ -219,7 +219,7 @@ pub struct Condvar<'self> { } #[unsafe_destructor] -impl<'self> Drop for Condvar<'self> { fn finalize(&self) {} } +impl<'self> Drop for Condvar<'self> { fn drop(&self) {} } impl<'self> Condvar<'self> { /** @@ -295,7 +295,7 @@ impl<'self> Condvar<'self> { #[unsafe_destructor] impl<'self> Drop for CondvarReacquire<'self> { - fn finalize(&self) { + fn drop(&self) { unsafe { // Needs to succeed, instead of itself dying. do task::unkillable { @@ -689,7 +689,7 @@ struct RWlockReleaseRead<'self> { #[doc(hidden)] #[unsafe_destructor] impl<'self> Drop for RWlockReleaseRead<'self> { - fn finalize(&self) { + fn drop(&self) { unsafe { do task::unkillable { let state = &mut *self.lock.state.get(); @@ -726,7 +726,7 @@ struct RWlockReleaseDowngrade<'self> { #[doc(hidden)] #[unsafe_destructor] impl<'self> Drop for RWlockReleaseDowngrade<'self> { - fn finalize(&self) { + fn drop(&self) { unsafe { do task::unkillable { let writer_or_last_reader; @@ -769,12 +769,12 @@ fn RWlockReleaseDowngrade<'r>(lock: &'r RWlock) /// The "write permission" token used for rwlock.write_downgrade(). pub struct RWlockWriteMode<'self> { priv lock: &'self RWlock } #[unsafe_destructor] -impl<'self> Drop for RWlockWriteMode<'self> { fn finalize(&self) {} } +impl<'self> Drop for RWlockWriteMode<'self> { fn drop(&self) {} } /// The "read permission" token used for rwlock.write_downgrade(). pub struct RWlockReadMode<'self> { priv lock: &'self RWlock } #[unsafe_destructor] -impl<'self> Drop for RWlockReadMode<'self> { fn finalize(&self) {} } +impl<'self> Drop for RWlockReadMode<'self> { fn drop(&self) {} } impl<'self> RWlockWriteMode<'self> { /// Access the pre-downgrade rwlock in write mode. @@ -1104,7 +1104,7 @@ mod tests { } impl Drop for SendOnFailure { - fn finalize(&self) { + fn drop(&self) { self.c.send(()); } } diff --git a/src/libextra/task_pool.rs b/src/libextra/task_pool.rs index 643081d4a7ad..6a715d7b481b 100644 --- a/src/libextra/task_pool.rs +++ b/src/libextra/task_pool.rs @@ -35,7 +35,7 @@ pub struct TaskPool { #[unsafe_destructor] impl Drop for TaskPool { - fn finalize(&self) { + fn drop(&self) { for self.channels.iter().advance |channel| { channel.send(Quit); } diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index 2c994fbc3fc1..fa261a977f59 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -23,7 +23,7 @@ pub struct PassManager { } impl Drop for PassManager { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposePassManager(self.llpm); } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 4bc96117ff51..d7f33dcf0d0a 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2216,7 +2216,7 @@ pub struct target_data_res { } impl Drop for target_data_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeTargetData(self.TD); } @@ -2253,7 +2253,7 @@ pub struct pass_manager_res { } impl Drop for pass_manager_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposePassManager(self.PM); } @@ -2289,7 +2289,7 @@ pub struct object_file_res { } impl Drop for object_file_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeObjectFile(self.ObjectFile); } @@ -2326,7 +2326,7 @@ pub struct section_iter_res { } impl Drop for section_iter_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeSectionIterator(self.SI); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0e322c187af2..6b826a9b9404 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -110,7 +110,7 @@ pub struct _InsnCtxt { _x: () } #[unsafe_destructor] impl Drop for _InsnCtxt { - fn finalize(&self) { + fn drop(&self) { unsafe { do local_data::local_data_modify(task_local_insn_key) |c| { do c.map_consume |@ctx| { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 7baa3ec068b8..442ab475046f 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -110,7 +110,7 @@ pub struct BuilderRef_res { } impl Drop for BuilderRef_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeBuilder(self.B); } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 715b1c88327f..57cfb1474dfe 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -241,7 +241,7 @@ impl CrateContext { #[unsafe_destructor] impl Drop for CrateContext { - fn finalize(&self) { + fn drop(&self) { unsafe { unset_task_llcx(); } diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 20705b3d7975..899dc85bb8a9 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -328,7 +328,7 @@ pub fn monitor(f: ~fn(diagnostic::Emitter)) { } impl Drop for finally { - fn finalize(&self) { self.ch.send(done); } + fn drop(&self) { self.ch.send(done); } } let _finally = finally { ch: ch }; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 0839c2b963b4..351519975adf 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -41,7 +41,7 @@ pub struct _indenter { } impl Drop for _indenter { - fn finalize(&self) { debug!("<<"); } + fn drop(&self) { debug!("<<"); } } pub fn _indenter(_i: ()) -> _indenter { diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs index c5fb8f289f65..9cac958a113f 100644 --- a/src/librustdoc/demo.rs +++ b/src/librustdoc/demo.rs @@ -128,7 +128,7 @@ struct Bored { } impl Drop for Bored { - fn finalize(&self) { } + fn drop(&self) { } } /** diff --git a/src/libstd/condition.rs b/src/libstd/condition.rs index 2f150a0d1b28..04f2d815d081 100644 --- a/src/libstd/condition.rs +++ b/src/libstd/condition.rs @@ -90,7 +90,7 @@ struct Guard<'self, T, U> { #[unsafe_destructor] impl<'self, T, U> Drop for Guard<'self, T, U> { - fn finalize(&self) { + fn drop(&self) { unsafe { debug!("Guard: popping handler from TLS"); let curr = local_data_pop(self.cond.key); diff --git a/src/libstd/io.rs b/src/libstd/io.rs index fc0b4da79bd8..71a0dd6b9b2a 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -989,7 +989,7 @@ impl FILERes { } impl Drop for FILERes { - fn finalize(&self) { + fn drop(&self) { unsafe { libc::fclose(self.f); } @@ -1234,7 +1234,7 @@ impl FdRes { } impl Drop for FdRes { - fn finalize(&self) { + fn drop(&self) { unsafe { libc::close(self.fd); } @@ -1772,7 +1772,7 @@ pub mod fsync { #[unsafe_destructor] impl Drop for Res { - fn finalize(&self) { + fn drop(&self) { match self.arg.opt_level { None => (), Some(level) => { diff --git a/src/libstd/ops.rs b/src/libstd/ops.rs index 77cfe62e4952..020131ab119e 100644 --- a/src/libstd/ops.rs +++ b/src/libstd/ops.rs @@ -14,7 +14,7 @@ #[lang="drop"] pub trait Drop { - fn finalize(&self); // FIXME(#4332): Rename to "drop"? --pcwalton + fn drop(&self); } #[lang="add"] diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 88a66249c961..f3ea81f1ae56 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -416,7 +416,7 @@ fn test_unwrap_resource() { #[unsafe_destructor] impl ::ops::Drop for R { - fn finalize(&self) { *(self.i) += 1; } + fn drop(&self) { *(self.i) += 1; } } fn R(i: @mut int) -> R { diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 26dd4af45d6c..661dc2a659f7 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -309,7 +309,7 @@ struct BufferResource { #[unsafe_destructor] impl Drop for BufferResource { - fn finalize(&self) { + fn drop(&self) { unsafe { // FIXME(#4330) Need self by value to get mutability. let this: &mut BufferResource = transmute_mut(self); @@ -672,7 +672,7 @@ pub struct SendPacketBuffered { #[unsafe_destructor] impl Drop for SendPacketBuffered { - fn finalize(&self) { + fn drop(&self) { unsafe { let this: &mut SendPacketBuffered = transmute(self); if this.p != None { @@ -730,7 +730,7 @@ pub struct RecvPacketBuffered { #[unsafe_destructor] impl Drop for RecvPacketBuffered { - fn finalize(&self) { + fn drop(&self) { unsafe { let this: &mut RecvPacketBuffered = transmute(self); if this.p != None { diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 5d85e2928613..75b1d8f38103 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -222,7 +222,7 @@ impl Peekable for PortOne { #[unsafe_destructor] impl Drop for ChanOneHack { - fn finalize(&self) { + fn drop(&self) { if self.suppress_finalize { return } unsafe { @@ -249,7 +249,7 @@ impl Drop for ChanOneHack { #[unsafe_destructor] impl Drop for PortOneHack { - fn finalize(&self) { + fn drop(&self) { if self.suppress_finalize { return } unsafe { diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 6bf228a1b220..c5c22f451593 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -57,7 +57,7 @@ impl LocalHeap { } impl Drop for LocalHeap { - fn finalize(&self) { + fn drop(&self) { unsafe { rust_delete_boxed_region(self.boxed_region); rust_delete_memory_region(self.memory_region); diff --git a/src/libstd/rt/rc.rs b/src/libstd/rt/rc.rs index 2977d0815081..18a5dd4a1145 100644 --- a/src/libstd/rt/rc.rs +++ b/src/libstd/rt/rc.rs @@ -74,7 +74,7 @@ impl RC { #[unsafe_destructor] impl Drop for RC { - fn finalize(&self) { + fn drop(&self) { assert!(self.refcount() > 0); unsafe { diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs index b0e87a62c8b7..fbb516b2df40 100644 --- a/src/libstd/rt/stack.rs +++ b/src/libstd/rt/stack.rs @@ -49,7 +49,7 @@ impl StackSegment { } impl Drop for StackSegment { - fn finalize(&self) { + fn drop(&self) { unsafe { // XXX: Using the FFI to call a C macro. Slow rust_valgrind_stack_deregister(self.valgrind_id); diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 41390aec80c5..f5f5aca71f55 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -103,7 +103,7 @@ impl Task { } impl Drop for Task { - fn finalize(&self) { assert!(self.destroyed) } + fn drop(&self) { assert!(self.destroyed) } } // Just a sanity check to make sure we are catching a Rust-thrown exception diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs index bc2901913107..98d08c060e02 100644 --- a/src/libstd/rt/thread.rs +++ b/src/libstd/rt/thread.rs @@ -33,7 +33,7 @@ impl Thread { } impl Drop for Thread { - fn finalize(&self) { + fn drop(&self) { unsafe { rust_raw_thread_join_delete(self.raw_thread) } } } diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs index 964ee460c1d2..15c405bae695 100644 --- a/src/libstd/rt/uv/uvio.rs +++ b/src/libstd/rt/uv/uvio.rs @@ -47,7 +47,7 @@ impl UvEventLoop { } impl Drop for UvEventLoop { - fn finalize(&self) { + fn drop(&self) { // XXX: Need mutable finalizer let this = unsafe { transmute::<&UvEventLoop, &mut UvEventLoop>(self) @@ -200,7 +200,7 @@ impl UvTcpListener { } impl Drop for UvTcpListener { - fn finalize(&self) { + fn drop(&self) { let watcher = self.watcher(); let scheduler = Local::take::(); do scheduler.deschedule_running_task_and_then |task| { @@ -261,7 +261,7 @@ impl UvTcpStream { } impl Drop for UvTcpStream { - fn finalize(&self) { + fn drop(&self) { rtdebug!("closing tcp stream"); let watcher = self.watcher(); let scheduler = Local::take::(); diff --git a/src/libstd/rt/uvio.rs b/src/libstd/rt/uvio.rs index f4a79934e7e4..0187ad3abf51 100644 --- a/src/libstd/rt/uvio.rs +++ b/src/libstd/rt/uvio.rs @@ -42,7 +42,7 @@ impl UvEventLoop { } impl Drop for UvEventLoop { - fn finalize(&self) { + fn drop(&self) { // XXX: Need mutable finalizer let this = unsafe { transmute::<&UvEventLoop, &mut UvEventLoop>(self) @@ -164,7 +164,7 @@ impl UvTcpListener { } impl Drop for UvTcpListener { - fn finalize(&self) { + fn drop(&self) { // XXX: Again, this never gets called. Use .close() instead //self.watcher().as_stream().close(||()); } @@ -230,7 +230,7 @@ impl UvStream { } impl Drop for UvStream { - fn finalize(&self) { + fn drop(&self) { rtdebug!("closing stream"); //self.watcher().close(||()); } diff --git a/src/libstd/run.rs b/src/libstd/run.rs index c965af7c10ce..08bb7ee72814 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -428,7 +428,7 @@ impl Process { } impl Drop for Process { - fn finalize(&self) { + fn drop(&self) { // FIXME(#4330) Need self by value to get mutability. let mut_self: &mut Process = unsafe { cast::transmute(self) }; diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 77053f396779..f0e3bda34ea4 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -317,7 +317,7 @@ struct TCB { impl Drop for TCB { // Runs on task exit. - fn finalize(&self) { + fn drop(&self) { unsafe { // FIXME(#4330) Need self by value to get mutability. let this: &mut TCB = transmute(self); @@ -372,7 +372,7 @@ struct AutoNotify { } impl Drop for AutoNotify { - fn finalize(&self) { + fn drop(&self) { let result = if self.failed { Failure } else { Success }; self.notify_chan.send(result); } diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index 7a3a5f51d356..45eced9846ce 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -276,7 +276,7 @@ impl AtomicOption { #[unsafe_destructor] impl Drop for AtomicOption { - fn finalize(&self) { + fn drop(&self) { // This will ensure that the contained data is // destroyed, unless it's null. unsafe { diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 64dd5bba6bcf..9ea353969155 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -25,7 +25,7 @@ use result::*; pub struct DynamicLibrary { priv handle: *libc::c_void } impl Drop for DynamicLibrary { - fn finalize(&self) { + fn drop(&self) { match do dl::check_for_errors_in { unsafe { dl::close(self.handle) diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs index b15bceddb1c2..10db664450eb 100644 --- a/src/libstd/unstable/finally.rs +++ b/src/libstd/unstable/finally.rs @@ -64,7 +64,7 @@ struct Finallyalizer<'self> { #[unsafe_destructor] impl<'self> Drop for Finallyalizer<'self> { - fn finalize(&self) { + fn drop(&self) { (self.dtor)(); } } diff --git a/src/libstd/unstable/global.rs b/src/libstd/unstable/global.rs index f81252274c49..4fde8f704b98 100644 --- a/src/libstd/unstable/global.rs +++ b/src/libstd/unstable/global.rs @@ -147,7 +147,7 @@ struct GlobalState { } impl Drop for GlobalState { - fn finalize(&self) { + fn drop(&self) { for self.map.each_value |v| { match v { &(_, ref dtor) => (*dtor)() diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index 235dfa018493..0f9298595eec 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -75,7 +75,7 @@ impl Clone for UnsafeAtomicRcBox { #[unsafe_destructor] impl Drop for UnsafeAtomicRcBox{ - fn finalize(&self) { + fn drop(&self) { unsafe { do task::unkillable { let mut data: ~AtomicRcBoxData = cast::transmute(self.data); @@ -102,7 +102,7 @@ struct LittleLock { } impl Drop for LittleLock { - fn finalize(&self) { + fn drop(&self) { unsafe { rust_destroy_little_lock(self.l); } diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 2a5d44c9ce26..6eddae17ce6f 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -83,7 +83,7 @@ impl NonCopyable { } impl Drop for NonCopyable { - fn finalize(&self) { } + fn drop(&self) { } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d8aab1f68eea..d8829da3b31b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -268,7 +268,7 @@ pub struct Parser { #[unsafe_destructor] impl Drop for Parser { /* do not copy the parser; its state is tied to outside state */ - fn finalize(&self) {} + fn drop(&self) {} } impl Parser { diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index bbc0f1ad3e55..d4f6a1ec4040 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -21,7 +21,7 @@ struct arc_destruct { #[unsafe_destructor] impl Drop for arc_destruct { - fn finalize(&self) {} + fn drop(&self) {} } fn arc_destruct(data: int) -> arc_destruct { @@ -45,7 +45,7 @@ struct context_res { } impl Drop for context_res { - fn finalize(&self) {} + fn drop(&self) {} } fn context_res() -> context_res { diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/auxiliary/issue-3012-1.rs index ce40afff3ae3..9c9b3d9f2434 100644 --- a/src/test/auxiliary/issue-3012-1.rs +++ b/src/test/auxiliary/issue-3012-1.rs @@ -19,7 +19,7 @@ pub mod socket { } impl Drop for socket_handle { - fn finalize(&self) { + fn drop(&self) { /* c::close(self.sockfd); */ } } diff --git a/src/test/auxiliary/issue2170lib.rs b/src/test/auxiliary/issue2170lib.rs index 0690a0174494..ec5d8baf2590 100644 --- a/src/test/auxiliary/issue2170lib.rs +++ b/src/test/auxiliary/issue2170lib.rs @@ -16,7 +16,7 @@ pub struct rsrc { } impl Drop for rsrc { - fn finalize(&self) { + fn drop(&self) { foo(self.x); } } diff --git a/src/test/auxiliary/moves_based_on_type_lib.rs b/src/test/auxiliary/moves_based_on_type_lib.rs index b3a9b3e1ee9a..cd72468511ea 100644 --- a/src/test/auxiliary/moves_based_on_type_lib.rs +++ b/src/test/auxiliary/moves_based_on_type_lib.rs @@ -15,7 +15,7 @@ pub struct S { } impl Drop for S { - fn finalize(&self) { + fn drop(&self) { println("goodbye"); } } diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 7a04a06d6a64..e245ab894f5b 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -60,7 +60,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) {} + fn drop(&self) {} } fn r(l: @nillist) -> r { diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs index e9bc4a5e195d..6353d7c6581b 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -11,7 +11,7 @@ struct X { x: () } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs index 6548adddf195..6ea5f85797f1 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs @@ -11,7 +11,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs index aaa9d9f920a6..8f0642896f1e 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs @@ -11,7 +11,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs index b5686b64c810..859bf7bd26d9 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs @@ -11,7 +11,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs index c8537afa1905..3f96d568a55c 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs @@ -13,7 +13,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs index 26b1084c0917..c17a444ce6e9 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs @@ -13,7 +13,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs index c86158be5ea7..a1243dd01d9f 100644 --- a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs +++ b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs @@ -11,7 +11,7 @@ struct X { x: (), } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/block-must-not-have-result-res.rs b/src/test/compile-fail/block-must-not-have-result-res.rs index 8b8bb04c08b5..c9b627f55f80 100644 --- a/src/test/compile-fail/block-must-not-have-result-res.rs +++ b/src/test/compile-fail/block-must-not-have-result-res.rs @@ -13,7 +13,7 @@ struct r; impl Drop for r { - fn finalize(&self) { + fn drop(&self) { true } } diff --git a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs index 1e5c4c5cc410..98099360f3c7 100644 --- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs +++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs @@ -14,7 +14,7 @@ struct defer<'self> { #[unsafe_destructor] impl<'self> Drop for defer<'self> { - fn finalize(&self) { + fn drop(&self) { unsafe { error!("%?", self.x); } diff --git a/src/test/compile-fail/copy-a-resource.rs b/src/test/compile-fail/copy-a-resource.rs index 2767447d8193..f709ddc0e0d2 100644 --- a/src/test/compile-fail/copy-a-resource.rs +++ b/src/test/compile-fail/copy-a-resource.rs @@ -13,7 +13,7 @@ struct foo { } impl Drop for foo { - fn finalize(&self) {} + fn drop(&self) {} } fn foo(i:int) -> foo { diff --git a/src/test/compile-fail/disallowed-deconstructing-destructing-struct-let.rs b/src/test/compile-fail/disallowed-deconstructing-destructing-struct-let.rs index c363f172d2f4..e550475d64f0 100644 --- a/src/test/compile-fail/disallowed-deconstructing-destructing-struct-let.rs +++ b/src/test/compile-fail/disallowed-deconstructing-destructing-struct-let.rs @@ -14,7 +14,7 @@ struct X { } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("value: %s", self.x); } } diff --git a/src/test/compile-fail/disallowed-deconstructing-destructing-struct-match.rs b/src/test/compile-fail/disallowed-deconstructing-destructing-struct-match.rs index 478a56c03010..748114a4f12f 100644 --- a/src/test/compile-fail/disallowed-deconstructing-destructing-struct-match.rs +++ b/src/test/compile-fail/disallowed-deconstructing-destructing-struct-match.rs @@ -13,7 +13,7 @@ struct X { } impl Drop for X { - fn finalize(&self) { + fn drop(&self) { error!("value: %s", self.x); } } diff --git a/src/test/compile-fail/drop-on-non-struct.rs b/src/test/compile-fail/drop-on-non-struct.rs index 5e422d267538..2eb58d496123 100644 --- a/src/test/compile-fail/drop-on-non-struct.rs +++ b/src/test/compile-fail/drop-on-non-struct.rs @@ -12,7 +12,7 @@ type Foo = @[u8]; impl Drop for Foo { //~ ERROR the Drop trait may only be implemented //~^ ERROR cannot provide an extension implementation - fn finalize(&self) { + fn drop(&self) { println("kaboom"); } } diff --git a/src/test/compile-fail/explicit-call-to-dtor.rs b/src/test/compile-fail/explicit-call-to-dtor.rs index ce2942c3146c..5ffc9ea08eda 100644 --- a/src/test/compile-fail/explicit-call-to-dtor.rs +++ b/src/test/compile-fail/explicit-call-to-dtor.rs @@ -13,12 +13,12 @@ struct Foo { } impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { println("kaboom"); } } fn main() { let x = Foo { x: 3 }; - x.finalize(); //~ ERROR explicit call to destructor + x.drop(); //~ ERROR explicit call to destructor } diff --git a/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs b/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs index 1a5eb696fa2e..ace31183d76a 100644 --- a/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs +++ b/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs @@ -17,14 +17,14 @@ trait Bar : Drop { } impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { println("kaboom"); } } impl Bar for Foo { fn blah(&self) { - self.finalize(); //~ ERROR explicit call to destructor + self.drop(); //~ ERROR explicit call to destructor } } diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs index 2f6900084406..314f282355db 100644 --- a/src/test/compile-fail/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -18,7 +18,7 @@ struct foo { #[unsafe_destructor] impl Drop for foo { - fn finalize(&self) { + fn drop(&self) { unsafe { println("Goodbye, World!"); *self.x += 1; diff --git a/src/test/compile-fail/issue-2823.rs b/src/test/compile-fail/issue-2823.rs index b29b19b406f0..7d1f64b9dd2d 100644 --- a/src/test/compile-fail/issue-2823.rs +++ b/src/test/compile-fail/issue-2823.rs @@ -13,7 +13,7 @@ struct C { } impl Drop for C { - fn finalize(&self) { + fn drop(&self) { error!("dropping: %?", self.x); } } diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs index 2dd58906ddb7..8eb110e6ce9b 100644 --- a/src/test/compile-fail/issue-3214.rs +++ b/src/test/compile-fail/issue-3214.rs @@ -15,7 +15,7 @@ fn foo() { } impl Drop for foo { - fn finalize(&self) {} + fn drop(&self) {} } } fn main() { } diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs index faad36a15d2f..551b50c94f24 100644 --- a/src/test/compile-fail/kindck-destructor-owned.rs +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -3,7 +3,7 @@ struct Foo { } impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Owned - fn finalize(&self) { + fn drop(&self) { *self.f = 10; } } diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 5e18a40a99c8..1f5b600157f2 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -20,7 +20,7 @@ fn main() { #[unsafe_destructor] impl Drop for foo { - fn finalize(&self) {} + fn drop(&self) {} } fn foo(x: Port<()>) -> foo { diff --git a/src/test/compile-fail/noncopyable-class.rs b/src/test/compile-fail/noncopyable-class.rs index 77e62497d078..aa7100f0aad5 100644 --- a/src/test/compile-fail/noncopyable-class.rs +++ b/src/test/compile-fail/noncopyable-class.rs @@ -15,7 +15,7 @@ struct bar { } impl Drop for bar { - fn finalize(&self) {} + fn drop(&self) {} } fn bar(x:int) -> bar { diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index 17e23360a5bb..2e48992e81e8 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -14,7 +14,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) = *(self.i) + 1; } diff --git a/src/test/compile-fail/repeat-to-run-dtor-twice.rs b/src/test/compile-fail/repeat-to-run-dtor-twice.rs index 0dd12822dfae..c997ce2a2815 100644 --- a/src/test/compile-fail/repeat-to-run-dtor-twice.rs +++ b/src/test/compile-fail/repeat-to-run-dtor-twice.rs @@ -17,7 +17,7 @@ struct Foo { } impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { println("Goodbye!"); } } diff --git a/src/test/compile-fail/unique-object-noncopyable.rs b/src/test/compile-fail/unique-object-noncopyable.rs index 3844dab726e6..dacfd4660401 100644 --- a/src/test/compile-fail/unique-object-noncopyable.rs +++ b/src/test/compile-fail/unique-object-noncopyable.rs @@ -17,7 +17,7 @@ struct Bar { } impl Drop for Bar { - fn finalize(&self) {} + fn drop(&self) {} } impl Foo for Bar { diff --git a/src/test/compile-fail/unique-pinned-nocopy.rs b/src/test/compile-fail/unique-pinned-nocopy.rs index a08f03d5628c..1deb850741e9 100644 --- a/src/test/compile-fail/unique-pinned-nocopy.rs +++ b/src/test/compile-fail/unique-pinned-nocopy.rs @@ -13,7 +13,7 @@ struct r { } impl Drop for r { - fn finalize(&self) {} + fn drop(&self) {} } fn main() { diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 003e8ccf3095..e231e5e50377 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -14,7 +14,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) = *(self.i) + 1; } diff --git a/src/test/compile-fail/use-after-move-self-based-on-type.rs b/src/test/compile-fail/use-after-move-self-based-on-type.rs index 5b4d67fb0cef..0622c028c631 100644 --- a/src/test/compile-fail/use-after-move-self-based-on-type.rs +++ b/src/test/compile-fail/use-after-move-self-based-on-type.rs @@ -3,7 +3,7 @@ struct S { } impl Drop for S { - fn finalize(&self) {} + fn drop(&self) {} } impl S { diff --git a/src/test/compile-fail/vec-res-add.rs b/src/test/compile-fail/vec-res-add.rs index 938e8c41e793..d881750bd3c2 100644 --- a/src/test/compile-fail/vec-res-add.rs +++ b/src/test/compile-fail/vec-res-add.rs @@ -17,7 +17,7 @@ struct r { fn r(i:int) -> r { r { i: i } } impl Drop for r { - fn finalize(&self) {} + fn drop(&self) {} } fn main() { diff --git a/src/test/run-fail/issue-2061.rs b/src/test/run-fail/issue-2061.rs index cee3546acfa8..3e78fd1f7db5 100644 --- a/src/test/run-fail/issue-2061.rs +++ b/src/test/run-fail/issue-2061.rs @@ -15,7 +15,7 @@ struct R { } impl Drop for R { - fn finalize(&self) { + fn drop(&self) { let _y = R { b: self.b }; } } diff --git a/src/test/run-fail/morestack2.rs b/src/test/run-fail/morestack2.rs index d03433d58725..37bc3b6de8ac 100644 --- a/src/test/run-fail/morestack2.rs +++ b/src/test/run-fail/morestack2.rs @@ -44,7 +44,7 @@ struct and_then_get_big_again { } impl Drop for and_then_get_big_again { - fn finalize(&self) { + fn drop(&self) { fn getbig(i: int) { if i != 0 { getbig(i - 1); diff --git a/src/test/run-fail/morestack3.rs b/src/test/run-fail/morestack3.rs index d2e17d285617..4e059c5bd3c3 100644 --- a/src/test/run-fail/morestack3.rs +++ b/src/test/run-fail/morestack3.rs @@ -30,7 +30,7 @@ struct and_then_get_big_again { } impl Drop for and_then_get_big_again { - fn finalize(&self) { + fn drop(&self) { fn getbig(i: int) { if i != 0 { getbig(i - 1); diff --git a/src/test/run-fail/morestack4.rs b/src/test/run-fail/morestack4.rs index c4f7de495556..db46438ea3c0 100644 --- a/src/test/run-fail/morestack4.rs +++ b/src/test/run-fail/morestack4.rs @@ -30,7 +30,7 @@ struct and_then_get_big_again { } impl Drop for and_then_get_big_again { - fn finalize(&self) {} + fn drop(&self) {} } fn and_then_get_big_again(x:int) -> and_then_get_big_again { diff --git a/src/test/run-fail/rt-set-exit-status-fail2.rs b/src/test/run-fail/rt-set-exit-status-fail2.rs index 3d0341d01f4b..ee268f409a5e 100644 --- a/src/test/run-fail/rt-set-exit-status-fail2.rs +++ b/src/test/run-fail/rt-set-exit-status-fail2.rs @@ -21,7 +21,7 @@ struct r { // failed has no effect and the process exits with the // runtime's exit code impl Drop for r { - fn finalize(&self) { + fn drop(&self) { os::set_exit_status(50); } } diff --git a/src/test/run-fail/too-much-recursion-unwinding.rs b/src/test/run-fail/too-much-recursion-unwinding.rs index 1c668dfc90d4..16d0fe346687 100644 --- a/src/test/run-fail/too-much-recursion-unwinding.rs +++ b/src/test/run-fail/too-much-recursion-unwinding.rs @@ -24,7 +24,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { if !*(self.recursed) { *(self.recursed) = true; diff --git a/src/test/run-fail/unwind-box-res.rs b/src/test/run-fail/unwind-box-res.rs index a1e1ee433bb6..7f022d5761c2 100644 --- a/src/test/run-fail/unwind-box-res.rs +++ b/src/test/run-fail/unwind-box-res.rs @@ -21,7 +21,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { let _v2: ~int = cast::transmute(self.v); } diff --git a/src/test/run-fail/unwind-resource-fail.rs b/src/test/run-fail/unwind-resource-fail.rs index 486c2dd3b36a..b4b0150013a5 100644 --- a/src/test/run-fail/unwind-resource-fail.rs +++ b/src/test/run-fail/unwind-resource-fail.rs @@ -15,7 +15,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { fail!("squirrel") } + fn drop(&self) { fail!("squirrel") } } fn r(i: int) -> r { r { i: i } } diff --git a/src/test/run-fail/unwind-resource-fail2.rs b/src/test/run-fail/unwind-resource-fail2.rs index ca98a61f2345..6ebb4a742c43 100644 --- a/src/test/run-fail/unwind-resource-fail2.rs +++ b/src/test/run-fail/unwind-resource-fail2.rs @@ -16,7 +16,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { fail!("wombat") } + fn drop(&self) { fail!("wombat") } } fn r(i: int) -> r { r { i: i } } diff --git a/src/test/run-fail/unwind-resource-fail3.rs b/src/test/run-fail/unwind-resource-fail3.rs index 9d6f877293b1..2de9d4cec77e 100644 --- a/src/test/run-fail/unwind-resource-fail3.rs +++ b/src/test/run-fail/unwind-resource-fail3.rs @@ -19,7 +19,7 @@ fn faily_box(i: @int) -> faily_box { faily_box { i: i } } #[unsafe_destructor] impl Drop for faily_box { - fn finalize(&self) { + fn drop(&self) { fail!("quux"); } } diff --git a/src/test/run-pass/attr-no-drop-flag-size.rs b/src/test/run-pass/attr-no-drop-flag-size.rs index e6f05970cced..00a7955d834c 100644 --- a/src/test/run-pass/attr-no-drop-flag-size.rs +++ b/src/test/run-pass/attr-no-drop-flag-size.rs @@ -17,7 +17,7 @@ struct Test { #[unsafe_destructor] impl Drop for Test { - fn finalize(&self) { } + fn drop(&self) { } } fn main() { diff --git a/src/test/run-pass/borrowck-unary-move-2.rs b/src/test/run-pass/borrowck-unary-move-2.rs index c74fd4a68e71..c52371de54af 100644 --- a/src/test/run-pass/borrowck-unary-move-2.rs +++ b/src/test/run-pass/borrowck-unary-move-2.rs @@ -13,7 +13,7 @@ struct noncopyable { } impl Drop for noncopyable { - fn finalize(&self) { + fn drop(&self) { error!("dropped"); } } diff --git a/src/test/run-pass/class-attributes-1.rs b/src/test/run-pass/class-attributes-1.rs index b7ecb622e7fe..108ae023e12a 100644 --- a/src/test/run-pass/class-attributes-1.rs +++ b/src/test/run-pass/class-attributes-1.rs @@ -16,7 +16,7 @@ struct cat { impl Drop for cat { #[cat_dropper] - fn finalize(&self) { error!("%s landed on hir feet" , self . name); } + fn drop(&self) { error!("%s landed on hir feet" , self . name); } } diff --git a/src/test/run-pass/class-attributes-2.rs b/src/test/run-pass/class-attributes-2.rs index 8636699c4825..02279677276f 100644 --- a/src/test/run-pass/class-attributes-2.rs +++ b/src/test/run-pass/class-attributes-2.rs @@ -17,7 +17,7 @@ impl Drop for cat { /** Actually, cats don't always land on their feet when you drop them. */ - fn finalize(&self) { + fn drop(&self) { error!("%s landed on hir feet", self.name); } } diff --git a/src/test/run-pass/class-dtor.rs b/src/test/run-pass/class-dtor.rs index 229c683706df..c294670faa3d 100644 --- a/src/test/run-pass/class-dtor.rs +++ b/src/test/run-pass/class-dtor.rs @@ -14,7 +14,7 @@ struct cat { } impl Drop for cat { - fn finalize(&self) { + fn drop(&self) { (self.done)(self.meows); } } diff --git a/src/test/run-pass/drop-trait-generic.rs b/src/test/run-pass/drop-trait-generic.rs index 894c387b036f..557a153bce23 100644 --- a/src/test/run-pass/drop-trait-generic.rs +++ b/src/test/run-pass/drop-trait-generic.rs @@ -14,7 +14,7 @@ struct S { #[unsafe_destructor] impl ::std::ops::Drop for S { - fn finalize(&self) { + fn drop(&self) { println("bye"); } } diff --git a/src/test/run-pass/drop-trait.rs b/src/test/run-pass/drop-trait.rs index 258a0f88ab52..0ed5a27eb194 100644 --- a/src/test/run-pass/drop-trait.rs +++ b/src/test/run-pass/drop-trait.rs @@ -13,7 +13,7 @@ struct Foo { } impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { println("bye"); } } diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs index 5e10419da6e7..cad6661bbce1 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/run-pass/init-res-into-things.rs @@ -19,7 +19,7 @@ struct Box { x: r } #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) = *(self.i) + 1; } diff --git a/src/test/run-pass/issue-2487-a.rs b/src/test/run-pass/issue-2487-a.rs index 5e5fb70bcd4a..0f9f1102aeac 100644 --- a/src/test/run-pass/issue-2487-a.rs +++ b/src/test/run-pass/issue-2487-a.rs @@ -14,7 +14,7 @@ struct socket { } impl Drop for socket { - fn finalize(&self) {} + fn drop(&self) {} } impl socket { diff --git a/src/test/run-pass/issue-2708.rs b/src/test/run-pass/issue-2708.rs index 9e8438efad57..44ace16fb95e 100644 --- a/src/test/run-pass/issue-2708.rs +++ b/src/test/run-pass/issue-2708.rs @@ -16,7 +16,7 @@ struct Font { } impl Drop for Font { - fn finalize(&self) {} + fn drop(&self) {} } fn Font() -> Font { diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 014aebeff9da..9fbca7d05720 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -160,7 +160,7 @@ pub mod pipes { #[unsafe_destructor] impl Drop for send_packet { - fn finalize(&self) { + fn drop(&self) { unsafe { if self.p != None { let self_p: &mut Option<*packet> = @@ -190,7 +190,7 @@ pub mod pipes { #[unsafe_destructor] impl Drop for recv_packet { - fn finalize(&self) { + fn drop(&self) { unsafe { if self.p != None { let self_p: &mut Option<*packet> = diff --git a/src/test/run-pass/issue-2735-2.rs b/src/test/run-pass/issue-2735-2.rs index ca584e1a6e3b..b44d50921a5e 100644 --- a/src/test/run-pass/issue-2735-2.rs +++ b/src/test/run-pass/issue-2735-2.rs @@ -15,7 +15,7 @@ struct defer { #[unsafe_destructor] impl Drop for defer { - fn finalize(&self) { + fn drop(&self) { *self.b = true; } } diff --git a/src/test/run-pass/issue-2735-3.rs b/src/test/run-pass/issue-2735-3.rs index 44ca5d6929bd..902b2f69d614 100644 --- a/src/test/run-pass/issue-2735-3.rs +++ b/src/test/run-pass/issue-2735-3.rs @@ -15,7 +15,7 @@ struct defer { #[unsafe_destructor] impl Drop for defer { - fn finalize(&self) { + fn drop(&self) { *self.b = true; } } diff --git a/src/test/run-pass/issue-2895.rs b/src/test/run-pass/issue-2895.rs index e6b3f9f6f359..a80a079b6951 100644 --- a/src/test/run-pass/issue-2895.rs +++ b/src/test/run-pass/issue-2895.rs @@ -19,7 +19,7 @@ struct Kitty { } impl Drop for Kitty { - fn finalize(&self) {} + fn drop(&self) {} } #[cfg(target_arch = "x86_64")] diff --git a/src/test/run-pass/issue-3220.rs b/src/test/run-pass/issue-3220.rs index 9cc5e5910435..dce6d8f0bf10 100644 --- a/src/test/run-pass/issue-3220.rs +++ b/src/test/run-pass/issue-3220.rs @@ -11,7 +11,7 @@ struct thing { x: int, } impl Drop for thing { - fn finalize(&self) {} + fn drop(&self) {} } fn thing() -> thing { diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 012e70988ad1..e574502a9fb7 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -58,7 +58,7 @@ struct AsciiArt { } impl Drop for AsciiArt { - fn finalize(&self) {} + fn drop(&self) {} } // It's common to define a constructor sort of function to create struct instances. diff --git a/src/test/run-pass/issue-4252.rs b/src/test/run-pass/issue-4252.rs index f3b73c847147..de1f630a245b 100644 --- a/src/test/run-pass/issue-4252.rs +++ b/src/test/run-pass/issue-4252.rs @@ -26,7 +26,7 @@ impl X for Y { } impl Drop for Z { - fn finalize(&self) { + fn drop(&self) { self.x.call(); // Adding this statement causes an ICE. } } diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs index 057622d22517..3da90ba1edcb 100644 --- a/src/test/run-pass/issue-4735.rs +++ b/src/test/run-pass/issue-4735.rs @@ -15,7 +15,7 @@ use std::libc::c_void; struct NonCopyable(*c_void); impl Drop for NonCopyable { - fn finalize(&self) { + fn drop(&self) { let p = **self; let v = unsafe { transmute::<*c_void, ~int>(p) }; } diff --git a/src/test/run-pass/issue-6341.rs b/src/test/run-pass/issue-6341.rs index 394345556fcf..29fc07443058 100644 --- a/src/test/run-pass/issue-6341.rs +++ b/src/test/run-pass/issue-6341.rs @@ -12,7 +12,7 @@ struct A { x: uint } impl Drop for A { - fn finalize(&self) {} + fn drop(&self) {} } fn main() {} \ No newline at end of file diff --git a/src/test/run-pass/issue-6344-let.rs b/src/test/run-pass/issue-6344-let.rs index 916131b6b711..bb0c71d6d55c 100644 --- a/src/test/run-pass/issue-6344-let.rs +++ b/src/test/run-pass/issue-6344-let.rs @@ -11,7 +11,7 @@ struct A { x: uint } impl Drop for A { - fn finalize(&self) {} + fn drop(&self) {} } fn main() { diff --git a/src/test/run-pass/issue-6344-match.rs b/src/test/run-pass/issue-6344-match.rs index 5bf57aa71169..7987f9689fae 100644 --- a/src/test/run-pass/issue-6344-match.rs +++ b/src/test/run-pass/issue-6344-match.rs @@ -10,7 +10,7 @@ struct A { x: uint } impl Drop for A { - fn finalize(&self) {} + fn drop(&self) {} } fn main() { diff --git a/src/test/run-pass/issue-979.rs b/src/test/run-pass/issue-979.rs index 20bb8ea965ba..34a9055ae834 100644 --- a/src/test/run-pass/issue-979.rs +++ b/src/test/run-pass/issue-979.rs @@ -14,7 +14,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.b) += 1; } diff --git a/src/test/run-pass/newtype-struct-drop-run.rs b/src/test/run-pass/newtype-struct-drop-run.rs index dd5da3b09bb6..b7fdfabff9ab 100644 --- a/src/test/run-pass/newtype-struct-drop-run.rs +++ b/src/test/run-pass/newtype-struct-drop-run.rs @@ -14,7 +14,7 @@ struct Foo(@mut int); #[unsafe_destructor] impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { ***self = 23; } } diff --git a/src/test/run-pass/newtype-struct-with-dtor.rs b/src/test/run-pass/newtype-struct-with-dtor.rs index 0e36f27aa929..6062f3075e20 100644 --- a/src/test/run-pass/newtype-struct-with-dtor.rs +++ b/src/test/run-pass/newtype-struct-with-dtor.rs @@ -4,7 +4,7 @@ use std::libc; pub struct Fd(c_int); impl Drop for Fd { - fn finalize(&self) { + fn drop(&self) { unsafe { libc::close(**self); } diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index ea8a6f236cd1..5c8cfd68240f 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -15,7 +15,7 @@ struct dtor { #[unsafe_destructor] impl Drop for dtor { - fn finalize(&self) { + fn drop(&self) { // abuse access to shared mutable state to write this code unsafe { *self.x -= 1; diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs index 54cf8ba9c0ac..65e0537dfb70 100644 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ b/src/test/run-pass/pipe-presentation-examples.rs @@ -85,7 +85,7 @@ pub struct Buffer { } impl Drop for Buffer { - fn finalize(&self) {} + fn drop(&self) {} } proto! double_buffer ( diff --git a/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/run-pass/resource-assign-is-not-copy.rs index edd692196ecd..112c6be560d6 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/run-pass/resource-assign-is-not-copy.rs @@ -14,7 +14,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) += 1; } diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index 3ce5ea66781f..e48b841144a7 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -17,7 +17,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { debug!("r's dtor: self = %x, self.v = %x, self.v's value = %x", cast::transmute::<*r, uint>(self), diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs index 0f031424ad4a..1a82e321bd7c 100644 --- a/src/test/run-pass/resource-cycle2.rs +++ b/src/test/run-pass/resource-cycle2.rs @@ -23,7 +23,7 @@ struct r { } impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { let v2: ~int = cast::transmute(self.v.c); } diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs index f3ca932778a8..1e0d8447aeb5 100644 --- a/src/test/run-pass/resource-cycle3.rs +++ b/src/test/run-pass/resource-cycle3.rs @@ -27,7 +27,7 @@ struct R { } impl Drop for R { - fn finalize(&self) { + fn drop(&self) { unsafe { let _v2: ~int = cast::transmute(self.v.c); // let _v3: ~int = cast::transmute_copy(self.x); diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs index c240c6708a4a..7eac25535a8c 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/run-pass/resource-destruct.rs @@ -14,7 +14,7 @@ struct shrinky_pointer { #[unsafe_destructor] impl Drop for shrinky_pointer { - fn finalize(&self) { + fn drop(&self) { unsafe { error!(~"Hello!"); **(self.i) -= 1; } diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index 7a18cd02c2de..75d978b0d052 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -18,7 +18,7 @@ struct finish { #[unsafe_destructor] impl Drop for finish { - fn finalize(&self) { + fn drop(&self) { unsafe { (self.arg.fin)(copy self.arg.val); } diff --git a/src/test/run-pass/resource-in-struct.rs b/src/test/run-pass/resource-in-struct.rs index d74ec61d3c07..836b49f9a152 100644 --- a/src/test/run-pass/resource-in-struct.rs +++ b/src/test/run-pass/resource-in-struct.rs @@ -20,7 +20,7 @@ struct close_res { #[unsafe_destructor] impl Drop for close_res { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) = false; } diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs index a2cee0082b5e..e450e1f48c01 100644 --- a/src/test/run-pass/send-resource.rs +++ b/src/test/run-pass/send-resource.rs @@ -16,7 +16,7 @@ struct test { } impl Drop for test { - fn finalize(&self) {} + fn drop(&self) {} } fn test(f: int) -> test { diff --git a/src/test/run-pass/struct-literal-dtor.rs b/src/test/run-pass/struct-literal-dtor.rs index 9f5b8cf27dd4..2fc6833242f2 100644 --- a/src/test/run-pass/struct-literal-dtor.rs +++ b/src/test/run-pass/struct-literal-dtor.rs @@ -13,7 +13,7 @@ struct foo { } impl Drop for foo { - fn finalize(&self) { + fn drop(&self) { error!("%s", self.x); } } diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 2025a5c304c8..aa37f5e9ce9b 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -24,7 +24,7 @@ struct notify { #[unsafe_destructor] impl Drop for notify { - fn finalize(&self) { + fn drop(&self) { unsafe { error!("notify: task=%? v=%x unwinding=%b b=%b", task::get_task(), diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs index bd6165806c27..416e7bf82bb8 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/run-pass/type-param-constraints.rs @@ -19,7 +19,7 @@ struct r { } impl Drop for r { - fn finalize(&self) {} + fn drop(&self) {} } fn r(i:int) -> r { diff --git a/src/test/run-pass/unique-pinned-nocopy-2.rs b/src/test/run-pass/unique-pinned-nocopy-2.rs index 197f26f897d8..b0ad7f50420a 100644 --- a/src/test/run-pass/unique-pinned-nocopy-2.rs +++ b/src/test/run-pass/unique-pinned-nocopy-2.rs @@ -14,7 +14,7 @@ struct r { #[unsafe_destructor] impl Drop for r { - fn finalize(&self) { + fn drop(&self) { unsafe { *(self.i) = *(self.i) + 1; } diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs index b19a0aa1e98a..41b971d64d02 100644 --- a/src/test/run-pass/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/unit-like-struct-drop-run.rs @@ -16,7 +16,7 @@ use std::task; struct Foo; impl Drop for Foo { - fn finalize(&self) { + fn drop(&self) { fail!("This failure should happen."); } } diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs index 4b71d79ccc4f..450e81bee33d 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/run-pass/unwind-resource.rs @@ -19,7 +19,7 @@ struct complainer { } impl Drop for complainer { - fn finalize(&self) { + fn drop(&self) { error!("About to send!"); self.c.send(true); error!("Sent!"); diff --git a/src/test/run-pass/unwind-resource2.rs b/src/test/run-pass/unwind-resource2.rs index b5a496eb2061..841fb37d29d5 100644 --- a/src/test/run-pass/unwind-resource2.rs +++ b/src/test/run-pass/unwind-resource2.rs @@ -19,7 +19,7 @@ struct complainer { #[unsafe_destructor] impl Drop for complainer { - fn finalize(&self) {} + fn drop(&self) {} } fn complainer(c: @int) -> complainer { diff --git a/src/test/run-pass/vec-slice-drop.rs b/src/test/run-pass/vec-slice-drop.rs index 695441daf285..54626e52d23e 100644 --- a/src/test/run-pass/vec-slice-drop.rs +++ b/src/test/run-pass/vec-slice-drop.rs @@ -15,7 +15,7 @@ struct foo { #[unsafe_destructor] impl Drop for foo { - fn finalize(&self) { + fn drop(&self) { unsafe { *self.x += 1; } From 6a772731045bc6bf0ffe4d75fd5522c0d073d14e Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Wed, 26 Jun 2013 10:25:12 +0900 Subject: [PATCH 144/336] rt: add android dummy functions for mman related --- src/rt/rust_android_dummy.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/rt/rust_android_dummy.cpp b/src/rt/rust_android_dummy.cpp index 437893594a56..add7af8a6e32 100644 --- a/src/rt/rust_android_dummy.cpp +++ b/src/rt/rust_android_dummy.cpp @@ -83,4 +83,29 @@ extern "C" int pthread_atfork(void (*prefork)(void), return 0; } +extern "C" int mlockall(int flags) +{ + return 0; +} + +extern "C" int munlockall(void) +{ + return 0; +} + +extern "C" int shm_open(const char *name, int oflag, mode_t mode) +{ + return 0; +} + +extern "C" int shm_unlink(const char *name) +{ + return 0; +} + +extern "C" int posix_madvise(void *addr, size_t len, int advice) +{ + return 0; +} + #endif From 3789433b4f588301140c97bb5b67094a8c8576cc Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 25 Jun 2013 22:26:22 -0700 Subject: [PATCH 145/336] rustpkg: Begin allowing package scripts to call the default build logic rustpkg/api.rs provides functions intended for package scripts to call. It will probably need more functionality added to it later, but this is a start. Added a test case checking that a package script can use the API. Closes #6401 --- src/librustc/driver/driver.rs | 2 +- src/librustpkg/api.rs | 92 +++++++++++++++++++ src/librustpkg/rustpkg.rs | 31 ++++--- src/librustpkg/tests.rs | 16 ++++ .../src/fancy-lib/{fancy-lib.rs => lib.rs} | 0 .../testsuite/pass/src/fancy-lib/pkg.rs | 40 ++++++-- src/librustpkg/util.rs | 7 +- 7 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 src/librustpkg/api.rs rename src/librustpkg/testsuite/pass/src/fancy-lib/{fancy-lib.rs => lib.rs} (100%) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index fbb273450df2..88134b9ea3d6 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -161,7 +161,7 @@ pub struct compile_upto { #[deriving(Eq)] pub enum compile_phase { cu_parse, - cu_expand, + cu_expand, // means "it's already expanded" cu_typeck, cu_no_trans, cu_everything, diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs new file mode 100644 index 000000000000..9f8e925fa075 --- /dev/null +++ b/src/librustpkg/api.rs @@ -0,0 +1,92 @@ +// 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. + +use context::*; +use crate::*; +use package_id::*; +use package_source::*; +use version::Version; + +use core::option::*; +use core::os; +use core::hashmap::*; +use core::path::*; + +/// Convenience functions intended for calling from pkg.rs + +fn default_ctxt(p: @Path) -> Ctx { + Ctx { sysroot_opt: Some(p), json: false, dep_cache: @mut HashMap::new() } +} + +pub fn build_lib(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version, + lib: Path) { + + let pkg_src = PkgSrc { + root: root, + dst_dir: dest, + id: PkgId{ version: version, ..PkgId::new(name)}, + libs: ~[mk_crate(lib)], + mains: ~[], + tests: ~[], + benchs: ~[] + }; + pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]); +} + +pub fn build_exe(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version, + main: Path) { + let pkg_src = PkgSrc { + root: root, + dst_dir: dest, + id: PkgId{ version: version, ..PkgId::new(name)}, + libs: ~[], + mains: ~[mk_crate(main)], + tests: ~[], + benchs: ~[] + }; + pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]); + +} + +pub fn install_lib(sysroot: @Path, + workspace: Path, + name: ~str, + lib_path: Path, + version: Version) { + debug!("self_exe: %?", os::self_exe_path()); + debug!("sysroot = %s", sysroot.to_str()); + debug!("workspace = %s", workspace.to_str()); + // make a PkgSrc + let pkg_id = PkgId{ version: version, ..PkgId::new(name)}; + let build_dir = workspace.push("build"); + let dst_dir = build_dir.push_rel(&*pkg_id.local_path); + let pkg_src = PkgSrc { + root: copy workspace, + dst_dir: copy dst_dir, + id: copy pkg_id, + libs: ~[mk_crate(lib_path)], + mains: ~[], + tests: ~[], + benchs: ~[] + }; + let cx = default_ctxt(sysroot); + pkg_src.build(&cx, dst_dir, ~[]); + cx.install_no_build(&workspace, &pkg_id); +} + +pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) { + default_ctxt(sysroot).install(&workspace, &PkgId{ version: version, + ..PkgId::new(name)}); + +} + +fn mk_crate(p: Path) -> Crate { + Crate { file: p, flags: ~[], cfgs: ~[] } +} \ No newline at end of file diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 9242e450e249..d70428e73385 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -46,6 +46,7 @@ use context::Ctx; use package_id::PkgId; use package_source::PkgSrc; +pub mod api; mod conditions; mod context; mod crate; @@ -104,8 +105,10 @@ impl<'self> PkgScript<'self> { let binary = os::args()[0].to_managed(); // Build the rustc session data structures to pass // to the compiler + debug!("pkgscript parse: %?", os::self_exe_path()); let options = @session::options { binary: binary, + maybe_sysroot: Some(@os::self_exe_path().get().pop()), crate_type: session::bin_crate, .. copy *session::basic_options() }; @@ -132,8 +135,7 @@ impl<'self> PkgScript<'self> { /// Returns a pair of an exit code and list of configs (obtained by /// calling the package script's configs() function if it exists // FIXME (#4432): Use workcache to only compile the script when changed - fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) { - debug!("run_custom: %s", what); + fn run_custom(&self, sysroot: @Path) -> (~[~str], ExitCode) { let sess = self.sess; debug!("Working directory = %s", self.build_dir.to_str()); @@ -152,9 +154,12 @@ impl<'self> PkgScript<'self> { sess, crate, driver::build_configuration(sess, - binary, &self.input)); - debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what); - let status = run::process_status(exe.to_str(), [root.to_str(), what]); + binary, &self.input), + driver::cu_parse); + debug!("Running program: %s %s %s %s", exe.to_str(), + sysroot.to_str(), root.to_str(), "install"); + // FIXME #7401 should support commands besides `install` + let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]); if status != 0 { return (~[], status); } @@ -291,10 +296,8 @@ impl Ctx { let pscript = PkgScript::parse(package_script_path, workspace, pkgid); - // Limited right now -- we're only running the post_build - // hook and probably fail otherwise - // also post_build should be called pre_build - let (cfgs, hook_result) = pscript.run_custom(~"post_build"); + let sysroot = self.sysroot_opt.expect("custom build needs a sysroot"); + let (cfgs, hook_result) = pscript.run_custom(sysroot); debug!("Command return code = %?", hook_result); if hook_result != 0 { fail!("Error running custom build command") @@ -341,13 +344,17 @@ impl Ctx { } fn install(&self, workspace: &Path, id: &PkgId) { - use conditions::copy_failed::cond; - - // Should use RUST_PATH in the future. + // FIXME #7402: Use RUST_PATH to determine target dir // Also should use workcache to not build if not necessary. self.build(workspace, id); debug!("install: workspace = %s, id = %s", workspace.to_str(), id.to_str()); + self.install_no_build(workspace, id); + + } + + fn install_no_build(&self, workspace: &Path, id: &PkgId) { + use conditions::copy_failed::cond; // Now copy stuff into the install dirs let maybe_executable = built_executable_in_workspace(id, workspace); diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 973b960008be..65c9c67f3f5f 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -546,6 +546,22 @@ fn rustpkg_local_pkg() { assert_executable_exists(&dir, "foo"); } +#[test] +fn package_script_with_default_build() { + let dir = create_local_package(&PkgId::new("fancy-lib")); + debug!("dir = %s", dir.to_str()); + let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg"). + push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs"); + debug!("package_script_with_default_build: %s", source.to_str()); + if !os::copy_file(&source, + & dir.push("src").push("fancy_lib-0.1").push("pkg.rs")) { + fail!("Couldn't copy file"); + } + command_line_test([~"install", ~"fancy-lib"], &dir); + assert_lib_exists(&dir, "fancy-lib"); + assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs"))); +} + #[test] #[ignore (reason = "RUST_PATH not yet implemented -- #5682")] fn rust_path_test() { diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/fancy-lib.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs similarity index 100% rename from src/librustpkg/testsuite/pass/src/fancy-lib/fancy-lib.rs rename to src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs index 2d3a75d9197b..009f37c8a49e 100644 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs +++ b/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs @@ -8,12 +8,37 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::run; +extern mod rustpkg; +extern mod rustc; + +use std::{io, os}; +use rustpkg::api; +use rustpkg::version::NoVersion; + +use rustc::metadata::filesearch; pub fn main() { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + let args = os::args(); - let out_path = Path(~"build/fancy_lib"); +// by convention, first arg is sysroot + if args.len() < 2 { + fail!("Package script requires a directory where rustc libraries live as the first \ + argument"); + } + + let sysroot_arg = copy args[1]; + let sysroot = Path(sysroot_arg); + if !os::path_exists(&sysroot) { + fail!("Package script requires a sysroot that exists; %s doesn't", sysroot.to_str()); + } + + if args[2] != ~"install" { + io::println(fmt!("Warning: I don't know how to %s", args[2])); + return; + } + + let out_path = Path("build/fancy_lib"); if !os::path_exists(&out_path) { assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); } @@ -22,7 +47,10 @@ pub fn main() { [io::Create]).get(); file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }"); - // now compile the crate itself - run::process_status("rustc", [~"src/fancy-lib/fancy-lib.rs", ~"--lib", ~"-o", - out_path.push(~"fancy_lib").to_str()]); + + debug!("api_____install_____lib, my sysroot:"); + debug!(sysroot.to_str()); + + api::install_lib(@sysroot, os::getcwd(), ~"fancy-lib", Path("lib.rs"), + NoVersion); } \ No newline at end of file diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 6d39495002a4..92cc5bbd2c1d 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -257,7 +257,7 @@ pub fn compile_input(ctxt: &Ctx, debug!("calling compile_crate_from_input, out_dir = %s, building_library = %?", out_dir.to_str(), sess.building_library); - compile_crate_from_input(&input, out_dir, sess, crate, copy cfg); + compile_crate_from_input(&input, out_dir, sess, crate, copy cfg, driver::cu_expand); true } @@ -270,7 +270,8 @@ pub fn compile_crate_from_input(input: &driver::input, build_dir: &Path, sess: session::Session, crate: @ast::crate, - cfg: ast::crate_cfg) { + cfg: ast::crate_cfg, + compile_from: driver::compile_phase) { debug!("Calling build_output_filenames with %s, building library? %?", build_dir.to_str(), sess.building_library); @@ -287,7 +288,7 @@ pub fn compile_crate_from_input(input: &driver::input, driver::compile_rest(sess, cfg, compile_upto { - from: driver::cu_expand, + from: compile_from, to: driver::cu_everything }, Some(outputs), From 73e3dbf9c082659d9f7aa9281ef4af4080ed019d Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 22 Jun 2013 13:20:00 +1000 Subject: [PATCH 146/336] driver: perform stripping before and after macro expansion. This allows macros to both be conditionally defined, and expand to items with #[cfg]'s. --- src/librustc/driver/driver.rs | 13 +++++++++- src/test/run-pass/cfg-macros-foo.rs | 35 ++++++++++++++++++++++++++ src/test/run-pass/cfg-macros-notfoo.rs | 35 ++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/cfg-macros-foo.rs create mode 100644 src/test/run-pass/cfg-macros-notfoo.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index fbb273450df2..f6b05711c13d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -188,11 +188,22 @@ pub fn compile_rest(sess: Session, *sess.building_library = session::building_library( sess.opts.crate_type, crate_opt.unwrap(), sess.opts.test); + // strip before expansion to allow macros to depend on + // configuration variables e.g/ in + // + // #[macro_escape] #[cfg(foo)] + // mod bar { macro_rules! baz!(() => {{}}) } + // + // baz! should not use this definition unless foo is enabled. + crate_opt = Some(time(time_passes, ~"configuration 1", || + front::config::strip_unconfigured_items(crate_opt.unwrap()))); + crate_opt = Some(time(time_passes, ~"expansion", || syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg, crate_opt.unwrap()))); - crate_opt = Some(time(time_passes, ~"configuration", || + // strip again, in case expansion added anything with a #[cfg]. + crate_opt = Some(time(time_passes, ~"configuration 2", || front::config::strip_unconfigured_items(crate_opt.unwrap()))); crate_opt = Some(time(time_passes, ~"maybe building test harness", || diff --git a/src/test/run-pass/cfg-macros-foo.rs b/src/test/run-pass/cfg-macros-foo.rs new file mode 100644 index 000000000000..8dfb7190c218 --- /dev/null +++ b/src/test/run-pass/cfg-macros-foo.rs @@ -0,0 +1,35 @@ +// 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-fast compile-flags directive doesn't work for check-fast +// compile-flags: --cfg foo + +// check that cfg correctly chooses between the macro impls (see also +// cfg-macros-notfoo.rs) + +#[cfg(foo)] +#[macro_escape] +mod foo { + macro_rules! bar { + () => { true } + } +} + +#[cfg(not(foo))] +#[macro_escape] +mod foo { + macro_rules! bar { + () => { false } + } +} + +fn main() { + assert!(bar!()) +} diff --git a/src/test/run-pass/cfg-macros-notfoo.rs b/src/test/run-pass/cfg-macros-notfoo.rs new file mode 100644 index 000000000000..8ede6eff2dd5 --- /dev/null +++ b/src/test/run-pass/cfg-macros-notfoo.rs @@ -0,0 +1,35 @@ +// 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-fast compile-flags directive doesn't work for check-fast +// compile-flags: + +// check that cfg correctly chooses between the macro impls (see also +// cfg-macros-foo.rs) + +#[cfg(foo)] +#[macro_escape] +mod foo { + macro_rules! bar { + () => { true } + } +} + +#[cfg(not(foo))] +#[macro_escape] +mod foo { + macro_rules! bar { + () => { false } + } +} + +fn main() { + assert!(!bar!()) +} From 8edb8f6d39498476f1124ce1bb5bb4e094bde43f Mon Sep 17 00:00:00 2001 From: gifnksm Date: Thu, 27 Jun 2013 06:51:04 +0900 Subject: [PATCH 147/336] iterator: Add `IteratorUtil::max_by/min_by` method --- src/libstd/iterator.rs | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index ab433a9a79d0..9e434272198a 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -351,6 +351,26 @@ pub trait IteratorUtil { /// Count the number of elements satisfying the specified predicate fn count(&mut self, predicate: &fn(A) -> bool) -> uint; + + /// Return the element that gives the maximum value from the specfied function + /// + /// # Example + /// + /// --- {.rust} + /// let xs = [-3, 0, 1, 5, -10]; + /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); + /// --- + fn max_by(&mut self, f: &fn(&A) -> B) -> Option; + + /// Return the element that gives the minimum value from the specfied function + /// + /// # Example + /// + /// --- {.rust} + /// let xs = [-3, 0, 1, 5, -10]; + /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); + /// --- + fn min_by(&mut self, f: &fn(&A) -> B) -> Option; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -519,6 +539,36 @@ impl> IteratorUtil for T { } i } + + #[inline] + fn max_by(&mut self, f: &fn(&A) -> B) -> Option { + self.fold(None, |max: Option<(A, B)>, x| { + let x_val = f(&x); + match max { + None => Some((x, x_val)), + Some((y, y_val)) => if x_val > y_val { + Some((x, x_val)) + } else { + Some((y, y_val)) + } + } + }).map_consume(|(x, _)| x) + } + + #[inline] + fn min_by(&mut self, f: &fn(&A) -> B) -> Option { + self.fold(None, |min: Option<(A, B)>, x| { + let x_val = f(&x); + match min { + None => Some((x, x_val)), + Some((y, y_val)) => if x_val < y_val { + Some((x, x_val)) + } else { + Some((y, y_val)) + } + } + }).map_consume(|(x, _)| x) + } } /// A trait for iterators over elements which can be added together @@ -1237,4 +1287,16 @@ mod tests { assert_eq!(xs.iter().count(|x| *x == 5), 1); assert_eq!(xs.iter().count(|x| *x == 95), 0); } + + #[test] + fn test_max_by() { + let xs = [-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); + } + + #[test] + fn test_min_by() { + let xs = [-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); + } } From 41f953af2ee86e4bda1025d77dc8525f42bc7a69 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Tue, 25 Jun 2013 23:33:39 +0530 Subject: [PATCH 148/336] .gitmodules: specify submodule..branch So --remote can work. Signed-off-by: Ramkumar Ramachandra --- .gitmodules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitmodules b/.gitmodules index 52ece628c573..c84426161796 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,8 @@ [submodule "src/llvm"] path = src/llvm url = https://github.com/brson/llvm.git + branch = master [submodule "src/libuv"] path = src/libuv url = https://github.com/brson/libuv.git + branch = master From 00b4138857055ba3495a70a01eea0bc8d9fed690 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Tue, 25 Jun 2013 18:36:48 -0400 Subject: [PATCH 149/336] Make ^~~~~ colour dependent on error/warning/note level. Also correct spelling of squigglies. --- src/libsyntax/diagnostic.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 13fa01c96e12..a904416d7a44 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -231,7 +231,7 @@ pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) { let ss = cm.span_to_str(sp); let lines = cm.span_to_lines(sp); print_diagnostic(ss, lvl, msg); - highlight_lines(cm, sp, lines); + highlight_lines(cm, sp, lvl, lines); print_macro_backtrace(cm, sp); } None => { @@ -241,7 +241,7 @@ pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) { } fn highlight_lines(cm: @codemap::CodeMap, - sp: span, + sp: span, lvl: level, lines: @codemap::FileLines) { let fm = lines.file; @@ -293,18 +293,18 @@ fn highlight_lines(cm: @codemap::CodeMap, let curChar = (orig[pos] as char); s += match curChar { // Whenever a tab occurs on the previous '\t' => "\t", // line, we insert one on the error-point- - _ => " " // -squigly-line as well (instead of a - }; // space). This way the squigly-line will + _ => " " // -squiggly-line as well (instead of a + }; // space). This way the squiggly-line will } // usually appear in the correct position. io::stderr().write_str(s); let mut s = ~"^"; let hi = cm.lookup_char_pos(sp.hi); if hi.col != lo.col { // the ^ already takes up one space - let num_squiglies = hi.col.to_uint()-lo.col.to_uint()-1u; - for num_squiglies.times() { s += "~"; } + let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u; + for num_squigglies.times() { s += "~"; } } - print_maybe_colored(s + "\n", term::color_bright_green); + print_maybe_colored(s + "\n", diagnosticcolor(lvl)); } } From 0ae203a779b8a75b3b79b409d92558d4bda92133 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 25 Jun 2013 16:38:32 -0700 Subject: [PATCH 150/336] Refactor extra::term a bit Move all the colors into a nested mod named color instead of prefixing with "color_". Define a new type color::Color, and make this a u16 instead of a u8 (to allow for easy comparisons against num_colors, which is a u16). Remove color_supported and replace it with num_colors. Teach fg() and bg() to "dim" bright colors down to the normal intensity if num_colors isn't high enough. Remove unnecessary copies, and fix a bug where a terminfo parse failure would try to use the wrong error and end up failing. --- src/libextra/term.rs | 112 +++++++++++++++++++++--------------- src/libextra/test.rs | 14 ++--- src/librustpkg/messages.rs | 8 +-- src/libsyntax/diagnostic.rs | 12 ++-- 4 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 782a73deadf9..9a4469cb5265 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -24,35 +24,38 @@ use core::io; // FIXME (#2807): Windows support. -pub static color_black: u8 = 0u8; -pub static color_red: u8 = 1u8; -pub static color_green: u8 = 2u8; -pub static color_yellow: u8 = 3u8; -pub static color_blue: u8 = 4u8; -pub static color_magenta: u8 = 5u8; -pub static color_cyan: u8 = 6u8; -pub static color_light_gray: u8 = 7u8; -pub static color_light_grey: u8 = 7u8; -pub static color_dark_gray: u8 = 8u8; -pub static color_dark_grey: u8 = 8u8; -pub static color_bright_red: u8 = 9u8; -pub static color_bright_green: u8 = 10u8; -pub static color_bright_yellow: u8 = 11u8; -pub static color_bright_blue: u8 = 12u8; -pub static color_bright_magenta: u8 = 13u8; -pub static color_bright_cyan: u8 = 14u8; -pub static color_bright_white: u8 = 15u8; +pub mod color { + pub type Color = u16; + + pub static black: Color = 0u16; + pub static red: Color = 1u16; + pub static green: Color = 2u16; + pub static yellow: Color = 3u16; + pub static blue: Color = 4u16; + pub static magenta: Color = 5u16; + pub static cyan: Color = 6u16; + pub static white: Color = 7u16; + + pub static bright_black: Color = 8u16; + pub static bright_red: Color = 9u16; + pub static bright_green: Color = 10u16; + pub static bright_yellow: Color = 11u16; + pub static bright_blue: Color = 12u16; + pub static bright_magenta: Color = 13u16; + pub static bright_cyan: Color = 14u16; + pub static bright_white: Color = 15u16; +} #[cfg(not(target_os = "win32"))] pub struct Terminal { - color_supported: bool, + num_colors: u16, priv out: @io::Writer, priv ti: ~TermInfo } #[cfg(target_os = "win32")] pub struct Terminal { - color_supported: bool, + num_colors: u16, priv out: @io::Writer, } @@ -66,66 +69,81 @@ impl Terminal { let entry = open(term.unwrap()); if entry.is_err() { - return Err(entry.get_err()); + return Err(entry.unwrap_err()); } - let ti = parse(entry.get(), false); + let ti = parse(entry.unwrap(), false); if ti.is_err() { - return Err(entry.get_err()); + return Err(ti.unwrap_err()); } - let mut inf = ti.get(); - let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16 - && inf.strings.find(&~"setaf").is_some() - && inf.strings.find_equiv(&("setab")).is_some(); + let inf = ti.unwrap(); + let nc = if inf.strings.find_equiv(&("setaf")).is_some() + && inf.strings.find_equiv(&("setab")).is_some() { + inf.numbers.find_equiv(&("colors")).map_consume_default(0, |&n| n) + } else { 0 }; - return Ok(Terminal {out: out, ti: inf, color_supported: cs}); + return Ok(Terminal {out: out, ti: inf, num_colors: nc}); } - pub fn fg(&self, color: u8) { - if self.color_supported { + /// Sets the foreground color to the given color. + /// + /// If the color is a bright color, but the terminal only supports 8 colors, + /// the corresponding normal color will be used instead. + pub fn fg(&self, color: color::Color) { + let color = self.dim_if_necessary(color); + if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.get()); + self.out.write(s.unwrap()); } else { - warn!(s.get_err()); + warn!(s.unwrap_err()); } } } - pub fn bg(&self, color: u8) { - if self.color_supported { + /// Sets the background color to the given color. + /// + /// If the color is a bright color, but the terminal only supports 8 colors, + /// the corresponding normal color will be used instead. + pub fn bg(&self, color: color::Color) { + let color = self.dim_if_necessary(color); + if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.get()); + self.out.write(s.unwrap()); } else { - warn!(s.get_err()); + warn!(s.unwrap_err()); } } } pub fn reset(&self) { - if self.color_supported { - let mut vars = Variables::new(); - let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars); - if s.is_ok() { - self.out.write(s.get()); - } else { - warn!(s.get_err()); - } + let mut vars = Variables::new(); + let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars); + if s.is_ok() { + self.out.write(s.unwrap()); + } else { + warn!(s.unwrap_err()); } } + + priv fn dim_if_necessary(&self, color: color::Color) -> color::Color { + if color >= self.num_colors && color >= 8 && color < 16 { + color-8 + } else { color } + } } #[cfg(target_os = "win32")] impl Terminal { pub fn new(out: @io::Writer) -> Result { - return Ok(Terminal {out: out, color_supported: false}); + return Ok(Terminal {out: out, num_colors: 0}); } - pub fn fg(&self, _color: u8) { + pub fn fg(&self, _color: color::Color) { } - pub fn bg(&self, _color: u8) { + pub fn bg(&self, _color: color::Color) { } pub fn reset(&self) { diff --git a/src/libextra/test.rs b/src/libextra/test.rs index e058a098fa49..03d9a0607980 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -326,33 +326,33 @@ pub fn run_tests_console(opts: &TestOpts, } fn write_ok(out: @io::Writer, use_color: bool) { - write_pretty(out, "ok", term::color_green, use_color); + write_pretty(out, "ok", term::color::green, use_color); } fn write_failed(out: @io::Writer, use_color: bool) { - write_pretty(out, "FAILED", term::color_red, use_color); + write_pretty(out, "FAILED", term::color::red, use_color); } fn write_ignored(out: @io::Writer, use_color: bool) { - write_pretty(out, "ignored", term::color_yellow, use_color); + write_pretty(out, "ignored", term::color::yellow, use_color); } fn write_bench(out: @io::Writer, use_color: bool) { - write_pretty(out, "bench", term::color_cyan, use_color); + write_pretty(out, "bench", term::color::cyan, use_color); } fn write_pretty(out: @io::Writer, word: &str, - color: u8, + color: term::color::Color, use_color: bool) { let t = term::Terminal::new(out); match t { Ok(term) => { - if use_color && term.color_supported { + if use_color { term.fg(color); } out.write_str(word); - if use_color && term.color_supported { + if use_color { term.reset(); } }, diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index d3962470e7c8..bde7aaeab8e4 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -13,18 +13,18 @@ use core::io; use core::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: u8, out: @io::Writer) { +fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: term::color::Color, out: @io::Writer) { let term = term::Terminal::new(out); match term { Ok(ref t) => { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index a904416d7a44..89867922b25b 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -178,16 +178,16 @@ fn diagnosticstr(lvl: level) -> ~str { } } -fn diagnosticcolor(lvl: level) -> u8 { +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 } } -fn print_maybe_colored(msg: &str, color: u8) { +fn print_maybe_colored(msg: &str, color: term::color::Color) { let stderr = io::stderr(); let t = term::Terminal::new(stderr); From 9423850fc38617089a976f748af7ee113132fd1a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 24 Jun 2013 23:46:38 -0700 Subject: [PATCH 151/336] More 0.7 release notes --- RELEASES.txt | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/RELEASES.txt b/RELEASES.txt index 60169b347ad8..dbee53f8e305 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -4,6 +4,8 @@ Version 0.7 (July 2013) * ??? changes, numerous bugfixes * Syntax changes + * `impl`s no longer accept a visibility qualifier. Put them on methods + instead. * `use mod` is no longer valid. * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style argument list. @@ -25,6 +27,10 @@ Version 0.7 (July 2013) no padding between fields. * The `for` loop protocol now requires `for`-iterators to return `bool` so they compose better. + * Trait default methods work more often. + * Type parameters bound by `Copy` must now be copied explicitly with + the `copy` keyword. + * It is now illegal to move out of a dereferenced unsafe pointer. * `Option<~T>` is now represented as a nullable pointer. * `@mut` does dynamic borrow checks correctly. * Macros TODO @@ -43,26 +49,30 @@ Version 0.7 (July 2013) * Libraries * The `core` crate was renamed to `std`. * The `std` crate was renamed to `extra`. - * `std::mut` removed. + * std: `iterator` module for external iterator objects. + * Many old-style (internal, higher-order function) iterators replaced by + implementations of `Iterator`. + * std: Many old internal vector and string iterators, + incl. `any`, `all`. removed. + * std: The `finalize` method of `Drop` renamed to `drop`. * std: The prelude no longer reexports any modules, only types and traits. * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. - * std: `iterator` module for external iterator objects. - * std: Many old internal vector and string iterators, - incl. `any`, `all`. removed. - * std: new numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, + * std: New numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`. * std: Tuple traits and accessors defined for up to 12-tuples, e.g. `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. - * std: many types implement `Clone`. + * std: Many types implement `Clone`. * std: `path` type renamed to `Path`. + * std: `mut` module and `Mut` type removed. * std: Many standalone functions removed in favor of methods and iterators in `vec`, `str`. In the future methods will also work as functions. - * std: `reinterpret_cast` removed. Used `transmute`. + * std: `reinterpret_cast` removed. Use `transmute`. * std: ascii string handling in `std::ascii`. * std: `Rand` is implemented for ~/@. * std: `run` module for spawning processes overhauled. * std: Various atomic types added to `unstable::atomic`. + * std: Various types implement `Zero`. * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`. * std: Borrowed pointer functions moved from `ptr` to `borrow`. * std: Added `os::mkdir_recursive`. @@ -96,7 +106,6 @@ Version 0.7 (July 2013) * More and improved library documentation. * Various improvements on ARM and Android. * Various improvements to MIPS backend. - * jemalloc is the Rust allocator. Version 0.6 (April 2013) ------------------------ From 8a4d359ffcfc9b0055580e27b841caf7e88f8f15 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Jun 2013 23:54:41 -0700 Subject: [PATCH 152/336] Fix a formatting bug in rusti --- src/librusti/program.rs | 2 +- src/librusti/rusti.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librusti/program.rs b/src/librusti/program.rs index f17777559deb..869b3472422b 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -107,7 +107,7 @@ impl Program { match *to_print { Some(ref s) => { code.push_str(*s); - code.push_char('\n'); + code.push_str(";\n"); } None => {} } diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 57a2a48a0f63..54a404d971ee 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -648,6 +648,11 @@ mod tests { fn f() {} f() "); + + debug!("simultaneous definitions + expressions are allowed"); + run_program(" + let a = 3; a as u8 + "); } #[test] From 87c1b59e8bf59ca32e725ca72f09ebef98928091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Tue, 25 Jun 2013 11:27:43 +0200 Subject: [PATCH 153/336] Fix some warnings in the check-fast tests --- src/etc/combine-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index 8e9caf189c22..36031d31149a 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -60,7 +60,7 @@ i = 0 for t in stage2_tests: p = os.path.join("test", "run-pass", t) p = p.replace("\\", "\\\\") - d.write(" out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p) + d.write(" out.write_str(\"run-pass [stage2]: %s\\n\");\n" % p) d.write(" t_%d::main();\n" % i) i += 1 d.write("}\n") From 2234f61038f5a91fce0d7f4765eec55fc4b0c622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Tue, 25 Jun 2013 11:32:02 +0200 Subject: [PATCH 154/336] Remove the last traces of shapes --- src/librustc/middle/trans/base.rs | 21 ++++++- src/librustc/middle/trans/closure.rs | 2 +- src/librustc/middle/trans/common.rs | 16 +---- src/librustc/middle/trans/context.rs | 5 -- src/librustc/middle/trans/mod.rs | 1 - src/librustc/middle/trans/shape.rs | 63 ------------------- .../run-pass/shape_intrinsic_tag_then_rec.rs | 5 -- 7 files changed, 22 insertions(+), 91 deletions(-) delete mode 100644 src/librustc/middle/trans/shape.rs diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0886704bbb15..ea90f554babc 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -55,7 +55,6 @@ use middle::trans::machine::{llalign_of_min, llsize_of}; use middle::trans::meth; use middle::trans::monomorphize; use middle::trans::reachable; -use middle::trans::shape::*; use middle::trans::tvec; use middle::trans::type_of; use middle::trans::type_of::*; @@ -2870,6 +2869,26 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { } } +fn mk_global(ccx: &CrateContext, + name: &str, + llval: ValueRef, + internal: bool) + -> ValueRef { + unsafe { + let llglobal = do str::as_c_str(name) |buf| { + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) + }; + llvm::LLVMSetInitializer(llglobal, llval); + llvm::LLVMSetGlobalConstant(llglobal, True); + + if internal { + lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); + } + + return llglobal; + } +} + // Writes the current ABI version into the crate. pub fn write_abi_version(ccx: &mut CrateContext) { mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 6cff996d0d45..227e22131636 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -210,7 +210,7 @@ pub fn store_environment(bcx: block, let ccx = bcx.ccx(); let tcx = ccx.tcx; - // compute the shape of the closure + // compute the type of the closure let cdata_ty = mk_closure_tys(tcx, bound_values); // allocate closure in the heap diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 442ab475046f..272d7b234aa5 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -658,7 +658,7 @@ impl block_ { pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { let ptr = ty::mk_ptr( tcx, - ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} + ty::mt {ty: ty::mk_i8(), mutbl: ast::m_imm} ); return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), ptr, ptr, @@ -826,20 +826,6 @@ pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { } } -pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { - unsafe { - let llshape = C_bytes_plus_null(bytes); - let name = fmt!("shape%u", token::gensym("shape")); - let llglobal = do name.as_c_str |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) - }; - llvm::LLVMSetInitializer(llglobal, llshape); - llvm::LLVMSetGlobalConstant(llglobal, True); - lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); - } -} - pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef { unsafe { llvm::LLVMGetParam(fndecl, param as c_uint) diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 57cfb1474dfe..a0ae579c8655 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -22,7 +22,6 @@ use middle::trans::adt; use middle::trans::base; use middle::trans::debuginfo; use middle::trans::reachable; -use middle::trans::shape; use middle::trans::type_use; use middle::ty; @@ -40,8 +39,6 @@ use middle::trans::common::{mono_id,new_namegen}; use middle::trans::base::{decl_crate_map}; -use middle::trans::shape::{mk_ctxt}; - pub struct CrateContext { sess: session::Session, llmod: ModuleRef, @@ -110,7 +107,6 @@ pub struct CrateContext { float_type: Type, opaque_vec_type: Type, builder: BuilderRef_res, - shape_cx: shape::Ctxt, crate_map: ValueRef, // Set when at least one function uses GC. Needed so that // decl_gc_metadata knows whether to link to the module metadata, which @@ -223,7 +219,6 @@ impl CrateContext { float_type: float_type, opaque_vec_type: opaque_vec_type, builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), - shape_cx: mk_ctxt(llmod), crate_map: crate_map, uses_gc: false, dbg_cx: dbg_cx, diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index 1345b92418e3..c2a25d80998a 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -35,7 +35,6 @@ pub mod cabi_arm; pub mod cabi_mips; pub mod foreign; pub mod reflect; -pub mod shape; pub mod debuginfo; pub mod type_use; pub mod reachable; diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs deleted file mode 100644 index 4118291dca0d..000000000000 --- a/src/librustc/middle/trans/shape.rs +++ /dev/null @@ -1,63 +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. - -// A "shape" is a compact encoding of a type that is used by interpreted glue. -// This substitutes for the runtime tags used by e.g. MLs. - - -use lib::llvm::llvm; -use lib::llvm::{True, ModuleRef, ValueRef}; -use middle::trans::common::*; - -use middle::trans::type_::Type; - -use core::str; - -pub struct Ctxt { - next_tag_id: u16, - pad: u16, - pad2: u32 -} - -pub fn mk_global(ccx: &CrateContext, - name: &str, - llval: ValueRef, - internal: bool) - -> ValueRef { - unsafe { - let llglobal = do str::as_c_str(name) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) - }; - llvm::LLVMSetInitializer(llglobal, llval); - llvm::LLVMSetGlobalConstant(llglobal, True); - - if internal { - ::lib::llvm::SetLinkage(llglobal, - ::lib::llvm::InternalLinkage); - } - - return llglobal; - } -} - -pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { - unsafe { - let llshapetablesty = Type::named_struct("shapes"); - do "shapes".as_c_str |buf| { - llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf) - }; - - Ctxt { - next_tag_id: 0u16, - pad: 0u16, - pad2: 0u32 - } - } -} diff --git a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs index f29d0c6f108c..34afc12f02e4 100644 --- a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs +++ b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs @@ -1,5 +1,3 @@ -// xfail-fast - // 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. @@ -14,9 +12,6 @@ // on x86_64: when there is a enum embedded in an // interior record which is then itself interior to // something else, shape calculations were off. -extern mod extra; -use extra::list; -use extra::list::list; enum opt_span { From 2b17e4775c816b59d92e166b8a8db039aaa7ba85 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 24 Jun 2013 12:38:14 -0700 Subject: [PATCH 155/336] rustc: Eliminate extra failing case in metadata::loader::crate_from_metas Closes #2406 --- src/librustc/metadata/loader.rs | 104 ++++++++++++++++---------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index f6ad676546dd..17aad969e325 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -89,70 +89,68 @@ fn find_library_crate_aux( filesearch: @filesearch::FileSearch ) -> Option<(~str, @~[u8])> { let crate_name = crate_name_from_metas(cx.metas); - let prefix: ~str = prefix + crate_name + "-"; - let suffix: ~str = /*bad*/copy suffix; + let prefix = prefix + crate_name + "-"; let mut matches = ~[]; - filesearch::search(filesearch, |path| { + filesearch::search(filesearch, |path| -> Option<()> { debug!("inspecting file %s", path.to_str()); - let f: ~str = path.filename().get(); - if !(f.starts_with(prefix) && f.ends_with(suffix)) { - debug!("skipping %s, doesn't look like %s*%s", path.to_str(), - prefix, suffix); - option::None::<()> - } else { - debug!("%s is a candidate", path.to_str()); - match get_metadata_section(cx.os, path) { - option::Some(cvec) => { - if !crate_matches(cvec, cx.metas, cx.hash) { - debug!("skipping %s, metadata doesn't match", - path.to_str()); - option::None::<()> - } else { - debug!("found %s with matching metadata", path.to_str()); - matches.push((path.to_str(), cvec)); - option::None::<()> + match path.filename() { + Some(ref f) if f.starts_with(prefix) && f.ends_with(suffix) => { + debug!("%s is a candidate", path.to_str()); + match get_metadata_section(cx.os, path) { + Some(cvec) => + if !crate_matches(cvec, cx.metas, cx.hash) { + debug!("skipping %s, metadata doesn't match", + path.to_str()); + None + } else { + debug!("found %s with matching metadata", path.to_str()); + matches.push((path.to_str(), cvec)); + None + }, + _ => { + debug!("could not load metadata for %s", path.to_str()); + None + } } - } - _ => { - debug!("could not load metadata for %s", path.to_str()); - option::None::<()> - } + } + _ => { + debug!("skipping %s, doesn't look like %s*%s", path.to_str(), + prefix, suffix); + None + } + }}); + + match matches.len() { + 0 => None, + 1 => Some(matches[0]), + _ => { + cx.diag.span_err( + cx.span, fmt!("multiple matching crates for `%s`", crate_name)); + cx.diag.handler().note("candidates:"); + for matches.each |&(ident, data)| { + cx.diag.handler().note(fmt!("path: %s", ident)); + let attrs = decoder::get_crate_attributes(data); + note_linkage_attrs(cx.intr, cx.diag, attrs); + } + cx.diag.handler().abort_if_errors(); + None } } - }); - - if matches.is_empty() { - None - } else if matches.len() == 1u { - Some(/*bad*/copy matches[0]) - } else { - cx.diag.span_err( - cx.span, fmt!("multiple matching crates for `%s`", crate_name)); - cx.diag.handler().note("candidates:"); - for matches.iter().advance |&(ident, data)| { - cx.diag.handler().note(fmt!("path: %s", ident)); - let attrs = decoder::get_crate_attributes(data); - note_linkage_attrs(cx.intr, cx.diag, attrs); - } - cx.diag.handler().abort_if_errors(); - None - } } pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { - let name_items = attr::find_meta_items_by_name(metas, "name"); - match name_items.last_opt() { - Some(i) => { - match attr::get_meta_item_value_str(*i) { - Some(n) => n, - // FIXME (#2406): Probably want a warning here since the user - // is using the wrong type of meta item. - _ => fail!() - } + for metas.each |m| { + match m.node { + ast::meta_name_value(s, ref l) if s == @"name" => + match l.node { + ast::lit_str(s) => return s, + _ => () + }, + _ => () } - None => fail!("expected to find the crate name") } + fail!("expected to find the crate name") } pub fn note_linkage_attrs(intr: @ident_interner, From f4621cab6859ee0f8ddacea0ece98e4a4c00d5a6 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Wed, 26 Jun 2013 15:49:21 +0530 Subject: [PATCH 156/336] priority_queue: implement simple iterator Remove PriorityQueue::each and replace it with PriorityQueue::iter, which ultimately calls into vec::VecIterator via PriorityQueueIterator. Implement iterator::Iterator for PriorityQueueIterator. Now you should be able to do: extern mod extra; let mut pq = extra::priority_queue::PriorityQueue::new(); pq.push(5); pq.push(6); pq.push(3); for pq.iter().advance |el| { println(fmt!("%d", *el)); } just like you iterate over vectors, hashmaps, hashsets etc. Note that the iteration order is arbitrary (as before with PriorityQueue::each), and _not_ the order you get when you pop() repeatedly. Add an in-file test to guard this. Reported-by: Daniel Micay Signed-off-by: Ramkumar Ramachandra --- src/libextra/priority_queue.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 4e201a6538ba..af891edf9e5f 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -37,10 +37,11 @@ impl Mutable for PriorityQueue { } impl PriorityQueue { - /// Visit all values in the underlying vector. - /// - /// The values are **not** visited in order. - pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.iter().advance(f) } + /// An iterator visiting all values in underlying vector, in + /// arbitrary order. + pub fn iter<'a>(&'a self) -> PriorityQueueIterator<'a, T> { + PriorityQueueIterator { iter: self.data.iter() } + } /// Returns the greatest item in the queue - fails if empty pub fn top<'a>(&'a self) -> &'a T { &self.data[0] } @@ -178,11 +179,33 @@ impl PriorityQueue { } } +/// PriorityQueue iterator +pub struct PriorityQueueIterator <'self, T> { + priv iter: vec::VecIterator<'self, T>, +} + +impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<(&'self T)> { self.iter.next() } +} + #[cfg(test)] mod tests { use sort::merge_sort; use priority_queue::PriorityQueue; + #[test] + fn test_iterator() { + let data = ~[5, 9, 3]; + let iterout = ~[9, 5, 3]; + let pq = PriorityQueue::from_vec(data); + let mut i = 0; + for pq.iter().advance |el| { + assert_eq!(*el, iterout[i]); + i += 1; + } + } + #[test] fn test_top_and_pop() { let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]; From 4f7a742a067dcd6e8dbcf1da2bbcf203147562cf Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Tue, 25 Jun 2013 15:08:47 -0400 Subject: [PATCH 157/336] deque iterator --- src/libextra/deque.rs | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index c8bb984736a1..2aacf9089829 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -153,6 +153,101 @@ impl Deque { pub fn reserve_at_least(&mut self, n: uint) { vec::reserve_at_least(&mut self.elts, n); } + + /// Front-to-back iterator. + pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> { + DequeIterator { iter: self.elts.iter() } + } + + /// Front-to-back iterator which returns mutable values. + pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> { + DequeMutIterator { iter: self.elts.mut_iter() } + } + + /// Back-to-front iterator. + pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> { + DequeRevIterator { iter: self.elts.rev_iter() } + } + + /// Back-to-front iterator which returns mutable values. + pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> { + DequeMutRevIterator { iter: self.elts.mut_rev_iter() } + } +} + +/// Deque iterator +pub struct DequeIterator<'self, T> { + priv iter: vec::VecIterator<'self, Option> +} + +/// Deque reverse iterator +pub struct DequeRevIterator<'self, T> { + priv iter: vec::VecRevIterator<'self, Option> +} +/// Deque mutable iterator +pub struct DequeMutIterator<'self, T> { + priv iter: vec::VecMutIterator<'self, Option> +} + +/// Deque mutable reverse iterator +pub struct DequeMutRevIterator<'self, T> { + priv iter: vec::VecMutRevIterator<'self, Option> +} + +/// Iterator visiting elements of the deque from front to back +impl<'self, T> Iterator<&'self T> for DequeIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self T> { + for self.iter.advance |elt| { + match elt { + &Some(ref e) => return Some(e), + &None => {}, + } + } + None + } +} + +/// Iterator visiting elements of the deque mutably from front to back +impl<'self, T> Iterator<&'self mut T> for DequeMutIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self mut T> { + for self.iter.advance |elt| { + match elt { + &Some(ref mut e) => return Some(e), + &None => {}, + } + } + None + } +} + +/// Iterator visiting elements of the deque from back to front +impl<'self, T> Iterator<&'self T> for DequeRevIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self T> { + for self.iter.advance |elt| { + match elt { + &Some(ref e) => return Some(e), + &None => {}, + } + } + None + } +} + +/// Iterator visiting elements of the deque mutably from back to front +impl<'self, T> Iterator<&'self mut T> for DequeMutRevIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<&'self mut T> { + for self.iter.advance |elt| { + match elt { + &Some(ref mut e) => return Some(e), + &None => {}, + } + } + None + } } /// Grow is only called on full elts, so nelts is also len(elts), unlike From dfc9392c381c9c5b3e4313e23765c4b04d128e99 Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Tue, 25 Jun 2013 22:33:02 -0400 Subject: [PATCH 158/336] iterators use deque ordering --- src/libextra/deque.rs | 121 +++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 49 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 2aacf9089829..a33314b67bc5 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -9,7 +9,6 @@ // except according to those terms. //! A double-ended queue implemented as a circular buffer - use core::prelude::*; use core::uint; @@ -156,98 +155,122 @@ impl Deque { /// Front-to-back iterator. pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> { - DequeIterator { iter: self.elts.iter() } + DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } } /// Front-to-back iterator which returns mutable values. pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> { - DequeMutIterator { iter: self.elts.mut_iter() } + DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } } /// Back-to-front iterator. pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> { - DequeRevIterator { iter: self.elts.rev_iter() } + DequeRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } } /// Back-to-front iterator which returns mutable values. pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> { - DequeMutRevIterator { iter: self.elts.mut_rev_iter() } + DequeMutRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } } } /// Deque iterator pub struct DequeIterator<'self, T> { - priv iter: vec::VecIterator<'self, Option> + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self [Option] } /// Deque reverse iterator pub struct DequeRevIterator<'self, T> { - priv iter: vec::VecRevIterator<'self, Option> + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self [Option] } /// Deque mutable iterator pub struct DequeMutIterator<'self, T> { - priv iter: vec::VecMutIterator<'self, Option> + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self mut [Option] + } /// Deque mutable reverse iterator pub struct DequeMutRevIterator<'self, T> { - priv iter: vec::VecMutRevIterator<'self, Option> + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self mut [Option] } /// Iterator visiting elements of the deque from front to back impl<'self, T> Iterator<&'self T> for DequeIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self T> { - for self.iter.advance |elt| { - match elt { - &Some(ref e) => return Some(e), - &None => {}, - } - } - None - } + fn next(&mut self) -> Option<&'self T> { + if self.used >= self.nelts { + return None; + } + let ret = match self.vec[self.idx % self.vec.len()] { + Some(ref e) => Some(e), + None => None + }; + self.idx += 1; + self.used += 1; + ret + } } /// Iterator visiting elements of the deque mutably from front to back impl<'self, T> Iterator<&'self mut T> for DequeMutIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self mut T> { - for self.iter.advance |elt| { - match elt { - &Some(ref mut e) => return Some(e), - &None => {}, - } - } - None - } + fn next(&mut self) -> Option<&'self mut T> { + if self.used >= self.nelts { + return None; + } + let ret = match self.vec[self.idx % self.vec.len()] { + Some(ref mut e) => Some(e), + None => None + }; + self.idx += 1; + self.used += 1; + ret + } } /// Iterator visiting elements of the deque from back to front impl<'self, T> Iterator<&'self T> for DequeRevIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self T> { - for self.iter.advance |elt| { - match elt { - &Some(ref e) => return Some(e), - &None => {}, - } - } - None - } + #[inline] + fn next(&mut self) -> Option<&'self T> { + if self.used >= self.nelts { + return None; + } + let ret = match self.vec[self.idx % self.vec.len()] { + Some(ref e) => Some(e), + None => None + }; + self.idx -= 1; + self.used += 1; + ret + + } } /// Iterator visiting elements of the deque mutably from back to front impl<'self, T> Iterator<&'self mut T> for DequeMutRevIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self mut T> { - for self.iter.advance |elt| { - match elt { - &Some(ref mut e) => return Some(e), - &None => {}, - } - } - None - } + #[inline] + fn next(&mut self) -> Option<&'self mut T> { + if self.used >= self.nelts { + return None; + } + let ret = match self.vec[self.idx % self.vec.len()] { + Some(ref mut e) => Some(e), + None => None + }; + self.idx -= 1; + self.used += 1; + ret + } } /// Grow is only called on full elts, so nelts is also len(elts), unlike From 096fb795de0c194b439a9e332ca30d3d5886ddbb Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Wed, 26 Jun 2013 10:04:44 -0400 Subject: [PATCH 159/336] A few iterator tests --- src/libextra/deque.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index a33314b67bc5..e9a819d9292f 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -500,4 +500,35 @@ mod tests { assert_eq!(capacity(&mut d.elts), 64); } + #[test] + fn test_iter() { + let mut d = Deque::new(); + for std::int::range(0,5) |i| { + d.add_back(i); + } + assert_eq!(d.iter().collect::<~[&int]>(), + ~[&0,&1,&2,&3,&4]); + + for std::int::range(6,9) |i| { + d.add_front(i); + } + assert_eq!(d.iter().collect::<~[&int]>(), + ~[&8,&7,&6,&0,&1,&2,&3,&4]); + } + + #[test] + fn test_rev_iter() { + let mut d = Deque::new(); + for std::int::range(0,5) |i| { + d.add_back(i); + } + assert_eq!(d.rev_iter().collect::<~[&int]>(), + ~[&4,&3,&2,&1,&0]); + + for std::int::range(6,9) |i| { + d.add_front(i); + } + assert_eq!(d.rev_iter().collect::<~[&int]>(), + ~[&4,&3,&2,&1,&0,&6,&7,&8]); + } } From 35314c93fa07a21aea18548f59886285a303c696 Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Wed, 26 Jun 2013 11:38:29 -0400 Subject: [PATCH 160/336] Moving implementation details to a macro --- src/libextra/deque.rs | 95 +++++++++++++------------------------------ 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index e9a819d9292f..ba9f12ad37a3 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -14,6 +14,7 @@ use core::prelude::*; use core::uint; use core::util::replace; use core::vec; +use core::cast::transmute; static initial_capacity: uint = 32u; // 2^5 @@ -174,6 +175,28 @@ impl Deque { } } +macro_rules! iterator { + (impl $name:ident -> $elem:ty, $step:expr) => { + impl<'self, T> Iterator<$elem> for $name<'self, T> { + #[inline] + fn next(&mut self) -> Option<$elem> { + if self.used >= self.nelts { + return None; + } + let ret = unsafe { + match self.vec[self.idx % self.vec.len()] { + Some(ref e) => Some(transmute(e)), + None => None + } + }; + self.idx += $step; + self.used += 1; + ret + } + } + } +} + /// Deque iterator pub struct DequeIterator<'self, T> { priv idx: uint, @@ -181,6 +204,7 @@ pub struct DequeIterator<'self, T> { priv used: uint, priv vec: &'self [Option] } +iterator!{impl DequeIterator -> &'self T, 1} /// Deque reverse iterator pub struct DequeRevIterator<'self, T> { @@ -189,6 +213,8 @@ pub struct DequeRevIterator<'self, T> { priv used: uint, priv vec: &'self [Option] } +iterator!{impl DequeRevIterator -> &'self T, -1} + /// Deque mutable iterator pub struct DequeMutIterator<'self, T> { priv idx: uint, @@ -197,6 +223,7 @@ pub struct DequeMutIterator<'self, T> { priv vec: &'self mut [Option] } +iterator!{impl DequeMutIterator -> &'self mut T, 1} /// Deque mutable reverse iterator pub struct DequeMutRevIterator<'self, T> { @@ -205,73 +232,7 @@ pub struct DequeMutRevIterator<'self, T> { priv used: uint, priv vec: &'self mut [Option] } - -/// Iterator visiting elements of the deque from front to back -impl<'self, T> Iterator<&'self T> for DequeIterator<'self, T> { - fn next(&mut self) -> Option<&'self T> { - if self.used >= self.nelts { - return None; - } - let ret = match self.vec[self.idx % self.vec.len()] { - Some(ref e) => Some(e), - None => None - }; - self.idx += 1; - self.used += 1; - ret - } -} - -/// Iterator visiting elements of the deque mutably from front to back -impl<'self, T> Iterator<&'self mut T> for DequeMutIterator<'self, T> { - fn next(&mut self) -> Option<&'self mut T> { - if self.used >= self.nelts { - return None; - } - let ret = match self.vec[self.idx % self.vec.len()] { - Some(ref mut e) => Some(e), - None => None - }; - self.idx += 1; - self.used += 1; - ret - } -} - -/// Iterator visiting elements of the deque from back to front -impl<'self, T> Iterator<&'self T> for DequeRevIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self T> { - if self.used >= self.nelts { - return None; - } - let ret = match self.vec[self.idx % self.vec.len()] { - Some(ref e) => Some(e), - None => None - }; - self.idx -= 1; - self.used += 1; - ret - - } -} - -/// Iterator visiting elements of the deque mutably from back to front -impl<'self, T> Iterator<&'self mut T> for DequeMutRevIterator<'self, T> { - #[inline] - fn next(&mut self) -> Option<&'self mut T> { - if self.used >= self.nelts { - return None; - } - let ret = match self.vec[self.idx % self.vec.len()] { - Some(ref mut e) => Some(e), - None => None - }; - self.idx -= 1; - self.used += 1; - ret - } -} +iterator!{impl DequeMutRevIterator -> &'self mut T, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. From 524a92c72ff05613aa5bbd0d806910222741ae2a Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Mon, 17 Jun 2013 23:20:53 -0700 Subject: [PATCH 161/336] Add method .set_memory in vec::bytes for &[u8] Add new trait vec::bytes::MutableByteVector which currently defines one method .set_memory(). --- src/libstd/vec.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 2e18a588fae3..3d5ec23c3290 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2288,6 +2288,22 @@ pub mod bytes { use uint; use vec::raw; use vec; + use ptr; + + /// A trait for operations on mutable operations on `[u8]` + pub trait MutableByteVector { + /// Sets all bytes of the receiver to the given value. + pub fn set_memory(self, value: u8); + } + + impl<'self> MutableByteVector for &'self mut [u8] { + #[inline] + fn set_memory(self, value: u8) { + do vec::as_mut_buf(self) |p, len| { + unsafe { ptr::set_memory(p, value, len) }; + } + } + } /// Bytewise string comparison pub fn memcmp(a: &~[u8], b: &~[u8]) -> int { @@ -3941,4 +3957,14 @@ mod tests { t!(@[int]); t!(~[int]); } + + #[test] + fn test_bytes_set_memory() { + use vec::bytes::MutableByteVector; + let mut values = [1u8,2,3,4,5]; + values.mut_slice(0,5).set_memory(0xAB); + assert_eq!(values, [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]); + values.mut_slice(2,4).set_memory(0xFF); + assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]); + } } From 3df37326cf880425625373f3e11f74afac4dbb67 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Mon, 17 Jun 2013 23:52:14 -0700 Subject: [PATCH 162/336] Add methods .move_from() and .copy_from() to vec Add method .move_from() to MutableVector, which consumes another vector and moves elements into the receiver. Add new trait MutableCloneableVector with one method .copy_from(), which clones elements from another vector into the receiver. --- src/libstd/vec.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 3d5ec23c3290..b707530ebce0 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -15,6 +15,7 @@ use cast::transmute; use cast; use container::{Container, Mutable}; +use cmp; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; @@ -2059,6 +2060,21 @@ pub trait MutableVector<'self, T> { fn mut_iter(self) -> VecMutIterator<'self, T>; fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>; + /** + * Consumes `src` and moves as many elements as it can into `self` + * from the range [start,end). + * + * Returns the number of elements copied (the shorter of self.len() + * and end - start). + * + * # Arguments + * + * * src - A mutable vector of `T` + * * start - The index into `src` to start copying from + * * end - The index into `str` to stop copying from + */ + fn move_from(self, src: ~[T], start: uint, end: uint) -> uint; + unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T; unsafe fn unsafe_set(&self, index: uint, val: T); } @@ -2087,6 +2103,14 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } + #[inline] + fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint { + for self.mut_iter().zip(src.mut_slice(start, end).mut_iter()).advance |(a, b)| { + util::swap(a, b); + } + cmp::min(self.len(), end-start) + } + #[inline] unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T { let pair_ptr: &(*mut T, uint) = transmute(self); @@ -2100,6 +2124,23 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } +/// Trait for ~[T] where T is Cloneable +pub trait MutableCloneableVector { + /// Copies as many elements from `src` as it can into `self` + /// (the shorter of self.len() and src.len()). Returns the number of elements copied. + fn copy_from(self, &[T]) -> uint; +} + +impl<'self, T:Clone> MutableCloneableVector for &'self mut [T] { + #[inline] + fn copy_from(self, src: &[T]) -> uint { + for self.mut_iter().zip(src.iter()).advance |(a, b)| { + *a = b.clone(); + } + cmp::min(self.len(), src.len()) + } +} + /** * Constructs a vector from an unsafe pointer to a buffer * @@ -3895,6 +3936,38 @@ mod tests { assert_eq!(xs, [5, 5, 5, 5, 5]) } + #[test] + fn test_move_from() { + let mut a = [1,2,3,4,5]; + let b = ~[6,7,8]; + assert_eq!(a.move_from(b, 0, 3), 3); + assert_eq!(a, [6,7,8,4,5]); + let mut a = [7,2,8,1]; + let b = ~[3,1,4,1,5,9]; + assert_eq!(a.move_from(b, 0, 6), 4); + assert_eq!(a, [3,1,4,1]); + let mut a = [1,2,3,4]; + let b = ~[5,6,7,8,9,0]; + assert_eq!(a.move_from(b, 2, 3), 1); + assert_eq!(a, [7,2,3,4]); + let mut a = [1,2,3,4,5]; + let b = ~[5,6,7,8,9,0]; + assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2); + assert_eq!(a, [1,2,6,7,5]); + } + + #[test] + fn test_copy_from() { + let mut a = [1,2,3,4,5]; + let b = [6,7,8]; + assert_eq!(a.copy_from(b), 3); + assert_eq!(a, [6,7,8,4,5]); + let mut c = [7,2,8,1]; + let d = [3,1,4,1,5,9]; + assert_eq!(c.copy_from(d), 4); + assert_eq!(c, [3,1,4,1]); + } + #[test] fn test_reverse_part() { let mut values = [1,2,3,4,5]; From f8ae9b0ae64e23aff1408097a5a4a03a72895ae6 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Wed, 26 Jun 2013 18:14:35 -0400 Subject: [PATCH 163/336] Fix whitespace issues (thanks @jedestep!) --- src/libextra/deque.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index ba9f12ad37a3..b82984cb2c54 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -158,7 +158,7 @@ impl Deque { pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> { DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } } - + /// Front-to-back iterator which returns mutable values. pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> { DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } @@ -183,7 +183,7 @@ macro_rules! iterator { if self.used >= self.nelts { return None; } - let ret = unsafe { + let ret = unsafe { match self.vec[self.idx % self.vec.len()] { Some(ref e) => Some(transmute(e)), None => None @@ -397,8 +397,7 @@ mod tests { #[test] fn test_param_taggy() { - test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), - Two(17, 42)); + test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42)); } #[test] @@ -467,14 +466,12 @@ mod tests { for std::int::range(0,5) |i| { d.add_back(i); } - assert_eq!(d.iter().collect::<~[&int]>(), - ~[&0,&1,&2,&3,&4]); - + assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]); + for std::int::range(6,9) |i| { d.add_front(i); } - assert_eq!(d.iter().collect::<~[&int]>(), - ~[&8,&7,&6,&0,&1,&2,&3,&4]); + assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]); } #[test] @@ -483,13 +480,11 @@ mod tests { for std::int::range(0,5) |i| { d.add_back(i); } - assert_eq!(d.rev_iter().collect::<~[&int]>(), - ~[&4,&3,&2,&1,&0]); - + assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]); + for std::int::range(6,9) |i| { d.add_front(i); } - assert_eq!(d.rev_iter().collect::<~[&int]>(), - ~[&4,&3,&2,&1,&0,&6,&7,&8]); + assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); } } From 12e09afd6d7bb4ca30e572a5214c11284ea1965b Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 20 Jun 2013 20:18:16 -0400 Subject: [PATCH 164/336] Work-around 'static bound requirement in io::with_bytes_reader (note: does not fix #5723, interface still unsafe) --- src/libextra/io_util.rs | 6 +++++- src/libstd/io.rs | 13 ++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libextra/io_util.rs b/src/libextra/io_util.rs index 91424ae3ba2c..11dea1c3a708 100644 --- a/src/libextra/io_util.rs +++ b/src/libextra/io_util.rs @@ -10,6 +10,7 @@ use core::io::{Reader, BytesReader}; use core::io; +use core::cast; /// An implementation of the io::Reader interface which reads a buffer of bytes pub struct BufReader { @@ -29,10 +30,13 @@ impl BufReader { } fn as_bytes_reader(&self, f: &fn(&BytesReader) -> A) -> A { + // XXX FIXME(#5723) + let bytes = ::core::util::id::<&[u8]>(self.buf); + let bytes: &'static [u8] = unsafe { cast::transmute(bytes) }; // Recreating the BytesReader state every call since // I can't get the borrowing to work correctly let bytes_reader = BytesReader { - bytes: ::core::util::id::<&[u8]>(self.buf), + bytes: bytes, pos: @mut *self.pos }; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 71a0dd6b9b2a..a78be9c8b2b1 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1042,12 +1042,14 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> { // Byte readers -pub struct BytesReader<'self> { - bytes: &'self [u8], +pub struct BytesReader { + // FIXME(#5723) see other FIXME below + // FIXME(#7268) this should also be parameterized over <'self> + bytes: &'static [u8], pos: @mut uint } -impl<'self> Reader for BytesReader<'self> { +impl Reader for BytesReader { fn read(&self, bytes: &mut [u8], len: uint) -> uint { let count = uint::min(len, self.bytes.len() - *self.pos); @@ -1084,6 +1086,10 @@ impl<'self> Reader for BytesReader<'self> { } pub fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> T) -> T { + // XXX XXX XXX this is glaringly unsound + // FIXME(#5723) Use a &Reader for the callback's argument. Should be: + // fn with_bytes_reader<'r, T>(bytes: &'r [u8], f: &fn(&'r Reader) -> T) -> T + let bytes: &'static [u8] = unsafe { cast::transmute(bytes) }; f(@BytesReader { bytes: bytes, pos: @mut 0 @@ -1091,6 +1097,7 @@ pub fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> T) -> T { } pub fn with_str_reader(s: &str, f: &fn(@Reader) -> T) -> T { + // FIXME(#5723): As above. with_bytes_reader(s.as_bytes(), f) } From 7b968783d79301af2305c0b1052092f9d31fd622 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 20 Jun 2013 18:23:25 -0400 Subject: [PATCH 165/336] Infer default static/Owned bounds for unbounded heap fns/traits (#7264) --- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/kind.rs | 2 +- src/librustc/middle/resolve.rs | 16 ++-- src/librustc/middle/ty.rs | 4 +- src/librustc/middle/typeck/astconv.rs | 73 +++++++++++++------ src/libsyntax/ast.rs | 8 +- src/libsyntax/ext/build.rs | 10 +-- src/libsyntax/ext/deriving/generic.rs | 2 +- src/libsyntax/ext/deriving/ty.rs | 4 +- src/libsyntax/ext/pipes/pipec.rs | 20 ++--- src/libsyntax/ext/pipes/proto.rs | 3 +- src/libsyntax/fold.rs | 11 ++- src/libsyntax/parse/mod.rs | 4 +- src/libsyntax/parse/parser.rs | 20 +++-- src/libsyntax/print/pprust.rs | 12 +-- src/libsyntax/visit.rs | 8 +- ...bounds-cant-promote-superkind-in-struct.rs | 2 +- .../compile-fail/closure-bounds-subtype.rs | 4 +- .../compile-fail/trait-bounds-cant-coerce.rs | 2 +- src/test/compile-fail/trait-bounds-sugar.rs | 37 ++++++++++ ...losure-bounds-copyable-squiggle-closure.rs | 2 +- ...ds-squiggle-closure-as-copyable-typaram.rs | 2 +- .../run-pass/kindck-owned-trait-contains-1.rs | 4 +- src/test/run-pass/regions-trait.rs | 4 +- src/test/run-pass/trait-bounds-basic.rs | 6 +- 25 files changed, 176 insertions(+), 86 deletions(-) create mode 100644 src/test/compile-fail/trait-bounds-sugar.rs diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 9c28da10e40d..cb47c88d3d4f 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -959,7 +959,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_attributes(ebml_w, item.attrs); match ty.node { ast::ty_path(path, bounds, _) if path.idents.len() == 1 => { - assert!(bounds.is_empty()); + assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index b0b2a16cf893..1c669631244c 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -128,7 +128,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // Yes, it's a destructor. match self_type.node { ty_path(_, bounds, path_node_id) => { - assert!(bounds.is_empty()); + assert!(bounds.is_none()); let struct_def = cx.tcx.def_map.get_copy( &path_node_id); let struct_did = diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index a8626ca89aa8..e06fd8f97179 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4195,15 +4195,19 @@ impl Resolver { } } - for bounds.iter().advance |bound| { - self.resolve_type_parameter_bound(bound, visitor); - } + do bounds.map |bound_vec| { + for bound_vec.iter().advance |bound| { + self.resolve_type_parameter_bound(bound, visitor); + } + }; } ty_closure(c) => { - for c.bounds.iter().advance |bound| { - self.resolve_type_parameter_bound(bound, visitor); - } + do c.bounds.map |bounds| { + for bounds.iter().advance |bound| { + self.resolve_type_parameter_bound(bound, visitor); + } + }; visit_ty(ty, ((), visitor)); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 328b331ea63e..a43025e4ff97 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4497,7 +4497,9 @@ pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) { }; let trait_lang_item = tcx.lang_items.ty_visitor(); let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs }; + let mut static_trait_bound = EmptyBuiltinBounds(); + static_trait_bound.add(BoundStatic); (trait_ref, mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, - BoxTraitStore, ast::m_imm, EmptyBuiltinBounds())) + BoxTraitStore, ast::m_imm, static_trait_bound)) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 5e6574850f1b..997061a61ba6 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -303,7 +303,7 @@ pub fn ast_ty_to_ty( ty::BoxTraitStore } }; - let bounds = conv_builtin_bounds(this.tcx(), bounds); + let bounds = conv_builtin_bounds(this.tcx(), bounds, trait_store); return ty::mk_trait(tcx, result.def_id, copy result.substs, @@ -386,7 +386,13 @@ pub fn ast_ty_to_ty( bf.abis, &bf.lifetimes, &bf.decl)) } ast::ty_closure(ref f) => { - let bounds = conv_builtin_bounds(this.tcx(), &f.bounds); + let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil { + // Use corresponding trait store to figure out default bounds + // if none were specified. + ast::BorrowedSigil => ty::RegionTraitStore(ty::re_empty), // dummy region + ast::OwnedSigil => ty::UniqTraitStore, + ast::ManagedSigil => ty::BoxTraitStore, + }); let fn_decl = ty_of_closure(this, rscope, f.sigil, @@ -411,7 +417,7 @@ pub fn ast_ty_to_ty( match a_def { // But don't emit the error if the user meant to do a trait anyway. ast::def_trait(*) => { }, - _ if !bounds.is_empty() => + _ if bounds.is_some() => tcx.sess.span_err(ast_ty.span, "kind bounds can only be used on trait types"), _ => { }, @@ -741,8 +747,8 @@ pub fn ty_of_closure( } } -fn conv_builtin_bounds(tcx: ty::ctxt, - ast_bounds: &OptVec) +fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option>, + store: ty::TraitStore) -> ty::BuiltinBounds { //! Converts a list of bounds from the AST into a `BuiltinBounds` //! struct. Reports an error if any of the bounds that appear @@ -750,32 +756,51 @@ fn conv_builtin_bounds(tcx: ty::ctxt, //! like `Copy` or `Owned`. Used to translate the bounds that //! appear in closure and trait types, where only builtin bounds are //! legal. + //! If no bounds were specified, we choose a "default" bound based on + //! the allocation type of the fn/trait, as per issue #7264. The user can + //! override this with an empty bounds list, e.g. "~fn:()" or "~Trait:". - let mut builtin_bounds = ty::EmptyBuiltinBounds(); - for ast_bounds.iter().advance |ast_bound| { - match *ast_bound { - ast::TraitTyParamBound(b) => { - match lookup_def_tcx(tcx, b.path.span, b.ref_id) { - ast::def_trait(trait_did) => { - if try_add_builtin_trait(tcx, - trait_did, - &mut builtin_bounds) { - loop; // success + match (ast_bounds, store) { + (&Some(ref bound_vec), _) => { + let mut builtin_bounds = ty::EmptyBuiltinBounds(); + for bound_vec.iter().advance |ast_bound| { + match *ast_bound { + ast::TraitTyParamBound(b) => { + match lookup_def_tcx(tcx, b.path.span, b.ref_id) { + ast::def_trait(trait_did) => { + if try_add_builtin_trait(tcx, + trait_did, + &mut builtin_bounds) { + loop; // success + } + } + _ => { } } + tcx.sess.span_fatal( + b.path.span, + fmt!("only the builtin traits can be used \ + as closure or object bounds")); + } + ast::RegionTyParamBound => { + builtin_bounds.add(ty::BoundStatic); } - _ => { } } - tcx.sess.span_fatal( - b.path.span, - fmt!("only the builtin traits can be used \ - as closure or object bounds")); - } - ast::RegionTyParamBound => { - builtin_bounds.add(ty::BoundStatic); } + builtin_bounds + }, + // ~Trait is sugar for ~Trait:Owned. + (&None, ty::UniqTraitStore) => { + let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundOwned); set } + // @Trait is sugar for @Trait:'static. + // &'static Trait is sugar for &'static Trait:'static. + (&None, ty::BoxTraitStore) | + (&None, ty::RegionTraitStore(ty::re_static)) => { + let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundStatic); set + } + // &'r Trait is sugar for &'r Trait:. + (&None, ty::RegionTraitStore(*)) => ty::EmptyBuiltinBounds(), } - builtin_bounds } pub fn try_add_builtin_trait(tcx: ty::ctxt, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 90b2f131b00e..1a7094acf7e4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -771,7 +771,11 @@ pub struct TyClosure { purity: purity, onceness: Onceness, decl: fn_decl, - bounds: OptVec + // Optional optvec distinguishes between "fn()" and "fn:()" so we can + // implement issue #7264. None means "fn()", which means infer a default + // bound based on pointer sigil during typeck. Some(Empty) means "fn:()", + // which means use no bounds (e.g., not even Owned on a ~fn()). + bounds: Option>, } #[deriving(Eq, Encodable, Decodable)] @@ -795,7 +799,7 @@ pub enum ty_ { ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), - ty_path(@Path, @OptVec, node_id), + 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 diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 02d5991e1a7b..2c1b4cfc5915 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -46,7 +46,7 @@ pub trait AstBuilder { 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, @OptVec) -> @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, @@ -265,7 +265,7 @@ impl AstBuilder for @ExtCtxt { } } - fn ty_path(&self, path: @ast::Path, bounds: @OptVec) + fn ty_path(&self, path: @ast::Path, bounds: @Option>) -> @ast::Ty { self.ty(path.span, ast::ty_path(path, bounds, self.next_id())) @@ -275,7 +275,7 @@ impl AstBuilder for @ExtCtxt { // 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), @opt_vec::Empty) + self.ty_path(self.path_ident(span, ident), @None) } fn ty_rptr(&self, @@ -306,7 +306,7 @@ impl AstBuilder for @ExtCtxt { ], None, ~[ ty ]), - @opt_vec::Empty) + @None) } fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field { @@ -344,7 +344,7 @@ impl AstBuilder for @ExtCtxt { 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]), @opt_vec::Empty))) + self.path_global(dummy_sp(), ~[p.ident]), @None))) } fn strip_bounds(&self, generics: &Generics) -> Generics { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 17bbe7a333e6..10d9f878bc45 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -357,7 +357,7 @@ impl<'self> TraitDef<'self> { // 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)), - @opt_vec::Empty); + @None); let doc_attr = cx.attribute( span, diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 9da6bf27eada..2f21eba11d7e 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -63,7 +63,7 @@ impl<'self> Path<'self> { self_generics: &Generics) -> @ast::Ty { cx.ty_path(self.to_path(cx, span, - self_ty, self_generics), @opt_vec::Empty) + self_ty, self_generics), @None) } pub fn to_path(&self, cx: @ExtCtxt, @@ -143,7 +143,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), - @opt_vec::Empty) + @None) } Tuple(ref fields) => { let ty = if fields.is_empty() { diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index a75a20a0fa97..2c5ec0909d95 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -59,7 +59,7 @@ impl gen_send for message { let pipe_ty = cx.ty_path( path(~[this.data_name()], span) - .add_tys(cx.ty_vars(&this.generics.ty_params)), @opt_vec::Empty); + .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); @@ -115,7 +115,7 @@ impl gen_send for message { let mut rty = cx.ty_path(path(~[next.data_name()], span) - .add_tys(copy next_state.tys), @opt_vec::Empty); + .add_tys(copy next_state.tys), @None); if try { rty = cx.ty_option(rty); } @@ -144,7 +144,7 @@ impl gen_send for message { cx.ty_path( path(~[this.data_name()], span) .add_tys(cx.ty_vars( - &this.generics.ty_params)), @opt_vec::Empty))], + &this.generics.ty_params)), @None))], args_ast); let message_args = if arg_names.len() == 0 { @@ -190,7 +190,7 @@ impl gen_send for message { 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)), @opt_vec::Empty) + .add_tys(cx.ty_vars(&self.get_generics().ty_params)), @None) } } @@ -224,7 +224,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), @opt_vec::Empty)) + .add_tys(copy next_state.tys), @None)) } None => tys }; @@ -277,8 +277,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars( - &self.generics.ty_params)), @opt_vec::Empty)), - @opt_vec::Empty), + &self.generics.ty_params)), @None)), + @None), cx.strip_bounds(&self.generics))); } else { @@ -297,8 +297,8 @@ impl to_type_decls for state { self.data_name()], dummy_sp()) .add_tys(cx.ty_vars_global( - &self.generics.ty_params)), @opt_vec::Empty), - self.proto.buffer_ty_path(cx)]), @opt_vec::Empty), + &self.generics.ty_params)), @None), + self.proto.buffer_ty_path(cx)]), @None), cx.strip_bounds(&self.generics))); }; items @@ -383,7 +383,7 @@ 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)), @opt_vec::Empty) + .add_tys(cx.ty_vars_global(¶ms)), @None) } fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item { diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index e86ced847d74..0525c6664780 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -13,7 +13,6 @@ use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::pipes::ast_builder::{append_types, path}; -use opt_vec; #[deriving(Eq)] pub enum direction { send, recv } @@ -100,7 +99,7 @@ impl state_ { 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)), @opt_vec::Empty) + cx.ty_vars(&self.generics.ty_params)), @None) } /// Iterate over the states that can be reached in one message diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2c7c335a8410..2fc111da453c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -651,6 +651,12 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { span: fld.new_span(f.span), } } + fn fold_opt_bounds(b: &Option>, fld: @ast_fold) + -> Option> { + do b.map |bounds| { + do bounds.map |bound| { fold_ty_param_bound(bound, fld) } + } + } match *t { ty_nil | ty_bot | ty_infer => copy *t, ty_box(ref mt) => ty_box(fold_mt(mt, fld)), @@ -664,7 +670,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { purity: f.purity, region: f.region, onceness: f.onceness, - bounds: f.bounds.map(|x| fold_ty_param_bound(x, fld)), + bounds: fold_opt_bounds(&f.bounds, fld), decl: fold_fn_decl(&f.decl, fld), lifetimes: copy f.lifetimes, }) @@ -679,8 +685,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ { } ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))), ty_path(path, bounds, id) => - ty_path(fld.fold_path(path), - @bounds.map(|x| fold_ty_param_bound(x, fld)), fld.new_id(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), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d54c64e7ee60..6dd8d4880e3f 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -490,7 +490,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @opt_vec::Empty, 2), + @None, 2), span:sp(4,7)}, pat: @ast::pat{id:1, node: ast::pat_ident(ast::bind_infer, @@ -526,7 +526,7 @@ mod test { idents:~[str_to_ident("int")], rp: None, types: ~[]}, - @opt_vec::Empty, 2), + @None, 2), span:sp(10,13)}, pat: @ast::pat{id:1, // fixme node: ast::pat_ident( diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b10005aeaf1a..d67771fc4354 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1047,8 +1047,8 @@ impl Parser { // 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, OptVec) { - let mut bounds = opt_vec::Empty; + 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 // macro-generated path. But that's the macro parser's job. @@ -2884,9 +2884,13 @@ impl Parser { // matches optbounds = ( ( : ( boundseq )? )? ) // where boundseq = ( bound + boundseq ) | bound // and bound = 'static | ty - fn parse_optional_ty_param_bounds(&self) -> OptVec { + // Returns "None" if there's no colon (e.g. "T"); + // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:") + // Returns "Some(stuff)" otherwise (e.g. "T:stuff"). + // NB: The None/Some distinction is important for issue #7264. + fn parse_optional_ty_param_bounds(&self) -> Option> { if !self.eat(&token::COLON) { - return opt_vec::Empty; + return None; } let mut result = opt_vec::Empty; @@ -2935,13 +2939,15 @@ impl Parser { } } - return result; + return Some(result); } // matches typaram = IDENT optbounds fn parse_ty_param(&self) -> TyParam { let ident = self.parse_ident(); - let bounds = @self.parse_optional_ty_param_bounds(); + 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); ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } @@ -3288,7 +3294,7 @@ 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, @opt_vec::Empty, node_id) => { + ty_path(path, @None, node_id) => { Some(@trait_ref { path: path, ref_id: node_id diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 277cc6208fb0..0be8c31647f6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1488,7 +1488,7 @@ pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) { } fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, - opt_bounds: Option<@OptVec>) { + opt_bounds: &Option>) { maybe_print_comment(s, path.span.lo); if path.global { word(s.s, "::"); } let mut first = true; @@ -1496,7 +1496,7 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, if first { first = false; } else { word(s.s, "::"); } print_ident(s, *id); } - do opt_bounds.map_consume |bounds| { + do opt_bounds.map |bounds| { print_bounds(s, bounds); }; if path.rp.is_some() || !path.types.is_empty() { @@ -1520,12 +1520,12 @@ 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) + print_path_(s, path, colons_before_params, &None) } pub fn print_bounded_path(s: @ps, path: @ast::Path, - bounds: @OptVec) { - print_path_(s, path, false, Some(bounds)) + bounds: &Option>) { + print_path_(s, path, false, bounds) } pub fn print_irrefutable_pat(s: @ps, pat: @ast::pat) { @@ -1737,7 +1737,7 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { maybe_print_comment(s, decl.output.span.lo); } -pub fn print_bounds(s: @ps, bounds: @OptVec) { +pub fn print_bounds(s: @ps, bounds: &OptVec) { if !bounds.is_empty() { word(s.s, ":"); let mut first = true; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 9b816ce5e5b7..f0a993dbb942 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -246,7 +246,9 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { 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)); - visit_ty_param_bounds(&f.bounds, (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)); } @@ -254,7 +256,9 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { }, ty_path(p, bounds, _) => { visit_path(p, (copy e, v)); - visit_ty_param_bounds(bounds, (e, v)); + do bounds.map |bounds| { + visit_ty_param_bounds(bounds, (copy e, v)); + }; }, ty_fixed_length_vec(ref mt, ex) => { (v.visit_ty)(mt.ty, (copy e, v)); diff --git a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs index c3c8467233c4..098a395f0174 100644 --- a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs +++ b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs @@ -12,7 +12,7 @@ struct X { field: @fn:Copy(), } -fn foo(blk: @fn()) -> X { +fn foo(blk: @fn:()) -> X { return X { field: blk }; //~ ERROR expected bounds `Copy` but found no bounds } diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs index a975349e7302..887346e35e5e 100644 --- a/src/test/compile-fail/closure-bounds-subtype.rs +++ b/src/test/compile-fail/closure-bounds-subtype.rs @@ -1,5 +1,5 @@ -fn take_any(_: &fn()) { +fn take_any(_: &fn:()) { } fn take_copyable(_: &fn:Copy()) { @@ -11,7 +11,7 @@ fn take_copyable_owned(_: &fn:Copy+Owned()) { fn take_const_owned(_: &fn:Const+Owned()) { } -fn give_any(f: &fn()) { +fn give_any(f: &fn:()) { take_any(f); take_copyable(f); //~ ERROR expected bounds `Copy` but found no bounds take_copyable_owned(f); //~ ERROR expected bounds `Copy+Owned` but found no bounds diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs index 88c2d4917473..adaea1de9bd0 100644 --- a/src/test/compile-fail/trait-bounds-cant-coerce.rs +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -21,7 +21,7 @@ fn c(x: ~Foo:Const+Owned) { b(x); //~ ERROR expected bounds `Copy+Owned` } -fn d(x: ~Foo) { +fn d(x: ~Foo:) { a(x); //~ ERROR found no bounds } diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs new file mode 100644 index 000000000000..8c641f4c850d --- /dev/null +++ b/src/test/compile-fail/trait-bounds-sugar.rs @@ -0,0 +1,37 @@ +// 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. + +// Tests for "default" bounds inferred for traits with no bounds list. + +trait Foo { +} + +fn a(_x: ~Foo) { // should be same as ~Foo:Owned +} + +fn b(_x: @Foo) { // should be same as ~Foo:'static +} + +fn c(_x: &'static Foo) { // should be same as &'static Foo:'static +} + +fn d(x: ~Foo:Const) { + a(x); //~ ERROR expected bounds `Owned` +} + +fn e(x: @Foo:Const) { + b(x); //~ ERROR expected bounds `'static` +} + +fn f(x: &'static Foo:Const) { + c(x); //~ ERROR expected bounds `'static` +} + +fn main() { } diff --git a/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs index f39c914916ff..171f2bbb872e 100644 --- a/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs +++ b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs @@ -12,7 +12,7 @@ // Tests correct copying of heap closures' environments. -fn foo(x: ~fn:Copy()) -> (~fn(), ~fn()) { +fn foo(x: ~fn:Copy()) -> (~fn:(), ~fn:()) { (copy x, x) } fn main() { diff --git a/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs index 2fdce4e5c7cd..9bfda034878b 100644 --- a/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs +++ b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs @@ -15,7 +15,7 @@ fn bar(x: T) -> (T, T) { (copy x, x) } -fn foo(x: ~fn:Copy()) -> (~fn(), ~fn()) { +fn foo(x: ~fn:Copy()) -> (~fn:(), ~fn:()) { bar(x) } fn main() { diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs index c51094d26c88..e733400527b2 100644 --- a/src/test/run-pass/kindck-owned-trait-contains-1.rs +++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs @@ -14,9 +14,9 @@ impl repeat for @A { fn get(&self) -> A { copy **self } } -fn repeater(v: @A) -> @repeat { +fn repeater(v: @A) -> @repeat: { // Note: owned kind is not necessary as A appears in the trait type - @v as @repeat // No + @v as @repeat: // No } pub fn main() { diff --git a/src/test/run-pass/regions-trait.rs b/src/test/run-pass/regions-trait.rs index b5b13efa634f..049d5305ca42 100644 --- a/src/test/run-pass/regions-trait.rs +++ b/src/test/run-pass/regions-trait.rs @@ -22,7 +22,7 @@ impl<'self> get_ctxt<'self> for HasCtxt<'self> { } } -fn get_v(gc: @get_ctxt) -> uint { +fn get_v(gc: @get_ctxt:) -> uint { gc.get_ctxt().v } @@ -30,5 +30,5 @@ pub fn main() { let ctxt = Ctxt { v: 22 }; let hc = HasCtxt { c: &ctxt }; - assert_eq!(get_v(@hc as @get_ctxt), 22); + assert_eq!(get_v(@hc as @get_ctxt:), 22); } diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs index b9251c038afa..5bfbf84d8aca 100644 --- a/src/test/run-pass/trait-bounds-basic.rs +++ b/src/test/run-pass/trait-bounds-basic.rs @@ -11,7 +11,7 @@ trait Foo { } -fn a(_x: ~Foo) { +fn a(_x: ~Foo:) { } fn b(_x: ~Foo:Owned) { @@ -25,4 +25,8 @@ fn d(x: ~Foo:Owned+Copy) { b(x); } +fn e(x: ~Foo) { // sugar for ~Foo:Owned + b(x); +} + fn main() { } From 108739f533efd1a4faca62db1afb611f22c5f5f2 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 19 Jun 2013 22:06:50 -0400 Subject: [PATCH 166/336] Looser restrictions on what can be captured in unbounded traits. --- src/libextra/test.rs | 2 +- src/librustc/middle/kind.rs | 11 +++------ src/librustc/middle/ty.rs | 45 +++++++++++++++++++++++++------------ 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index e058a098fa49..ee0d3649467b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -423,7 +423,7 @@ type MonitorMsg = (TestDesc, TestResult); fn run_tests(opts: &TestOpts, tests: ~[TestDescAndFn], - callback: @fn(e: TestEvent)) { + callback: &fn(e: TestEvent)) { let filtered_tests = filter_tests(opts, tests); let filtered_descs = filtered_tests.map(|t| copy t.desc); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 1c669631244c..4dde982c34ca 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -293,9 +293,9 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { expr_cast(source, _) => { check_cast_for_escaping_regions(cx, source, e); match ty::get(ty::expr_ty(cx.tcx, e)).sty { - ty::ty_trait(_, _, store, _, bounds) => { + ty::ty_trait(_, _, _, _, bounds) => { let source_ty = ty::expr_ty(cx.tcx, source); - check_trait_cast_bounds(cx, e.span, source_ty, bounds, store) + check_trait_cast_bounds(cx, e.span, source_ty, bounds) } _ => { } } @@ -391,7 +391,7 @@ pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, } pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t, - bounds: ty::BuiltinBounds, store: ty::TraitStore) { + bounds: ty::BuiltinBounds) { do check_builtin_bounds(cx, ty, bounds) |missing| { cx.tcx.sess.span_err(sp, fmt!("cannot pack type `%s`, which does not fulfill \ @@ -399,11 +399,6 @@ pub fn check_trait_cast_bounds(cx: Context, sp: span, ty: ty::t, ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx), bounds.user_string(cx.tcx))); } - // FIXME(#3569): Remove this check when the corresponding restriction - // is made with type contents. - if store == ty::UniqTraitStore && !ty::type_is_owned(cx.tcx, ty) { - cx.tcx.sess.span_err(sp, "uniquely-owned trait objects must be sendable"); - } } fn is_nullary_variant(cx: Context, ex: @expr) -> bool { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a43025e4ff97..9e6d9e167cd6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2063,20 +2063,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache))) } - ty_trait(_, _, UniqTraitStore, _, _bounds) => { - // FIXME(#3569): Make this conditional on the trait's bounds. - TC_NONCOPY_TRAIT + TC_OWNED_POINTER - } - - ty_trait(_, _, BoxTraitStore, mutbl, _bounds) => { - match mutbl { - ast::m_mutbl => TC_MANAGED + TC_MUTABLE, - _ => TC_MANAGED - } - } - - ty_trait(_, _, RegionTraitStore(r), mutbl, _bounds) => { - borrowed_contents(r, mutbl) + ty_trait(_, _, store, mutbl, bounds) => { + trait_contents(store, mutbl, bounds) } ty_rptr(r, mt) => { @@ -2278,6 +2266,35 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { st + rt + ot } + fn trait_contents(store: TraitStore, mutbl: ast::mutability, + bounds: BuiltinBounds) -> TypeContents { + let st = match store { + UniqTraitStore => TC_OWNED_POINTER, + BoxTraitStore => TC_MANAGED, + RegionTraitStore(r) => borrowed_contents(r, mutbl), + }; + let mt = match mutbl { ast::m_mutbl => TC_MUTABLE, _ => TC_NONE }; + // We get additional "special type contents" for each bound that *isn't* + // on the trait. So iterate over the inverse of the bounds that are set. + // This is like with typarams below, but less "pessimistic" and also + // dependent on the trait store. + let mut bt = TC_NONE; + for (AllBuiltinBounds() - bounds).each |bound| { + bt = bt + match bound { + BoundCopy if store == UniqTraitStore + => TC_NONCOPY_TRAIT, + BoundCopy => TC_NONE, // @Trait/&Trait are copyable either way + BoundStatic if bounds.contains_elem(BoundOwned) + => TC_NONE, // Owned bound implies static bound. + BoundStatic => TC_BORROWED_POINTER, // Useful for "@Trait:'static" + BoundOwned => TC_NON_OWNED, + BoundConst => TC_MUTABLE, + BoundSized => TC_NONE, // don't care if interior is sized + }; + } + st + mt + bt + } + fn type_param_def_to_contents(cx: ctxt, type_param_def: &TypeParameterDef) -> TypeContents { From f8c892ab966e37c7fb8936ace6c7d40c8642f6ab Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 20 Jun 2013 14:25:17 -0400 Subject: [PATCH 167/336] Make closure contents call out to trait_contents. --- src/librustc/middle/ty.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9e6d9e167cd6..e6a1ab212526 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2249,16 +2249,23 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } fn closure_contents(cty: &ClosureTy) -> TypeContents { + // Closure contents are just like trait contents, but with potentially + // even more stuff. let st = match cty.sigil { - ast::BorrowedSigil => TC_BORROWED_POINTER, - ast::ManagedSigil => TC_MANAGED, - ast::OwnedSigil => if cty.bounds.contains_elem(BoundCopy) { - TC_OWNED_POINTER - } else { - TC_OWNED_POINTER + TC_NONCOPY_TRAIT - } + ast::BorrowedSigil => + trait_contents(RegionTraitStore(cty.region), m_imm, cty.bounds) + + TC_BORROWED_POINTER, // might be an env packet even if static + ast::ManagedSigil => + trait_contents(BoxTraitStore, m_imm, cty.bounds), + ast::OwnedSigil => + trait_contents(UniqTraitStore, m_imm, cty.bounds), }; + // FIXME(#3569): This borrowed_contents call should be taken care of in + // trait_contents, after ~Traits and @Traits can have region bounds too. + // This one here is redundant for &fns but important for ~fns and @fns. let rt = borrowed_contents(cty.region, m_imm); + // This also prohibits "@once fn" from being copied, which allows it to + // be called. Neither way really makes much sense. let ot = match cty.onceness { ast::Once => TC_ONCE_CLOSURE, ast::Many => TC_NONE From ffc8c0ba210630121c58290b1652fea66e0d1da8 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Thu, 20 Jun 2013 14:29:19 -0400 Subject: [PATCH 168/336] Looser restrictions on what can be captured in unbounded heap closures. --- src/librustc/middle/kind.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 4dde982c34ca..a1f595fc8969 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -169,10 +169,6 @@ fn with_appropriate_checker(cx: Context, id: node_id, let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); - // FIXME(#3569): Once closure capabilities are restricted based on their - // incoming bounds, make this check conditional based on the bounds. - if !check_owned(cx, var_t, fv.span) { return; } - // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); @@ -184,10 +180,6 @@ fn with_appropriate_checker(cx: Context, id: node_id, let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); - // FIXME(#3569): Once closure capabilities are restricted based on their - // incoming bounds, make this check conditional based on the bounds. - if !check_durable(cx.tcx, var_t, fv.span) { return; } - // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); From d0f56db9630f4b01a6a170aac220aa1b891d5016 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 15:50:38 -0400 Subject: [PATCH 169/336] Change expected error message in kindchk compile-fail tests. --- src/test/compile-fail/kindck-nonsendable-1.rs | 6 +++--- src/test/compile-fail/kindck-owned-trait.rs | 4 +++- src/test/compile-fail/kindck-owned.rs | 3 +-- src/test/compile-fail/no-send-res-ports.rs | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index 928abae24238..38983a9aca6a 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -12,7 +12,7 @@ fn foo(_x: @uint) {} fn main() { let x = @3u; - let _: ~fn() = || foo(x); //~ ERROR value has non-owned type `@uint` - let _: ~fn() = || foo(x); //~ ERROR value has non-owned type `@uint` - let _: ~fn() = || foo(x); //~ ERROR value has non-owned type `@uint` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` } diff --git a/src/test/compile-fail/kindck-owned-trait.rs b/src/test/compile-fail/kindck-owned-trait.rs index 857c71db72ce..c2352e35a46e 100644 --- a/src/test/compile-fail/kindck-owned-trait.rs +++ b/src/test/compile-fail/kindck-owned-trait.rs @@ -11,7 +11,9 @@ trait foo { fn foo(&self); } fn to_foo(t: T) -> @foo { - @t as @foo //~ ERROR value may contain borrowed pointers; add `'static` bound + @t as @foo + //~^ ERROR value may contain borrowed pointers; add `'static` bound + //~^^ ERROR cannot pack type } fn to_foo2(t: T) -> @foo { diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index ec84551f7b0a..3f859b7dc84e 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -9,8 +9,7 @@ // except according to those terms. fn copy1(t: T) -> @fn() -> T { - let result: @fn() -> T = || copy t; - //~^ ERROR value may contain borrowed pointers + let result: @fn() -> T = || copy t; //~ ERROR does not fulfill `'static` result } diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 1f5b600157f2..605e59d56c89 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -32,7 +32,7 @@ fn main() { let x = Cell::new(foo(Port(@()))); do task::spawn { - let y = x.take(); //~ ERROR value has non-owned type + let y = x.take(); //~ ERROR does not fulfill `Owned` error!(y); } } From 21aeb0f6cffa33d2a721e8b130fdc1877c961dc5 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 14:32:05 -0400 Subject: [PATCH 170/336] Fix pretty-printing for bounded closures. Close #7333. --- src/libsyntax/print/pprust.rs | 17 +++++++++++------ .../closure-bounds-copyable-squiggle-closure.rs | 2 -- ...unds-squiggle-closure-as-copyable-typaram.rs | 2 -- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0be8c31647f6..728a5a3d32af 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -410,14 +410,14 @@ pub fn print_type(s: @ps, ty: @ast::Ty) { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; print_ty_fn(s, Some(f.abis), None, None, - f.purity, ast::Many, &f.decl, 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, - f.purity, f.onceness, &f.decl, None, + f.purity, f.onceness, &f.decl, None, &f.bounds, Some(&generics), None); } ast::ty_path(path, bounds, _) => print_bounded_path(s, path, bounds), @@ -806,7 +806,7 @@ pub fn print_ty_method(s: @ps, m: &ast::ty_method) { maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); print_ty_fn(s, None, None, None, m.purity, ast::Many, - &m.decl, Some(m.ident), Some(&m.generics), + &m.decl, Some(m.ident), &None, Some(&m.generics), Some(/*bad*/ copy m.explicit_self.node)); word(s.s, ";"); } @@ -1497,7 +1497,7 @@ fn print_path_(s: @ps, path: @ast::Path, colons_before_params: bool, print_ident(s, *id); } do opt_bounds.map |bounds| { - print_bounds(s, bounds); + print_bounds(s, bounds, true); }; if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, "::"); } @@ -1737,7 +1737,8 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) { maybe_print_comment(s, decl.output.span.lo); } -pub fn print_bounds(s: @ps, bounds: &OptVec) { +pub fn print_bounds(s: @ps, bounds: &OptVec, + print_colon_anyway: bool) { if !bounds.is_empty() { word(s.s, ":"); let mut first = true; @@ -1754,6 +1755,8 @@ pub fn print_bounds(s: @ps, bounds: &OptVec) { RegionTyParamBound => word(s.s, "'static"), } } + } else if print_colon_anyway { + word(s.s, ":"); } } @@ -1774,7 +1777,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); + print_bounds(s, param.bounds, false); } } @@ -1917,6 +1920,7 @@ pub fn print_ty_fn(s: @ps, onceness: ast::Onceness, decl: &ast::fn_decl, id: Option, + opt_bounds: &Option>, generics: Option<&ast::Generics>, opt_explicit_self: Option) { ibox(s, indent_unit); @@ -1930,6 +1934,7 @@ pub fn print_ty_fn(s: @ps, print_onceness(s, onceness); word(s.s, "fn"); match id { Some(id) => { word(s.s, " "); print_ident(s, id); } _ => () } + do opt_bounds.map |bounds| { print_bounds(s, bounds, true); }; match generics { Some(g) => print_generics(s, g), _ => () } zerobreak(s.s); diff --git a/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs index 171f2bbb872e..8c2ae22e8edf 100644 --- a/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs +++ b/src/test/run-pass/closure-bounds-copyable-squiggle-closure.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-pretty - // Tests correct copying of heap closures' environments. fn foo(x: ~fn:Copy()) -> (~fn:(), ~fn:()) { diff --git a/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs index 9bfda034878b..88d474a51e1d 100644 --- a/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs +++ b/src/test/run-pass/closure-bounds-squiggle-closure-as-copyable-typaram.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-pretty - // Tests correct copying of heap closures' environments. fn bar(x: T) -> (T, T) { From 8918461fc41576664719c12ce7d655aaad2c78d1 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 17 May 2013 17:46:01 -0700 Subject: [PATCH 171/336] rt: Release big stacks immediately after use to avoid holding on to them through yields This avoids the following pathological scenario that makes threadring OOM: 1) task calls C using fast_ffi, borrowing a big stack from the scheduler. 2) task returns from C and places the big stack on the task-local stack segment list 3) task calls further Rust functions that require growing the stack, and for this reuses the big stack 4) task yields, failing to return the big stack to the scheduler. 5) repeat 500+ times and OOM Conflicts: src/rt/rust_task.cpp --- src/rt/rust_sched_loop.h | 3 +- src/rt/rust_task.cpp | 56 +++++++-------------------- src/rt/rust_task.h | 19 +++++++-- src/test/bench/shootout-threadring.rs | 18 ++++----- 4 files changed, 40 insertions(+), 56 deletions(-) diff --git a/src/rt/rust_sched_loop.h b/src/rt/rust_sched_loop.h index a099c5e0c749..e0101c46fb99 100644 --- a/src/rt/rust_sched_loop.h +++ b/src/rt/rust_sched_loop.h @@ -211,12 +211,13 @@ rust_sched_loop::return_c_stack(stk_seg *stack) { // NB: Runs on the Rust stack. Might return NULL! inline stk_seg * rust_sched_loop::borrow_big_stack() { - assert(cached_big_stack); stk_seg *your_stack; if (extra_big_stack) { your_stack = extra_big_stack; extra_big_stack = NULL; } else { + // NB: This may be null if we're asking for a *second* + // big stack, in which case the caller will fall back to a slow path your_stack = cached_big_stack; cached_big_stack = NULL; } diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 81ae991623f8..4d6d2567cd45 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -54,8 +54,7 @@ rust_task::rust_task(rust_sched_loop *sched_loop, rust_task_state state, disallow_yield(0), c_stack(NULL), next_c_sp(0), - next_rust_sp(0), - big_stack(NULL) + next_rust_sp(0) { LOGPTR(sched_loop, "new task", (uintptr_t)this); DLOG(sched_loop, task, "sizeof(task) = %d (0x%x)", @@ -566,14 +565,8 @@ rust_task::cleanup_after_turn() { while (stk->next) { stk_seg *new_next = stk->next->next; - - if (stk->next->is_big) { - assert (big_stack == stk->next); - sched_loop->return_big_stack(big_stack); - big_stack = NULL; - } else { - free_stack(stk->next); - } + assert (!stk->next->is_big); + free_stack(stk->next); stk->next = new_next; } @@ -584,38 +577,20 @@ rust_task::cleanup_after_turn() { bool rust_task::new_big_stack() { assert(stk); - // If we have a cached big stack segment, use it. - if (big_stack) { - // Check to see if we're already on the big stack. - stk_seg *ss = stk; - while (ss != NULL) { - if (ss == big_stack) - return false; - ss = ss->prev; - } - // Unlink the big stack. - if (big_stack->next) - big_stack->next->prev = big_stack->prev; - if (big_stack->prev) - big_stack->prev->next = big_stack->next; - } else { - stk_seg *borrowed_big_stack = sched_loop->borrow_big_stack(); - if (!borrowed_big_stack) { - abort(); - } else { - big_stack = borrowed_big_stack; - } + stk_seg *borrowed_big_stack = sched_loop->borrow_big_stack(); + if (!borrowed_big_stack) { + return false; } - big_stack->task = this; - big_stack->next = stk->next; - if (big_stack->next) - big_stack->next->prev = big_stack; - big_stack->prev = stk; - stk->next = big_stack; + borrowed_big_stack->task = this; + borrowed_big_stack->next = stk->next; + if (borrowed_big_stack->next) + borrowed_big_stack->next->prev = borrowed_big_stack; + borrowed_big_stack->prev = stk; + stk->next = borrowed_big_stack; - stk = big_stack; + stk = borrowed_big_stack; return true; } @@ -640,10 +615,9 @@ void rust_task::reset_stack_limit() { uintptr_t sp = get_sp(); while (!sp_in_stk_seg(sp, stk)) { - stk = stk->prev; + prev_stack(); assert(stk != NULL && "Failed to find the current stack"); } - record_stack_limit(); } void @@ -667,8 +641,6 @@ rust_task::delete_all_stacks() { stk = prev; } - - big_stack = NULL; } /* diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 982102cdde0c..1735d35b0652 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -278,9 +278,6 @@ private: uintptr_t next_c_sp; uintptr_t next_rust_sp; - // The big stack. - stk_seg *big_stack; - // Called when the atomic refcount reaches zero void delete_this(); @@ -607,7 +604,21 @@ rust_task::prev_stack() { // require switching to the C stack and be costly. Instead we'll just move // up the link list and clean up later, either in new_stack or after our // turn ends on the scheduler. - stk = stk->prev; + if (stk->is_big) { + stk_seg *ss = stk; + stk = stk->prev; + + // Unlink the big stack. + if (ss->next) + ss->next->prev = ss->prev; + if (ss->prev) + ss->prev->next = ss->next; + + sched_loop->return_big_stack(ss); + } else { + stk = stk->prev; + } + record_stack_limit(); } diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 213c5140ccf0..a67bbb05dfb5 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -10,18 +10,18 @@ // Based on threadring.erlang by Jira Isa -// xfail-test FIXME #5985 OOM's on the mac bot +use std::os; fn start(n_tasks: int, token: int) { - let mut (p, ch1) = comm::stream(); + let mut (p, ch1) = stream(); ch1.send(token); // XXX could not get this to work with a range closure let mut i = 2; while i <= n_tasks { - let (next_p, ch) = comm::stream(); + let (next_p, ch) = stream(); let imm_i = i; let imm_p = p; - do task::spawn { + do spawn { roundtrip(imm_i, n_tasks, &imm_p, &ch); }; p = next_p; @@ -29,16 +29,16 @@ fn start(n_tasks: int, token: int) { } let imm_p = p; let imm_ch = ch1; - do task::spawn { + do spawn { roundtrip(1, n_tasks, &imm_p, &imm_ch); } } -fn roundtrip(id: int, n_tasks: int, p: &comm::Port, ch: &comm::Chan) { +fn roundtrip(id: int, n_tasks: int, p: &Port, ch: &Chan) { while (true) { match p.recv() { 1 => { - io::println(fmt!("%d\n", id)); + println(fmt!("%d\n", id)); return; } token => { @@ -60,13 +60,13 @@ fn main() { os::args() }; let token = if args.len() > 1u { - int::from_str(args[1]).get() + FromStr::from_str(args[1]).get() } else { 1000 }; let n_tasks = if args.len() > 2u { - int::from_str(args[2]).get() + FromStr::from_str(args[2]).get() } else { 503 From c37ccac9313b52a8f4299b370fe33b0fbe202db4 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 15:35:02 -0400 Subject: [PATCH 172/336] Add a run-pass test for existential traits in ARCs. --- src/test/run-pass/trait-bounds-in-arc.rs | 103 +++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/test/run-pass/trait-bounds-in-arc.rs diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs new file mode 100644 index 000000000000..585c2185a7ec --- /dev/null +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -0,0 +1,103 @@ +// 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. + +// Tests that a heterogeneous list of existential types can be put inside an ARC +// and shared between tasks as long as all types fulfill Const+Owned. + +// xfail-fast + +extern mod extra; +use extra::arc; +use std::comm; +use std::task; +use std::cell; + +trait Pet { + fn name(&self, blk: &fn(&str)); + fn num_legs(&self) -> uint; + fn of_good_pedigree(&self) -> bool; +} + +struct Catte { + num_whiskers: uint, + name: ~str, +} + +struct Dogge { + bark_decibels: uint, + tricks_known: uint, + name: ~str, +} + +struct Goldfyshe { + swim_speed: uint, + name: ~str, +} + +impl Pet for Catte { + fn name(&self, blk: &fn(&str)) { blk(self.name) } + fn num_legs(&self) -> uint { 4 } + fn of_good_pedigree(&self) -> bool { self.num_whiskers >= 4 } +} +impl Pet for Dogge { + fn name(&self, blk: &fn(&str)) { blk(self.name) } + fn num_legs(&self) -> uint { 4 } + fn of_good_pedigree(&self) -> bool { + self.bark_decibels < 70 || self.tricks_known > 20 + } +} +impl Pet for Goldfyshe { + fn name(&self, blk: &fn(&str)) { blk(self.name) } + fn num_legs(&self) -> uint { 0 } + fn of_good_pedigree(&self) -> bool { self.swim_speed >= 500 } +} + +fn main() { + let catte = Catte { num_whiskers: 7, name: ~"alonzo_church" }; + let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" }; + let dogge2 = Dogge { bark_decibels: 55, tricks_known: 11, name: ~"albert_einstein" }; + let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" }; + let arc = arc::ARC(~[~catte as ~Pet:Const+Owned, + ~dogge1 as ~Pet:Const+Owned, + ~fishe as ~Pet:Const+Owned, + ~dogge2 as ~Pet:Const+Owned]); + let (p1,c1) = comm::stream(); + let arc1 = cell::Cell::new(arc.clone()); + do task::spawn { check_legs(arc1.take()); c1.send(()); } + let (p2,c2) = comm::stream(); + let arc2 = cell::Cell::new(arc.clone()); + do task::spawn { check_names(arc2.take()); c2.send(()); } + let (p3,c3) = comm::stream(); + let arc3 = cell::Cell::new(arc.clone()); + do task::spawn { check_pedigree(arc3.take()); c3.send(()); } + p1.recv(); + p2.recv(); + p3.recv(); +} + +fn check_legs(arc: arc::ARC<~[~Pet:Const+Owned]>) { + let mut legs = 0; + for arc.get().iter().advance |pet| { + legs += pet.num_legs(); + } + assert!(legs == 12); +} +fn check_names(arc: arc::ARC<~[~Pet:Const+Owned]>) { + for arc.get().iter().advance |pet| { + do pet.name |name| { + assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8); + } + } +} +fn check_pedigree(arc: arc::ARC<~[~Pet:Const+Owned]>) { + for arc.get().iter().advance |pet| { + assert!(pet.of_good_pedigree()); + } +} From 394d28cac54b936bf5c3d1420229b52156744e7f Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Wed, 26 Jun 2013 18:22:15 -0400 Subject: [PATCH 173/336] Fix old .each usage --- src/librustc/metadata/loader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 17aad969e325..9e0d6fb8e3a6 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -128,7 +128,7 @@ fn find_library_crate_aux( cx.diag.span_err( cx.span, fmt!("multiple matching crates for `%s`", crate_name)); cx.diag.handler().note("candidates:"); - for matches.each |&(ident, data)| { + for matches.iter().advance |&(ident, data)| { cx.diag.handler().note(fmt!("path: %s", ident)); let attrs = decoder::get_crate_attributes(data); note_linkage_attrs(cx.intr, cx.diag, attrs); @@ -140,7 +140,7 @@ fn find_library_crate_aux( } pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { - for metas.each |m| { + for metas.iter().advance |m| { match m.node { ast::meta_name_value(s, ref l) if s == @"name" => match l.node { From 82fa5b615ec65501abccb470fe71c1aff1f29fc8 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Tue, 25 Jun 2013 15:21:05 -0700 Subject: [PATCH 174/336] Fix run-pass/match-borrowed_str.rs Fixes #7306 --- src/test/run-pass/match-borrowed_str.rs | 78 +++++++++++++------------ 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/src/test/run-pass/match-borrowed_str.rs b/src/test/run-pass/match-borrowed_str.rs index 99e1ae6ec56e..346f2d07a4b7 100644 --- a/src/test/run-pass/match-borrowed_str.rs +++ b/src/test/run-pass/match-borrowed_str.rs @@ -1,55 +1,61 @@ -// FIXME #7306 -// xfail-fast +// 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. -use std::io; - -fn f1(ref_string: &str) { +fn f1(ref_string: &str) -> ~str { match ref_string { - "a" => io::println("found a"), - "b" => io::println("found b"), - _ => io::println("not found") + "a" => ~"found a", + "b" => ~"found b", + _ => ~"not found" } } -fn f2(ref_string: &str) { +fn f2(ref_string: &str) -> ~str { match ref_string { - "a" => io::println("found a"), - "b" => io::println("found b"), - s => io::println(fmt!("not found (%s)", s)) + "a" => ~"found a", + "b" => ~"found b", + s => fmt!("not found (%s)", s) } } -fn g1(ref_1: &str, ref_2: &str) { +fn g1(ref_1: &str, ref_2: &str) -> ~str { match (ref_1, ref_2) { - ("a", "b") => io::println("found a,b"), - ("b", "c") => io::println("found b,c"), - _ => io::println("not found") + ("a", "b") => ~"found a,b", + ("b", "c") => ~"found b,c", + _ => ~"not found" } } -fn g2(ref_1: &str, ref_2: &str) { +fn g2(ref_1: &str, ref_2: &str) -> ~str { match (ref_1, ref_2) { - ("a", "b") => io::println("found a,b"), - ("b", "c") => io::println("found b,c"), - (s1, s2) => io::println(fmt!("not found (%s, %s)", s1, s2)) + ("a", "b") => ~"found a,b", + ("b", "c") => ~"found b,c", + (s1, s2) => fmt!("not found (%s, %s)", s1, s2) } } pub fn main() { - f1(@"a"); - f1(~"b"); - f1(&"c"); - f1("d"); - f2(@"a"); - f2(~"b"); - f2(&"c"); - f2("d"); - g1(@"a", @"b"); - g1(~"b", ~"c"); - g1(&"c", &"d"); - g1("d", "e"); - g2(@"a", @"b"); - g2(~"b", ~"c"); - g2(&"c", &"d"); - g2("d", "e"); + assert_eq!(f1(@"a"), ~"found a"); + assert_eq!(f1(~"b"), ~"found b"); + assert_eq!(f1(&"c"), ~"not found"); + assert_eq!(f1("d"), ~"not found"); + assert_eq!(f2(@"a"), ~"found a"); + assert_eq!(f2(~"b"), ~"found b"); + assert_eq!(f2(&"c"), ~"not found (c)"); + assert_eq!(f2("d"), ~"not found (d)"); + assert_eq!(g1(@"a", @"b"), ~"found a,b"); + assert_eq!(g1(~"b", ~"c"), ~"found b,c"); + assert_eq!(g1(&"c", &"d"), ~"not found"); + assert_eq!(g1("d", "e"), ~"not found"); + assert_eq!(g2(@"a", @"b"), ~"found a,b"); + assert_eq!(g2(~"b", ~"c"), ~"found b,c"); + assert_eq!(g2(&"c", &"d"), ~"not found (c, d)"); + assert_eq!(g2("d", "e"), ~"not found (d, e)"); } + From 808b52351a82bc2730e5b5f31adf86167b1d60b9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Wed, 26 Jun 2013 17:19:06 +0530 Subject: [PATCH 175/336] treemap: remove .each in favor of .iter().advance Both extra::treemap::TreeMap and extra::treemap::TreeSet have corresponding iterators TreeMapIterator and TreeSetIterator. Unfortunately, the tests and extra::serialize use the older .each. Update all the dependent code, and remove .each. Signed-off-by: Ramkumar Ramachandra --- src/libextra/serialize.rs | 4 ++-- src/libextra/treemap.rs | 23 +++++++---------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 345b217871cc..3d35d1332b2f 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -832,7 +832,7 @@ impl< fn encode(&self, e: &mut E) { do e.emit_map(self.len()) |e| { let mut i = 0; - for self.each |key, val| { + for self.iter().advance |(key, val)| { e.emit_map_elt_key(i, |e| key.encode(e)); e.emit_map_elt_val(i, |e| val.encode(e)); i += 1; @@ -866,7 +866,7 @@ impl< fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { let mut i = 0; - for self.each |e| { + for self.iter().advance |e| { s.emit_seq_elt(i, |s| e.encode(s)); i += 1; } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index fd83fd199167..33ec4ae94ba5 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -164,19 +164,14 @@ impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } - /// Visit all key-value pairs in order - pub fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { - each(&self.root, f) - } - /// Visit all keys in order pub fn each_key(&self, f: &fn(&K) -> bool) -> bool { - self.each(|k, _| f(k)) + self.iter().advance(|(k, _)| f(k)) } /// Visit all values in order pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { - self.each(|_, v| f(v)) + self.iter().advance(|(_, v)| f(v)) } /// Iterate over the map and mutate the contained values @@ -484,10 +479,6 @@ impl TreeSet { TreeSetIterator{iter: self.map.iter()} } - /// Visit all values in order - #[inline] - pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } - /// Visit all values in reverse order #[inline] pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { @@ -779,7 +770,7 @@ mod test_treemap { let &(k, v) = x; assert!(map.find(&k).unwrap() == &v) } - for map.each |map_k, map_v| { + for map.iter().advance |(map_k, map_v)| { let mut found = false; for ctrl.iter().advance |x| { let &(ctrl_k, ctrl_v) = x; @@ -885,7 +876,7 @@ mod test_treemap { } #[test] - fn test_each() { + fn test_iterator() { let mut m = TreeMap::new(); assert!(m.insert(3, 6)); @@ -895,7 +886,7 @@ mod test_treemap { assert!(m.insert(1, 2)); let mut n = 0; - for m.each |k, v| { + for m.iter().advance |(k, v)| { assert_eq!(*k, n); assert_eq!(*v, n * 2); n += 1; @@ -1090,7 +1081,7 @@ mod test_set { } #[test] - fn test_each() { + fn test_iterator() { let mut m = TreeSet::new(); assert!(m.insert(3)); @@ -1100,7 +1091,7 @@ mod test_set { assert!(m.insert(1)); let mut n = 0; - for m.each |x| { + for m.iter().advance |x| { println(fmt!("%?", x)); assert_eq!(*x, n); n += 1 From 332671c4794f159129eeb948aef4b5e928d38894 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 26 Jun 2013 15:34:12 -0700 Subject: [PATCH 176/336] Whitespace --- src/compiletest/compiletest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 527e472b0b7b..683d5fecc349 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -261,7 +261,7 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { let dir = path.pop().filename(); fmt!("%s/%s", dir.get_or_default(~""), filename.get_or_default(~"")) } - + test::DynTestName(fmt!("[%s] %s", mode_str(config.mode), shorten(testfile))) From 58fc1fccad8a0343dd7399a44305b5b3a51a9547 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Wed, 26 Jun 2013 19:00:44 -0400 Subject: [PATCH 177/336] last bit of whitespace --- src/test/run-pass/match-borrowed_str.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/run-pass/match-borrowed_str.rs b/src/test/run-pass/match-borrowed_str.rs index 346f2d07a4b7..7a30f5152d01 100644 --- a/src/test/run-pass/match-borrowed_str.rs +++ b/src/test/run-pass/match-borrowed_str.rs @@ -58,4 +58,3 @@ pub fn main() { assert_eq!(g2(&"c", &"d"), ~"not found (c, d)"); assert_eq!(g2("d", "e"), ~"not found (d, e)"); } - From 9f5f609b1c9a70d2034ed25a79961503843bb9c7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 26 Jun 2013 19:37:19 -0400 Subject: [PATCH 178/336] vec: remove superseded reverse_part function `reverse(xs.mut_slice(a, b))` replaces `reverse_part(xs, a, b)` --- src/libstd/vec.rs | 42 ++---------------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index b707530ebce0..56e6bacf93e3 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1300,44 +1300,6 @@ pub fn reverse(v: &mut [T]) { } } -/** - * Reverse part of a vector in place. - * - * Reverse the elements in the vector between `start` and `end - 1`. - * - * If either start or end do not represent valid positions in the vector, the - * vector is returned unchanged. - * - * # Arguments - * - * * `v` - The mutable vector to be modified - * - * * `start` - Index of the first element of the slice - * - * * `end` - Index one past the final element to be reversed. - * - * # Example - * - * Assume a mutable vector `v` contains `[1,2,3,4,5]`. After the call: - * - * ~~~ {.rust} - * reverse_part(v, 1, 4); - * ~~~ - * - * `v` now contains `[1,4,3,2,5]`. - */ -pub fn reverse_part(v: &mut [T], start: uint, end : uint) { - let sz = v.len(); - if start >= sz || end > sz { return; } - let mut i = start; - let mut j = end - 1; - while i < j { - vec::swap(v, i, j); - i += 1; - j -= 1; - } -} - /// Returns a vector with the order of elements reversed pub fn reversed(v: &const [T]) -> ~[T] { let mut rs: ~[T] = ~[]; @@ -1394,7 +1356,7 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> // swap indices[k] and indices[l]; sort indices[k+1..] // (they're just reversed) vec::swap(indices, k, l); - reverse_part(indices, k+1, length); + reverse(indices.mut_slice(k+1, length)); // fixup permutation based on indices for uint::range(k, length) |i| { permutation[i] = copy values[indices[i]]; @@ -3971,7 +3933,7 @@ mod tests { #[test] fn test_reverse_part() { let mut values = [1,2,3,4,5]; - reverse_part(values,1,4); + reverse(values.mut_slice(1, 4)); assert_eq!(values, [1,4,3,2,5]); } From e8151de88ff7186d2eaf9b55be087343c148451d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 26 Jun 2013 17:44:36 -0700 Subject: [PATCH 179/336] Update version number to 0.7-pre. There's a reason we didn't update this after 0.6 but I don't know what it is. Let's see what breaks. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index fa6c78065813..0404e2bdee6c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -139,7 +139,7 @@ endif # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git -CFG_RELEASE = 0.6 +CFG_RELEASE = 0.7-pre CFG_VERSION = $(CFG_RELEASE) ifneq ($(wildcard $(CFG_GIT)),) From ab428b648001030a0ea71c61dd89a531109c0cdd Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Wed, 26 Jun 2013 20:02:34 -0400 Subject: [PATCH 180/336] Fix deque tests --- src/libextra/deque.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index b82984cb2c54..e6a7dd648373 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -257,6 +257,7 @@ mod tests { use core::cmp::Eq; use core::kinds::Copy; use core::vec::capacity; + use core; #[test] fn test_simple() { @@ -463,12 +464,12 @@ mod tests { #[test] fn test_iter() { let mut d = Deque::new(); - for std::int::range(0,5) |i| { + for core::int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]); - for std::int::range(6,9) |i| { + for core::int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]); @@ -477,12 +478,12 @@ mod tests { #[test] fn test_rev_iter() { let mut d = Deque::new(); - for std::int::range(0,5) |i| { + for core::int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]); - for std::int::range(6,9) |i| { + for core::int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); From d0512b1055eac15db86d83c994fb546cbfa62676 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 27 Jun 2013 19:48:50 +1000 Subject: [PATCH 181/336] Convert vec::[mut_]slice to methods, remove vec::const_slice. --- src/compiletest/runtest.rs | 3 +- src/libextra/crypto/sha2.rs | 79 +++++++------- src/libextra/ebml.rs | 3 +- src/libextra/net_tcp.rs | 4 +- src/libextra/num/bigint.rs | 17 ++- src/libextra/sort.rs | 24 ++--- src/librustc/back/rpath.rs | 2 +- src/librustc/metadata/decoder.rs | 4 +- src/librustc/metadata/tydecode.rs | 5 +- src/librustc/middle/dataflow.rs | 22 ++-- src/librustc/middle/kind.rs | 1 - src/librustc/middle/trans/_match.rs | 14 +-- src/librustc/middle/trans/common.rs | 7 +- src/librustc/middle/trans/meth.rs | 2 +- src/librusti/rusti.rs | 4 +- src/librustpkg/package_source.rs | 5 +- src/libstd/io.rs | 11 +- src/libstd/os.rs | 2 +- src/libstd/rt/io/extensions.rs | 2 +- src/libstd/rt/io/mem.rs | 2 +- src/libstd/vec.rs | 100 +++++++----------- src/libsyntax/diagnostic.rs | 3 +- src/test/bench/core-std.rs | 2 +- src/test/bench/shootout-fasta-redux.rs | 2 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 6 +- src/test/bench/shootout-k-nucleotide.rs | 10 +- src/test/bench/shootout-pfib.rs | 3 +- src/test/run-pass/issue-3888-2.rs | 6 +- src/test/run-pass/vec-slice.rs | 4 +- 29 files changed, 151 insertions(+), 198 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 3e2f484ee53d..a31e0b961f7f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -321,8 +321,7 @@ fn check_error_patterns(props: &TestProps, if done { return; } let missing_patterns = - vec::slice(props.error_patterns, next_err_idx, - props.error_patterns.len()); + props.error_patterns.slice(next_err_idx, props.error_patterns.len()); if missing_patterns.len() == 1u { fatal_ProcRes(fmt!("error pattern '%s' not found!", missing_patterns[0]), ProcRes); diff --git a/src/libextra/crypto/sha2.rs b/src/libextra/crypto/sha2.rs index dd179fde70f5..e9c6ac722124 100644 --- a/src/libextra/crypto/sha2.rs +++ b/src/libextra/crypto/sha2.rs @@ -11,7 +11,6 @@ use core::prelude::*; use core::uint; -use core::vec; use digest::Digest; @@ -118,7 +117,7 @@ impl Engine512 { } while in.len() - i >= 8 { - let w = to_u64(vec::slice(in, i, i + 8)); + let w = to_u64(in.slice(i, i + 8)); self.process_word(w); self.bit_counter.add_bytes(8); i += 8; @@ -274,43 +273,43 @@ impl Engine512 { fn result_512(&mut self, out: &mut [u8]) { self.finish(); - from_u64(self.H0, vec::mut_slice(out, 0, 8)); - from_u64(self.H1, vec::mut_slice(out, 8, 16)); - from_u64(self.H2, vec::mut_slice(out, 16, 24)); - from_u64(self.H3, vec::mut_slice(out, 24, 32)); - from_u64(self.H4, vec::mut_slice(out, 32, 40)); - from_u64(self.H5, vec::mut_slice(out, 40, 48)); - from_u64(self.H6, vec::mut_slice(out, 48, 56)); - from_u64(self.H7, vec::mut_slice(out, 56, 64)); + from_u64(self.H0, out.mut_slice(0, 8)); + from_u64(self.H1, out.mut_slice(8, 16)); + from_u64(self.H2, out.mut_slice(16, 24)); + from_u64(self.H3, out.mut_slice(24, 32)); + from_u64(self.H4, out.mut_slice(32, 40)); + from_u64(self.H5, out.mut_slice(40, 48)); + from_u64(self.H6, out.mut_slice(48, 56)); + from_u64(self.H7, out.mut_slice(56, 64)); } fn result_384(&mut self, out: &mut [u8]) { self.finish(); - from_u64(self.H0, vec::mut_slice(out, 0, 8)); - from_u64(self.H1, vec::mut_slice(out, 8, 16)); - from_u64(self.H2, vec::mut_slice(out, 16, 24)); - from_u64(self.H3, vec::mut_slice(out, 24, 32)); - from_u64(self.H4, vec::mut_slice(out, 32, 40)); - from_u64(self.H5, vec::mut_slice(out, 40, 48)); + from_u64(self.H0, out.mut_slice(0, 8)); + from_u64(self.H1, out.mut_slice(8, 16)); + from_u64(self.H2, out.mut_slice(16, 24)); + from_u64(self.H3, out.mut_slice(24, 32)); + from_u64(self.H4, out.mut_slice(32, 40)); + from_u64(self.H5, out.mut_slice(40, 48)); } fn result_256(&mut self, out: &mut [u8]) { self.finish(); - from_u64(self.H0, vec::mut_slice(out, 0, 8)); - from_u64(self.H1, vec::mut_slice(out, 8, 16)); - from_u64(self.H2, vec::mut_slice(out, 16, 24)); - from_u64(self.H3, vec::mut_slice(out, 24, 32)); + from_u64(self.H0, out.mut_slice(0, 8)); + from_u64(self.H1, out.mut_slice(8, 16)); + from_u64(self.H2, out.mut_slice(16, 24)); + from_u64(self.H3, out.mut_slice(24, 32)); } fn result_224(&mut self, out: &mut [u8]) { self.finish(); - from_u64(self.H0, vec::mut_slice(out, 0, 8)); - from_u64(self.H1, vec::mut_slice(out, 8, 16)); - from_u64(self.H2, vec::mut_slice(out, 16, 24)); - from_u32((self.H3 >> 32) as u32, vec::mut_slice(out, 24, 28)); + from_u64(self.H0, out.mut_slice(0, 8)); + from_u64(self.H1, out.mut_slice(8, 16)); + from_u64(self.H2, out.mut_slice(16, 24)); + from_u32((self.H3 >> 32) as u32, out.mut_slice(24, 28)); } } @@ -400,7 +399,7 @@ impl Engine256 { } while in.len() - i >= 4 { - let w = to_u32(vec::slice(in, i, i + 4)); + let w = to_u32(in.slice(i, i + 4)); self.process_word(w); self.length_bytes += 4; i += 4; @@ -556,26 +555,26 @@ impl Engine256 { fn result_256(&mut self, out: &mut [u8]) { self.finish(); - from_u32(self.H0, vec::mut_slice(out, 0, 4)); - from_u32(self.H1, vec::mut_slice(out, 4, 8)); - from_u32(self.H2, vec::mut_slice(out, 8, 12)); - from_u32(self.H3, vec::mut_slice(out, 12, 16)); - from_u32(self.H4, vec::mut_slice(out, 16, 20)); - from_u32(self.H5, vec::mut_slice(out, 20, 24)); - from_u32(self.H6, vec::mut_slice(out, 24, 28)); - from_u32(self.H7, vec::mut_slice(out, 28, 32)); + from_u32(self.H0, out.mut_slice(0, 4)); + from_u32(self.H1, out.mut_slice(4, 8)); + from_u32(self.H2, out.mut_slice(8, 12)); + from_u32(self.H3, out.mut_slice(12, 16)); + from_u32(self.H4, out.mut_slice(16, 20)); + from_u32(self.H5, out.mut_slice(20, 24)); + from_u32(self.H6, out.mut_slice(24, 28)); + from_u32(self.H7, out.mut_slice(28, 32)); } fn result_224(&mut self, out: &mut [u8]) { self.finish(); - from_u32(self.H0, vec::mut_slice(out, 0, 4)); - from_u32(self.H1, vec::mut_slice(out, 4, 8)); - from_u32(self.H2, vec::mut_slice(out, 8, 12)); - from_u32(self.H3, vec::mut_slice(out, 12, 16)); - from_u32(self.H4, vec::mut_slice(out, 16, 20)); - from_u32(self.H5, vec::mut_slice(out, 20, 24)); - from_u32(self.H6, vec::mut_slice(out, 24, 28)); + from_u32(self.H0, out.mut_slice(0, 4)); + from_u32(self.H1, out.mut_slice(4, 8)); + from_u32(self.H2, out.mut_slice(8, 12)); + from_u32(self.H3, out.mut_slice(12, 16)); + from_u32(self.H4, out.mut_slice(16, 20)); + from_u32(self.H5, out.mut_slice(20, 24)); + from_u32(self.H6, out.mut_slice(24, 28)); } } diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index dd08f23a7a10..92a027100daf 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -85,7 +85,6 @@ pub mod reader { use core::ptr::offset; use core::str; use core::unstable::intrinsics::bswap32; - use core::vec; // ebml reading @@ -248,7 +247,7 @@ pub mod reader { } pub fn with_doc_data(d: Doc, f: &fn(x: &[u8]) -> T) -> T { - f(vec::slice(*d.data, d.start, d.end)) + f(d.data.slice(d.start, d.end)) } diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index 6ad51931c676..f8ecac373a6c 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -976,9 +976,7 @@ impl io::Writer for TcpSocketBuf { let socket_data_ptr: *TcpSocketData = &(*((*(self.data)).sock).socket_data); let w_result = write_common_impl(socket_data_ptr, - vec::slice(data, - 0, - data.len()).to_owned()); + data.slice(0, data.len()).to_owned()); if w_result.is_err() { let err_data = w_result.get_err(); debug!( diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 4b080e0153cc..1ac913e8a00d 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -298,9 +298,8 @@ impl Mul for BigUint { fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { let mid = uint::min(a.data.len(), n); - return (BigUint::from_slice(vec::slice(a.data, mid, - a.data.len())), - BigUint::from_slice(vec::slice(a.data, 0, mid))); + return (BigUint::from_slice(a.data.slice(mid, a.data.len())), + BigUint::from_slice(a.data.slice(0, mid))); } @@ -413,7 +412,7 @@ impl Integer for BigUint { return (Zero::zero(), Zero::zero(), copy *a); } - let an = vec::slice(a.data, a.data.len() - n, a.data.len()); + let an = a.data.slice(a.data.len() - n, a.data.len()); let bn = *b.data.last(); let mut d = ~[]; let mut carry = 0; @@ -578,7 +577,7 @@ impl BigUint { let mut power: BigUint = One::one(); loop { let start = uint::max(end, unit_len) - unit_len; - match uint::parse_bytes(vec::slice(buf, start, end), radix) { + match uint::parse_bytes(buf.slice(start, end), radix) { // FIXME(#6102): Assignment operator for BigInt causes ICE // Some(d) => n += BigUint::from_uint(d) * power, Some(d) => n = n + BigUint::from_uint(d) * power, @@ -634,7 +633,7 @@ impl BigUint { if n_unit == 0 { return copy *self; } if self.data.len() < n_unit { return Zero::zero(); } return BigUint::from_slice( - vec::slice(self.data, n_unit, self.data.len()) + self.data.slice(n_unit, self.data.len()) ); } @@ -1132,7 +1131,7 @@ impl BigInt { sign = Minus; start = 1; } - return BigUint::parse_bytes(vec::slice(buf, start, buf.len()), radix) + return BigUint::parse_bytes(buf.slice(start, buf.len()), radix) .map_consume(|bu| BigInt::from_biguint(sign, bu)); } @@ -1176,7 +1175,7 @@ mod biguint_tests { let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ] .map(|v| BigUint::from_slice(*v)); for data.iter().enumerate().advance |(i, ni)| { - for vec::slice(data, i, data.len()).iter().enumerate().advance |(j0, nj)| { + for data.slice(i, data.len()).iter().enumerate().advance |(j0, nj)| { let j = j0 + i; if i == j { assert_eq!(ni.cmp(nj), Equal); @@ -1654,7 +1653,7 @@ mod bigint_tests { nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s))); for nums.iter().enumerate().advance |(i, ni)| { - for vec::slice(nums, i, nums.len()).iter().enumerate().advance |(j0, nj)| { + for nums.slice(i, nums.len()).iter().enumerate().advance |(j0, nj)| { let j = i + j0; if i == j { assert_eq!(ni.cmp(nj), Equal); diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 3c872d64ca05..5377dfadbaa1 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -57,8 +57,8 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { a_ix += 1; } else { rs.push(copy b[b_ix]); b_ix += 1; } } - rs.push_all(vec::slice(a, a_ix, a_len)); - rs.push_all(vec::slice(b, b_ix, b_len)); + rs.push_all(a.slice(a_ix, a_len)); + rs.push_all(b.slice(b_ix, b_len)); rs } } @@ -201,12 +201,12 @@ pub fn tim_sort(array: &mut [T]) { loop { let run_len: uint = { // This scope contains the slice `arr` here: - let arr = vec::mut_slice(array, idx, size); + let arr = array.mut_slice(idx, size); let mut run_len: uint = count_run_ascending(arr); if run_len < min_run { let force = if remaining <= min_run {remaining} else {min_run}; - let slice = vec::mut_slice(arr, 0, force); + let slice = arr.mut_slice(0, force); binarysort(slice, run_len); run_len = force; } @@ -443,14 +443,14 @@ impl MergeState { } let k = { // constrain lifetime of slice below - let slice = vec::slice(array, b1, b1+l1); + let slice = array.slice(b1, b1+l1); gallop_right(&array[b2], slice, 0) }; b1 += k; l1 -= k; if l1 != 0 { let l2 = { // constrain lifetime of slice below - let slice = vec::slice(array, b2, b2+l2); + let slice = array.slice(b2, b2+l2); gallop_left(&array[b1+l1-1],slice,l2-1) }; if l2 > 0 { @@ -526,7 +526,7 @@ impl MergeState { assert!(len1 > 1 && len2 != 0); count1 = { - let tmp_view = vec::slice(tmp, c1, c1+len1); + let tmp_view = tmp.slice(c1, c1+len1); gallop_right(&array[c2], tmp_view, 0) }; if count1 != 0 { @@ -539,7 +539,7 @@ impl MergeState { if len2 == 0 { break_outer = true; break; } count2 = { - let tmp_view = vec::slice(array, c2, c2+len2); + let tmp_view = array.slice(c2, c2+len2); gallop_left(&tmp[c1], tmp_view, 0) }; if count2 != 0 { @@ -638,7 +638,7 @@ impl MergeState { assert!(len2 > 1 && len1 != 0); { // constrain scope of tmp_view: - let tmp_view = vec::mut_slice (array, base1, base1+len1); + let tmp_view = array.mut_slice(base1, base1+len1); count1 = len1 - gallop_right( &tmp[c2], tmp_view, len1-1); } @@ -655,7 +655,7 @@ impl MergeState { let count2; { // constrain scope of tmp_view - let tmp_view = vec::mut_slice(tmp, 0, len2); + let tmp_view = tmp.mut_slice(0, len2); count2 = len2 - gallop_left(&array[c1], tmp_view, len2-1); @@ -1111,7 +1111,7 @@ mod big_tests { isSorted(arr); let mut arr = if n > 4 { - let part = vec::slice(arr, 0, 4); + let part = arr.slice(0, 4); multiplyVec(part, n) } else { arr }; tim_sort(arr); // ~sort @@ -1183,7 +1183,7 @@ mod big_tests { isSorted(arr); let mut arr = if n > 4 { - let part = vec::slice(arr, 0, 4); + let part = arr.slice(0, 4); multiplyVec(part, n) } else { arr }; tim_sort(arr); // ~sort diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 4657c069c21e..dce2b7fe3dfb 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -154,7 +154,7 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { let mut path = ~[]; for uint::range(start_idx, len1 - 1) |_i| { path.push(~".."); }; - path.push_all(vec::slice(split2, start_idx, len2 - 1)); + path.push_all(split2.slice(start_idx, len2 - 1)); return if !path.is_empty() { Path("").push_many(path) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 824f67b074c2..39cce41b3869 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -60,7 +60,7 @@ fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) -> let belt = tag_index_buckets_bucket_elt; for reader::tagged_docs(tagged_doc.doc, belt) |elt| { let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint; - if eq_fn(vec::slice(*elt.data, elt.start + 4u, elt.end)) { + if eq_fn(elt.data.slice(elt.start + 4u, elt.end)) { return Some(reader::doc_at(d.data, pos).doc); } }; @@ -72,7 +72,7 @@ pub type GetCrateDataCb<'self> = &'self fn(ast::crate_num) -> cmd; pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option { fn eq_item(bytes: &[u8], item_id: int) -> bool { return io::u64_from_be_bytes( - vec::slice(bytes, 0u, 4u), 0u, 4u) as int + bytes.slice(0u, 4u), 0u, 4u) as int == item_id; } lookup_hash(items, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index b53bdcc9bbe0..58fac69659ce 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -20,7 +20,6 @@ use middle::ty; use core::str; use core::uint; -use core::vec; use syntax::abi::AbiSet; use syntax::abi; use syntax::ast; @@ -519,8 +518,8 @@ pub fn parse_def_id(buf: &[u8]) -> ast::def_id { fail!(); } - let crate_part = vec::slice(buf, 0u, colon_idx); - let def_part = vec::slice(buf, colon_idx + 1u, len); + let crate_part = buf.slice(0u, colon_idx); + let def_part = buf.slice(colon_idx + 1u, len); let crate_num = match uint::parse_bytes(crate_part, 10u) { Some(cn) => cn as int, diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index acd47eca7265..93202f3fd558 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -132,7 +132,7 @@ impl DataFlowContext { debug!("add_gen(id=%?, bit=%?)", id, bit); let (start, end) = self.compute_id_range(id); { - let gens = vec::mut_slice(self.gens, start, end); + let gens = self.gens.mut_slice(start, end); set_bit(gens, bit); } } @@ -143,7 +143,7 @@ impl DataFlowContext { debug!("add_kill(id=%?, bit=%?)", id, bit); let (start, end) = self.compute_id_range(id); { - let kills = vec::mut_slice(self.kills, start, end); + let kills = self.kills.mut_slice(start, end); set_bit(kills, bit); } } @@ -216,7 +216,7 @@ impl DataFlowContext { return true; } let (start, end) = self.compute_id_range_frozen(id); - let on_entry = vec::slice(self.on_entry, start, end); + let on_entry = self.on_entry.slice(start, end); debug!("each_bit_on_entry_frozen(id=%?, on_entry=%s)", id, bits_to_str(on_entry)); self.each_bit(on_entry, f) @@ -229,7 +229,7 @@ impl DataFlowContext { //! Only useful after `propagate()` has been called. let (start, end) = self.compute_id_range(id); - let on_entry = vec::slice(self.on_entry, start, end); + let on_entry = self.on_entry.slice(start, end); debug!("each_bit_on_entry(id=%?, on_entry=%s)", id, bits_to_str(on_entry)); self.each_bit(on_entry, f) @@ -241,7 +241,7 @@ impl DataFlowContext { //! Iterates through each bit in the gen set for `id`. let (start, end) = self.compute_id_range(id); - let gens = vec::slice(self.gens, start, end); + let gens = self.gens.slice(start, end); debug!("each_gen_bit(id=%?, gens=%s)", id, bits_to_str(gens)); self.each_bit(gens, f) @@ -255,7 +255,7 @@ impl DataFlowContext { return true; } let (start, end) = self.compute_id_range_frozen(id); - let gens = vec::slice(self.gens, start, end); + let gens = self.gens.slice(start, end); debug!("each_gen_bit(id=%?, gens=%s)", id, bits_to_str(gens)); self.each_bit(gens, f) @@ -338,17 +338,17 @@ impl DataFlowContext { if self.nodeid_to_bitset.contains_key(&id) { let (start, end) = self.compute_id_range_frozen(id); - let on_entry = vec::slice(self.on_entry, start, end); + let on_entry = self.on_entry.slice(start, end); let entry_str = bits_to_str(on_entry); - let gens = vec::slice(self.gens, start, end); + let gens = self.gens.slice(start, end); let gens_str = if gens.iter().any_(|&u| u != 0) { fmt!(" gen: %s", bits_to_str(gens)) } else { ~"" }; - let kills = vec::slice(self.kills, start, end); + let kills = self.kills.slice(start, end); let kills_str = if kills.iter().any_(|&u| u != 0) { fmt!(" kill: %s", bits_to_str(kills)) } else { @@ -953,7 +953,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { id, bits_to_str(pred_bits)); let (start, end) = self.dfcx.compute_id_range(id); let changed = { // FIXME(#5074) awkward construction - let on_entry = vec::mut_slice(self.dfcx.on_entry, start, end); + let on_entry = self.dfcx.on_entry.mut_slice(start, end); join_bits(&self.dfcx.oper, pred_bits, on_entry) }; if changed { @@ -970,7 +970,7 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { id, mut_bits_to_str(pred_bits)); let (start, end) = self.dfcx.compute_id_range(id); let changed = { // FIXME(#5074) awkward construction - let on_entry = vec::mut_slice(self.dfcx.on_entry, start, end); + let on_entry = self.dfcx.on_entry.mut_slice(start, end); let changed = join_bits(&self.dfcx.oper, reslice(pred_bits), on_entry); copy_bits(reslice(on_entry), pred_bits); changed diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a1f595fc8969..ca0d544198e8 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -17,7 +17,6 @@ use middle::typeck; use util::ppaux::{Repr, ty_to_str}; use util::ppaux::UserString; -use core::vec; use syntax::ast::*; use syntax::attr::attrs_contains_name; use syntax::codemap::span; diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 63b39b8fe763..7e17a947d303 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -388,9 +388,9 @@ pub fn expand_nested_bindings<'r>(bcx: block, match br.pats[col].node { ast::pat_ident(_, path, Some(inner)) => { let pats = vec::append( - vec::slice(br.pats, 0u, col).to_owned(), + br.pats.slice(0u, col).to_owned(), vec::append(~[inner], - vec::slice(br.pats, col + 1u, + br.pats.slice(col + 1u, br.pats.len()))); let binding_info = @@ -437,8 +437,8 @@ pub fn enter_match<'r>(bcx: block, Some(sub) => { let pats = vec::append( - vec::append(sub, vec::slice(br.pats, 0u, col)), - vec::slice(br.pats, col + 1u, br.pats.len())); + vec::append(sub, br.pats.slice(0u, col)), + br.pats.slice(col + 1u, br.pats.len())); let this = br.pats[col]; match this.node { @@ -1290,7 +1290,7 @@ pub fn compile_submatch(bcx: block, match data.arm.guard { Some(guard_expr) => { bcx = compile_guard(bcx, guard_expr, m[0].data, - vec::slice(m, 1, m.len()), + m.slice(1, m.len()), vals, chk); } _ => () @@ -1309,8 +1309,8 @@ pub fn compile_submatch(bcx: block, } }; - let vals_left = vec::append(vec::slice(vals, 0u, col).to_owned(), - vec::slice(vals, col + 1u, vals.len())); + let vals_left = vec::append(vals.slice(0u, col).to_owned(), + vals.slice(col + 1u, vals.len())); let ccx = bcx.fcx.ccx; let mut pat_id = 0; let mut pat_span = dummy_sp(); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 272d7b234aa5..fd3ebd3d9515 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -419,10 +419,9 @@ pub fn revoke_clean(cx: block, val: ValueRef) { }); for cleanup_pos.iter().advance |i| { scope_info.cleanups = - vec::append(vec::slice(scope_info.cleanups, 0u, *i).to_owned(), - vec::slice(scope_info.cleanups, - *i + 1u, - scope_info.cleanups.len())); + vec::append(scope_info.cleanups.slice(0u, *i).to_owned(), + scope_info.cleanups.slice(*i + 1u, + scope_info.cleanups.len())); shrink_scope_clean(scope_info, *i); } } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 96f8a1976a68..38e4f087b0ec 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -528,7 +528,7 @@ pub fn combine_impl_and_methods_origins(bcx: block, } = ty::lookup_item_type(tcx, mth_did); let n_r_m_tps = r_m_generics.type_param_defs.len(); // rcvr + method tps let m_type_param_defs = - vec::slice(*r_m_generics.type_param_defs, n_r_m_tps - n_m_tps, n_r_m_tps); + r_m_generics.type_param_defs.slice(n_r_m_tps - n_m_tps, n_r_m_tps); // Flatten out to find the number of vtables the method expects. let m_vtables = ty::count_traits_and_supertraits(tcx, m_type_param_defs); diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 54a404d971ee..a586cb83fa18 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -55,7 +55,7 @@ extern mod extra; extern mod rustc; extern mod syntax; -use std::{libc, io, os, task, vec}; +use std::{libc, io, os, task}; use std::cell::Cell; use extra::rl; @@ -430,7 +430,7 @@ pub fn run_line(repl: &mut Repl, in: @io::Reader, out: @io::Writer, line: ~str, if !cmd.is_empty() { let args = if len > 1 { - vec::slice(split, 1, len).to_owned() + split.slice(1, len).to_owned() } else { ~[] }; match run_cmd(repl, in, out, cmd, args, use_rl) { diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index 9b727e9d3e05..ebdea2537ac3 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -12,7 +12,7 @@ use target::*; use package_id::PkgId; use core::path::Path; use core::option::*; -use core::{os, run, str, vec}; +use core::{os, run, str}; use context::*; use crate::Crate; use messages::*; @@ -146,8 +146,7 @@ impl PkgSrc { fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) { assert!(p.components.len() > prefix); let mut sub = Path(""); - for vec::slice(p.components, prefix, - p.components.len()).iter().advance |c| { + for p.components.slice(prefix, p.components.len()).iter().advance |c| { sub = sub.push(*c); } debug!("found crate %s", sub.to_str()); diff --git a/src/libstd/io.rs b/src/libstd/io.rs index a78be9c8b2b1..4d9c08f25da7 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -65,7 +65,7 @@ use str::StrSlice; use to_str::ToStr; use uint; use vec; -use vec::{ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector}; +use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector}; #[allow(non_camel_case_types)] // not sure what to do about this pub type fd_t = c_int; @@ -698,7 +698,7 @@ impl ReaderUtil for T { // over-read by reading 1-byte per char needed nbread = if ncreq > nbreq { ncreq } else { nbreq }; if nbread > 0 { - bytes = vec::slice(bytes, offset, bytes.len()).to_owned(); + bytes = bytes.slice(offset, bytes.len()).to_owned(); } } chars @@ -1053,7 +1053,7 @@ impl Reader for BytesReader { fn read(&self, bytes: &mut [u8], len: uint) -> uint { let count = uint::min(len, self.bytes.len() - *self.pos); - let view = vec::slice(self.bytes, *self.pos, self.bytes.len()); + let view = self.bytes.slice(*self.pos, self.bytes.len()); vec::bytes::copy_memory(bytes, view, count); *self.pos += count; @@ -1663,7 +1663,7 @@ impl Writer for BytesWriter { unsafe { vec::raw::set_len(bytes, count); - let view = vec::mut_slice(*bytes, *self.pos, count); + let view = bytes.mut_slice(*self.pos, count); vec::bytes::copy_memory(view, v, v_len); } @@ -1909,8 +1909,7 @@ mod tests { if len <= ivals.len() { assert_eq!(res.len(), len); } - assert!(vec::slice(ivals, 0u, res.len()) == - vec::map(res, |x| *x as int)); + assert!(ivals.slice(0u, res.len()) == vec::map(res, |x| *x as int)); } } let mut i = 0; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 112540c405da..5534c5befc2b 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -134,7 +134,7 @@ pub mod win32 { } } if k != 0 && done { - let sub = vec::slice(buf, 0u, k as uint); + let sub = buf.slice(0, k as uint); res = option::Some(str::from_utf16(sub)); } } diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index 55861f127bb4..5320bd0f42ee 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -298,7 +298,7 @@ impl ReaderUtil for T { do (|| { while total_read < len { let len = buf.len(); - let slice = vec::mut_slice(*buf, start_len + total_read, len); + let slice = buf.mut_slice(start_len + total_read, len); match self.read(slice) { Some(nread) => { total_read += nread; diff --git a/src/libstd/rt/io/mem.rs b/src/libstd/rt/io/mem.rs index bd9cff76e576..c93945a6a9aa 100644 --- a/src/libstd/rt/io/mem.rs +++ b/src/libstd/rt/io/mem.rs @@ -86,7 +86,7 @@ impl Reader for MemReader { let write_len = min(buf.len(), self.buf.len() - self.pos); { let input = self.buf.slice(self.pos, self.pos + write_len); - let output = vec::mut_slice(buf, 0, write_len); + let output = buf.mut_slice(0, write_len); assert_eq!(input.len(), output.len()); vec::bytes::copy_memory(output, input, write_len); } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 56e6bacf93e3..c8dc5aa7f799 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -251,17 +251,17 @@ pub fn head_opt<'r,T>(v: &'r [T]) -> Option<&'r T> { } /// Returns a vector containing all but the first element of a slice -pub fn tail<'r,T>(v: &'r [T]) -> &'r [T] { slice(v, 1, v.len()) } +pub fn tail<'r,T>(v: &'r [T]) -> &'r [T] { v.slice(1, v.len()) } /// Returns a vector containing all but the first `n` elements of a slice -pub fn tailn<'r,T>(v: &'r [T], n: uint) -> &'r [T] { slice(v, n, v.len()) } +pub fn tailn<'r,T>(v: &'r [T], n: uint) -> &'r [T] { v.slice(n, v.len()) } /// Returns a vector containing all but the last element of a slice -pub fn init<'r,T>(v: &'r [T]) -> &'r [T] { slice(v, 0, v.len() - 1) } +pub fn init<'r,T>(v: &'r [T]) -> &'r [T] { v.slice(0, v.len() - 1) } /// Returns a vector containing all but the last `n' elements of a slice pub fn initn<'r,T>(v: &'r [T], n: uint) -> &'r [T] { - slice(v, 0, v.len() - n) + v.slice(0, v.len() - n) } /// Returns the last element of the slice `v`, failing if the slice is empty. @@ -276,47 +276,6 @@ pub fn last_opt<'r,T>(v: &'r [T]) -> Option<&'r T> { if v.len() == 0 { None } else { Some(&v[v.len() - 1]) } } -/// Return a slice that points into another slice. -#[inline] -pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] { - assert!(start <= end); - assert!(end <= v.len()); - do as_imm_buf(v) |p, _len| { - unsafe { - transmute((ptr::offset(p, start), - (end - start) * sys::nonzero_size_of::())) - } - } -} - -/// Return a slice that points into another slice. -#[inline] -pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint) - -> &'r mut [T] { - assert!(start <= end); - assert!(end <= v.len()); - do as_mut_buf(v) |p, _len| { - unsafe { - transmute((ptr::mut_offset(p, start), - (end - start) * sys::nonzero_size_of::())) - } - } -} - -/// Return a slice that points into another slice. -#[inline] -pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint) - -> &'r const [T] { - assert!(start <= end); - assert!(end <= v.len()); - do as_const_buf(v) |p, _len| { - unsafe { - transmute((ptr::const_offset(p, start), - (end - start) * sys::nonzero_size_of::())) - } - } -} - /// Copies /// Split the vector `v` by applying each element against the predicate `f`. @@ -330,12 +289,12 @@ pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i).to_owned()); + result.push(v.slice(start, i).to_owned()); start = i + 1u; } } } - result.push(slice(v, start, ln).to_owned()); + result.push(v.slice(start, ln).to_owned()); result } @@ -354,14 +313,14 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { match position_between(v, start, ln, f) { None => break, Some(i) => { - result.push(slice(v, start, i).to_owned()); + result.push(v.slice(start, i).to_owned()); // Make sure to skip the separator. start = i + 1u; count -= 1u; } } } - result.push(slice(v, start, ln).to_owned()); + result.push(v.slice(start, ln).to_owned()); result } @@ -379,12 +338,12 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1, end).to_owned()); + result.push(v.slice(i + 1, end).to_owned()); end = i; } } } - result.push(slice(v, 0u, end).to_owned()); + result.push(v.slice(0u, end).to_owned()); reverse(result); result } @@ -404,14 +363,14 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { match rposition_between(v, 0u, end, f) { None => break, Some(i) => { - result.push(slice(v, i + 1u, end).to_owned()); + result.push(v.slice(i + 1u, end).to_owned()); // Make sure to skip the separator. end = i; count -= 1u; } } } - result.push(slice(v, 0u, end).to_owned()); + result.push(v.slice(0u, end).to_owned()); reverse(result); result } @@ -487,15 +446,15 @@ pub fn shift(v: &mut ~[T]) -> T { // popped. For the moment it unsafely exists at both the head and last // positions { - let first_slice = slice(*v, 0, 1); - let last_slice = slice(*v, next_ln, ln); + let first_slice = v.slice(0, 1); + let last_slice = v.slice(next_ln, ln); raw::copy_memory(transmute(last_slice), first_slice, 1); } // Memcopy everything to the left one element { - let init_slice = slice(*v, 0, next_ln); - let tail_slice = slice(*v, 1, ln); + let init_slice = v.slice(0, next_ln); + let tail_slice = v.slice(1, ln); raw::copy_memory(transmute(init_slice), tail_slice, next_ln); @@ -1689,7 +1648,14 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// Return a slice that points into another slice. #[inline] fn slice(&self, start: uint, end: uint) -> &'self [T] { - slice(*self, start, end) + assert!(start <= end); + assert!(end <= self.len()); + do as_imm_buf(*self) |p, _len| { + unsafe { + transmute((ptr::offset(p, start), + (end - start) * sys::nonzero_size_of::())) + } + } } #[inline] @@ -2042,9 +2008,17 @@ pub trait MutableVector<'self, T> { } impl<'self,T> MutableVector<'self, T> for &'self mut [T] { + /// Return a slice that points into another slice. #[inline] fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { - mut_slice(self, start, end) + assert!(start <= end); + assert!(end <= self.len()); + do as_mut_buf(self) |p, _len| { + unsafe { + transmute((ptr::mut_offset(p, start), + (end - start) * sys::nonzero_size_of::())) + } + } } #[inline] @@ -2713,7 +2687,7 @@ mod tests { fn test_slice() { // Test fixed length vector. let vec_fixed = [1, 2, 3, 4]; - let v_a = slice(vec_fixed, 1u, vec_fixed.len()).to_owned(); + let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned(); assert_eq!(v_a.len(), 3u); assert_eq!(v_a[0], 2); assert_eq!(v_a[1], 3); @@ -2721,14 +2695,14 @@ mod tests { // Test on stack. let vec_stack = &[1, 2, 3]; - let v_b = slice(vec_stack, 1u, 3u).to_owned(); + let v_b = vec_stack.slice(1u, 3u).to_owned(); assert_eq!(v_b.len(), 2u); assert_eq!(v_b[0], 2); assert_eq!(v_b[1], 3); // Test on managed heap. let vec_managed = @[1, 2, 3, 4, 5]; - let v_c = slice(vec_managed, 0u, 3u).to_owned(); + let v_c = vec_managed.slice(0u, 3u).to_owned(); assert_eq!(v_c.len(), 3u); assert_eq!(v_c[0], 1); assert_eq!(v_c[1], 2); @@ -2736,7 +2710,7 @@ mod tests { // Test on exchange heap. let vec_unique = ~[1, 2, 3, 4, 5, 6]; - let v_d = slice(vec_unique, 1u, 6u).to_owned(); + let v_d = vec_unique.slice(1u, 6u).to_owned(); assert_eq!(v_d.len(), 5u); assert_eq!(v_d[0], 2); assert_eq!(v_d[1], 3); diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 89867922b25b..c7f33587f315 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -13,7 +13,6 @@ use codemap; use std::io; use std::uint; -use std::vec; use extra::term; pub type Emitter = @fn(cmsp: Option<(@codemap::CodeMap, span)>, @@ -250,7 +249,7 @@ fn highlight_lines(cm: @codemap::CodeMap, let mut elided = false; let mut display_lines = /* FIXME (#2543) */ copy lines.lines; if display_lines.len() > max_lines { - display_lines = vec::slice(display_lines, 0u, max_lines).to_owned(); + display_lines = display_lines.slice(0u, max_lines).to_owned(); elided = true; } // Print the offending lines diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 4b5880de8a52..787cf696cc34 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -29,7 +29,7 @@ macro_rules! bench ( fn main() { let argv = os::args(); - let tests = vec::slice(argv, 1, argv.len()); + let tests = argv.slice(1, argv.len()); bench!(shift_push); bench!(read_line); diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index 670e77bc3a0e..5ebcfe164ce7 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -96,7 +96,7 @@ impl RepeatFasta { copy_memory(buf, alu, alu_len); let buf_len = buf.len(); - copy_memory(vec::mut_slice(buf, alu_len, buf_len), + copy_memory(buf.mut_slice(alu_len, buf_len), alu, LINE_LEN); diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 20042aa0e918..57683fa3dbf0 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -90,7 +90,7 @@ fn find(mm: &HashMap<~[u8], uint>, key: ~str) -> uint { // given a map, increment the counter for a key fn update_freq(mm: &mut HashMap<~[u8], uint>, key: &[u8]) { - let key = vec::slice(key, 0, key.len()).to_owned(); + let key = key.to_owned(); let newval = match mm.pop(&key) { Some(v) => v + 1, None => 1 @@ -107,11 +107,11 @@ fn windows_with_carry(bb: &[u8], nn: uint, let len = bb.len(); while ii < len - (nn - 1u) { - it(vec::slice(bb, ii, ii+nn)); + it(bb.slice(ii, ii+nn)); ii += 1u; } - return vec::slice(bb, len - (nn - 1u), len).to_owned(); + return bb.slice(len - (nn - 1u), len).to_owned(); } fn make_sequence_processor(sz: uint, diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 646b9788f706..405aa68c483b 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -8,7 +8,7 @@ use std::libc::{STDIN_FILENO, c_int, fdopen, fgets, fileno, fopen, fstat}; use std::libc::{stat, strlen}; use std::ptr::null; use std::unstable::intrinsics::init; -use std::vec::{reverse, slice}; +use std::vec::{reverse}; use extra::sort::quick_sort3; static LINE_LEN: uint = 80; @@ -194,7 +194,7 @@ fn unpack_symbol(c: u8) -> u8 { fn next_char<'a>(mut buf: &'a [u8]) -> &'a [u8] { loop { - buf = slice(buf, 1, buf.len()); + buf = buf.slice(1, buf.len()); if buf.len() == 0 { break; } @@ -226,7 +226,7 @@ fn read_stdin() -> ~[u8] { fgets(transmute(&mut window[0]), LINE_LEN as c_int, stdin); { - if vec::slice(window, 0, 6) == header { + if window.slice(0, 6) == header { break; } } @@ -235,9 +235,7 @@ fn read_stdin() -> ~[u8] { while fgets(transmute(&mut window[0]), LINE_LEN as c_int, stdin) != null() { - window = vec::mut_slice(window, - strlen(transmute(&window[0])) as uint, - window.len()); + window = window.mut_slice(strlen(transmute(&window[0])) as uint, window.len()); } } diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 01425d82db29..295211e03a14 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -32,7 +32,6 @@ use std::str; use std::task; use std::u64; use std::uint; -use std::vec; fn fib(n: int) -> int { fn pfib(c: &Chan, n: int) { @@ -62,7 +61,7 @@ struct Config { fn parse_opts(argv: ~[~str]) -> Config { let opts = ~[getopts::optflag(~"stress")]; - let opt_args = vec::slice(argv, 1, argv.len()); + let opt_args = argv.slice(1, argv.len()); match getopts::getopts(opt_args, opts) { Ok(ref m) => { diff --git a/src/test/run-pass/issue-3888-2.rs b/src/test/run-pass/issue-3888-2.rs index 60c506244351..c9f6733fa258 100644 --- a/src/test/run-pass/issue-3888-2.rs +++ b/src/test/run-pass/issue-3888-2.rs @@ -8,12 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn vec_peek<'r, T>(v: &'r [T]) -> &'r [T] { -// This doesn't work, and should. -// v.slice(1, 5) - vec::slice(v, 1, 5) + v.slice(1, 5) } pub fn main() {} diff --git a/src/test/run-pass/vec-slice.rs b/src/test/run-pass/vec-slice.rs index 8448e4e0532c..e3012b086214 100644 --- a/src/test/run-pass/vec-slice.rs +++ b/src/test/run-pass/vec-slice.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - pub fn main() { let v = ~[1,2,3,4,5]; - let v2 = vec::slice(v, 1, 3); + let v2 = v.slice(1, 3); assert_eq!(v2[0], 2); assert_eq!(v2[1], 3); } From d2e3e1e52ba008c58ecfa801cb5d127365d20ae5 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 27 Jun 2013 22:36:27 +1000 Subject: [PATCH 182/336] Convert vec::{head, tail, init, last} (and similar fns) to methods. --- src/compiletest/compiletest.rs | 2 +- src/libextra/test.rs | 2 +- src/librustc/middle/trans/cabi_x86_64.rs | 2 +- src/librustc/middle/trans/callee.rs | 3 +- src/librustc/middle/trans/meth.rs | 5 +- src/librustc/middle/ty.rs | 2 +- src/libstd/vec.rs | 76 ++++++++---------------- 7 files changed, 33 insertions(+), 59 deletions(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index e8876c4851bc..b2ba05c550de 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -75,7 +75,7 @@ pub fn parse_config(args: ~[~str]) -> config { ]; assert!(!args.is_empty()); - let args_ = vec::tail(args); + let args_ = args.tail(); let matches = &match getopts::getopts(args_, opts) { Ok(m) => m, diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 72e70943ce1c..bb03e3ab9bb2 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -139,7 +139,7 @@ type OptRes = Either; // Parses command line arguments into test options pub fn parse_opts(args: &[~str]) -> OptRes { - let args_ = vec::tail(args); + let args_ = args.tail(); let opts = ~[getopts::optflag("ignored"), getopts::optflag("test"), getopts::optflag("bench"), diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 14ab17f5030d..73323634c2b6 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -312,7 +312,7 @@ fn llreg_ty(cls: &[RegClass]) -> Type { tys.push(Type::i64()); } SSEFv => { - let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; + let vec_len = llvec_len(cls.tailn(i + 1u)) * 2u; let vec_ty = Type::vector(&Type::f32(), vec_len as u64); tys.push(vec_ty); i += vec_len; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index cb4755506384..064a457c7127 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -47,7 +47,6 @@ use util::ppaux::Repr; use middle::trans::type_::Type; -use core::vec; use syntax::ast; use syntax::ast_map; use syntax::visit; @@ -503,7 +502,7 @@ pub fn trans_call_inner(in_cx: block, do base::with_scope(in_cx, call_info, "call") |cx| { let ret_in_loop = match args { ArgExprs(args) => { - args.len() > 0u && match vec::last(args).node { + args.len() > 0u && match args.last().node { ast::expr_loop_body(@ast::expr { node: ast::expr_fn_block(_, ref body), _ diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 38e4f087b0ec..b6911a7eb96d 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -492,8 +492,7 @@ pub fn combine_impl_and_methods_tps(bcx: block, debug!("rcvr_substs=%?", rcvr_substs.map(|t| bcx.ty_to_str(*t))); let ty_substs = vec::append(rcvr_substs.to_owned(), - vec::tailn(node_substs, - node_substs.len() - n_m_tps)); + node_substs.tailn(node_substs.len() - n_m_tps)); debug!("n_m_tps=%?", n_m_tps); debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t))); debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t))); @@ -540,7 +539,7 @@ pub fn combine_impl_and_methods_origins(bcx: block, }; // Extract those that belong to method: - let m_origins = vec::tailn(*r_m_origins, r_m_origins.len() - m_vtables); + let m_origins = r_m_origins.tailn(r_m_origins.len() - m_vtables); // Combine rcvr + method to find the final result: @vec::append(/*bad*/copy *rcvr_origins, m_origins) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4cea4c949724..939fecfe40ae 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3954,7 +3954,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { } ast_map::node_variant(ref variant, _, path) => { - vec::append_one(vec::to_owned(vec::init(*path)), + vec::append_one(vec::to_owned(path.init()), ast_map::path_name((*variant).node.name)) } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index c8dc5aa7f799..3dae32d717de 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -238,44 +238,6 @@ pub fn build_sized_opt(size: Option, // Accessors -/// Returns the first element of a vector -pub fn head<'r,T>(v: &'r [T]) -> &'r T { - if v.len() == 0 { fail!("head: empty vector") } - &v[0] -} - -/// Returns `Some(x)` where `x` is the first element of the slice `v`, -/// or `None` if the vector is empty. -pub fn head_opt<'r,T>(v: &'r [T]) -> Option<&'r T> { - if v.len() == 0 { None } else { Some(&v[0]) } -} - -/// Returns a vector containing all but the first element of a slice -pub fn tail<'r,T>(v: &'r [T]) -> &'r [T] { v.slice(1, v.len()) } - -/// Returns a vector containing all but the first `n` elements of a slice -pub fn tailn<'r,T>(v: &'r [T], n: uint) -> &'r [T] { v.slice(n, v.len()) } - -/// Returns a vector containing all but the last element of a slice -pub fn init<'r,T>(v: &'r [T]) -> &'r [T] { v.slice(0, v.len() - 1) } - -/// Returns a vector containing all but the last `n' elements of a slice -pub fn initn<'r,T>(v: &'r [T], n: uint) -> &'r [T] { - v.slice(0, v.len() - n) -} - -/// Returns the last element of the slice `v`, failing if the slice is empty. -pub fn last<'r,T>(v: &'r [T]) -> &'r T { - if v.len() == 0 { fail!("last: empty vector") } - &v[v.len() - 1] -} - -/// Returns `Some(x)` where `x` is the last element of the slice `v`, or -/// `None` if the vector is empty. -pub fn last_opt<'r,T>(v: &'r [T]) -> Option<&'r T> { - if v.len() == 0 { None } else { Some(&v[v.len() - 1]) } -} - /// Copies /// Split the vector `v` by applying each element against the predicate `f`. @@ -1678,35 +1640,49 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { /// Returns the first element of a vector, failing if the vector is empty. #[inline] - fn head(&self) -> &'self T { head(*self) } + fn head(&self) -> &'self T { + if self.len() == 0 { fail!("head: empty vector") } + &self[0] + } - /// Returns the first element of a vector + /// Returns the first element of a vector, or `None` if it is empty #[inline] - fn head_opt(&self) -> Option<&'self T> { head_opt(*self) } + fn head_opt(&self) -> Option<&'self T> { + if self.len() == 0 { None } else { Some(&self[0]) } + } /// Returns all but the first element of a vector #[inline] - fn tail(&self) -> &'self [T] { tail(*self) } + fn tail(&self) -> &'self [T] { self.slice(1, self.len()) } /// Returns all but the first `n' elements of a vector #[inline] - fn tailn(&self, n: uint) -> &'self [T] { tailn(*self, n) } + fn tailn(&self, n: uint) -> &'self [T] { self.slice(n, self.len()) } - /// Returns all but the last elemnt of a vector + /// Returns all but the last element of a vector #[inline] - fn init(&self) -> &'self [T] { init(*self) } + fn init(&self) -> &'self [T] { + self.slice(0, self.len() - 1) + } /// Returns all but the last `n' elemnts of a vector #[inline] - fn initn(&self, n: uint) -> &'self [T] { initn(*self, n) } + fn initn(&self, n: uint) -> &'self [T] { + self.slice(0, self.len() - n) + } - /// Returns the last element of a `v`, failing if the vector is empty. + /// Returns the last element of a vector, failing if the vector is empty. #[inline] - fn last(&self) -> &'self T { last(*self) } + fn last(&self) -> &'self T { + if self.len() == 0 { fail!("last: empty vector") } + &self[self.len() - 1] + } - /// Returns the last element of a `v`, failing if the vector is empty. + /// Returns the last element of a vector, or `None` if it is empty. #[inline] - fn last_opt(&self) -> Option<&'self T> { last_opt(*self) } + fn last_opt(&self) -> Option<&'self T> { + if self.len() == 0 { None } else { Some(&self[self.len() - 1]) } + } /** * Find the last index matching some predicate From 7295a6da92ac4bfcbc714848bd611dae54df0b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 27 Jun 2013 15:04:22 +0200 Subject: [PATCH 183/336] Remove many shared pointers Mostly just low-haning fruit, i.e. function arguments that were @ even though & would work just as well. Reduces librustc.so size by 200k when compiling without -O, by 100k when compiling with -O. --- src/librustc/driver/driver.rs | 24 ++-- src/librustc/driver/session.rs | 2 +- src/librustc/front/config.rs | 13 +- src/librustc/front/std_inject.rs | 4 +- src/librustc/front/test.rs | 2 +- src/librustc/metadata/creader.rs | 30 ++--- src/librustc/middle/borrowck/mod.rs | 6 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_loop.rs | 2 +- src/librustc/middle/check_match.rs | 32 ++--- src/librustc/middle/const_eval.rs | 20 +-- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/entry.rs | 2 +- src/librustc/middle/freevars.rs | 2 +- src/librustc/middle/kind.rs | 13 +- src/librustc/middle/lang_items.rs | 135 ++++++++++----------- src/librustc/middle/lint.rs | 12 +- src/librustc/middle/liveness.rs | 18 +-- src/librustc/middle/moves.rs | 4 +- src/librustc/middle/pat_util.rs | 2 +- src/librustc/middle/privacy.rs | 2 +- src/librustc/middle/region.rs | 104 +++++++--------- src/librustc/middle/trans/_match.rs | 8 +- src/librustc/middle/trans/base.rs | 17 ++- src/librustc/middle/trans/block.rs | 0 src/librustc/middle/trans/closure.rs | 2 +- src/librustc/middle/trans/common.rs | 13 +- src/librustc/middle/trans/consts.rs | 17 +-- src/librustc/middle/trans/controlflow.rs | 2 +- src/librustc/middle/trans/datum.rs | 2 +- src/librustc/middle/trans/expr.rs | 28 ++--- src/librustc/middle/trans/foreign.rs | 14 +-- src/librustc/middle/trans/glue.rs | 21 ++-- src/librustc/middle/trans/meth.rs | 8 +- src/librustc/middle/trans/reflect.rs | 92 +++++++------- src/librustc/middle/trans/tvec.rs | 12 +- src/librustc/middle/trans/type_use.rs | 16 +-- src/librustc/middle/ty.rs | 20 +-- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/check/method.rs | 4 +- src/librustc/middle/typeck/check/mod.rs | 2 +- src/librustc/middle/typeck/coherence.rs | 14 +-- src/librustc/middle/typeck/collect.rs | 26 ++-- src/librustc/middle/typeck/mod.rs | 18 +-- src/librustpkg/util.rs | 2 +- src/libsyntax/ast_map.rs | 2 +- src/libsyntax/ast_util.rs | 6 +- src/libsyntax/ext/deriving/cmp/totaleq.rs | 2 - src/libsyntax/ext/expand.rs | 4 +- src/libsyntax/visit.rs | 28 ++--- 50 files changed, 388 insertions(+), 427 deletions(-) delete mode 100644 src/librustc/middle/trans/block.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index f6b05711c13d..8caf7d9a8e92 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -181,12 +181,12 @@ pub fn compile_rest(sess: Session, let time_passes = sess.time_passes(); - let mut crate_opt = curr; + let mut crate = curr.unwrap(); if phases.from == cu_parse || phases.from == cu_everything { *sess.building_library = session::building_library( - sess.opts.crate_type, crate_opt.unwrap(), sess.opts.test); + sess.opts.crate_type, crate, sess.opts.test); // strip before expansion to allow macros to depend on // configuration variables e.g/ in @@ -195,27 +195,25 @@ pub fn compile_rest(sess: Session, // mod bar { macro_rules! baz!(() => {{}}) } // // baz! should not use this definition unless foo is enabled. - crate_opt = Some(time(time_passes, ~"configuration 1", || - front::config::strip_unconfigured_items(crate_opt.unwrap()))); + crate = time(time_passes, ~"configuration 1", || + front::config::strip_unconfigured_items(crate)); - crate_opt = Some(time(time_passes, ~"expansion", || + crate = time(time_passes, ~"expansion", || syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg, - crate_opt.unwrap()))); + crate)); // strip again, in case expansion added anything with a #[cfg]. - crate_opt = Some(time(time_passes, ~"configuration 2", || - front::config::strip_unconfigured_items(crate_opt.unwrap()))); + crate = time(time_passes, ~"configuration 2", || + front::config::strip_unconfigured_items(crate)); - crate_opt = Some(time(time_passes, ~"maybe building test harness", || - front::test::modify_for_testing(sess, crate_opt.unwrap()))); + crate = time(time_passes, ~"maybe building test harness", || + front::test::modify_for_testing(sess, crate)); } - if phases.to == cu_expand { return (crate_opt, None); } + if phases.to == cu_expand { return (Some(crate), None); } assert!(phases.from != cu_no_trans); - let mut crate = crate_opt.unwrap(); - let (llcx, llmod, link_meta) = { crate = time(time_passes, ~"extra injection", || front::std_inject::maybe_inject_libstd_ref(sess, crate)); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 73e8cfea8ca2..b5eb351a8a58 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -349,7 +349,7 @@ pub fn expect(sess: Session, } pub fn building_library(req_crate_type: crate_type, - crate: @ast::crate, + crate: &ast::crate, testing: bool) -> bool { match req_crate_type { bin_crate => false, diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 71375966a28b..43098b98ea3b 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -24,11 +24,11 @@ struct Context { // any items that do not belong in the current configuration pub fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate { do strip_items(crate) |attrs| { - in_cfg(/*bad*/copy crate.node.config, attrs) + in_cfg(crate.node.config, attrs) } } -pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred) +pub fn strip_items(crate: &ast::crate, in_cfg: in_cfg_pred) -> @ast::crate { let ctxt = @Context { in_cfg: in_cfg }; @@ -44,8 +44,7 @@ pub fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred) .. *fold::default_ast_fold()}; let fold = fold::make_fold(precursor); - let res = @fold.fold_crate(&*crate); - return res; + @fold.fold_crate(crate) } fn filter_item(cx: @Context, item: @ast::item) -> @@ -183,12 +182,12 @@ fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool { // Determine if an item should be translated in the current crate // configuration based on the item's attributes -fn in_cfg(cfg: ast::crate_cfg, attrs: ~[ast::attribute]) -> bool { +fn in_cfg(cfg: &[@ast::meta_item], attrs: &[ast::attribute]) -> bool { metas_in_cfg(cfg, attr::attr_metas(attrs)) } -pub fn metas_in_cfg(cfg: ast::crate_cfg, - metas: ~[@ast::meta_item]) -> bool { +pub fn metas_in_cfg(cfg: &[@ast::meta_item], + metas: &[@ast::meta_item]) -> bool { // The "cfg" attributes on the item let cfg_metas = attr::find_meta_items_by_name(metas, "cfg"); diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 38a21af65b93..a86e7c5e39b3 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -30,11 +30,11 @@ pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate) } } -fn use_std(crate: @ast::crate) -> bool { +fn use_std(crate: &ast::crate) -> bool { !attr::attrs_contains_name(crate.node.attrs, "no_std") } -fn inject_libstd_ref(sess: Session, crate: @ast::crate) -> @ast::crate { +fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { fn spanned(x: T) -> codemap::spanned { codemap::spanned { node: x, span: dummy_sp() } } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index c9eb97b44cd7..97f1b3997ddc 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -92,7 +92,7 @@ fn generate_test_harness(sess: session::Session, return res; } -fn strip_test_functions(crate: @ast::crate) -> @ast::crate { +fn strip_test_functions(crate: &ast::crate) -> @ast::crate { // When not compiling with --test we should not compile the // #[test] functions do config::strip_items(crate) |attrs| { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 2743cd1ddc1e..5e36b8fddcc7 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -18,7 +18,6 @@ use metadata::filesearch::FileSearch; use metadata::loader; use core::hashmap::HashMap; -use core::vec; use syntax::attr; use syntax::codemap::{span, dummy_sp}; use syntax::diagnostic::span_handler; @@ -30,7 +29,7 @@ use syntax::ast; // Traverses an AST, reading all the information about use'd crates and extern // libraries necessary for later resolving, typechecking, linking, etc. pub fn read_crates(diag: @span_handler, - crate: @ast::crate, + crate: &ast::crate, cstore: @mut cstore::CStore, filesearch: @FileSearch, os: loader::os, @@ -53,8 +52,8 @@ pub fn read_crates(diag: @span_handler, .. *visit::default_simple_visitor()}); visit_crate(e, crate); visit::visit_crate(crate, ((), v)); - dump_crates(e.crate_cache); - warn_if_multiple_versions(e, diag, e.crate_cache); + dump_crates(*e.crate_cache); + warn_if_multiple_versions(e, diag, *e.crate_cache); } struct cache_entry { @@ -64,7 +63,7 @@ struct cache_entry { metas: @~[@ast::meta_item] } -fn dump_crates(crate_cache: @mut ~[cache_entry]) { +fn dump_crates(crate_cache: &[cache_entry]) { debug!("resolved crates:"); for crate_cache.iter().advance |entry| { debug!("cnum: %?", entry.cnum); @@ -75,11 +74,9 @@ fn dump_crates(crate_cache: @mut ~[cache_entry]) { fn warn_if_multiple_versions(e: @mut Env, diag: @span_handler, - crate_cache: @mut ~[cache_entry]) { + crate_cache: &[cache_entry]) { use core::either::*; - let crate_cache = &mut *crate_cache; - if crate_cache.len() != 0u { let name = loader::crate_name_from_metas( *crate_cache[crate_cache.len() - 1].metas @@ -111,7 +108,7 @@ fn warn_if_multiple_versions(e: @mut Env, } } - warn_if_multiple_versions(e, diag, @mut non_matches); + warn_if_multiple_versions(e, diag, non_matches); } } @@ -126,7 +123,7 @@ struct Env { intr: @ident_interner } -fn visit_crate(e: @mut Env, c: &ast::crate) { +fn visit_crate(e: &Env, c: &ast::crate) { let cstore = e.cstore; let link_args = attr::find_attrs_by_name(c.node.attrs, "link_args"); @@ -152,7 +149,7 @@ fn visit_view_item(e: @mut Env, i: @ast::view_item) { } } -fn visit_item(e: @mut Env, i: @ast::item) { +fn visit_item(e: &Env, i: @ast::item) { match i.node { ast::item_foreign_mod(ref fm) => { if fm.abis.is_rust() || fm.abis.is_intrinsic() { @@ -204,14 +201,13 @@ fn visit_item(e: @mut Env, i: @ast::item) { } } -fn metas_with(ident: @str, key: @str, metas: ~[@ast::meta_item]) +fn metas_with(ident: @str, key: @str, mut metas: ~[@ast::meta_item]) -> ~[@ast::meta_item] { let name_items = attr::find_meta_items_by_name(metas, key); if name_items.is_empty() { - vec::append_one(metas, attr::mk_name_value_item_str(key, ident)) - } else { - metas + metas.push(attr::mk_name_value_item_str(key, ident)); } + metas } fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item]) @@ -219,11 +215,11 @@ fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item]) metas_with(ident, @"name", metas) } -fn existing_match(e: @mut Env, metas: &[@ast::meta_item], hash: @str) +fn existing_match(e: &Env, metas: &[@ast::meta_item], hash: &str) -> Option { for e.crate_cache.iter().advance |c| { if loader::metadata_matches(*c.metas, metas) - && (hash.is_empty() || c.hash == hash) { + && (hash.is_empty() || c.hash.as_slice() == hash) { return Some(c.cnum); } } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 745e792eec75..f22edd2e1d64 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -58,7 +58,7 @@ pub fn check_crate( moves_map: moves::MovesMap, moved_variables_set: moves::MovedVariablesSet, capture_map: moves::CaptureMap, - crate: @ast::crate) -> (root_map, write_guard_map) + crate: &ast::crate) -> (root_map, write_guard_map) { let bccx = @BorrowckCtxt { tcx: tcx, @@ -507,7 +507,7 @@ impl BorrowckCtxt { pub fn report_use_of_moved_value(&self, use_span: span, use_kind: MovedValueUseKind, - lp: @LoanPath, + lp: &LoanPath, move: &move_data::Move, moved_lp: @LoanPath) { let verb = match use_kind { @@ -570,7 +570,7 @@ impl BorrowckCtxt { pub fn report_reassigned_immutable_variable(&self, span: span, - lp: @LoanPath, + lp: &LoanPath, assign: &move_data::Assignment) { self.tcx.sess.span_err( diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 2fa25b10f605..2c6ba79e96e4 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -21,7 +21,7 @@ use syntax::codemap; use syntax::{visit, ast_util, ast_map}; pub fn check_crate(sess: Session, - crate: @crate, + crate: &crate, ast_map: ast_map::map, def_map: resolve::DefMap, method_map: typeck::method_map, diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 2ed7b7adecc1..190602e815d3 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -19,7 +19,7 @@ pub struct Context { can_ret: bool } -pub fn check_crate(tcx: ty::ctxt, crate: @crate) { +pub fn check_crate(tcx: ty::ctxt, crate: &crate) { visit::visit_crate(crate, (Context { in_loop: false, can_ret: true }, visit::mk_vt(@visit::Visitor { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index b4c8a6b19c29..e2ab3247c19c 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -36,7 +36,7 @@ pub struct MatchCheckCtxt { pub fn check_crate(tcx: ty::ctxt, method_map: method_map, moves_map: moves::MovesMap, - crate: @crate) { + crate: &crate) { let cx = @MatchCheckCtxt {tcx: tcx, method_map: method_map, moves_map: moves_map}; @@ -50,7 +50,7 @@ pub fn check_crate(tcx: ty::ctxt, tcx.sess.abort_if_errors(); } -pub fn expr_is_non_moving_lvalue(cx: @MatchCheckCtxt, expr: @expr) -> bool { +pub fn expr_is_non_moving_lvalue(cx: &MatchCheckCtxt, expr: &expr) -> bool { if !ty::expr_is_lval(cx.tcx, cx.method_map, expr) { return false; } @@ -108,7 +108,7 @@ pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { } // Check for unreachable patterns -pub fn check_arms(cx: @MatchCheckCtxt, arms: &[arm]) { +pub fn check_arms(cx: &MatchCheckCtxt, arms: &[arm]) { let mut seen = ~[]; for arms.iter().advance |arm| { for arm.pats.iter().advance |pat| { @@ -131,7 +131,7 @@ pub fn raw_pat(p: @pat) -> @pat { } } -pub fn check_exhaustive(cx: @MatchCheckCtxt, sp: span, pats: ~[@pat]) { +pub fn check_exhaustive(cx: &MatchCheckCtxt, sp: span, pats: ~[@pat]) { assert!((!pats.is_empty())); let ext = match is_useful(cx, &pats.map(|p| ~[*p]), [wild()]) { not_useful => { @@ -205,7 +205,7 @@ pub enum ctor { // Note: is_useful doesn't work on empty types, as the paper notes. // So it assumes that v is non-empty. -pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { +pub fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { if m.len() == 0u { return useful_; } if m[0].len() == 0u { return not_useful; } let real_pat = match m.iter().find_(|r| r[0].id != 0) { @@ -281,7 +281,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { } } -pub fn is_useful_specialized(cx: @MatchCheckCtxt, +pub fn is_useful_specialized(cx: &MatchCheckCtxt, m: &matrix, v: &[@pat], ctor: ctor, @@ -297,7 +297,7 @@ pub fn is_useful_specialized(cx: @MatchCheckCtxt, } } -pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option { +pub fn pat_ctor_id(cx: &MatchCheckCtxt, p: @pat) -> Option { let pat = raw_pat(p); match pat.node { pat_wild => { None } @@ -333,7 +333,7 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option { } } -pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool { +pub fn is_wild(cx: &MatchCheckCtxt, p: @pat) -> bool { let pat = raw_pat(p); match pat.node { pat_wild => { true } @@ -347,7 +347,7 @@ pub fn is_wild(cx: @MatchCheckCtxt, p: @pat) -> bool { } } -pub fn missing_ctor(cx: @MatchCheckCtxt, +pub fn missing_ctor(cx: &MatchCheckCtxt, m: &matrix, left_ty: ty::t) -> Option { @@ -449,7 +449,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, } } -pub fn ctor_arity(cx: @MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint { +pub fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint { match ty::get(ty).sty { ty::ty_tup(ref fs) => fs.len(), ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u, @@ -476,7 +476,7 @@ pub fn wild() -> @pat { @pat {id: 0, node: pat_wild, span: dummy_sp()} } -pub fn specialize(cx: @MatchCheckCtxt, +pub fn specialize(cx: &MatchCheckCtxt, r: &[@pat], ctor_id: &ctor, arity: uint, @@ -743,12 +743,12 @@ pub fn specialize(cx: @MatchCheckCtxt, } } -pub fn default(cx: @MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> { +pub fn default(cx: &MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> { if is_wild(cx, r[0]) { Some(vec::to_owned(r.tail())) } else { None } } -pub fn check_local(cx: @MatchCheckCtxt, +pub fn check_local(cx: &MatchCheckCtxt, loc: @local, (s, v): ((), visit::vt<()>)) { @@ -766,7 +766,7 @@ pub fn check_local(cx: @MatchCheckCtxt, check_legality_of_move_bindings(cx, is_lvalue, false, [ loc.node.pat ]); } -pub fn check_fn(cx: @MatchCheckCtxt, +pub fn check_fn(cx: &MatchCheckCtxt, kind: &visit::fn_kind, decl: &fn_decl, body: &blk, @@ -783,7 +783,7 @@ pub fn check_fn(cx: @MatchCheckCtxt, } } -pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool { +pub fn is_refutable(cx: &MatchCheckCtxt, pat: &pat) -> bool { match cx.tcx.def_map.find(&pat.id) { Some(&def_variant(enum_id, _)) => { if ty::enum_variants(cx.tcx, enum_id).len() != 1u { @@ -821,7 +821,7 @@ pub fn is_refutable(cx: @MatchCheckCtxt, pat: &pat) -> bool { // Legality of move bindings checking -pub fn check_legality_of_move_bindings(cx: @MatchCheckCtxt, +pub fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, is_lvalue: bool, has_guard: bool, pats: &[@pat]) { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 299d71b2567a..df7de540ea9a 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -75,7 +75,7 @@ pub fn join_all(cs: &[constness]) -> constness { cs.iter().fold(integral_const, |a, b| join(a, *b)) } -pub fn classify(e: @expr, +pub fn classify(e: &expr, tcx: ty::ctxt) -> constness { let did = ast_util::local_def(e.id); @@ -164,7 +164,7 @@ pub fn classify(e: @expr, } } -pub fn lookup_const(tcx: ty::ctxt, e: @expr) -> Option<@expr> { +pub fn lookup_const(tcx: ty::ctxt, e: &expr) -> Option<@expr> { match tcx.def_map.find(&e.id) { Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id), _ => None @@ -203,7 +203,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, } } -pub fn lookup_constness(tcx: ty::ctxt, e: @expr) -> constness { +pub fn lookup_constness(tcx: ty::ctxt, e: &expr) -> constness { match lookup_const(tcx, e) { Some(rhs) => { let ty = ty::expr_ty(tcx, rhs); @@ -217,7 +217,7 @@ pub fn lookup_constness(tcx: ty::ctxt, e: @expr) -> constness { } } -pub fn process_crate(crate: @ast::crate, +pub fn process_crate(crate: &ast::crate, tcx: ty::ctxt) { let v = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_expr_post: |e| { classify(e, tcx); }, @@ -239,14 +239,14 @@ pub enum const_val { const_bool(bool) } -pub fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val { +pub fn eval_const_expr(tcx: middle::ty::ctxt, e: &expr) -> const_val { match eval_const_expr_partial(tcx, e) { Ok(r) => r, Err(s) => tcx.sess.span_fatal(e.span, s) } } -pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: @expr) +pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) -> Result { use middle::ty; fn fromb(b: bool) -> Result { Ok(const_int(b as i64)) } @@ -406,7 +406,7 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: @expr) } } -pub fn lit_to_const(lit: @lit) -> const_val { +pub fn lit_to_const(lit: &lit) -> const_val { match lit.node { lit_str(s) => const_str(s), lit_int(n, _) => const_int(n), @@ -434,14 +434,14 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option { } } -pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option { +pub fn compare_lit_exprs(tcx: middle::ty::ctxt, a: &expr, b: &expr) -> Option { compare_const_vals(&eval_const_expr(tcx, a), &eval_const_expr(tcx, b)) } -pub fn lit_expr_eq(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> Option { +pub fn lit_expr_eq(tcx: middle::ty::ctxt, a: &expr, b: &expr) -> Option { compare_lit_exprs(tcx, a, b).map(|&val| val == 0) } -pub fn lit_eq(a: @lit, b: @lit) -> Option { +pub fn lit_eq(a: &lit, b: &lit) -> Option { compare_const_vals(&lit_to_const(a), &lit_to_const(b)).map(|&val| val == 0) } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 513b2015a834..654cc25c15e8 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -47,7 +47,7 @@ fn type_is_unsafe_function(ty: ty::t) -> bool { pub fn check_crate(tcx: ty::ctxt, method_map: method_map, - crate: @ast::crate) { + crate: &ast::crate) { let context = @mut Context { method_map: method_map, unsafe_context: SafeContext, diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 06feb9e7ba95..904a7ec8c871 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -41,7 +41,7 @@ struct EntryContext { type EntryVisitor = vt<@mut EntryContext>; -pub fn find_entry_point(session: Session, crate: @crate, ast_map: ast_map::map) { +pub fn find_entry_point(session: Session, crate: &crate, ast_map: ast_map::map) { // FIXME #4404 android JNI hacks if *session.building_library && diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index e18143042b0e..c2f663ae23cd 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -88,7 +88,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::blk) // efficient as it fully recomputes the free variables at every // node of interest rather than building up the free variables in // one pass. This could be improved upon if it turns out to matter. -pub fn annotate_freevars(def_map: resolve::DefMap, crate: @ast::crate) -> +pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::crate) -> freevar_map { let freevars = @mut HashMap::new(); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a1f595fc8969..ef96fa979727 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -17,7 +17,6 @@ use middle::typeck; use util::ppaux::{Repr, ty_to_str}; use util::ppaux::UserString; -use core::vec; use syntax::ast::*; use syntax::attr::attrs_contains_name; use syntax::codemap::span; @@ -63,7 +62,7 @@ pub struct Context { pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, - crate: @crate) { + crate: &crate) { let ctx = Context { tcx: tcx, method_map: method_map, @@ -163,7 +162,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // closure. fn with_appropriate_checker(cx: Context, id: node_id, b: &fn(checker: &fn(Context, @freevar_entry))) { - fn check_for_uniq(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_uniq(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned, regardless of whether it is // moved in or copied in. let id = ast_util::def_id_of_def(fv.def).node; @@ -175,7 +174,7 @@ fn with_appropriate_checker(cx: Context, id: node_id, check_freevar_bounds(cx, fv.span, var_t, bounds); } - fn check_for_box(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_box(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { // all captured data must be owned let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); @@ -186,7 +185,7 @@ fn with_appropriate_checker(cx: Context, id: node_id, check_freevar_bounds(cx, fv.span, var_t, bounds); } - fn check_for_block(cx: Context, fv: @freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_block(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); check_freevar_bounds(cx, fv.span, var_t, bounds); @@ -496,8 +495,8 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool { /// FIXME(#5723)---This code should probably move into regionck. pub fn check_cast_for_escaping_regions( cx: Context, - source: @expr, - target: @expr) + source: &expr, + target: &expr) { // Determine what type we are casting to; if it is not an trait, then no // worries. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 9d4064e99bdb..cd6070cc638f 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -281,80 +281,79 @@ impl LanguageItems { } } -fn LanguageItemCollector(crate: @crate, - session: Session) - -> LanguageItemCollector { - let mut item_refs = HashMap::new(); - - item_refs.insert(@"const", ConstTraitLangItem as uint); - item_refs.insert(@"copy", CopyTraitLangItem as uint); - item_refs.insert(@"owned", OwnedTraitLangItem as uint); - item_refs.insert(@"sized", SizedTraitLangItem as uint); - - item_refs.insert(@"drop", DropTraitLangItem as uint); - - item_refs.insert(@"add", AddTraitLangItem as uint); - item_refs.insert(@"sub", SubTraitLangItem as uint); - item_refs.insert(@"mul", MulTraitLangItem as uint); - item_refs.insert(@"div", DivTraitLangItem as uint); - item_refs.insert(@"rem", RemTraitLangItem as uint); - item_refs.insert(@"neg", NegTraitLangItem as uint); - item_refs.insert(@"not", NotTraitLangItem as uint); - item_refs.insert(@"bitxor", BitXorTraitLangItem as uint); - item_refs.insert(@"bitand", BitAndTraitLangItem as uint); - item_refs.insert(@"bitor", BitOrTraitLangItem as uint); - item_refs.insert(@"shl", ShlTraitLangItem as uint); - item_refs.insert(@"shr", ShrTraitLangItem as uint); - item_refs.insert(@"index", IndexTraitLangItem as uint); - - item_refs.insert(@"eq", EqTraitLangItem as uint); - item_refs.insert(@"ord", OrdTraitLangItem as uint); - - item_refs.insert(@"str_eq", StrEqFnLangItem as uint); - item_refs.insert(@"uniq_str_eq", UniqStrEqFnLangItem as uint); - item_refs.insert(@"annihilate", AnnihilateFnLangItem as uint); - item_refs.insert(@"log_type", LogTypeFnLangItem as uint); - item_refs.insert(@"fail_", FailFnLangItem as uint); - item_refs.insert(@"fail_bounds_check", - FailBoundsCheckFnLangItem as uint); - item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint); - item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); - item_refs.insert(@"malloc", MallocFnLangItem as uint); - item_refs.insert(@"free", FreeFnLangItem as uint); - item_refs.insert(@"borrow_as_imm", BorrowAsImmFnLangItem as uint); - item_refs.insert(@"borrow_as_mut", BorrowAsMutFnLangItem as uint); - item_refs.insert(@"return_to_mut", ReturnToMutFnLangItem as uint); - item_refs.insert(@"check_not_borrowed", - CheckNotBorrowedFnLangItem as uint); - item_refs.insert(@"strdup_uniq", StrDupUniqFnLangItem as uint); - item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint); - item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint); - item_refs.insert(@"start", StartFnLangItem as uint); - item_refs.insert(@"ty_desc", TyDescStructLangItem as uint); - item_refs.insert(@"ty_visitor", TyVisitorTraitLangItem as uint); - item_refs.insert(@"opaque", OpaqueStructLangItem as uint); - - LanguageItemCollector { - crate: crate, - session: session, - items: LanguageItems::new(), - item_refs: item_refs - } -} - -struct LanguageItemCollector { +struct LanguageItemCollector<'self> { items: LanguageItems, - crate: @crate, + crate: &'self crate, session: Session, item_refs: HashMap<@str, uint>, } -impl LanguageItemCollector { +impl<'self> LanguageItemCollector<'self> { + + pub fn new<'a>(crate: &'a crate, session: Session) -> LanguageItemCollector<'a> { + let mut item_refs = HashMap::new(); + + item_refs.insert(@"const", ConstTraitLangItem as uint); + item_refs.insert(@"copy", CopyTraitLangItem as uint); + item_refs.insert(@"owned", OwnedTraitLangItem as uint); + item_refs.insert(@"sized", SizedTraitLangItem as uint); + + item_refs.insert(@"drop", DropTraitLangItem as uint); + + item_refs.insert(@"add", AddTraitLangItem as uint); + item_refs.insert(@"sub", SubTraitLangItem as uint); + item_refs.insert(@"mul", MulTraitLangItem as uint); + item_refs.insert(@"div", DivTraitLangItem as uint); + item_refs.insert(@"rem", RemTraitLangItem as uint); + item_refs.insert(@"neg", NegTraitLangItem as uint); + item_refs.insert(@"not", NotTraitLangItem as uint); + item_refs.insert(@"bitxor", BitXorTraitLangItem as uint); + item_refs.insert(@"bitand", BitAndTraitLangItem as uint); + item_refs.insert(@"bitor", BitOrTraitLangItem as uint); + item_refs.insert(@"shl", ShlTraitLangItem as uint); + item_refs.insert(@"shr", ShrTraitLangItem as uint); + item_refs.insert(@"index", IndexTraitLangItem as uint); + + item_refs.insert(@"eq", EqTraitLangItem as uint); + item_refs.insert(@"ord", OrdTraitLangItem as uint); + + item_refs.insert(@"str_eq", StrEqFnLangItem as uint); + item_refs.insert(@"uniq_str_eq", UniqStrEqFnLangItem as uint); + item_refs.insert(@"annihilate", AnnihilateFnLangItem as uint); + item_refs.insert(@"log_type", LogTypeFnLangItem as uint); + item_refs.insert(@"fail_", FailFnLangItem as uint); + item_refs.insert(@"fail_bounds_check", + FailBoundsCheckFnLangItem as uint); + item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint); + item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); + item_refs.insert(@"malloc", MallocFnLangItem as uint); + item_refs.insert(@"free", FreeFnLangItem as uint); + item_refs.insert(@"borrow_as_imm", BorrowAsImmFnLangItem as uint); + item_refs.insert(@"borrow_as_mut", BorrowAsMutFnLangItem as uint); + item_refs.insert(@"return_to_mut", ReturnToMutFnLangItem as uint); + item_refs.insert(@"check_not_borrowed", + CheckNotBorrowedFnLangItem as uint); + item_refs.insert(@"strdup_uniq", StrDupUniqFnLangItem as uint); + item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint); + item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint); + item_refs.insert(@"start", StartFnLangItem as uint); + item_refs.insert(@"ty_desc", TyDescStructLangItem as uint); + item_refs.insert(@"ty_visitor", TyVisitorTraitLangItem as uint); + item_refs.insert(@"opaque", OpaqueStructLangItem as uint); + + LanguageItemCollector { + crate: crate, + session: session, + items: LanguageItems::new(), + item_refs: item_refs + } + } + pub fn match_and_collect_meta_item(&mut self, item_def_id: def_id, - meta_item: @meta_item) { + meta_item: &meta_item) { match meta_item.node { meta_name_value(key, literal) => { match literal.node { @@ -386,7 +385,7 @@ impl LanguageItemCollector { pub fn match_and_collect_item(&mut self, item_def_id: def_id, - key: @str, + key: &str, value: @str) { if "lang" != key { return; // Didn't match. @@ -455,10 +454,10 @@ impl LanguageItemCollector { } } -pub fn collect_language_items(crate: @crate, +pub fn collect_language_items(crate: &crate, session: Session) -> LanguageItems { - let mut collector = LanguageItemCollector(crate, session); + let mut collector = LanguageItemCollector::new(crate, session); collector.collect(); let LanguageItemCollector { items, _ } = collector; session.abort_if_errors(); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6da10b7c2774..ccbd006edec3 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -701,7 +701,7 @@ fn lint_type_limits() -> visit::vt<@mut Context> { }) } -fn check_item_default_methods(cx: &Context, item: @ast::item) { +fn check_item_default_methods(cx: &Context, item: &ast::item) { match item.node { ast::item_trait(_, _, ref methods) => { for methods.iter().advance |method| { @@ -718,8 +718,8 @@ fn check_item_default_methods(cx: &Context, item: @ast::item) { } } -fn check_item_ctypes(cx: &Context, it: @ast::item) { - fn check_ty(cx: &Context, ty: @ast::Ty) { +fn check_item_ctypes(cx: &Context, it: &ast::item) { + fn check_ty(cx: &Context, ty: &ast::Ty) { match ty.node { ast::ty_path(_, _, id) => { match cx.tcx.def_map.get_copy(&id) { @@ -797,7 +797,7 @@ fn check_type(cx: &Context, span: span, ty: ty::t) { } } -fn check_item_heap(cx: &Context, it: @ast::item) { +fn check_item_heap(cx: &Context, it: &ast::item) { match it.node { ast::item_fn(*) | ast::item_ty(*) | @@ -851,7 +851,7 @@ fn lint_path_statement() -> visit::vt<@mut Context> { }) } -fn check_item_non_camel_case_types(cx: &Context, it: @ast::item) { +fn check_item_non_camel_case_types(cx: &Context, it: &ast::item) { fn is_camel_case(cx: ty::ctxt, ident: ast::ident) -> bool { let ident = cx.sess.str_of(ident); assert!(!ident.is_empty()); @@ -973,7 +973,7 @@ fn lint_session() -> visit::vt<@mut Context> { fn lint_unnecessary_allocations() -> visit::vt<@mut Context> { // Warn if string and vector literals with sigils are immediately borrowed. // Those can have the sigil removed. - fn check(cx: &Context, e: @ast::expr) { + fn check(cx: &Context, e: &ast::expr) { match e.node { ast::expr_vstore(e2, ast::expr_vstore_uniq) | ast::expr_vstore(e2, ast::expr_vstore_box) => { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d8308c516b05..86b8b2943198 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -150,7 +150,7 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str { pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, capture_map: moves::CaptureMap, - crate: @crate) { + crate: &crate) { let visitor = visit::mk_vt(@visit::Visitor { visit_fn: visit_fn, visit_local: visit_local, @@ -322,7 +322,7 @@ impl IrMaps { self.capture_info_map.insert(node_id, @cs); } - pub fn captures(&mut self, expr: @expr) -> @~[CaptureInfo] { + pub fn captures(&mut self, expr: &expr) -> @~[CaptureInfo] { match self.capture_info_map.find(&expr.id) { Some(&caps) => caps, None => { @@ -596,7 +596,7 @@ impl Liveness { } } - pub fn variable_from_path(&self, expr: @expr) -> Option { + pub fn variable_from_path(&self, expr: &expr) -> Option { match expr.node { expr_path(_) => { let def = self.tcx.def_map.get_copy(&expr.id); @@ -923,7 +923,7 @@ impl Liveness { } } - pub fn propagate_through_stmt(&self, stmt: @stmt, succ: LiveNode) + pub fn propagate_through_stmt(&self, stmt: &stmt, succ: LiveNode) -> LiveNode { match stmt.node { stmt_decl(decl, _) => { @@ -940,7 +940,7 @@ impl Liveness { } } - pub fn propagate_through_decl(&self, decl: @decl, succ: LiveNode) + pub fn propagate_through_decl(&self, decl: &decl, succ: LiveNode) -> LiveNode { match decl.node { decl_local(ref local) => { @@ -950,7 +950,7 @@ impl Liveness { } } - pub fn propagate_through_local(&self, local: @local, succ: LiveNode) + pub fn propagate_through_local(&self, local: &local, succ: LiveNode) -> LiveNode { // Note: we mark the variable as defined regardless of whether // there is an initializer. Initially I had thought to only mark @@ -1293,7 +1293,7 @@ impl Liveness { } // see comment on propagate_through_lvalue() - pub fn write_lvalue(&self, expr: @expr, succ: LiveNode, acc: uint) + pub fn write_lvalue(&self, expr: &expr, succ: LiveNode, acc: uint) -> LiveNode { match expr.node { expr_path(_) => self.access_path(expr, succ, acc), @@ -1306,7 +1306,7 @@ impl Liveness { } } - pub fn access_path(&self, expr: @expr, succ: LiveNode, acc: uint) + pub fn access_path(&self, expr: &expr, succ: LiveNode, acc: uint) -> LiveNode { let def = self.tcx.def_map.get_copy(&expr.id); match moves::moved_variable_node_id_from_def(def) { @@ -1324,7 +1324,7 @@ impl Liveness { } pub fn propagate_through_loop(&self, - expr: @expr, + expr: &expr, cond: Option<@expr>, body: &blk, succ: LiveNode) diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 0050239e0663..68307a49d3b6 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -190,7 +190,7 @@ enum UseMode { pub fn compute_moves(tcx: ty::ctxt, method_map: method_map, - crate: @crate) -> MoveMaps + crate: &crate) -> MoveMaps { let visitor = visit::mk_vt(@visit::Visitor { visit_expr: compute_modes_for_expr, @@ -521,7 +521,7 @@ impl VisitContext { } pub fn use_overloaded_operator(&self, - expr: @expr, + expr: &expr, receiver_expr: @expr, arg_exprs: &[@expr], visitor: vt) diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 5bd39e858637..654d77b2a794 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -29,7 +29,7 @@ pub fn pat_id_map(dm: resolve::DefMap, pat: @pat) -> PatIdMap { map } -pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: @pat) -> bool { +pub fn pat_is_variant_or_struct(dm: resolve::DefMap, pat: &pat) -> bool { match pat.node { pat_enum(_, _) | pat_ident(_, _, None) | pat_struct(*) => { match dm.find(&pat.id) { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 94771b4ed0b3..c3241dca1b87 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -40,7 +40,7 @@ use syntax::visit; pub fn check_crate<'mm>(tcx: ty::ctxt, method_map: &'mm method_map, - crate: @ast::crate) { + crate: &ast::crate) { let privileged_items = @mut ~[]; // Adds an item to its scope. diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 7d3e895a0edd..00a44904fed1 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -34,8 +34,6 @@ use syntax::parse::token; use syntax::parse::token::special_idents; use syntax::{ast, visit}; -pub type parent = Option; - /** The region maps encode information about region relationships. @@ -68,10 +66,10 @@ pub struct Context { region_maps: @mut RegionMaps, // Scope where variables should be parented to - var_parent: parent, + var_parent: Option, // Innermost enclosing expression - parent: parent, + parent: Option, } impl RegionMaps { @@ -313,20 +311,8 @@ impl RegionMaps { } } -/// Extracts that current parent from cx, failing if there is none. -pub fn parent_id(cx: Context, span: span) -> ast::node_id { - match cx.parent { - None => { - cx.sess.span_bug(span, "crate should not be parent here"); - } - Some(parent_id) => { - parent_id - } - } -} - /// Records the current parent (if any) as the parent of `child_id`. -pub fn parent_to_expr(cx: Context, child_id: ast::node_id, sp: span) { +fn parent_to_expr(cx: Context, child_id: ast::node_id, sp: span) { debug!("region::parent_to_expr(span=%?)", cx.sess.codemap.span_to_str(sp)); for cx.parent.iter().advance |parent_id| { @@ -334,7 +320,7 @@ pub fn parent_to_expr(cx: Context, child_id: ast::node_id, sp: span) { } } -pub fn resolve_block(blk: &ast::blk, (cx, visitor): (Context, visit::vt)) { +fn resolve_block(blk: &ast::blk, (cx, visitor): (Context, visit::vt)) { // Record the parent of this block. parent_to_expr(cx, blk.node.id, blk.span); @@ -345,17 +331,17 @@ pub fn resolve_block(blk: &ast::blk, (cx, visitor): (Context, visit::vt visit::visit_block(blk, (new_cx, visitor)); } -pub fn resolve_arm(arm: &ast::arm, (cx, visitor): (Context, visit::vt)) { +fn resolve_arm(arm: &ast::arm, (cx, visitor): (Context, visit::vt)) { visit::visit_arm(arm, (cx, visitor)); } -pub fn resolve_pat(pat: @ast::pat, (cx, visitor): (Context, visit::vt)) { +fn resolve_pat(pat: @ast::pat, (cx, visitor): (Context, visit::vt)) { assert_eq!(cx.var_parent, cx.parent); parent_to_expr(cx, pat.id, pat.span); visit::visit_pat(pat, (cx, visitor)); } -pub fn resolve_stmt(stmt: @ast::stmt, (cx, visitor): (Context, visit::vt)) { +fn resolve_stmt(stmt: @ast::stmt, (cx, visitor): (Context, visit::vt)) { match stmt.node { ast::stmt_decl(*) => { visit::visit_stmt(stmt, (cx, visitor)); @@ -370,7 +356,7 @@ pub fn resolve_stmt(stmt: @ast::stmt, (cx, visitor): (Context, visit::vt)) { +fn resolve_expr(expr: @ast::expr, (cx, visitor): (Context, visit::vt)) { parent_to_expr(cx, expr.id, expr.span); let mut new_cx = cx; @@ -409,27 +395,27 @@ pub fn resolve_expr(expr: @ast::expr, (cx, visitor): (Context, visit::vt)) { +fn resolve_local(local: @ast::local, + (cx, visitor) : (Context, + visit::vt)) { assert_eq!(cx.var_parent, cx.parent); parent_to_expr(cx, local.node.id, local.span); visit::visit_local(local, (cx, visitor)); } -pub fn resolve_item(item: @ast::item, (cx, visitor): (Context, visit::vt)) { +fn resolve_item(item: @ast::item, (cx, visitor): (Context, visit::vt)) { // Items create a new outer block scope as far as we're concerned. let new_cx = Context {var_parent: None, parent: None, ..cx}; visit::visit_item(item, (new_cx, visitor)); } -pub fn resolve_fn(fk: &visit::fn_kind, - decl: &ast::fn_decl, - body: &ast::blk, - sp: span, - id: ast::node_id, - (cx, visitor): (Context, - visit::vt)) { +fn resolve_fn(fk: &visit::fn_kind, + decl: &ast::fn_decl, + body: &ast::blk, + sp: span, + id: ast::node_id, + (cx, visitor): (Context, + visit::vt)) { debug!("region::resolve_fn(id=%?, \ span=%?, \ body.node.id=%?, \ @@ -468,7 +454,7 @@ pub fn resolve_fn(fk: &visit::fn_kind, pub fn resolve_crate(sess: Session, def_map: resolve::DefMap, - crate: @ast::crate) -> @mut RegionMaps + crate: &ast::crate) -> @mut RegionMaps { let region_maps = @mut RegionMaps { scope_map: HashMap::new(), @@ -522,14 +508,12 @@ pub struct region_dep { id: ast::node_id } -pub type dep_map = @mut HashMap; - pub struct DetermineRpCtxt { sess: Session, ast_map: ast_map::map, def_map: resolve::DefMap, region_paramd_items: region_paramd_items, - dep_map: dep_map, + dep_map: @mut HashMap, worklist: ~[ast::node_id], // the innermost enclosing item id @@ -619,14 +603,8 @@ impl DetermineRpCtxt { ast_map::node_id_to_str(self.ast_map, self.item_id, token::get_ident_interner()), copy self.ambient_variance); - let vec = match self.dep_map.find(&from) { - Some(&vec) => vec, - None => { - let vec = @mut ~[]; - let dep_map = self.dep_map; - dep_map.insert(from, vec); - vec - } + let vec = do self.dep_map.find_or_insert_with(from) |_| { + @mut ~[] }; let dep = region_dep { ambient_variance: self.ambient_variance, @@ -715,21 +693,21 @@ impl DetermineRpCtxt { } } -pub fn determine_rp_in_item(item: @ast::item, - (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { +fn determine_rp_in_item(item: @ast::item, + (cx, visitor): (@mut DetermineRpCtxt, + visit::vt<@mut DetermineRpCtxt>)) { do cx.with(item.id, true) { visit::visit_item(item, (cx, visitor)); } } -pub fn determine_rp_in_fn(fk: &visit::fn_kind, - decl: &ast::fn_decl, - body: &ast::blk, - _: span, - _: ast::node_id, - (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { +fn determine_rp_in_fn(fk: &visit::fn_kind, + decl: &ast::fn_decl, + body: &ast::blk, + _: span, + _: ast::node_id, + (cx, visitor): (@mut DetermineRpCtxt, + visit::vt<@mut DetermineRpCtxt>)) { do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { for decl.inputs.iter().advance |a| { @@ -743,17 +721,17 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind, } } -pub fn determine_rp_in_ty_method(ty_m: &ast::ty_method, - (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { +fn determine_rp_in_ty_method(ty_m: &ast::ty_method, + (cx, visitor): (@mut DetermineRpCtxt, + visit::vt<@mut DetermineRpCtxt>)) { do cx.with(cx.item_id, false) { visit::visit_ty_method(ty_m, (cx, visitor)); } } -pub fn determine_rp_in_ty(ty: @ast::Ty, - (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { +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 // be region-parameterized. if cx.item_id is zero, then this type // is not a member of a type defn nor is it a constitutent of an @@ -883,7 +861,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, } } -pub fn determine_rp_in_struct_field( +fn determine_rp_in_struct_field( cm: @ast::struct_field, (cx, visitor): (@mut DetermineRpCtxt, visit::vt<@mut DetermineRpCtxt>)) { @@ -893,7 +871,7 @@ pub fn determine_rp_in_struct_field( pub fn determine_rp_in_crate(sess: Session, ast_map: ast_map::map, def_map: resolve::DefMap, - crate: @ast::crate) + crate: &ast::crate) -> region_paramd_items { let cx = @mut DetermineRpCtxt { sess: sess, diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 63b39b8fe763..a2cbc4d6fe05 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -406,8 +406,6 @@ pub fn expand_nested_bindings<'r>(bcx: block, } } -pub type enter_pat<'self> = &'self fn(@ast::pat) -> Option<~[@ast::pat]>; - pub fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) { if !pat_is_binding_or_wild(bcx.tcx().def_map, p) { bcx.sess().span_bug( @@ -417,6 +415,8 @@ pub fn assert_is_binding_or_wild(bcx: block, p: @ast::pat) { } } +pub type enter_pat<'self> = &'self fn(@ast::pat) -> Option<~[@ast::pat]>; + pub fn enter_match<'r>(bcx: block, dm: DefMap, m: &[@Match<'r>], @@ -1048,7 +1048,7 @@ pub fn any_tuple_struct_pat(bcx: block, m: &[@Match], col: uint) -> bool { pub type mk_fail = @fn() -> BasicBlockRef; pub fn pick_col(m: &[@Match]) -> uint { - fn score(p: @ast::pat) -> uint { + fn score(p: &ast::pat) -> uint { match p.node { ast::pat_lit(_) | ast::pat_enum(_, _) | ast::pat_range(_, _) => 1u, ast::pat_ident(_, _, Some(p)) => score(p), @@ -1609,7 +1609,7 @@ pub fn compile_submatch(bcx: block, } pub fn trans_match(bcx: block, - match_expr: @ast::expr, + match_expr: &ast::expr, discr_expr: @ast::expr, arms: ~[ast::arm], dest: Dest) -> block { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b4e6245f629d..a0628bc8e87c 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -160,7 +160,7 @@ pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { // Only use this if you are going to actually define the function. It's // not valid to simply declare a function as internal. -pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, ty: Type) -> ValueRef { +pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { let llfn = decl_cdecl_fn(llmod, name, ty); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); return llfn; @@ -592,8 +592,7 @@ pub fn compare_scalar_values(cx: block, } } -pub type val_pair_fn = @fn(block, ValueRef, ValueRef) -> block; -pub type val_and_ty_fn = @fn(block, ValueRef, ty::t) -> block; +pub type val_and_ty_fn<'self> = &'self fn(block, ValueRef, ty::t) -> block; pub fn load_inbounds(cx: block, p: ValueRef, idxs: &[uint]) -> ValueRef { return Load(cx, GEPi(cx, p, idxs)); @@ -1032,13 +1031,13 @@ pub fn build_return(bcx: block) { Br(bcx, bcx.fcx.llreturn); } -pub fn ignore_lhs(_bcx: block, local: @ast::local) -> bool { +pub fn ignore_lhs(_bcx: block, local: &ast::local) -> bool { match local.node.pat.node { ast::pat_wild => true, _ => false } } -pub fn init_local(bcx: block, local: @ast::local) -> block { +pub fn init_local(bcx: block, local: &ast::local) -> block { debug!("init_local(bcx=%s, local.id=%?)", bcx.to_str(), local.node.id); @@ -1378,7 +1377,7 @@ pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { } } -pub fn alloc_local(cx: block, local: @ast::local) -> block { +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 { @@ -2379,7 +2378,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef, Store(bcx, llenvblobptr, env_cell); } -pub fn item_path(ccx: &CrateContext, i: @ast::item) -> path { +pub fn item_path(ccx: &CrateContext, i: &ast::item) -> path { let base = match ccx.tcx.items.get_copy(&i.id) { ast_map::node_item(_, p) => p, // separate map for paths? @@ -2544,7 +2543,7 @@ pub fn register_method(ccx: @mut CrateContext, } // The constant translation pass. -pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { +pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) { let _icx = push_ctxt("trans_constant"); match it.node { ast::item_enum(ref enum_definition, _) => { @@ -2894,7 +2893,7 @@ pub fn write_abi_version(ccx: &mut CrateContext) { } pub fn trans_crate(sess: session::Session, - crate: @ast::crate, + crate: &ast::crate, tcx: ty::ctxt, output: &Path, emap2: resolve::ExportMap2, diff --git a/src/librustc/middle/trans/block.rs b/src/librustc/middle/trans/block.rs deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 227e22131636..3ce52a63171e 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -468,7 +468,7 @@ pub fn make_closure_glue( cx: block, v: ValueRef, t: ty::t, - glue_fn: @fn(block, v: ValueRef, t: ty::t) -> block) -> block { + glue_fn: &fn(block, v: ValueRef, t: ty::t) -> block) -> block { let _icx = push_ctxt("closure::make_closure_glue"); let bcx = cx; let tcx = cx.tcx(); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 272d7b234aa5..79d83fbc8570 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -411,7 +411,6 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { // drop glue checks whether it is zero. pub fn revoke_clean(cx: block, val: ValueRef) { do in_scope_cx(cx) |scope_info| { - let scope_info = &mut *scope_info; // FIXME(#5074) workaround borrowck let cleanup_pos = scope_info.cleanups.iter().position_( |cu| match *cu { clean_temp(v, _, _) if v == val => true, @@ -473,7 +472,7 @@ pub trait get_node_info { fn info(&self) -> Option; } -impl get_node_info for @ast::expr { +impl get_node_info for ast::expr { fn info(&self) -> Option { Some(NodeInfo {id: self.id, callee_id: self.get_callee_id(), @@ -573,7 +572,7 @@ 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, f: &fn(si: &mut scope_info)) { let mut cur = cx; loop { match cur.kind { @@ -612,11 +611,11 @@ impl block_ { e.repr(self.tcx()) } - pub fn expr_is_lval(&self, e: @ast::expr) -> bool { + pub fn expr_is_lval(&self, e: &ast::expr) -> bool { ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e) } - pub fn expr_kind(&self, e: @ast::expr) -> ty::ExprKind { + pub fn expr_kind(&self, e: &ast::expr) -> ty::ExprKind { ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e) } @@ -995,11 +994,11 @@ pub fn node_id_type(bcx: block, id: ast::node_id) -> ty::t { monomorphize_type(bcx, t) } -pub fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t { +pub fn expr_ty(bcx: block, ex: &ast::expr) -> ty::t { node_id_type(bcx, ex.id) } -pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t { +pub fn expr_ty_adjusted(bcx: block, ex: &ast::expr) -> ty::t { let tcx = bcx.tcx(); let t = ty::expr_ty_adjusted(tcx, ex); monomorphize_type(bcx, t) diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 98eb858be55f..d7b6e9cf5a37 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -35,7 +35,7 @@ use core::libc::c_uint; use core::str; use syntax::{ast, ast_util, ast_map}; -pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) +pub fn const_lit(cx: &mut CrateContext, e: &ast::expr, lit: ast::lit) -> ValueRef { let _icx = push_ctxt("trans_lit"); match lit.node { @@ -82,7 +82,7 @@ pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef { } } -pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) +pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr]) -> (ValueRef, ValueRef, Type) { unsafe { let vec_ty = ty::expr_ty(cx.tcx, e); @@ -101,7 +101,7 @@ pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) } } -fn const_addr_of(cx: @mut CrateContext, cv: ValueRef) -> ValueRef { +fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef { unsafe { let gv = do "const".as_c_str |name| { llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name) @@ -113,7 +113,7 @@ fn const_addr_of(cx: @mut CrateContext, cv: ValueRef) -> ValueRef { } } -fn const_deref_ptr(cx: @mut CrateContext, v: ValueRef) -> ValueRef { +fn const_deref_ptr(cx: &mut CrateContext, v: ValueRef) -> ValueRef { let v = match cx.const_globals.find(&(v as int)) { Some(&v) => v, None => v @@ -124,13 +124,13 @@ fn const_deref_ptr(cx: @mut CrateContext, v: ValueRef) -> ValueRef { } } -fn const_deref_newtype(cx: @mut CrateContext, v: ValueRef, t: ty::t) +fn const_deref_newtype(cx: &mut CrateContext, v: ValueRef, t: ty::t) -> ValueRef { let repr = adt::represent_type(cx, t); adt::const_get_field(cx, repr, v, 0, 0) } -fn const_deref(cx: @mut CrateContext, v: ValueRef, t: ty::t, explicit: bool) +fn const_deref(cx: &mut CrateContext, v: ValueRef, t: ty::t, explicit: bool) -> (ValueRef, ty::t) { match ty::deref(cx.tcx, t, explicit) { Some(ref mt) => { @@ -247,7 +247,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { llconst } -fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { +fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { unsafe { let _icx = push_ctxt("const_expr"); return match e.node { @@ -393,7 +393,8 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { let llunitty = type_of::type_of(cx, unit_ty); let unit_sz = machine::llsize_of(cx, llunitty); - (const_deref_ptr(cx, const_get_elt(cx, bv, [0])), + let e1 = const_get_elt(cx, bv, [0]); + (const_deref_ptr(cx, e1), llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]), unit_sz)) }, diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index f101a8657322..862f455aeb6b 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -178,7 +178,7 @@ pub fn trans_loop(bcx:block, return next_bcx; } -pub fn trans_log(log_ex: @ast::expr, +pub fn trans_log(log_ex: &ast::expr, lvl: @ast::expr, bcx: block, e: @ast::expr) -> block { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 32d0f8887b90..de56d9a05f15 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -723,7 +723,7 @@ impl Datum { } /// expr: The deref expression. - pub fn deref(&self, bcx: block, expr: @ast::expr, derefs: uint) + pub fn deref(&self, bcx: block, expr: &ast::expr, derefs: uint) -> DatumBlock { match self.try_deref(bcx, expr.span, expr.id, derefs, false) { (Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres }, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 0e64d7582ac5..02f276cd0503 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -254,7 +254,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { fn auto_slice(bcx: block, autoderefs: uint, - expr: @ast::expr, + expr: &ast::expr, datum: Datum) -> DatumBlock { // This is not the most efficient thing possible; since slices // are two words it'd be better if this were compiled in @@ -280,7 +280,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { DatumBlock {bcx: bcx, datum: scratch} } - fn add_env(bcx: block, expr: @ast::expr, datum: Datum) -> DatumBlock { + fn add_env(bcx: block, expr: &ast::expr, datum: Datum) -> DatumBlock { // This is not the most efficient thing possible; since closures // are two words it'd be better if this were compiled in // 'dest' mode, but I can't find a nice way to structure the @@ -301,7 +301,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { fn auto_slice_and_ref(bcx: block, autoderefs: uint, - expr: @ast::expr, + expr: &ast::expr, datum: Datum) -> DatumBlock { let DatumBlock { bcx, datum } = auto_slice(bcx, autoderefs, expr, datum); auto_ref(bcx, datum) @@ -705,7 +705,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, } } -fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr, +fn trans_def_dps_unadjusted(bcx: block, ref_expr: &ast::expr, def: ast::def, dest: Dest) -> block { let _icx = push_ctxt("trans_def_dps_unadjusted"); let ccx = bcx.ccx(); @@ -752,7 +752,7 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr, } fn trans_def_datum_unadjusted(bcx: block, - ref_expr: @ast::expr, + ref_expr: &ast::expr, def: ast::def) -> DatumBlock { let _icx = push_ctxt("trans_def_datum_unadjusted"); @@ -776,7 +776,7 @@ fn trans_def_datum_unadjusted(bcx: block, } fn fn_data_to_datum(bcx: block, - ref_expr: @ast::expr, + ref_expr: &ast::expr, def_id: ast::def_id, fn_data: callee::FnData) -> DatumBlock { /*! @@ -873,7 +873,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } fn trans_index(bcx: block, - index_expr: @ast::expr, + index_expr: &ast::expr, base: @ast::expr, idx: @ast::expr) -> DatumBlock { //! Translates `base[idx]`. @@ -936,7 +936,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } fn trans_def_lvalue(bcx: block, - ref_expr: @ast::expr, + ref_expr: &ast::expr, def: ast::def) -> DatumBlock { @@ -1263,7 +1263,7 @@ fn trans_immediate_lit(bcx: block, expr: @ast::expr, } fn trans_unary_datum(bcx: block, - un_expr: @ast::expr, + un_expr: &ast::expr, op: ast::unop, sub_expr: @ast::expr) -> DatumBlock { let _icx = push_ctxt("trans_unary_datum"); @@ -1337,7 +1337,7 @@ fn trans_unary_datum(bcx: block, } } -fn trans_addr_of(bcx: block, expr: @ast::expr, +fn trans_addr_of(bcx: block, expr: &ast::expr, subexpr: @ast::expr) -> DatumBlock { let _icx = push_ctxt("trans_addr_of"); let mut bcx = bcx; @@ -1349,7 +1349,7 @@ fn trans_addr_of(bcx: block, expr: @ast::expr, // Important to get types for both lhs and rhs, because one might be _|_ // and the other not. fn trans_eager_binop(bcx: block, - binop_expr: @ast::expr, + binop_expr: &ast::expr, binop_ty: ty::t, op: ast::binop, lhs_datum: &Datum, @@ -1447,7 +1447,7 @@ fn trans_eager_binop(bcx: block, enum lazy_binop_ty { lazy_and, lazy_or } fn trans_lazy_binop(bcx: block, - binop_expr: @ast::expr, + binop_expr: &ast::expr, op: lazy_binop_ty, a: @ast::expr, b: @ast::expr) -> DatumBlock { @@ -1492,7 +1492,7 @@ fn trans_lazy_binop(bcx: block, } fn trans_binary(bcx: block, - binop_expr: @ast::expr, + binop_expr: &ast::expr, op: ast::binop, lhs: @ast::expr, rhs: @ast::expr) -> DatumBlock @@ -1518,7 +1518,7 @@ fn trans_binary(bcx: block, } fn trans_overloaded_op(bcx: block, - expr: @ast::expr, + expr: &ast::expr, callee_id: ast::node_id, rcvr: @ast::expr, args: ~[@ast::expr], diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index a5a6c1434c63..6263ffb318eb 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -55,7 +55,7 @@ fn abi_info(ccx: @mut CrateContext) -> @cabi::ABIInfo { } } -pub fn link_name(ccx: &CrateContext, i: @ast::foreign_item) -> @str { +pub fn link_name(ccx: &CrateContext, i: &ast::foreign_item) -> @str { match attr::first_attr_value_str_by_name(i.attrs, "link_name") { None => ccx.sess.str_of(i.ident), Some(ln) => ln, @@ -89,7 +89,7 @@ struct LlvmSignature { sret: bool, } -fn foreign_signature(ccx: @mut CrateContext, fn_sig: &ty::FnSig) +fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig) -> LlvmSignature { /*! * The ForeignSignature is the LLVM types of the arguments/return type @@ -138,7 +138,7 @@ type shim_ret_builder<'self> = llretval: ValueRef); fn build_shim_fn_(ccx: @mut CrateContext, - shim_name: ~str, + shim_name: &str, llbasefn: ValueRef, tys: &ShimTypes, cc: lib::llvm::CallConv, @@ -357,7 +357,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, } fn build_shim_fn(ccx: @mut CrateContext, - foreign_item: @ast::foreign_item, + foreign_item: &ast::foreign_item, tys: &ShimTypes, cc: lib::llvm::CallConv) -> ValueRef { @@ -419,7 +419,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, // over the place fn build_direct_fn(ccx: @mut CrateContext, decl: ValueRef, - item: @ast::foreign_item, + item: &ast::foreign_item, tys: &ShimTypes, cc: lib::llvm::CallConv) { debug!("build_direct_fn(%s)", link_name(ccx, item)); @@ -446,7 +446,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, // over the place fn build_fast_ffi_fn(ccx: @mut CrateContext, decl: ValueRef, - item: @ast::foreign_item, + item: &ast::foreign_item, tys: &ShimTypes, cc: lib::llvm::CallConv) { debug!("build_fast_ffi_fn(%s)", link_name(ccx, item)); @@ -541,7 +541,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, pub fn trans_intrinsic(ccx: @mut CrateContext, decl: ValueRef, - item: @ast::foreign_item, + item: &ast::foreign_item, path: ast_map::path, substs: @param_substs, attributes: &[ast::attribute], diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 1f16a735c7c6..0172b7054659 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -205,7 +205,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext, field: uint, - ti: @mut tydesc_info) -> bool { + ti: &mut tydesc_info) -> bool { let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue"); let simpl = simplified_glue_type(ccx.tcx, field, ti.ty); if simpl != ti.ty { @@ -244,7 +244,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, None => { debug!("+++ lazily_emit_tydesc_glue TAKE %s", ppaux::ty_to_str(ccx.tcx, ti.ty)); - let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"take"); + let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "take"); ti.take_glue = Some(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn, make_take_glue, "take"); debug!("--- lazily_emit_tydesc_glue TAKE %s", @@ -257,7 +257,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, None => { debug!("+++ lazily_emit_tydesc_glue DROP %s", ppaux::ty_to_str(ccx.tcx, ti.ty)); - let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"drop"); + let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "drop"); ti.drop_glue = Some(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn, make_drop_glue, "drop"); debug!("--- lazily_emit_tydesc_glue DROP %s", @@ -270,7 +270,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, None => { debug!("+++ lazily_emit_tydesc_glue FREE %s", ppaux::ty_to_str(ccx.tcx, ti.ty)); - let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"free"); + let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "free"); ti.free_glue = Some(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn, make_free_glue, "free"); debug!("--- lazily_emit_tydesc_glue FREE %s", @@ -283,7 +283,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, None => { debug!("+++ lazily_emit_tydesc_glue VISIT %s", ppaux::ty_to_str(ccx.tcx, ti.ty)); - let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"visit"); + let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit"); ti.visit_glue = Some(glue_fn); make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit"); debug!("--- lazily_emit_tydesc_glue VISIT %s", @@ -627,12 +627,12 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_opaque_closure_ptr(ck) => { closure::make_opaque_cbox_take_glue(bcx, ck, v) } - ty::ty_struct(did, ref substs) => { + ty::ty_struct(did, _) => { let tcx = bcx.tcx(); let bcx = iter_structural_ty(bcx, v, t, take_ty); match ty::ty_dtor(tcx, did) { - ty::TraitDtor(dtor, false) => { + ty::TraitDtor(_, false) => { // Zero out the struct unsafe { let ty = Type::from_ref(llvm::LLVMTypeOf(v)); @@ -700,12 +700,11 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { return inf; } -pub type glue_helper = @fn(block, ValueRef, ty::t); +pub type glue_helper<'self> = &'self fn(block, ValueRef, ty::t); -pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: Type, - name: ~str) -> ValueRef { +pub fn declare_generic_glue(ccx: &mut CrateContext, t: ty::t, llfnty: Type, + name: &str) -> ValueRef { let _icx = push_ctxt("declare_generic_glue"); - let name = name; let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed(); debug!("%s is for type %s", fn_nm, ppaux::ty_to_str(ccx.tcx, t)); note_unique_llvm_symbol(ccx, fn_nm); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 96f8a1976a68..ebcc3d811eba 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -357,7 +357,7 @@ pub fn method_from_methods(ms: &[@ast::method], name: ast::ident) ms.iter().find_(|m| m.ident == name).map(|m| ast_util::local_def(m.id)) } -pub fn method_with_name_or_default(ccx: @mut CrateContext, +pub fn method_with_name_or_default(ccx: &mut CrateContext, impl_id: ast::def_id, name: ast::ident) -> ast::def_id { let imp = ccx.impl_method_cache.find_copy(&(impl_id, name)); @@ -742,8 +742,8 @@ pub fn get_vtable(bcx: block, } /// Helper function to declare and initialize the vtable. -pub fn make_vtable(ccx: @mut CrateContext, - tydesc: @mut tydesc_info, +pub fn make_vtable(ccx: &mut CrateContext, + tydesc: &tydesc_info, ptrs: &[ValueRef]) -> ValueRef { unsafe { @@ -770,7 +770,7 @@ pub fn make_vtable(ccx: @mut CrateContext, pub fn make_impl_vtable(bcx: block, impl_id: ast::def_id, self_ty: ty::t, - substs: ~[ty::t], + substs: &[ty::t], vtables: typeck::vtable_res) -> ValueRef { let ccx = bcx.ccx(); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 24c733346976..16695ad59a07 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -86,7 +86,7 @@ impl Reflector { self.c_tydesc(mt.ty)] } - pub fn visit(&mut self, ty_name: ~str, args: &[ValueRef]) { + pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) { let tcx = self.bcx.tcx(); let mth_idx = ty::method_idx( tcx.sess.ident_of(~"visit_" + ty_name), @@ -122,7 +122,7 @@ impl Reflector { } pub fn bracketed(&mut self, - bracket_name: ~str, + bracket_name: &str, extra: &[ValueRef], inner: &fn(&mut Reflector)) { self.visit(~"enter_" + bracket_name, extra); @@ -146,7 +146,7 @@ impl Reflector { } } - pub fn leaf(&mut self, name: ~str) { + pub fn leaf(&mut self, name: &str) { self.visit(name, []); } @@ -156,27 +156,27 @@ impl Reflector { debug!("reflect::visit_ty %s", ty_to_str(bcx.ccx().tcx, t)); match ty::get(t).sty { - ty::ty_bot => self.leaf(~"bot"), - ty::ty_nil => self.leaf(~"nil"), - ty::ty_bool => self.leaf(~"bool"), - ty::ty_int(ast::ty_i) => self.leaf(~"int"), - ty::ty_int(ast::ty_char) => self.leaf(~"char"), - ty::ty_int(ast::ty_i8) => self.leaf(~"i8"), - ty::ty_int(ast::ty_i16) => self.leaf(~"i16"), - ty::ty_int(ast::ty_i32) => self.leaf(~"i32"), - ty::ty_int(ast::ty_i64) => self.leaf(~"i64"), - ty::ty_uint(ast::ty_u) => self.leaf(~"uint"), - ty::ty_uint(ast::ty_u8) => self.leaf(~"u8"), - ty::ty_uint(ast::ty_u16) => self.leaf(~"u16"), - ty::ty_uint(ast::ty_u32) => self.leaf(~"u32"), - ty::ty_uint(ast::ty_u64) => self.leaf(~"u64"), - ty::ty_float(ast::ty_f) => self.leaf(~"float"), - ty::ty_float(ast::ty_f32) => self.leaf(~"f32"), - ty::ty_float(ast::ty_f64) => self.leaf(~"f64"), + ty::ty_bot => self.leaf("bot"), + ty::ty_nil => self.leaf("nil"), + ty::ty_bool => self.leaf("bool"), + ty::ty_int(ast::ty_i) => self.leaf("int"), + ty::ty_int(ast::ty_char) => self.leaf("char"), + ty::ty_int(ast::ty_i8) => self.leaf("i8"), + ty::ty_int(ast::ty_i16) => self.leaf("i16"), + ty::ty_int(ast::ty_i32) => self.leaf("i32"), + ty::ty_int(ast::ty_i64) => self.leaf("i64"), + ty::ty_uint(ast::ty_u) => self.leaf("uint"), + ty::ty_uint(ast::ty_u8) => self.leaf("u8"), + ty::ty_uint(ast::ty_u16) => self.leaf("u16"), + ty::ty_uint(ast::ty_u32) => self.leaf("u32"), + ty::ty_uint(ast::ty_u64) => self.leaf("u64"), + ty::ty_float(ast::ty_f) => self.leaf("float"), + ty::ty_float(ast::ty_f32) => self.leaf("f32"), + ty::ty_float(ast::ty_f64) => self.leaf("f64"), ty::ty_unboxed_vec(ref mt) => { let values = self.c_mt(mt); - self.visit(~"vec", values) + self.visit("vec", values) } ty::ty_estr(vst) => { @@ -190,28 +190,28 @@ impl Reflector { } ty::ty_box(ref mt) => { let extra = self.c_mt(mt); - self.visit(~"box", extra) + self.visit("box", extra) } ty::ty_uniq(ref mt) => { let extra = self.c_mt(mt); - self.visit(~"uniq", extra) + self.visit("uniq", extra) } ty::ty_ptr(ref mt) => { let extra = self.c_mt(mt); - self.visit(~"ptr", extra) + self.visit("ptr", extra) } ty::ty_rptr(_, ref mt) => { let extra = self.c_mt(mt); - self.visit(~"rptr", extra) + self.visit("rptr", extra) } ty::ty_tup(ref tys) => { let extra = ~[self.c_uint(tys.len())] + self.c_size_and_align(t); - do self.bracketed(~"tup", extra) |this| { + do self.bracketed("tup", extra) |this| { for tys.iter().enumerate().advance |(i, t)| { let extra = ~[this.c_uint(i), this.c_tydesc(*t)]; - this.visit(~"tup_field", extra); + this.visit("tup_field", extra); } } } @@ -226,9 +226,9 @@ impl Reflector { self.c_uint(sigilval), self.c_uint(fty.sig.inputs.len()), self.c_uint(retval)]; - self.visit(~"enter_fn", extra); + self.visit("enter_fn", extra); self.visit_sig(retval, &fty.sig); - self.visit(~"leave_fn", extra); + self.visit("leave_fn", extra); } // FIXME (#2594): fetch constants out of intrinsic:: for the @@ -241,9 +241,9 @@ impl Reflector { self.c_uint(sigilval), self.c_uint(fty.sig.inputs.len()), self.c_uint(retval)]; - self.visit(~"enter_fn", extra); + self.visit("enter_fn", extra); self.visit_sig(retval, &fty.sig); - self.visit(~"leave_fn", extra); + self.visit("leave_fn", extra); } ty::ty_struct(did, ref substs) => { @@ -253,13 +253,13 @@ impl Reflector { let extra = ~[self.c_uint(fields.len())] + self.c_size_and_align(t); - do self.bracketed(~"class", extra) |this| { + do self.bracketed("class", extra) |this| { for fields.iter().enumerate().advance |(i, field)| { let extra = ~[this.c_uint(i), this.c_slice( bcx.ccx().sess.str_of(field.ident))] + this.c_mt(&field.mt); - this.visit(~"class_field", extra); + this.visit("class_field", extra); } } } @@ -309,14 +309,14 @@ impl Reflector { let enum_args = ~[self.c_uint(variants.len()), make_get_disr()] + self.c_size_and_align(t); - do self.bracketed(~"enum", enum_args) |this| { + do self.bracketed("enum", enum_args) |this| { for variants.iter().enumerate().advance |(i, v)| { let name = ccx.sess.str_of(v.name); let variant_args = ~[this.c_uint(i), this.c_int(v.disr_val), this.c_uint(v.args.len()), this.c_slice(name)]; - do this.bracketed(~"enum_variant", variant_args) |this| { + do this.bracketed("enum_variant", variant_args) |this| { for v.args.iter().enumerate().advance |(j, a)| { let bcx = this.bcx; let null = C_null(llptrty); @@ -325,7 +325,7 @@ impl Reflector { let field_args = ~[this.c_uint(j), offset, this.c_tydesc(*a)]; - this.visit(~"enum_variant_field", field_args); + this.visit("enum_variant_field", field_args); } } } @@ -333,20 +333,20 @@ impl Reflector { } // Miscallaneous extra types - ty::ty_trait(_, _, _, _, _) => self.leaf(~"trait"), - ty::ty_infer(_) => self.leaf(~"infer"), - ty::ty_err => self.leaf(~"err"), + ty::ty_trait(_, _, _, _, _) => self.leaf("trait"), + ty::ty_infer(_) => self.leaf("infer"), + ty::ty_err => self.leaf("err"), ty::ty_param(ref p) => { let extra = ~[self.c_uint(p.idx)]; - self.visit(~"param", extra) + self.visit("param", extra) } - ty::ty_self(*) => self.leaf(~"self"), - ty::ty_type => self.leaf(~"type"), - ty::ty_opaque_box => self.leaf(~"opaque_box"), + ty::ty_self(*) => self.leaf("self"), + ty::ty_type => self.leaf("type"), + ty::ty_opaque_box => self.leaf("opaque_box"), ty::ty_opaque_closure_ptr(ck) => { let ckval = ast_sigil_constant(ck); let extra = ~[self.c_uint(ckval)]; - self.visit(~"closure_ptr", extra) + self.visit("closure_ptr", extra) } } } @@ -357,11 +357,11 @@ impl Reflector { let extra = ~[self.c_uint(i), self.c_uint(modeval), self.c_tydesc(*arg)]; - self.visit(~"fn_input", extra); + self.visit("fn_input", extra); } let extra = ~[self.c_uint(retval), self.c_tydesc(sig.output)]; - self.visit(~"fn_output", extra); + self.visit("fn_output", extra); } } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index df8de7b7cd5a..1344bed96eec 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -164,7 +164,7 @@ impl VecTypes { pub fn trans_fixed_vstore(bcx: block, vstore_expr: @ast::expr, - content_expr: @ast::expr, + content_expr: &ast::expr, dest: expr::Dest) -> block { //! @@ -286,7 +286,7 @@ pub fn trans_lit_str(bcx: block, pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::expr, - content_expr: @ast::expr) -> DatumBlock { + content_expr: &ast::expr) -> DatumBlock { //! // // @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the @@ -346,7 +346,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e pub fn write_content(bcx: block, vt: &VecTypes, vstore_expr: @ast::expr, - content_expr: @ast::expr, + content_expr: &ast::expr, dest: Dest) -> block { let _icx = push_ctxt("tvec::write_content"); @@ -471,7 +471,7 @@ pub fn write_content(bcx: block, } } -pub fn vec_types_from_expr(bcx: block, vec_expr: @ast::expr) -> VecTypes { +pub fn vec_types_from_expr(bcx: block, vec_expr: &ast::expr) -> VecTypes { let vec_ty = node_id_type(bcx, vec_expr.id); vec_types(bcx, vec_ty) } @@ -488,7 +488,7 @@ pub fn vec_types(bcx: block, vec_ty: ty::t) -> VecTypes { llunit_size: llunit_size} } -pub fn elements_required(bcx: block, content_expr: @ast::expr) -> uint { +pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint { //! Figure out the number of elements we need to store this content match content_expr.node { @@ -542,8 +542,6 @@ pub fn get_base_and_len(bcx: block, } } -pub type val_and_ty_fn = @fn(block, ValueRef, ty::t) -> Result; - pub type iter_vec_block<'self> = &'self fn(block, ValueRef, ty::t) -> block; pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 8cd776c99d69..c636b7f48761 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -79,7 +79,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { for sig.inputs.iter().advance |arg| { - type_needs(cx, use_repr, *arg); + type_needs(&cx, use_repr, *arg); } } _ => () @@ -100,7 +100,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) ast_map::node_item(@ast::item { node: item_fn(_, _, _, _, ref body), _ }, _) | ast_map::node_method(@ast::method {body: ref body, _}, _, _) => { - handle_body(cx, body); + handle_body(&cx, body); } ast_map::node_trait_method(*) => { // This will be a static trait method. For now, we just assume @@ -177,7 +177,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) uses } -pub fn type_needs(cx: Context, use_: uint, ty: ty::t) { +pub fn type_needs(cx: &Context, use_: uint, ty: ty::t) { // Optimization -- don't descend type if all params already have this use let len = { let uses = &*cx.uses; @@ -191,7 +191,7 @@ pub fn type_needs(cx: Context, use_: uint, ty: ty::t) { } } -pub fn type_needs_inner(cx: Context, +pub fn type_needs_inner(cx: &Context, use_: uint, ty: ty::t, enums_seen: @List) { @@ -233,11 +233,11 @@ pub fn type_needs_inner(cx: Context, } } -pub fn node_type_needs(cx: Context, use_: uint, id: node_id) { +pub fn node_type_needs(cx: &Context, use_: uint, id: node_id) { type_needs(cx, use_, ty::node_id_to_type(cx.ccx.tcx, id)); } -pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) { +pub fn mark_for_method_call(cx: &Context, e_id: node_id, callee_id: node_id) { let mut opt_static_did = None; { let r = cx.ccx.maps.method_map.find(&e_id); @@ -275,7 +275,7 @@ pub fn mark_for_method_call(cx: Context, e_id: node_id, callee_id: node_id) { } } -pub fn mark_for_expr(cx: Context, e: @expr) { +pub fn mark_for_expr(cx: &Context, e: &expr) { match e.node { expr_vstore(_, _) | expr_vec(_, _) | expr_struct(*) | expr_tup(_) | expr_unary(_, box(_), _) | expr_unary(_, uniq(_), _) | @@ -379,7 +379,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } } -pub fn handle_body(cx: Context, body: &blk) { +pub fn handle_body(cx: &Context, body: &blk) { let v = visit::mk_vt(@visit::Visitor { visit_expr: |e, (cx, v)| { visit::visit_expr(e, (cx, v)); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 242c617a0e87..d34befddad5f 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3017,7 +3017,7 @@ pub fn block_ty(cx: ctxt, b: &ast::blk) -> t { // Returns the type of a pattern as a monotype. Like @expr_ty, this function // doesn't provide type parameter substitutions. -pub fn pat_ty(cx: ctxt, pat: @ast::pat) -> t { +pub fn pat_ty(cx: ctxt, pat: &ast::pat) -> t { return node_id_to_type(cx, pat.id); } @@ -3033,11 +3033,11 @@ pub fn pat_ty(cx: ctxt, pat: @ast::pat) -> t { // ask for the type of "id" in "id(3)", it will return "fn(&int) -> int" // instead of "fn(t) -> T with T = int". If this isn't what you want, see // expr_ty_params_and_ty() below. -pub fn expr_ty(cx: ctxt, expr: @ast::expr) -> t { +pub fn expr_ty(cx: ctxt, expr: &ast::expr) -> t { return node_id_to_type(cx, expr.id); } -pub fn expr_ty_adjusted(cx: ctxt, expr: @ast::expr) -> t { +pub fn expr_ty_adjusted(cx: ctxt, expr: &ast::expr) -> t { /*! * * Returns the type of `expr`, considering any `AutoAdjustment` @@ -3191,7 +3191,7 @@ pub struct ParamsTy { } pub fn expr_ty_params_and_ty(cx: ctxt, - expr: @ast::expr) + expr: &ast::expr) -> ParamsTy { ParamsTy { params: node_id_to_type_params(cx, expr.id), @@ -3199,7 +3199,7 @@ pub fn expr_ty_params_and_ty(cx: ctxt, } } -pub fn expr_has_ty_params(cx: ctxt, expr: @ast::expr) -> bool { +pub fn expr_has_ty_params(cx: ctxt, expr: &ast::expr) -> bool { return node_id_has_type_params(cx, expr.id); } @@ -3235,7 +3235,7 @@ pub fn method_call_type_param_defs( } } -pub fn resolve_expr(tcx: ctxt, expr: @ast::expr) -> ast::def { +pub fn resolve_expr(tcx: ctxt, expr: &ast::expr) -> ast::def { match tcx.def_map.find(&expr.id) { Some(&def) => def, None => { @@ -3247,7 +3247,7 @@ pub fn resolve_expr(tcx: ctxt, expr: @ast::expr) -> ast::def { pub fn expr_is_lval(tcx: ctxt, method_map: typeck::method_map, - e: @ast::expr) -> bool { + e: &ast::expr) -> bool { match expr_kind(tcx, method_map, e) { LvalueExpr => true, RvalueDpsExpr | RvalueDatumExpr | RvalueStmtExpr => false @@ -3268,7 +3268,7 @@ pub enum ExprKind { pub fn expr_kind(tcx: ctxt, method_map: typeck::method_map, - expr: @ast::expr) -> ExprKind { + expr: &ast::expr) -> ExprKind { if method_map.contains_key(&expr.id) { // Overloaded operations are generally calls, and hence they are // generated via DPS. However, assign_op (e.g., `x += y`) is an @@ -3388,7 +3388,7 @@ pub fn expr_kind(tcx: ctxt, } } -pub fn stmt_node_id(s: @ast::stmt) -> ast::node_id { +pub fn stmt_node_id(s: &ast::stmt) -> ast::node_id { match s.node { ast::stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) => { return id; @@ -4374,7 +4374,7 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { } // Returns the repeat count for a repeating vector expression. -pub fn eval_repeat_count(tcx: ctxt, count_expr: @ast::expr) -> uint { +pub fn eval_repeat_count(tcx: ctxt, count_expr: &ast::expr) -> uint { match const_eval::eval_const_expr_partial(tcx, count_expr) { Ok(ref const_val) => match *const_val { const_eval::const_int(count) => if count < 0 { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 997061a61ba6..b7242e64f230 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -248,7 +248,7 @@ pub static NO_TPS: uint = 2; // internal notion of a type. `getter` is a function that returns the type // corresponding to a definition ID: pub fn ast_ty_to_ty( - this: &AC, rscope: &RS, ast_ty: @ast::Ty) -> ty::t { + this: &AC, rscope: &RS, ast_ty: &ast::Ty) -> ty::t { fn ast_mt_to_mt( this: &AC, rscope: &RS, mt: &ast::mt) -> ty::mt { diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 338342f9307d..777b11186c6f 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -329,11 +329,9 @@ impl<'self> LookupContext<'self> { let opt_applicable_traits = trait_map.find(&self.expr.id); for opt_applicable_traits.iter().advance |applicable_traits| { for applicable_traits.iter().advance |trait_did| { - let coherence_info = self.fcx.ccx.coherence_info; - // Look for explicit implementations. let opt_impl_infos = - coherence_info.extension_methods.find(trait_did); + self.fcx.ccx.coherence_info.extension_methods.find(trait_did); for opt_impl_infos.iter().advance |impl_infos| { for impl_infos.iter().advance |impl_info| { self.push_candidates_from_impl( diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a38a2dced93b..97e0cd4baf84 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -284,7 +284,7 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, } } -pub fn check_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { +pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { let visit = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_item: |a| check_item(ccx, a), .. *visit::default_simple_visitor() diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index bd99a8e150b7..6da9895534b0 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -197,7 +197,7 @@ pub struct CoherenceChecker { } impl CoherenceChecker { - pub fn check_coherence(self, crate: @crate) { + pub fn check_coherence(self, crate: &crate) { // Check implementations and traits. This populates the tables // containing the inherent methods and extension methods. It also // builds up the trait inheritance table. @@ -455,7 +455,7 @@ impl CoherenceChecker { } pub fn check_implementation_coherence(&self) { - let coherence_info = self.crate_context.coherence_info; + let coherence_info = &self.crate_context.coherence_info; for coherence_info.extension_methods.each_key |&trait_id| { self.check_implementation_coherence_of(trait_id); } @@ -514,7 +514,7 @@ impl CoherenceChecker { } pub fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) { - let coherence_info = self.crate_context.coherence_info; + let coherence_info = &self.crate_context.coherence_info; let extension_methods = &*coherence_info.extension_methods; match extension_methods.find(&trait_def_id) { @@ -631,7 +631,7 @@ impl CoherenceChecker { } // Privileged scope checking - pub fn check_privileged_scopes(self, crate: @crate) { + pub fn check_privileged_scopes(self, crate: &crate) { visit_crate(crate, ((), mk_vt(@Visitor { visit_item: |item, (_context, visitor)| { match item.node { @@ -978,7 +978,7 @@ impl CoherenceChecker { // pub fn populate_destructor_table(&self) { - let coherence_info = self.crate_context.coherence_info; + let coherence_info = &self.crate_context.coherence_info; let tcx = self.crate_context.tcx; let drop_trait = tcx.lang_items.drop_trait(); let impls_opt = coherence_info.extension_methods.find(&drop_trait); @@ -1102,7 +1102,7 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt, ) } -pub fn check_coherence(crate_context: @mut CrateCtxt, crate: @crate) { - let coherence_checker = @CoherenceChecker(crate_context); +pub fn check_coherence(crate_context: @mut CrateCtxt, crate: &crate) { + let coherence_checker = CoherenceChecker(crate_context); coherence_checker.check_coherence(crate); } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 7812a0ed0eba..0e118adb8f42 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -61,8 +61,8 @@ use syntax::visit; use syntax::opt_vec::OptVec; use syntax::opt_vec; -pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { - fn collect_intrinsic_type(ccx: @mut CrateCtxt, +pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { + fn collect_intrinsic_type(ccx: &CrateCtxt, lang_item: ast::def_id) { let ty::ty_param_bounds_and_ty { ty: ty, _ } = ccx.get_item_ty(lang_item); @@ -83,7 +83,7 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { impl CrateCtxt { fn to_ty( - &self, rs: &RS, ast_ty: @ast::Ty) -> ty::t + &self, rs: &RS, ast_ty: &ast::Ty) -> ty::t { ast_ty_to_ty(self, rs, ast_ty) } @@ -632,7 +632,7 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, generics: &ast::Generics, rp: Option, selfty: ty::t, - a_trait_ty: @ast::trait_ref, + a_trait_ty: &ast::trait_ref, impl_ms: &[ConvertedMethod]) { let tcx = ccx.tcx; @@ -670,7 +670,7 @@ pub fn check_methods_against_trait(ccx: &CrateCtxt, pub fn convert_field(ccx: &CrateCtxt, rp: Option, type_param_defs: @~[ty::TypeParameterDef], - v: @ast::struct_field, + v: &ast::struct_field, generics: &ast::Generics) { let region_parameterization = RegionParameterization::from_variance_and_generics(rp, generics); @@ -736,7 +736,7 @@ pub fn convert_methods(ccx: &CrateCtxt, }); fn ty_of_method(ccx: &CrateCtxt, - m: @ast::method, + m: &ast::method, rp: Option, untransformed_rcvr_ty: ty::t, rcvr_generics: &ast::Generics, @@ -785,7 +785,7 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, } } -pub fn convert(ccx: &CrateCtxt, it: @ast::item) { +pub fn convert(ccx: &CrateCtxt, it: &ast::item) { let tcx = ccx.tcx; let rp = tcx.region_paramd_items.find(&it.id).map_consume(|x| *x); debug!("convert: item %s with id %d rp %?", @@ -875,7 +875,7 @@ pub fn convert(ccx: &CrateCtxt, it: @ast::item) { pub fn convert_struct(ccx: &CrateCtxt, rp: Option, - struct_def: @ast::struct_def, + struct_def: &ast::struct_def, generics: &ast::Generics, tpt: ty::ty_param_bounds_and_ty, id: ast::node_id) { @@ -914,7 +914,7 @@ pub fn convert_struct(ccx: &CrateCtxt, } } -pub fn convert_foreign(ccx: &CrateCtxt, i: @ast::foreign_item) { +pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::foreign_item) { // As above, this call populates the type table with the converted // type of the foreign item. We simply write it into the node type // table. @@ -937,7 +937,7 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: @ast::foreign_item) { } pub fn instantiate_trait_ref(ccx: &CrateCtxt, - ast_trait_ref: @ast::trait_ref, + ast_trait_ref: &ast::trait_ref, rp: Option, generics: &ast::Generics, self_ty: ty::t) -> @ty::TraitRef @@ -983,7 +983,7 @@ fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::def_id) -> @ty::TraitDef { } } -pub fn trait_def_of_item(ccx: &CrateCtxt, it: @ast::item) -> @ty::TraitDef { +pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::item) -> @ty::TraitDef { let def_id = local_def(it.id); let tcx = ccx.tcx; match tcx.trait_defs.find(&def_id) { @@ -1011,7 +1011,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: @ast::item) -> @ty::TraitDef { } } -pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item) +pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::item) -> ty::ty_param_bounds_and_ty { let def_id = local_def(it.id); let tcx = ccx.tcx; @@ -1103,7 +1103,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item) } pub fn ty_of_foreign_item(ccx: &CrateCtxt, - it: @ast::foreign_item, + it: &ast::foreign_item, abis: AbiSet) -> ty::ty_param_bounds_and_ty { match it.node { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 99fa745fa8b0..d834998d4ee2 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -182,7 +182,7 @@ pub struct CrateCtxt { trait_map: resolve::TraitMap, method_map: method_map, vtable_map: vtable_map, - coherence_info: @coherence::CoherenceInfo, + coherence_info: coherence::CoherenceInfo, tcx: ty::ctxt } @@ -220,7 +220,7 @@ pub fn lookup_def_tcx(tcx: ty::ctxt, sp: span, id: ast::node_id) -> ast::def { } } -pub fn lookup_def_ccx(ccx: @mut CrateCtxt, sp: span, id: ast::node_id) +pub fn lookup_def_ccx(ccx: &CrateCtxt, sp: span, id: ast::node_id) -> ast::def { lookup_def_tcx(ccx.tcx, sp, id) } @@ -276,11 +276,11 @@ trait get_and_find_region { } impl get_and_find_region for isr_alist { - fn get(&self, br: ty::bound_region) -> ty::Region { + pub fn get(&self, br: ty::bound_region) -> ty::Region { self.find(br).get() } - fn find(&self, br: ty::bound_region) -> Option { + pub fn find(&self, br: ty::bound_region) -> Option { for list::each(*self) |isr| { let (isr_br, isr_r) = *isr; if isr_br == br { return Some(isr_r); } @@ -289,7 +289,7 @@ impl get_and_find_region for isr_alist { } } -fn check_main_fn_ty(ccx: @mut CrateCtxt, +fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::node_id, main_span: span) { let tcx = ccx.tcx; @@ -330,7 +330,7 @@ fn check_main_fn_ty(ccx: @mut CrateCtxt, } } -fn check_start_fn_ty(ccx: @mut CrateCtxt, +fn check_start_fn_ty(ccx: &CrateCtxt, start_id: ast::node_id, start_span: span) { let tcx = ccx.tcx; @@ -379,7 +379,7 @@ fn check_start_fn_ty(ccx: @mut CrateCtxt, } } -fn check_for_entry_fn(ccx: @mut CrateCtxt) { +fn check_for_entry_fn(ccx: &CrateCtxt) { let tcx = ccx.tcx; if !*tcx.sess.building_library { match *tcx.sess.entry_fn { @@ -395,14 +395,14 @@ fn check_for_entry_fn(ccx: @mut CrateCtxt) { pub fn check_crate(tcx: ty::ctxt, trait_map: resolve::TraitMap, - crate: @ast::crate) + crate: &ast::crate) -> (method_map, vtable_map) { let time_passes = tcx.sess.time_passes(); let ccx = @mut CrateCtxt { trait_map: trait_map, method_map: @mut HashMap::new(), vtable_map: @mut HashMap::new(), - coherence_info: @coherence::CoherenceInfo(), + coherence_info: coherence::CoherenceInfo(), tcx: tcx }; diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 6d39495002a4..aba7a01f869c 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -331,7 +331,7 @@ pub fn find_and_install_dependencies(ctxt: &Ctx, debug!("In find_and_install_dependencies..."); let my_workspace = copy *workspace; let my_ctxt = copy *ctxt; - for c.each_view_item() |vi: @ast::view_item| { + for c.each_view_item() |vi: &ast::view_item| { debug!("A view item!"); match vi.node { // ignore metadata, I guess diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index d381f934d9ad..3abbe3970540 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -124,7 +124,7 @@ pub fn mk_ast_map_visitor() -> vt { }); } -pub fn map_crate(diag: @span_handler, c: @crate) -> map { +pub fn map_crate(diag: @span_handler, c: &crate) -> map { let cx = @mut Ctx { map: @mut HashMap::new(), path: ~[], diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index fd8fbc72e57f..9ba7cb3c818e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -565,11 +565,11 @@ pub fn walk_pat(pat: @pat, it: &fn(@pat) -> bool) -> bool { } pub trait EachViewItem { - pub fn each_view_item(&self, f: @fn(@ast::view_item) -> bool) -> bool; + pub fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool; } impl EachViewItem for ast::crate { - fn each_view_item(&self, f: @fn(@ast::view_item) -> bool) -> bool { + fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool { let broke = @mut false; let vtor: visit::vt<()> = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_view_item: |vi| { *broke = f(vi); }, ..*visit::default_simple_visitor() @@ -579,7 +579,7 @@ impl EachViewItem for ast::crate { } } -pub fn view_path_id(p: @view_path) -> node_id { +pub fn view_path_id(p: &view_path) -> node_id { match p.node { view_path_simple(_, _, id) | view_path_glob(_, id) | diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index ccfb34a3a2f5..70ac4d3d4c18 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::prelude::*; - use ast::{meta_item, item, expr}; use codemap::span; use ext::base::ExtCtxt; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7fc784320ac1..15f915ba4d8d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -644,7 +644,7 @@ pub fn core_macros() -> @str { } pub fn expand_crate(parse_sess: @mut parse::ParseSess, - cfg: ast::crate_cfg, c: @crate) -> @crate { + cfg: ast::crate_cfg, c: &crate) -> @crate { // adding *another* layer of indirection here so that the block // visitor can swap out one exts table for another for the duration // of the block. The cleaner alternative would be to thread the @@ -695,7 +695,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess, // as it registers all the core macros as expanders. f.fold_item(cm); - @f.fold_crate(&*c) + @f.fold_crate(c) } // given a function from idents to idents, produce diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f0a993dbb942..9fcffc110130 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -39,7 +39,7 @@ pub enum fn_kind<'self> { // fn foo(&self) fk_method(ident, &'self Generics, &'self method), - // fn@(x, y) { ... } + // @fn(x, y) { ... } fk_anon(ast::Sigil), // |x, y| ... @@ -129,9 +129,9 @@ pub fn visit_mod(m: &_mod, _sp: span, _id: node_id, (e, v): (E, vt)) for m.items.iter().advance |i| { (v.visit_item)(*i, (copy e, v)); } } -pub fn visit_view_item(_vi: @view_item, (_e, _v): (E, vt)) { } +pub fn visit_view_item(_vi: &view_item, (_e, _v): (E, vt)) { } -pub fn visit_local(loc: @local, (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)); match loc.node.init { @@ -140,11 +140,11 @@ pub fn visit_local(loc: @local, (e, v): (E, vt)) { } } -fn visit_trait_ref(tref: @ast::trait_ref, (e, v): (E, vt)) { +fn visit_trait_ref(tref: &ast::trait_ref, (e, v): (E, vt)) { visit_path(tref.path, (e, v)); } -pub fn visit_item(i: @item, (e, v): (E, vt)) { +pub fn visit_item(i: &item, (e, v): (E, vt)) { match i.node { item_static(t, _, ex) => { (v.visit_ty)(t, (copy e, v)); @@ -230,9 +230,9 @@ pub fn visit_enum_def(enum_definition: &ast::enum_def, } } -pub fn skip_ty(_t: @Ty, (_e,_v): (E, vt)) {} +pub fn skip_ty(_t: &Ty, (_e,_v): (E, vt)) {} -pub fn visit_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) => { @@ -268,11 +268,11 @@ pub fn visit_ty(t: @Ty, (e, v): (E, vt)) { } } -pub fn visit_path(p: @Path, (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)); } } -pub fn visit_pat(p: @pat, (e, v): (E, vt)) { +pub fn visit_pat(p: &pat, (e, v): (E, vt)) { match p.node { pat_enum(path, ref children) => { visit_path(path, (copy e, v)); @@ -322,7 +322,7 @@ pub fn visit_pat(p: @pat, (e, v): (E, vt)) { } } -pub fn visit_foreign_item(ni: @foreign_item, (e, v): (E, vt)) { +pub fn visit_foreign_item(ni: &foreign_item, (e, v): (E, vt)) { match ni.node { foreign_item_fn(ref fd, _, ref generics) => { visit_fn_decl(fd, (copy e, v)); @@ -410,11 +410,11 @@ pub fn visit_struct_def( } } -pub fn visit_struct_field(sf: @struct_field, (e, v): (E, vt)) { +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)) { +pub fn visit_struct_method(m: &method, (e, v): (E, vt)) { visit_method_helper(m, (e, v)); } @@ -428,7 +428,7 @@ pub fn visit_block(b: &blk, (e, v): (E, vt)) { visit_expr_opt(b.node.expr, (e, v)); } -pub fn visit_stmt(s: @stmt, (e, v): (E, vt)) { +pub fn visit_stmt(s: &stmt, (e, v): (E, vt)) { match s.node { stmt_decl(d, _) => (v.visit_decl)(d, (e, v)), stmt_expr(ex, _) => (v.visit_expr)(ex, (e, v)), @@ -437,7 +437,7 @@ pub fn visit_stmt(s: @stmt, (e, v): (E, vt)) { } } -pub fn visit_decl(d: @decl, (e, v): (E, vt)) { +pub fn visit_decl(d: &decl, (e, v): (E, vt)) { match d.node { decl_local(ref loc) => (v.visit_local)(*loc, (e, v)), decl_item(it) => (v.visit_item)(it, (e, v)) From 1cb0a567d1209855b476689b0e449a832035f05b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 27 Jun 2013 22:59:52 +1000 Subject: [PATCH 184/336] Convert vec::{pop, shift, unshift, insert, remove, swap_remove} to methods. --- src/libextra/treemap.rs | 3 +- src/librustc/middle/resolve.rs | 2 +- src/libstd/vec.rs | 234 ++++++++++++++------------------- 3 files changed, 103 insertions(+), 136 deletions(-) diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 33ec4ae94ba5..4622b8c72848 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -695,7 +695,6 @@ mod test_treemap { use core::rand::RngUtil; use core::rand; - use core::vec; #[test] fn find_empty() { @@ -848,7 +847,7 @@ mod test_treemap { for 30.times { let r = rng.gen_uint_range(0, ctrl.len()); - let (key, _) = vec::remove(&mut ctrl, r); + let (key, _) = ctrl.remove(r); assert!(map.remove(&key)); check_structure(&map); check_equal(ctrl, &map); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index e06fd8f97179..7cd64e863d2b 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4882,7 +4882,7 @@ impl Resolver { values[smallest] <= max_distance && name != maybes[smallest] { - Some(vec::swap_remove(&mut maybes, smallest)) + Some(maybes.swap_remove(smallest)) } else { None diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 3dae32d717de..bc933e70b373 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -377,96 +377,6 @@ pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { (lefts, rights) } -// Mutators - -/// Removes the first element from a vector and return it -pub fn shift(v: &mut ~[T]) -> T { - unsafe { - assert!(!v.is_empty()); - - if v.len() == 1 { return v.pop() } - - if v.len() == 2 { - let last = v.pop(); - let first = v.pop(); - v.push(last); - return first; - } - - let ln = v.len(); - let next_ln = v.len() - 1; - - // Save the last element. We're going to overwrite its position - let work_elt = v.pop(); - // We still should have room to work where what last element was - assert!(capacity(v) >= ln); - // Pretend like we have the original length so we can use - // the vector copy_memory to overwrite the hole we just made - raw::set_len(&mut *v, ln); - - // Memcopy the head element (the one we want) to the location we just - // popped. For the moment it unsafely exists at both the head and last - // positions - { - let first_slice = v.slice(0, 1); - let last_slice = v.slice(next_ln, ln); - raw::copy_memory(transmute(last_slice), first_slice, 1); - } - - // Memcopy everything to the left one element - { - let init_slice = v.slice(0, next_ln); - let tail_slice = v.slice(1, ln); - raw::copy_memory(transmute(init_slice), - tail_slice, - next_ln); - } - - // Set the new length. Now the vector is back to normal - raw::set_len(&mut *v, next_ln); - - // Swap out the element we want from the end - let vp = raw::to_mut_ptr(*v); - let vp = ptr::mut_offset(vp, next_ln - 1); - - ptr::replace_ptr(vp, work_elt) - } -} - -/// Prepend an element to the vector -pub fn unshift(v: &mut ~[T], x: T) { - let vv = util::replace(v, ~[x]); - v.push_all_move(vv); -} - -/// Insert an element at position i within v, shifting all -/// elements after position i one position to the right. -pub fn insert(v: &mut ~[T], i: uint, x: T) { - let len = v.len(); - assert!(i <= len); - - v.push(x); - let mut j = len; - while j > i { - swap(*v, j, j - 1); - j -= 1; - } -} - -/// Remove and return the element at position i within v, shifting -/// all elements after position i one position to the left. -pub fn remove(v: &mut ~[T], i: uint) -> T { - let len = v.len(); - assert!(i < len); - - let mut j = i; - while j < len - 1 { - swap(*v, j, j + 1); - j += 1; - } - v.pop() -} - /// Consumes all elements, in a vector, moving them out into the / closure /// provided. The vector is traversed from the start to the end. /// @@ -528,37 +438,6 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { } } -/// Remove the last element from a vector and return it -pub fn pop(v: &mut ~[T]) -> T { - let ln = v.len(); - if ln == 0 { - fail!("sorry, cannot vec::pop an empty vector") - } - let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]); - unsafe { - let val = ptr::replace_ptr(valptr, intrinsics::init()); - raw::set_len(v, ln - 1u); - val - } -} - -/** - * Remove an element from anywhere in the vector and return it, replacing it - * with the last element. This does not preserve ordering, but is O(1). - * - * Fails if index >= length. - */ -pub fn swap_remove(v: &mut ~[T], index: uint) -> T { - let ln = v.len(); - if index >= ln { - fail!("vec::swap_remove - index %u >= length %u", index, ln); - } - if index < ln - 1 { - swap(*v, index, ln - 1); - } - v.pop() -} - /// Append an element to a vector #[inline] pub fn push(v: &mut ~[T], initval: T) { @@ -1847,34 +1726,123 @@ impl OwnedVector for ~[T] { push_all_move(self, rhs); } - #[inline] + /// Remove the last element from a vector and return it fn pop(&mut self) -> T { - pop(self) + 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 + } } - #[inline] + /// Removes the first element from a vector and return it fn shift(&mut self) -> T { - shift(self) + unsafe { + assert!(!self.is_empty()); + + 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 + let work_elt = self.pop(); + // We still should have room to work where what last element was + assert!(capacity(self) >= ln); + // Pretend like we have the original length so we can use + // the vector copy_memory to overwrite the hole we just made + raw::set_len(self, ln); + + // Memcopy the head element (the one we want) to the location we just + // popped. For the moment it unsafely exists at both the head and last + // positions + { + let first_slice = self.slice(0, 1); + let last_slice = self.slice(next_ln, ln); + raw::copy_memory(transmute(last_slice), first_slice, 1); + } + + // Memcopy everything to the left one element + { + let init_slice = self.slice(0, next_ln); + let tail_slice = self.slice(1, ln); + raw::copy_memory(transmute(init_slice), + tail_slice, + next_ln); + } + + // Set the new length. Now the vector is back to normal + raw::set_len(self, next_ln); + + // Swap out the element we want from the end + let vp = raw::to_mut_ptr(*self); + let vp = ptr::mut_offset(vp, next_ln - 1); + + ptr::replace_ptr(vp, work_elt) + } } - #[inline] + /// Prepend an element to the vector fn unshift(&mut self, x: T) { - unshift(self, x) + let v = util::replace(self, ~[x]); + self.push_all_move(v); } - #[inline] + /// Insert an element at position i within v, shifting all + /// elements after position i one position to the right. fn insert(&mut self, i: uint, x:T) { - insert(self, i, x) + let len = self.len(); + assert!(i <= len); + + self.push(x); + let mut j = len; + while j > i { + swap(*self, j, j - 1); + j -= 1; + } } - #[inline] + /// Remove and return the element at position i within v, shifting + /// all elements after position i one position to the left. fn remove(&mut self, i: uint) -> T { - remove(self, i) + let len = self.len(); + assert!(i < len); + + let mut j = i; + while j < len - 1 { + swap(*self, j, j + 1); + j += 1; + } + self.pop() } - #[inline] + /** + * Remove an element from anywhere in the vector and return it, replacing it + * with the last element. This does not preserve ordering, but is O(1). + * + * Fails if index >= length. + */ fn swap_remove(&mut self, index: uint) -> T { - swap_remove(self, index) + let ln = self.len(); + if index >= ln { + fail!("vec::swap_remove - index %u >= length %u", index, ln); + } + if index < ln - 1 { + swap(*self, index, ln - 1); + } + self.pop() } #[inline] From 29b0649a6af8c4821f0d69c544569a9529a68431 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 27 Jun 2013 23:53:37 +1000 Subject: [PATCH 185/336] Convert vec::{push, push_all, push_all_move} to methods. --- doc/rust.md | 2 +- src/librustc/metadata/decoder.rs | 3 +- src/librustc/middle/resolve.rs | 4 +- src/librustc/middle/typeck/coherence.rs | 2 +- src/libstd/os.rs | 5 +- src/libstd/vec.rs | 158 +++++++++++------------- 6 files changed, 81 insertions(+), 93 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 0939664fc79f..8f742d0d2100 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2620,7 +2620,7 @@ assert!(b != "world"); The vector type constructor represents a homogeneous array of values of a given type. A vector has a fixed size. -(Operations like `vec::push` operate solely on owned vectors.) +(Operations like `vec.push` operate solely on owned vectors.) A vector type can be annotated with a _definite_ size, written with a trailing asterisk and integer literal, such as `[int * 10]`. Such a definite-sized vector type is a first-class type, since its size is known statically. diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 39cce41b3869..d7c20ed2d50b 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -763,8 +763,7 @@ pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd, if item_method_sort(mth) != 'p' { loop; } - vec::push(&mut result, - @get_method(intr, cdata, did.node, tcx)); + result.push(@get_method(intr, cdata, did.node, tcx)); } return result; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 7cd64e863d2b..b839e22f9060 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4862,8 +4862,8 @@ impl Resolver { while j != 0 { j -= 1; for this.value_ribs[j].bindings.each_key |&k| { - vec::push(&mut maybes, this.session.str_of(k)); - vec::push(&mut values, uint::max_value); + maybes.push(this.session.str_of(k)); + values.push(uint::max_value); } } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index bd99a8e150b7..5d0fbfcb1bae 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -788,7 +788,7 @@ impl CoherenceChecker { `%s` to impl", provided_method.method_info .ident.repr(self.crate_context.tcx)); - vec::push(all_methods, provided_method.method_info); + all_methods.push(provided_method.method_info); } } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 5534c5befc2b..165996f935e4 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1140,7 +1140,7 @@ pub fn set_exit_status(code: int) { unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { let mut args = ~[]; for uint::range(0, argc as uint) |i| { - vec::push(&mut args, str::raw::from_c_str(*argv.offset(i))); + args.push(str::raw::from_c_str(*argv.offset(i))); } args } @@ -1186,8 +1186,7 @@ pub fn real_args() -> ~[~str] { while *ptr.offset(len) != 0 { len += 1; } // Push it onto the list. - vec::push(&mut args, - vec::raw::buf_as_slice(ptr, len, + args.push(vec::raw::buf_as_slice(ptr, len, str::from_utf16)); } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index bc933e70b373..f0c81f9c04bb 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -438,86 +438,6 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { } } -/// Append an element to a vector -#[inline] -pub fn push(v: &mut ~[T], initval: T) { - unsafe { - let repr: **raw::VecRepr = transmute(&mut *v); - let fill = (**repr).unboxed.fill; - if (**repr).unboxed.alloc > fill { - push_fast(v, initval); - } - else { - push_slow(v, initval); - } - } -} - -// This doesn't bother to make sure we have space. -#[inline] // really pretty please -unsafe fn push_fast(v: &mut ~[T], initval: T) { - let repr: **mut raw::VecRepr = transmute(v); - let fill = (**repr).unboxed.fill; - (**repr).unboxed.fill += sys::nonzero_size_of::(); - let p = to_unsafe_ptr(&((**repr).unboxed.data)); - let p = ptr::offset(p, fill) as *mut T; - intrinsics::move_val_init(&mut(*p), initval); -} - -#[inline(never)] -fn push_slow(v: &mut ~[T], initval: T) { - let new_len = v.len() + 1; - reserve_at_least(&mut *v, new_len); - unsafe { push_fast(v, initval) } -} - -/// Iterates over the slice `rhs`, copies each element, and then appends it to -/// the vector provided `v`. The `rhs` vector is traversed in-order. -/// -/// # Example -/// -/// ~~~ {.rust} -/// let mut a = ~[1]; -/// vec::push_all(&mut a, [2, 3, 4]); -/// assert!(a == ~[1, 2, 3, 4]); -/// ~~~ -#[inline] -pub fn push_all(v: &mut ~[T], rhs: &const [T]) { - let new_len = v.len() + rhs.len(); - reserve(&mut *v, new_len); - - for uint::range(0u, rhs.len()) |i| { - push(&mut *v, unsafe { raw::get(rhs, i) }) - } -} - -/// Takes ownership of the vector `rhs`, moving all elements into the specified -/// vector `v`. This does not copy any elements, and it is illegal to use the -/// `rhs` vector after calling this method (because it is moved here). -/// -/// # Example -/// -/// ~~~ {.rust} -/// let mut a = ~[~1]; -/// vec::push_all_move(&mut a, ~[~2, ~3, ~4]); -/// assert!(a == ~[~1, ~2, ~3, ~4]); -/// ~~~ -#[inline] -pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { - let new_len = v.len() + rhs.len(); - reserve(&mut *v, new_len); - unsafe { - do as_mut_buf(rhs) |p, len| { - for uint::range(0, len) |i| { - let x = ptr::replace_ptr(ptr::mut_offset(p, i), - intrinsics::uninit()); - push(&mut *v, x); - } - } - raw::set_len(&mut rhs, 0); - } -} - /// Shorten a vector, dropping excess elements. pub fn truncate(v: &mut ~[T], newlen: uint) { do as_mut_buf(*v) |p, oldlen| { @@ -1699,6 +1619,8 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { fn push(&mut self, t: T); + unsafe fn push_fast(&mut self, t: T); + fn push_all_move(&mut self, rhs: ~[T]); fn pop(&mut self) -> T; fn shift(&mut self) -> T; @@ -1716,14 +1638,67 @@ pub trait OwnedVector { } impl OwnedVector for ~[T] { + /// Append an element to a vector #[inline] fn push(&mut self, t: T) { - push(self, t); + unsafe { + let repr: **raw::VecRepr = transmute(&mut *self); + let fill = (**repr).unboxed.fill; + if (**repr).unboxed.alloc <= fill { + // need more space + reserve_no_inline(self); + } + + self.push_fast(t); + } + + // this peculiar function is because reserve_at_least is very + // large (because of reserve), and will be inlined, which + // makes push too large. + #[inline(never)] + fn reserve_no_inline(v: &mut ~[T]) { + let new_len = v.len() + 1; + reserve_at_least(v, new_len); + } } + // This doesn't bother to make sure we have space. + #[inline] // really pretty please + unsafe fn push_fast(&mut self, t: T) { + let repr: **mut raw::VecRepr = transmute(self); + let fill = (**repr).unboxed.fill; + (**repr).unboxed.fill += sys::nonzero_size_of::(); + let p = to_unsafe_ptr(&((**repr).unboxed.data)); + let p = ptr::offset(p, fill) as *mut T; + intrinsics::move_val_init(&mut(*p), t); + } + + /// Takes ownership of the vector `rhs`, moving all elements into + /// the current vector. This does not copy any elements, and it is + /// illegal to use the `rhs` vector after calling this method + /// (because it is moved here). + /// + /// # Example + /// + /// ~~~ {.rust} + /// let mut a = ~[~1]; + /// a.push_all_move(~[~2, ~3, ~4]); + /// assert!(a == ~[~1, ~2, ~3, ~4]); + /// ~~~ #[inline] - fn push_all_move(&mut self, rhs: ~[T]) { - push_all_move(self, rhs); + fn push_all_move(&mut self, mut rhs: ~[T]) { + let new_len = self.len() + rhs.len(); + reserve(self, new_len); + unsafe { + do as_mut_buf(rhs) |p, len| { + for uint::range(0, len) |i| { + let x = ptr::replace_ptr(ptr::mut_offset(p, i), + intrinsics::uninit()); + self.push(x); + } + } + raw::set_len(&mut rhs, 0); + } } /// Remove the last element from a vector and return it @@ -1898,9 +1873,24 @@ pub trait OwnedCopyableVector { } impl OwnedCopyableVector for ~[T] { + /// Iterates over the slice `rhs`, copies each element, and then appends it to + /// the vector provided `v`. The `rhs` vector is traversed in-order. + /// + /// # Example + /// + /// ~~~ {.rust} + /// let mut a = ~[1]; + /// a.push_all([2, 3, 4]); + /// assert!(a == ~[1, 2, 3, 4]); + /// ~~~ #[inline] fn push_all(&mut self, rhs: &const [T]) { - push_all(self, rhs); + let new_len = self.len() + rhs.len(); + reserve(self, new_len); + + for uint::range(0u, rhs.len()) |i| { + self.push(unsafe { raw::get(rhs, i) }) + } } #[inline] From 4470d14388b1637a1e4862c0650baddf6ed7c430 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 27 Jun 2013 23:58:07 +1000 Subject: [PATCH 186/336] Convert vec::truncate to a method. --- src/libstd/vec.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index f0c81f9c04bb..2cc278612076 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -438,20 +438,6 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { } } -/// Shorten a vector, dropping excess elements. -pub fn truncate(v: &mut ~[T], newlen: uint) { - do as_mut_buf(*v) |p, oldlen| { - assert!(newlen <= oldlen); - unsafe { - // This loop is optimized out for non-drop types. - for uint::range(newlen, oldlen) |i| { - ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); - } - } - } - unsafe { raw::set_len(&mut *v, newlen); } -} - /** * Remove consecutive repeated elements from a vector; if the vector is * sorted, this removes all duplicates. @@ -1820,9 +1806,18 @@ impl OwnedVector for ~[T] { self.pop() } - #[inline] + /// Shorten a vector, dropping excess elements. fn truncate(&mut self, newlen: uint) { - truncate(self, newlen); + do as_mut_buf(*self) |p, oldlen| { + assert!(newlen <= oldlen); + unsafe { + // This loop is optimized out for non-drop types. + for uint::range(newlen, oldlen) |i| { + ptr::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); + } + } + } + unsafe { raw::set_len(self, newlen); } } #[inline] From 206d4f00dc628cf0c7680ae2dc5b3ab6771c32e4 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 28 Jun 2013 00:01:21 +1000 Subject: [PATCH 187/336] Convert vec::retain to a method. --- src/libstd/vec.rs | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 2cc278612076..65c394f032c5 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -687,26 +687,6 @@ pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { result } -/** - * Like `filter()`, but in place. Preserves order of `v`. Linear time. - */ -pub fn retain(v: &mut ~[T], f: &fn(t: &T) -> bool) { - let len = v.len(); - let mut deleted: uint = 0; - - for uint::range(0, len) |i| { - if !f(&v[i]) { - deleted += 1; - } else if deleted > 0 { - swap(*v, i - deleted, i); - } - } - - if deleted > 0 { - v.truncate(len - deleted); - } -} - /// Flattens a vector of vectors of T into a single vector of T. pub fn concat(v: &[~[T]]) -> ~[T] { v.concat_vec() } @@ -1820,9 +1800,25 @@ impl OwnedVector for ~[T] { unsafe { raw::set_len(self, newlen); } } - #[inline] + + /** + * Like `filter()`, but in place. Preserves order of `v`. Linear time. + */ fn retain(&mut self, f: &fn(t: &T) -> bool) { - retain(self, f); + let len = self.len(); + let mut deleted: uint = 0; + + for uint::range(0, len) |i| { + if !f(&self[i]) { + deleted += 1; + } else if deleted > 0 { + swap(*self, i - deleted, i); + } + } + + if deleted > 0 { + self.truncate(len - deleted); + } } #[inline] From ae2f1853491540b9e70be2209b235f6c920706a8 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 28 Jun 2013 00:10:18 +1000 Subject: [PATCH 188/336] Convert vec::{partition, partitioned} to methods. --- src/libextra/test.rs | 2 +- src/libstd/vec.rs | 75 +++++++++++++++++--------------------------- 2 files changed, 29 insertions(+), 48 deletions(-) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index bb03e3ab9bb2..7b68298a8ddd 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -431,7 +431,7 @@ fn run_tests(opts: &TestOpts, callback(TeFiltered(filtered_descs)); let (filtered_tests, filtered_benchs) = - do vec::partition(filtered_tests) |e| { + do filtered_tests.partition |e| { match e.testfn { StaticTestFn(_) | DynTestFn(_) => true, StaticBenchFn(_) | DynBenchFn(_) => false diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 65c394f032c5..4dbc0c4e3e04 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -337,46 +337,6 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { result } -/** - * Partitions a vector into two new vectors: those that satisfies the - * predicate, and those that do not. - */ -pub fn partition(v: ~[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { - let mut lefts = ~[]; - let mut rights = ~[]; - - // FIXME (#4355 maybe): using v.consume here crashes - // do v.consume |_, elt| { - do consume(v) |_, elt| { - if f(&elt) { - lefts.push(elt); - } else { - rights.push(elt); - } - } - - (lefts, rights) -} - -/** - * Partitions a vector into two new vectors: those that satisfies the - * predicate, and those that do not. - */ -pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { - let mut lefts = ~[]; - let mut rights = ~[]; - - for v.iter().advance |elt| { - if f(elt) { - lefts.push(copy *elt); - } else { - rights.push(copy *elt); - } - } - - (lefts, rights) -} - /// Consumes all elements, in a vector, moving them out into the / closure /// provided. The vector is traversed from the start to the end. /// @@ -1572,7 +1532,18 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { */ #[inline] fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { - partitioned(*self, f) + let mut lefts = ~[]; + let mut rights = ~[]; + + for self.iter().advance |elt| { + if f(elt) { + lefts.push(copy *elt); + } else { + rights.push(copy *elt); + } + } + + (lefts, rights) } /// Returns the element at the given index, without doing bounds checking. @@ -1842,7 +1813,18 @@ impl OwnedVector for ~[T] { */ #[inline] fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { - partition(self, f) + let mut lefts = ~[]; + let mut rights = ~[]; + + do self.consume |_, elt| { + if f(&elt) { + lefts.push(elt); + } else { + rights.push(elt); + } + } + + (lefts, rights) } #[inline] @@ -3228,11 +3210,10 @@ mod tests { #[test] fn test_partition() { - // FIXME (#4355 maybe): using v.partition here crashes - assert_eq!(partition(~[], |x: &int| *x < 3), (~[], ~[])); - assert_eq!(partition(~[1, 2, 3], |x: &int| *x < 4), (~[1, 2, 3], ~[])); - assert_eq!(partition(~[1, 2, 3], |x: &int| *x < 2), (~[1], ~[2, 3])); - assert_eq!(partition(~[1, 2, 3], |x: &int| *x < 0), (~[], ~[1, 2, 3])); + assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[])); + assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[])); + assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3])); + assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3])); } #[test] From 32d655916f1c3365a521616b57d9d0efc2bae643 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 28 Jun 2013 00:40:47 +1000 Subject: [PATCH 189/336] Convert vec::{reserve, reserve_at_least, capacity} to methods. --- src/libextra/deque.rs | 13 +- src/libextra/priority_queue.rs | 6 +- src/libstd/io.rs | 2 +- src/libstd/rt/io/extensions.rs | 2 +- src/libstd/str.rs | 6 +- src/libstd/vec.rs | 142 +++++++++--------- src/test/bench/shootout-reverse-complement.rs | 7 +- 7 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index e6a7dd648373..c70c87b6ea13 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -137,7 +137,7 @@ impl Deque { /// /// * n - The number of elements to reserve space for pub fn reserve(&mut self, n: uint) { - vec::reserve(&mut self.elts, n); + self.elts.reserve(n); } /// Reserve capacity for at least `n` elements in the given deque, @@ -151,7 +151,7 @@ impl Deque { /// /// * n - The number of elements to reserve space for pub fn reserve_at_least(&mut self, n: uint) { - vec::reserve_at_least(&mut self.elts, n); + self.elts.reserve_at_least(n); } /// Front-to-back iterator. @@ -256,7 +256,6 @@ mod tests { use super::*; use core::cmp::Eq; use core::kinds::Copy; - use core::vec::capacity; use core; #[test] @@ -442,11 +441,11 @@ mod tests { let mut d = Deque::new(); d.add_back(0u64); d.reserve(50); - assert_eq!(capacity(&mut d.elts), 50); + assert_eq!(d.elts.capacity(), 50); let mut d = Deque::new(); d.add_back(0u32); d.reserve(50); - assert_eq!(capacity(&mut d.elts), 50); + assert_eq!(d.elts.capacity(), 50); } #[test] @@ -454,11 +453,11 @@ mod tests { let mut d = Deque::new(); d.add_back(0u64); d.reserve_at_least(50); - assert_eq!(capacity(&mut d.elts), 64); + assert_eq!(d.elts.capacity(), 64); let mut d = Deque::new(); d.add_back(0u32); d.reserve_at_least(50); - assert_eq!(capacity(&mut d.elts), 64); + assert_eq!(d.elts.capacity(), 64); } #[test] diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index af891edf9e5f..fbb4be0febb3 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -52,12 +52,12 @@ impl PriorityQueue { } /// Returns the number of elements the queue can hold without reallocating - pub fn capacity(&self) -> uint { vec::capacity(&self.data) } + pub fn capacity(&self) -> uint { self.data.capacity() } - pub fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) } + pub fn reserve(&mut self, n: uint) { self.data.reserve(n) } pub fn reserve_at_least(&mut self, n: uint) { - vec::reserve_at_least(&mut self.data, n) + self.data.reserve_at_least(n) } /// Pop the greatest item from the queue - fails if empty diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 4d9c08f25da7..36920bd24887 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1658,7 +1658,7 @@ impl Writer for BytesWriter { let bytes = &mut *self.bytes; let count = uint::max(bytes.len(), *self.pos + v_len); - vec::reserve(bytes, count); + bytes.reserve(count); unsafe { vec::raw::set_len(bytes, count); diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index 5320bd0f42ee..1f82a9cd9633 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -292,7 +292,7 @@ impl ReaderUtil for T { let start_len = buf.len(); let mut total_read = 0; - vec::reserve_at_least(buf, start_len + len); + buf.reserve_at_least(start_len + len); vec::raw::set_len(buf, start_len + len); do (|| { diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 16c287c1da82..58cdc6631f0b 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -2081,7 +2081,7 @@ impl OwnedStr for ~str { pub fn reserve(&mut self, n: uint) { unsafe { let v: *mut ~[u8] = cast::transmute(self); - vec::reserve(&mut *v, n + 1); + (*v).reserve(n + 1); } } @@ -2115,8 +2115,8 @@ impl OwnedStr for ~str { * reallocating */ fn capacity(&self) -> uint { - let buf: &const ~[u8] = unsafe { cast::transmute(self) }; - let vcap = vec::capacity(buf); + let buf: &~[u8] = unsafe { cast::transmute(self) }; + let vcap = buf.capacity(); assert!(vcap > 0u); vcap - 1u } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 4dbc0c4e3e04..5dfea811c233 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -68,63 +68,6 @@ pub fn same_length(xs: &const [T], ys: &const [U]) -> bool { xs.len() == ys.len() } -/** - * Reserves capacity for exactly `n` elements in the given vector. - * - * If the capacity for `v` is already equal to or greater than the requested - * capacity, then no action is taken. - * - * # Arguments - * - * * v - A vector - * * n - The number of elements to reserve space for - */ -#[inline] -pub fn reserve(v: &mut ~[T], n: uint) { - // Only make the (slow) call into the runtime if we have to - use managed; - if capacity(v) < n { - unsafe { - let ptr: **raw::VecRepr = cast::transmute(v); - let td = get_tydesc::(); - if ((**ptr).box_header.ref_count == - managed::raw::RC_MANAGED_UNIQUE) { - rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); - } else { - rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); - } - } - } -} - -/** - * Reserves capacity for at least `n` elements in the given vector. - * - * This function will over-allocate in order to amortize the allocation costs - * in scenarios where the caller may need to repeatedly reserve additional - * space. - * - * If the capacity for `v` is already equal to or greater than the requested - * capacity, then no action is taken. - * - * # Arguments - * - * * v - A vector - * * n - The number of elements to reserve space for - */ -pub fn reserve_at_least(v: &mut ~[T], n: uint) { - reserve(v, uint::next_power_of_two(n)); -} - -/// Returns the number of elements the vector can hold without reallocating -#[inline] -pub fn capacity(v: &const ~[T]) -> uint { - unsafe { - let repr: **raw::VecRepr = transmute(v); - (**repr).unboxed.alloc / sys::nonzero_size_of::() - } -} - /** * Creates and initializes an owned vector. * @@ -179,7 +122,7 @@ pub fn to_owned(t: &[T]) -> ~[T] { /// Creates a new vector with a capacity of `capacity` pub fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; - reserve(&mut vec, capacity); + vec.reserve(capacity); vec } @@ -466,7 +409,7 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { */ pub fn grow(v: &mut ~[T], n: uint, initval: &T) { let new_len = v.len() + n; - reserve_at_least(&mut *v, new_len); + v.reserve_at_least(new_len); let mut i: uint = 0u; while i < n { @@ -490,7 +433,7 @@ pub fn grow(v: &mut ~[T], n: uint, initval: &T) { */ pub fn grow_fn(v: &mut ~[T], n: uint, op: &fn(uint) -> T) { let new_len = v.len() + n; - reserve_at_least(&mut *v, new_len); + v.reserve_at_least(new_len); let mut i: uint = 0u; while i < n { v.push(op(i)); @@ -1298,13 +1241,11 @@ impl<'self,T:Copy> CopyableVector for &'self [T] { /// Returns a copy of `v`. #[inline] fn to_owned(&self) -> ~[T] { - let mut result = ~[]; - reserve(&mut result, self.len()); + let mut result = with_capacity(self.len()); for self.iter().advance |e| { result.push(copy *e); } result - } } @@ -1555,6 +1496,10 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { #[allow(missing_doc)] pub trait OwnedVector { + fn reserve(&mut self, n: uint); + fn reserve_at_least(&mut self, n: uint); + fn capacity(&self) -> uint; + fn push(&mut self, t: T); unsafe fn push_fast(&mut self, t: T); @@ -1575,6 +1520,61 @@ pub trait OwnedVector { } impl OwnedVector for ~[T] { + /** + * Reserves capacity for exactly `n` elements in the given vector. + * + * If the capacity for `self` is already equal to or greater than the requested + * capacity, then no action is taken. + * + * # Arguments + * + * * n - The number of elements to reserve space for + */ + #[inline] + fn reserve(&mut self, n: uint) { + // Only make the (slow) call into the runtime if we have to + use managed; + if self.capacity() < n { + unsafe { + let ptr: **raw::VecRepr = cast::transmute(self); + let td = get_tydesc::(); + if ((**ptr).box_header.ref_count == + managed::raw::RC_MANAGED_UNIQUE) { + rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); + } else { + rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); + } + } + } + } + + /** + * Reserves capacity for at least `n` elements in the given vector. + * + * This function will over-allocate in order to amortize the allocation costs + * in scenarios where the caller may need to repeatedly reserve additional + * space. + * + * If the capacity for `self` is already equal to or greater than the requested + * capacity, then no action is taken. + * + * # Arguments + * + * * n - The number of elements to reserve space for + */ + fn reserve_at_least(&mut self, n: uint) { + self.reserve(uint::next_power_of_two(n)); + } + + /// Returns the number of elements the vector can hold without reallocating. + #[inline] + fn capacity(&self) -> uint { + unsafe { + let repr: **raw::VecRepr = transmute(self); + (**repr).unboxed.alloc / sys::nonzero_size_of::() + } + } + /// Append an element to a vector #[inline] fn push(&mut self, t: T) { @@ -1595,7 +1595,7 @@ impl OwnedVector for ~[T] { #[inline(never)] fn reserve_no_inline(v: &mut ~[T]) { let new_len = v.len() + 1; - reserve_at_least(v, new_len); + v.reserve_at_least(new_len); } } @@ -1625,7 +1625,7 @@ impl OwnedVector for ~[T] { #[inline] fn push_all_move(&mut self, mut rhs: ~[T]) { let new_len = self.len() + rhs.len(); - reserve(self, new_len); + self.reserve(new_len); unsafe { do as_mut_buf(rhs) |p, len| { for uint::range(0, len) |i| { @@ -1672,7 +1672,7 @@ impl OwnedVector for ~[T] { // Save the last element. We're going to overwrite its position let work_elt = self.pop(); // We still should have room to work where what last element was - assert!(capacity(self) >= ln); + assert!(self.capacity() >= ln); // Pretend like we have the original length so we can use // the vector copy_memory to overwrite the hole we just made raw::set_len(self, ln); @@ -1859,7 +1859,7 @@ impl OwnedCopyableVector for ~[T] { #[inline] fn push_all(&mut self, rhs: &const [T]) { let new_len = self.len() + rhs.len(); - reserve(self, new_len); + self.reserve(new_len); for uint::range(0u, rhs.len()) |i| { self.push(unsafe { raw::get(rhs, i) }) @@ -3333,11 +3333,11 @@ mod tests { #[test] fn test_capacity() { let mut v = ~[0u64]; - reserve(&mut v, 10u); - assert_eq!(capacity(&v), 10u); + v.reserve(10u); + assert_eq!(v.capacity(), 10u); let mut v = ~[0u32]; - reserve(&mut v, 10u); - assert_eq!(capacity(&v), 10u); + v.reserve(10u); + assert_eq!(v.capacity(), 10u); } #[test] diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 9893785ecfa2..e57dee06c75b 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -5,7 +5,6 @@ use std::cast::transmute; use std::libc::{STDOUT_FILENO, c_int, fdopen, fgets, fopen, fputc, fwrite}; use std::libc::{size_t}; use std::ptr::null; -use std::vec::{capacity, reserve, reserve_at_least}; use std::vec::raw::set_len; static LINE_LEN: u32 = 80; @@ -103,13 +102,13 @@ fn main() { let stdout = fdopen(STDOUT_FILENO as c_int, transmute(&mode[0])); let mut out: ~[u8] = ~[]; - reserve(&mut out, 12777888); + out.reserve(12777888); let mut pos = 0; loop { let needed = pos + (LINE_LEN as uint) + 1; - if capacity(&out) < needed { - reserve_at_least(&mut out, needed); + if out.capacity() < needed { + out.reserve_at_least(needed); } let mut ptr = out.unsafe_mut_ref(pos); From d8087cae442ba3ca5070c7f3865e798f3786d28c Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 28 Jun 2013 00:50:48 +1000 Subject: [PATCH 190/336] extra: silence some test warnings. --- src/libextra/arc.rs | 1 - src/libextra/c_vec.rs | 3 +-- src/libextra/dlist.rs | 2 -- src/libextra/net_tcp.rs | 20 +++++--------------- src/libextra/sync.rs | 1 - src/libextra/uv_global_loop.rs | 34 +++++++++++++++------------------- src/libextra/uv_ll.rs | 4 +--- 7 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 8e4a45fadd33..c076b7f8fbe0 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -517,7 +517,6 @@ mod tests { use arc::*; - use core::vec; use core::cell::Cell; use core::comm; use core::task; diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index 84593630cabd..79ef5bf2b7ea 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -159,8 +159,7 @@ mod tests { assert!(mem as int != 0); - return c_vec_with_dtor(mem as *mut u8, n as uint, - || unsafe { free(mem) }); + c_vec_with_dtor(mem as *mut u8, n as uint, || free(mem)) } } diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 1767aa8c3972..ee86340e47be 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -526,8 +526,6 @@ mod tests { use super::*; - use core::vec; - #[test] fn test_dlist_concat() { let a = from_vec([1,2]); diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index f8ecac373a6c..f3f6ffde6603 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -1457,33 +1457,23 @@ mod test { #[test] fn test_gl_tcp_server_and_client_ipv4() { - unsafe { - impl_gl_tcp_ipv4_server_and_client(); - } + impl_gl_tcp_ipv4_server_and_client(); } #[test] fn test_gl_tcp_get_peer_addr() { - unsafe { - impl_gl_tcp_ipv4_get_peer_addr(); - } + impl_gl_tcp_ipv4_get_peer_addr(); } #[test] fn test_gl_tcp_ipv4_client_error_connection_refused() { - unsafe { - impl_gl_tcp_ipv4_client_error_connection_refused(); - } + impl_gl_tcp_ipv4_client_error_connection_refused(); } #[test] fn test_gl_tcp_server_address_in_use() { - unsafe { - impl_gl_tcp_ipv4_server_address_in_use(); - } + impl_gl_tcp_ipv4_server_address_in_use(); } #[test] fn test_gl_tcp_server_access_denied() { - unsafe { - impl_gl_tcp_ipv4_server_access_denied(); - } + impl_gl_tcp_ipv4_server_access_denied(); } // Strange failure on Windows. --pcwalton #[test] diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 8cfe39c5ef25..817e1ab12261 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -808,7 +808,6 @@ mod tests { use core::comm; use core::result; use core::task; - use core::vec; /************************************************************************ * Semaphore tests diff --git a/src/libextra/uv_global_loop.rs b/src/libextra/uv_global_loop.rs index 286863bef641..f1dde1b8cb41 100644 --- a/src/libextra/uv_global_loop.rs +++ b/src/libextra/uv_global_loop.rs @@ -150,9 +150,7 @@ mod test { let hl_loop = &get_gl(); do iotask::interact(hl_loop) |_loop_ptr| { debug!(~"closing timer"); - unsafe { - ll::close(timer_ptr, simple_timer_close_cb); - } + ll::close(timer_ptr, simple_timer_close_cb); debug!(~"about to deref exit_ch_ptr"); debug!(~"after msg sent on deref'd exit_ch"); }; @@ -169,24 +167,22 @@ mod test { let timer_handle = ll::timer_t(); let timer_ptr: *ll::uv_timer_t = &timer_handle; do iotask::interact(iotask) |loop_ptr| { - unsafe { - debug!(~"user code inside interact loop!!!"); - let init_status = ll::timer_init(loop_ptr, timer_ptr); - if(init_status == 0i32) { - ll::set_data_for_uv_handle( - timer_ptr as *libc::c_void, - exit_ch_ptr); - let start_status = ll::timer_start(timer_ptr, - simple_timer_cb, - 1u, 0u); - if(start_status != 0i32) { - fail!("failure on ll::timer_start()"); - } - } - else { - fail!("failure on ll::timer_init()"); + debug!(~"user code inside interact loop!!!"); + let init_status = ll::timer_init(loop_ptr, timer_ptr); + if(init_status == 0i32) { + ll::set_data_for_uv_handle( + timer_ptr as *libc::c_void, + exit_ch_ptr); + let start_status = ll::timer_start(timer_ptr, + simple_timer_cb, + 1u, 0u); + if(start_status != 0i32) { + fail!("failure on ll::timer_start()"); } } + else { + fail!("failure on ll::timer_init()"); + } }; exit_po.recv(); debug!( diff --git a/src/libextra/uv_ll.rs b/src/libextra/uv_ll.rs index 744f4555d5cb..58b477d4ccf4 100644 --- a/src/libextra/uv_ll.rs +++ b/src/libextra/uv_ll.rs @@ -1767,9 +1767,7 @@ mod test { mod impl64 { #[test] fn test_uv_ll_tcp_server_and_request() { - unsafe { - super::super::impl_uv_tcp_server_and_request(); - } + super::super::impl_uv_tcp_server_and_request(); } } #[cfg(target_arch="x86")] From 366ca44cc8f79704f8781adb15e74d3c2a0e5572 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 28 Jun 2013 01:45:24 +1000 Subject: [PATCH 191/336] std: silence some test warnings. --- src/libstd/iterator.rs | 1 - src/libstd/local_data.rs | 23 ++++++++++------------- src/libstd/rt/uv/timer.rs | 4 ++-- src/libstd/str.rs | 3 ++- src/libstd/task/mod.rs | 14 ++++++-------- src/libstd/vec.rs | 4 ++-- 6 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index ab433a9a79d0..7de02a9f815b 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -980,7 +980,6 @@ mod tests { use super::*; use prelude::*; - use iter; use uint; #[test] diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index 82c01c998cf1..33b4e3f1963a 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -92,14 +92,12 @@ fn test_tls_multitask() { fn my_key(_x: @~str) { } local_data_set(my_key, @~"parent data"); do task::spawn { - unsafe { - // TLS shouldn't carry over. - assert!(local_data_get(my_key).is_none()); - local_data_set(my_key, @~"child data"); - assert!(*(local_data_get(my_key).get()) == + // TLS shouldn't carry over. + assert!(local_data_get(my_key).is_none()); + local_data_set(my_key, @~"child data"); + assert!(*(local_data_get(my_key).get()) == ~"child data"); - // should be cleaned up for us - } + // should be cleaned up for us } // Must work multiple times assert!(*(local_data_get(my_key).get()) == ~"parent data"); @@ -206,12 +204,11 @@ fn test_tls_cleanup_on_failure() { local_data_set(str_key, @~"parent data"); local_data_set(box_key, @@()); do task::spawn { - unsafe { // spawn_linked - local_data_set(str_key, @~"string data"); - local_data_set(box_key, @@()); - local_data_set(int_key, @42); - fail!(); - } + // spawn_linked + local_data_set(str_key, @~"string data"); + local_data_set(box_key, @@()); + local_data_set(int_key, @42); + fail!(); } // Not quite nondeterministic. local_data_set(int_key, @31337); diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index cd6fc5c0a250..14465eb7dfd3 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -160,14 +160,14 @@ mod test { let mut timer2 = TimerWatcher::new(&mut loop_); do timer2.start(10, 0) |timer2, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer2.close(||()); // Restart the original timer let mut timer = timer; do timer.start(1, 0) |timer, _| { - unsafe { *count_ptr += 1; } + *count_ptr += 1; timer.close(||()); } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 58cdc6631f0b..b4292a30541d 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -2249,7 +2249,7 @@ mod tests { assert!("" <= ""); assert!("" <= "foo"); assert!("foo" <= "foo"); - assert!("foo" != ~"bar"); + assert!("foo" != "bar"); } #[test] @@ -3156,6 +3156,7 @@ mod tests { #[test] fn test_add() { + #[allow(unnecessary_allocation)]; macro_rules! t ( ($s1:expr, $s2:expr, $e:expr) => { assert_eq!($s1 + $s2, $e); diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 223afbce091b..b558b9d53a3c 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -934,17 +934,15 @@ fn test_spawn_sched_blocking() { let lock = testrt::rust_dbg_lock_create(); do spawn_sched(SingleThreaded) { - unsafe { - testrt::rust_dbg_lock_lock(lock); + testrt::rust_dbg_lock_lock(lock); - start_ch.send(()); + start_ch.send(()); - // Block the scheduler thread - testrt::rust_dbg_lock_wait(lock); - testrt::rust_dbg_lock_unlock(lock); + // Block the scheduler thread + testrt::rust_dbg_lock_wait(lock); + testrt::rust_dbg_lock_unlock(lock); - fin_ch.send(()); - } + fin_ch.send(()); }; // Wait until the other task has its lock diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 5dfea811c233..8cbd9309cc6b 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -3861,11 +3861,11 @@ mod tests { fn test_vec_zero() { use num::Zero; macro_rules! t ( - ($ty:ty) => { + ($ty:ty) => {{ let v: $ty = Zero::zero(); assert!(v.is_empty()); assert!(v.is_zero()); - } + }} ); t!(&[int]); From fda193de247c592b7b5b0081df9cf95aeb7d3ce3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 19 Jun 2013 16:26:35 +0200 Subject: [PATCH 192/336] Extended test cases for struct debug information. Added test cases for different kinds of padding (simple-struct.rs) Added test cases for nested structs (struct-in-struct.rs) --- src/test/debug-info/simple-struct.rs | 84 +++++++++++++ src/test/debug-info/struct-in-struct.rs | 153 ++++++++++++++++++++++++ src/test/debug-info/struct.rs | 35 ------ 3 files changed, 237 insertions(+), 35 deletions(-) create mode 100644 src/test/debug-info/simple-struct.rs create mode 100644 src/test/debug-info/struct-in-struct.rs delete mode 100644 src/test/debug-info/struct.rs diff --git a/src/test/debug-info/simple-struct.rs b/src/test/debug-info/simple-struct.rs new file mode 100644 index 000000000000..64cfe4a4e23a --- /dev/null +++ b/src/test/debug-info/simple-struct.rs @@ -0,0 +1,84 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding16 +// check:$1 = {x = 10000, y = -10001} + +// debugger:print noPadding32 +// check:$2 = {x = -10002, y = -10003.5, z = 10004} + +// debugger:print noPadding64 +// check:$3 = {x = -10005.5, y = 10006, z = 10007} + +// debugger:print noPadding163264 +// check:$4 = {a = -10008, b = 10009, c = 10010, d = 10011} + +// debugger:print internalPadding +// check:$5 = {x = 10012, y = -10013} + +// debugger:print paddingAtEnd +// check:$6 = {x = -10014, y = 10015} + + +struct NoPadding16 { + x: u16, + y: i16 +} + +struct NoPadding32 { + x: i32, + y: f32, + z: u32 +} + +struct NoPadding64 { + x: f64, + y: i64, + z: u64 +} + +struct NoPadding163264 { + a: i16, + b: u16, + c: i32, + d: u64 +} + +struct InternalPadding { + x: u16, + y: i64 +} + +struct PaddingAtEnd { + x: i64, + y: u16 +} + +fn main() { + let noPadding16 = NoPadding16 { x: 10000, y: -10001 }; + let noPadding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; + let noPadding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; + let noPadding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; + + let internalPadding = InternalPadding { x: 10012, y: -10013 }; + let paddingAtEnd = PaddingAtEnd { x: -10014, y: 10015 }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs new file mode 100644 index 000000000000..a74eb727dc0f --- /dev/null +++ b/src/test/debug-info/struct-in-struct.rs @@ -0,0 +1,153 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print three_simple_structs +// check:$1 = {x = {x = 1}, y = {x = 2}, z = {x = 3}} + +// debugger:print internal_padding_parent +// check:$2 = {x = {x = 4, y = 5}, y = {x = 6, y = 7}, z = {x = 8, y = 9}} + +// debugger:print padding_at_end_parent +// check:$3 = {x = {x = 10, y = 11}, y = {x = 12, y = 13}, z = {x = 14, y = 15}} + + +struct Simple { + x: i32 +} + +struct InternalPadding { + x: i32, + y: i64 +} + +struct PaddingAtEnd { + x: i64, + y: i32 +} + +struct ThreeSimpleStructs { + x: Simple, + y: Simple, + z: Simple +} + +struct InternalPaddingParent { + x: InternalPadding, + y: InternalPadding, + z: InternalPadding +} + +struct PaddingAtEndParent { + x: PaddingAtEnd, + y: PaddingAtEnd, + z: PaddingAtEnd +} + +struct Mixed { + x: PaddingAtEnd, + y: InternalPadding, + z: Simple, + w: i16 +} + +struct Bag { + x: Simple +} + +struct BagInBag { + x: Bag +} + +struct ThatsJustOverkill { + x: BagInBag +} + +struct Tree { + x: Simple, + y: InternalPaddingParent, + z: BagInBag +} + +fn main() { + + let three_simple_structs = ThreeSimpleStructs { + x: Simple { x: 1 }, + y: Simple { x: 2 }, + z: Simple { x: 3 } + }; + + let internal_padding_parent = InternalPaddingParent { + x: InternalPadding { x: 4, y: 5 }, + y: InternalPadding { x: 6, y: 7 }, + z: InternalPadding { x: 8, y: 9 } + }; + + let padding_at_end_parent = PaddingAtEndParent { + x: PaddingAtEnd { x: 10, y: 11 }, + y: PaddingAtEnd { x: 12, y: 13 }, + z: PaddingAtEnd { x: 14, y: 15 } + }; + + let mixed = Mixed { + x: PaddingAtEnd { x: 16, y: 17 }, + y: InternalPadding { x: 18, y: 19 }, + z: Simple { x: 20 }, + w: 21 + }; + + let bag = Bag { x: Simple { x: 22 } }; + let bag_in_bag = BagInBag + { + x: Bag + { + x: Simple { x: 23 } + } + }; + + let tjo = ThatsJustOverkill + { + x: BagInBag + { + x: Bag + { + x: Simple { x: 24 } + } + } + }; + + let tree = Tree { + x: Simple { x: 25 }, + y: InternalPaddingParent + { + x: InternalPadding { x: 26, y: 27 }, + y: InternalPadding { x: 28, y: 29 }, + z: InternalPadding { x: 30, y: 31 } + }, + z: BagInBag + { + x: Bag + { + x: Simple { x: 32 } + } + } + }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/struct.rs b/src/test/debug-info/struct.rs deleted file mode 100644 index ddfac9cbeea8..000000000000 --- a/src/test/debug-info/struct.rs +++ /dev/null @@ -1,35 +0,0 @@ -// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 - -// compile-flags:-Z extra-debug-info -// debugger:set print pretty off -// debugger:break _zzz -// debugger:run -// debugger:finish -// debugger:print pair -// check:$1 = {x = 1, y = 2} -// debugger:print pair.x -// check:$2 = 1 -// debugger:print pair.y -// check:$3 = 2 - -struct Pair { - x: int, - y: int -} - -fn main() { - let pair = Pair { x: 1, y: 2 }; - _zzz(); -} - -fn _zzz() {()} \ No newline at end of file From 7bb189e56c3ee7d5496e0938f2ec7ed7c3048258 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 19 Jun 2013 16:30:35 +0200 Subject: [PATCH 193/336] Fixed debug information bug regarding struct padding. --- src/librustc/middle/trans/debuginfo.rs | 92 ++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index dae3d58d2be5..5281dcb91936 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -56,7 +56,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashMap; use core::libc; -use core::libc::c_uint; +use core::libc::{c_uint, c_ulonglong}; use core::cmp; use core::ptr; use core::str::as_c_str; @@ -337,6 +337,9 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { fn create_compile_unit(cx: @mut CrateContext) { let dcx = dbg_cx(cx); let crate_name: &str = dcx.crate_file; + + debug!("create_compile_unit: %?", crate_name); + let work_dir = cx.sess.working_dir.to_str(); let producer = fmt!("rustc version %s", env!("CFG_VERSION")); @@ -507,14 +510,23 @@ impl StructContext { } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { - debug!("StructContext(%s)::add_member: %s, size=%u, align=%u", - self.name, name, size, align); let offset = roundup(self.total_size, align); + + debug!("StructContext(%s)::add_member: %s, size=%u, align=%u, offset=%u", + self.name, name, size, align, offset); + let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType( - self.builder, ptr::null(), name, self.file, line as c_uint, - size * 8 as u64, align * 8 as u64, offset * 8 as u64, - 0, ty) + self.builder, + self.file, + name, + self.file, + line as c_uint, + (size * 8) as c_ulonglong, + (align * 8) as c_ulonglong, + (offset * 8) as c_ulonglong, + 0, + ty) }}; self.members.push(mem_t); self.total_size = offset + size; @@ -522,25 +534,67 @@ impl StructContext { self.align = cmp::max(self.align, align); } + fn get_total_size_with_alignment(&self) -> uint { + roundup(self.total_size, self.align) + } + + //fn verify_against_struct_or_tuple_type(&self, t: ty::t, ccx: &mut CrateContext) { + // let repr = adt::represent_type(ccx, t); + + // match *repr { + // Univariant(*) => + // { + // let size_with_alignment = self.get_total_size_with_alignment(); + + // if st.size != size_with_alignment { + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", + // st.size, size_with_alignment); + // } + + // if st.align != self.align { + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type alignment. Expected = %u, actual = %u", + // st.align, self.align); + // } + // }, + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", + // self.name, t)) + // } + //} + fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); let members_md = create_DIArray(self.builder, self.members); + // The size of the struct/tuple must be rounded to the next multiple of its alignment. + // Otherwise gdb has trouble reading the struct correct when it is embedded into another + // data structure. This is also the value `sizeof` in C would give. + let total_size_with_alignment = self.get_total_size_with_alignment(); + let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( - self.builder, self.file, name, - self.file, self.line as c_uint, - self.total_size * 8 as u64, self.align * 8 as u64, 0, ptr::null(), - members_md, 0, ptr::null()) + self.builder, + self.file, + name, + self.file, + self.line as c_uint, + (total_size_with_alignment * 8) as c_ulonglong, + (self.align * 8) as c_ulonglong, + 0, + ptr::null(), + members_md, + 0, + ptr::null()) }}; return struct_md; } } -fn create_struct(cx: @mut CrateContext, t: ty::t, fields: ~[ty::field], span: span) +fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { + debug!("create_struct: %?", ty::get(struct_type)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -565,8 +619,10 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span) +fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) -> DICompositeType { + debug!("create_tuple: %?", ty::get(tuple_type)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); @@ -582,6 +638,8 @@ fn create_tuple(cx: @mut CrateContext, _t: ty::t, elements: &[ty::t], span: span fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { + debug!("create_boxed_type: %?", ty::get(contents)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let int_t = ty::mk_int(); @@ -604,6 +662,8 @@ fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { + debug!("create_fixed_vec: %?", ty::get(_vec_t)); + let elem_ty_md = create_ty(cx, elem_t, span); let (size, align) = size_and_align_of(cx, elem_t); @@ -620,6 +680,8 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { + debug!("create_boxed_vec: %?", ty::get(vec_t)); + let loc = span_start(cx, vec_ty_span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, vec_ty_span); @@ -663,6 +725,8 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { + debug!("create_vec_slice: %?", ty::get(vec_t)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let elem_ty_md = create_ty(cx, elem_t, span); @@ -679,6 +743,8 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { + debug!("create_fn_ty: %?", ty::get(_fn_ty)); + let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); let (vp, _, _) = voidptr(cx); @@ -694,6 +760,8 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: } fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { + debug!("create_unimpl_ty: %?", ty::get(t)); + let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( From 36aa04b9aba097ad8f86a873066dda1b417c14e5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 12:45:18 +0200 Subject: [PATCH 194/336] debuginfo: Added test cases for tuples. --- src/test/debug-info/simple-tuple.rs | 51 +++++++++++++++++++++++++++ src/test/debug-info/tuple-in-tuple.rs | 50 ++++++++++++++++++++++++++ src/test/debug-info/tuple.rs | 26 -------------- 3 files changed, 101 insertions(+), 26 deletions(-) create mode 100644 src/test/debug-info/simple-tuple.rs create mode 100644 src/test/debug-info/tuple-in-tuple.rs delete mode 100644 src/test/debug-info/tuple.rs diff --git a/src/test/debug-info/simple-tuple.rs b/src/test/debug-info/simple-tuple.rs new file mode 100644 index 000000000000..6193e58969f1 --- /dev/null +++ b/src/test/debug-info/simple-tuple.rs @@ -0,0 +1,51 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding8 +// check:$1 = {-100 '\234', 100 'd'} +// debugger:print noPadding16 +// check:$2 = {0, 1, 2} +// debugger:print noPadding32 +// check:$3 = {3, 4.5, 5} +// debugger:print noPadding64 +// check:$4 = {6, 7.5, 8} + +// debugger:print internalPadding1 +// check:$5 = {9, 10} +// debugger:print internalPadding2 +// check:$6 = {11, 12, 13, 14} + +// debugger:print paddingAtEnd +// check:$7 = {15, 16} + + +fn main() { + let noPadding8 : (i8, u8) = (-100, 100); + let noPadding16 : (i16, i16, u16) = (0, 1, 2); + let noPadding32 : (i32, f32, u32) = (3, 4.5, 5); + let noPadding64 : (i64, f64, u64) = (6, 7.5, 8); + + let internalPadding1 : (i16, i32) = (9, 10); + let internalPadding2 : (i16, i32, u32, u64) = (11, 12, 13, 14); + + let paddingAtEnd : (i32, i16) = (15, 16); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple-in-tuple.rs b/src/test/debug-info/tuple-in-tuple.rs new file mode 100644 index 000000000000..f500ecef132b --- /dev/null +++ b/src/test/debug-info/tuple-in-tuple.rs @@ -0,0 +1,50 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding1 +// check:$1 = {{0, 1}, 2, 3} +// debugger:print noPadding2 +// check:$2 = {4, {5, 6}, 7} +// debugger:print noPadding3 +// check:$3 = {8, 9, {10, 11}} + +// debugger:print internalPadding1 +// check:$4 = {12, {13, 14}} +// debugger:print internalPadding2 +// check:$5 = {15, {16, 17}} + +// debugger:print paddingAtEnd1 +// check:$6 = {18, {19, 20}} +// debugger:print paddingAtEnd2 +// check:$7 = {{21, 22}, 23} + +fn main() { + let noPadding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); + let noPadding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); + let noPadding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); + + let internalPadding1 : (i16, (i32, i32)) = (12, (13, 14)); + let internalPadding2 : (i16, (i16, i32)) = (15, (16, 17)); + + let paddingAtEnd1 : (i32, (i32, i16)) = (18, (19, 20)); + let paddingAtEnd2 : ((i32, i16), i32) = ((21, 22), 23); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/tuple.rs b/src/test/debug-info/tuple.rs deleted file mode 100644 index a50996871cee..000000000000 --- a/src/test/debug-info/tuple.rs +++ /dev/null @@ -1,26 +0,0 @@ -// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 - -// compile-flags:-Z extra-debug-info -// debugger:set print pretty off -// debugger:break _zzz -// debugger:run -// debugger:finish -// debugger:print t -// check:$1 = {4, 5.5, true} - -fn main() { - let t = (4, 5.5, true); - _zzz(); -} - -fn _zzz() {()} \ No newline at end of file From 5f97a6e951bfd45743c9153fc78743462472351b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 15:25:30 +0200 Subject: [PATCH 195/336] debuginfo: Added test cases for tuples contained in structs. --- src/test/debug-info/tuple-in-struct.rs | 151 +++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/test/debug-info/tuple-in-struct.rs diff --git a/src/test/debug-info/tuple-in-struct.rs b/src/test/debug-info/tuple-in-struct.rs new file mode 100644 index 000000000000..1ad4d7c069ec --- /dev/null +++ b/src/test/debug-info/tuple-in-struct.rs @@ -0,0 +1,151 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// compile-flags:-Z extra-debug-info +// debugger:set print pretty off +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print noPadding1 +// check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}} +// debugger:print noPadding2 +// check:$2 = {x = {6, 7}, y = {{8, 9}, 10}} + +// debugger:print tupleInternalPadding +// check:$3 = {x = {11, 12}, y = {13, 14}} +// debugger:print structInternalPadding +// check:$4 = {x = {15, 16}, y = {17, 18}} +// debugger:print bothInternallyPadded +// check:$5 = {x = {19, 20, 21}, y = {22, 23}} + +// debugger:print singleTuple +// check:$6 = {x = {24, 25, 26}} + +// debugger:print tuplePaddedAtEnd +// check:$7 = {x = {27, 28}, y = {29, 30}} +// debugger:print structPaddedAtEnd +// check:$8 = {x = {31, 32}, y = {33, 34}} +// debugger:print bothPaddedAtEnd +// check:$9 = {x = {35, 36, 37}, y = {38, 39}} + +// debugger:print mixedPadding +// check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}} + +struct NoPadding1 { + x: (i32, i32), + y: i32, + z: (i32, i32, i32) +} + +struct NoPadding2 { + x: (i32, i32), + y: ((i32, i32), i32) +} + +struct TupleInternalPadding { + x: (i16, i32), + y: (i32, i64) +} + +struct StructInternalPadding { + x: (i16, i16), + y: (i64, i64) +} + +struct BothInternallyPadded { + x: (i16, i32, i32), + y: (i32, i64) +} + +struct SingleTuple { + x: (i16, i32, i64) +} + +struct TuplePaddedAtEnd { + x: (i32, i16), + y: (i64, i32) +} + +struct StructPaddedAtEnd { + x: (i64, i64), + y: (i16, i16) +} + +struct BothPaddedAtEnd { + x: (i32, i32, i16), + y: (i64, i32) +} + +// Data-layout (padding signified by dots, one column = 2 bytes): +// [a.bbc...ddddee..ffffg.hhi...] +struct MixedPadding { + x: ((i16, i32, i16), (i64, i32)), + y: (i64, i16, i32, i16) +} + + +fn main() { + let noPadding1 = NoPadding1 { + x: (0, 1), + y: 2, + z: (3, 4, 5) + }; + + let noPadding2 = NoPadding2 { + x: (6, 7), + y: ((8, 9), 10) + }; + + let tupleInternalPadding = TupleInternalPadding { + x: (11, 12), + y: (13, 14) + }; + + let structInternalPadding = StructInternalPadding { + x: (15, 16), + y: (17, 18) + }; + + let bothInternallyPadded = BothInternallyPadded { + x: (19, 20, 21), + y: (22, 23) + }; + + let singleTuple = SingleTuple { + x: (24, 25, 26) + }; + + let tuplePaddedAtEnd = TuplePaddedAtEnd { + x: (27, 28), + y: (29, 30) + }; + + let structPaddedAtEnd = StructPaddedAtEnd { + x: (31, 32), + y: (33, 34) + }; + + let bothPaddedAtEnd = BothPaddedAtEnd { + x: (35, 36, 37), + y: (38, 39) + }; + + let mixedPadding = MixedPadding { + x: ((40, 41, 42), (43, 44)), + y: (45, 46, 47, 48) + }; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 4d8f2fd8714b983aa8ae5d697c90998424930f5b Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 16:00:59 +0200 Subject: [PATCH 196/336] debuginfo: Many little formatting improvements. --- src/librustc/middle/trans/debuginfo.rs | 177 +++++++++++++++++-------- 1 file changed, 121 insertions(+), 56 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 5281dcb91936..0a1f2d1fe241 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -211,9 +211,17 @@ pub fn create_arg(bcx: block, arg: ast::arg, span: span) -> Option { let ident = path.idents.last(); let name: &str = cx.sess.str_of(*ident); let mdnode = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreateLocalVariable(DIB(cx), - ArgVariableTag as u32, context, name, - filemd, loc.line as c_uint, tymd, false, 0, 0) + llvm::LLVMDIBuilderCreateLocalVariable( + DIB(cx), + ArgVariableTag as u32, + context, + name, + filemd, + loc.line as c_uint, + tymd, + false, + 0, + 0) // XXX need to pass in a real argument number }}; @@ -290,16 +298,17 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { let ret_ty_md = if cx.sess.opts.extra_debuginfo { match ret_ty.node { ast::ty_nil => ptr::null(), - _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), - ret_ty.span) + _ => create_ty(cx, ty::node_id_to_type(cx.tcx, id), ret_ty.span) } } else { ptr::null() }; let fn_ty = unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), - file_md, create_DIArray(DIB(cx), [ret_ty_md])) + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(cx), + file_md, + create_DIArray(DIB(cx), [ret_ty_md])) }; let fn_md = @@ -308,13 +317,19 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { llvm::LLVMDIBuilderCreateFunction( DIB(cx), file_md, - name, linkage, - file_md, loc.line as c_uint, - fn_ty, false, true, + name, + linkage, + file_md, + loc.line as c_uint, + fn_ty, + false, + true, loc.line as c_uint, FlagPrototyped as c_uint, cx.sess.opts.optimize != session::No, - fcx.llfn, ptr::null(), ptr::null()) + fcx.llfn, + ptr::null(), + ptr::null()) }}}; dbg_cx(cx).created_functions.insert(id, fn_md); @@ -463,8 +478,11 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { let (size, align) = size_and_align_of(cx, t); let ty_md = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - DIB(cx), name, - size * 8 as u64, align * 8 as u64, encoding as c_uint) + DIB(cx), + name, + bytes_to_bits(size), + bytes_to_bits(align), + encoding as c_uint) }}; // One could think that this call is not necessary, as the create_ty() function will insert the @@ -478,8 +496,12 @@ fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DI let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(DIB(cx), - pointee, size * 8 as u64, align * 8 as u64, name) + llvm::LLVMDIBuilderCreatePointerType( + DIB(cx), + pointee, + bytes_to_bits(size), + bytes_to_bits(align), + name) }}; return ptr_md; } @@ -514,18 +536,18 @@ impl StructContext { debug!("StructContext(%s)::add_member: %s, size=%u, align=%u, offset=%u", self.name, name, size, align, offset); - + let mem_t = do as_c_str(name) |name| { unsafe { llvm::LLVMDIBuilderCreateMemberType( - self.builder, + self.builder, + self.file, + name, self.file, - name, - self.file, line as c_uint, - (size * 8) as c_ulonglong, - (align * 8) as c_ulonglong, - (offset * 8) as c_ulonglong, - 0, + bytes_to_bits(size), + bytes_to_bits(align), + bytes_to_bits(offset), + 0, ty) }}; self.members.push(mem_t); @@ -542,10 +564,10 @@ impl StructContext { // let repr = adt::represent_type(ccx, t); // match *repr { - // Univariant(*) => + // Univariant(*) => // { // let size_with_alignment = self.get_total_size_with_alignment(); - + // if st.size != size_with_alignment { // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", // st.size, size_with_alignment); @@ -556,7 +578,7 @@ impl StructContext { // st.align, self.align); // } // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", // self.name, t)) // } //} @@ -567,24 +589,24 @@ impl StructContext { let members_md = create_DIArray(self.builder, self.members); // The size of the struct/tuple must be rounded to the next multiple of its alignment. - // Otherwise gdb has trouble reading the struct correct when it is embedded into another + // Otherwise gdb has trouble reading the struct correctly when it is embedded into another // data structure. This is also the value `sizeof` in C would give. - let total_size_with_alignment = self.get_total_size_with_alignment(); + let actual_total_size = self.get_total_size_with_alignment(); let struct_md = do as_c_str(self.name) |name| { unsafe { llvm::LLVMDIBuilderCreateStructType( self.builder, - self.file, + self.file, name, - self.file, + self.file, self.line as c_uint, - (total_size_with_alignment * 8) as c_ulonglong, - (self.align * 8) as c_ulonglong, + bytes_to_bits(actual_total_size), + bytes_to_bits(self.align), 0, ptr::null(), - members_md, - 0, + members_md, + 0, ptr::null()) }}; return struct_md; @@ -613,8 +635,12 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { - llvm::LLVMDIBuilderCreatePointerType(DIB(cx), ptr::null(), - size*8 as u64, align*8 as u64, name) + llvm::LLVMDIBuilderCreatePointerType( + DIB(cx), + ptr::null(), + bytes_to_bits(size), + bytes_to_bits(align), + name) }}; return (vp, size, align); } @@ -673,8 +699,12 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, let subscripts = create_DIArray(DIB(cx), [subrange]); return unsafe { - llvm::LLVMDIBuilderCreateArrayType(DIB(cx), - size * len * 8 as u64, align * 8 as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType( + DIB(cx), + bytes_to_bits(size * len), + bytes_to_bits(align), + elem_ty_md, + subscripts) }; } @@ -688,10 +718,21 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, let mut vec_scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let size_t_type = create_basic_type(cx, ty::mk_uint(), vec_ty_span); - vec_scx.add_member("fill", 0, sys::size_of::(), - sys::min_align_of::(), size_t_type); - vec_scx.add_member("alloc", 0, sys::size_of::(), - sys::min_align_of::(), size_t_type); + + vec_scx.add_member( + "fill", + 0, + sys::size_of::(), + sys::min_align_of::(), + size_t_type); + + vec_scx.add_member( + "alloc", + 0, + sys::size_of::(), + sys::min_align_of::(), + size_t_type); + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0_i64, 0_i64) }; @@ -700,18 +741,32 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, let subscripts = create_DIArray(DIB(cx), [subrange]); let data_ptr = unsafe { - llvm::LLVMDIBuilderCreateArrayType(DIB(cx), - arr_size * 8 as u64, arr_align * 8 as u64, elem_ty_md, subscripts) + llvm::LLVMDIBuilderCreateArrayType( + DIB(cx), + bytes_to_bits(arr_size), + bytes_to_bits(arr_align), + elem_ty_md, + subscripts) }; - vec_scx.add_member("data", 0, 0, // clang says the size should be 0 - sys::min_align_of::(), data_ptr); + vec_scx.add_member( + "data", + 0, + 0, // clang says the size should be 0 + sys::min_align_of::(), data_ptr); + let vec_md = vec_scx.finalize(); let mut box_scx = StructContext::new(cx, fmt!("box<%s>", name), file_md, 0); let int_t = ty::mk_int(); let refcount_type = create_basic_type(cx, int_t, vec_ty_span); - box_scx.add_member("refcnt", 0, sys::size_of::(), - sys::min_align_of::(), refcount_type); + + box_scx.add_member( + "refcnt", + 0, + sys::size_of::(), + sys::min_align_of::(), + refcount_type); + let (vp, vpsize, vpalign) = voidptr(cx); box_scx.add_member("tydesc", 0, vpsize, vpalign, vp); box_scx.add_member("prev", 0, vpsize, vpalign, vp); @@ -736,8 +791,7 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, vec_t), file_md, 0); let (_, ptr_size, ptr_align) = voidptr(cx); scx.add_member("vec", 0, ptr_size, ptr_align, elem_ptr); - scx.add_member("length", 0, sys::size_of::(), - sys::min_align_of::(), uint_type); + scx.add_member("length", 0, sys::size_of::(), sys::min_align_of::(), uint_type); return scx.finalize(); } @@ -754,7 +808,9 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: let members = ~[output_ptr_md, vp] + inputs_vals; return unsafe { - llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_md, + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(cx), + file_md, create_DIArray(DIB(cx), members)) }; } @@ -765,8 +821,11 @@ fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { let name = ty_to_str(cx.tcx, t); let md = do as_c_str(fmt!("NYI<%s>", name)) |name| { unsafe { llvm::LLVMDIBuilderCreateBasicType( - DIB(cx), name, - 0_u64, 8_u64, DW_ATE_unsigned as c_uint) + DIB(cx), + name, + 0_u64, + 8_u64, + DW_ATE_unsigned as c_uint) }}; return md; } @@ -867,8 +926,10 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui let elems = ~[C_i32(line as i32), C_i32(col as i32), scope, ptr::null()]; unsafe { let dbg_loc = llvm::LLVMMDNodeInContext( - dbg_cx(cx).llcontext, vec::raw::to_ptr(elems), - elems.len() as libc::c_uint); + dbg_cx(cx).llcontext, + vec::raw::to_ptr(elems), + elems.len() as c_uint); + llvm::LLVMSetCurrentDebugLocation(cx.builder.B, dbg_loc); } } @@ -887,7 +948,7 @@ fn roundup(x: uint, a: uint) -> uint { /// Return codemap::Loc corresponding to the beginning of the span fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { - return cx.sess.codemap.lookup_char_pos(span.lo); + cx.sess.codemap.lookup_char_pos(span.lo) } fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { @@ -895,6 +956,10 @@ fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } +fn bytes_to_bits(bytes: uint) -> c_ulonglong { + (bytes * 8) as c_ulonglong +} + #[inline] fn dbg_cx<'a>(cx: &'a mut CrateContext) -> &'a mut DebugContext { cx.dbg_cx.get_mut_ref() From 1dc8e76d3a32fbb304b152f815d394577fe008c6 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 20 Jun 2013 16:45:47 +0200 Subject: [PATCH 197/336] debuginfo: Made test cases use correct naming convention for variables. --- src/test/debug-info/simple-struct.rs | 28 ++++++++--------- src/test/debug-info/struct-in-struct.rs | 32 ++++++++++---------- src/test/debug-info/tuple-in-struct.rs | 40 ++++++++++++------------- src/test/debug-info/tuple-in-tuple.rs | 28 ++++++++--------- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/test/debug-info/simple-struct.rs b/src/test/debug-info/simple-struct.rs index 64cfe4a4e23a..49e7bc255c10 100644 --- a/src/test/debug-info/simple-struct.rs +++ b/src/test/debug-info/simple-struct.rs @@ -16,22 +16,22 @@ // debugger:run // debugger:finish -// debugger:print noPadding16 +// debugger:print no_padding16 // check:$1 = {x = 10000, y = -10001} -// debugger:print noPadding32 +// debugger:print no_padding32 // check:$2 = {x = -10002, y = -10003.5, z = 10004} -// debugger:print noPadding64 +// debugger:print no_padding64 // check:$3 = {x = -10005.5, y = 10006, z = 10007} -// debugger:print noPadding163264 +// debugger:print no_padding163264 // check:$4 = {a = -10008, b = 10009, c = 10010, d = 10011} -// debugger:print internalPadding +// debugger:print internal_padding // check:$5 = {x = 10012, y = -10013} -// debugger:print paddingAtEnd +// debugger:print padding_at_end // check:$6 = {x = -10014, y = 10015} @@ -39,7 +39,7 @@ struct NoPadding16 { x: u16, y: i16 } - + struct NoPadding32 { x: i32, y: f32, @@ -70,13 +70,13 @@ struct PaddingAtEnd { } fn main() { - let noPadding16 = NoPadding16 { x: 10000, y: -10001 }; - let noPadding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; - let noPadding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; - let noPadding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; - - let internalPadding = InternalPadding { x: 10012, y: -10013 }; - let paddingAtEnd = PaddingAtEnd { x: -10014, y: 10015 }; + let no_padding16 = NoPadding16 { x: 10000, y: -10001 }; + let no_padding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }; + let no_padding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }; + let no_padding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }; + + let internal_padding = InternalPadding { x: 10012, y: -10013 }; + let padding_at_end = PaddingAtEnd { x: -10014, y: 10015 }; zzz(); } diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs index a74eb727dc0f..cfd8c24caa21 100644 --- a/src/test/debug-info/struct-in-struct.rs +++ b/src/test/debug-info/struct-in-struct.rs @@ -55,7 +55,7 @@ struct InternalPaddingParent { struct PaddingAtEndParent { x: PaddingAtEnd, y: PaddingAtEnd, - z: PaddingAtEnd + z: PaddingAtEnd } struct Mixed { @@ -84,7 +84,7 @@ struct Tree { } fn main() { - + let three_simple_structs = ThreeSimpleStructs { x: Simple { x: 1 }, y: Simple { x: 2 }, @@ -100,7 +100,7 @@ fn main() { let padding_at_end_parent = PaddingAtEndParent { x: PaddingAtEnd { x: 10, y: 11 }, y: PaddingAtEnd { x: 12, y: 13 }, - z: PaddingAtEnd { x: 14, y: 15 } + z: PaddingAtEnd { x: 14, y: 15 } }; let mixed = Mixed { @@ -111,22 +111,22 @@ fn main() { }; let bag = Bag { x: Simple { x: 22 } }; - let bag_in_bag = BagInBag + let bag_in_bag = BagInBag { - x: Bag + x: Bag { - x: Simple { x: 23 } - } + x: Simple { x: 23 } + } }; - let tjo = ThatsJustOverkill + let tjo = ThatsJustOverkill { - x: BagInBag + x: BagInBag { - x: Bag + x: Bag { - x: Simple { x: 24 } - } + x: Simple { x: 24 } + } } }; @@ -138,12 +138,12 @@ fn main() { y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, - z: BagInBag + z: BagInBag { - x: Bag + x: Bag { - x: Simple { x: 32 } - } + x: Simple { x: 32 } + } } }; diff --git a/src/test/debug-info/tuple-in-struct.rs b/src/test/debug-info/tuple-in-struct.rs index 1ad4d7c069ec..369c9fd28ccd 100644 --- a/src/test/debug-info/tuple-in-struct.rs +++ b/src/test/debug-info/tuple-in-struct.rs @@ -16,29 +16,29 @@ // debugger:run // debugger:finish -// debugger:print noPadding1 +// debugger:print no_padding1 // check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}} -// debugger:print noPadding2 +// debugger:print no_padding2 // check:$2 = {x = {6, 7}, y = {{8, 9}, 10}} -// debugger:print tupleInternalPadding +// debugger:print tuple_internal_padding // check:$3 = {x = {11, 12}, y = {13, 14}} -// debugger:print structInternalPadding +// debugger:print struct_internal_padding // check:$4 = {x = {15, 16}, y = {17, 18}} -// debugger:print bothInternallyPadded +// debugger:print both_internally_padded // check:$5 = {x = {19, 20, 21}, y = {22, 23}} -// debugger:print singleTuple +// debugger:print single_tuple // check:$6 = {x = {24, 25, 26}} -// debugger:print tuplePaddedAtEnd +// debugger:print tuple_padded_at_end // check:$7 = {x = {27, 28}, y = {29, 30}} -// debugger:print structPaddedAtEnd +// debugger:print struct_padded_at_end // check:$8 = {x = {31, 32}, y = {33, 34}} -// debugger:print bothPaddedAtEnd +// debugger:print both_padded_at_end // check:$9 = {x = {35, 36, 37}, y = {38, 39}} -// debugger:print mixedPadding +// debugger:print mixed_padding // check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}} struct NoPadding1 { @@ -95,52 +95,52 @@ struct MixedPadding { fn main() { - let noPadding1 = NoPadding1 { + let no_padding1 = NoPadding1 { x: (0, 1), y: 2, z: (3, 4, 5) }; - let noPadding2 = NoPadding2 { + let no_padding2 = NoPadding2 { x: (6, 7), y: ((8, 9), 10) }; - let tupleInternalPadding = TupleInternalPadding { + let tuple_internal_padding = TupleInternalPadding { x: (11, 12), y: (13, 14) }; - let structInternalPadding = StructInternalPadding { + let struct_internal_padding = StructInternalPadding { x: (15, 16), y: (17, 18) }; - let bothInternallyPadded = BothInternallyPadded { + let both_internally_padded = BothInternallyPadded { x: (19, 20, 21), y: (22, 23) }; - let singleTuple = SingleTuple { + let single_tuple = SingleTuple { x: (24, 25, 26) }; - let tuplePaddedAtEnd = TuplePaddedAtEnd { + let tuple_padded_at_end = TuplePaddedAtEnd { x: (27, 28), y: (29, 30) }; - let structPaddedAtEnd = StructPaddedAtEnd { + let struct_padded_at_end = StructPaddedAtEnd { x: (31, 32), y: (33, 34) }; - let bothPaddedAtEnd = BothPaddedAtEnd { + let both_padded_at_end = BothPaddedAtEnd { x: (35, 36, 37), y: (38, 39) }; - let mixedPadding = MixedPadding { + let mixed_padding = MixedPadding { x: ((40, 41, 42), (43, 44)), y: (45, 46, 47, 48) }; diff --git a/src/test/debug-info/tuple-in-tuple.rs b/src/test/debug-info/tuple-in-tuple.rs index f500ecef132b..13f8719694e5 100644 --- a/src/test/debug-info/tuple-in-tuple.rs +++ b/src/test/debug-info/tuple-in-tuple.rs @@ -16,33 +16,33 @@ // debugger:run // debugger:finish -// debugger:print noPadding1 +// debugger:print no_padding1 // check:$1 = {{0, 1}, 2, 3} -// debugger:print noPadding2 +// debugger:print no_padding2 // check:$2 = {4, {5, 6}, 7} -// debugger:print noPadding3 +// debugger:print no_padding3 // check:$3 = {8, 9, {10, 11}} -// debugger:print internalPadding1 +// debugger:print internal_padding1 // check:$4 = {12, {13, 14}} -// debugger:print internalPadding2 +// debugger:print internal_padding2 // check:$5 = {15, {16, 17}} -// debugger:print paddingAtEnd1 +// debugger:print padding_at_end1 // check:$6 = {18, {19, 20}} -// debugger:print paddingAtEnd2 +// debugger:print padding_at_end2 // check:$7 = {{21, 22}, 23} fn main() { - let noPadding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); - let noPadding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); - let noPadding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); + let no_padding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3); + let no_padding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7); + let no_padding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11)); - let internalPadding1 : (i16, (i32, i32)) = (12, (13, 14)); - let internalPadding2 : (i16, (i16, i32)) = (15, (16, 17)); + let internal_padding1 : (i16, (i32, i32)) = (12, (13, 14)); + let internal_padding2 : (i16, (i16, i32)) = (15, (16, 17)); - let paddingAtEnd1 : (i32, (i32, i16)) = (18, (19, 20)); - let paddingAtEnd2 : ((i32, i16), i32) = ((21, 22), 23); + let padding_at_end1 : (i32, (i32, i16)) = (18, (19, 20)); + let padding_at_end2 : ((i32, i16), i32) = ((21, 22), 23); zzz(); } From 0b5fef3b267510dc9abd890f80b076f11543a919 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 21 Jun 2013 11:19:33 +0200 Subject: [PATCH 198/336] debuginfo: Added test case for local variable scopes. --- src/test/debug-info/variable-scope.rs | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/debug-info/variable-scope.rs diff --git a/src/test/debug-info/variable-scope.rs b/src/test/debug-info/variable-scope.rs new file mode 100644 index 000000000000..a9177ac19664 --- /dev/null +++ b/src/test/debug-info/variable-scope.rs @@ -0,0 +1,49 @@ +// 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 + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print x +// check:$1 = false +// debugger:print y +// check:$2 = true + +// debugger:run +// debugger:finish +// debugger:print x +// check:$3 = 10 + +// debugger:run +// debugger:finish +// debugger:print x +// check:$4 = false +// debugger:print y +// check:$5 = 11 + +fn main() { + let x = false; + let y = true; + + zzz(); + + { + let x = 10; + zzz(); + } + + let y = 11; + zzz(); +} + +fn zzz() {()} From 168eba9201011e34a70febc8395d5e0808585600 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 21 Jun 2013 12:09:30 +0200 Subject: [PATCH 199/336] debuginfo: Added test case for structs with destructor. --- src/test/debug-info/struct-with-destructor.rs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/test/debug-info/struct-with-destructor.rs diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs new file mode 100644 index 000000000000..b5ae4bbe8fba --- /dev/null +++ b/src/test/debug-info/struct-with-destructor.rs @@ -0,0 +1,77 @@ +// 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 + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print simple +// check:$1 = {x = 10, y = 20} + +// debugger:print noDestructor +// check:$2 = {a = {x = 10, y = 20}, guard = -1} + +// debugger:print withDestructor +// check:$3 = {a = {x = 10, y = 20}, guard = -1} + +struct NoDestructor { + x : i32, + y : i64 +} + +struct WithDestructor { + x : i32, + y : i64 +} + +impl Drop for WithDestructor { + fn finalize(&self) {} +} + +struct NoDestructorGuarded +{ + a: NoDestructor, + guard: i64 +} + +struct WithDestructorGuarded +{ + a: WithDestructor, + guard: i64 +} + + +// The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used +// at runtime to prevent finalize() to be executed more than once (see middle::trans::adt). +// This field must be incorporated by the debug info generation. Otherwise the debugger assumes a +// wrong size/layout for the struct. +fn main() { + + let simple = WithDestructor { x: 10, y: 20 }; + + let noDestructor = NoDestructorGuarded { + a: NoDestructor { x: 10, y: 20 }, + guard: -1 + }; + + // If the destructor flag field is not incorporated into the debug info for 'WithDestructor' + // then the debugger will have an invalid offset for the field 'guard' and thus should not be + // able to read its value correctly. + let withDestructor = WithDestructorGuarded { + a: WithDestructor { x: 10, y: 20 }, + guard: -1 + }; + + zzz(); +} + +fn zzz() {()} From 46d28c874ccb342e6b8f7fa45f7927bcde2f396e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 15:55:33 +0200 Subject: [PATCH 200/336] debuginfo: Replaced many instances of @ with &. --- src/librustc/middle/trans/debuginfo.rs | 45 +++++++++++++------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 0a1f2d1fe241..a0ba0667f4b4 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -370,7 +370,7 @@ fn create_compile_unit(cx: @mut CrateContext) { }}}}}}; } -fn create_file(cx: @mut CrateContext, full_path: &str) -> DIFile { +fn create_file(cx: &mut CrateContext, full_path: &str) -> DIFile { match dbg_cx(cx).created_files.find_equiv(&full_path) { Some(file_md) => return *file_md, None => () @@ -440,7 +440,7 @@ fn create_block(bcx: block) -> DILexicalBlock { -fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { +fn create_basic_type(cx: &mut CrateContext, t: ty::t, _span: span) -> DIType { let ty_id = ty::type_id(t); match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -492,7 +492,7 @@ fn create_basic_type(cx: @mut CrateContext, t: ty::t, _span: span) -> DIType { return ty_md; } -fn create_pointer_type(cx: @mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { +fn create_pointer_type(cx: &mut CrateContext, t: ty::t, _span: span, pointee: DIType) -> DIType { let (size, align) = size_and_align_of(cx, t); let name = ty_to_str(cx.tcx, t); let ptr_md = do as_c_str(name) |name| { unsafe { @@ -517,9 +517,9 @@ struct StructContext { } impl StructContext { - fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> ~StructContext { + fn new(cx: &CrateContext, name: ~str, file: DIFile, line: uint) -> StructContext { debug!("StructContext::create: %s", name); - let scx = ~StructContext { + return StructContext { builder: DIB(cx), file: file, name: name, @@ -528,7 +528,6 @@ impl StructContext { total_size: 0, align: 1 }; - return scx; } fn add_member(&mut self, name: &str, line: uint, size: uint, align: uint, ty: DIType) { @@ -569,17 +568,19 @@ impl StructContext { // let size_with_alignment = self.get_total_size_with_alignment(); // if st.size != size_with_alignment { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type size. Expected = %u, actual = %u", + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: + // invalid type size. Expected = %u, actual = %u", // st.size, size_with_alignment); // } // if st.align != self.align { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: invalid type alignment. Expected = %u, actual = %u", + // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: + // invalid type alignment. Expected = %u, actual = %u", // st.align, self.align); // } // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: called with invalid type %?", - // self.name, t)) + // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: + // called with invalid type %?", self.name, t)) // } //} @@ -613,14 +614,14 @@ impl StructContext { } } -fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) +fn create_struct(cx: &mut CrateContext, struct_type: ty::t, fields: ~[ty::field], span: span) -> DICompositeType { debug!("create_struct: %?", ty::get(struct_type)); let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, t), file_md, loc.line); + let mut scx = StructContext::new(cx, ty_to_str(cx.tcx, struct_type), file_md, loc.line); for fields.iter().advance |field| { let field_t = field.mt.ty; let ty_md = create_ty(cx, field_t, span); @@ -631,7 +632,7 @@ fn create_struct(cx: @mut CrateContext, struct_type: ty::t, fields: ~[ty::field] } // returns (void* type as a ValueRef, size in bytes, align in bytes) -fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { +fn voidptr(cx: &mut CrateContext) -> (DIDerivedType, uint, uint) { let size = sys::size_of::(); let align = sys::min_align_of::(); let vp = do as_c_str("*void") |name| { unsafe { @@ -645,7 +646,7 @@ fn voidptr(cx: @mut CrateContext) -> (DIDerivedType, uint, uint) { return (vp, size, align); } -fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) +fn create_tuple(cx: &mut CrateContext, tuple_type: ty::t, elements: &[ty::t], span: span) -> DICompositeType { debug!("create_tuple: %?", ty::get(tuple_type)); @@ -662,7 +663,7 @@ fn create_tuple(cx: @mut CrateContext, tuple_type: ty::t, elements: &[ty::t], sp return scx.finalize(); } -fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, +fn create_boxed_type(cx: &mut CrateContext, contents: ty::t, span: span, boxed: DIType) -> DICompositeType { debug!("create_boxed_type: %?", ty::get(contents)); @@ -686,7 +687,7 @@ fn create_boxed_type(cx: @mut CrateContext, contents: ty::t, return scx.finalize(); } -fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, +fn create_fixed_vec(cx: &mut CrateContext, _vec_t: ty::t, elem_t: ty::t, len: uint, span: span) -> DIType { debug!("create_fixed_vec: %?", ty::get(_vec_t)); @@ -708,7 +709,7 @@ fn create_fixed_vec(cx: @mut CrateContext, _vec_t: ty::t, elem_t: ty::t, }; } -fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, +fn create_boxed_vec(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, vec_ty_span: span) -> DICompositeType { debug!("create_boxed_vec: %?", ty::get(vec_t)); @@ -778,7 +779,7 @@ fn create_boxed_vec(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, return mdval; } -fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) +fn create_vec_slice(cx: &mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: span) -> DICompositeType { debug!("create_vec_slice: %?", ty::get(vec_t)); @@ -795,7 +796,7 @@ fn create_vec_slice(cx: @mut CrateContext, vec_t: ty::t, elem_t: ty::t, span: sp return scx.finalize(); } -fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, +fn create_fn_ty(cx: &mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: ty::t, span: span) -> DICompositeType { debug!("create_fn_ty: %?", ty::get(_fn_ty)); @@ -815,7 +816,7 @@ fn create_fn_ty(cx: @mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output: }; } -fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { +fn create_unimpl_ty(cx: &mut CrateContext, t: ty::t) -> DIType { debug!("create_unimpl_ty: %?", ty::get(t)); let name = ty_to_str(cx.tcx, t); @@ -830,7 +831,7 @@ fn create_unimpl_ty(cx: @mut CrateContext, t: ty::t) -> DIType { return md; } -fn create_ty(cx: @mut CrateContext, t: ty::t, span: span) -> DIType { +fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType { let ty_id = ty::type_id(t); match dbg_cx(cx).created_types.find(&ty_id) { Some(ty_md) => return *ty_md, @@ -951,7 +952,7 @@ fn span_start(cx: &CrateContext, span: span) -> codemap::Loc { cx.sess.codemap.lookup_char_pos(span.lo) } -fn size_and_align_of(cx: @mut CrateContext, t: ty::t) -> (uint, uint) { +fn size_and_align_of(cx: &mut CrateContext, t: ty::t) -> (uint, uint) { let llty = type_of::type_of(cx, t); (machine::llsize_of_real(cx, llty), machine::llalign_of_min(cx, llty)) } From 6af78610e745f68b8eb3e107bdb1e4b2288c617c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:17:19 +0200 Subject: [PATCH 201/336] debuginfo: Added support for region pointers. --- src/librustc/middle/trans/debuginfo.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a0ba0667f4b4..b1434bb798a9 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -886,9 +886,9 @@ fn create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType { let pointee = create_ty(cx, mt.ty, span); create_pointer_type(cx, t, span, pointee) }, - ty::ty_rptr(ref _region, ref _mt) => { - cx.sess.span_note(span, "debuginfo for rptr NYI"); - create_unimpl_ty(cx, t) + ty::ty_rptr(_, ref mt) => { + let pointee = create_ty(cx, mt.ty, span); + create_pointer_type(cx, t, span, pointee) }, ty::ty_bare_fn(ref barefnty) => { let inputs = barefnty.sig.inputs.map(|a| *a); From 751f0fba6fe9df4003cd18e95c8438e2cf742f9a Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:18:10 +0200 Subject: [PATCH 202/336] debuginfo: Added test case for region pointers pointing to stack values with basic type. --- src/test/debug-info/reference-to-basic.rs | 116 ++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/debug-info/reference-to-basic.rs diff --git a/src/test/debug-info/reference-to-basic.rs b/src/test/debug-info/reference-to-basic.rs new file mode 100644 index 000000000000..dfd0fbf86555 --- /dev/null +++ b/src/test/debug-info/reference-to-basic.rs @@ -0,0 +1,116 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values) +// as its numerical value along with its associated ASCII char, there +// doesn't seem to be any way around this. Also, gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print *i8_ref +// check:$4 = 68 'D' + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print *u8_ref +// check:$9 = 100 'd' + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + +fn main() { + let bool_val: bool = true; + let bool_ref : &bool = &bool_val; + + let int_val: int = -1; + let int_ref : &int = &int_val; + + let char_val: char = 'a'; + let char_ref : &char = &char_val; + + let i8_val: i8 = 68; + let i8_ref : &i8 = &i8_val; + + let i16_val: i16 = -16; + let i16_ref : &i16 = &i16_val; + + let i32_val: i32 = -32; + let i32_ref : &i32 = &i32_val; + + let uint_val: i64 = -64; + let i64_ref : &i64 = &uint_val; + + let uint_val: uint = 1; + let uint_ref : &uint = &uint_val; + + let u8_val: u8 = 100; + let u8_ref : &u8 = &u8_val; + + let u16_val: u16 = 16; + let u16_ref : &u16 = &u16_val; + + let u32_val: u32 = 32; + let u32_ref : &u32 = &u32_val; + + let u64_val: u64 = 64; + let u64_ref : &u64 = &u64_val; + + let float_val: float = 1.5; + let float_ref : &float = &float_val; + + let f32_val: f32 = 2.5; + let f32_ref : &f32 = &f32_val; + + let f64_val: f64 = 3.5; + let f64_ref : &f64 = &f64_val; + zzz(); +} + +fn zzz() {()} \ No newline at end of file From fb3e17b93a7a9824459ca9a7fb0d8a638016f6fa Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:47:21 +0200 Subject: [PATCH 203/336] debuginfo: Added test cases for region pointers into heap boxes for basic types. --- .../debug-info/reference-to-managed-basic.rs | 115 ++++++++++++++++++ .../debug-info/reference-to-unique-basic.rs | 115 ++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 src/test/debug-info/reference-to-managed-basic.rs create mode 100644 src/test/debug-info/reference-to-unique-basic.rs diff --git a/src/test/debug-info/reference-to-managed-basic.rs b/src/test/debug-info/reference-to-managed-basic.rs new file mode 100644 index 000000000000..b93b2cee2d27 --- /dev/null +++ b/src/test/debug-info/reference-to-managed-basic.rs @@ -0,0 +1,115 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print/d *i8_ref +// check:$4 = 68 + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print/d *u8_ref +// check:$9 = 100 + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + + +fn main() { + let bool_box: @bool = @true; + let bool_ref : &bool = bool_box; + + let int_box: @int = @-1; + let int_ref : &int = int_box; + + let char_box: @char = @'a'; + let char_ref : &char = char_box; + + let i8_box: @i8 = @68; + let i8_ref : &i8 = i8_box; + + let i16_box: @i16 = @-16; + let i16_ref : &i16 = i16_box; + + let i32_box: @i32 = @-32; + let i32_ref : &i32 = i32_box; + + let i64_box: @i64 = @-64; + let i64_ref : &i64 = i64_box; + + let uint_box: @uint = @1; + let uint_ref : &uint = uint_box; + + let u8_box: @u8 = @100; + let u8_ref : &u8 = u8_box; + + let u16_box: @u16 = @16; + let u16_ref : &u16 = u16_box; + + let u32_box: @u32 = @32; + let u32_ref : &u32 = u32_box; + + let u64_box: @u64 = @64; + let u64_ref : &u64 = u64_box; + + let float_box: @float = @1.5; + let float_ref : &float = float_box; + + let f32_box: @f32 = @2.5; + let f32_ref : &f32 = f32_box; + + let f64_box: @f64 = @3.5; + let f64_ref : &f64 = f64_box; + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/reference-to-unique-basic.rs b/src/test/debug-info/reference-to-unique-basic.rs new file mode 100644 index 000000000000..ce5b50459f66 --- /dev/null +++ b/src/test/debug-info/reference-to-unique-basic.rs @@ -0,0 +1,115 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// Gdb doesn't know +// about UTF-32 character encoding and will print a rust char as only +// its numerical value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish +// debugger:print *bool_ref +// check:$1 = true + +// debugger:print *int_ref +// check:$2 = -1 + +// debugger:print *char_ref +// check:$3 = 97 + +// debugger:print/d *i8_ref +// check:$4 = 68 + +// debugger:print *i16_ref +// check:$5 = -16 + +// debugger:print *i32_ref +// check:$6 = -32 + +// debugger:print *i64_ref +// check:$7 = -64 + +// debugger:print *uint_ref +// check:$8 = 1 + +// debugger:print/d *u8_ref +// check:$9 = 100 + +// debugger:print *u16_ref +// check:$10 = 16 + +// debugger:print *u32_ref +// check:$11 = 32 + +// debugger:print *u64_ref +// check:$12 = 64 + +// debugger:print *float_ref +// check:$13 = 1.5 + +// debugger:print *f32_ref +// check:$14 = 2.5 + +// debugger:print *f64_ref +// check:$15 = 3.5 + + +fn main() { + let bool_box: ~bool = ~true; + let bool_ref : &bool = bool_box; + + let int_box: ~int = ~-1; + let int_ref : &int = int_box; + + let char_box: ~char = ~'a'; + let char_ref : &char = char_box; + + let i8_box: ~i8 = ~68; + let i8_ref : &i8 = i8_box; + + let i16_box: ~i16 = ~-16; + let i16_ref : &i16 = i16_box; + + let i32_box: ~i32 = ~-32; + let i32_ref : &i32 = i32_box; + + let i64_box: ~i64 = ~-64; + let i64_ref : &i64 = i64_box; + + let uint_box: ~uint = ~1; + let uint_ref : &uint = uint_box; + + let u8_box: ~u8 = ~100; + let u8_ref : &u8 = u8_box; + + let u16_box: ~u16 = ~16; + let u16_ref : &u16 = u16_box; + + let u32_box: ~u32 = ~32; + let u32_ref : &u32 = u32_box; + + let u64_box: ~u64 = ~64; + let u64_ref : &u64 = u64_box; + + let float_box: ~float = ~1.5; + let float_ref : &float = float_box; + + let f32_box: ~f32 = ~2.5; + let f32_ref : &f32 = f32_box; + + let f64_box: ~f64 = ~3.5; + let f64_ref : &f64 = f64_box; + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 6a3094159fc50c062e55e76379b402b4a5d5270d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 24 Jun 2013 17:52:22 +0200 Subject: [PATCH 204/336] debuginfo: Fixed some instances of gdb wrongly printing u8/i8 values as chars. --- src/test/debug-info/basic-types.rs | 8 ++++---- src/test/debug-info/simple-tuple.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/debug-info/basic-types.rs b/src/test/debug-info/basic-types.rs index 616740c850c5..7125ebe8d564 100644 --- a/src/test/debug-info/basic-types.rs +++ b/src/test/debug-info/basic-types.rs @@ -26,8 +26,8 @@ // check:$2 = -1 // debugger:print c // check:$3 = 97 -// debugger:print i8 -// check:$4 = 68 'D' +// debugger:print/d i8 +// check:$4 = 68 // debugger:print i16 // check:$5 = -16 // debugger:print i32 @@ -36,8 +36,8 @@ // check:$7 = -64 // debugger:print u // check:$8 = 1 -// debugger:print u8 -// check:$9 = 100 'd' +// debugger:print/d u8 +// check:$9 = 100 // debugger:print u16 // check:$10 = 16 // debugger:print u32 diff --git a/src/test/debug-info/simple-tuple.rs b/src/test/debug-info/simple-tuple.rs index 6193e58969f1..84c736fab6b0 100644 --- a/src/test/debug-info/simple-tuple.rs +++ b/src/test/debug-info/simple-tuple.rs @@ -16,8 +16,8 @@ // debugger:run // debugger:finish -// debugger:print noPadding8 -// check:$1 = {-100 '\234', 100 'd'} +// debugger:print/d noPadding8 +// check:$1 = {-100, 100} // debugger:print noPadding16 // check:$2 = {0, 1, 2} // debugger:print noPadding32 From 9102ad035c2e61066d6fb85c2be80afc5860e043 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:53:15 +0200 Subject: [PATCH 205/336] debuginfo: Added more tests for region pointers (tuples, structs). --- src/test/debug-info/reference-to-struct.rs | 78 ++++++++++++++++++++++ src/test/debug-info/reference-to-tuple.rs | 47 +++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/test/debug-info/reference-to-struct.rs create mode 100644 src/test/debug-info/reference-to-tuple.rs diff --git a/src/test/debug-info/reference-to-struct.rs b/src/test/debug-info/reference-to-struct.rs new file mode 100644 index 000000000000..f00872c00b0e --- /dev/null +++ b/src/test/debug-info/reference-to-struct.rs @@ -0,0 +1,78 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print *stack_val_ref +// check:$1 = {x = 10, y = 23.5} + +// debugger:print *stack_val_interior_ref_1 +// check:$2 = 10 + +// debugger:print *stack_val_interior_ref_2 +// check:$3 = 23.5 + +// debugger:print *ref_to_unnamed +// check:$4 = {x = 11, y = 24.5} + +// debugger:print *managed_val_ref +// check:$5 = {x = 12, y = 25.5} + +// debugger:print *managed_val_interior_ref_1 +// check:$6 = 12 + +// debugger:print *managed_val_interior_ref_2 +// check:$7 = 25.5 + +// debugger:print *unique_val_ref +// check:$8 = {x = 13, y = 26.5} + +// debugger:print *unique_val_interior_ref_1 +// check:$9 = 13 + +// debugger:print *unique_val_interior_ref_2 +// check:$10 = 26.5 + + + +struct SomeStruct { + x: int, + y: f64 +} + +fn main() { + let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 }; + let stack_val_ref : &SomeStruct = &stack_val; + let stack_val_interior_ref_1 : &int = &stack_val.x; + let stack_val_interior_ref_2 : &f64 = &stack_val.y; + let ref_to_unnamed : &SomeStruct = &SomeStruct { x: 11, y: 24.5 }; + + let managed_val = @SomeStruct { x: 12, y: 25.5 }; + let managed_val_ref : &SomeStruct = managed_val; + let managed_val_interior_ref_1 : &int = &managed_val.x; + let managed_val_interior_ref_2 : &f64 = &managed_val.y; + + let unique_val = ~SomeStruct { x: 13, y: 26.5 }; + let unique_val_ref : &SomeStruct = unique_val; + let unique_val_interior_ref_1 : &int = &unique_val.x; + let unique_val_interior_ref_2 : &f64 = &unique_val.y; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file diff --git a/src/test/debug-info/reference-to-tuple.rs b/src/test/debug-info/reference-to-tuple.rs new file mode 100644 index 000000000000..86d02185bdae --- /dev/null +++ b/src/test/debug-info/reference-to-tuple.rs @@ -0,0 +1,47 @@ +// 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-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print *stack_val_ref +// check:$1 = {-14, -19} + +// debugger:print *ref_to_unnamed +// check:$2 = {-15, -20} + +// debugger:print *managed_val_ref +// check:$3 = {-16, -21} + +// debugger:print *unique_val_ref +// check:$4 = {-17, -22} + +fn main() { + let stack_val: (i16, f32) = (-14, -19f32); + let stack_val_ref : &(i16, f32) = &stack_val; + let ref_to_unnamed : &(i16, f32) = &(-15, -20f32); + + let managed_val : @(i16, f32) = @(-16, -21f32); + let managed_val_ref : &(i16, f32) = managed_val; + + let unique_val: ~(i16, f32) = ~(-17, -22f32); + let unique_val_ref : &(i16, f32) = unique_val; + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 074e0fa2a95d9cc723c9c952cf6dc5e7daed574d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:54:03 +0200 Subject: [PATCH 206/336] debuginfo: Added test case for local variables declared with destructuring. --- src/test/debug-info/destructured-local.rs | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/debug-info/destructured-local.rs diff --git a/src/test/debug-info/destructured-local.rs b/src/test/debug-info/destructured-local.rs new file mode 100644 index 000000000000..bf53d95b588d --- /dev/null +++ b/src/test/debug-info/destructured-local.rs @@ -0,0 +1,33 @@ +// 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 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print a +// check:$1 = 9898 + +// debugger:print b +// check:$2 = false + +fn main() { + let (a, b) : (int, bool) = (9898, false); + + zzz(); +} + +fn zzz() {()} \ No newline at end of file From 4fb471ab7828e31c29054b76217c42917c4206c5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 25 Jun 2013 21:55:02 +0200 Subject: [PATCH 207/336] debuginfo: Added test case for function arguments. --- src/test/debug-info/function-arguments.rs | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/debug-info/function-arguments.rs diff --git a/src/test/debug-info/function-arguments.rs b/src/test/debug-info/function-arguments.rs new file mode 100644 index 000000000000..f5563cda259e --- /dev/null +++ b/src/test/debug-info/function-arguments.rs @@ -0,0 +1,51 @@ +// 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 + +// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical +// value. + +// compile-flags:-Z extra-debug-info +// debugger:break zzz +// debugger:run +// debugger:finish + +// debugger:print x +// check:$1 = 111102 +// debugger:print y +// check:$2 = true + +// debugger:continue +// debugger:finish + +// debugger:print a +// check:$3 = 2000 +// debugger:print b +// check:$4 = 3000 + +fn main() { + + fun(111102, true); + nested(2000, 3000); + + fn nested(a: i32, b: i64) -> (i32, i64) { + zzz() + (a, b) + } +} + +fn fun(x: int, y: bool) -> (int, bool) { + zzz(); + + (x, y) +} + +fn zzz() {()} \ No newline at end of file From 42dbae7f2a7dbdc414646e706eeffacdf7d4b338 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 26 Jun 2013 22:17:45 +0200 Subject: [PATCH 208/336] debuginfo: Formatting cleanup. --- src/test/debug-info/struct-in-struct.rs | 24 +++++++------------ src/test/debug-info/struct-with-destructor.rs | 6 ++--- src/test/debug-info/variable-scope.rs | 4 ++-- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/test/debug-info/struct-in-struct.rs b/src/test/debug-info/struct-in-struct.rs index cfd8c24caa21..04c5eec610b7 100644 --- a/src/test/debug-info/struct-in-struct.rs +++ b/src/test/debug-info/struct-in-struct.rs @@ -111,20 +111,15 @@ fn main() { }; let bag = Bag { x: Simple { x: 22 } }; - let bag_in_bag = BagInBag - { - x: Bag - { + let bag_in_bag = BagInBag { + x: Bag { x: Simple { x: 23 } } }; - let tjo = ThatsJustOverkill - { - x: BagInBag - { - x: Bag - { + let tjo = ThatsJustOverkill { + x: BagInBag { + x: Bag { x: Simple { x: 24 } } } @@ -132,16 +127,13 @@ fn main() { let tree = Tree { x: Simple { x: 25 }, - y: InternalPaddingParent - { + y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, - z: BagInBag - { - x: Bag - { + z: BagInBag { + x: Bag { x: Simple { x: 32 } } } diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs index b5ae4bbe8fba..c023e3c2ccbd 100644 --- a/src/test/debug-info/struct-with-destructor.rs +++ b/src/test/debug-info/struct-with-destructor.rs @@ -37,14 +37,12 @@ impl Drop for WithDestructor { fn finalize(&self) {} } -struct NoDestructorGuarded -{ +struct NoDestructorGuarded { a: NoDestructor, guard: i64 } -struct WithDestructorGuarded -{ +struct WithDestructorGuarded { a: WithDestructor, guard: i64 } diff --git a/src/test/debug-info/variable-scope.rs b/src/test/debug-info/variable-scope.rs index a9177ac19664..dd3a1671b785 100644 --- a/src/test/debug-info/variable-scope.rs +++ b/src/test/debug-info/variable-scope.rs @@ -19,12 +19,12 @@ // debugger:print y // check:$2 = true -// debugger:run +// debugger:continue // debugger:finish // debugger:print x // check:$3 = 10 -// debugger:run +// debugger:continue // debugger:finish // debugger:print x // check:$4 = false From 2f5e33d02f0103a40de2493f824627effaedc6e0 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 27 Jun 2013 19:27:06 +0200 Subject: [PATCH 209/336] debuginfo: Some corrections after review. --- src/librustc/middle/trans/debuginfo.rs | 25 ------------------- .../debug-info/reference-to-managed-basic.rs | 3 +-- src/test/debug-info/struct-with-destructor.rs | 17 +++++++++++-- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index b1434bb798a9..a42f20ea39ca 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -559,31 +559,6 @@ impl StructContext { roundup(self.total_size, self.align) } - //fn verify_against_struct_or_tuple_type(&self, t: ty::t, ccx: &mut CrateContext) { - // let repr = adt::represent_type(ccx, t); - - // match *repr { - // Univariant(*) => - // { - // let size_with_alignment = self.get_total_size_with_alignment(); - - // if st.size != size_with_alignment { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: - // invalid type size. Expected = %u, actual = %u", - // st.size, size_with_alignment); - // } - - // if st.align != self.align { - // ccx.sess.bug("StructContext(%s)::verify_against_struct_or_tuple_type: - // invalid type alignment. Expected = %u, actual = %u", - // st.align, self.align); - // } - // }, - // _ => ccx.sess.bug(fmt!("StructContext(%s)::verify_against_struct_or_tuple_type: - // called with invalid type %?", self.name, t)) - // } - //} - fn finalize(&self) -> DICompositeType { debug!("StructContext(%s)::finalize: total_size=%u, align=%u", self.name, self.total_size, self.align); diff --git a/src/test/debug-info/reference-to-managed-basic.rs b/src/test/debug-info/reference-to-managed-basic.rs index b93b2cee2d27..e3951c94b6f8 100644 --- a/src/test/debug-info/reference-to-managed-basic.rs +++ b/src/test/debug-info/reference-to-managed-basic.rs @@ -10,8 +10,7 @@ // xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249 -// Gdb doesn't know -// about UTF-32 character encoding and will print a rust char as only +// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only // its numerical value. // compile-flags:-Z extra-debug-info diff --git a/src/test/debug-info/struct-with-destructor.rs b/src/test/debug-info/struct-with-destructor.rs index c023e3c2ccbd..f8281bba49e9 100644 --- a/src/test/debug-info/struct-with-destructor.rs +++ b/src/test/debug-info/struct-with-destructor.rs @@ -49,7 +49,7 @@ struct WithDestructorGuarded { // The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used -// at runtime to prevent finalize() to be executed more than once (see middle::trans::adt). +// at runtime to prevent drop() to be executed more than once (see middle::trans::adt). // This field must be incorporated by the debug info generation. Otherwise the debugger assumes a // wrong size/layout for the struct. fn main() { @@ -63,7 +63,20 @@ fn main() { // If the destructor flag field is not incorporated into the debug info for 'WithDestructor' // then the debugger will have an invalid offset for the field 'guard' and thus should not be - // able to read its value correctly. + // able to read its value correctly (dots are padding bytes, D is the boolean destructor flag): + // + // NoDestructorGuarded = 0000....00000000FFFFFFFF + // <--------------><------> + // NoDestructor guard + // + // + // withDestructorGuarded = 0000....00000000D.......FFFFFFFF + // <--------------><------> // How debug info says it is + // WithDestructor guard + // + // <----------------------><------> // How it actually is + // WithDestructor guard + // let withDestructor = WithDestructorGuarded { a: WithDestructor { x: 10, y: 20 }, guard: -1 From d9fed2b06f0850fa9e2455e98606644d5d54757f Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Thu, 27 Jun 2013 13:37:55 -0700 Subject: [PATCH 210/336] Teach extra::term::Terminal.reset() to handle missing op Unlike fg() and bg(), we haven't already checked for the presence of "op" in the terminfo when we call reset(), so we need to handle the case where it's missing. Also update the warn!() lines to avoid double-quoting the output. Fixes #7431. --- src/libextra/term.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 9a4469cb5265..880b89f2bbe1 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -97,7 +97,7 @@ impl Terminal { if s.is_ok() { self.out.write(s.unwrap()); } else { - warn!(s.unwrap_err()); + warn!("%s", s.unwrap_err()); } } } @@ -113,17 +113,20 @@ impl Terminal { if s.is_ok() { self.out.write(s.unwrap()); } else { - warn!(s.unwrap_err()); + warn!("%s", s.unwrap_err()); } } } pub fn reset(&self) { let mut vars = Variables::new(); - let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars); + let s = do self.ti.strings.find_equiv(&("op")) + .map_consume_default(Err(~"can't find op")) |&op| { + expand(op, [], &mut vars) + }; if s.is_ok() { self.out.write(s.unwrap()); } else { - warn!(s.unwrap_err()); + warn!("%s", s.unwrap_err()); } } From 3dfbc5a9c49d65295bf96ce435a29df72e03c09e Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 27 Jun 2013 16:27:13 -0700 Subject: [PATCH 211/336] rustpkg: Silence extra output from rustpkg tests Closes #7250 --- src/librustpkg/tests.rs | 4 ++-- src/librustpkg/util.rs | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index afeb64075335..8b72b08e6fe9 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -144,10 +144,10 @@ fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput { err_fd: None }); let output = prog.finish_with_output(); - io::println(fmt!("Output from command %s with args %? was %s {%s}[%?]", + debug!("Output from command %s with args %? was %s {%s}[%?]", cmd, args, str::from_bytes(output.output), str::from_bytes(output.error), - output.status)); + output.status); /* By the way, rustpkg *won't* return a nonzero exit code if it fails -- see #4547 diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 38e6a4824afc..cb9bbf80ea8f 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -187,7 +187,7 @@ pub fn compile_input(ctxt: &Ctx, Lib => lib_crate, Test | Bench | Main => bin_crate }; - let matches = getopts(~[~"-Z", ~"time-passes"] + let matches = getopts(debug_flags() + match what { Lib => ~[~"--lib"], // --test compiles both #[test] and #[bench] fns @@ -415,3 +415,7 @@ mod test { } } + +// tjc: cheesy +fn debug_flags() -> ~[~str] { ~[] } +// static debug_flags: ~[~str] = ~[~"-Z", ~"time-passes"]; \ No newline at end of file From 76b910d8cca5535774cc94637dc6b7e1fda6de1c Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 27 Jun 2013 16:53:40 -0700 Subject: [PATCH 212/336] testsuite: Add test cases, some xfailed Closes #5060 Closes #4446 Closes #5192 --- src/test/compile-fail/issue-5060-fail.rs | 29 ++++++++++++++++ src/test/run-pass/issue-4446.rs | 21 +++++++++++ src/test/run-pass/issue-5060.rs | 28 +++++++++++++++ src/test/run-pass/issue-5192.rs | 44 ++++++++++++++++++++++++ src/test/run-pass/issue-5280.rs | 27 +++++++++++++++ 5 files changed, 149 insertions(+) create mode 100644 src/test/compile-fail/issue-5060-fail.rs create mode 100644 src/test/run-pass/issue-4446.rs create mode 100644 src/test/run-pass/issue-5060.rs create mode 100644 src/test/run-pass/issue-5192.rs create mode 100644 src/test/run-pass/issue-5280.rs diff --git a/src/test/compile-fail/issue-5060-fail.rs b/src/test/compile-fail/issue-5060-fail.rs new file mode 100644 index 000000000000..c1795d31485f --- /dev/null +++ b/src/test/compile-fail/issue-5060-fail.rs @@ -0,0 +1,29 @@ +// 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. + + +use std::io; + +macro_rules! print_hd_tl ( + ($field_hd:ident, $($field_tl:ident),+) => ({ + io::print(stringify!($field)); //~ ERROR unknown macro variable + io::print("::["); + $( + io::print(stringify!($field_tl)); + io::print(", "); + )+ + io::print("]\n"); + }) +) + +fn main() { + print_hd_tl!(x, y, z, w) +} + diff --git a/src/test/run-pass/issue-4446.rs b/src/test/run-pass/issue-4446.rs new file mode 100644 index 000000000000..2f44f9783e16 --- /dev/null +++ b/src/test/run-pass/issue-4446.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. + +use std::{pipes, io, task, comm}; + +fn main() { + let (port, chan) = comm::stream(); + + do task::spawn { + io::println(port.recv()); + } + + chan.send("hello, world"); +} diff --git a/src/test/run-pass/issue-5060.rs b/src/test/run-pass/issue-5060.rs new file mode 100644 index 000000000000..0922f555beaa --- /dev/null +++ b/src/test/run-pass/issue-5060.rs @@ -0,0 +1,28 @@ +// 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. + +use std::io; + +macro_rules! print_hd_tl ( + ($field_hd:ident, $($field_tl:ident),+) => ({ + io::print(stringify!($field_hd)); + io::print("::["); + $( + io::print(stringify!($field_tl)); + io::print(", "); + )+ + io::print("]\n"); + }) +) + +fn main() { + print_hd_tl!(x, y, z, w) +} + diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs new file mode 100644 index 000000000000..d5a1a779d45e --- /dev/null +++ b/src/test/run-pass/issue-5192.rs @@ -0,0 +1,44 @@ +// 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. + +pub trait EventLoop { +} + +pub struct UvEventLoop { + uvio: int +} + +impl UvEventLoop { + pub fn new() -> UvEventLoop { + UvEventLoop { + uvio: 0 + } + } +} + +impl EventLoop for UvEventLoop { +} + +pub struct Scheduler { + event_loop: ~EventLoop, +} + +impl Scheduler { + + pub fn new(event_loop: ~EventLoop) -> Scheduler { + Scheduler { + event_loop: event_loop, + } + } +} + +fn main() { + let mut sched = Scheduler::new(~UvEventLoop::new() as ~EventLoop); +} diff --git a/src/test/run-pass/issue-5280.rs b/src/test/run-pass/issue-5280.rs new file mode 100644 index 000000000000..72bf0cee05d2 --- /dev/null +++ b/src/test/run-pass/issue-5280.rs @@ -0,0 +1,27 @@ +// 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 + +type FontTableTag = u32; + +trait FontTableTagConversions { + fn tag_to_str(self); +} + +impl FontTableTagConversions for FontTableTag { + fn tag_to_str(self) { + &self; + } +} + +fn main() { + 5.tag_to_str(); +} From 9591832112cb1fa1553bb6d1057bcc53bf4074cd Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 27 Jun 2013 17:10:07 -0700 Subject: [PATCH 213/336] mk: add mechanisms for triggering clean-llvm builds from commits --- Makefile.in | 11 ++++++++++- mk/clean.mk | 2 +- src/rustllvm/llvm-auto-clean-trigger | 0 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/rustllvm/llvm-auto-clean-trigger diff --git a/Makefile.in b/Makefile.in index 0404e2bdee6c..7d1d8c7996d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -536,10 +536,19 @@ ALL_TARGET_RULES = $(foreach target,$(CFG_TARGET_TRIPLES), \ $(foreach host,$(CFG_HOST_TRIPLES), \ all-target-$(target)-host-$(host))) -all: $(ALL_TARGET_RULES) $(GENERATED) docs +all: rustllvm/llvm-auto-clean-stamp \ + $(ALL_TARGET_RULES) $(GENERATED) docs endif +# This is used to independently force an LLVM clean rebuild +# when we changed something not otherwise captured by builtin +# dependencies. In these cases, commit a change that touches +# the stamp in the source dir. +rustllvm/llvm-auto-clean-stamp: $(S)src/rustllvm/llvm-auto-clean-trigger + $(Q)$(MAKE) clean-llvm + touch $@ + ###################################################################### # Re-configuration diff --git a/mk/clean.mk b/mk/clean.mk index 23efbb3ee15c..32dd3902b1fe 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -23,7 +23,7 @@ CLEAN_LLVM_RULES = \ $(foreach target, $(CFG_TARGET_TRIPLES), \ clean-llvm$(target)) -.PHONY: clean clean-all clean-misc +.PHONY: clean clean-all clean-misc clean-llvm clean-all: clean clean-llvm diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger new file mode 100644 index 000000000000..e69de29bb2d1 From 767374976b71965415ada45cf8e7d9da5ddef43f Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 24 May 2013 15:33:46 -0400 Subject: [PATCH 214/336] librustc: Always pass self ByRef. --- src/librustc/middle/trans/asm.rs | 3 ++ src/librustc/middle/trans/base.rs | 24 ++++++---------- src/librustc/middle/trans/callee.rs | 33 ++++++++++++++++++---- src/librustc/middle/trans/meth.rs | 8 ++++-- src/librustc/middle/typeck/check/method.rs | 11 ++------ 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 3c263b1c01eb..7d0defde4354 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -41,6 +41,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, out), ty::ByCopy, + ast::sty_static, out, &mut cleanups, None, @@ -56,6 +57,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, e), ty::ByCopy, + ast::sty_static, e, &mut cleanups, None, @@ -77,6 +79,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, in), ty::ByCopy, + ast::sty_static, in, &mut cleanups, None, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a0628bc8e87c..6ab228cc1726 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1680,23 +1680,15 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, let mut bcx = bcx; match fcx.llself { - Some(slf) => { - let self_val = if slf.is_owned - && datum::appropriate_mode(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); - alloc - } else { - PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) - }; + Some(slf) => { + let self_val = PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()); + fcx.llself = Some(ValSelfData {v: self_val, ..slf}); - fcx.llself = Some(ValSelfData {v: self_val, ..slf}); - if slf.is_owned { - add_clean(bcx, self_val, slf.t); - } - } - _ => {} + if slf.is_owned { + add_clean(bcx, slf.v, slf.t); + } + } + _ => {} } for uint::range(0, arg_tys.len()) |arg_n| { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 064a457c7127..78c796329d80 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -63,6 +63,7 @@ pub struct MethodData { llself: ValueRef, self_ty: ty::t, self_mode: ty::SelfMode, + explicit_self: ast::explicit_self_ } pub enum CalleeData { @@ -565,7 +566,8 @@ pub fn trans_call_inner(in_cx: block, // Now that the arguments have finished evaluating, we need to revoke // the cleanup for the self argument, if it exists match callee.data { - Method(d) if d.self_mode == ty::ByCopy => { + Method(d) if d.self_mode == ty::ByCopy || + d.explicit_self == ast::sty_value => { revoke_clean(bcx, d.llself); } _ => {} @@ -687,6 +689,7 @@ pub fn trans_args(cx: block, trans_arg_expr(bcx, arg_tys[i], ty::ByCopy, + ast::sty_static, *arg_expr, &mut temp_cleanups, if i == last { ret_flag } else { None }, @@ -720,6 +723,7 @@ pub enum AutorefArg { pub fn trans_arg_expr(bcx: block, formal_arg_ty: ty::t, self_mode: ty::SelfMode, + ex_self: ast::explicit_self_, arg_expr: @ast::expr, temp_cleanups: &mut ~[ValueRef], ret_flag: Option, @@ -727,9 +731,10 @@ pub fn trans_arg_expr(bcx: block, let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); - debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \ + debug!("trans_arg_expr(formal_arg_ty=(%s), explicit_self=%? self_mode=%?, arg_expr=%s, \ ret_flag=%?)", formal_arg_ty.repr(bcx.tcx()), + ex_self, self_mode, arg_expr.repr(bcx.tcx()), ret_flag.map(|v| bcx.val_to_str(*v))); @@ -789,8 +794,26 @@ pub fn trans_arg_expr(bcx: block, val = arg_datum.to_ref_llval(bcx); } DontAutorefArg => { - match self_mode { - ty::ByRef => { + match (self_mode, ex_self) { + (ty::ByRef, ast::sty_value) => { + debug!("by value self with type %s, storing to scratch", + bcx.ty_to_str(arg_datum.ty)); + let scratch = scratch_datum(bcx, arg_datum.ty, false); + + arg_datum.store_to_datum(bcx, + arg_expr.id, + INIT, + scratch); + + // Technically, ownership of val passes to the callee. + // However, we must cleanup should we fail before the + // callee is actually invoked. + scratch.add_clean(bcx); + temp_cleanups.push(scratch.val); + + val = scratch.to_ref_llval(bcx); + } + (ty::ByRef, _) => { // This assertion should really be valid, but because // the explicit self code currently passes by-ref, it // does not hold. @@ -801,7 +824,7 @@ pub fn trans_arg_expr(bcx: block, bcx.ty_to_str(arg_datum.ty)); val = arg_datum.to_ref_llval(bcx); } - ty::ByCopy => { + (ty::ByCopy, _) => { if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || arg_datum.appropriate_mode().is_by_ref() { debug!("by copy arg with type %s, storing to scratch", diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 4f7ce6381d85..80ae2ca135e2 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -110,9 +110,7 @@ pub fn trans_method(ccx: @mut CrateContext, debug!("calling trans_fn with self_ty %s", self_ty.repr(ccx.tcx)); match method.explicit_self.node { - ast::sty_value => { - impl_owned_self(self_ty) - } + ast::sty_value => impl_owned_self(self_ty), _ => { impl_self(self_ty) } @@ -145,6 +143,7 @@ pub fn trans_self_arg(bcx: block, let result = trans_arg_expr(bcx, self_ty, mentry.self_mode, + mentry.explicit_self, base, &mut temp_cleanups, None, @@ -231,6 +230,7 @@ pub fn trans_method_callee(bcx: block, llself: val, self_ty: node_id_type(bcx, this.id), self_mode: mentry.self_mode, + explicit_self: mentry.explicit_self }) } } @@ -453,6 +453,7 @@ pub fn trans_monomorphized_callee(bcx: block, llself: llself_val, self_ty: node_id_type(bcx, base.id), self_mode: mentry.self_mode, + explicit_self: mentry.explicit_self }) } } @@ -692,6 +693,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, llself: llself, self_ty: ty::mk_opaque_box(bcx.tcx()), self_mode: self_mode, + explicit_self: explicit_self /* XXX: Some(llbox) */ }) }; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 777b11186c6f..8c3315e49b45 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -976,7 +976,9 @@ impl<'self> LookupContext<'self> { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty}); debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty)); - let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self); + // FIXME(#7411): We always pass self by-ref since we stuff it in the environment slot. + // Eventually that should not be the case + let self_mode = ty::ByRef; // before we only checked whether self_ty could be a subtype // of rcvr_ty; now we actually make it so (this may cause @@ -1242,10 +1244,3 @@ impl<'self> LookupContext<'self> { self.tcx().sess.bug(s) } } - -pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode { - match explicit_self { - sty_value => ty::ByCopy, - _ => ty::ByRef, - } -} From 0aa94ff3c3419fdd58d87ad226d94ee0128f778b Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 19 Jun 2013 19:49:23 -0400 Subject: [PATCH 215/336] Add test for #5321. --- .../issue-5321-immediates-with-bare-self.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/test/run-pass/issue-5321-immediates-with-bare-self.rs diff --git a/src/test/run-pass/issue-5321-immediates-with-bare-self.rs b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs new file mode 100644 index 000000000000..7b809c39cb83 --- /dev/null +++ b/src/test/run-pass/issue-5321-immediates-with-bare-self.rs @@ -0,0 +1,25 @@ +// 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 Fooable { + fn yes(self); +} + +impl Fooable for uint { + fn yes(self) { + for self.times { + println("yes"); + } + } +} + +fn main() { + 2.yes(); +} From 59905d1f27192797bd5fd81c8ace934955be8a81 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 27 Jun 2013 15:36:05 -0700 Subject: [PATCH 216/336] mk: Make windows installer work with -pre versions --- Makefile.in | 4 ++++ src/etc/pkg/rust.iss | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 0404e2bdee6c..dfeb735f5f1e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -141,6 +141,9 @@ endif CFG_GIT_DIR := $(CFG_SRC_DIR).git CFG_RELEASE = 0.7-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 ifneq ($(wildcard $(CFG_GIT)),) ifneq ($(wildcard $(CFG_GIT_DIR)),) @@ -311,6 +314,7 @@ $(foreach host,$(CFG_HOST_TRIPLES), \ export CFG_SRC_DIR export CFG_BUILD_DIR export CFG_VERSION +export CFG_VERSION_WIN export CFG_BUILD_TRIPLE export CFG_LLVM_ROOT export CFG_ENABLE_MINGW_CROSS diff --git a/src/etc/pkg/rust.iss b/src/etc/pkg/rust.iss index 18f358a9893d..0375a041a39e 100644 --- a/src/etc/pkg/rust.iss +++ b/src/etc/pkg/rust.iss @@ -1,4 +1,5 @@ #define CFG_VERSION GetEnv("CFG_VERSION") +#define CFG_VERSION_WIN GetEnv("CFG_VERSION_WIN") [Setup] @@ -8,7 +9,7 @@ AppVersion={#CFG_VERSION} AppCopyright=Copyright (C) 2006-2013 Mozilla Foundation, MIT license AppPublisher=Mozilla Foundation AppPublisherURL=http://www.rust-lang.org -VersionInfoVersion={#CFG_VERSION} +VersionInfoVersion={#CFG_VERSION_WIN} LicenseFile=LICENSE.txt DisableWelcomePage=true From 6511fe45e2df0328a5267dae9b1dda160edd1861 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 27 Jun 2013 18:57:38 -0700 Subject: [PATCH 217/336] mk: Include all bins in the windows install --- mk/dist.mk | 2 +- mk/tools.mk | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mk/dist.mk b/mk/dist.mk index 912b692a247e..cb5b3607fca8 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -57,7 +57,7 @@ LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT cp $< $@ $(PKG_EXE): rust.iss modpath.iss LICENSE.txt rust-logo.ico \ - $(PKG_FILES) all rustc-stage3 + $(PKG_FILES) $(CSREQ3_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE)) @$(call E, ISCC: $@) $(Q)"$(CFG_ISCC)" $< endif diff --git a/mk/tools.mk b/mk/tools.mk index 7b50441b3c7f..0a901358ac1f 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -191,7 +191,8 @@ $(foreach host,$(CFG_HOST_TRIPLES), \ $(foreach target,$(CFG_TARGET_TRIPLES), \ $(eval $(call TOOLS_STAGE_N_TARGET,0,1,$(host),$(target))) \ $(eval $(call TOOLS_STAGE_N_TARGET,1,2,$(host),$(target))) \ - $(eval $(call TOOLS_STAGE_N_TARGET,2,3,$(host),$(target))))) + $(eval $(call TOOLS_STAGE_N_TARGET,2,3,$(host),$(target))) \ + $(eval $(call TOOLS_STAGE_N_TARGET,3,bogus,$(host),$(target))))) $(foreach host,$(CFG_HOST_TRIPLES), \ $(eval $(call TOOLS_STAGE_N_HOST,0,1,$(host),$(host))) \ From 779ee2a2dd06235470cf5b6bea90b78619dc0654 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 27 Jun 2013 03:32:21 -0400 Subject: [PATCH 218/336] util: make NonCopyable 0 size (instead of 1 byte) this also adds a derived Eq, TotalEq, Ord and TotalOrd along with removing the useless constructor --- src/libstd/option.rs | 2 +- src/libstd/util.rs | 51 +++++++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/libstd/option.rs b/src/libstd/option.rs index f3ea81f1ae56..12ae2abd4a1f 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -447,7 +447,7 @@ fn test_option_dance() { } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_option_too_much_dance() { - let mut y = Some(util::NonCopyable::new()); + let mut y = Some(util::NonCopyable); let _y2 = y.swap_unwrap(); let _y3 = y.swap_unwrap(); } diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 6eddae17ce6f..e66271df4784 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -75,18 +75,14 @@ pub fn replace(dest: &mut T, mut src: T) -> T { } /// A non-copyable dummy type. +#[deriving(Eq, TotalEq, Ord, TotalOrd)] +#[no_drop_flag] pub struct NonCopyable; -impl NonCopyable { - /// Creates a dummy non-copyable structure and returns it for use. - pub fn new() -> NonCopyable { NonCopyable } -} - impl Drop for NonCopyable { fn drop(&self) { } } - /// A type with no inhabitants pub enum Void { } @@ -130,39 +126,70 @@ pub fn unreachable() -> ! { #[cfg(test)] mod tests { + use super::*; use option::{None, Some}; - use util::{Void, NonCopyable, id, replace, swap}; use either::{Either, Left, Right}; + use sys::size_of; + use kinds::Drop; #[test] - pub fn identity_crisis() { + fn identity_crisis() { // Writing a test for the identity function. How did it come to this? let x = ~[(5, false)]; //FIXME #3387 assert!(x.eq(id(copy x))); let y = copy x; assert!(x.eq(&id(y))); } + #[test] - pub fn test_swap() { + fn test_swap() { let mut x = 31337; let mut y = 42; swap(&mut x, &mut y); assert_eq!(x, 42); assert_eq!(y, 31337); } + #[test] - pub fn test_replace() { - let mut x = Some(NonCopyable::new()); + fn test_replace() { + let mut x = Some(NonCopyable); let y = replace(&mut x, None); assert!(x.is_none()); assert!(y.is_some()); } + #[test] - pub fn test_uninhabited() { + fn test_uninhabited() { let could_only_be_coin : Either = Right (()); match could_only_be_coin { Right (coin) => coin, Left (is_void) => is_void.uninhabited () } } + + #[test] + fn test_noncopyable() { + assert_eq!(size_of::(), 0); + + // verify that `#[no_drop_flag]` works as intended on a zero-size struct + + static mut did_run: bool = false; + + struct Foo { five: int } + + impl Drop for Foo { + fn drop(&self) { + assert_eq!(self.five, 5); + unsafe { + did_run = true; + } + } + } + + { + let _a = (NonCopyable, Foo { five: 5 }, NonCopyable); + } + + unsafe { assert_eq!(did_run, true); } + } } From dcf1dc060a895d2b4de04b6d13291989c2f3dbec Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Thu, 27 Jun 2013 20:47:45 +0300 Subject: [PATCH 219/336] Rename #[no_drop_flag] to #[unsafe_no_drop_flag] --- src/librustc/middle/ty.rs | 2 +- src/libstd/unstable/atomics.rs | 2 +- src/libstd/util.rs | 4 ++-- src/test/run-pass/attr-no-drop-flag-size.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b53359abed4b..29d81f37da7d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3904,7 +3904,7 @@ impl DtorKind { pub fn ty_dtor(cx: ctxt, struct_id: def_id) -> DtorKind { match cx.destructor_for_type.find(&struct_id) { Some(&method_def_id) => { - let flag = !has_attr(cx, struct_id, "no_drop_flag"); + let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag"); TraitDtor(method_def_id, flag) } diff --git a/src/libstd/unstable/atomics.rs b/src/libstd/unstable/atomics.rs index 45eced9846ce..1e5ac305df37 100644 --- a/src/libstd/unstable/atomics.rs +++ b/src/libstd/unstable/atomics.rs @@ -62,7 +62,7 @@ pub struct AtomicPtr { /** * An owned atomic pointer. Ensures that only a single reference to the data is held at any time. */ -#[no_drop_flag] +#[unsafe_no_drop_flag] pub struct AtomicOption { priv p: *mut c_void } diff --git a/src/libstd/util.rs b/src/libstd/util.rs index e66271df4784..fe1087a04389 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -76,7 +76,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// A non-copyable dummy type. #[deriving(Eq, TotalEq, Ord, TotalOrd)] -#[no_drop_flag] +#[unsafe_no_drop_flag] pub struct NonCopyable; impl Drop for NonCopyable { @@ -171,7 +171,7 @@ mod tests { fn test_noncopyable() { assert_eq!(size_of::(), 0); - // verify that `#[no_drop_flag]` works as intended on a zero-size struct + // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct static mut did_run: bool = false; diff --git a/src/test/run-pass/attr-no-drop-flag-size.rs b/src/test/run-pass/attr-no-drop-flag-size.rs index 00a7955d834c..87c476d781e7 100644 --- a/src/test/run-pass/attr-no-drop-flag-size.rs +++ b/src/test/run-pass/attr-no-drop-flag-size.rs @@ -10,7 +10,7 @@ use std::sys::size_of; -#[no_drop_flag] +#[unsafe_no_drop_flag] struct Test { a: T } From b854d6ea1caf9051fcd3da822e0f65c437d1ed84 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 27 Jun 2013 12:00:00 -0700 Subject: [PATCH 220/336] docs: Mention rustpkg in release notes --- RELEASES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.txt b/RELEASES.txt index dbee53f8e305..9ac4d650b43f 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -101,6 +101,7 @@ Version 0.7 (July 2013) dynamic borrowcheck failures for debugging. * rustdoc has a nicer stylesheet. * Various improvements to rustdoc. + * Improvements to rustpkg (see the detailed release notes) * Other * More and improved library documentation. From d805859ff5bf90f7513550453a7fd797eb2e778d Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 27 Jun 2013 12:13:55 -0700 Subject: [PATCH 221/336] rustpkg: Update manual --- doc/rustpkg.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/rustpkg.md b/doc/rustpkg.md index b12bce5a0afd..506fc2ad15a8 100644 --- a/doc/rustpkg.md +++ b/doc/rustpkg.md @@ -95,12 +95,22 @@ When building a package that is in a `git` repository, When building a package that is not under version control, or that has no tags, `rustpkg` assumes the intended version is 0.1. +# Dependencies + +rustpkg infers dependencies from `extern mod` directives. +Thus, there should be no need to pass a `-L` flag to rustpkg to tell it where to find a library. +(In the future, it will also be possible to write an `extern mod` directive referring to a remote package.) + # Custom build scripts A file called `pkg.rs` at the root level in a workspace is called a *package script*. If a package script exists, rustpkg executes it to build the package rather than inferring crates as described previously. +Inside `pkg.rs`, it's possible to call back into rustpkg to finish up the build. +`rustpkg::api` contains functions to build, install, or clean libraries and executables +in the way rustpkg normally would without custom build logic. + # Command reference ## build From aabeba3d63221651d965b7aa39bbf28781f9d16f Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Thu, 27 Jun 2013 14:48:53 +0900 Subject: [PATCH 222/336] extra: unused import fix for android --- src/libextra/ebml.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 92a027100daf..dd3ba639c054 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -82,8 +82,14 @@ pub mod reader { use core::cast::transmute; use core::int; use core::io; - use core::ptr::offset; use core::str; + + #[cfg(target_arch = "x86")] + #[cfg(target_arch = "x86_64")] + use core::ptr::offset; + + #[cfg(target_arch = "x86")] + #[cfg(target_arch = "x86_64")] use core::unstable::intrinsics::bswap32; // ebml reading From 6b2297d118bdbc3b1487dc48ae56f9e1755b41f5 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Thu, 27 Jun 2013 14:49:12 +0900 Subject: [PATCH 223/336] std: unused import fix for android --- src/libstd/libc.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 3c2ae93b6563..41b78afded1a 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -349,7 +349,6 @@ pub mod types { use libc::types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t}; use libc::types::os::arch::c99::{c_longlong, c_ulonglong}; use libc::types::os::arch::posix88::{uid_t, gid_t, ino_t}; - use libc::types::os::arch::posix88::{uid_t}; pub type nlink_t = u16; pub type blksize_t = u32; From 5fccce4051f452f68ad725d2e7520d3971f3178d Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 27 Jun 2013 16:45:09 -0400 Subject: [PATCH 224/336] rc: add missing `#[unsafe_no_drop_flag]` The destructors were updated in d9f6dd263c16a21108c27dbf15a3d59a43a5b490 but this was accidentally left out. --- src/libextra/rc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 8ef58a188d93..5b1451387e7a 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -36,6 +36,7 @@ struct RcBox { /// Immutable reference counted pointer type #[non_owned] +#[unsafe_no_drop_flag] pub struct Rc { priv ptr: *mut RcBox, } @@ -168,6 +169,7 @@ struct RcMutBox { /// Mutable reference counted pointer type #[non_owned] #[mutable] +#[unsafe_no_drop_flag] pub struct RcMut { priv ptr: *mut RcMutBox, } From c45af013517148b8fe6e6234ecad729baf135c23 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 28 Jun 2013 00:23:38 -0400 Subject: [PATCH 225/336] fix stage0 build --- src/libstd/util.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libstd/util.rs b/src/libstd/util.rs index fe1087a04389..fd29d7dc14bd 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -173,16 +173,18 @@ mod tests { // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct - static mut did_run: bool = false; + // NOTE: uncomment after snapshot, will not parse yet + //static mut did_run: bool = false; struct Foo { five: int } impl Drop for Foo { fn drop(&self) { assert_eq!(self.five, 5); - unsafe { - did_run = true; - } + // NOTE: uncomment after snapshot, will not parse yet + //unsafe { + //did_run = true; + //} } } @@ -190,6 +192,7 @@ mod tests { let _a = (NonCopyable, Foo { five: 5 }, NonCopyable); } - unsafe { assert_eq!(did_run, true); } + // NOTE: uncomment after snapshot, will not parse yet + //unsafe { assert_eq!(did_run, true); } } } From 659cd55e758094cd473033c28587d8429496c860 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 27 Jun 2013 18:48:12 -0400 Subject: [PATCH 226/336] add a tutorial on containers and iterators --- doc/tutorial-container.md | 207 ++++++++++++++++++++++++++++++++++++++ doc/tutorial.md | 127 +---------------------- mk/docs.mk | 10 ++ 3 files changed, 218 insertions(+), 126 deletions(-) create mode 100644 doc/tutorial-container.md diff --git a/doc/tutorial-container.md b/doc/tutorial-container.md new file mode 100644 index 000000000000..66bd0b9c1319 --- /dev/null +++ b/doc/tutorial-container.md @@ -0,0 +1,207 @@ +% Containers and iterators + +# Containers + +The container traits are defined in the `std::container` module. + +## Unique and managed vectors + +Vectors have `O(1)` indexing and removal from the end, along with `O(1)` +amortized insertion. Vectors are the most common container in Rust, and are +flexible enough to fit many use cases. + +Vectors can also be sorted and used as efficient lookup tables with the +`std::vec::bsearch` function, if all the elements are inserted at one time and +deletions are unnecessary. + +## Maps and sets + +Maps are collections of unique keys with corresponding values, and sets are +just unique keys without a corresponding value. The `Map` and `Set` traits in +`std::container` define the basic interface. + +The standard library provides three owned map/set types: + +* `std::hashmap::HashMap` and `std::hashmap::HashSet`, requiring the keys to + implement `Eq` and `Hash` +* `std::trie::TrieMap` and `std::trie::TrieSet`, requiring the keys to be `uint` +* `extra::treemap::TreeMap` and `extra::treemap::TreeSet`, requiring the keys + to implement `TotalOrd` + +These maps do not use managed pointers so they can be sent between tasks as +long as the key and value types are sendable. Neither the key or value type has +to be copyable. + +The `TrieMap` and `TreeMap` maps are ordered, while `HashMap` uses an arbitrary +order. + +Each `HashMap` instance has a random 128-bit key to use with a keyed hash, +making the order of a set of keys in a given hash table randomized. Rust +provides a [SipHash](https://131002.net/siphash/) implementation for any type +implementing the `IterBytes` trait. + +## Double-ended queues + +The `extra::deque` module implements a double-ended queue with `O(1)` amortized +inserts and removals from both ends of the container. It also has `O(1)` +indexing like a vector. The contained elements are not required to be copyable, +and the queue will be sendable if the contained type is sendable. + +## Priority queues + +The `extra::priority_queue` module implements a queue ordered by a key. The +contained elements are not required to be copyable, and the queue will be +sendable if the contained type is sendable. + +Insertions have `O(log n)` time complexity and checking or popping the largest +element is `O(1)`. Converting a vector to a priority queue can be done +in-place, and has `O(n)` complexity. A priority queue can also be converted to +a sorted vector in-place, allowing it to be used for an `O(n log n)` in-place +heapsort. + +# Iterators + +## Iteration protocol + +The iteration protocol is defined by the `Iterator` trait in the +`std::iterator` module. The minimal implementation of the trait is a `next` +method, yielding the next element from an iterator object: + +~~~ +/// An infinite stream of zeroes +struct ZeroStream; + +impl Iterator for ZeroStream { + fn next(&mut self) -> Option { + Some(0) + } +} +~~~~ + +Reaching the end of the iterator is signalled by returning `None` instead of +`Some(item)`: + +~~~ +/// A stream of N zeroes +struct ZeroStream { + priv remaining: uint +} + +impl ZeroStream { + fn new(n: uint) -> ZeroStream { + ZeroStream { remaining: n } + } +} + +impl Iterator for ZeroStream { + fn next(&mut self) -> Option { + if self.remaining == 0 { + None + } else { + self.remaining -= 1; + Some(0) + } + } +} +~~~ + +## Container iterators + +Containers implement iteration over the contained elements by returning an +iterator object. For example, vectors have four iterators available: + +* `vector.iter()`, for immutable references to the elements +* `vector.mut_iter()`, for mutable references to the elements +* `vector.rev_iter()`, for immutable references to the elements in reverse order +* `vector.mut_rev_iter()`, for mutable references to the elements in reverse order + +### Freezing + +Unlike most other languages with external iterators, Rust has no *iterator +invalidation*. As long an iterator is still in scope, the compiler will prevent +modification of the container through another handle. + +~~~ +let mut xs = [1, 2, 3]; +{ + let _it = xs.iter(); + + // the vector is frozen for this scope, the compiler will statically + // prevent modification +} +// the vector becomes unfrozen again at the end of the scope +~~~ + +These semantics are due to most container iterators being implemented with `&` +and `&mut`. + +## Iterator adaptors + +The `IteratorUtil` trait implements common algorithms as methods extending +every `Iterator` implementation. For example, the `fold` method will accumulate +the items yielded by an `Iterator` into a single value: + +~~~ +let xs = [1, 9, 2, 3, 14, 12]; +let result = xs.iter().fold(0, |accumulator, item| accumulator - *item); +assert_eq!(result, -41); +~~~ + +Some adaptors return an adaptor object implementing the `Iterator` trait itself: + +~~~ +let xs = [1, 9, 2, 3, 14, 12]; +let ys = [5, 2, 1, 8]; +let sum = xs.iter().chain_(ys.iter()).fold(0, |a, b| a + *b); +assert_eq!(sum, 57); +~~~ + +Note that some adaptors like the `chain_` method above use a trailing +underscore to work around an issue with method resolve. The underscores will be +dropped when they become unnecessary. + +## For loops + +The `for` loop syntax is currently in transition, and will switch from the old +closure-based iteration protocol to iterator objects. For now, the `advance` +adaptor is required as a compatibility shim to use iterators with for loops. + +~~~ +let xs = [2, 3, 5, 7, 11, 13, 17]; + +// print out all the elements in the vector +for xs.iter().advance |x| { + println(x.to_str()) +} + +// print out all but the first 3 elements in the vector +for xs.iter().skip(3).advance |x| { + println(x.to_str()) +} +~~~ + +For loops are *often* used with a temporary iterator object, as above. They can +also advance the state of an iterator in a mutable location: + +~~~ +let xs = [1, 2, 3, 4, 5]; +let ys = ["foo", "bar", "baz", "foobar"]; + +// create an iterator yielding tuples of elements from both vectors +let mut it = xs.iter().zip(ys.iter()); + +// print out the pairs of elements up to (&3, &"baz") +for it.advance |(x, y)| { + println(fmt!("%d %s", *x, *y)); + + if *x == 3 { + break; + } +} + +// yield and print the last pair from the iterator +println(fmt!("last: %?", it.next())); + +// the iterator is now fully consumed +assert!(it.next().is_none()); +~~~ diff --git a/doc/tutorial.md b/doc/tutorial.md index 0701d61351ce..fc0f7b74a7af 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1607,132 +1607,6 @@ do spawn { If you want to see the output of `debug!` statements, you will need to turn on `debug!` logging. To enable `debug!` logging, set the RUST_LOG environment variable to the name of your crate, which, for a file named `foo.rs`, will be `foo` (e.g., with bash, `export RUST_LOG=foo`). -## For loops - -> ***Note:*** The closure-based protocol used `for` loop is on the way out. The `for` loop will -> use iterator objects in the future instead. - -The most common way to express iteration in Rust is with a `for` -loop. Like `do`, `for` is a nice syntax for describing control flow -with closures. Additionally, within a `for` loop, `break`, `loop`, -and `return` work just as they do with `while` and `loop`. - -Consider again our `each` function, this time improved to return -immediately when the iteratee returns `false`: - -~~~~ -fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { - let mut n = 0; - while n < v.len() { - if !op(&v[n]) { - return false; - } - n += 1; - } - return true; -} -~~~~ - -And using this function to iterate over a vector: - -~~~~ -# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { -# let mut n = 0; -# while n < v.len() { -# if !op(&v[n]) { -# return false; -# } -# n += 1; -# } -# return true; -# } -each([2, 4, 8, 5, 16], |n| { - if *n % 2 != 0 { - println("found odd number!"); - false - } else { true } -}); -~~~~ - -With `for`, functions like `each` can be treated more -like built-in looping structures. When calling `each` -in a `for` loop, instead of returning `false` to break -out of the loop, you just write `break`. To skip ahead -to the next iteration, write `loop`. - -~~~~ -# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { -# let mut n = 0; -# while n < v.len() { -# if !op(&v[n]) { -# return false; -# } -# n += 1; -# } -# return true; -# } -for each([2, 4, 8, 5, 16]) |n| { - if *n % 2 != 0 { - println("found odd number!"); - break; - } -} -~~~~ - -As an added bonus, you can use the `return` keyword, which is not -normally allowed in closures, in a block that appears as the body of a -`for` loop: the meaning of `return` in such a block is to return from -the enclosing function, not just the loop body. - -~~~~ -# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { -# let mut n = 0; -# while n < v.len() { -# if !op(&v[n]) { -# return false; -# } -# n += 1; -# } -# return true; -# } -fn contains(v: &[int], elt: int) -> bool { - for each(v) |x| { - if (*x == elt) { return true; } - } - false -} -~~~~ - -Notice that, because `each` passes each value by borrowed pointer, -the iteratee needs to dereference it before using it. -In these situations it can be convenient to lean on Rust's -argument patterns to bind `x` to the actual value, not the pointer. - -~~~~ -# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { -# let mut n = 0; -# while n < v.len() { -# if !op(&v[n]) { -# return false; -# } -# n += 1; -# } -# return true; -# } -# fn contains(v: &[int], elt: int) -> bool { - for each(v) |&x| { - if (x == elt) { return true; } - } -# false -# } -~~~~ - -`for` syntax only works with stack closures. - -> ***Note:*** This is, essentially, a special loop protocol: -> the keywords `break`, `loop`, and `return` work, in varying degree, -> with `while`, `loop`, `do`, and `for` constructs. - # Methods Methods are like functions except that they always begin with a special argument, @@ -2653,6 +2527,7 @@ tutorials on individual topics. * [Tasks and communication][tasks] * [Macros][macros] * [The foreign function interface][ffi] +* [Containers and iterators](tutorial-container.html) There is further documentation on the [wiki]. diff --git a/mk/docs.mk b/mk/docs.mk index 8470da7c07b2..f11a3d24b8d2 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -99,6 +99,16 @@ doc/tutorial-macros.html: tutorial-macros.md doc/version_info.html \ --include-before-body=doc/version_info.html \ --output=$@ +DOCS += doc/tutorial-container.html +doc/tutorial-container.html: tutorial-container.md doc/version_info.html doc/rust.css + @$(call E, pandoc: $@) + $(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \ + $(CFG_PANDOC) --standalone --toc \ + --section-divs --number-sections \ + --from=markdown --to=html --css=rust.css \ + --include-before-body=doc/version_info.html \ + --output=$@ + DOCS += doc/tutorial-ffi.html doc/tutorial-ffi.html: tutorial-ffi.md doc/version_info.html doc/rust.css @$(call E, pandoc: $@) From 3fbea161075aa21a217bd794e3f5cac7085e94ec Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 27 Jun 2013 16:39:06 -0700 Subject: [PATCH 227/336] Update man page --- man/rustc.1 | 69 ++++++++++++++--------------------------------------- 1 file changed, 18 insertions(+), 51 deletions(-) diff --git a/man/rustc.1 b/man/rustc.1 index 9ed98c142943..4e76749f707e 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -1,4 +1,4 @@ -.TH RUSTC "1" "February 2013" "rustc 0.6" "User Commands" +.TH RUSTC "1" "July 2013" "rustc 0.7" "User Commands" .SH NAME rustc \- rust compiler .SH SYNOPSIS @@ -33,6 +33,12 @@ Add a directory to the library search path \fB\-\-lib\fR Compile a library crate .TP +\fB\-\-linker\fR LINKER +Program to use for linking instead of the default +.TP +\fB\-\-link-args\fR FLAGS +A space-separated list of flags passed to the linker +.TP \fB\-\-ls\fR List the symbols defined by a library crate .TP @@ -48,6 +54,11 @@ Write output to \fB\-\-opt\-level\fR LEVEL Optimize with possible levels 0-3 .TP +\fB\-\-passes\fR NAMES +Comma- or space-separated list of optimization passes. Overrides +the default passes for the optimization level. A value of 'list' +will list the available passes. +.TP \fB\-\-out\-dir\fR DIR Write output to compiler-chosen filename in .TP @@ -77,6 +88,12 @@ Target triple cpu-manufacturer-kernel[-os] to compile for (see http://sources.redhat.com/autobook/autobook/autobook_17.html for detail) .TP +\fB\-\-target-feature\fR TRIPLE +Target-specific attributes (see llc -mattr=help for detail) +.TP +\fB\-\-android-cross-path\fR PATH +The path to the Android NDK +.TP \fB\-W\fR help Print 'lint' options and default settings .TP @@ -94,56 +111,6 @@ Set lint forbidden .TP \fB\-Z\fR FLAG Set internal debugging options. Use "-Z help" to print available options. - -Available debug flags are: -.RS -.IP \[bu] -\fBverbose\fR - in general, enable more debug printouts -.IP \[bu] -\fBtime\-passes\fR - measure time of each rustc pass -.IP \[bu] -\fBcount\-llvm\-insns\fR - count where LLVM instrs originate -.IP \[bu] -\fBtime\-llvm\-passes\fR - measure time of each LLVM pass -.IP \[bu] -\fBtrans\-stats\fR - gather trans statistics -.IP \[bu] -\fBno\-asm\-comments\fR - omit comments when using \fI\-S\fR -.IP \[bu] -\fBno\-verify\fR - skip LLVM verification -.IP \[bu] -\fBtrace\fR - emit trace logs -.IP \[bu] -\fBcoherence\fR - perform coherence checking -.IP \[bu] -\fBborrowck\-stats\fR - gather borrowck statistics -.IP \[bu] -\fBborrowck\-note\-pure\fR - note where purity is req'd -.IP \[bu] -\fBborrowck\-note\-loan\fR - note where loans are req'd -.IP \[bu] -\fBno\-landing\-pads\fR - omit landing pads for unwinding -.IP \[bu] -\fBdebug\-llvm\fR - enable debug output from LLVM -.IP \[bu] -\fBcount\-type\-sizes\fR - count the sizes of aggregate types -.IP \[bu] -\fBmeta\-stats\fR - gather metadata statistics -.IP \[bu] -\fBno\-opt\fR - do not optimize, even if \fI\-O\fR is passed -.IP \[bu] -\fBno\-monomorphic\-collapse\fR - do not collapse template instantiations -.IP \[bu] -\fBgc\fR - Garbage collect shared data (experimental) -.IP \[bu] -\fBjit\fR - Execute using JIT (experimental) -.IP \[bu] -\fBextra\-debug\-info\fR - Extra debugging info (experimental) -.IP \[bu] -\fBdebug\-info\fR - Produce debug info (experimental) -.IP \[bu] -\fBstatic\fR - Use or produce static libraries or binaries (experimental) -.RE .TP \fB\-v\fR, \fB\-\-version\fR Print version info and exit From ea62fd1090fda26e1e4b68bdc7ef2e11864d80b6 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 25 Jun 2013 19:49:01 -0700 Subject: [PATCH 228/336] rustpkg: Implement RUST_PATH Unfortunately, the main test for this is ignored due to #7071. Closes #5682 --- src/librustpkg/path_util.rs | 35 +++++++++++++++++++-- src/librustpkg/tests.rs | 61 ++++++++++++++++++++++++++++++++----- src/libstd/path.rs | 9 ++++++ 3 files changed, 94 insertions(+), 11 deletions(-) diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 6d146145f36f..c0425b4d2606 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -22,11 +22,40 @@ use core::iterator::IteratorUtil; use messages::*; use package_id::*; +fn push_if_exists(vec: &mut ~[Path], p: &Path) { + let maybe_dir = p.push(".rust"); + if os::path_exists(&maybe_dir) { + vec.push(maybe_dir); + } +} + +#[cfg(windows)] +static path_entry_separator: &'static str = ";"; +#[cfg(not(windows))] +static path_entry_separator: &'static str = ":"; + /// Returns the value of RUST_PATH, as a list -/// of Paths. In general this should be read from the -/// environment; for now, it's hard-wired to just be "." +/// of Paths. Includes default entries for, if they exist: +/// $HOME/.rust +/// DIR/.rust for any DIR that's the current working directory +/// or an ancestor of it pub fn rust_path() -> ~[Path] { - ~[Path(".")] + let env_path: ~str = os::getenv("RUST_PATH").get_or_default(~""); + 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_components.map(|&s| Path(s)) + } + None => ~[] + }; + let cwd = os::getcwd(); + // now add in default entries + env_rust_path.push(copy cwd); + do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) }; + let h = os::homedir(); + for h.iter().advance |h| { push_if_exists(&mut env_rust_path, h); } + env_rust_path } pub static u_rwx: i32 = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index afeb64075335..8d8628c77181 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -12,7 +12,7 @@ use context::Ctx; use core::hashmap::HashMap; -use core::{io, libc, os, result, run, str}; +use core::{io, libc, os, result, run, str, vec}; use core::prelude::*; use extra::tempfile::mkdtemp; use core::run::ProcessOutput; @@ -25,7 +25,7 @@ use path_util::{target_executable_in_workspace, target_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}; + installed_library_in_workspace, rust_path}; use target::*; /// Returns the last-modified date as an Option @@ -562,13 +562,58 @@ fn package_script_with_default_build() { } #[test] -#[ignore (reason = "RUST_PATH not yet implemented -- #5682")] +#[ignore (reason = "Un-ignore when #7071 is fixed")] fn rust_path_test() { - let dir = mk_workspace(&Path("/home/more_rust"), - &normalize(RemotePath(Path("foo"))), - &NoVersion); - // command_line_test("RUST_PATH=/home/rust:/home/more_rust rustpkg install foo"); - command_line_test([~"install", ~"foo"], &dir); + let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed"); + let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion); + debug!("dir = %s", dir.to_str()); + writeFile(&Path("/Users/tjc/more_rust/src/foo-0.1/main.rs"), + "fn main() { let _x = (); }"); + + let cwd = os::getcwd(); + debug!("cwd = %s", cwd.to_str()); + let mut prog = run::Process::new("rustpkg", + [~"install", ~"foo"], + run::ProcessOptions { env: Some(&[(~"RUST_PATH", + dir_for_path.to_str())]), + dir: Some(&cwd), + in_fd: None, + out_fd: None, + err_fd: None + }); + prog.finish_with_output(); + assert_executable_exists(&dir_for_path, "foo"); +} + +#[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!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) { + let p = rust_path(); + let cwd = os::getcwd().push(".rust"); + let parent = cwd.pop().pop().push(".rust"); + let grandparent = cwd.pop().pop().pop().push(".rust"); + assert!(vec::contains(p, &cwd)); + assert!(vec::contains(p, &parent)); + assert!(vec::contains(p, &grandparent)); + for p.iter().advance() |a_path| { + assert!(!a_path.components.is_empty()); + } + }); +} + +#[test] +fn rust_path_parse() { + os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i"); + let paths = rust_path(); + assert!(vec::contains(paths, &Path("/g/h/i"))); + assert!(vec::contains(paths, &Path("/d/e/f"))); + assert!(vec::contains(paths, &Path("/a/b/c"))); + os::unsetenv("RUST_PATH"); } #[test] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 700bfff3f5d7..897926940116 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -382,6 +382,15 @@ impl Path { Some(ref st) => Some(st.st_mode as uint), } } + + /// Execute a function on p as well as all of its ancestors + pub fn each_parent(&self, f: &fn(&Path)) { + if !self.components.is_empty() { + f(self); + self.pop().each_parent(f); + } + } + } #[cfg(target_os = "freebsd")] From a897a9ab9fa046483564efdf84e731b872d2356a Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 21 Jun 2013 20:28:33 +1200 Subject: [PATCH 229/336] Remove useless namegen thunk --- src/librustc/back/link.rs | 14 +++++++----- src/librustc/middle/trans/base.rs | 27 ++++++++++++----------- src/librustc/middle/trans/common.rs | 15 +++++-------- src/librustc/middle/trans/context.rs | 5 +---- src/librustc/middle/trans/debuginfo.rs | 10 ++++----- src/librustc/middle/trans/meth.rs | 9 ++++---- src/librustc/middle/trans/monomorphize.rs | 5 +++-- 7 files changed, 40 insertions(+), 45 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 01ad3507b83e..55d0219a7871 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -19,6 +19,7 @@ use lib; use metadata::common::LinkMeta; use metadata::{encoder, csearch, cstore}; use middle::trans::context::CrateContext; +use middle::trans::common::gensym_name; use middle::ty; use util::ppaux; @@ -37,6 +38,7 @@ use syntax::ast; use syntax::ast_map::{path, path_mod, path_name}; use syntax::attr; use syntax::print::pprust; +use syntax::parse::token; #[deriving(Eq)] pub enum output_type { @@ -731,22 +733,22 @@ pub fn mangle_internal_name_by_type_and_seq(ccx: &mut CrateContext, return mangle(ccx.sess, ~[path_name(ccx.sess.ident_of(s)), path_name(ccx.sess.ident_of(hash)), - path_name((ccx.names)(name))]); + path_name(gensym_name(name))]); } pub fn mangle_internal_name_by_path_and_seq(ccx: &mut CrateContext, - path: path, + mut path: path, flav: &str) -> ~str { - mangle(ccx.sess, - vec::append_one(path, path_name((ccx.names)(flav)))) + path.push(path_name(gensym_name(flav))); + mangle(ccx.sess, path) } pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str { mangle(ccx.sess, path) } -pub fn mangle_internal_name_by_seq(ccx: &mut CrateContext, flav: &str) -> ~str { - fmt!("%s_%u", flav, (ccx.names)(flav).name) +pub fn mangle_internal_name_by_seq(_ccx: &mut CrateContext, flav: &str) -> ~str { + return fmt!("%s_%u", flav, token::gensym(flav)); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a0628bc8e87c..38c6b14806c4 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1129,15 +1129,10 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, is_lpad: bool, name: &str, opt_node_info: Option) -> block { - let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo { - (cx.ccx.names)(name) - } else { - special_idents::invalid - }; unsafe { - let llbb = str::as_c_str(cx.ccx.sess.str_of(s), |buf| { + let llbb = do name.as_c_str |buf| { llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf) - }); + }; let bcx = mk_block(llbb, parent, kind, @@ -1145,8 +1140,11 @@ pub fn new_block(cx: fn_ctxt, parent: Option, kind: block_kind, opt_node_info, cx); for parent.iter().advance |cx| { - if cx.unreachable { Unreachable(bcx); } - }; + if cx.unreachable { + Unreachable(bcx); + break; + } + } bcx } } @@ -2532,12 +2530,15 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { pub fn register_method(ccx: @mut CrateContext, id: ast::node_id, - pth: @ast_map::path, + path: @ast_map::path, m: @ast::method) -> ValueRef { let mty = ty::node_id_to_type(ccx.tcx, id); - let pth = vec::append(/*bad*/copy *pth, [path_name((ccx.names)("meth")), - path_name(m.ident)]); - let llfn = register_fn_full(ccx, m.span, pth, id, m.attrs, mty); + + let mut path = /*bad*/ copy *path; + path.push(path_name(gensym_name("meth"))); + path.push(path_name(m.ident)); + + let llfn = register_fn_full(ccx, m.span, path, id, m.attrs, mty); set_inline_hint_if_appr(m.attrs, llfn); llfn } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 714dc8368e50..67ca647862ba 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -45,14 +45,8 @@ use syntax::{ast, ast_map}; pub use middle::trans::context::CrateContext; -// NOTE: this thunk is totally pointless now that we're not passing -// interners around... -pub type namegen = @fn(s: &str) -> ident; -pub fn new_namegen() -> namegen { - let f: @fn(s: &str) -> ident = |prefix| { - token::str_to_ident(fmt!("%s_%u", prefix, token::gensym(prefix))) - }; - f +pub fn gensym_name(name: &str) -> ident { + token::str_to_ident(fmt!("%s_%u", name, token::gensym(name))) } pub struct tydesc_info { @@ -819,8 +813,9 @@ pub fn C_bytes(bytes: &[u8]) -> ValueRef { pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { unsafe { - let ptr = cast::transmute(vec::raw::to_ptr(bytes)); - return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint,False); + return llvm::LLVMConstStringInContext(base::task_llcx(), + cast::transmute(vec::raw::to_ptr(bytes)), + bytes.len() as c_uint, False); } } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index a0ae579c8655..7046c8b9f41b 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -34,8 +34,7 @@ use core::local_data; use extra::time; use syntax::ast; -use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen}; -use middle::trans::common::{mono_id,new_namegen}; +use middle::trans::common::{mono_id,ExternMap,tydesc_info,BuilderRef_res,Stats}; use middle::trans::base::{decl_crate_map}; @@ -93,7 +92,6 @@ pub struct CrateContext { lltypes: HashMap, llsizingtypes: HashMap, adt_reprs: HashMap, - names: namegen, symbol_hasher: hash::State, type_hashcodes: HashMap, type_short_names: HashMap, @@ -194,7 +192,6 @@ impl CrateContext { lltypes: HashMap::new(), llsizingtypes: HashMap::new(), adt_reprs: HashMap::new(), - names: new_namegen(), symbol_hasher: symbol_hasher, type_hashcodes: HashMap::new(), type_short_names: HashMap::new(), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index a42f20ea39ca..22448f577a35 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -64,6 +64,7 @@ use core::sys; use core::vec; use syntax::codemap::span; use syntax::{ast, codemap, ast_util, ast_map}; +use syntax::parse::token; static DW_LANG_RUST: int = 0x9000; @@ -86,7 +87,6 @@ static DW_ATE_unsigned_char: int = 0x08; /// A context object for maintaining all state needed by the debuginfo module. pub struct DebugContext { - names: namegen, crate_file: ~str, llcontext: ContextRef, builder: DIBuilderRef, @@ -104,7 +104,6 @@ impl DebugContext { // DIBuilder inherits context from the module, so we'd better use the same one let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; return DebugContext { - names: new_namegen(), crate_file: crate, llcontext: llcontext, builder: builder, @@ -276,7 +275,8 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram { ast_map::node_expr(expr) => { match expr.node { ast::expr_fn_block(ref decl, _) => { - ((dbg_cx(cx).names)("fn"), decl.output, expr.id) + let name = gensym_name("fn"); + (name, decl.output, expr.id) } _ => fcx.ccx.sess.span_bug(expr.span, "create_function: expected an expr_fn_block here") @@ -628,7 +628,7 @@ fn create_tuple(cx: &mut CrateContext, tuple_type: ty::t, elements: &[ty::t], sp let loc = span_start(cx, span); let file_md = create_file(cx, loc.file.name); - let name = (cx.sess.str_of((dbg_cx(cx).names)("tuple"))).to_owned(); + let name = fmt!("tuple_%u", token::gensym("tuple")); let mut scx = StructContext::new(cx, name, file_md, loc.line); for elements.iter().advance |element| { let ty_md = create_ty(cx, *element, span); @@ -911,8 +911,6 @@ fn set_debug_location(cx: @mut CrateContext, scope: DIScope, line: uint, col: ui } - - //=------------------------------------------------------------------------------------------------- // Utility Functions //=------------------------------------------------------------------------------------------------- diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 4f7ce6381d85..3d2049cb75ac 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -28,15 +28,15 @@ use middle::trans::type_of::*; use middle::ty; use middle::typeck; use util::common::indenter; -use util::ppaux::Repr; +use util::ppaux::{Repr, ty_to_str}; use middle::trans::type_::Type; -use core::str; use core::vec; use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_util; use syntax::{ast, ast_map}; +use syntax::parse::token; /** The main "translation" pass for methods. Generates code @@ -753,9 +753,10 @@ pub fn make_vtable(ccx: &mut CrateContext, components.push(ptr) } + let name = fmt!("%s_vtable_%u", ty_to_str(ccx.tcx, tydesc.ty), token::gensym("vtable")); + let tbl = C_struct(components); - let vtable = ccx.sess.str_of((ccx.names)("vtable")); - let vt_gvar = do str::as_c_str(vtable) |buf| { + let vt_gvar = do name.as_c_str |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf) }; llvm::LLVMSetInitializer(vt_gvar, tbl); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 1ffe26e3affe..586dfd7e98a0 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -161,8 +161,9 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } ccx.monomorphizing.insert(fn_id, depth + 1); - let pt = vec::append(/*bad*/copy *pt, - [path_name((ccx.names)(ccx.sess.str_of(name)))]); + let elt = path_name(gensym_name(ccx.sess.str_of(name))); + let mut pt = /* bad */copy (*pt); + pt.push(elt); let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty); let mk_lldecl = || { From 9b95b6d210a6491396311c83f0d12dfb4962d678 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Fri, 28 Jun 2013 19:02:39 +0900 Subject: [PATCH 230/336] std: adjust run.rs test for android --- src/libstd/run.rs | 152 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 3 deletions(-) diff --git a/src/libstd/run.rs b/src/libstd/run.rs index ce6a68beec75..9e5def253c7e 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -943,12 +943,20 @@ mod tests { } #[test] + #[cfg(not(target_os="android"))] fn test_process_status() { assert_eq!(run::process_status("false", []), 1); assert_eq!(run::process_status("true", []), 0); } + #[test] + #[cfg(target_os="android")] + fn test_process_status() { + assert_eq!(run::process_status("/system/bin/sh", [~"-c",~"false"]), 1); + assert_eq!(run::process_status("/system/bin/sh", [~"-c",~"true"]), 0); + } #[test] + #[cfg(not(target_os="android"))] fn test_process_output_output() { let run::ProcessOutput {status, output, error} @@ -962,8 +970,24 @@ mod tests { assert_eq!(error, ~[]); } } + #[test] + #[cfg(target_os="android")] + fn test_process_output_output() { + + let run::ProcessOutput {status, output, error} + = run::process_output("/system/bin/sh", [~"-c",~"echo hello"]); + let output_str = str::from_bytes(output); + + assert_eq!(status, 0); + assert_eq!(output_str.trim().to_owned(), ~"hello"); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } + } #[test] + #[cfg(not(target_os="android"))] fn test_process_output_error() { let run::ProcessOutput {status, output, error} @@ -973,6 +997,17 @@ mod tests { assert_eq!(output, ~[]); assert!(!error.is_empty()); } + #[test] + #[cfg(target_os="android")] + fn test_process_output_error() { + + let run::ProcessOutput {status, output, error} + = run::process_output("/system/bin/mkdir", [~"."]); + + assert_eq!(status, 255); + assert_eq!(output, ~[]); + assert!(!error.is_empty()); + } #[test] fn test_pipes() { @@ -1023,19 +1058,37 @@ mod tests { } #[test] + #[cfg(not(target_os="android"))] fn test_finish_once() { let mut prog = run::Process::new("false", [], run::ProcessOptions::new()); assert_eq!(prog.finish(), 1); } + #[test] + #[cfg(target_os="android")] + fn test_finish_once() { + let mut prog = run::Process::new("/system/bin/sh", [~"-c",~"false"], + run::ProcessOptions::new()); + assert_eq!(prog.finish(), 1); + } #[test] + #[cfg(not(target_os="android"))] fn test_finish_twice() { let mut prog = run::Process::new("false", [], run::ProcessOptions::new()); assert_eq!(prog.finish(), 1); assert_eq!(prog.finish(), 1); } + #[test] + #[cfg(target_os="android")] + fn test_finish_twice() { + let mut prog = run::Process::new("/system/bin/sh", [~"-c",~"false"], + run::ProcessOptions::new()); + assert_eq!(prog.finish(), 1); + assert_eq!(prog.finish(), 1); + } #[test] + #[cfg(not(target_os="android"))] fn test_finish_with_output_once() { let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new()); @@ -1050,8 +1103,26 @@ mod tests { assert_eq!(error, ~[]); } } + #[test] + #[cfg(target_os="android")] + fn test_finish_with_output_once() { + + let mut prog = run::Process::new("/system/bin/sh", [~"-c",~"echo hello"], + run::ProcessOptions::new()); + let run::ProcessOutput {status, output, error} + = prog.finish_with_output(); + let output_str = str::from_bytes(output); + + assert_eq!(status, 0); + assert_eq!(output_str.trim().to_owned(), ~"hello"); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } + } #[test] + #[cfg(not(target_os="android"))] fn test_finish_with_output_twice() { let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new()); @@ -1077,10 +1148,38 @@ mod tests { assert_eq!(error, ~[]); } } + #[test] + #[cfg(target_os="android")] + fn test_finish_with_output_twice() { + + let mut prog = run::Process::new("/system/bin/sh", [~"-c",~"echo hello"], + run::ProcessOptions::new()); + let run::ProcessOutput {status, output, error} + = prog.finish_with_output(); + + let output_str = str::from_bytes(output); + + assert_eq!(status, 0); + assert_eq!(output_str.trim().to_owned(), ~"hello"); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } + + let run::ProcessOutput {status, output, error} + = prog.finish_with_output(); + + assert_eq!(status, 0); + assert_eq!(output, ~[]); + // FIXME #7224 + if !running_on_valgrind() { + assert_eq!(error, ~[]); + } + } #[test] #[should_fail] - #[cfg(not(windows))] + #[cfg(not(windows),not(target_os="android"))] fn test_finish_with_output_redirected() { let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions { env: None, @@ -1092,14 +1191,36 @@ mod tests { // this should fail because it is not valid to read the output when it was redirected prog.finish_with_output(); } + #[test] + #[should_fail] + #[cfg(not(windows),target_os="android")] + fn test_finish_with_output_redirected() { + let mut prog = run::Process::new("/system/bin/sh", [~"-c",~"echo hello"], + run::ProcessOptions { + env: None, + dir: None, + in_fd: Some(0), + out_fd: Some(1), + err_fd: Some(2) + }); + // this should fail because it is not valid to read the output when it was redirected + prog.finish_with_output(); + } - #[cfg(unix)] + #[cfg(unix,not(target_os="android"))] fn run_pwd(dir: Option<&Path>) -> run::Process { run::Process::new("pwd", [], run::ProcessOptions { dir: dir, .. run::ProcessOptions::new() }) } + #[cfg(unix,target_os="android")] + fn run_pwd(dir: Option<&Path>) -> run::Process { + run::Process::new("/system/bin/sh", [~"-c",~"pwd"], run::ProcessOptions { + dir: dir, + .. run::ProcessOptions::new() + }) + } #[cfg(windows)] fn run_pwd(dir: Option<&Path>) -> run::Process { @@ -1141,13 +1262,20 @@ mod tests { assert_eq!(parent_stat.st_ino, child_stat.st_ino); } - #[cfg(unix)] + #[cfg(unix,not(target_os="android"))] fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process { run::Process::new("env", [], run::ProcessOptions { env: env, .. run::ProcessOptions::new() }) } + #[cfg(unix,target_os="android")] + fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process { + run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions { + env: env, + .. run::ProcessOptions::new() + }) + } #[cfg(windows)] fn run_env(env: Option<&[(~str, ~str)]>) -> run::Process { @@ -1158,6 +1286,7 @@ mod tests { } #[test] + #[cfg(not(target_os="android"))] fn test_inherit_env() { if running_on_valgrind() { return; } @@ -1170,6 +1299,23 @@ mod tests { assert!(k.is_empty() || output.contains(fmt!("%s=%s", k, v))); } } + #[test] + #[cfg(target_os="android")] + fn test_inherit_env() { + if running_on_valgrind() { return; } + + let mut prog = run_env(None); + let output = str::from_bytes(prog.finish_with_output().output); + + let r = os::env(); + for r.iter().advance |&(k, v)| { + // don't check android RANDOM variables + if k != ~"RANDOM" { + assert!(output.contains(fmt!("%s=%s", k, v)) || + output.contains(fmt!("%s=\'%s\'", k, v))); + } + } + } #[test] fn test_add_to_env() { From 7971202a4ea07c897eb3969e939d0979e5f7f0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Thu, 27 Jun 2013 18:47:03 +0200 Subject: [PATCH 231/336] ctags: add macros --- src/etc/ctags.rust | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/ctags.rust b/src/etc/ctags.rust index 4654116bc4d2..5c2f4f82566b 100644 --- a/src/etc/ctags.rust +++ b/src/etc/ctags.rust @@ -8,3 +8,4 @@ --regex-rust=/[ \t]*static[ \t]+([a-zA-Z0-9_]+)/\1/m,consts/ --regex-rust=/[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\1/m,traits/ --regex-rust=/[ \t]*impl[ \t]+([a-zA-Z0-9_]+)/\1/m,impls/ +--regex-rust=/[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/m,macros/ From 607b91d5f94b352f953a8503a03af50d6d4aff3b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 5 Jun 2013 11:33:14 -0700 Subject: [PATCH 232/336] librustc: Rename Owned to Send in the compiler --- src/libextra/rc.rs | 3 +- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/kind.rs | 21 ++++++------ src/librustc/middle/lang_items.rs | 24 +++++++------- src/librustc/middle/ty.rs | 46 ++++++++++++++------------- src/librustc/middle/typeck/astconv.rs | 8 ++--- src/librustc/util/ppaux.rs | 4 +-- src/libstd/kinds.rs | 9 +++++- 9 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 5b1451387e7a..8bd42eae2406 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -35,8 +35,8 @@ struct RcBox { } /// Immutable reference counted pointer type -#[non_owned] #[unsafe_no_drop_flag] +#[non_sendable] pub struct Rc { priv ptr: *mut RcBox, } @@ -168,6 +168,7 @@ struct RcMutBox { /// Mutable reference counted pointer type #[non_owned] +#[non_sendable] #[mutable] #[unsafe_no_drop_flag] pub struct RcMut { diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 717a0ecd8dfe..0aae22b40ef4 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -554,7 +554,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { loop { match next(st) { 'S' => { - param_bounds.builtin_bounds.add(ty::BoundOwned); + param_bounds.builtin_bounds.add(ty::BoundSend); } 'C' => { param_bounds.builtin_bounds.add(ty::BoundCopy); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 37fedc16122e..7c8741b41d98 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -401,7 +401,7 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) { fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) { for bs.builtin_bounds.each |bound| { match bound { - ty::BoundOwned => w.write_char('S'), + ty::BoundSend => w.write_char('S'), ty::BoundCopy => w.write_char('C'), ty::BoundConst => w.write_char('K'), ty::BoundStatic => w.write_char('O'), diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index ef96fa979727..7a615601b1e8 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -33,7 +33,7 @@ use syntax::{visit, ast_util}; // copy: Things that can be copied. // const: Things thare are deeply immutable. They are guaranteed never to // change, and can be safely shared without copying between tasks. -// owned: Things that do not contain borrowed pointers. +// 'static: Things that do not contain borrowed pointers. // // Send includes scalar types as well as classes and unique types containing // only sendable types. @@ -90,10 +90,10 @@ fn check_struct_safe_for_destructor(cx: Context, self_ty: None, tps: ~[] }); - if !ty::type_is_owned(cx.tcx, struct_ty) { + if !ty::type_is_sendable(cx.tcx, struct_ty) { cx.tcx.sess.span_err(span, - "cannot implement a destructor on a struct \ - that is not Owned"); + "cannot implement a destructor on a \ + structure that does not satisfy Send"); cx.tcx.sess.span_note(span, "use \"#[unsafe_destructor]\" on the \ implementation to force the compiler to \ @@ -101,7 +101,7 @@ fn check_struct_safe_for_destructor(cx: Context, } } else { cx.tcx.sess.span_err(span, - "cannot implement a destructor on a struct \ + "cannot implement a destructor on a structure \ with type parameters"); cx.tcx.sess.span_note(span, "use \"#[unsafe_destructor]\" on the \ @@ -438,10 +438,10 @@ fn check_copy(cx: Context, ty: ty::t, sp: span, reason: &str) { } } -pub fn check_owned(cx: Context, ty: ty::t, sp: span) -> bool { - if !ty::type_is_owned(cx.tcx, ty) { +pub fn check_send(cx: Context, ty: ty::t, sp: span) -> bool { + if !ty::type_is_sendable(cx.tcx, ty) { cx.tcx.sess.span_err( - sp, fmt!("value has non-owned type `%s`", + sp, fmt!("value has non-sendable type `%s`", ty_to_str(cx.tcx, ty))); false } else { @@ -489,7 +489,7 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool { /// `deque`, then whatever borrowed ptrs may appear in `T` also /// appear in `deque`. /// -/// (3) The type parameter is owned (and therefore does not contain +/// (3) The type parameter is sendable (and therefore does not contain /// borrowed ptrs). /// /// FIXME(#5723)---This code should probably move into regionck. @@ -528,7 +528,7 @@ pub fn check_cast_for_escaping_regions( } // Assuming the trait instance can escape, then ensure that each parameter - // either appears in the trait type or is owned. + // either appears in the trait type or is sendable. let target_params = ty::param_tys_in_type(target_ty); let source_ty = ty::expr_ty(cx.tcx, source); ty::walk_regions_and_ty( @@ -574,3 +574,4 @@ pub fn check_cast_for_escaping_regions( cx.tcx.region_maps.is_subregion_of(r_sub, r_sup) } } + diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index cd6070cc638f..8b9a3c6bdae8 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -13,7 +13,7 @@ // Language items are items that represent concepts intrinsic to the language // itself. Examples are: // -// * Traits that specify "kinds"; e.g. "const", "copy", "owned". +// * Traits that specify "kinds"; e.g. "const", "copy", "send". // // * Traits that represent operators; e.g. "add", "sub", "index". // @@ -33,9 +33,9 @@ use syntax::visit::visit_crate; use core::hashmap::HashMap; pub enum LangItem { - ConstTraitLangItem, // 0 + FreezeTraitLangItem, // 0 CopyTraitLangItem, // 1 - OwnedTraitLangItem, // 2 + SendTraitLangItem, // 2 SizedTraitLangItem, // 3 DropTraitLangItem, // 4 @@ -101,7 +101,7 @@ impl LanguageItems { match index { 0 => "const", 1 => "copy", - 2 => "owned", + 2 => "send", 3 => "sized", 4 => "drop", @@ -152,14 +152,14 @@ impl LanguageItems { // FIXME #4621: Method macros sure would be nice here. - pub fn const_trait(&const self) -> def_id { - self.items[ConstTraitLangItem as uint].get() + pub fn freeze_trait(&const self) -> def_id { + self.items[FreezeTraitLangItem as uint].get() } pub fn copy_trait(&const self) -> def_id { self.items[CopyTraitLangItem as uint].get() } - pub fn owned_trait(&const self) -> def_id { - self.items[OwnedTraitLangItem as uint].get() + pub fn send_trait(&const self) -> def_id { + self.items[SendTraitLangItem as uint].get() } pub fn sized_trait(&const self) -> def_id { self.items[SizedTraitLangItem as uint].get() @@ -291,13 +291,13 @@ struct LanguageItemCollector<'self> { } impl<'self> LanguageItemCollector<'self> { - - pub fn new<'a>(crate: &'a crate, session: Session) -> LanguageItemCollector<'a> { + pub fn new<'a>(crate: &'a crate, session: Session) + -> LanguageItemCollector<'a> { let mut item_refs = HashMap::new(); - item_refs.insert(@"const", ConstTraitLangItem as uint); + item_refs.insert(@"const", FreezeTraitLangItem as uint); item_refs.insert(@"copy", CopyTraitLangItem as uint); - item_refs.insert(@"owned", OwnedTraitLangItem as uint); + item_refs.insert(@"owned", SendTraitLangItem as uint); item_refs.insert(@"sized", SizedTraitLangItem as uint); item_refs.insert(@"drop", DropTraitLangItem as uint); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 29d81f37da7d..001ace4e7dbe 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -686,7 +686,7 @@ pub type BuiltinBounds = EnumSet; pub enum BuiltinBound { BoundCopy, BoundStatic, - BoundOwned, + BoundSend, BoundConst, BoundSized, } @@ -699,7 +699,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds { let mut set = EnumSet::empty(); set.add(BoundCopy); set.add(BoundStatic); - set.add(BoundOwned); + set.add(BoundSend); set.add(BoundConst); set.add(BoundSized); set @@ -1839,7 +1839,7 @@ impl TypeContents { BoundCopy => self.is_copy(cx), BoundStatic => self.is_static(cx), BoundConst => self.is_const(cx), - BoundOwned => self.is_owned(cx), + BoundSend => self.is_sendable(cx), BoundSized => self.is_sized(cx), } } @@ -1865,12 +1865,12 @@ impl TypeContents { TC_BORROWED_POINTER } - pub fn is_owned(&self, cx: ctxt) -> bool { - !self.intersects(TypeContents::nonowned(cx)) + pub fn is_sendable(&self, cx: ctxt) -> bool { + !self.intersects(TypeContents::nonsendable(cx)) } - pub fn nonowned(_cx: ctxt) -> TypeContents { - TC_MANAGED + TC_BORROWED_POINTER + TC_NON_OWNED + pub fn nonsendable(_cx: ctxt) -> TypeContents { + TC_MANAGED + TC_BORROWED_POINTER + TC_NON_SENDABLE } pub fn contains_managed(&self) -> bool { @@ -1912,8 +1912,8 @@ impl TypeContents { self.intersects(tc) } - pub fn owned(_cx: ctxt) -> TypeContents { - //! Any kind of owned contents. + pub fn sendable(_cx: ctxt) -> TypeContents { + //! Any kind of sendable contents. TC_OWNED_POINTER + TC_OWNED_VEC } } @@ -1969,8 +1969,8 @@ static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits: 0b0001_0000_0000}; /// An enum with no variants. static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000}; -/// Contains a type marked with `#[non_owned]` -static TC_NON_OWNED: TypeContents = TypeContents{bits: 0b0100_0000_0000}; +/// Contains a type marked with `#[non_sendable]` +static TC_NON_SENDABLE: TypeContents = TypeContents{bits: 0b0100_0000_0000}; /// Is a bare vector, str, function, trait, etc (only relevant at top level). static TC_DYNAMIC_SIZE: TypeContents = TypeContents{bits: 0b1000_0000_0000}; @@ -1986,8 +1986,8 @@ pub fn type_is_static(cx: ctxt, t: ty::t) -> bool { type_contents(cx, t).is_static(cx) } -pub fn type_is_owned(cx: ctxt, t: ty::t) -> bool { - type_contents(cx, t).is_owned(cx) +pub fn type_is_sendable(cx: ctxt, t: ty::t) -> bool { + type_contents(cx, t).is_sendable(cx) } pub fn type_is_const(cx: ctxt, t: ty::t) -> bool { @@ -2045,7 +2045,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { let _i = indenter(); let result = match get(ty).sty { - // Scalar and unique types are sendable, constant, and owned + // Scalar and unique types are sendable, constant, and durable ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_bare_fn(_) | ty_ptr(_) => { TC_NONE @@ -2060,7 +2060,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } ty_box(mt) => { - TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache))) + TC_MANAGED + + statically_sized(nonsendable(tc_mt(cx, mt, cache))) } ty_trait(_, _, store, mutbl, bounds) => { @@ -2069,7 +2070,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ty_rptr(r, mt) => { borrowed_contents(r, mt.mutbl) + - statically_sized(nonowned(tc_mt(cx, mt, cache))) + statically_sized(nonsendable(tc_mt(cx, mt, cache))) } ty_uniq(mt) => { @@ -2081,12 +2082,13 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } ty_evec(mt, vstore_box) => { - TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache))) + TC_MANAGED + + statically_sized(nonsendable(tc_mt(cx, mt, cache))) } ty_evec(mt, vstore_slice(r)) => { borrowed_contents(r, mt.mutbl) + - statically_sized(nonowned(tc_mt(cx, mt, cache))) + statically_sized(nonsendable(tc_mt(cx, mt, cache))) } ty_evec(mt, vstore_fixed(_)) => { @@ -2205,8 +2207,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { if has_attr(cx, did, "mutable") { tc += TC_MUTABLE; } - if has_attr(cx, did, "non_owned") { - tc += TC_NON_OWNED; + if has_attr(cx, did, "non_sendable") { + tc += TC_NON_SENDABLE; } tc } @@ -2227,7 +2229,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { mc + rc } - fn nonowned(pointee: TypeContents) -> TypeContents { + fn nonsendable(pointee: TypeContents) -> TypeContents { /*! * * Given a non-owning pointer to some type `T` with @@ -2314,7 +2316,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { tc = tc - match bound { BoundCopy => TypeContents::noncopyable(cx), BoundStatic => TypeContents::nonstatic(cx), - BoundOwned => TypeContents::nonowned(cx), + BoundSend => TypeContents::nonsendable(cx), BoundConst => TypeContents::nonconst(cx), // The dynamic-size bit can be removed at pointer-level, etc. BoundSized => TypeContents::dynamically_sized(cx), diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index b7242e64f230..0608d27cf6ce 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -753,7 +753,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option bool { //! Checks whether `trait_ref` refers to one of the builtin - //! traits, like `Copy` or `Owned`, and adds the corresponding + //! traits, like `Copy` or `Send`, and adds the corresponding //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref` //! is a builtin trait. let li = &tcx.lang_items; - if trait_def_id == li.owned_trait() { - builtin_bounds.add(ty::BoundOwned); + if trait_def_id == li.send_trait() { + builtin_bounds.add(ty::BoundSend); true } else if trait_def_id == li.copy_trait() { builtin_bounds.add(ty::BoundCopy); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 3194df269c0e..559d478e7638 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -575,7 +575,7 @@ impl Repr for ty::ParamBounds { res.push(match b { ty::BoundCopy => ~"Copy", ty::BoundStatic => ~"'static", - ty::BoundOwned => ~"Owned", + ty::BoundSend => ~"Send", ty::BoundConst => ~"Const", ty::BoundSized => ~"Sized", }); @@ -781,7 +781,7 @@ impl UserString for ty::BuiltinBound { match *self { ty::BoundCopy => ~"Copy", ty::BoundStatic => ~"'static", - ty::BoundOwned => ~"Owned", + ty::BoundSend => ~"Send", ty::BoundConst => ~"Const", ty::BoundSized => ~"Sized", } diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index 05c963a32cc7..123468cad88e 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -44,9 +44,16 @@ pub trait Copy { // Empty. } +#[cfg(stage0)] #[lang="owned"] pub trait Owned { - // Empty. + // empty. +} + +#[cfg(not(stage0))] +#[lang="send"] +pub trait Owned { + // empty. } #[lang="const"] From d350981c0e8daa778d9760ba0e19b3157026e743 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 5 Jun 2013 14:52:27 -0700 Subject: [PATCH 233/336] librustc: Change Const to Freeze in the compiler --- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/kind.rs | 8 ++++---- src/librustc/middle/lang_items.rs | 6 +++--- src/librustc/middle/ty.rs | 20 ++++++++++---------- src/librustc/middle/typeck/astconv.rs | 4 ++-- src/librustc/util/ppaux.rs | 4 ++-- src/libstd/kinds.rs | 12 +++++++++--- src/libstd/prelude.rs | 3 ++- 9 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 0aae22b40ef4..1507fc186e7a 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -560,7 +560,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { param_bounds.builtin_bounds.add(ty::BoundCopy); } 'K' => { - param_bounds.builtin_bounds.add(ty::BoundConst); + param_bounds.builtin_bounds.add(ty::BoundFreeze); } 'O' => { param_bounds.builtin_bounds.add(ty::BoundStatic); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 7c8741b41d98..0f9937fd3c0c 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -403,7 +403,7 @@ fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) { match bound { ty::BoundSend => w.write_char('S'), ty::BoundCopy => w.write_char('C'), - ty::BoundConst => w.write_char('K'), + ty::BoundFreeze => w.write_char('K'), ty::BoundStatic => w.write_char('O'), ty::BoundSized => w.write_char('Z'), } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 7a615601b1e8..f0c091ac53ca 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -31,7 +31,7 @@ use syntax::{visit, ast_util}; // // send: Things that can be sent on channels or included in spawned closures. // copy: Things that can be copied. -// const: Things thare are deeply immutable. They are guaranteed never to +// freeze: Things thare are deeply immutable. They are guaranteed never to // change, and can be safely shared without copying between tasks. // 'static: Things that do not contain borrowed pointers. // @@ -40,12 +40,12 @@ use syntax::{visit, ast_util}; // // Copy includes boxes, closure and unique types containing copyable types. // -// Const include scalar types, things without non-const fields, and pointers -// to const things. +// Freeze include scalar types, things without non-const fields, and pointers +// to freezable things. // // This pass ensures that type parameters are only instantiated with types // whose kinds are equal or less general than the way the type parameter was -// annotated (with the `send`, `copy` or `const` keyword). +// annotated (with the `Send`, `Copy` or `Freeze` bound). // // It also verifies that noncopyable kinds are not copied. Sendability is not // applied, since none of our language primitives send. Instead, the sending diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 8b9a3c6bdae8..3418fc649da0 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -13,9 +13,9 @@ // Language items are items that represent concepts intrinsic to the language // itself. Examples are: // -// * Traits that specify "kinds"; e.g. "const", "copy", "send". +// * Traits that specify "kinds"; e.g. "Freeze", "Copy", "Send". // -// * Traits that represent operators; e.g. "add", "sub", "index". +// * Traits that represent operators; e.g. "Add", "Sub", "Index". // // * Functions called by the compiler itself. @@ -99,7 +99,7 @@ impl LanguageItems { pub fn item_name(index: uint) -> &'static str { match index { - 0 => "const", + 0 => "freeze", 1 => "copy", 2 => "send", 3 => "sized", diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 001ace4e7dbe..81a1ef6563f4 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -687,7 +687,7 @@ pub enum BuiltinBound { BoundCopy, BoundStatic, BoundSend, - BoundConst, + BoundFreeze, BoundSized, } @@ -700,7 +700,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds { set.add(BoundCopy); set.add(BoundStatic); set.add(BoundSend); - set.add(BoundConst); + set.add(BoundFreeze); set.add(BoundSized); set } @@ -1838,7 +1838,7 @@ impl TypeContents { match bb { BoundCopy => self.is_copy(cx), BoundStatic => self.is_static(cx), - BoundConst => self.is_const(cx), + BoundFreeze => self.is_freezable(cx), BoundSend => self.is_sendable(cx), BoundSized => self.is_sized(cx), } @@ -1877,11 +1877,11 @@ impl TypeContents { self.intersects(TC_MANAGED) } - pub fn is_const(&self, cx: ctxt) -> bool { - !self.intersects(TypeContents::nonconst(cx)) + pub fn is_freezable(&self, cx: ctxt) -> bool { + !self.intersects(TypeContents::nonfreezable(cx)) } - pub fn nonconst(_cx: ctxt) -> TypeContents { + pub fn nonfreezable(_cx: ctxt) -> TypeContents { TC_MUTABLE } @@ -1990,8 +1990,8 @@ pub fn type_is_sendable(cx: ctxt, t: ty::t) -> bool { type_contents(cx, t).is_sendable(cx) } -pub fn type_is_const(cx: ctxt, t: ty::t) -> bool { - type_contents(cx, t).is_const(cx) +pub fn type_is_freezable(cx: ctxt, t: ty::t) -> bool { + type_contents(cx, t).is_freezable(cx) } pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { @@ -2045,7 +2045,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { let _i = indenter(); let result = match get(ty).sty { - // Scalar and unique types are sendable, constant, and durable + // Scalar and unique types are sendable, freezable, and durable ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_bare_fn(_) | ty_ptr(_) => { TC_NONE @@ -2317,7 +2317,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { BoundCopy => TypeContents::noncopyable(cx), BoundStatic => TypeContents::nonstatic(cx), BoundSend => TypeContents::nonsendable(cx), - BoundConst => TypeContents::nonconst(cx), + BoundFreeze => TypeContents::nonfreezable(cx), // The dynamic-size bit can be removed at pointer-level, etc. BoundSized => TypeContents::dynamically_sized(cx), }; diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 0608d27cf6ce..70df9877162e 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -818,8 +818,8 @@ pub fn try_add_builtin_trait(tcx: ty::ctxt, } else if trait_def_id == li.copy_trait() { builtin_bounds.add(ty::BoundCopy); true - } else if trait_def_id == li.const_trait() { - builtin_bounds.add(ty::BoundConst); + } else if trait_def_id == li.freeze_trait() { + builtin_bounds.add(ty::BoundFreeze); true } else if trait_def_id == li.sized_trait() { builtin_bounds.add(ty::BoundSized); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 559d478e7638..58dc121959ed 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -576,7 +576,7 @@ impl Repr for ty::ParamBounds { ty::BoundCopy => ~"Copy", ty::BoundStatic => ~"'static", ty::BoundSend => ~"Send", - ty::BoundConst => ~"Const", + ty::BoundFreeze => ~"Freeze", ty::BoundSized => ~"Sized", }); } @@ -782,7 +782,7 @@ impl UserString for ty::BuiltinBound { ty::BoundCopy => ~"Copy", ty::BoundStatic => ~"'static", ty::BoundSend => ~"Send", - ty::BoundConst => ~"Const", + ty::BoundFreeze => ~"Freeze", ty::BoundSized => ~"Sized", } } diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index 123468cad88e..b7ec90574e29 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -27,8 +27,7 @@ The 4 kinds are * Owned - owned types and types containing owned types. These types may be transferred across task boundaries. -* Const - types that are deeply immutable. Const types are used for - freezable data structures. +* Freeze - types that are deeply immutable. `Copy` types include both implicitly copyable types that the compiler will copy automatically and non-implicitly copyable types that require @@ -56,9 +55,16 @@ pub trait Owned { // empty. } +#[cfg(stage0)] #[lang="const"] pub trait Const { - // Empty. + // empty. +} + +#[cfg(not(stage0))] +#[lang="freeze"] +pub trait Const { + // empty. } #[lang="sized"] diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 6d7cb2a28a88..8e240a62236f 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -29,7 +29,8 @@ Rust's prelude has three main parts: // Reexported core operators pub use either::{Either, Left, Right}; -pub use kinds::{Const, Copy, Owned, Sized}; +pub use kinds::{Copy, Sized}; +pub use kinds::{Const, Owned}; pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not}; pub use ops::{BitAnd, BitOr, BitXor}; pub use ops::{Drop}; From 1eec3bba13fef50324d1a7542713b3189a627547 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 5 Jun 2013 15:53:17 -0700 Subject: [PATCH 234/336] librustc: Rename Const to Freeze --- src/libextra/arc.rs | 20 +++++++++---------- src/libextra/rc.rs | 8 ++++---- src/librustc/middle/borrowck/doc.rs | 4 ++-- .../borrowck/gather_loans/restrictions.rs | 2 +- src/librustc/middle/typeck/collect.rs | 2 +- src/librustdoc/markdown_pass.rs | 4 ++-- src/libstd/clone.rs | 10 +++++----- src/libstd/kinds.rs | 4 ++-- src/libstd/prelude.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/util/interner.rs | 2 +- src/test/auxiliary/issue-2526.rs | 6 +++--- src/test/compile-fail/issue-2611-4.rs | 2 +- .../compile-fail/issue-3177-mutable-struct.rs | 2 +- src/test/compile-fail/mutable-enum.rs | 4 ++-- src/test/compile-fail/mutable-struct.rs | 4 ++-- src/test/run-pass/const-bound.rs | 2 +- src/test/run-pass/issue-2611-3.rs | 2 +- 19 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 5e3b60bb3a8c..e0ab2558e3fe 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -112,7 +112,7 @@ impl<'self> Condvar<'self> { pub struct ARC { x: UnsafeAtomicRcBox } /// Create an atomically reference counted wrapper. -pub fn ARC(data: T) -> ARC { +pub fn ARC(data: T) -> ARC { ARC { x: UnsafeAtomicRcBox::new(data) } } @@ -120,7 +120,7 @@ pub fn ARC(data: T) -> ARC { * Access the underlying data in an atomically reference counted * wrapper. */ -impl ARC { +impl ARC { pub fn get<'a>(&'a self) -> &'a T { unsafe { &*self.x.get_immut() } } @@ -133,7 +133,7 @@ impl ARC { * object. However, one of the `arc` objects can be sent to another task, * allowing them to share the underlying data. */ -impl Clone for ARC { +impl Clone for ARC { fn clone(&self) -> ARC { ARC { x: self.x.clone() } } @@ -282,14 +282,14 @@ struct RWARC { } /// Create a reader/writer ARC with the supplied data. -pub fn RWARC(user_data: T) -> RWARC { +pub fn RWARC(user_data: T) -> RWARC { rw_arc_with_condvars(user_data, 1) } /** * Create a reader/writer ARC with the supplied data and a specified number * of condvars (as sync::rwlock_with_condvars). */ -pub fn rw_arc_with_condvars( +pub fn rw_arc_with_condvars( user_data: T, num_condvars: uint) -> RWARC { @@ -299,7 +299,7 @@ pub fn rw_arc_with_condvars( RWARC { x: UnsafeAtomicRcBox::new(data), } } -impl RWARC { +impl RWARC { /// Duplicate a rwlock-protected ARC, as arc::clone. pub fn clone(&self) -> RWARC { RWARC { @@ -309,7 +309,7 @@ impl RWARC { } -impl RWARC { +impl RWARC { /** * Access the underlying data mutably. Locks the rwlock in write mode; * other readers and writers will block. @@ -435,7 +435,7 @@ impl RWARC { // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. #[doc(hidden)] -fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { +fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { unsafe { cast::transmute(&const (*state).lock) } } @@ -452,7 +452,7 @@ pub struct RWReadMode<'self, T> { token: sync::RWlockReadMode<'self>, } -impl<'self, T:Const + Owned> RWWriteMode<'self, T> { +impl<'self, T:Freeze + Owned> RWWriteMode<'self, T> { /// Access the pre-downgrade RWARC in write mode. pub fn write(&mut self, blk: &fn(x: &mut T) -> U) -> U { match *self { @@ -493,7 +493,7 @@ impl<'self, T:Const + Owned> RWWriteMode<'self, T> { } } -impl<'self, T:Const + Owned> RWReadMode<'self, T> { +impl<'self, T:Freeze + Owned> RWReadMode<'self, T> { /// Access the post-downgrade rwlock in read mode. pub fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 8bd42eae2406..ca3229d4b25c 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -13,10 +13,10 @@ /** Task-local reference counted smart pointers Task-local reference counted smart pointers are an alternative to managed boxes with deterministic -destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to +destruction. They are restricted to containing types that are either `Owned` or `Freeze` (or both) to prevent cycles. -Neither `Rc` or `RcMut` is ever `Owned` and `RcMut` is never `Const`. If `T` is `Const`, a +Neither `Rc` or `RcMut` is ever `Owned` and `RcMut` is never `Freeze`. If `T` is `Freeze`, a cycle cannot be created with `Rc` because there is no way to modify it after creation. */ @@ -56,7 +56,7 @@ pub fn rc_from_owned(value: T) -> Rc { } // FIXME: #6516: should be a static method -pub fn rc_from_const(value: T) -> Rc { +pub fn rc_from_const(value: T) -> Rc { unsafe { Rc::new(value) } } @@ -190,7 +190,7 @@ pub fn rc_mut_from_owned(value: T) -> RcMut { } // FIXME: #6516: should be a static method -pub fn rc_mut_from_const(value: T) -> RcMut { +pub fn rc_mut_from_const(value: T) -> RcMut { unsafe { RcMut::new(value) } } diff --git a/src/librustc/middle/borrowck/doc.rs b/src/librustc/middle/borrowck/doc.rs index cb3983117e97..7a91f204b131 100644 --- a/src/librustc/middle/borrowck/doc.rs +++ b/src/librustc/middle/borrowck/doc.rs @@ -539,14 +539,14 @@ mutable borrowed pointers. ### Restrictions for loans of const aliasable pointees -Const pointers are read-only. There may be `&mut` or `&` aliases, and +Freeze pointers are read-only. There may be `&mut` or `&` aliases, and we can not prevent *anything* but moves in that case. So the `RESTRICTIONS` function is only defined if `ACTIONS` is the empty set. Because moves from a `&const` or `@const` lvalue are never legal, it is not necessary to add any restrictions at all to the final result. - RESTRICTIONS(*LV, []) = [] // R-Deref-Const-Borrowed + RESTRICTIONS(*LV, []) = [] // R-Deref-Freeze-Borrowed TYPE(LV) = &const Ty or @const Ty ### Restrictions for loans of mutable borrowed pointees diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index bedb465c5c14..a867ea948025 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -125,7 +125,7 @@ impl RestrictionsContext { mc::cat_deref(_, _, mc::region_ptr(m_const, _)) | mc::cat_deref(_, _, mc::gc_ptr(m_const)) => { - // R-Deref-Const-Borrowed + // R-Deref-Freeze-Borrowed self.check_no_mutability_control(cmt, restrictions); Safe } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 0e118adb8f42..94520b6faca6 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1165,7 +1165,7 @@ pub fn ty_generics(ccx: &CrateCtxt, * enum consisting of a newtyped Ty or a region) to ty's * notion of ty param bounds, which can either be user-defined * traits, or one of the four built-in traits (formerly known - * as kinds): Const, Copy, and Send. + * as kinds): Freeze, Copy, and Send. */ let mut param_bounds = ty::ParamBounds { diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index 6622ea1551bf..ca167c3726ae 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -152,7 +152,7 @@ pub fn header_kind(doc: doc::ItemTag) -> ~str { ~"Function" } doc::ConstTag(_) => { - ~"Const" + ~"Freeze" } doc::EnumTag(_) => { ~"Enum" @@ -786,7 +786,7 @@ mod test { #[test] fn should_write_const_header() { let markdown = render(~"static a: bool = true;"); - assert!(markdown.contains("## Const `a`\n\n")); + assert!(markdown.contains("## Freeze `a`\n\n")); } #[test] diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index 046693632c60..4a85a8c871d6 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -22,7 +22,7 @@ by convention implementing the `Clone` trait and calling the */ -use core::kinds::Const; +use core::kinds::Freeze; /// A common trait for cloning an object. pub trait Clone { @@ -113,16 +113,16 @@ impl DeepClone for ~T { } // FIXME: #6525: should also be implemented for `T: Owned + DeepClone` -impl DeepClone for @T { - /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing +impl DeepClone for @T { + /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. #[inline] fn deep_clone(&self) -> @T { @(**self).deep_clone() } } // FIXME: #6525: should also be implemented for `T: Owned + DeepClone` -impl DeepClone for @mut T { - /// Return a deep copy of the managed box. The `Const` trait is required to prevent performing +impl DeepClone for @mut T { + /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. #[inline] fn deep_clone(&self) -> @mut T { @mut (**self).deep_clone() } diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index b7ec90574e29..9d5348ff98f0 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -57,13 +57,13 @@ pub trait Owned { #[cfg(stage0)] #[lang="const"] -pub trait Const { +pub trait Freeze { // empty. } #[cfg(not(stage0))] #[lang="freeze"] -pub trait Const { +pub trait Freeze { // empty. } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 8e240a62236f..5959cdaf318c 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -30,7 +30,7 @@ Rust's prelude has three main parts: // Reexported core operators pub use either::{Either, Left, Right}; pub use kinds::{Copy, Sized}; -pub use kinds::{Const, Owned}; +pub use kinds::{Freeze, Owned}; pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not}; pub use ops::{BitAnd, BitOr, BitXor}; pub use ops::{Drop}; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index feb03896558e..a9b0c3986f8b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -147,7 +147,7 @@ pub static crate_node_id: node_id = 0; // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and -// detects Copy, Send, Owned, and Const. +// detects Copy, Send, Owned, and Freeze. pub enum TyParamBound { TraitTyParamBound(@trait_ref), RegionTyParamBound diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 2ddae73a3fcd..df599596d7d0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -563,7 +563,7 @@ pub mod keywords { // Strict keywords As, Break, - Const, + Freeze, Copy, Do, Else, diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index af37c1d27d82..3cdc4fd0fa10 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -21,7 +21,7 @@ pub struct Interner { } // when traits can extend traits, we should extend index to get [] -impl Interner { +impl Interner { pub fn new() -> Interner { Interner { map: @mut HashMap::new(), diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index d4f6a1ec4040..8c491a4dfc83 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -20,17 +20,17 @@ struct arc_destruct { } #[unsafe_destructor] -impl Drop for arc_destruct { +impl Drop for arc_destruct { fn drop(&self) {} } -fn arc_destruct(data: int) -> arc_destruct { +fn arc_destruct(data: int) -> arc_destruct { arc_destruct { _data: data } } -fn arc(_data: T) -> arc_destruct { +fn arc(_data: T) -> arc_destruct { arc_destruct(0) } diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs index 2385be5723e2..531d4eab5357 100644 --- a/src/test/compile-fail/issue-2611-4.rs +++ b/src/test/compile-fail/issue-2611-4.rs @@ -20,7 +20,7 @@ struct E { } impl A for E { - fn b(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Const` + fn b(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Freeze` } fn main() {} diff --git a/src/test/compile-fail/issue-3177-mutable-struct.rs b/src/test/compile-fail/issue-3177-mutable-struct.rs index 31c0dc7d9c4e..180f13d03719 100644 --- a/src/test/compile-fail/issue-3177-mutable-struct.rs +++ b/src/test/compile-fail/issue-3177-mutable-struct.rs @@ -10,7 +10,7 @@ // xfail-test // error-pattern: instantiating a type parameter with an incompatible type -struct S { +struct S { s: T, cant_nest: () } diff --git a/src/test/compile-fail/mutable-enum.rs b/src/test/compile-fail/mutable-enum.rs index 2368e5eb5c51..db2172b2e570 100644 --- a/src/test/compile-fail/mutable-enum.rs +++ b/src/test/compile-fail/mutable-enum.rs @@ -11,9 +11,9 @@ #[mutable] enum Foo { A } -fn bar(_: T) {} +fn bar(_: T) {} fn main() { let x = A; - bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Const` + bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Freeze` } diff --git a/src/test/compile-fail/mutable-struct.rs b/src/test/compile-fail/mutable-struct.rs index ee040506c40b..8511bcdcd350 100644 --- a/src/test/compile-fail/mutable-struct.rs +++ b/src/test/compile-fail/mutable-struct.rs @@ -11,9 +11,9 @@ #[mutable] struct Foo { a: int } -fn bar(_: T) {} +fn bar(_: T) {} fn main() { let x = Foo { a: 5 }; - bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Const` + bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Freeze` } diff --git a/src/test/run-pass/const-bound.rs b/src/test/run-pass/const-bound.rs index 685d86c740d9..05f586f76e95 100644 --- a/src/test/run-pass/const-bound.rs +++ b/src/test/run-pass/const-bound.rs @@ -12,7 +12,7 @@ // are const. -fn foo(x: T) -> T { x } +fn foo(x: T) -> T { x } struct F { field: int } diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs index acc6ffd0dd1b..7f6535526312 100644 --- a/src/test/run-pass/issue-2611-3.rs +++ b/src/test/run-pass/issue-2611-3.rs @@ -12,7 +12,7 @@ // than the traits require. trait A { - fn b(x: C) -> C; + fn b(x: C) -> C; } struct E { From 1c0aa7848103b5018473df851bc115d3e5585185 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 5 Jun 2013 17:56:24 -0700 Subject: [PATCH 235/336] librustc: Change "Owned" to "Send" everywhere --- src/libextra/arc.rs | 28 ++--- src/libextra/comm.rs | 14 +-- src/libextra/flatpipes.rs | 24 ++--- src/libextra/future.rs | 4 +- src/libextra/par.rs | 10 +- src/libextra/rc.rs | 8 +- src/libextra/sync.rs | 6 +- src/libextra/timer.rs | 4 +- src/libextra/workcache.rs | 10 +- src/librustc/middle/borrowck/doc.rs | 4 +- .../middle/borrowck/gather_loans/lifetime.rs | 2 +- .../borrowck/gather_loans/restrictions.rs | 2 +- src/librustc/middle/typeck/check/_match.rs | 8 +- src/librustdoc/astsrv.rs | 2 +- src/librustdoc/attr_pass.rs | 2 +- src/libstd/clone.rs | 4 +- src/libstd/comm.rs | 100 +++++++++--------- src/libstd/kinds.rs | 6 +- src/libstd/pipes.rs | 34 +++--- src/libstd/prelude.rs | 2 +- src/libstd/rt/comm.rs | 10 +- src/libstd/rt/message_queue.rs | 4 +- src/libstd/rt/work_queue.rs | 4 +- src/libstd/task/mod.rs | 8 +- src/libstd/unstable/global.rs | 14 +-- src/libstd/unstable/sync.rs | 12 +-- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/deriving/to_str.rs | 2 +- src/libsyntax/ext/deriving/ty.rs | 6 +- src/test/auxiliary/cci_capture_clause.rs | 2 +- src/test/bench/pingpong.rs | 6 +- .../compile-fail/closure-bounds-subtype.rs | 14 +-- src/test/compile-fail/issue-2766-a.rs | 6 +- .../compile-fail/kindck-destructor-owned.rs | 2 +- .../compile-fail/liveness-use-after-send.rs | 2 +- src/test/compile-fail/non_owned-enum.rs | 4 +- src/test/compile-fail/non_owned-struct.rs | 4 +- src/test/compile-fail/unique-unique-kind.rs | 4 +- src/test/compile-fail/unsendable-class.rs | 4 +- src/test/run-fail/bug-811.rs | 2 +- src/test/run-pass/alignment-gep-tup-like-2.rs | 2 +- src/test/run-pass/fixed-point-bind-unique.rs | 4 +- src/test/run-pass/fn-bare-spawn.rs | 2 +- src/test/run-pass/generic-alias-unique.rs | 2 +- src/test/run-pass/issue-2718.rs | 24 ++--- src/test/run-pass/issue-2834.rs | 2 +- src/test/run-pass/issue-2930.rs | 2 +- src/test/run-pass/pipe-bank-proto.rs | 4 +- src/test/run-pass/pipe-select.rs | 4 +- src/test/run-pass/pipe-sleep.rs | 2 +- src/test/run-pass/send-type-inference.rs | 2 +- src/test/run-pass/type-param-constraints.rs | 2 +- src/test/run-pass/uniq-cc-generic.rs | 2 +- src/test/run-pass/unique-kinds.rs | 4 +- 54 files changed, 222 insertions(+), 222 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index e0ab2558e3fe..2fb03fecb598 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -112,7 +112,7 @@ impl<'self> Condvar<'self> { pub struct ARC { x: UnsafeAtomicRcBox } /// Create an atomically reference counted wrapper. -pub fn ARC(data: T) -> ARC { +pub fn ARC(data: T) -> ARC { ARC { x: UnsafeAtomicRcBox::new(data) } } @@ -120,7 +120,7 @@ pub fn ARC(data: T) -> ARC { * Access the underlying data in an atomically reference counted * wrapper. */ -impl ARC { +impl ARC { pub fn get<'a>(&'a self) -> &'a T { unsafe { &*self.x.get_immut() } } @@ -133,7 +133,7 @@ impl ARC { * object. However, one of the `arc` objects can be sent to another task, * allowing them to share the underlying data. */ -impl Clone for ARC { +impl Clone for ARC { fn clone(&self) -> ARC { ARC { x: self.x.clone() } } @@ -149,14 +149,14 @@ struct MutexARCInner { lock: Mutex, failed: bool, data: T } struct MutexARC { x: UnsafeAtomicRcBox> } /// Create a mutex-protected ARC with the supplied data. -pub fn MutexARC(user_data: T) -> MutexARC { +pub fn MutexARC(user_data: T) -> MutexARC { mutex_arc_with_condvars(user_data, 1) } /** * Create a mutex-protected ARC with the supplied data and a specified number * of condvars (as sync::mutex_with_condvars). */ -pub fn mutex_arc_with_condvars(user_data: T, +pub fn mutex_arc_with_condvars(user_data: T, num_condvars: uint) -> MutexARC { let data = MutexARCInner { lock: mutex_with_condvars(num_condvars), @@ -164,7 +164,7 @@ pub fn mutex_arc_with_condvars(user_data: T, MutexARC { x: UnsafeAtomicRcBox::new(data) } } -impl Clone for MutexARC { +impl Clone for MutexARC { /// Duplicate a mutex-protected ARC, as arc::clone. fn clone(&self) -> MutexARC { // NB: Cloning the underlying mutex is not necessary. Its reference @@ -173,7 +173,7 @@ impl Clone for MutexARC { } } -impl MutexARC { +impl MutexARC { /** * Access the underlying mutable data with mutual exclusion from other @@ -282,14 +282,14 @@ struct RWARC { } /// Create a reader/writer ARC with the supplied data. -pub fn RWARC(user_data: T) -> RWARC { +pub fn RWARC(user_data: T) -> RWARC { rw_arc_with_condvars(user_data, 1) } /** * Create a reader/writer ARC with the supplied data and a specified number * of condvars (as sync::rwlock_with_condvars). */ -pub fn rw_arc_with_condvars( +pub fn rw_arc_with_condvars( user_data: T, num_condvars: uint) -> RWARC { @@ -299,7 +299,7 @@ pub fn rw_arc_with_condvars( RWARC { x: UnsafeAtomicRcBox::new(data), } } -impl RWARC { +impl RWARC { /// Duplicate a rwlock-protected ARC, as arc::clone. pub fn clone(&self) -> RWARC { RWARC { @@ -309,7 +309,7 @@ impl RWARC { } -impl RWARC { +impl RWARC { /** * Access the underlying data mutably. Locks the rwlock in write mode; * other readers and writers will block. @@ -435,7 +435,7 @@ impl RWARC { // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. #[doc(hidden)] -fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { +fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { unsafe { cast::transmute(&const (*state).lock) } } @@ -452,7 +452,7 @@ pub struct RWReadMode<'self, T> { token: sync::RWlockReadMode<'self>, } -impl<'self, T:Freeze + Owned> RWWriteMode<'self, T> { +impl<'self, T:Freeze + Send> RWWriteMode<'self, T> { /// Access the pre-downgrade RWARC in write mode. pub fn write(&mut self, blk: &fn(x: &mut T) -> U) -> U { match *self { @@ -493,7 +493,7 @@ impl<'self, T:Freeze + Owned> RWWriteMode<'self, T> { } } -impl<'self, T:Freeze + Owned> RWReadMode<'self, T> { +impl<'self, T:Freeze + Send> RWReadMode<'self, T> { /// Access the post-downgrade rwlock in read mode. pub fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { diff --git a/src/libextra/comm.rs b/src/libextra/comm.rs index 1001d4f6ac9e..2cb2128db5f7 100644 --- a/src/libextra/comm.rs +++ b/src/libextra/comm.rs @@ -30,7 +30,7 @@ pub struct DuplexStream { } // Allow these methods to be used without import: -impl DuplexStream { +impl DuplexStream { pub fn send(&self, x: T) { self.chan.send(x) } @@ -48,19 +48,19 @@ impl DuplexStream { } } -impl GenericChan for DuplexStream { +impl GenericChan for DuplexStream { fn send(&self, x: T) { self.chan.send(x) } } -impl GenericSmartChan for DuplexStream { +impl GenericSmartChan for DuplexStream { fn try_send(&self, x: T) -> bool { self.chan.try_send(x) } } -impl GenericPort for DuplexStream { +impl GenericPort for DuplexStream { fn recv(&self) -> U { self.port.recv() } @@ -70,20 +70,20 @@ impl GenericPort for DuplexStream { } } -impl Peekable for DuplexStream { +impl Peekable for DuplexStream { fn peek(&self) -> bool { self.port.peek() } } -impl Selectable for DuplexStream { +impl Selectable for DuplexStream { fn header(&mut self) -> *mut pipes::PacketHeader { self.port.header() } } /// Creates a bidirectional stream. -pub fn DuplexStream() +pub fn DuplexStream() -> (DuplexStream, DuplexStream) { let (p1, c2) = comm::stream(); diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index 60fbfdeb62c1..d5e43e85a140 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -166,8 +166,8 @@ Constructors for flat pipes that send POD types using memcpy. # Safety Note -This module is currently unsafe because it uses `Copy Owned` as a type -parameter bounds meaning POD (plain old data), but `Copy Owned` and +This module is currently unsafe because it uses `Copy Send` as a type +parameter bounds meaning POD (plain old data), but `Copy Send` and POD are not equivelant. */ @@ -191,7 +191,7 @@ pub mod pod { pub type PipeChan = FlatChan, PipeByteChan>; /// Create a `FlatPort` from a `Reader` - pub fn reader_port( + pub fn reader_port( reader: R ) -> ReaderPort { let unflat: PodUnflattener = PodUnflattener::new(); @@ -200,7 +200,7 @@ pub mod pod { } /// Create a `FlatChan` from a `Writer` - pub fn writer_chan( + pub fn writer_chan( writer: W ) -> WriterChan { let flat: PodFlattener = PodFlattener::new(); @@ -209,21 +209,21 @@ pub mod pod { } /// Create a `FlatPort` from a `Port<~[u8]>` - pub fn pipe_port(port: Port<~[u8]>) -> PipePort { + pub fn pipe_port(port: Port<~[u8]>) -> PipePort { let unflat: PodUnflattener = PodUnflattener::new(); let byte_port = PipeBytePort::new(port); FlatPort::new(unflat, byte_port) } /// Create a `FlatChan` from a `Chan<~[u8]>` - pub fn pipe_chan(chan: Chan<~[u8]>) -> PipeChan { + pub fn pipe_chan(chan: Chan<~[u8]>) -> PipeChan { let flat: PodFlattener = PodFlattener::new(); let byte_chan = PipeByteChan::new(chan); FlatChan::new(flat, byte_chan) } /// Create a pair of `FlatChan` and `FlatPort`, backed by pipes - pub fn pipe_stream() -> (PipePort, PipeChan) { + pub fn pipe_stream() -> (PipePort, PipeChan) { let (port, chan) = comm::stream(); return (pipe_port(port), pipe_chan(chan)); } @@ -352,7 +352,7 @@ pub mod flatteners { use core::sys::size_of; use core::vec; - // FIXME #4074: Copy + Owned != POD + // FIXME #4074: Copy + Send != POD pub struct PodUnflattener { bogus: () } @@ -361,7 +361,7 @@ pub mod flatteners { bogus: () } - impl Unflattener for PodUnflattener { + impl Unflattener for PodUnflattener { fn unflatten(&self, buf: ~[u8]) -> T { assert!(size_of::() != 0); assert_eq!(size_of::(), buf.len()); @@ -371,7 +371,7 @@ pub mod flatteners { } } - impl Flattener for PodFlattener { + impl Flattener for PodFlattener { fn flatten(&self, val: T) -> ~[u8] { assert!(size_of::() != 0); let val: *T = ptr::to_unsafe_ptr(&val); @@ -380,7 +380,7 @@ pub mod flatteners { } } - impl PodUnflattener { + impl PodUnflattener { pub fn new() -> PodUnflattener { PodUnflattener { bogus: () @@ -388,7 +388,7 @@ pub mod flatteners { } } - impl PodFlattener { + impl PodFlattener { pub fn new() -> PodFlattener { PodFlattener { bogus: () diff --git a/src/libextra/future.rs b/src/libextra/future.rs index f2cd64085eff..00f4cc3989be 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -101,7 +101,7 @@ pub fn from_value(val: A) -> Future { Future {state: Forced(val)} } -pub fn from_port(port: PortOne) -> Future { +pub fn from_port(port: PortOne) -> Future { /*! * Create a future from a port * @@ -127,7 +127,7 @@ pub fn from_fn(f: ~fn() -> A) -> Future { Future {state: Pending(f)} } -pub fn spawn(blk: ~fn() -> A) -> Future { +pub fn spawn(blk: ~fn() -> A) -> Future { /*! * Create a future from a unique closure. * diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 334ab7c9c990..a3014cf8894b 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -33,7 +33,7 @@ static min_granularity : uint = 1024u; * This is used to build most of the other parallel vector functions, * like map or alli. */ -fn map_slices( +fn map_slices( xs: &[A], f: &fn() -> ~fn(uint, v: &[A]) -> B) -> ~[B] { @@ -88,7 +88,7 @@ fn map_slices( } /// A parallel version of map. -pub fn map( +pub fn map( xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] { vec::concat(map_slices(xs, || { let f = fn_factory(); @@ -99,7 +99,7 @@ pub fn map( } /// A parallel version of mapi. -pub fn mapi( +pub fn mapi( xs: &[A], fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] { let slices = map_slices(xs, || { @@ -118,7 +118,7 @@ pub fn mapi( } /// Returns true if the function holds for all elements in the vector. -pub fn alli( +pub fn alli( xs: &[A], fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool { @@ -133,7 +133,7 @@ pub fn alli( } /// Returns true if the function holds for any elements in the vector. -pub fn any( +pub fn any( xs: &[A], fn_factory: &fn() -> ~fn(&A) -> bool) -> bool { let mapped = map_slices(xs, || { diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index ca3229d4b25c..009d68ac0260 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -13,10 +13,10 @@ /** Task-local reference counted smart pointers Task-local reference counted smart pointers are an alternative to managed boxes with deterministic -destruction. They are restricted to containing types that are either `Owned` or `Freeze` (or both) to +destruction. They are restricted to containing types that are either `Send` or `Freeze` (or both) to prevent cycles. -Neither `Rc` or `RcMut` is ever `Owned` and `RcMut` is never `Freeze`. If `T` is `Freeze`, a +Neither `Rc` or `RcMut` is ever `Send` and `RcMut` is never `Freeze`. If `T` is `Freeze`, a cycle cannot be created with `Rc` because there is no way to modify it after creation. */ @@ -51,7 +51,7 @@ impl Rc { } // FIXME: #6516: should be a static method -pub fn rc_from_owned(value: T) -> Rc { +pub fn rc_from_owned(value: T) -> Rc { unsafe { Rc::new(value) } } @@ -185,7 +185,7 @@ impl RcMut { } // FIXME: #6516: should be a static method -pub fn rc_mut_from_owned(value: T) -> RcMut { +pub fn rc_mut_from_owned(value: T) -> RcMut { unsafe { RcMut::new(value) } } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 817e1ab12261..61b6a233944c 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -86,7 +86,7 @@ struct SemInner { struct Sem(Exclusive>); #[doc(hidden)] -fn new_sem(count: int, q: Q) -> Sem { +fn new_sem(count: int, q: Q) -> Sem { Sem(exclusive(SemInner { count: count, waiters: new_waitqueue(), blocked: q })) } @@ -101,7 +101,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint) } #[doc(hidden)] -impl Sem { +impl Sem { pub fn acquire(&self) { unsafe { let mut waiter_nobe = None; @@ -175,7 +175,7 @@ struct SemReleaseGeneric<'self, Q> { sem: &'self Sem } #[doc(hidden)] #[unsafe_destructor] -impl<'self, Q:Owned> Drop for SemReleaseGeneric<'self, Q> { +impl<'self, Q:Send> Drop for SemReleaseGeneric<'self, Q> { fn drop(&self) { self.sem.release(); } diff --git a/src/libextra/timer.rs b/src/libextra/timer.rs index 71d8a5d81e7e..5a622ddfa0de 100644 --- a/src/libextra/timer.rs +++ b/src/libextra/timer.rs @@ -39,7 +39,7 @@ use core::libc; * * ch - a channel of type T to send a `val` on * * val - a value of type T to send over the provided `ch` */ -pub fn delayed_send(iotask: &IoTask, +pub fn delayed_send(iotask: &IoTask, msecs: uint, ch: &Chan, val: T) { @@ -119,7 +119,7 @@ pub fn sleep(iotask: &IoTask, msecs: uint) { * on the provided port in the allotted timeout period, then the result will * be a `Some(T)`. If not, then `None` will be returned. */ -pub fn recv_timeout(iotask: &IoTask, +pub fn recv_timeout(iotask: &IoTask, msecs: uint, wait_po: &Port) -> Option { diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index a014293f0630..567f9eda2fba 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -272,7 +272,7 @@ impl Context { } } - pub fn prep + Decodable>(@self, // FIXME(#5121) fn_name:&str, @@ -292,7 +292,7 @@ trait TPrep { fn declare_input(&mut self, kind:&str, name:&str, val:&str); fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool; fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool; - fn exec + Decodable>( // FIXME(#5121) &self, blk: ~fn(&Exec) -> T) -> Work; @@ -328,7 +328,7 @@ impl TPrep for Prep { return true; } - fn exec + Decodable>( // FIXME(#5121) &self, blk: ~fn(&Exec) -> T) -> Work { @@ -365,7 +365,7 @@ impl TPrep for Prep { } } -impl + Decodable> Work { // FIXME(#5121) pub fn new(p: @mut Prep, e: Either>) -> Work { @@ -374,7 +374,7 @@ impl + Decodable>( // FIXME(#5121) w: Work) -> T { diff --git a/src/librustc/middle/borrowck/doc.rs b/src/librustc/middle/borrowck/doc.rs index 7a91f204b131..8bb5c4620ef7 100644 --- a/src/librustc/middle/borrowck/doc.rs +++ b/src/librustc/middle/borrowck/doc.rs @@ -359,7 +359,7 @@ of its owner: LIFETIME(LV.f, LT, MQ) // L-Field LIFETIME(LV, LT, MQ) - LIFETIME(*LV, LT, MQ) // L-Deref-Owned + LIFETIME(*LV, LT, MQ) // L-Deref-Send TYPE(LV) = ~Ty LIFETIME(LV, LT, MQ) @@ -504,7 +504,7 @@ must prevent the owned pointer `LV` from being mutated, which means that we always add `MUTATE` and `CLAIM` to the restriction set imposed on `LV`: - RESTRICTIONS(*LV, ACTIONS) = RS, (*LV, ACTIONS) // R-Deref-Owned-Pointer + RESTRICTIONS(*LV, ACTIONS) = RS, (*LV, ACTIONS) // R-Deref-Send-Pointer TYPE(LV) = ~Ty RESTRICTIONS(LV, ACTIONS|MUTATE|CLAIM) = RS diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index 9455340268ef..131ee5aa067b 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -109,7 +109,7 @@ impl GuaranteeLifetimeContext { } mc::cat_downcast(base) | - mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Owned + mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Send mc::cat_interior(base, _) => { // L-Field self.check(base, discr_scope) } diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index a867ea948025..5f4251ad0a42 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -103,7 +103,7 @@ impl RestrictionsContext { } mc::cat_deref(cmt_base, _, mc::uniq_ptr(*)) => { - // R-Deref-Owned-Pointer + // R-Deref-Send-Pointer // // When we borrow the interior of an owned pointer, we // cannot permit the base to be mutated, because that diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index de6b792032b1..58a527f35018 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -538,7 +538,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { check_pointer_pat(pcx, Managed, inner, pat.id, pat.span, expected); } ast::pat_uniq(inner) => { - check_pointer_pat(pcx, Owned, inner, pat.id, pat.span, expected); + check_pointer_pat(pcx, Send, inner, pat.id, pat.span, expected); } ast::pat_region(inner) => { check_pointer_pat(pcx, Borrowed, inner, pat.id, pat.span, expected); @@ -624,7 +624,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, ty::ty_box(e_inner) if pointer_kind == Managed => { check_inner(e_inner); } - ty::ty_uniq(e_inner) if pointer_kind == Owned => { + ty::ty_uniq(e_inner) if pointer_kind == Send => { check_inner(e_inner); } ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => { @@ -641,7 +641,7 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, Some(expected), fmt!("%s pattern", match pointer_kind { Managed => "an @-box", - Owned => "a ~-box", + Send => "a ~-box", Borrowed => "an &-pointer" }), None); @@ -651,4 +651,4 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, } #[deriving(Eq)] -enum PointerKind { Managed, Owned, Borrowed } +enum PointerKind { Managed, Send, Borrowed } diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index 3775aafb5696..27ab3aca0209 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -99,7 +99,7 @@ fn act(po: &Port, source: @str, parse: Parser) { } } -pub fn exec( +pub fn exec( srv: Srv, f: ~fn(ctxt: Ctxt) -> T ) -> T { diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index 1c34007c99d4..a2e50d37fb63 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -101,7 +101,7 @@ fn fold_item( } } -fn parse_item_attrs( +fn parse_item_attrs( srv: astsrv::Srv, id: doc::AstId, parse_attrs: ~fn(a: ~[ast::attribute]) -> T) -> T { diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index 4a85a8c871d6..947aa5708c29 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -112,7 +112,7 @@ impl DeepClone for ~T { fn deep_clone(&self) -> ~T { ~(**self).deep_clone() } } -// FIXME: #6525: should also be implemented for `T: Owned + DeepClone` +// FIXME: #6525: should also be implemented for `T: Send + DeepClone` impl DeepClone for @T { /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. @@ -120,7 +120,7 @@ impl DeepClone for @T { fn deep_clone(&self) -> @T { @(**self).deep_clone() } } -// FIXME: #6525: should also be implemented for `T: Owned + DeepClone` +// FIXME: #6525: should also be implemented for `T: Send + DeepClone` impl DeepClone for @mut T { /// Return a deep copy of the managed box. The `Freeze` trait is required to prevent performing /// a deep clone of a potentially cyclical type. diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 7918abe4ae6a..8316a33ecf1f 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -17,7 +17,7 @@ Message passing use cast::{transmute, transmute_mut}; use container::Container; use either::{Either, Left, Right}; -use kinds::Owned; +use kinds::Send; use option::{Option, Some, None}; use uint; use vec::OwnedVector; @@ -77,7 +77,7 @@ pub struct Port { These allow sending or receiving an unlimited number of messages. */ -pub fn stream() -> (Port, Chan) { +pub fn stream() -> (Port, Chan) { let (port, chan) = match rt::context() { rt::OldTaskContext => match pipesy::stream() { (p, c) => (Left(p), Left(c)) @@ -91,7 +91,7 @@ pub fn stream() -> (Port, Chan) { return (port, chan); } -impl GenericChan for Chan { +impl GenericChan for Chan { fn send(&self, x: T) { match self.inner { Left(ref chan) => chan.send(x), @@ -100,7 +100,7 @@ impl GenericChan for Chan { } } -impl GenericSmartChan for Chan { +impl GenericSmartChan for Chan { fn try_send(&self, x: T) -> bool { match self.inner { Left(ref chan) => chan.try_send(x), @@ -109,7 +109,7 @@ impl GenericSmartChan for Chan { } } -impl GenericPort for Port { +impl GenericPort for Port { fn recv(&self) -> T { match self.inner { Left(ref port) => port.recv(), @@ -125,7 +125,7 @@ impl GenericPort for Port { } } -impl Peekable for Port { +impl Peekable for Port { fn peek(&self) -> bool { match self.inner { Left(ref port) => port.peek(), @@ -134,7 +134,7 @@ impl Peekable for Port { } } -impl Selectable for Port { +impl Selectable for Port { fn header(&mut self) -> *mut PacketHeader { match self.inner { Left(ref mut port) => port.header(), @@ -149,7 +149,7 @@ pub struct PortSet { ports: ~[pipesy::Port], } -impl PortSet { +impl PortSet { pub fn new() -> PortSet { PortSet { ports: ~[] @@ -175,7 +175,7 @@ impl PortSet { } } -impl GenericPort for PortSet { +impl GenericPort for PortSet { fn try_recv(&self) -> Option { unsafe { let self_ports = transmute_mut(&self.ports); @@ -204,7 +204,7 @@ impl GenericPort for PortSet { } } -impl Peekable for PortSet { +impl Peekable for PortSet { fn peek(&self) -> bool { // It'd be nice to use self.port.each, but that version isn't // pure. @@ -223,7 +223,7 @@ pub struct SharedChan { ch: Exclusive> } -impl SharedChan { +impl SharedChan { /// Converts a `chan` into a `shared_chan`. pub fn new(c: Chan) -> SharedChan { let Chan { inner } = c; @@ -235,7 +235,7 @@ impl SharedChan { } } -impl GenericChan for SharedChan { +impl GenericChan for SharedChan { fn send(&self, x: T) { unsafe { let mut xx = Some(x); @@ -247,7 +247,7 @@ impl GenericChan for SharedChan { } } -impl GenericSmartChan for SharedChan { +impl GenericSmartChan for SharedChan { fn try_send(&self, x: T) -> bool { unsafe { let mut xx = Some(x); @@ -259,7 +259,7 @@ impl GenericSmartChan for SharedChan { } } -impl ::clone::Clone for SharedChan { +impl ::clone::Clone for SharedChan { fn clone(&self) -> SharedChan { SharedChan { ch: self.ch.clone() } } @@ -273,7 +273,7 @@ pub struct ChanOne { inner: Either, rtcomm::ChanOne> } -pub fn oneshot() -> (PortOne, ChanOne) { +pub fn oneshot() -> (PortOne, ChanOne) { let (port, chan) = match rt::context() { rt::OldTaskContext => match pipesy::oneshot() { (p, c) => (Left(p), Left(c)), @@ -287,7 +287,7 @@ pub fn oneshot() -> (PortOne, ChanOne) { return (port, chan); } -impl PortOne { +impl PortOne { pub fn recv(self) -> T { let PortOne { inner } = self; match inner { @@ -305,7 +305,7 @@ impl PortOne { } } -impl ChanOne { +impl ChanOne { pub fn send(self, data: T) { let ChanOne { inner } = self; match inner { @@ -323,7 +323,7 @@ impl ChanOne { } } -pub fn recv_one(port: PortOne) -> T { +pub fn recv_one(port: PortOne) -> T { let PortOne { inner } = port; match inner { Left(p) => pipesy::recv_one(p), @@ -331,7 +331,7 @@ pub fn recv_one(port: PortOne) -> T { } } -pub fn try_recv_one(port: PortOne) -> Option { +pub fn try_recv_one(port: PortOne) -> Option { let PortOne { inner } = port; match inner { Left(p) => pipesy::try_recv_one(p), @@ -339,7 +339,7 @@ pub fn try_recv_one(port: PortOne) -> Option { } } -pub fn send_one(chan: ChanOne, data: T) { +pub fn send_one(chan: ChanOne, data: T) { let ChanOne { inner } = chan; match inner { Left(c) => pipesy::send_one(c, data), @@ -347,7 +347,7 @@ pub fn send_one(chan: ChanOne, data: T) { } } -pub fn try_send_one(chan: ChanOne, data: T) -> bool { +pub fn try_send_one(chan: ChanOne, data: T) -> bool { let ChanOne { inner } = chan; match inner { Left(c) => pipesy::try_send_one(c, data), @@ -357,7 +357,7 @@ pub fn try_send_one(chan: ChanOne, data: T) -> bool { mod pipesy { - use kinds::Owned; + use kinds::Send; use option::{Option, Some, None}; use pipes::{recv, try_recv, peek, PacketHeader}; use super::{GenericChan, GenericSmartChan, GenericPort, Peekable, Selectable}; @@ -365,17 +365,17 @@ mod pipesy { use util::replace; /*proto! oneshot ( - Oneshot:send { + Oneshot:send { send(T) -> ! } )*/ #[allow(non_camel_case_types)] pub mod oneshot { - priv use core::kinds::Owned; + priv use core::kinds::Send; use ptr::to_mut_unsafe_ptr; - pub fn init() -> (server::Oneshot, client::Oneshot) { + pub fn init() -> (server::Oneshot, client::Oneshot) { pub use core::pipes::HasBuffer; let buffer = ~::core::pipes::Buffer { @@ -399,10 +399,10 @@ mod pipesy { #[allow(non_camel_case_types)] pub mod client { - priv use core::kinds::Owned; + priv use core::kinds::Send; #[allow(non_camel_case_types)] - pub fn try_send(pipe: Oneshot, x_0: T) -> + pub fn try_send(pipe: Oneshot, x_0: T) -> ::core::option::Option<()> { { use super::send; @@ -414,7 +414,7 @@ mod pipesy { } #[allow(non_camel_case_types)] - pub fn send(pipe: Oneshot, x_0: T) { + pub fn send(pipe: Oneshot, x_0: T) { { use super::send; let message = send(x_0); @@ -464,12 +464,12 @@ mod pipesy { } /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. - pub fn oneshot() -> (PortOne, ChanOne) { + pub fn oneshot() -> (PortOne, ChanOne) { let (port, chan) = oneshot::init(); (PortOne::new(port), ChanOne::new(chan)) } - impl PortOne { + impl PortOne { pub fn recv(self) -> T { recv_one(self) } pub fn try_recv(self) -> Option { try_recv_one(self) } pub fn unwrap(self) -> oneshot::server::Oneshot { @@ -479,7 +479,7 @@ mod pipesy { } } - impl ChanOne { + impl ChanOne { pub fn send(self, data: T) { send_one(self, data) } pub fn try_send(self, data: T) -> bool { try_send_one(self, data) } pub fn unwrap(self) -> oneshot::client::Oneshot { @@ -493,7 +493,7 @@ mod pipesy { * Receive a message from a oneshot pipe, failing if the connection was * closed. */ - pub fn recv_one(port: PortOne) -> T { + pub fn recv_one(port: PortOne) -> T { match port { PortOne { contents: port } => { let oneshot::send(message) = recv(port); @@ -503,7 +503,7 @@ mod pipesy { } /// Receive a message from a oneshot pipe unless the connection was closed. - pub fn try_recv_one (port: PortOne) -> Option { + pub fn try_recv_one (port: PortOne) -> Option { match port { PortOne { contents: port } => { let message = try_recv(port); @@ -519,7 +519,7 @@ mod pipesy { } /// Send a message on a oneshot pipe, failing if the connection was closed. - pub fn send_one(chan: ChanOne, data: T) { + pub fn send_one(chan: ChanOne, data: T) { match chan { ChanOne { contents: chan } => oneshot::client::send(chan, data), } @@ -529,7 +529,7 @@ mod pipesy { * Send a message on a oneshot pipe, or return false if the connection was * closed. */ - pub fn try_send_one(chan: ChanOne, data: T) -> bool { + pub fn try_send_one(chan: ChanOne, data: T) -> bool { match chan { ChanOne { contents: chan } => { oneshot::client::try_send(chan, data).is_some() @@ -540,16 +540,16 @@ mod pipesy { // Streams - Make pipes a little easier in general. /*proto! streamp ( - Open:send { + Open:send { data(T) -> Open } )*/ #[allow(non_camel_case_types)] pub mod streamp { - priv use core::kinds::Owned; + priv use core::kinds::Send; - pub fn init() -> (server::Open, client::Open) { + pub fn init() -> (server::Open, client::Open) { pub use core::pipes::HasBuffer; ::core::pipes::entangle() } @@ -559,10 +559,10 @@ mod pipesy { #[allow(non_camel_case_types)] pub mod client { - priv use core::kinds::Owned; + priv use core::kinds::Send; #[allow(non_camel_case_types)] - pub fn try_data(pipe: Open, x_0: T) -> + pub fn try_data(pipe: Open, x_0: T) -> ::core::option::Option> { { use super::data; @@ -575,7 +575,7 @@ mod pipesy { } #[allow(non_camel_case_types)] - pub fn data(pipe: Open, x_0: T) -> Open { + pub fn data(pipe: Open, x_0: T) -> Open { { use super::data; let (s, c) = ::core::pipes::entangle(); @@ -613,7 +613,7 @@ mod pipesy { These allow sending or receiving an unlimited number of messages. */ - pub fn stream() -> (Port, Chan) { + pub fn stream() -> (Port, Chan) { let (s, c) = streamp::init(); (Port { @@ -623,7 +623,7 @@ mod pipesy { }) } - impl GenericChan for Chan { + impl GenericChan for Chan { #[inline] fn send(&self, x: T) { unsafe { @@ -634,7 +634,7 @@ mod pipesy { } } - impl GenericSmartChan for Chan { + impl GenericSmartChan for Chan { #[inline] fn try_send(&self, x: T) -> bool { unsafe { @@ -651,7 +651,7 @@ mod pipesy { } } - impl GenericPort for Port { + impl GenericPort for Port { #[inline] fn recv(&self) -> T { unsafe { @@ -679,7 +679,7 @@ mod pipesy { } } - impl Peekable for Port { + impl Peekable for Port { #[inline] fn peek(&self) -> bool { unsafe { @@ -695,7 +695,7 @@ mod pipesy { } } - impl Selectable for Port { + impl Selectable for Port { fn header(&mut self) -> *mut PacketHeader { match self.endp { Some(ref mut endp) => endp.header(), @@ -723,15 +723,15 @@ pub fn select2i(a: &mut A, b: &mut B) } /// Receive a message from one of two endpoints. -pub trait Select2 { +pub trait Select2 { /// Receive a message or return `None` if a connection closes. fn try_select(&mut self) -> Either, Option>; /// Receive a message or fail if a connection closes. fn select(&mut self) -> Either; } -impl, Right:Selectable + GenericPort> Select2 diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs index 9d5348ff98f0..f350e1061680 100644 --- a/src/libstd/kinds.rs +++ b/src/libstd/kinds.rs @@ -24,7 +24,7 @@ The 4 kinds are scalar types and managed pointers, and exludes owned pointers. It also excludes types that implement `Drop`. -* Owned - owned types and types containing owned types. These types +* Send - owned types and types containing owned types. These types may be transferred across task boundaries. * Freeze - types that are deeply immutable. @@ -45,13 +45,13 @@ pub trait Copy { #[cfg(stage0)] #[lang="owned"] -pub trait Owned { +pub trait Send { // empty. } #[cfg(not(stage0))] #[lang="send"] -pub trait Owned { +pub trait Send { // empty. } diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 661dc2a659f7..49713a3a23b9 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -88,7 +88,7 @@ use container::Container; use cast::{forget, transmute, transmute_copy, transmute_mut}; use either::{Either, Left, Right}; use iterator::IteratorUtil; -use kinds::Owned; +use kinds::Send; use libc; use ops::Drop; use option::{None, Option, Some}; @@ -177,7 +177,7 @@ impl PacketHeader { transmute_copy(&self.buffer) } - pub fn set_buffer(&mut self, b: ~Buffer) { + pub fn set_buffer(&mut self, b: ~Buffer) { unsafe { self.buffer = transmute_copy(&b); } @@ -193,13 +193,13 @@ pub trait HasBuffer { fn set_buffer(&mut self, b: *libc::c_void); } -impl HasBuffer for Packet { +impl HasBuffer for Packet { fn set_buffer(&mut self, b: *libc::c_void) { self.header.buffer = b; } } -pub fn mk_packet() -> Packet { +pub fn mk_packet() -> Packet { Packet { header: PacketHeader(), payload: None, @@ -230,7 +230,7 @@ pub fn packet() -> *mut Packet { p } -pub fn entangle_buffer( +pub fn entangle_buffer( mut buffer: ~Buffer, init: &fn(*libc::c_void, x: &mut T) -> *mut Packet) -> (RecvPacketBuffered, SendPacketBuffered) { @@ -396,7 +396,7 @@ pub fn send(mut p: SendPacketBuffered, Fails if the sender closes the connection. */ -pub fn recv( +pub fn recv( p: RecvPacketBuffered) -> T { try_recv(p).expect("connection closed") } @@ -407,7 +407,7 @@ Returns `None` if the sender has closed the connection without sending a message, or `Some(T)` if a message was received. */ -pub fn try_recv(mut p: RecvPacketBuffered) +pub fn try_recv(mut p: RecvPacketBuffered) -> Option { let p_ = p.unwrap(); let p = unsafe { &mut *p_ }; @@ -427,7 +427,7 @@ pub fn try_recv(mut p: RecvPacketBuffered) } } -fn try_recv_(p: &mut Packet) -> Option { +fn try_recv_(p: &mut Packet) -> Option { // optimistic path match p.header.state { Full => { @@ -511,7 +511,7 @@ fn try_recv_(p: &mut Packet) -> Option { } /// Returns true if messages are available. -pub fn peek(p: &mut RecvPacketBuffered) -> bool { +pub fn peek(p: &mut RecvPacketBuffered) -> bool { unsafe { match (*p.header()).state { Empty | Terminated => false, @@ -521,7 +521,7 @@ pub fn peek(p: &mut RecvPacketBuffered) -> bool { } } -fn sender_terminate(p: *mut Packet) { +fn sender_terminate(p: *mut Packet) { let p = unsafe { &mut *p }; @@ -553,7 +553,7 @@ fn sender_terminate(p: *mut Packet) { } } -fn receiver_terminate(p: *mut Packet) { +fn receiver_terminate(p: *mut Packet) { let p = unsafe { &mut *p }; @@ -671,7 +671,7 @@ pub struct SendPacketBuffered { } #[unsafe_destructor] -impl Drop for SendPacketBuffered { +impl Drop for SendPacketBuffered { fn drop(&self) { unsafe { let this: &mut SendPacketBuffered = transmute(self); @@ -729,7 +729,7 @@ pub struct RecvPacketBuffered { } #[unsafe_destructor] -impl Drop for RecvPacketBuffered { +impl Drop for RecvPacketBuffered { fn drop(&self) { unsafe { let this: &mut RecvPacketBuffered = transmute(self); @@ -741,7 +741,7 @@ impl Drop for RecvPacketBuffered { } } -impl RecvPacketBuffered { +impl RecvPacketBuffered { pub fn unwrap(&mut self) -> *mut Packet { replace(&mut self.p, None).unwrap() } @@ -751,7 +751,7 @@ impl RecvPacketBuffered { } } -impl Selectable for RecvPacketBuffered { +impl Selectable for RecvPacketBuffered { fn header(&mut self) -> *mut PacketHeader { match self.p { Some(packet) => unsafe { @@ -807,7 +807,7 @@ Sometimes messages will be available on both endpoints at once. In this case, `select2` may return either `left` or `right`. */ -pub fn select2( +pub fn select2( mut a: RecvPacketBuffered, mut b: RecvPacketBuffered) -> Either<(Option, RecvPacketBuffered), @@ -847,7 +847,7 @@ pub fn select2i(a: &mut A, b: &mut B) /// Waits on a set of endpoints. Returns a message, its index, and a /// list of the remaining endpoints. -pub fn select(mut endpoints: ~[RecvPacketBuffered]) +pub fn select(mut endpoints: ~[RecvPacketBuffered]) -> (uint, Option, ~[RecvPacketBuffered]) { diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 5959cdaf318c..13d19b276f59 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -30,7 +30,7 @@ Rust's prelude has three main parts: // Reexported core operators pub use either::{Either, Left, Right}; pub use kinds::{Copy, Sized}; -pub use kinds::{Freeze, Owned}; +pub use kinds::{Freeze, Send}; pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not}; pub use ops::{BitAnd, BitOr, BitXor}; pub use ops::{Drop}; diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 75b1d8f38103..72907f40a074 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -19,7 +19,7 @@ use option::*; use cast; use util; use ops::Drop; -use kinds::Owned; +use kinds::Send; use rt::sched::{Scheduler, Coroutine}; use rt::local::Local; use unstable::intrinsics::{atomic_xchg, atomic_load}; @@ -68,7 +68,7 @@ pub struct PortOneHack { suppress_finalize: bool } -pub fn oneshot() -> (PortOne, ChanOne) { +pub fn oneshot() -> (PortOne, ChanOne) { let packet: ~Packet = ~Packet { state: STATE_BOTH, payload: None @@ -307,20 +307,20 @@ pub struct Port { next: Cell>> } -pub fn stream() -> (Port, Chan) { +pub fn stream() -> (Port, Chan) { let (pone, cone) = oneshot(); let port = Port { next: Cell::new(pone) }; let chan = Chan { next: Cell::new(cone) }; return (port, chan); } -impl GenericChan for Chan { +impl GenericChan for Chan { fn send(&self, val: T) { self.try_send(val); } } -impl GenericSmartChan for Chan { +impl GenericSmartChan for Chan { fn try_send(&self, val: T) -> bool { let (next_pone, next_cone) = oneshot(); let cone = self.next.take(); diff --git a/src/libstd/rt/message_queue.rs b/src/libstd/rt/message_queue.rs index 5b60543344de..d561e81d0327 100644 --- a/src/libstd/rt/message_queue.rs +++ b/src/libstd/rt/message_queue.rs @@ -9,7 +9,7 @@ // except according to those terms. use container::Container; -use kinds::Owned; +use kinds::Send; use vec::OwnedVector; use cell::Cell; use option::*; @@ -21,7 +21,7 @@ pub struct MessageQueue { priv queue: ~Exclusive<~[T]> } -impl MessageQueue { +impl MessageQueue { pub fn new() -> MessageQueue { MessageQueue { queue: ~exclusive(~[]) diff --git a/src/libstd/rt/work_queue.rs b/src/libstd/rt/work_queue.rs index cfffc55a58c8..00d277442688 100644 --- a/src/libstd/rt/work_queue.rs +++ b/src/libstd/rt/work_queue.rs @@ -13,7 +13,7 @@ use option::*; use vec::OwnedVector; use unstable::sync::{Exclusive, exclusive}; use cell::Cell; -use kinds::Owned; +use kinds::Send; use clone::Clone; pub struct WorkQueue { @@ -21,7 +21,7 @@ pub struct WorkQueue { priv queue: ~Exclusive<~[T]> } -impl WorkQueue { +impl WorkQueue { pub fn new() -> WorkQueue { WorkQueue { queue: ~exclusive(~[]) diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index b558b9d53a3c..a8e8cfd163ad 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -353,7 +353,7 @@ impl TaskBuilder { } /// Runs a task, while transfering ownership of one argument to the child. - pub fn spawn_with(&mut self, arg: A, f: ~fn(v: A)) { + pub fn spawn_with(&mut self, arg: A, f: ~fn(v: A)) { let arg = Cell::new(arg); do self.spawn { f(arg.take()); @@ -373,7 +373,7 @@ impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - pub fn try(&mut self, f: ~fn() -> T) -> Result { + pub fn try(&mut self, f: ~fn() -> T) -> Result { let (po, ch) = stream::(); let mut result = None; @@ -445,7 +445,7 @@ pub fn spawn_supervised(f: ~fn()) { task.spawn(f) } -pub fn spawn_with(arg: A, f: ~fn(v: A)) { +pub fn spawn_with(arg: A, f: ~fn(v: A)) { /*! * Runs a task, while transfering ownership of one argument to the * child. @@ -478,7 +478,7 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) { task.spawn(f) } -pub fn try(f: ~fn() -> T) -> Result { +pub fn try(f: ~fn() -> T) -> Result { /*! * Execute a function in another task and return either the return value * of the function or result::err. diff --git a/src/libstd/unstable/global.rs b/src/libstd/unstable/global.rs index 4fde8f704b98..285a8114cc24 100644 --- a/src/libstd/unstable/global.rs +++ b/src/libstd/unstable/global.rs @@ -27,7 +27,7 @@ avoid hitting the mutex. use cast::{transmute}; use clone::Clone; -use kinds::Owned; +use kinds::Send; use libc::{c_void}; use option::{Option, Some, None}; use ops::Drop; @@ -43,7 +43,7 @@ use sys::Closure; pub type GlobalDataKey<'self,T> = &'self fn(v: T); -pub unsafe fn global_data_clone_create( +pub unsafe fn global_data_clone_create( key: GlobalDataKey, create: &fn() -> ~T) -> T { /*! * Clone a global value or, if it has not been created, @@ -59,7 +59,7 @@ pub unsafe fn global_data_clone_create( global_data_clone_create_(key_ptr(key), create) } -unsafe fn global_data_clone_create_( +unsafe fn global_data_clone_create_( key: uint, create: &fn() -> ~T) -> T { let mut clone_value: Option = None; @@ -79,13 +79,13 @@ unsafe fn global_data_clone_create_( return clone_value.unwrap(); } -unsafe fn global_data_modify( +unsafe fn global_data_modify( key: GlobalDataKey, op: &fn(Option<~T>) -> Option<~T>) { global_data_modify_(key_ptr(key), op) } -unsafe fn global_data_modify_( +unsafe fn global_data_modify_( key: uint, op: &fn(Option<~T>) -> Option<~T>) { let mut old_dtor = None; @@ -124,7 +124,7 @@ unsafe fn global_data_modify_( } } -pub unsafe fn global_data_clone( +pub unsafe fn global_data_clone( key: GlobalDataKey) -> Option { let mut maybe_clone: Option = None; do global_data_modify(key) |current| { @@ -220,7 +220,7 @@ fn get_global_state() -> Exclusive { } } -fn key_ptr(key: GlobalDataKey) -> uint { +fn key_ptr(key: GlobalDataKey) -> uint { unsafe { let closure: Closure = transmute(key); return transmute(closure.code); diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index 0f9298595eec..06c3ecb81475 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -17,7 +17,7 @@ use unstable::finally::Finally; use unstable::intrinsics; use ops::Drop; use clone::Clone; -use kinds::Owned; +use kinds::Send; /// An atomically reference counted pointer. /// @@ -31,7 +31,7 @@ struct AtomicRcBoxData { data: Option, } -impl UnsafeAtomicRcBox { +impl UnsafeAtomicRcBox { pub fn new(data: T) -> UnsafeAtomicRcBox { unsafe { let data = ~AtomicRcBoxData { count: 1, data: Some(data) }; @@ -61,7 +61,7 @@ impl UnsafeAtomicRcBox { } } -impl Clone for UnsafeAtomicRcBox { +impl Clone for UnsafeAtomicRcBox { fn clone(&self) -> UnsafeAtomicRcBox { unsafe { let mut data: ~AtomicRcBoxData = cast::transmute(self.data); @@ -144,7 +144,7 @@ pub struct Exclusive { x: UnsafeAtomicRcBox> } -pub fn exclusive(user_data: T) -> Exclusive { +pub fn exclusive(user_data: T) -> Exclusive { let data = ExData { lock: LittleLock(), failed: false, @@ -155,14 +155,14 @@ pub fn exclusive(user_data: T) -> Exclusive { } } -impl Clone for Exclusive { +impl Clone for Exclusive { // Duplicate an exclusive ARC, as std::arc::clone. fn clone(&self) -> Exclusive { Exclusive { x: self.x.clone() } } } -impl Exclusive { +impl Exclusive { // Exactly like std::arc::mutex_arc,access(), but with the little_lock // instead of a proper mutex. Same reason for being unsafe. // diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a9b0c3986f8b..265e9e444e94 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -147,7 +147,7 @@ pub static crate_node_id: node_id = 0; // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and -// detects Copy, Send, Owned, and Freeze. +// detects Copy, Send, Send, and Freeze. pub enum TyParamBound { TraitTyParamBound(@trait_ref), RegionTyParamBound diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index d1d4d173a3f3..c9d63d2c4167 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -30,7 +30,7 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt, generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), args: ~[], - ret_ty: Ptr(~Literal(Path::new_local("str")), Owned), + ret_ty: Ptr(~Literal(Path::new_local("str")), Send), const_nonmatching: false, combine_substructure: to_str_substructure } diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index 2f21eba11d7e..a2f9aa58d99a 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -22,7 +22,7 @@ use opt_vec; /// The types of pointers pub enum PtrTy<'self> { - Owned, // ~ + Send, // ~ Managed(ast::mutability), // @[mut] Borrowed(Option<&'self str>, ast::mutability), // &['lifetime] [mut] } @@ -128,7 +128,7 @@ impl<'self> Ty<'self> { Ptr(ref ty, ref ptr) => { let raw_ty = ty.to_ty(cx, span, self_ty, self_generics); match *ptr { - Owned => { + Send => { cx.ty_uniq(span, raw_ty) } Managed(mutbl) => { @@ -248,7 +248,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option) let self_ty = respan( span, match *ptr { - Owned => ast::sty_uniq(ast::m_imm), + Send => ast::sty_uniq(ast::m_imm), Managed(mutbl) => ast::sty_box(mutbl), Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| @cx.lifetime(span, diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs index e45bfc8ea5dc..beca0adbe3c5 100644 --- a/src/test/auxiliary/cci_capture_clause.rs +++ b/src/test/auxiliary/cci_capture_clause.rs @@ -11,7 +11,7 @@ use std::comm::*; use std::task; -pub fn foo(x: T) -> Port { +pub fn foo(x: T) -> Port { let (p, c) = stream(); do task::spawn() { c.send(copy x); diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index 63e4174a0fc7..1d32a78303a8 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -82,7 +82,7 @@ endpoint. The send endpoint is returned to the caller and the receive endpoint is passed to the new task. */ -pub fn spawn_service( +pub fn spawn_service( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), service: ~fn(v: RecvPacketBuffered)) @@ -103,7 +103,7 @@ pub fn spawn_service( receive state. */ -pub fn spawn_service_recv( +pub fn spawn_service_recv( init: extern fn() -> (SendPacketBuffered, RecvPacketBuffered), service: ~fn(v: SendPacketBuffered)) @@ -120,7 +120,7 @@ pub fn spawn_service_recv( client } -fn switch(endp: std::pipes::RecvPacketBuffered, +fn switch(endp: std::pipes::RecvPacketBuffered, f: &fn(v: Option) -> U) -> U { f(std::pipes::try_recv(endp)) diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs index 887346e35e5e..6ffdd0f541e1 100644 --- a/src/test/compile-fail/closure-bounds-subtype.rs +++ b/src/test/compile-fail/closure-bounds-subtype.rs @@ -5,7 +5,7 @@ fn take_any(_: &fn:()) { fn take_copyable(_: &fn:Copy()) { } -fn take_copyable_owned(_: &fn:Copy+Owned()) { +fn take_copyable_owned(_: &fn:Copy+Send()) { } fn take_const_owned(_: &fn:Const+Owned()) { @@ -14,22 +14,22 @@ fn take_const_owned(_: &fn:Const+Owned()) { fn give_any(f: &fn:()) { take_any(f); take_copyable(f); //~ ERROR expected bounds `Copy` but found no bounds - take_copyable_owned(f); //~ ERROR expected bounds `Copy+Owned` but found no bounds + take_copyable_owned(f); //~ ERROR expected bounds `Copy+Send` but found no bounds } fn give_copyable(f: &fn:Copy()) { take_any(f); take_copyable(f); - take_copyable_owned(f); //~ ERROR expected bounds `Copy+Owned` but found bounds `Copy` + take_copyable_owned(f); //~ ERROR expected bounds `Copy+Send` but found bounds `Copy` } -fn give_owned(f: &fn:Owned()) { +fn give_owned(f: &fn:Send()) { take_any(f); - take_copyable(f); //~ ERROR expected bounds `Copy` but found bounds `Owned` - take_copyable_owned(f); //~ ERROR expected bounds `Copy+Owned` but found bounds `Owned` + take_copyable(f); //~ ERROR expected bounds `Copy` but found bounds `Send` + take_copyable_owned(f); //~ ERROR expected bounds `Copy+Send` but found bounds `Send` } -fn give_copyable_owned(f: &fn:Copy+Owned()) { +fn give_copyable_owned(f: &fn:Copy+Send()) { take_any(f); take_copyable(f); take_copyable_owned(f); diff --git a/src/test/compile-fail/issue-2766-a.rs b/src/test/compile-fail/issue-2766-a.rs index 91ae0e1c07a5..c5d13c81b7c5 100644 --- a/src/test/compile-fail/issue-2766-a.rs +++ b/src/test/compile-fail/issue-2766-a.rs @@ -9,12 +9,12 @@ // except according to those terms. pub mod stream { - pub enum Stream { send(T, ::stream::server::Stream), } + pub enum Stream { send(T, ::stream::server::Stream), } pub mod server { use std::option; use std::pipes; - impl Stream { + impl Stream { pub fn recv() -> extern fn(v: Stream) -> ::stream::Stream { // resolve really should report just one error here. // Change the test case when it changes. @@ -28,7 +28,7 @@ pub mod stream { } } - pub type Stream = pipes::RecvPacket<::stream::Stream>; + pub type Stream = pipes::RecvPacket<::stream::Stream>; } } diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs index 551b50c94f24..00d73b02dbc6 100644 --- a/src/test/compile-fail/kindck-destructor-owned.rs +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -2,7 +2,7 @@ struct Foo { f: @mut int, } -impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Owned +impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Send fn drop(&self) { *self.f = 10; } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index 23d3fff01cf3..72555d7e8511 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn send(ch: _chan, data: T) { +fn send(ch: _chan, data: T) { debug!(ch); debug!(data); fail!(); diff --git a/src/test/compile-fail/non_owned-enum.rs b/src/test/compile-fail/non_owned-enum.rs index 79c2be8183a6..6068b7f17303 100644 --- a/src/test/compile-fail/non_owned-enum.rs +++ b/src/test/compile-fail/non_owned-enum.rs @@ -11,9 +11,9 @@ #[non_owned] enum Foo { A } -fn bar(_: T) {} +fn bar(_: T) {} fn main() { let x = A; - bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Owned` + bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Send` } diff --git a/src/test/compile-fail/non_owned-struct.rs b/src/test/compile-fail/non_owned-struct.rs index 2d0bc9a7e8e4..b6f29df05752 100644 --- a/src/test/compile-fail/non_owned-struct.rs +++ b/src/test/compile-fail/non_owned-struct.rs @@ -11,9 +11,9 @@ #[non_owned] struct Foo { a: int } -fn bar(_: T) {} +fn bar(_: T) {} fn main() { let x = Foo { a: 5 }; - bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Owned` + bar(x); //~ ERROR instantiating a type parameter with an incompatible type `Foo`, which does not fulfill `Send` } diff --git a/src/test/compile-fail/unique-unique-kind.rs b/src/test/compile-fail/unique-unique-kind.rs index 26058bf89cad..d51df4979e35 100644 --- a/src/test/compile-fail/unique-unique-kind.rs +++ b/src/test/compile-fail/unique-unique-kind.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(_i: T) { +fn f(_i: T) { } fn main() { let i = ~@100; - f(i); //~ ERROR does not fulfill `Owned` + f(i); //~ ERROR does not fulfill `Send` } diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs index 58de0926f7c6..de089dcf914b 100644 --- a/src/test/compile-fail/unsendable-class.rs +++ b/src/test/compile-fail/unsendable-class.rs @@ -27,6 +27,6 @@ fn foo(i:int, j: @~str) -> foo { fn main() { let cat = ~"kitty"; - let (_, ch) = comm::stream(); //~ ERROR does not fulfill `Owned` - ch.send(foo(42, @(cat))); //~ ERROR does not fulfill `Owned` + let (_, ch) = comm::stream(); //~ ERROR does not fulfill `Send` + ch.send(foo(42, @(cat))); //~ ERROR does not fulfill `Send` } diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs index b497b0224b9f..992747187f63 100644 --- a/src/test/run-fail/bug-811.rs +++ b/src/test/run-fail/bug-811.rs @@ -19,6 +19,6 @@ struct chan_t { port: port_id, } -fn send(ch: chan_t, data: T) { fail!(); } +fn send(ch: chan_t, data: T) { fail!(); } fn main() { fail!("quux"); } diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 753e5339de9d..24709fb29740 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -23,7 +23,7 @@ fn make_cycle(a: A) { g.rec = Some(g); } -fn f(a: A, b: B) -> @fn() -> (A, B) { +fn f(a: A, b: B) -> @fn() -> (A, B) { let result: @fn() -> (A, B) = || (copy a, copy b); result } diff --git a/src/test/run-pass/fixed-point-bind-unique.rs b/src/test/run-pass/fixed-point-bind-unique.rs index 53f9c723a473..c7b64fde3fd5 100644 --- a/src/test/run-pass/fixed-point-bind-unique.rs +++ b/src/test/run-pass/fixed-point-bind-unique.rs @@ -10,11 +10,11 @@ // xfail-fast -fn fix_help(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B { +fn fix_help(f: extern fn(@fn(A) -> B, A) -> B, x: A) -> B { return f(|a| fix_help(f, a), x); } -fn fix(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B { +fn fix(f: extern fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B { return |a| fix_help(f, a); } diff --git a/src/test/run-pass/fn-bare-spawn.rs b/src/test/run-pass/fn-bare-spawn.rs index 4f0f451a08c0..e9954be93575 100644 --- a/src/test/run-pass/fn-bare-spawn.rs +++ b/src/test/run-pass/fn-bare-spawn.rs @@ -10,7 +10,7 @@ // This is what the signature to spawn should look like with bare functions -fn spawn(val: T, f: extern fn(T)) { +fn spawn(val: T, f: extern fn(T)) { f(val); } diff --git a/src/test/run-pass/generic-alias-unique.rs b/src/test/run-pass/generic-alias-unique.rs index ad271186639b..815cc1bc79bc 100644 --- a/src/test/run-pass/generic-alias-unique.rs +++ b/src/test/run-pass/generic-alias-unique.rs @@ -10,7 +10,7 @@ -fn id(t: T) -> T { return t; } +fn id(t: T) -> T { return t; } pub fn main() { let expected = ~100; diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 9fbca7d05720..14915555889d 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -39,7 +39,7 @@ pub mod pipes { payload: Option } - pub fn packet() -> *packet { + pub fn packet() -> *packet { unsafe { let p: *packet = cast::transmute(~Stuff{ state: empty, @@ -74,7 +74,7 @@ pub mod pipes { } } - pub fn send(mut p: send_packet, payload: T) { + pub fn send(mut p: send_packet, payload: T) { let mut p = p.unwrap(); let mut p = unsafe { uniquify(p) }; assert!((*p).payload.is_none()); @@ -100,7 +100,7 @@ pub mod pipes { } } - pub fn recv(mut p: recv_packet) -> Option { + pub fn recv(mut p: recv_packet) -> Option { let mut p = p.unwrap(); let mut p = unsafe { uniquify(p) }; loop { @@ -120,7 +120,7 @@ pub mod pipes { } } - pub fn sender_terminate(mut p: *packet) { + pub fn sender_terminate(mut p: *packet) { let mut p = unsafe { uniquify(p) }; match swap_state_rel(&mut (*p).state, terminated) { empty | blocked => { @@ -137,7 +137,7 @@ pub mod pipes { } } - pub fn receiver_terminate(mut p: *packet) { + pub fn receiver_terminate(mut p: *packet) { let mut p = unsafe { uniquify(p) }; match swap_state_rel(&mut (*p).state, terminated) { empty => { @@ -159,7 +159,7 @@ pub mod pipes { } #[unsafe_destructor] - impl Drop for send_packet { + impl Drop for send_packet { fn drop(&self) { unsafe { if self.p != None { @@ -172,13 +172,13 @@ pub mod pipes { } } - impl send_packet { + impl send_packet { pub fn unwrap(&mut self) -> *packet { util::replace(&mut self.p, None).unwrap() } } - pub fn send_packet(p: *packet) -> send_packet { + pub fn send_packet(p: *packet) -> send_packet { send_packet { p: Some(p) } @@ -189,7 +189,7 @@ pub mod pipes { } #[unsafe_destructor] - impl Drop for recv_packet { + impl Drop for recv_packet { fn drop(&self) { unsafe { if self.p != None { @@ -202,19 +202,19 @@ pub mod pipes { } } - impl recv_packet { + impl recv_packet { pub fn unwrap(&mut self) -> *packet { util::replace(&mut self.p, None).unwrap() } } - pub fn recv_packet(p: *packet) -> recv_packet { + pub fn recv_packet(p: *packet) -> recv_packet { recv_packet { p: Some(p) } } - pub fn entangle() -> (send_packet, recv_packet) { + pub fn entangle() -> (send_packet, recv_packet) { let p = packet(); (send_packet(p), recv_packet(p)) } diff --git a/src/test/run-pass/issue-2834.rs b/src/test/run-pass/issue-2834.rs index 5d3a2d2331c9..b0ddccf28944 100644 --- a/src/test/run-pass/issue-2834.rs +++ b/src/test/run-pass/issue-2834.rs @@ -12,7 +12,7 @@ // proto! streamp ( - open:send { + open:send { data(T) -> open } ) diff --git a/src/test/run-pass/issue-2930.rs b/src/test/run-pass/issue-2930.rs index cfce19826d7e..10a19d62bd97 100644 --- a/src/test/run-pass/issue-2930.rs +++ b/src/test/run-pass/issue-2930.rs @@ -9,7 +9,7 @@ // except according to those terms. proto! stream ( - Stream:send { + Stream:send { send(T) -> Stream } ) diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index 7ac38966faa3..11c43b939019 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -45,8 +45,8 @@ proto! bank ( } ) -fn switch(endp: pipes::RecvPacket, - f: &fn(v: Option) -> U) -> U { +fn switch(endp: pipes::RecvPacket, + f: &fn(v: Option) -> U) -> U { f(pipes::try_recv(endp)) } diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs index 0a860d0a1e22..36f144152f2a 100644 --- a/src/test/run-pass/pipe-select.rs +++ b/src/test/run-pass/pipe-select.rs @@ -29,12 +29,12 @@ proto! oneshot ( ) proto! stream ( - Stream:send { + Stream:send { send(T) -> Stream } ) -pub fn spawn_service( +pub fn spawn_service( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), service: ~fn(v: RecvPacketBuffered)) diff --git a/src/test/run-pass/pipe-sleep.rs b/src/test/run-pass/pipe-sleep.rs index dc88f36ba113..dbf860cd0407 100644 --- a/src/test/run-pass/pipe-sleep.rs +++ b/src/test/run-pass/pipe-sleep.rs @@ -33,7 +33,7 @@ endpoint. The send endpoint is returned to the caller and the receive endpoint is passed to the new task. */ -pub fn spawn_service( +pub fn spawn_service( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), service: ~fn(v: RecvPacketBuffered)) diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs index bdb1fbaf4226..4fcbc789f57b 100644 --- a/src/test/run-pass/send-type-inference.rs +++ b/src/test/run-pass/send-type-inference.rs @@ -16,7 +16,7 @@ struct Command { val: V } -fn cache_server(c: Chan>>) { +fn cache_server(c: Chan>>) { let (ctrl_port, ctrl_chan) = stream(); c.send(ctrl_chan); } diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs index 416e7bf82bb8..216a7a939fe0 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/run-pass/type-param-constraints.rs @@ -12,7 +12,7 @@ fn p_foo(pinned: T) { } fn s_foo(shared: T) { } -fn u_foo(unique: T) { } +fn u_foo(unique: T) { } struct r { i: int, diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index b54b3b52692e..2c3424d1f06f 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.rs @@ -20,7 +20,7 @@ struct Pointy { d : ~fn() -> uint, } -fn make_uniq_closure(a: A) -> ~fn() -> uint { +fn make_uniq_closure(a: A) -> ~fn() -> uint { let result: ~fn() -> uint = || ptr::to_unsafe_ptr(&a) as uint; result } diff --git a/src/test/run-pass/unique-kinds.rs b/src/test/run-pass/unique-kinds.rs index b3ce71dcbff5..391881deff66 100644 --- a/src/test/run-pass/unique-kinds.rs +++ b/src/test/run-pass/unique-kinds.rs @@ -12,11 +12,11 @@ use std::cmp::Eq; fn sendable() { - fn f(i: T, j: T) { + fn f(i: T, j: T) { assert_eq!(i, j); } - fn g(i: T, j: T) { + fn g(i: T, j: T) { assert!(i != j); } From f9b54541ee2bbab1d81b14252f4d4172e10fd748 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 6 Jun 2013 18:54:14 -0700 Subject: [PATCH 236/336] librustc: Disallow "mut" from distributing over bindings. This is the backwards-incompatible part of per-binding-site "mut". --- doc/rust.md | 14 ++-- doc/tutorial-ffi.md | 4 +- src/libextra/md4.rs | 3 +- src/libextra/net_url.rs | 4 +- src/libextra/num/bigint.rs | 8 ++- src/libextra/timer.rs | 4 +- src/librustc/middle/trans/cabi_arm.rs | 4 +- src/librustc/middle/trans/cabi_mips.rs | 4 +- src/librustc/middle/trans/cabi_x86_64.rs | 3 +- src/librustc/middle/trans/callee.rs | 3 +- src/librustc/middle/trans/expr.rs | 5 +- src/libstd/io.rs | 7 +- src/libstd/num/int_macros.rs | 3 +- src/libstd/num/uint_macros.rs | 3 +- src/libstd/rand.rs | 3 +- src/libstd/rand/distributions.rs | 3 +- src/libstd/rt/io/extensions.rs | 7 +- src/libstd/str.rs | 70 ++++++++++++++++++- src/libstd/task/spawn.rs | 4 +- src/libstd/to_str.rs | 17 +++-- src/libstd/vec.rs | 9 ++- src/libsyntax/ast_util.rs | 9 +++ src/libsyntax/parse/obsolete.rs | 6 ++ src/libsyntax/parse/parser.rs | 16 ++++- src/test/bench/shootout-mandelbrot.rs | 5 +- .../compile-fail/kindck-destructor-owned.rs | 2 +- src/test/compile-fail/kindck-nonsendable-1.rs | 6 +- src/test/compile-fail/no-send-res-ports.rs | 2 +- src/test/compile-fail/non_owned-enum.rs | 2 +- src/test/compile-fail/non_owned-struct.rs | 2 +- src/test/run-pass/let-destruct-fresh-mem.rs | 4 +- src/test/run-pass/pipe-peek.rs | 4 +- 32 files changed, 190 insertions(+), 50 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 8f742d0d2100..cc53d7d17a25 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2862,13 +2862,13 @@ call to the method `make_string`. Types in Rust are categorized into kinds, based on various properties of the components of the type. The kinds are: -`Const` +`Freeze` : Types of this kind are deeply immutable; they contain no mutable memory locations directly or indirectly via pointers. -`Owned` +`Send` : 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 `Owned` types are `Static`. + 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). @@ -2882,7 +2882,7 @@ The kinds are: trait provides a single method `finalize` 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 `Owned` types + 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. @@ -2968,10 +2968,10 @@ frame they are allocated within. A task owns all memory it can *safely* reach through local variables, as well as managed, owning and borrowed pointers. -When a task sends a value that has the `Owned` trait to another task, +When a task sends a value that has the `Send` trait to another task, it loses ownership of the value sent and can no longer refer to it. This is statically guaranteed by the combined use of "move semantics", -and the compiler-checked _meaning_ of the `Owned` trait: +and the compiler-checked _meaning_ of the `Send` trait: it is only instantiated for (transitively) sendable kinds of data constructor and pointers, never including managed or borrowed pointers. @@ -3116,7 +3116,7 @@ These include: - read-only and read-write shared variables with various safe mutual exclusion patterns - simple locks and semaphores -When such facilities carry values, the values are restricted to the [`Owned` type-kind](#type-kinds). +When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds). Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks. Thus access to an entire data structure can be mediated through its owning "root" value; no further locking or copying is required to avoid data races within the substructure of such a value. diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 346112e655ba..047b57e56a61 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -159,7 +159,7 @@ pub struct Unique { priv ptr: *mut T } -impl Unique { +impl Unique { pub fn new(value: T) -> Unique { unsafe { let ptr = malloc(std::sys::size_of::() as size_t) as *mut T; @@ -182,7 +182,7 @@ impl Unique { } #[unsafe_destructor] -impl Drop for Unique { +impl Drop for Unique { fn drop(&self) { unsafe { let x = intrinsics::init(); // dummy value to swap in diff --git a/src/libextra/md4.rs b/src/libextra/md4.rs index 6c972a313c42..2534fedd9611 100644 --- a/src/libextra/md4.rs +++ b/src/libextra/md4.rs @@ -59,7 +59,8 @@ pub fn md4(msg: &[u8]) -> Quad { while i < e { let (aa, bb, cc, dd) = (a, b, c, d); - let mut (j, base) = (0u, i); + let mut j = 0u; + let mut base = i; while j < 16u { x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) + (msg[base + 2u] as u32 << 16u32) + diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index 5d3d31fdec47..f9eaa2bf02dd 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -415,7 +415,9 @@ fn get_authority(rawurl: &str) -> let mut port = None; let mut colon_count = 0; - let mut (pos, begin, end) = (0, 2, len); + let mut pos = 0; + let mut begin = 2; + let mut end = len; for rawurl.iter().enumerate().advance |(i,c)| { if i < 2 { loop; } // ignore the leading // diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 1ac913e8a00d..c2702ac70b13 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -380,7 +380,10 @@ impl Integer for BigUint { let mut d = Zero::zero::(); let mut n = 1; while m >= b { - let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n); + let (d0, d_unit, b_unit) = div_estimate(&m, &b, n); + let mut d0 = d0; + let mut d_unit = d_unit; + let mut b_unit = b_unit; let mut prod = b * d0; while prod > m { // FIXME(#6050): overloaded operators force moves with generic types @@ -442,7 +445,8 @@ impl Integer for BigUint { fn gcd(&self, other: &BigUint) -> BigUint { // Use Euclid's algorithm - let mut (m, n) = (copy *self, copy *other); + let mut m = copy *self; + let mut n = copy *other; while !m.is_zero() { let temp = m; m = n % temp; diff --git a/src/libextra/timer.rs b/src/libextra/timer.rs index 5a622ddfa0de..79451db8b171 100644 --- a/src/libextra/timer.rs +++ b/src/libextra/timer.rs @@ -123,7 +123,9 @@ pub fn recv_timeout(iotask: &IoTask, msecs: uint, wait_po: &Port) -> Option { - let mut (timeout_po, timeout_ch) = stream::<()>(); + let (timeout_po, timeout_ch) = stream::<()>(); + let mut timeout_po = timeout_po; + let mut timeout_ch = timeout_ch; delayed_send(iotask, msecs, &timeout_ch, ()); // XXX: Workaround due to ports and channels not being &mut. They should diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index ac51c7efc6f0..45fdda1990cc 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -139,12 +139,14 @@ impl ABIInfo for ARM_ABIInfo { attrs.push(attr); } - let mut (ret_ty, ret_attr) = if ret_def { + let (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { (LLVMType { cast: false, ty: Type::void() }, None) }; + let mut ret_ty = ret_ty; + let sret = ret_attr.is_some(); if sret { arg_tys.unshift(ret_ty); diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 8604ae37f774..47f2fb8634c1 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -178,12 +178,14 @@ impl ABIInfo for MIPS_ABIInfo { atys: &[Type], rty: Type, ret_def: bool) -> FnType { - let mut (ret_ty, ret_attr) = if ret_def { + let (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { (LLVMType { cast: false, ty: Type::void() }, None) }; + let mut ret_ty = ret_ty; + let sret = ret_attr.is_some(); let mut arg_tys = ~[]; let mut attrs = ~[]; diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 73323634c2b6..755075c17e9c 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -360,8 +360,9 @@ fn x86_64_tys(atys: &[Type], arg_tys.push(ty); attrs.push(attr); } - let mut (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(), + let (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(), StructRetAttribute); + let mut ret_ty = ret_ty; let sret = ret_attr.is_some(); if sret { arg_tys = vec::append(~[ret_ty], arg_tys); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 78c796329d80..045c8ec01aa1 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -319,9 +319,10 @@ pub fn trans_fn_ref_with_vtables( // Should be either intra-crate or inlined. assert_eq!(def_id.crate, ast::local_crate); - let mut (val, must_cast) = + let (val, must_cast) = monomorphize::monomorphic_fn(ccx, def_id, &substs, vtables, opt_impl_did, Some(ref_id)); + let mut val = val; if must_cast && ref_id != 0 { // Monotype of the REFERENCE to the function (type params // are subst'd) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 02f276cd0503..353227307560 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -907,9 +907,12 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let scaled_ix = Mul(bcx, ix_val, vt.llunit_size); base::maybe_name_value(bcx.ccx(), scaled_ix, "scaled_ix"); - let mut (bcx, base, len) = + let (bcx, base, len) = base_datum.get_vec_base_and_len(bcx, index_expr.span, index_expr.id, 0); + let mut bcx = bcx; + let mut base = base; + let mut len = len; if ty::type_is_str(base_ty) { // acccount for null terminator in the case of string diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 36920bd24887..59ac58a514f3 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -771,7 +771,9 @@ impl ReaderUtil for T { fn read_le_uint_n(&self, nbytes: uint) -> u64 { assert!(nbytes > 0 && nbytes <= 8); - let mut (val, pos, i) = (0u64, 0, nbytes); + let mut val = 0u64; + let mut pos = 0; + let mut i = nbytes; while i > 0 { val += (self.read_u8() as u64) << pos; pos += 8; @@ -787,7 +789,8 @@ impl ReaderUtil for T { fn read_be_uint_n(&self, nbytes: uint) -> u64 { assert!(nbytes > 0 && nbytes <= 8); - let mut (val, i) = (0u64, nbytes); + let mut val = 0u64; + let mut i = nbytes; while i > 0 { i -= 1; val += (self.read_u8() as u64) << i * 8; diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 74ec46ccfcd4..845152f85525 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -400,7 +400,8 @@ impl Integer for $T { #[inline] fn gcd(&self, other: &$T) -> $T { // Use Euclid's algorithm - let mut (m, n) = (*self, *other); + let mut m = *self; + let mut n = *other; while m != 0 { let temp = m; m = n % temp; diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 52f620f97ce8..0dabe7fafa83 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -237,7 +237,8 @@ impl Integer for $T { #[inline] fn gcd(&self, other: &$T) -> $T { // Use Euclid's algorithm - let mut (m, n) = (*self, *other); + let mut m = *self; + let mut n = *other; while m != 0 { let temp = m; m = n % temp; diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index ea4a9059e729..8a6c05ce6e2a 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -720,7 +720,8 @@ impl IsaacRng { fn isaac(&mut self) { self.c += 1; // abbreviations - let mut (a, b) = (self.a, self.b + self.c); + let mut a = self.a; + let mut b = self.b + self.c; static midpoint: uint = RAND_SIZE as uint / 2; diff --git a/src/libstd/rand/distributions.rs b/src/libstd/rand/distributions.rs index 6f4f1a34977e..e8dad2fc5e86 100644 --- a/src/libstd/rand/distributions.rs +++ b/src/libstd/rand/distributions.rs @@ -89,7 +89,8 @@ impl Rand for StandardNormal { // do-while, so the condition should be true on the first // run, they get overwritten anyway (0 < 1, so these are // good). - let mut (x, y) = (1.0, 0.0); + let mut x = 1.0; + let mut y = 0.0; // XXX infinities? while -2.0*y < x * x { diff --git a/src/libstd/rt/io/extensions.rs b/src/libstd/rt/io/extensions.rs index 1f82a9cd9633..c6654e9dabed 100644 --- a/src/libstd/rt/io/extensions.rs +++ b/src/libstd/rt/io/extensions.rs @@ -343,7 +343,9 @@ impl ReaderByteConversions for T { fn read_le_uint_n(&mut self, nbytes: uint) -> u64 { assert!(nbytes > 0 && nbytes <= 8); - let mut (val, pos, i) = (0u64, 0, nbytes); + let mut val = 0u64; + let mut pos = 0; + let mut i = nbytes; while i > 0 { val += (self.read_u8() as u64) << pos; pos += 8; @@ -359,7 +361,8 @@ impl ReaderByteConversions for T { fn read_be_uint_n(&mut self, nbytes: uint) -> u64 { assert!(nbytes > 0 && nbytes <= 8); - let mut (val, i) = (0u64, nbytes); + let mut val = 0u64; + let mut i = nbytes; while i > 0 { i -= 1; val += (self.read_u8() as u64) << i * 8; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index f8c8ffdbe35c..78538d099386 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -473,6 +473,31 @@ pub fn each_split_within<'a>(ss: &'a str, return cont; } +/** + * Replace all occurrences of one string with another + * + * # Arguments + * + * * s - The string containing substrings to replace + * * from - The string to replace + * * to - The replacement string + * + * # Return value + * + * The original string with all occurances of `from` replaced with `to` + */ +pub fn replace(s: &str, from: &str, to: &str) -> ~str { + let mut result = ~""; + let mut last_end = 0; + for s.matches_index_iter(from).advance |(start, end)| { + result.push_str(unsafe{raw::slice_bytes(s, last_end, start)}); + result.push_str(to); + last_end = end; + } + result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())}); + result +} + /* Section: Comparing strings */ @@ -631,6 +656,48 @@ pub fn with_capacity(capacity: uint) -> ~str { buf } +/** + * As char_len but for a slice of a string + * + * # Arguments + * + * * s - A valid string + * * start - The position inside `s` where to start counting in bytes + * * end - The position where to stop counting + * + * # Return value + * + * The number of Unicode characters in `s` between the given indices. + */ +pub fn count_chars(s: &str, start: uint, end: uint) -> uint { + assert!(s.is_char_boundary(start)); + assert!(s.is_char_boundary(end)); + let mut i = start; + let mut len = 0u; + while i < end { + let next = s.char_range_at(i).next; + len += 1u; + i = next; + } + return len; +} + +/// Counts the number of bytes taken by the first `n` chars in `s` +/// starting from `start`. +pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint { + assert!(is_char_boundary(s, start)); + let mut end = start; + let mut cnt = n; + let l = s.len(); + while cnt > 0u { + assert!(end < l); + let next = s.char_range_at(end).next; + cnt -= 1u; + end = next; + } + end - start +} + /// Given a first byte, determine how many bytes are in this UTF-8 character pub fn utf8_char_width(b: u8) -> uint { let byte: uint = b as uint; @@ -737,7 +804,8 @@ pub mod raw { /// Create a Rust string from a null-terminated *u8 buffer pub unsafe fn from_buf(buf: *u8) -> ~str { - let mut (curr, i) = (buf, 0u); + let mut curr = buf; + let mut i = 0u; while *curr != 0u8 { i += 1u; curr = ptr::offset(buf, i); diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 95fc53c1b55e..da3dc6b2a2e5 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -636,7 +636,9 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let child_data = Cell::new((notify_chan, child_arc, ancestors)); let result: ~fn() = || { // Agh. Get move-mode items into the closure. FIXME (#2829) - let mut (notify_chan, child_arc, ancestors) = child_data.take(); + let (notify_chan, child_arc, ancestors) = child_data.take(); + let mut child_arc = child_arc; + let mut ancestors = ancestors; // Child task runs this code. // Even if the below code fails to kick the child off, we must diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index ea0e212b14f7..dcd02744cf90 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -53,8 +53,9 @@ impl ToStr for (A,) { impl ToStr for HashMap { #[inline] fn to_str(&self) -> ~str { - let mut (acc, first) = (~"{", true); - for self.iter().advance |(key, value)| { + let mut acc = ~"{"; + let mut first = true; + for self.iter().advance |key, value| { if first { first = false; } @@ -73,7 +74,8 @@ impl ToStr for HashMap { impl ToStr for HashSet { #[inline] fn to_str(&self) -> ~str { - let mut (acc, first) = (~"{", true); + let mut acc = ~"{"; + let mut first = true; for self.iter().advance |element| { if first { first = false; @@ -121,7 +123,8 @@ impl ToStr for (A, B, C) { impl<'self,A:ToStr> ToStr for &'self [A] { #[inline] fn to_str(&self) -> ~str { - let mut (acc, first) = (~"[", true); + let mut acc = ~"["; + let mut first = true; for self.iter().advance |elt| { if first { first = false; @@ -139,7 +142,8 @@ impl<'self,A:ToStr> ToStr for &'self [A] { impl ToStr for ~[A] { #[inline] fn to_str(&self) -> ~str { - let mut (acc, first) = (~"[", true); + let mut acc = ~"["; + let mut first = true; for self.iter().advance |elt| { if first { first = false; @@ -157,7 +161,8 @@ impl ToStr for ~[A] { impl ToStr for @[A] { #[inline] fn to_str(&self) -> ~str { - let mut (acc, first) = (~"[", true); + let mut acc = ~"["; + let mut first = true; for self.iter().advance |elt| { if first { first = false; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 8cbd9309cc6b..aa4d632a4827 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -348,7 +348,8 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { pub fn dedup(v: &mut ~[T]) { unsafe { if v.len() < 1 { return; } - let mut (last_written, next_to_read) = (0, 1); + let mut last_written = 0; + let mut next_to_read = 1; do as_const_buf(*v) |p, ln| { // We have a mutable reference to v, so we can make arbitrary // changes. (cf. push and pop) @@ -798,7 +799,8 @@ pub fn bsearch_elem(v: &[T], x: &T) -> Option { * Convert a vector of pairs into a pair of vectors, by reference. As unzip(). */ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { - let mut (ts, us) = (~[], ~[]); + let mut ts = ~[]; + let mut us = ~[]; for v.iter().advance |p| { let (t, u) = copy *p; ts.push(t); @@ -816,7 +818,8 @@ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { * of the i-th tuple of the input vector. */ pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { - let mut (ts, us) = (~[], ~[]); + let mut ts = ~[]; + let mut us = ~[]; do consume(v) |_i, p| { let (t, u) = p; ts.push(t); diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 9ba7cb3c818e..4ffaba090610 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -619,6 +619,15 @@ pub enum Privacy { Public } +/// Returns true if the given pattern consists solely of an identifier +/// and false otherwise. +pub fn pat_is_ident(pat: @ast::pat) -> bool { + match pat.node { + ast::pat_ident(*) => true, + _ => false, + } +} + // HYGIENE FUNCTIONS /// Construct an identifier with the given name and an empty context: diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 32508f3b477a..383faf22037d 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -62,6 +62,7 @@ pub enum ObsoleteSyntax { ObsoleteFixedLengthVectorType, ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl, + ObsoleteMutWithMultipleBindings, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -223,6 +224,11 @@ impl Parser { "instead of e.g. `let a = 1, b = 2`, write \ `let (a, b) = (1, 2)`." ), + ObsoleteMutWithMultipleBindings => ( + "`mut` with multiple bindings", + "use multiple local declarations instead of e.g. `let mut \ + (x, y) = ...`." + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d67771fc4354..11c73fe57111 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -83,7 +83,8 @@ use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer}; use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType}; use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl}; -use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident, is_ident_or_path}; +use parse::obsolete::{ObsoleteMutWithMultipleBindings}; +use parse::token::{can_begin_expr, get_ident_interner, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents, token_to_binop}; use parse::token; use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; @@ -821,6 +822,11 @@ impl Parser { self.parse_arg_mode(); is_mutbl = self.eat_keyword(keywords::Mut); let pat = self.parse_pat(); + + if is_mutbl && !ast_util::pat_is_ident(pat) { + self.obsolete(*self.span, ObsoleteMutWithMultipleBindings) + } + self.expect(&token::COLON); pat } else { @@ -2560,6 +2566,11 @@ impl Parser { fn parse_local(&self, is_mutbl: bool) -> @local { let lo = self.span.lo; let pat = self.parse_pat(); + + if is_mutbl && !ast_util::pat_is_ident(pat) { + self.obsolete(*self.span, ObsoleteMutWithMultipleBindings) + } + let mut ty = @Ty { id: self.get_id(), node: ty_infer, @@ -4420,7 +4431,8 @@ impl Parser { let mut attrs = vec::append(first_item_attrs, self.parse_outer_attributes()); // First, parse view items. - let mut (view_items, items) = (~[], ~[]); + let mut view_items = ~[]; + let mut items = ~[]; let mut done = false; // I think this code would probably read better as a single // loop with a mutable three-state-variable (for extern mods, diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 70f56f5c5a39..b79ecd03c0c6 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -23,7 +23,10 @@ fn main() { for range(0, h) |y| { let y = y as f64; for range(0, w) |x| { - let mut (Zr, Zi, Tr, Ti) = (0f64, 0f64, 0f64, 0f64); + let mut Zr = 0f64; + let mut Zi = 0f64; + let mut Tr = 0f64; + let mut Ti = 0f64; let Cr = 2.0 * (x as f64) / (w as f64) - 1.5; let Ci = 2.0 * (y as f64) / (h as f64) - 1.0; diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs index 00d73b02dbc6..07adc3d81e5f 100644 --- a/src/test/compile-fail/kindck-destructor-owned.rs +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -2,7 +2,7 @@ struct Foo { f: @mut int, } -impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Send +impl Drop for Foo { //~ ERROR cannot implement a destructor on a structure that does not satisfy Send fn drop(&self) { *self.f = 10; } diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index 38983a9aca6a..99057ba940c5 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -12,7 +12,7 @@ fn foo(_x: @uint) {} fn main() { let x = @3u; - let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` - let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` - let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send` + let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send` } diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 605e59d56c89..5f0d4bc60ac0 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -32,7 +32,7 @@ fn main() { let x = Cell::new(foo(Port(@()))); do task::spawn { - let y = x.take(); //~ ERROR does not fulfill `Owned` + let y = x.take(); //~ ERROR does not fulfill `Send` error!(y); } } diff --git a/src/test/compile-fail/non_owned-enum.rs b/src/test/compile-fail/non_owned-enum.rs index 6068b7f17303..20b571ad6141 100644 --- a/src/test/compile-fail/non_owned-enum.rs +++ b/src/test/compile-fail/non_owned-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[non_owned] +#[non_sendable] enum Foo { A } fn bar(_: T) {} diff --git a/src/test/compile-fail/non_owned-struct.rs b/src/test/compile-fail/non_owned-struct.rs index b6f29df05752..d4b8e6755a12 100644 --- a/src/test/compile-fail/non_owned-struct.rs +++ b/src/test/compile-fail/non_owned-struct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[non_owned] +#[non_sendable] struct Foo { a: int } fn bar(_: T) {} diff --git a/src/test/run-pass/let-destruct-fresh-mem.rs b/src/test/run-pass/let-destruct-fresh-mem.rs index 500502320df0..2615396653d3 100644 --- a/src/test/run-pass/let-destruct-fresh-mem.rs +++ b/src/test/run-pass/let-destruct-fresh-mem.rs @@ -13,7 +13,9 @@ struct A { a: int } pub fn main() { let u = X {x: 10, y: @A {a: 20}}; - let mut X {x: x, y: @A {a: a}} = u; + let X {x: x, y: @A {a: a}} = u; + let mut x = x; + let mut a = a; x = 100; a = 100; assert_eq!(x, 100); diff --git a/src/test/run-pass/pipe-peek.rs b/src/test/run-pass/pipe-peek.rs index 8d8c96c6f514..cbc822060cec 100644 --- a/src/test/run-pass/pipe-peek.rs +++ b/src/test/run-pass/pipe-peek.rs @@ -22,7 +22,9 @@ proto! oneshot ( ) pub fn main() { - let mut (p, c) = oneshot::init(); + let (p, c) = oneshot::init(); + let mut p = p; + let mut c = c; assert!(!pipes::peek(&mut p)); From 90ad44428759617723f2f4630aa22bbed6f33aaf Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 7 Jun 2013 15:47:05 -0700 Subject: [PATCH 237/336] libsyntax: Fix merge fallout --- src/libsyntax/parse/parser.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 11c73fe57111..5981e39abb74 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -84,8 +84,10 @@ use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType}; use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl}; use parse::obsolete::{ObsoleteMutWithMultipleBindings}; -use parse::token::{can_begin_expr, get_ident_interner, is_ident, is_ident_or_path}; -use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents, token_to_binop}; +use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident}; +use parse::token::{is_ident_or_path}; +use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents}; +use parse::token::{token_to_binop}; use parse::token; use parse::{new_sub_parser_from_file, next_node_id, ParseSess}; use opt_vec; From f463e69d203ffdd1a0c6c73612a0ba514a700a78 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 7 Jun 2013 19:59:32 -0700 Subject: [PATCH 238/336] librustc: Add a small vector optimization for GEPi. Shaves a second off trans, I think? --- src/librustc/middle/trans/build.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 83c1a3c80db2..a90089bb4703 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -610,12 +610,21 @@ pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { // Simple wrapper around GEP that takes an array of ints and wraps them // in C_i32() -// -// FIXME #6571: Use a small-vector optimization to avoid allocations here. +#[inline] pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { - let v = do vec::map(ixs) |i| { C_i32(*i as i32) }; - count_insn(cx, "gepi"); - return InBoundsGEP(cx, base, v); + // Small vector optimization. This should catch 100% of the cases that + // we care about. + if ixs.len() < 16 { + let mut small_vec = [ C_i32(0), ..16 ]; + for ixs.eachi |i, &ix| { + small_vec[i] = C_i32(ix as i32) + } + InBoundsGEP(cx, base, small_vec.slice(0, ixs.len())) + } else { + let v = do vec::map(ixs) |i| { C_i32(*i as i32) }; + count_insn(cx, "gepi"); + InBoundsGEP(cx, base, v) + } } pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { From 8cd40f9032fa15dc083646ba2105b3fae0a96eb5 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 10 Jun 2013 15:55:51 -0700 Subject: [PATCH 239/336] libstd: Fix merge fallout. --- src/libstd/str.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 78538d099386..07a67ca3b1e6 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -357,7 +357,8 @@ impl<'self> Iterator<(uint, uint)> for StrMatchesIndexIterator<'self> { fn next(&mut self) -> Option<(uint, uint)> { // See Issue #1932 for why this is a naive search let (h_len, n_len) = (self.haystack.len(), self.needle.len()); - let mut (match_start, match_i) = (0, 0); + let mut match_start = 0; + let mut match_i = 0; while self.position < h_len { if self.haystack[self.position] == self.needle[match_i] { @@ -685,7 +686,7 @@ pub fn count_chars(s: &str, start: uint, end: uint) -> uint { /// Counts the number of bytes taken by the first `n` chars in `s` /// starting from `start`. pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint { - assert!(is_char_boundary(s, start)); + assert!(s.is_char_boundary(start)); let mut end = start; let mut cnt = n; let l = s.len(); From 3fcd4dca301d01c41a7db7f9023bc11be1025fc7 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 10 Jun 2013 19:42:28 -0700 Subject: [PATCH 240/336] libsyntax: Remove "copy" pattern bindings from the language --- src/libsyntax/parse/obsolete.rs | 5 +++++ src/libsyntax/parse/parser.rs | 4 ++-- src/test/compile-fail/rcmut-not-const-and-not-owned.rs | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 383faf22037d..7f2d06ee1e41 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -63,6 +63,7 @@ pub enum ObsoleteSyntax { ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl, ObsoleteMutWithMultipleBindings, + ObsoletePatternCopyKeyword, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -229,6 +230,10 @@ impl Parser { "use multiple local declarations instead of e.g. `let mut \ (x, y) = ...`." ), + ObsoletePatternCopyKeyword => ( + "`copy` in patterns", + "`copy` in patterns no longer has any effect" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5981e39abb74..ee5ef8dfa6b9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -84,6 +84,7 @@ use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType}; use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl}; use parse::obsolete::{ObsoleteMutWithMultipleBindings}; +use parse::obsolete::{ObsoletePatternCopyKeyword}; use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident}; use parse::token::{is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents}; @@ -2445,8 +2446,7 @@ impl Parser { pat = self.parse_pat_ident(bind_by_ref(mutbl)); } else if self.eat_keyword(keywords::Copy) { // parse copy pat - self.warn("copy keyword in patterns no longer has any effect, \ - remove it"); + self.obsolete(*self.span, ObsoletePatternCopyKeyword); pat = self.parse_pat_ident(bind_infer); } else { let can_be_enum_or_struct; diff --git a/src/test/compile-fail/rcmut-not-const-and-not-owned.rs b/src/test/compile-fail/rcmut-not-const-and-not-owned.rs index 9e7236a67d96..45cb137b0845 100644 --- a/src/test/compile-fail/rcmut-not-const-and-not-owned.rs +++ b/src/test/compile-fail/rcmut-not-const-and-not-owned.rs @@ -10,11 +10,11 @@ extern mod extra; -fn o(_: &T) {} -fn c(_: &T) {} +fn o(_: &T) {} +fn c(_: &T) {} fn main() { let x = extra::rc::rc_mut_from_owned(0); - o(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Owned` - c(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Const` + o(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Send` + c(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Freeze` } From a1531ed946e2d650fc6cb5af6258fed8003e9443 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 11 Jun 2013 19:13:42 -0700 Subject: [PATCH 241/336] librustc: Remove the broken overloaded assign-ops from the language. They evaluated the receiver twice. They should be added back with `AddAssign`, `SubAssign`, etc., traits. --- doc/tutorial.md | 4 +- src/compiletest/errors.rs | 2 +- src/compiletest/runtest.rs | 8 +-- src/libextra/arena.rs | 18 +++--- src/libextra/bitv.rs | 12 +++- src/libextra/getopts.rs | 50 ++++++++++------ src/libextra/json.rs | 22 +++---- src/libextra/md4.rs | 6 +- src/libextra/net_url.rs | 8 +-- src/libextra/num/bigint.rs | 4 +- src/libextra/time.rs | 2 +- src/librustc/back/link.rs | 30 +++++----- src/librustc/metadata/encoder.rs | 2 +- src/librustc/metadata/tydecode.rs | 4 +- src/librustc/middle/resolve.rs | 8 ++- src/librustc/middle/trans/asm.rs | 10 ++-- src/librustc/middle/trans/build.rs | 8 +-- src/librustc/middle/trans/common.rs | 9 ++- src/librustc/middle/ty.rs | 6 +- src/librustc/middle/typeck/check/mod.rs | 56 ++++++++++++++++-- src/librustdoc/markdown_pass.rs | 6 +- src/librustdoc/markdown_writer.rs | 4 +- src/librustdoc/page_pass.rs | 2 +- src/librusti/rusti.rs | 3 +- src/libstd/hash.rs | 7 ++- src/libstd/num/num.rs | 2 +- src/libstd/path.rs | 16 ++++-- src/libsyntax/diagnostic.rs | 27 ++++++--- src/libsyntax/ext/concat_idents.rs | 3 +- src/libsyntax/ext/pipes/pipec.rs | 57 ++++++++++--------- src/libsyntax/parse/attr.rs | 16 +++--- src/libsyntax/parse/comments.rs | 6 +- src/libsyntax/parse/common.rs | 8 +-- src/libsyntax/parse/lexer.rs | 8 +-- src/libsyntax/parse/parser.rs | 8 ++- src/libsyntax/parse/token.rs | 4 +- src/libsyntax/print/pp.rs | 8 ++- src/test/bench/core-std.rs | 5 +- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-fasta.rs | 2 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- src/test/bench/sudoku.rs | 4 +- src/test/compile-fail/issue-2149.rs | 2 +- src/test/run-fail/issue-3029.rs | 4 +- src/test/run-pass/istr.rs | 8 +-- src/test/run-pass/liveness-move-in-loop.rs | 2 +- src/test/run-pass/match-join.rs | 2 +- src/test/run-pass/monad.rs | 4 +- src/test/run-pass/mutable-alias-vec.rs | 4 +- src/test/run-pass/operator-overloading.rs | 2 +- src/test/run-pass/shadow.rs | 2 +- src/test/run-pass/static-impl.rs | 4 +- src/test/run-pass/str-append.rs | 2 +- src/test/run-pass/str-growth.rs | 6 +- src/test/run-pass/trait-generic.rs | 2 +- src/test/run-pass/vec-growth.rs | 8 +-- src/test/run-pass/while-prelude-drop.rs | 2 +- 57 files changed, 316 insertions(+), 209 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index fc0f7b74a7af..aa6e90826bbb 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1281,9 +1281,9 @@ let your_crayons = ~[BananaMania, Beaver, Bittersweet]; // Add two vectors to create a new one let our_crayons = my_crayons + your_crayons; -// += will append to a vector, provided it lives in a mutable slot +// .push_all() will append to a vector, provided it lives in a mutable slot let mut my_crayons = my_crayons; -my_crayons += your_crayons; +my_crayons.push_all(your_crayons); ~~~~ > ***Note:*** The above examples of vector addition use owned diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index cdc0defcbcab..4649d4dfc3c4 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -21,7 +21,7 @@ pub fn load_errors(testfile: &Path) -> ~[ExpectedError] { let mut line_num = 1u; while !rdr.eof() { let ln = rdr.read_line(); - error_patterns += parse_expected(line_num, ln); + error_patterns.push_all_move(parse_expected(line_num, ln)); line_num += 1u; } return error_patterns; diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index a31e0b961f7f..0e04be34c795 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -226,8 +226,8 @@ actual:\n\ ~"-L", config.build_base.to_str(), ~"-L", aux_output_dir_name(config, testfile).to_str()]; - args += split_maybe_args(&config.rustcflags); - args += split_maybe_args(&props.compile_flags); + args.push_all_move(split_maybe_args(&config.rustcflags)); + args.push_all_move(split_maybe_args(&props.compile_flags)); return ProcArgs {prog: config.rustc_path.to_str(), args: args}; } } @@ -581,8 +581,8 @@ fn make_compile_args(config: &config, props: &TestProps, extras: ~[~str], ~"-o", xform(config, testfile).to_str(), ~"-L", config.build_base.to_str()] + extras; - args += split_maybe_args(&config.rustcflags); - args += split_maybe_args(&props.compile_flags); + args.push_all_move(split_maybe_args(&config.rustcflags)); + args.push_all_move(split_maybe_args(&props.compile_flags)); return ProcArgs {prog: config.rustc_path.to_str(), args: args}; } diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 604d9ba73732..79e09c32030b 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -186,20 +186,18 @@ impl Arena { #[inline] fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 { unsafe { - // XXX: Borrow check - let head = transmute_mut_region(&mut self.pod_head); - - let start = round_up_to(head.fill, align); + let this = transmute_mut_region(self); + let start = round_up_to(this.pod_head.fill, align); let end = start + n_bytes; - if end > at_vec::capacity(head.data) { - return self.alloc_pod_grow(n_bytes, align); + if end > at_vec::capacity(this.pod_head.data) { + return this.alloc_pod_grow(n_bytes, align); } - head.fill = end; + this.pod_head.fill = end; //debug!("idx = %u, size = %u, align = %u, fill = %u", // start, n_bytes, align, head.fill); - ptr::offset(vec::raw::to_ptr(head.data), start) + ptr::offset(vec::raw::to_ptr(this.pod_head.data), start) } } @@ -237,7 +235,7 @@ impl Arena { let after_tydesc = head.fill + sys::size_of::<*TyDesc>(); let start = round_up_to(after_tydesc, align); let end = start + n_bytes; - if end > at_vec::capacity(head.data) { + if end > at_vec::capacity(self.head.data) { return self.alloc_nonpod_grow(n_bytes, align); } head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>()); @@ -245,7 +243,7 @@ impl Arena { //debug!("idx = %u, size = %u, align = %u, fill = %u", // start, n_bytes, align, head.fill); - let buf = vec::raw::to_ptr(head.data); + let buf = vec::raw::to_ptr(self.head.data); return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start)); } } diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 6e4507d4277a..4fe7761bf18d 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -476,9 +476,15 @@ impl Bitv { * character is either '0' or '1'. */ pub fn to_str(&self) -> ~str { - let mut rs = ~""; - for self.each() |i| { if i { rs += "1"; } else { rs += "0"; } }; - rs + let mut rs = ~""; + for self.each() |i| { + if i { + rs.push_char('1'); + } else { + rs.push_char('0'); + } + }; + rs } diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 9c416550eb78..fa064e6330e7 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -606,33 +606,47 @@ pub mod groups { let mut row = " ".repeat(4); // short option - row += match short_name.len() { - 0 => ~"", - 1 => ~"-" + short_name + " ", + match short_name.len() { + 0 => {} + 1 => { + row.push_char('-'); + row.push_str(short_name); + row.push_char(' '); + } _ => fail!("the short name should only be 1 ascii char long"), - }; + } // long option - row += match long_name.len() { - 0 => ~"", - _ => ~"--" + long_name + " ", - }; + match long_name.len() { + 0 => {} + _ => { + row.push_str("--"); + row.push_str(long_name); + row.push_char(' '); + } + } // arg - row += match hasarg { - No => ~"", - Yes => hint, - Maybe => ~"[" + hint + "]", - }; + match hasarg { + No => {} + Yes => row.push_str(hint), + Maybe => { + row.push_char('['); + row.push_str(hint); + row.push_char(']'); + } + } // FIXME: #5516 // here we just need to indent the start of the description let rowlen = row.len(); - row += if rowlen < 24 { - " ".repeat(24 - rowlen) + if rowlen < 24 { + for (24 - rowlen).times { + row.push_char(' ') + } } else { - copy desc_sep - }; + row.push_str(desc_sep) + } // Normalize desc to contain words separated by one space character let mut desc_normalized_whitespace = ~""; @@ -649,7 +663,7 @@ pub mod groups { // FIXME: #5516 // wrapped description - row += desc_rows.connect(desc_sep); + row.push_str(desc_rows.connect(desc_sep)); row }); diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 15553b035f65..a71be18174ab 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -60,25 +60,27 @@ fn escape_str(s: &str) -> ~str { let mut escaped = ~"\""; for s.iter().advance |c| { match c { - '"' => escaped += "\\\"", - '\\' => escaped += "\\\\", - '\x08' => escaped += "\\b", - '\x0c' => escaped += "\\f", - '\n' => escaped += "\\n", - '\r' => escaped += "\\r", - '\t' => escaped += "\\t", - _ => escaped += str::from_char(c) + '"' => escaped.push_str("\\\""), + '\\' => escaped.push_str("\\\\"), + '\x08' => escaped.push_str("\\b"), + '\x0c' => escaped.push_str("\\f"), + '\n' => escaped.push_str("\\n"), + '\r' => escaped.push_str("\\r"), + '\t' => escaped.push_str("\\t"), + _ => escaped.push_char(c), } }; - escaped += "\""; + escaped.push_char('"'); escaped } fn spaces(n: uint) -> ~str { let mut ss = ~""; - for n.times { ss.push_str(" "); } + for n.times { + ss.push_str(" "); + } return ss; } diff --git a/src/libextra/md4.rs b/src/libextra/md4.rs index 2534fedd9611..3be7394b46d0 100644 --- a/src/libextra/md4.rs +++ b/src/libextra/md4.rs @@ -119,8 +119,10 @@ pub fn md4_str(msg: &[u8]) -> ~str { let mut i = 0u32; while i < 4u32 { let byte = (u >> (i * 8u32)) as u8; - if byte <= 16u8 { result += "0"; } - result += uint::to_str_radix(byte as uint, 16u); + if byte <= 16u8 { + result.push_char('0') + } + result.push_str(uint::to_str_radix(byte as uint, 16u)); i += 1u32; } } diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index f9eaa2bf02dd..a60f51e751e1 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -93,10 +93,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { out.push_char(ch); } - _ => out += fmt!("%%%X", ch as uint) + _ => out.push_str(fmt!("%%%X", ch as uint)) } } else { - out += fmt!("%%%X", ch as uint); + out.push_str(fmt!("%%%X", ch as uint)); } } } @@ -192,7 +192,7 @@ fn encode_plus(s: &str) -> ~str { out.push_char(ch); } ' ' => out.push_char('+'), - _ => out += fmt!("%%%X", ch as uint) + _ => out.push_str(fmt!("%%%X", ch as uint)) } } @@ -218,7 +218,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str { first = false; } - out += fmt!("%s=%s", key, encode_plus(*value)); + out.push_str(fmt!("%s=%s", key, encode_plus(*value))); } } diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index c2702ac70b13..b0fa715fdd81 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -510,11 +510,11 @@ impl ToStrRadix for BigUint { let mut m = n; while m > divider { let (d, m0) = m.div_mod_floor(÷r); - result += [m0.to_uint() as BigDigit]; + result.push(m0.to_uint() as BigDigit); m = d; } if !m.is_zero() { - result += [m.to_uint() as BigDigit]; + result.push(m.to_uint() as BigDigit); } return result; } diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 555563a0cd7e..931a42d3c537 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -849,7 +849,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str { do io::with_str_reader(format) |rdr| { while !rdr.eof() { match rdr.read_char() { - '%' => buf += parse_type(rdr.read_char(), tm), + '%' => buf.push_str(parse_type(rdr.read_char(), tm)), ch => buf.push_char(ch) } } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 55d0219a7871..af23696cbc1a 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -642,15 +642,15 @@ pub fn sanitize(s: &str) -> ~str { for s.iter().advance |c| { match c { // Escape these with $ sequences - '@' => result += "$SP$", - '~' => result += "$UP$", - '*' => result += "$RP$", - '&' => result += "$BP$", - '<' => result += "$LT$", - '>' => result += "$GT$", - '(' => result += "$LP$", - ')' => result += "$RP$", - ',' => result += "$C$", + '@' => result.push_str("$SP$"), + '~' => result.push_str("$UP$"), + '*' => result.push_str("$RP$"), + '&' => result.push_str("$BP$"), + '<' => result.push_str("$LT$"), + '>' => result.push_str("$GT$"), + '(' => result.push_str("$LP$"), + ')' => result.push_str("$RP$"), + ',' => result.push_str("$C$"), // '.' doesn't occur in types and functions, so reuse it // for ':' @@ -686,12 +686,14 @@ pub fn mangle(sess: Session, ss: path) -> ~str { let mut n = ~"_ZN"; // Begin name-sequence. for ss.iter().advance |s| { - match *s { path_name(s) | path_mod(s) => { - let sani = sanitize(sess.str_of(s)); - n += fmt!("%u%s", sani.len(), sani); - } } + match *s { + path_name(s) | path_mod(s) => { + let sani = sanitize(sess.str_of(s)); + n.push_str(fmt!("%u%s", sani.len(), sani)); + } + } } - n += "E"; // End name-sequence. + n.push_char('E'); // End name-sequence. n } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index b96e96c9618f..f8ecef3b4a49 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -979,7 +979,7 @@ fn encode_info_for_item(ecx: &EncodeContext, // >:-< let mut impl_path = vec::append(~[], path); - impl_path += [ast_map::path_name(item.ident)]; + impl_path.push(ast_map::path_name(item.ident)); for methods.iter().advance |m| { index.push(entry {val: m.id, pos: ebml_w.writer.tell()}); diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 1507fc186e7a..1ec5c983f624 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -261,7 +261,9 @@ fn parse_opt(st: &mut PState, f: &fn(&mut PState) -> T) -> Option { fn parse_str(st: &mut PState, term: char) -> ~str { let mut result = ~""; while peek(st) != term { - result += str::from_byte(next_byte(st)); + unsafe { + str::raw::push_byte(&mut result, next_byte(st)); + } } next(st); return result; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index b839e22f9060..bf37ce676a81 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -2091,8 +2091,12 @@ impl Resolver { let mut first = true; let mut result = ~""; for idents.iter().advance |ident| { - if first { first = false; } else { result += "::" }; - result += self.session.str_of(*ident); + if first { + first = false + } else { + result.push_str("::") + } + result.push_str(*self.session.str_of(*ident)); }; return result; } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 7d0defde4354..b208592d113f 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -98,15 +98,15 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { if !ia.clobbers.is_empty() && !clobbers.is_empty() { clobbers = fmt!("%s,%s", ia.clobbers, clobbers); } else { - clobbers += ia.clobbers; + clobbers.push_str(*ia.clobbers); }; // Add the clobbers to our constraints list - if !clobbers.is_empty() && !constraints.is_empty() { - constraints += ","; - constraints += clobbers; + if clobbers.len() != 0 && constraints.len() != 0 { + constraints.push_char(','); + constraints.push_str(clobbers); } else { - constraints += clobbers; + constraints.push_str(clobbers); } debug!("Asm Constraints: %?", constraints); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index a90089bb4703..e48a98cd90c0 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -68,13 +68,13 @@ pub fn count_insn(cx: block, category: &str) { i = 0u; while i < len { i = *mm.get(&v[i]); - s += "/"; - s += v[i]; + s.push_char('/'); + s.push_str(v[i]); i += 1u; } - s += "/"; - s += category; + s.push_char('/'); + s.push_str(category); let n = match h.find(&s) { Some(&n) => n, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 67ca647862ba..4e3583a4095a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -964,9 +964,12 @@ pub fn path_str(sess: session::Session, p: &[path_elt]) -> ~str { for p.iter().advance |e| { match *e { ast_map::path_name(s) | ast_map::path_mod(s) => { - if first { first = false; } - else { r += "::"; } - r += sess.str_of(s); + if first { + first = false + } else { + r.push_str("::") + } + r.push_str(*sess.str_of(s)); } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 81a1ef6563f4..212f78c47568 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2120,7 +2120,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { TC_NONE, |tc, f| tc + tc_mt(cx, f.mt, cache)); if ty::has_dtor(cx, did) { - res += TC_DTOR; + res = res + TC_DTOR; } apply_tc_attr(cx, did, res) } @@ -2205,10 +2205,10 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { fn apply_tc_attr(cx: ctxt, did: def_id, mut tc: TypeContents) -> TypeContents { if has_attr(cx, did, "mutable") { - tc += TC_MUTABLE; + tc = tc + TC_MUTABLE; } if has_attr(cx, did, "non_sendable") { - tc += TC_NON_SENDABLE; + tc = tc + TC_NON_SENDABLE; } tc } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 97e0cd4baf84..1da76644244f 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -213,6 +213,13 @@ impl PurityState { } } +/// Whether `check_binop` allows overloaded operators to be invoked. +#[deriving(Eq)] +enum AllowOverloadedOperatorsFlag { + AllowOverloadedOperators, + DontAllowOverloadedOperators, +} + pub struct FnCtxt { // Number of errors that had been reported when we started // checking this function. On exit, if we find that *more* errors @@ -1487,7 +1494,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, lhs: @ast::expr, rhs: @ast::expr, // Used only in the error case - expected_result: Option + expected_result: Option, + allow_overloaded_operators: AllowOverloadedOperatorsFlag ) { let tcx = fcx.ccx.tcx; @@ -1537,8 +1545,30 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } - let result_t = check_user_binop(fcx, callee_id, expr, lhs, lhs_t, op, rhs, - expected_result); + // Check for overloaded operators if allowed. + let result_t; + if allow_overloaded_operators == AllowOverloadedOperators { + result_t = check_user_binop(fcx, + callee_id, + expr, + lhs, + lhs_t, + op, + rhs, + expected_result); + } else { + fcx.type_error_message(expr.span, + |actual| { + fmt!("binary operation %s cannot be \ + applied to type `%s`", + ast_util::binop_to_str(op), + actual) + }, + lhs_t, + None); + result_t = ty::mk_err(); + } + fcx.write_ty(expr.id, result_t); if ty::type_is_error(result_t) { fcx.write_ty(rhs.id, result_t); @@ -2229,7 +2259,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } ast::expr_binary(callee_id, op, lhs, rhs) => { - check_binop(fcx, callee_id, expr, op, lhs, rhs, expected); + check_binop(fcx, + callee_id, + expr, + op, + lhs, + rhs, + expected, + AllowOverloadedOperators); + let lhs_ty = fcx.expr_ty(lhs); let rhs_ty = fcx.expr_ty(rhs); if ty::type_is_error(lhs_ty) || @@ -2242,7 +2280,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_assign_op(callee_id, op, lhs, rhs) => { - check_binop(fcx, callee_id, expr, op, lhs, rhs, expected); + check_binop(fcx, + callee_id, + expr, + op, + lhs, + rhs, + expected, + DontAllowOverloadedOperators); + let lhs_t = fcx.expr_ty(lhs); let result_t = fcx.expr_ty(expr); demand::suptype(fcx, expr.span, result_t, lhs_t); diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index ca167c3726ae..e9deef6b2236 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -192,11 +192,11 @@ pub fn header_name(doc: doc::ItemTag) -> ~str { let mut trait_part = ~""; for doc.trait_types.iter().enumerate().advance |(i, trait_type)| { if i == 0 { - trait_part += " of "; + trait_part.push_str(" of "); } else { - trait_part += ", "; + trait_part.push_str(", "); } - trait_part += *trait_type; + trait_part.push_str(*trait_type); } fmt!("%s for %s%s", trait_part, *self_ty, bounds) } diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 353152763267..a093824e453b 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -130,7 +130,7 @@ fn generic_writer(process: ~fn(markdown: ~str)) -> Writer { let mut keep_going = true; while keep_going { match po.recv() { - Write(s) => markdown += s, + Write(s) => markdown.push_str(s), Done => keep_going = false } } @@ -214,7 +214,7 @@ fn future_writer() -> (Writer, future::Future<~str>) { let mut res = ~""; loop { match port.recv() { - Write(s) => res += s, + Write(s) => res.push_str(s), Done => break } } diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 584e6ccc8873..35a433ec9ded 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -70,7 +70,7 @@ fn make_doc_from_pages(page_port: &PagePort) -> doc::Doc { loop { let val = page_port.recv(); if val.is_some() { - pages += [val.unwrap()]; + pages.push(val.unwrap()); } else { break; } diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index a586cb83fa18..abb0cf271ec4 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -402,7 +402,8 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer, if line.trim() == ":}" { end_multiline = true; } else { - multiline_cmd += line + "\n"; + multiline_cmd.push_str(line); + multiline_cmd.push_char('\n'); } } } diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs index 8e88bfb46329..6c3fcd41ed3b 100644 --- a/src/libstd/hash.rs +++ b/src/libstd/hash.rs @@ -24,6 +24,7 @@ use container::Container; use iterator::IteratorUtil; use rt::io::Writer; +use str::OwnedStr; use to_bytes::IterBytes; use uint; use vec::ImmutableVector; @@ -369,7 +370,7 @@ impl Streaming for SipState { let r = self.result_bytes(); let mut s = ~""; for r.iter().advance |b| { - s += uint::to_str_radix(*b as uint, 16u); + s.push_str(uint::to_str_radix(*b as uint, 16u)); } s } @@ -471,7 +472,7 @@ mod tests { fn to_hex_str(r: &[u8, ..8]) -> ~str { let mut s = ~""; for r.iter().advance |b| { - s += uint::to_str_radix(*b as uint, 16u); + s.push_str(uint::to_str_radix(*b as uint, 16u)); } s } @@ -492,7 +493,7 @@ mod tests { assert!(f == i && f == v); - buf += [t as u8]; + buf.push(t as u8); stream_inc.input([t as u8]); t += 1; diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index 30a18a0587bc..b856c3c65ea5 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -412,7 +412,7 @@ pub fn pow_with_uint+Mul>(radix: uint, pow if my_pow % 2u == 1u { total = total * multiplier; } - my_pow = my_pow / 2u; + my_pow = my_pow / 2u; multiplier = multiplier * multiplier; } total diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 897926940116..6059ba5cbddd 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -21,8 +21,8 @@ use cmp::Eq; use iterator::IteratorUtil; use libc; use option::{None, Option, Some}; -use str; use str::{Str, StrSlice, StrVector}; +use str; use to_str::ToStr; use ascii::{AsciiCast, AsciiStr}; use vec::{OwnedVector, ImmutableVector}; @@ -476,7 +476,7 @@ impl ToStr for PosixPath { fn to_str(&self) -> ~str { let mut s = ~""; if self.is_absolute { - s += "/"; + s.push_str("/"); } s + self.components.connect("/") } @@ -655,15 +655,21 @@ impl ToStr for WindowsPath { fn to_str(&self) -> ~str { let mut s = ~""; match self.host { - Some(ref h) => { s += "\\\\"; s += *h; } + Some(ref h) => { + s.push_str("\\\\"); + s.push_str(*h); + } None => { } } match self.device { - Some(ref d) => { s += *d; s += ":"; } + Some(ref d) => { + s.push_str(*d); + s.push_str(":"); + } None => { } } if self.is_absolute { - s += "\\"; + s.push_str("\\"); } s + self.components.connect("\\") } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index c7f33587f315..ab7d3fda5013 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -263,8 +263,11 @@ fn highlight_lines(cm: @codemap::CodeMap, let s = fmt!("%s:%u ", fm.name, last_line + 1u); let mut indent = s.len(); let mut out = ~""; - while indent > 0u { out += " "; indent -= 1u; } - out += "...\n"; + while indent > 0u { + out.push_char(' '); + indent -= 1u; + } + out.push_str("...\n"); io::stderr().write_str(out); } @@ -285,23 +288,29 @@ fn highlight_lines(cm: @codemap::CodeMap, // part of the 'filename:line ' part of the previous line. let skip = fm.name.len() + digits + 3u; for skip.times() { - s += " "; + s.push_char(' '); } let orig = fm.get_line(lines.lines[0] as int); for uint::range(0u,left-skip) |pos| { let curChar = (orig[pos] as char); - s += match curChar { // Whenever a tab occurs on the previous - '\t' => "\t", // line, we insert one on the error-point- - _ => " " // -squiggly-line as well (instead of a - }; // space). This way the squiggly-line will - } // usually appear in the correct position. + // Whenever a tab occurs on the previous line, we insert one on + // the error-point-squiggly-line as well (instead of a space). + // That way the squiggly line will usually appear in the correct + // position. + match curChar { + '\t' => s.push_char('\t'), + _ => s.push_char(' '), + }; + } io::stderr().write_str(s); let mut s = ~"^"; let hi = cm.lookup_char_pos(sp.hi); if hi.col != lo.col { // the ^ already takes up one space let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u; - for num_squigglies.times() { s += "~"; } + for num_squigglies.times() { + s.push_char('~') + } } print_maybe_colored(s + "\n", diagnosticcolor(lvl)); } diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 80ab54b7e2cf..7df8874076e0 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -26,8 +26,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) } } else { match *e { - ast::tt_tok(_, token::IDENT(ident,_)) => - res_str += cx.str_of(ident), + ast::tt_tok(_, token::IDENT(ident,_)) => res_str.push_str(cx.str_of(ident)), _ => cx.span_fatal(sp, "concat_idents! requires ident args.") } } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 2c5ec0909d95..8e1276d52d1d 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -65,8 +65,8 @@ impl gen_send for message { args_ast); let mut body = ~"{\n"; - body += fmt!("use super::%s;\n", name); - body += "let mut pipe = pipe;\n"; + body.push_str(fmt!("use super::%s;\n", name)); + body.push_str("let mut pipe = pipe;\n"); if this.proto.is_bounded() { let (sp, rp) = match (this.dir, next.dir) { @@ -76,13 +76,15 @@ impl gen_send for message { (recv, recv) => (~"c", ~"s") }; - body += "let mut b = pipe.reuse_buffer();\n"; - body += fmt!("let %s = ::std::pipes::SendPacketBuffered(\ - &mut (b.buffer.data.%s));\n", - sp, next.name); - body += fmt!("let %s = ::std::pipes::RecvPacketBuffered(\ - &mut (b.buffer.data.%s));\n", - rp, next.name); + body.push_str("let mut b = pipe.reuse_buffer();\n"); + body.push_str(fmt!("let %s = ::std::pipes::SendPacketBuffered(\ + &mut (b.buffer.data.%s));\n", + sp, + next.name)); + body.push_str(fmt!("let %s = ::std::pipes::RecvPacketBuffered(\ + &mut (b.buffer.data.%s));\n", + rp, + next.name)); } else { let pat = match (this.dir, next.dir) { @@ -92,23 +94,22 @@ impl gen_send for message { (recv, recv) => "(s, c)" }; - body += fmt!("let %s = ::std::pipes::entangle();\n", pat); + body.push_str(fmt!("let %s = ::std::pipes::entangle();\n", pat)); } - body += fmt!("let message = %s(%s);\n", - name, - vec::append_one( - arg_names.map(|x| cx.str_of(*x)), - @"s").connect(", ")); + body.push_str(fmt!("let message = %s(%s);\n", + name, + vec::append_one(arg_names.map(|x| cx.str_of(*x)), ~"s") + .connect(", "))); if !try { - body += fmt!("::std::pipes::send(pipe, message);\n"); + body.push_str(fmt!("::std::pipes::send(pipe, message);\n")); // return the new channel - body += "c }"; + body.push_str("c }"); } else { - body += fmt!("if ::std::pipes::send(pipe, message) {\n \ + body.push_str(fmt!("if ::std::pipes::send(pipe, message) {\n \ ::std::pipes::rt::make_some(c) \ - } else { ::std::pipes::rt::make_none() } }"); + } else { ::std::pipes::rt::make_none() } }")); } let body = cx.parse_expr(body.to_managed()); @@ -155,19 +156,19 @@ impl gen_send for message { }; let mut body = ~"{ "; - body += fmt!("use super::%s;\n", name); - body += fmt!("let message = %s%s;\n", name, message_args); + body.push_str(fmt!("use super::%s;\n", name)); + body.push_str(fmt!("let message = %s%s;\n", name, message_args)); if !try { - body += fmt!("::std::pipes::send(pipe, message);\n"); - body += " }"; + body.push_str(fmt!("::std::pipes::send(pipe, message);\n")); + body.push_str(" }"); } else { - body += fmt!("if ::std::pipes::send(pipe, message) \ + body.push_str(fmt!("if ::std::pipes::send(pipe, message) \ { \ ::std::pipes::rt::make_some(()) \ } else { \ ::std::pipes::rt::make_none() \ - } }"); + } }")); } let body = cx.parse_expr(body.to_managed()); @@ -433,10 +434,10 @@ impl gen_init for protocol { let mut server_states = ~[]; for (copy self.states).iter().advance |s| { - items += s.to_type_decls(cx); + items.push_all_move(s.to_type_decls(cx)); - client_states += s.to_endpoint_decls(cx, send); - server_states += s.to_endpoint_decls(cx, recv); + client_states.push_all_move(s.to_endpoint_decls(cx, send)); + server_states.push_all_move(s.to_endpoint_decls(cx, recv)); } if self.is_bounded() { diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index ddcad5c3e8f6..d33b72ae3c90 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -42,7 +42,7 @@ impl parser_attr for Parser { if self.look_ahead(1u) != token::LBRACKET { break; } - attrs += [self.parse_attribute(ast::attr_outer)]; + attrs.push(self.parse_attribute(ast::attr_outer)); } token::DOC_COMMENT(s) => { let attr = ::attr::mk_sugared_doc_attr( @@ -53,7 +53,7 @@ impl parser_attr for Parser { if attr.node.style != ast::attr_outer { self.fatal("expected outer comment"); } - attrs += [attr]; + attrs.push(attr); self.bump(); } _ => break @@ -77,9 +77,7 @@ impl parser_attr for Parser { self.expect(&token::RBRACKET); let hi = self.span.hi; return spanned(lo, hi, ast::attribute_ { style: style, - value: meta_item, - is_sugared_doc: false }); - } + value: meta_item, is_sugared_doc: false }); } // Parse attributes that appear after the opening of an item, each // terminated by a semicolon. In addition to a vector of inner attributes, @@ -105,7 +103,7 @@ impl parser_attr for Parser { let attr = self.parse_attribute(ast::attr_inner); if *self.token == token::SEMI { self.bump(); - inner_attrs += [attr]; + inner_attrs.push(attr); } else { // It's not really an inner attribute let outer_attr = @@ -113,7 +111,7 @@ impl parser_attr for Parser { ast::attribute_ { style: ast::attr_outer, value: attr.node.value, is_sugared_doc: false }); - next_outer_attrs += [outer_attr]; + next_outer_attrs.push(outer_attr); break; } } @@ -125,9 +123,9 @@ impl parser_attr for Parser { ); self.bump(); if attr.node.style == ast::attr_inner { - inner_attrs += [attr]; + inner_attrs.push(attr); } else { - next_outer_attrs += [attr]; + next_outer_attrs.push(attr); break; } } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 2baf08b68f1c..01af33b13b85 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -254,7 +254,7 @@ fn read_block_comment(rdr: @mut StringReader, bump(rdr); } if !is_eof(rdr) { - curr_line += "*/"; + curr_line.push_str("*/"); bump(rdr); bump(rdr); } @@ -278,13 +278,13 @@ fn read_block_comment(rdr: @mut StringReader, if rdr.curr == '/' && nextch(rdr) == '*' { bump(rdr); bump(rdr); - curr_line += "*"; + curr_line.push_char('*'); level += 1; } else { if rdr.curr == '*' && nextch(rdr) == '/' { bump(rdr); bump(rdr); - curr_line += "/"; + curr_line.push_char('/'); level -= 1; } else { bump(rdr); } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index cde4c754d560..e003e2b27e9a 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -192,10 +192,10 @@ impl Parser { ); } else { let mut s: ~str = ~"expected `"; - s += self.token_to_str(&token::GT); - s += "`, found `"; - s += self.this_token_to_str(); - s += "`"; + s.push_str(self.token_to_str(&token::GT)); + s.push_str("`, found `"); + s.push_str(self.this_token_to_str()); + s.push_str("`"); self.fatal(s); } } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 2092f0fa5fac..4a8728329526 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -180,7 +180,7 @@ pub fn bump(rdr: &mut StringReader) { let byte_offset_diff = next.next - current_byte_offset; rdr.pos = rdr.pos + BytePos(byte_offset_diff); rdr.curr = next.ch; - rdr.col += CharPos(1u); + rdr.col = rdr.col + CharPos(1u); if last_char == '\n' { rdr.filemap.next_line(rdr.last_pos); rdr.col = CharPos(0u); @@ -448,8 +448,8 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { is_float = true; bump(rdr); let dec_part = scan_digits(rdr, 10u); - num_str += "."; - num_str += dec_part; + num_str.push_char('.'); + num_str.push_str(dec_part); } if is_float { match base { @@ -461,7 +461,7 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { match scan_exponent(rdr) { Some(ref s) => { is_float = true; - num_str += (*s); + num_str.push_str(*s); } None => () } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ee5ef8dfa6b9..a7c46d609cae 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4257,8 +4257,12 @@ impl Parser { // FAILURE TO PARSE ITEM if visibility != inherited { let mut s = ~"unmatched visibility `"; - s += if visibility == public { "pub" } else { "priv" }; - s += "`"; + if visibility == public { + s.push_str("pub") + } else { + s.push_str("priv") + } + s.push_char('`'); self.span_fatal(*self.last_span, s); } return iovi_none; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index df599596d7d0..18e6c1817991 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -178,14 +178,14 @@ pub fn to_str(in: @ident_interner, t: &Token) -> ~str { LIT_FLOAT(ref s, t) => { let mut body = ident_to_str(s).to_owned(); if body.ends_with(".") { - body += "0"; // `10.f` is not a float literal + body.push_char('0'); // `10.f` is not a float literal } body + ast_util::float_ty_to_str(t) } LIT_FLOAT_UNSUFFIXED(ref s) => { let mut body = ident_to_str(s).to_owned(); if body.ends_with(".") { - body += "0"; // `10.f` is not a float literal + body.push_char('0'); // `10.f` is not a float literal } body } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 4e03d9bac704..7cd3faf9a905 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -122,12 +122,14 @@ pub fn buf_str(toks: ~[token], szs: ~[int], left: uint, right: uint, let mut s = ~"["; while i != right && L != 0u { L -= 1u; - if i != left { s += ", "; } - s += fmt!("%d=%s", szs[i], tok_str(toks[i])); + if i != left { + s.push_str(", "); + } + s.push_str(fmt!("%d=%s", szs[i], tok_str(toks[i]))); i += 1u; i %= n; } - s += "]"; + s.push_char(']'); return s; } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 787cf696cc34..c4d89a698c1a 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -87,9 +87,8 @@ fn vec_plus() { while i < 1500 { let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i); if r.gen() { - v += rv; - } - else { + v.push_all_move(rv); + } else { v = rv + v; } i += 1; diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 96c7e4e9b375..49a3a3ec5d7d 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -50,8 +50,8 @@ fn show_color(cc: color) -> ~str { fn show_color_list(set: ~[color]) -> ~str { let mut out = ~""; for set.iter().advance |col| { - out += " "; - out += show_color(*col); + out.push_char(' '); + out.push_str(show_color(*col)); } return out; } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index f3efcc21ea9b..da8d65a1dcba 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -47,7 +47,7 @@ fn make_cumulative(aa: ~[AminoAcids]) -> ~[AminoAcids] { let mut ans: ~[AminoAcids] = ~[]; for aa.iter().advance |a| { cp += a.prob; - ans += [AminoAcids {ch: a.ch, prob: cp}]; + ans.push(AminoAcids {ch: a.ch, prob: cp}); } ans } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 57683fa3dbf0..d26fe80e8a12 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -70,7 +70,7 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { let b = str::raw::from_bytes(k); // FIXME: #4318 Instead of to_ascii and to_str_ascii, could use // to_ascii_consume and to_str_consume to not do a unnecessary copy. - buffer += (fmt!("%s %0.3f\n", b.to_ascii().to_upper().to_str_ascii(), v)); + buffer.push_str(fmt!("%s %0.3f\n", b.to_ascii().to_upper().to_str_ascii(), v)); } } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index f66de3853743..2396d6efc5cc 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -103,7 +103,9 @@ impl Sudoku { for u8::range(0u8, 9u8) |row| { for u8::range(0u8, 9u8) |col| { let color = self.grid[row][col]; - if color == 0u8 { work += [(row, col)]; } + if color == 0u8 { + work.push((row, col)); + } } } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index f7b9371df573..b5a5eed6a35a 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -15,7 +15,7 @@ trait vec_monad { impl vec_monad for ~[A] { fn bind(&self, f: &fn(A) -> ~[B]) { let mut r = fail!(); - for self.iter().advance |elt| { r += f(*elt); } + for self.iter().advance |elt| { r = r + f(*elt); } //~^ WARNING unreachable expression //~^^ ERROR the type of this value must be known } diff --git a/src/test/run-fail/issue-3029.rs b/src/test/run-fail/issue-3029.rs index 6f4a3f5ab1d2..caee00027883 100644 --- a/src/test/run-fail/issue-3029.rs +++ b/src/test/run-fail/issue-3029.rs @@ -10,9 +10,9 @@ // error-pattern:so long fn main() { - let x = ~[]; + let mut x = ~[]; let y = ~[3]; fail!("so long"); - x += y; + x.push_all_move(y); ~"good" + ~"bye"; } diff --git a/src/test/run-pass/istr.rs b/src/test/run-pass/istr.rs index a82b26394498..ab89a357d349 100644 --- a/src/test/run-pass/istr.rs +++ b/src/test/run-pass/istr.rs @@ -44,19 +44,19 @@ fn test_heap_add() { fn test_append() { let mut s = ~""; - s += ~"a"; + s.push_str(~"a"); assert_eq!(s, ~"a"); let mut s = ~"a"; - s += ~"b"; + s.push_str(~"b"); debug!(s.clone()); assert_eq!(s, ~"ab"); let mut s = ~"c"; - s += ~"offee"; + s.push_str(~"offee"); assert!(s == ~"coffee"); - s += ~"&tea"; + s.push_str(~"&tea"); assert!(s == ~"coffee&tea"); } diff --git a/src/test/run-pass/liveness-move-in-loop.rs b/src/test/run-pass/liveness-move-in-loop.rs index acdf388a8ff0..d910ac9a4e77 100644 --- a/src/test/run-pass/liveness-move-in-loop.rs +++ b/src/test/run-pass/liveness-move-in-loop.rs @@ -15,7 +15,7 @@ fn the_loop() { loop { let x = 5; if x > 3 { - list += ~[take(x)]; + list.push(take(x)); } else { break; } diff --git a/src/test/run-pass/match-join.rs b/src/test/run-pass/match-join.rs index 66b647680609..5ac62bae3922 100644 --- a/src/test/run-pass/match-join.rs +++ b/src/test/run-pass/match-join.rs @@ -23,7 +23,7 @@ fn foo(y: Option) { None:: => x = 17, _ => x = 42 } - rs += ~[x]; + rs.push(x); } return; } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 3f3cf5e5aaa0..fe06c973dbfd 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -19,7 +19,9 @@ trait vec_monad { impl vec_monad for ~[A] { fn bind(&self, f: &fn(&A) -> ~[B]) -> ~[B] { let mut r = ~[]; - for self.iter().advance |elt| { r += f(elt); } + for self.iter().advance |elt| { + r.push_all_move(f(elt)); + } r } } diff --git a/src/test/run-pass/mutable-alias-vec.rs b/src/test/run-pass/mutable-alias-vec.rs index 1d9e7d3c6496..538aedcf7c88 100644 --- a/src/test/run-pass/mutable-alias-vec.rs +++ b/src/test/run-pass/mutable-alias-vec.rs @@ -13,7 +13,9 @@ extern mod extra; use std::vec; -fn grow(v: &mut ~[int]) { *v += ~[1]; } +fn grow(v: &mut ~[int]) { + v.push(1); +} pub fn main() { let mut v: ~[int] = ~[]; diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index e75af5729d5c..05aa1e746083 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -57,7 +57,7 @@ impl cmp::Eq for Point { pub fn main() { let mut p = Point {x: 10, y: 20}; - p += Point {x: 101, y: 102}; + p = p + Point {x: 101, y: 102}; p = p - Point {x: 100, y: 100}; assert_eq!(p + Point {x: 5, y: 5}, Point {x: 16, y: 27}); assert_eq!(-p, Point {x: -11, y: -22}); diff --git a/src/test/run-pass/shadow.rs b/src/test/run-pass/shadow.rs index 85575b2ea8bb..d0c58b50e2ce 100644 --- a/src/test/run-pass/shadow.rs +++ b/src/test/run-pass/shadow.rs @@ -19,7 +19,7 @@ fn foo(c: ~[int]) { for c.iter().advance |i| { debug!(a); let a = 17; - b += ~[a]; + b.push(a); } } _ => { } diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 421cd1d4d0bb..0ddc39d6b18c 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -51,7 +51,9 @@ impl vec_utils for ~[T] { fn iter_(&self, f: &fn(&T)) { for self.iter().advance |x| { f(x); } } fn map_(&self, f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for self.iter().advance |elt| { r += ~[f(elt)]; } + for self.iter().advance |elt| { + r.push(f(elt)); + } r } } diff --git a/src/test/run-pass/str-append.rs b/src/test/run-pass/str-append.rs index 4fdf7dde031a..556247eb4260 100644 --- a/src/test/run-pass/str-append.rs +++ b/src/test/run-pass/str-append.rs @@ -15,7 +15,7 @@ extern mod extra; fn test1() { let mut s: ~str = ~"hello"; - s += ~"world"; + s.push_str("world"); debug!(s.clone()); assert_eq!(s[9], 'd' as u8); } diff --git a/src/test/run-pass/str-growth.rs b/src/test/run-pass/str-growth.rs index 6938b52eee83..0cdf1841331a 100644 --- a/src/test/run-pass/str-growth.rs +++ b/src/test/run-pass/str-growth.rs @@ -12,11 +12,11 @@ pub fn main() { let mut s = ~"a"; - s += ~"b"; + s.push_char('b'); assert_eq!(s[0], 'a' as u8); assert_eq!(s[1], 'b' as u8); - s += ~"c"; - s += ~"d"; + s.push_char('c'); + s.push_char('d'); assert_eq!(s[0], 'a' as u8); assert_eq!(s[1], 'b' as u8); assert_eq!(s[2], 'c' as u8); diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index dc6bdbf5c1a5..5952afa6676b 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -33,7 +33,7 @@ impl map for ~[T] { let mut r = ~[]; // FIXME: #7355 generates bad code with Iterator for std::uint::range(0, self.len()) |i| { - r += ~[f(&self[i])]; + r.push(f(&self[i])); } r } diff --git a/src/test/run-pass/vec-growth.rs b/src/test/run-pass/vec-growth.rs index 816228b62c67..c9a4c57cc9d3 100644 --- a/src/test/run-pass/vec-growth.rs +++ b/src/test/run-pass/vec-growth.rs @@ -12,10 +12,10 @@ pub fn main() { let mut v = ~[1]; - v += ~[2]; - v += ~[3]; - v += ~[4]; - v += ~[5]; + v.push(2); + v.push(3); + v.push(4); + v.push(5); assert_eq!(v[0], 1); assert_eq!(v[1], 2); assert_eq!(v[2], 3); diff --git a/src/test/run-pass/while-prelude-drop.rs b/src/test/run-pass/while-prelude-drop.rs index 082f2db259a4..503e37fcd76e 100644 --- a/src/test/run-pass/while-prelude-drop.rs +++ b/src/test/run-pass/while-prelude-drop.rs @@ -17,7 +17,7 @@ fn make(i: int) -> t { let mut s = ~"hello"; // Ensure s is non-const. - s += ~"there"; + s.push_str("there"); return b(s); } From 03ab6351ccc7b0e2b6102f88eddc0bbe84f2abc0 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 14 Jun 2013 18:21:47 -0700 Subject: [PATCH 242/336] librustc: Rewrite reachability and forbid duplicate methods in type implementations. This should allow fewer symbols to be exported. --- src/libextra/ebml.rs | 30 +- src/libextra/sync.rs | 8 +- src/libextra/test.rs | 282 ++++++------- src/librustc/driver/driver.rs | 18 +- src/librustc/metadata/encoder.rs | 75 ++-- src/librustc/metadata/tyencode.rs | 1 - src/librustc/middle/astencode.rs | 31 +- src/librustc/middle/reachable.rs | 414 ++++++++++++++++++++ src/librustc/middle/resolve.rs | 249 +++++------- src/librustc/middle/trans/base.rs | 14 +- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/common.rs | 79 +++- src/librustc/middle/trans/mod.rs | 1 - src/librustc/middle/trans/reachable.rs | 246 ------------ src/librustc/middle/typeck/check/mod.rs | 7 +- src/librustc/middle/typeck/collect.rs | 16 +- src/librustc/middle/typeck/infer/combine.rs | 3 +- src/librustc/middle/typeck/infer/lattice.rs | 116 ++++-- src/librustc/middle/typeck/infer/resolve.rs | 2 +- src/librustc/middle/typeck/infer/sub.rs | 1 + src/librustc/middle/typeck/infer/unify.rs | 95 +++-- src/librustc/rustc.rs | 1 + src/librustpkg/rustpkg.rs | 15 +- src/libstd/path.rs | 56 ++- src/libstd/str.rs | 3 +- src/libsyntax/ast.rs | 5 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/parse/common.rs | 248 ------------ src/libsyntax/parse/obsolete.rs | 21 +- src/libsyntax/parse/parser.rs | 251 +++++++++++- 30 files changed, 1331 insertions(+), 961 deletions(-) create mode 100644 src/librustc/middle/reachable.rs delete mode 100644 src/librustc/middle/trans/reachable.rs diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index dd3ba639c054..fad04b772eb7 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -12,6 +12,8 @@ use core::prelude::*; +use core::str; + // Simple Extensible Binary Markup Language (ebml) reader and writer on a // cursor model. See the specification here: // http://www.matroska.org/technical/specs/rfc/index.html @@ -34,6 +36,20 @@ pub struct Doc { end: uint, } +impl Doc { + pub fn get(&self, tag: uint) -> Doc { + reader::get_doc(*self, tag) + } + + pub fn as_str_slice<'a>(&'a self) -> &'a str { + str::from_bytes_slice(self.data.slice(self.start, self.end)) + } + + pub fn as_str(&self) -> ~str { + self.as_str_slice().to_owned() + } +} + pub struct TaggedDoc { tag: uint, doc: Doc, @@ -94,20 +110,6 @@ pub mod reader { // ebml reading - impl Doc { - pub fn get(&self, tag: uint) -> Doc { - get_doc(*self, tag) - } - - pub fn as_str_slice<'a>(&'a self) -> &'a str { - str::from_bytes_slice(self.data.slice(self.start, self.end)) - } - - pub fn as_str(&self) -> ~str { - self.as_str_slice().to_owned() - } - } - struct Res { val: uint, next: uint diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 61b6a233944c..56168f923ad7 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -153,7 +153,7 @@ impl Sem<()> { #[doc(hidden)] impl Sem<~[Waitqueue]> { - pub fn access(&self, blk: &fn() -> U) -> U { + pub fn access_waitqueue(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -456,7 +456,9 @@ impl Clone for Mutex { impl Mutex { /// Run a function with ownership of the mutex. - pub fn lock(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) } + pub fn lock(&self, blk: &fn() -> U) -> U { + (&self.sem).access_waitqueue(blk) + } /// Run a function with ownership of the mutex and a handle to a condvar. pub fn lock_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { @@ -559,7 +561,7 @@ impl RWlock { unsafe { do task::unkillable { (&self.order_lock).acquire(); - do (&self.access_lock).access { + do (&self.access_lock).access_waitqueue { (&self.order_lock).release(); task::rekillable(blk) } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 7b68298a8ddd..672c4cd648cf 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -19,15 +19,21 @@ use core::prelude::*; use getopts; use sort; +use stats::Stats; use term; +use time::precise_time_ns; use core::comm::{stream, SharedChan}; use core::either; use core::io; +use core::num; use core::option; +use core::rand::RngUtil; +use core::rand; use core::result; use core::task; use core::to_str::ToStr; +use core::u64; use core::uint; use core::vec; @@ -609,152 +615,146 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult { } } +impl BenchHarness { + /// Callback for benchmark functions to run in their body. + pub fn iter(&mut self, inner:&fn()) { + self.ns_start = precise_time_ns(); + let k = self.iterations; + for u64::range(0, k) |_| { + inner(); + } + self.ns_end = precise_time_ns(); + } + + pub fn ns_elapsed(&mut self) -> u64 { + if self.ns_start == 0 || self.ns_end == 0 { + 0 + } else { + self.ns_end - self.ns_start + } + } + + pub fn ns_per_iter(&mut self) -> u64 { + if self.iterations == 0 { + 0 + } else { + self.ns_elapsed() / self.iterations + } + } + + pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) { + self.iterations = n; + debug!("running benchmark for %u iterations", + n as uint); + f(self); + } + + // This is the Go benchmark algorithm. It produces a single + // datapoint and always tries to run for 1s. + pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) { + + // Rounds a number down to the nearest power of 10. + fn round_down_10(n: u64) -> u64 { + let mut n = n; + let mut res = 1; + while n > 10 { + n = n / 10; + res *= 10; + } + res + } + + // Rounds x up to a number of the form [1eX, 2eX, 5eX]. + fn round_up(n: u64) -> u64 { + let base = round_down_10(n); + if n < (2 * base) { + 2 * base + } else if n < (5 * base) { + 5 * base + } else { + 10 * base + } + } + + // Initial bench run to get ballpark figure. + let mut n = 1_u64; + self.bench_n(n, f); + + while n < 1_000_000_000 && + self.ns_elapsed() < 1_000_000_000 { + let last = n; + + // Try to estimate iter count for 1s falling back to 1bn + // iterations if first run took < 1ns. + if self.ns_per_iter() == 0 { + n = 1_000_000_000; + } else { + n = 1_000_000_000 / self.ns_per_iter(); + } + + n = u64::max(u64::min(n+n/2, 100*last), last+1); + n = round_up(n); + self.bench_n(n, f); + } + } + + // This is a more statistics-driven benchmark algorithm. + // It stops as quickly as 50ms, so long as the statistical + // properties are satisfactory. If those properties are + // not met, it may run as long as the Go algorithm. + pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] { + + let mut rng = rand::rng(); + let mut magnitude = 10; + let mut prev_madp = 0.0; + + loop { + let n_samples = rng.gen_uint_range(50, 60); + let n_iter = rng.gen_uint_range(magnitude, + magnitude * 2); + + let samples = do vec::from_fn(n_samples) |_| { + self.bench_n(n_iter as u64, f); + self.ns_per_iter() as f64 + }; + + // Eliminate outliers + let med = samples.median(); + let mad = samples.median_abs_dev(); + let samples = do vec::filter(samples) |f| { + num::abs(*f - med) <= 3.0 * mad + }; + + debug!("%u samples, median %f, MAD=%f, %u survived filter", + n_samples, med as float, mad as float, + samples.len()); + + if samples.len() != 0 { + // If we have _any_ cluster of signal... + let curr_madp = samples.median_abs_dev_pct(); + if self.ns_elapsed() > 1_000_000 && + (curr_madp < 1.0 || + num::abs(curr_madp - prev_madp) < 0.1) { + return samples; + } + prev_madp = curr_madp; + + if n_iter > 20_000_000 || + self.ns_elapsed() > 20_000_000 { + return samples; + } + } + + magnitude *= 2; + } + } +} + pub mod bench { use core::prelude::*; - use core::num; - use core::rand::RngUtil; - use core::rand; - use core::u64; use core::vec; - use stats::Stats; use test::{BenchHarness, BenchSamples}; - use time::precise_time_ns; - - impl BenchHarness { - /// Callback for benchmark functions to run in their body. - pub fn iter(&mut self, inner:&fn()) { - self.ns_start = precise_time_ns(); - let k = self.iterations; - for u64::range(0, k) |_| { - inner(); - } - self.ns_end = precise_time_ns(); - } - - pub fn ns_elapsed(&mut self) -> u64 { - if self.ns_start == 0 || self.ns_end == 0 { - 0 - } else { - self.ns_end - self.ns_start - } - } - - pub fn ns_per_iter(&mut self) -> u64 { - if self.iterations == 0 { - 0 - } else { - self.ns_elapsed() / self.iterations - } - } - - pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) { - self.iterations = n; - debug!("running benchmark for %u iterations", - n as uint); - f(self); - } - - // This is the Go benchmark algorithm. It produces a single - // datapoint and always tries to run for 1s. - pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) { - - // Rounds a number down to the nearest power of 10. - fn round_down_10(n: u64) -> u64 { - let mut n = n; - let mut res = 1; - while n > 10 { - n = n / 10; - res *= 10; - } - res - } - - // Rounds x up to a number of the form [1eX, 2eX, 5eX]. - fn round_up(n: u64) -> u64 { - let base = round_down_10(n); - if n < (2 * base) { - 2 * base - } else if n < (5 * base) { - 5 * base - } else { - 10 * base - } - } - - // Initial bench run to get ballpark figure. - let mut n = 1_u64; - self.bench_n(n, f); - - while n < 1_000_000_000 && - self.ns_elapsed() < 1_000_000_000 { - let last = n; - - // Try to estimate iter count for 1s falling back to 1bn - // iterations if first run took < 1ns. - if self.ns_per_iter() == 0 { - n = 1_000_000_000; - } else { - n = 1_000_000_000 / self.ns_per_iter(); - } - - n = u64::max(u64::min(n+n/2, 100*last), last+1); - n = round_up(n); - self.bench_n(n, f); - } - } - - // This is a more statistics-driven benchmark algorithm. - // It stops as quickly as 50ms, so long as the statistical - // properties are satisfactory. If those properties are - // not met, it may run as long as the Go algorithm. - pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] { - - let mut rng = rand::rng(); - let mut magnitude = 10; - let mut prev_madp = 0.0; - - loop { - let n_samples = rng.gen_uint_range(50, 60); - let n_iter = rng.gen_uint_range(magnitude, - magnitude * 2); - - let samples = do vec::from_fn(n_samples) |_| { - self.bench_n(n_iter as u64, f); - self.ns_per_iter() as f64 - }; - - // Eliminate outliers - let med = samples.median(); - let mad = samples.median_abs_dev(); - let samples = do vec::filter(samples) |f| { - num::abs(*f - med) <= 3.0 * mad - }; - - debug!("%u samples, median %f, MAD=%f, %u survived filter", - n_samples, med as float, mad as float, - samples.len()); - - if samples.len() != 0 { - // If we have _any_ cluster of signal... - let curr_madp = samples.median_abs_dev_pct(); - if self.ns_elapsed() > 1_000_000 && - (curr_madp < 1.0 || - num::abs(curr_madp - prev_madp) < 0.1) { - return samples; - } - prev_madp = curr_madp; - - if n_iter > 20_000_000 || - self.ns_elapsed() > 20_000_000 { - return samples; - } - } - - magnitude *= 2; - } - } - } pub fn benchmark(f: &fn(&mut BenchHarness)) -> BenchSamples { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 2229a85836aa..18693b52fc87 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -19,7 +19,7 @@ use front; use lib::llvm::llvm; use metadata::{creader, cstore, filesearch}; use metadata; -use middle::{trans, freevars, kind, ty, typeck, lint, astencode}; +use middle::{trans, freevars, kind, ty, typeck, lint, astencode, reachable}; use middle; use util::common::time; use util::ppaux; @@ -299,10 +299,16 @@ pub fn compile_rest(sess: Session, time(time_passes, ~"kind checking", || kind::check_crate(ty_cx, method_map, crate)); + let reachable_map = + time(time_passes, ~"reachability checking", || + reachable::find_reachable(ty_cx, method_map, crate)); + time(time_passes, ~"lint checking", || lint::check_crate(ty_cx, crate)); - if phases.to == cu_no_trans { return (Some(crate), Some(ty_cx)); } + if phases.to == cu_no_trans { + return (Some(crate), Some(ty_cx)); + } let maps = astencode::Maps { root_map: root_map, @@ -315,9 +321,13 @@ pub fn compile_rest(sess: Session, let outputs = outputs.get_ref(); time(time_passes, ~"translation", || - trans::base::trans_crate(sess, crate, ty_cx, + trans::base::trans_crate(sess, + crate, + ty_cx, &outputs.obj_filename, - exp_map2, maps)) + exp_map2, + reachable_map, + maps)) }; let outputs = outputs.get_ref(); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index f8ecef3b4a49..b1967752e45c 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -16,7 +16,6 @@ use metadata::common::*; use metadata::cstore; use metadata::decoder; use metadata::tyencode; -use middle::trans::reachable; use middle::ty::node_id_to_type; use middle::ty; use middle; @@ -60,7 +59,6 @@ pub type encode_inlined_item<'self> = &'self fn(ecx: &EncodeContext, pub struct EncodeParams<'self> { diag: @span_handler, tcx: ty::ctxt, - reachable: reachable::map, reexports2: middle::resolve::ExportMap2, item_symbols: &'self HashMap, discrim_symbols: &'self HashMap, @@ -87,7 +85,6 @@ pub struct EncodeContext<'self> { diag: @span_handler, tcx: ty::ctxt, stats: @mut Stats, - reachable: reachable::map, reexports2: middle::resolve::ExportMap2, item_symbols: &'self HashMap, discrim_symbols: &'self HashMap, @@ -157,8 +154,8 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; ebml_w.start_tag(tag); tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref); @@ -185,8 +182,8 @@ fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; for params.iter().advance |param| { ebml_w.start_tag(tag); tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param); @@ -218,8 +215,8 @@ pub fn write_type(ecx: &EncodeContext, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ); } @@ -231,8 +228,8 @@ pub fn write_vstore(ecx: &EncodeContext, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore); } @@ -264,8 +261,8 @@ fn encode_method_fty(ecx: &EncodeContext, diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ); ebml_w.end_tag(); @@ -780,13 +777,6 @@ fn encode_info_for_item(ecx: &EncodeContext, index: @mut ~[entry], path: &[ast_map::path_elt]) { let tcx = ecx.tcx; - let must_write = - match item.node { - item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) | - item_mod(*) | item_foreign_mod(*) | item_static(*) => true, - _ => false - }; - if !must_write && !reachable(ecx, item.id) { return; } fn add_to_index_(item: @item, ebml_w: &writer::Encoder, index: @mut ~[entry]) { @@ -898,23 +888,6 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); - // If this is a tuple- or enum-like struct, encode the type of the - // constructor. - if struct_def.fields.len() > 0 && - struct_def.fields[0].node.kind == ast::unnamed_field { - let ctor_id = match struct_def.ctor_id { - Some(ctor_id) => ctor_id, - None => ecx.tcx.sess.bug("struct def didn't have ctor id"), - }; - - encode_info_for_struct_ctor(ecx, - ebml_w, - path, - item.ident, - ctor_id, - index); - } - encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); @@ -944,6 +917,23 @@ fn encode_info_for_item(ecx: &EncodeContext, let bkts = create_index(idx); encode_index(ebml_w, bkts, write_int); ebml_w.end_tag(); + + // If this is a tuple- or enum-like struct, encode the type of the + // constructor. + if struct_def.fields.len() > 0 && + struct_def.fields[0].node.kind == ast::unnamed_field { + let ctor_id = match struct_def.ctor_id { + Some(ctor_id) => ctor_id, + None => ecx.tcx.sess.bug("struct def didn't have ctor id"), + }; + + encode_info_for_struct_ctor(ecx, + ebml_w, + path, + item.ident, + ctor_id, + index); + } } item_impl(ref generics, opt_trait, ty, ref methods) => { add_to_index(); @@ -1092,7 +1082,6 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, index: @mut ~[entry], path: ast_map::path, abi: AbiSet) { - if !reachable(ecx, nitem.id) { return; } index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() }); ebml_w.start_tag(tag_items_data_item); @@ -1162,6 +1151,12 @@ fn encode_info_for_items(ecx: &EncodeContext, visit::visit_foreign_item(ni, (cx, v)); match items.get_copy(&ni.id) { ast_map::node_foreign_item(_, abi, _, pt) => { + debug!("writing foreign item %s::%s", + ast_map::path_to_str( + *pt, + token::get_ident_interner()), + *token::ident_to_str(&ni.ident)); + let mut ebml_w = copy ebml_w; // See above let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) }; @@ -1466,7 +1461,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { total_bytes: 0, n_inlines: 0 }; - let EncodeParams{item_symbols, diag, tcx, reachable, reexports2, + let EncodeParams{item_symbols, diag, tcx, reexports2, discrim_symbols, cstore, encode_inlined_item, link_meta, _} = parms; let type_abbrevs = @mut HashMap::new(); @@ -1475,7 +1470,6 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { diag: diag, tcx: tcx, stats: stats, - reachable: reachable, reexports2: reexports2, item_symbols: item_symbols, discrim_symbols: discrim_symbols, @@ -1557,7 +1551,6 @@ pub fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str { diag: tcx.diag, ds: def_to_str, tcx: tcx, - reachable: |_id| false, abbrevs: tyencode::ac_no_abbrevs}; do io::with_str_writer |wr| { tyencode::enc_ty(wr, cx, t); diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 0f9937fd3c0c..fb72617b743f 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -31,7 +31,6 @@ pub struct ctxt { ds: @fn(def_id) -> ~str, // The type context. tcx: ty::ctxt, - reachable: @fn(node_id) -> bool, abbrevs: abbrev_ctxt } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index fb8238b84d6e..70e94844319e 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -368,14 +368,17 @@ impl tr for ast::def { ast::def_static_method(did.tr(xcx), did2_opt.map(|did2| did2.tr(xcx)), p) - }, - ast::def_self_ty(nid) => ast::def_self_ty(xcx.tr_id(nid)), - ast::def_self(nid, i) => ast::def_self(xcx.tr_id(nid), i), - ast::def_mod(did) => ast::def_mod(did.tr(xcx)), - ast::def_foreign_mod(did) => ast::def_foreign_mod(did.tr(xcx)), - ast::def_static(did, m) => ast::def_static(did.tr(xcx), m), - ast::def_arg(nid, b) => ast::def_arg(xcx.tr_id(nid), b), - ast::def_local(nid, b) => ast::def_local(xcx.tr_id(nid), b), + } + ast::def_method(did0, did1) => { + ast::def_method(did0.tr(xcx), did1.map(|did1| did1.tr(xcx))) + } + ast::def_self_ty(nid) => { ast::def_self_ty(xcx.tr_id(nid)) } + ast::def_self(nid, i) => { ast::def_self(xcx.tr_id(nid), i) } + ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) } + ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) } + ast::def_static(did, m) => { ast::def_static(did.tr(xcx), m) } + ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) } + ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) } ast::def_variant(e_did, v_did) => { ast::def_variant(e_did.tr(xcx), v_did.tr(xcx)) }, @@ -692,12 +695,12 @@ trait get_ty_str_ctxt { impl<'self> get_ty_str_ctxt for e::EncodeContext<'self> { fn ty_str_ctxt(&self) -> @tyencode::ctxt { - let r = self.reachable; - @tyencode::ctxt {diag: self.tcx.sess.diagnostic(), - ds: e::def_to_str, - tcx: self.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)} + @tyencode::ctxt { + diag: self.tcx.sess.diagnostic(), + ds: e::def_to_str, + tcx: self.tcx, + abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs) + } } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs new file mode 100644 index 000000000000..1361f2c245af --- /dev/null +++ b/src/librustc/middle/reachable.rs @@ -0,0 +1,414 @@ +// 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. + +// Finds items that are externally reachable, to determine which items +// need to have their metadata (and possibly their AST) serialized. +// All items that can be referred to through an exported name are +// reachable, and when a reachable thing is inline or generic, it +// makes all other generics or inline functions that it references +// reachable as well. + +use core::prelude::*; +use core::iterator::IteratorUtil; + +use middle::resolve; +use middle::ty; +use middle::typeck; + +use core::hashmap::HashSet; +use syntax::ast::*; +use syntax::ast; +use syntax::ast_map; +use syntax::ast_util::def_id_of_def; +use syntax::attr; +use syntax::codemap; +use syntax::parse::token; +use syntax::visit::Visitor; +use syntax::visit; + +// Returns true if the given set of attributes contains the `#[inline]` +// attribute. +fn attributes_specify_inlining(attrs: &[attribute]) -> bool { + attr::attrs_contains_name(attrs, "inline") +} + +// Returns true if the given set of generics implies that the item it's +// associated with must be inlined. +fn generics_require_inlining(generics: &Generics) -> bool { + !generics.ty_params.is_empty() +} + +// Returns true if the given item must be inlined because it may be +// monomorphized or it was marked with `#[inline]`. This will only return +// true for functions. +fn item_might_be_inlined(item: @item) -> bool { + if attributes_specify_inlining(item.attrs) { + return true + } + + match item.node { + item_fn(_, _, _, ref generics, _) => { + generics_require_inlining(generics) + } + _ => false, + } +} + +// Returns true if the given type method must be inlined because it may be +// monomorphized or it was marked with `#[inline]`. +fn ty_method_might_be_inlined(ty_method: &ty_method) -> bool { + attributes_specify_inlining(ty_method.attrs) || + generics_require_inlining(&ty_method.generics) +} + +// Returns true if the given trait method must be inlined because it may be +// monomorphized or it was marked with `#[inline]`. +fn trait_method_might_be_inlined(trait_method: &trait_method) -> bool { + match *trait_method { + required(ref ty_method) => ty_method_might_be_inlined(ty_method), + provided(_) => true + } +} + +// Information needed while computing reachability. +struct ReachableContext { + // The type context. + tcx: ty::ctxt, + // The method map, which links node IDs of method call expressions to the + // methods they've been resolved to. + method_map: typeck::method_map, + // The set of items which must be exported in the linkage sense. + reachable_symbols: @mut HashSet, + // A worklist of item IDs. Each item ID in this worklist will be inlined + // and will be scanned for further references. + worklist: @mut ~[node_id], +} + +impl ReachableContext { + // Creates a new reachability computation context. + fn new(tcx: ty::ctxt, method_map: typeck::method_map) + -> ReachableContext { + ReachableContext { + tcx: tcx, + method_map: method_map, + reachable_symbols: @mut HashSet::new(), + worklist: @mut ~[], + } + } + + // Step 1: Mark all public symbols, and add all public symbols that might + // be inlined to a worklist. + fn mark_public_symbols(&self, crate: @crate) { + let reachable_symbols = self.reachable_symbols; + let worklist = self.worklist; + let visitor = visit::mk_vt(@Visitor { + visit_item: |item, _, visitor| { + match item.node { + item_fn(*) => { + reachable_symbols.insert(item.id); + if item_might_be_inlined(item) { + worklist.push(item.id) + } + } + item_struct(ref struct_def, _) => { + match struct_def.ctor_id { + None => {} + Some(ctor_id) => { + reachable_symbols.insert(ctor_id); + } + } + } + item_enum(ref enum_def, _) => { + for enum_def.variants.each |variant| { + reachable_symbols.insert(variant.node.id); + } + } + item_impl(ref generics, 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 + // treating implementations of reachable or cross- + // crate traits as reachable. + + // Mark all public methods as reachable. + for methods.each |method| { + if method.vis == public || trait_ref.is_some() { + reachable_symbols.insert(method.id); + } + } + + if generics_require_inlining(generics) { + // If the impl itself has generics, add all public + // symbols to the worklist. + for methods.each |method| { + if method.vis == public || + trait_ref.is_some() { + worklist.push(method.id) + } + } + } else { + // Otherwise, add only public methods that have + // generics to the worklist. + for methods.each |method| { + let generics = &method.generics; + let attrs = &method.attrs; + if generics_require_inlining(generics) || + attributes_specify_inlining(*attrs) || + method.vis == public || + trait_ref.is_some() { + worklist.push(method.id) + } + } + } + } + item_trait(_, _, ref trait_methods) => { + // Mark all provided methods as reachable. + for trait_methods.each |trait_method| { + match *trait_method { + provided(method) => { + reachable_symbols.insert(method.id); + worklist.push(method.id) + } + required(_) => {} + } + } + } + _ => {} + } + + if item.vis == public { + visit::visit_item(item, (), visitor) + } + }, + .. *visit::default_visitor() + }); + + visit::visit_crate(crate, (), visitor) + } + + // Returns true if the given def ID represents a local item that is + // eligible for inlining and false otherwise. + fn def_id_represents_local_inlined_item(tcx: ty::ctxt, def_id: def_id) + -> bool { + if def_id.crate != local_crate { + return false + } + + let node_id = def_id.node; + match tcx.items.find(&node_id) { + Some(&ast_map::node_item(item, _)) => { + match item.node { + item_fn(*) => item_might_be_inlined(item), + _ => false, + } + } + Some(&ast_map::node_trait_method(trait_method, _, _)) => { + match *trait_method { + required(_) => false, + provided(_) => true, + } + } + Some(&ast_map::node_method(method, impl_did, _)) => { + if generics_require_inlining(&method.generics) || + attributes_specify_inlining(method.attrs) { + true + } else { + // Check the impl. If the generics on the self type of the + // impl require inlining, this method does too. + assert!(impl_did.crate == local_crate); + match tcx.items.find(&impl_did.node) { + Some(&ast_map::node_item(item, _)) => { + match item.node { + item_impl(ref generics, _, _, _) => { + generics_require_inlining(generics) + } + _ => false + } + } + Some(_) => { + tcx.sess.span_bug(method.span, + "method is not inside an \ + impl?!") + } + None => { + tcx.sess.span_bug(method.span, + "the impl that this method is \ + supposedly inside of doesn't \ + exist in the AST map?!") + } + } + } + } + Some(_) => false, + None => tcx.sess.bug("def ID not in def map?!"), + } + } + + // Helper function to set up a visitor for `propagate()` below. + fn init_visitor(&self) -> visit::vt<()> { + let (worklist, method_map) = (self.worklist, self.method_map); + let (tcx, reachable_symbols) = (self.tcx, self.reachable_symbols); + visit::mk_vt(@visit::Visitor { + visit_expr: |expr, _, visitor| { + match expr.node { + expr_path(_) => { + let def = match tcx.def_map.find(&expr.id) { + Some(&def) => def, + None => { + tcx.sess.span_bug(expr.span, + "def ID not in def map?!") + } + }; + + let def_id = def_id_of_def(def); + if ReachableContext:: + def_id_represents_local_inlined_item(tcx, + def_id) { + worklist.push(def_id.node) + } + reachable_symbols.insert(def_id.node); + } + expr_method_call(*) => { + match method_map.find(&expr.id) { + Some(&typeck::method_map_entry { + origin: typeck::method_static(def_id), + _ + }) => { + if ReachableContext:: + def_id_represents_local_inlined_item( + tcx, + def_id) { + worklist.push(def_id.node) + } + reachable_symbols.insert(def_id.node); + } + Some(_) => {} + None => { + tcx.sess.span_bug(expr.span, + "method call expression \ + not in method map?!") + } + } + } + _ => {} + } + + visit::visit_expr(expr, (), visitor) + }, + ..*visit::default_visitor() + }) + } + + // Step 2: Mark all symbols that the symbols on the worklist touch. + fn propagate(&self) { + let visitor = self.init_visitor(); + let mut scanned = HashSet::new(); + while self.worklist.len() > 0 { + let search_item = self.worklist.pop(); + if scanned.contains(&search_item) { + loop + } + scanned.insert(search_item); + self.reachable_symbols.insert(search_item); + + // Find the AST block corresponding to the item and visit it, + // marking all path expressions that resolve to something + // interesting. + match self.tcx.items.find(&search_item) { + Some(&ast_map::node_item(item, _)) => { + match item.node { + item_fn(_, _, _, _, ref search_block) => { + visit::visit_block(search_block, (), visitor) + } + _ => { + self.tcx.sess.span_bug(item.span, + "found non-function item \ + in worklist?!") + } + } + } + Some(&ast_map::node_trait_method(trait_method, _, _)) => { + match *trait_method { + required(ref ty_method) => { + self.tcx.sess.span_bug(ty_method.span, + "found required method in \ + worklist?!") + } + provided(ref method) => { + visit::visit_block(&method.body, (), visitor) + } + } + } + Some(&ast_map::node_method(ref method, _, _)) => { + visit::visit_block(&method.body, (), visitor) + } + Some(_) => { + let ident_interner = token::get_ident_interner(); + let desc = ast_map::node_id_to_str(self.tcx.items, + search_item, + ident_interner); + self.tcx.sess.bug(fmt!("found unexpected thingy in \ + worklist: %s", + desc)) + } + None => { + self.tcx.sess.bug(fmt!("found unmapped ID in worklist: \ + %d", + search_item)) + } + } + } + } + + // Step 3: Mark all destructors as reachable. + // + // XXX(pcwalton): This is a conservative overapproximation, but fixing + // this properly would result in the necessity of computing *type* + // reachability, which might result in a compile time loss. + fn mark_destructors_reachable(&self) { + for self.tcx.destructor_for_type.each |_, destructor_def_id| { + if destructor_def_id.crate == local_crate { + self.reachable_symbols.insert(destructor_def_id.node); + } + } + } +} + +pub fn find_reachable(tcx: ty::ctxt, + method_map: typeck::method_map, + crate: @crate) + -> @mut HashSet { + // XXX(pcwalton): We only need to mark symbols that are exported. But this + // is more complicated than just looking at whether the symbol is `pub`, + // because it might be the target of a `pub use` somewhere. For now, I + // think we are fine, because you can't `pub use` something that wasn't + // exported due to the bug whereby `use` only looks through public + // modules even if you're inside the module the `use` appears in. When + // this bug is fixed, however, this code will need to be updated. Probably + // the easiest way to fix this (although a conservative overapproximation) + // is to have the name resolution pass mark all targets of a `pub use` as + // "must be reachable". + + let reachable_context = ReachableContext::new(tcx, method_map); + + // Step 1: Mark all public symbols, and add all public symbols that might + // be inlined to a worklist. + reachable_context.mark_public_symbols(crate); + + // Step 2: Mark all symbols that the symbols on the worklist touch. + reachable_context.propagate(); + + // Step 3: Mark all destructors as reachable. + reachable_context.mark_destructors_reachable(); + + // Return the set of reachable symbols. + reachable_context.reachable_symbols +} + diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index bf37ce676a81..224cf7c32a87 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -652,21 +652,9 @@ impl NameBindings { match self.type_def { None => None, Some(ref type_def) => { - // FIXME (#3784): This is reallllly questionable. - // Perhaps the right thing to do is to merge def_mod - // and def_ty. match (*type_def).type_def { Some(type_def) => Some(type_def), - None => { - match (*type_def).module_def { - Some(module_def) => { - let module_def = &mut *module_def; - module_def.def_id.map(|def_id| - def_mod(*def_id)) - } - None => None - } - } + None => None, } } } @@ -1230,49 +1218,29 @@ impl Resolver { visit_item(item, (new_parent, visitor)); } - item_impl(_, trait_ref_opt, ty, ref methods) => { - // If this implements an anonymous trait and it has static - // methods, then add all the static methods within to a new - // module, if the type was defined within this module. + item_impl(_, None, 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. // // FIXME (#3785): This is quite unsatisfactory. Perhaps we // should modify anonymous traits to only be implementable in // the same module that declared the type. - // Bail out early if there are no static methods. - let mut methods_seen = HashMap::new(); - let mut has_static_methods = false; - for methods.iter().advance |method| { - match method.explicit_self.node { - sty_static => has_static_methods = true, - _ => { - // Make sure you can't define duplicate methods - let ident = method.ident; - let span = method.span; - let old_sp = methods_seen.find_or_insert(ident, span); - if *old_sp != span { - self.session.span_err(span, - fmt!("duplicate definition of method `%s`", - self.session.str_of(ident))); - self.session.span_note(*old_sp, - fmt!("first definition of method `%s` here", - self.session.str_of(ident))); - } - } - } - } - - // If there are static methods, then create the module - // and add them. - match (trait_ref_opt, ty) { - (None, @Ty { node: ty_path(path, _, _), _ }) if - has_static_methods && path.idents.len() == 1 => { + // Create the module and add all methods. + match *ty { + Ty { + node: ty_path(path, _), + _ + } if path.idents.len() == 1 => { let name = path_to_ident(path); let new_parent = match parent.children.find(&name) { // It already exists - Some(&child) if child.get_module_if_available().is_some() && - child.get_module().kind == ImplModuleKind => { + Some(&child) if child.get_module_if_available() + .is_some() && + child.get_module().kind == + ImplModuleKind => { ModuleReducedGraphParent(child.get_module()) } // Create the module @@ -1283,8 +1251,8 @@ impl Resolver { ForbidDuplicateModules, sp); - let parent_link = self.get_parent_link(new_parent, - ident); + let parent_link = + self.get_parent_link(new_parent, ident); let def_id = local_def(item.id); name_bindings.define_module(Public, parent_link, @@ -1292,30 +1260,36 @@ impl Resolver { ImplModuleKind, sp); - ModuleReducedGraphParent(name_bindings.get_module()) + ModuleReducedGraphParent( + name_bindings.get_module()) } }; - // For each static method... + // For each method... for methods.iter().advance |method| { - match method.explicit_self.node { + // Add the method to the module. + let ident = method.ident; + let (method_name_bindings, _) = + self.add_child(ident, + new_parent, + ForbidDuplicateValues, + method.span); + let def = match method.explicit_self.node { sty_static => { - // Add the static method to the - // module. - let ident = method.ident; - let (method_name_bindings, _) = - self.add_child( - ident, - new_parent, - ForbidDuplicateValues, - method.span); - let def = def_fn(local_def(method.id), - method.purity); - method_name_bindings.define_value( - Public, def, method.span); + // Static methods become `def_fn`s. + def_fn(local_def(method.id), + method.purity) } - _ => {} - } + _ => { + // Non-static methods become + // `def_method`s. + def_method(local_def(method.id), None) + } + }; + + method_name_bindings.define_value(Public, + def, + method.span); } } _ => {} @@ -1324,41 +1298,23 @@ impl Resolver { visit_item(item, (parent, visitor)); } + item_impl(_, Some(_), ty, ref methods) => { + visit_item(item, parent, visitor); + } + item_trait(_, _, ref methods) => { let (name_bindings, new_parent) = self.add_child(ident, parent, ForbidDuplicateTypes, sp); - // If the trait has static methods, then add all the static - // methods within to a new module. - // - // We only need to create the module if the trait has static - // methods, so check that first. - let mut has_static_methods = false; - for (*methods).iter().advance |method| { - let ty_m = trait_method_to_ty_method(method); - match ty_m.explicit_self.node { - sty_static => { - has_static_methods = true; - break; - } - _ => {} - } - } - - // Create the module if necessary. - let module_parent_opt; - if has_static_methods { - let parent_link = self.get_parent_link(parent, ident); - name_bindings.define_module(privacy, - parent_link, - Some(local_def(item.id)), - TraitModuleKind, - sp); - module_parent_opt = Some(ModuleReducedGraphParent( - name_bindings.get_module())); - } else { - module_parent_opt = None; - } + // Add all the methods within to a new module. + let parent_link = self.get_parent_link(parent, ident); + name_bindings.define_module(privacy, + parent_link, + Some(local_def(item.id)), + TraitModuleKind, + sp); + let module_parent = ModuleReducedGraphParent(name_bindings. + get_module()); // Add the names of all the methods to the trait info. let mut method_names = HashMap::new(); @@ -1366,35 +1322,34 @@ impl Resolver { let ty_m = trait_method_to_ty_method(method); let ident = ty_m.ident; - // Add it to the trait info if not static, - // add it as a name in the trait module otherwise. - match ty_m.explicit_self.node { - sty_static => { - let def = def_static_method( - local_def(ty_m.id), - Some(local_def(item.id)), - ty_m.purity); - let (method_name_bindings, _) = - self.add_child(ident, - module_parent_opt.get(), - ForbidDuplicateValues, - ty_m.span); - method_name_bindings.define_value(Public, - def, - ty_m.span); + // Add it as a name in the trait module. + let def = match ty_m.explicit_self.node { + sty_static => { + // Static methods become `def_static_method`s. + def_static_method(local_def(ty_m.id), + Some(local_def(item.id)), + ty_m.purity) } _ => { - // Make sure you can't define duplicate methods - let old_sp = method_names.find_or_insert(ident, ty_m.span); - if *old_sp != ty_m.span { - self.session.span_err(ty_m.span, - fmt!("duplicate definition of method `%s`", - self.session.str_of(ident))); - self.session.span_note(*old_sp, - fmt!("first definition of method `%s` here", - self.session.str_of(ident))); - } + // Non-static methods become `def_method`s. + def_method(local_def(ty_m.id), + Some(local_def(item.id))) + } + }; + + let (method_name_bindings, _) = + self.add_child(ident, + module_parent, + ForbidDuplicateValues, + ty_m.span); + method_name_bindings.define_value(Public, def, ty_m.span); + + // Add it to the trait info if not static. + match ty_m.explicit_self.node { + sty_static => {} + _ => { + method_names.insert(ident); } } } @@ -1751,6 +1706,9 @@ impl Resolver { child_name_bindings.define_type(privacy, def, dummy_sp()); self.structs.insert(def_id); } + def_method(*) => { + // Ignored; handled elsewhere. + } def_self(*) | def_arg(*) | def_local(*) | def_prim_ty(*) | def_ty_param(*) | def_binding(*) | def_use(*) | def_upvar(*) | def_region(*) | @@ -2391,7 +2349,8 @@ impl Resolver { } match type_result { BoundResult(target_module, name_bindings) => { - debug!("(resolving single import) found type target"); + debug!("(resolving single import) found type target: %?", + name_bindings.type_def.get().type_def); import_resolution.type_target = Some(Target(target_module, name_bindings)); import_resolution.type_id = directive.id; @@ -3269,22 +3228,8 @@ impl Resolver { pub fn add_exports_for_module(@mut self, exports2: &mut ~[Export2], module_: @mut Module) { - for module_.children.iter().advance |(ident, namebindings)| { - debug!("(computing exports) maybe export '%s'", - self.session.str_of(*ident)); - self.add_exports_of_namebindings(&mut *exports2, - *ident, - *namebindings, - TypeNS, - false); - self.add_exports_of_namebindings(&mut *exports2, - *ident, - *namebindings, - ValueNS, - false); - } - - for module_.import_resolutions.iter().advance |(ident, importresolution)| { + for module_.import_resolutions.iter().advance |ident, + importresolution| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", self.session.str_of(*ident)); @@ -4518,8 +4463,8 @@ impl Resolver { if path.global { return self.resolve_crate_relative_path(path, - self.xray_context, - namespace); + self.xray_context, + namespace); } if path.idents.len() > 1 { @@ -4947,6 +4892,22 @@ impl Resolver { // Write the result into the def map. debug!("(resolving expr) resolved `%s`", self.idents_to_str(path.idents)); + + // First-class methods are not supported yet; error + // out here. + match def { + def_method(*) => { + self.session.span_err(expr.span, + "first-class methods \ + are not supported"); + self.session.span_note(expr.span, + "call the method \ + using the `.` \ + syntax"); + } + _ => {} + } + self.record_def(expr.id, def); } None => { @@ -5415,7 +5376,7 @@ pub fn resolve_crate(session: Session, -> CrateMap { let resolver = @mut Resolver(session, lang_items, crate); resolver.resolve(); - let Resolver{def_map, export_map2, trait_map, _} = copy *resolver; + let Resolver { def_map, export_map2, trait_map, _ } = copy *resolver; CrateMap { def_map: def_map, exp_map2: export_map2, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 251add59326c..53d0118aa0e6 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -54,7 +54,6 @@ use middle::trans::machine; use middle::trans::machine::{llalign_of_min, llsize_of}; use middle::trans::meth; use middle::trans::monomorphize; -use middle::trans::reachable; use middle::trans::tvec; use middle::trans::type_of; use middle::trans::type_of::*; @@ -2437,7 +2436,6 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { } } ast_map::node_method(m, _, pth) => { - exprt = true; register_method(ccx, id, pth, m) } ast_map::node_foreign_item(ni, _, _, pth) => { @@ -2511,7 +2509,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { variant)) } }; - if !(exprt || ccx.reachable.contains(&id)) { + if !exprt { lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage); } ccx.item_vals.insert(id, val); @@ -2890,16 +2888,12 @@ pub fn trans_crate(sess: session::Session, tcx: ty::ctxt, output: &Path, emap2: resolve::ExportMap2, - maps: astencode::Maps) -> (ContextRef, ModuleRef, LinkMeta) { + reachable_map: @mut HashSet, + maps: astencode::Maps) + -> (ContextRef, ModuleRef, LinkMeta) { let mut symbol_hasher = hash::default_state(); let link_meta = link::build_link_meta(sess, crate, output, &mut symbol_hasher); - let reachable = reachable::find_reachable( - &crate.node.module, - emap2, - tcx, - maps.method_map - ); // Append ".rc" to crate name as LLVM module identifier. // diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 045c8ec01aa1..3405db8e52f6 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -146,7 +146,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee { ast::def_static(*) | ast::def_ty(*) | ast::def_prim_ty(*) | ast::def_use(*) | ast::def_typaram_binder(*) | ast::def_region(*) | ast::def_label(*) | ast::def_ty_param(*) | - ast::def_self_ty(*) => { + ast::def_self_ty(*) | ast::def_method(*) => { bcx.tcx().sess.span_bug( ref_expr.span, fmt!("Cannot translate def %? \ diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 4e3583a4095a..94a314862cbb 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -117,7 +117,84 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { } } -pub type ExternMap = HashMap<@str, ValueRef>; +pub type ExternMap = @mut HashMap<@str, ValueRef>; + +// Crate context. Every crate we compile has one of these. +pub struct CrateContext { + sess: session::Session, + llmod: ModuleRef, + td: TargetData, + tn: @TypeNames, + externs: ExternMap, + intrinsics: HashMap<&'static str, ValueRef>, + item_vals: @mut HashMap, + exp_map2: resolve::ExportMap2, + item_symbols: @mut HashMap, + link_meta: LinkMeta, + enum_sizes: @mut HashMap, + discrims: @mut HashMap, + discrim_symbols: @mut HashMap, + tydescs: @mut HashMap, + // Set when running emit_tydescs to enforce that no more tydescs are + // created. + finished_tydescs: @mut bool, + // Track mapping of external ids to local items imported for inlining + external: @mut HashMap>, + // Cache instances of monomorphized functions + monomorphized: @mut HashMap, + monomorphizing: @mut HashMap, + // Cache computed type parameter uses (see type_use.rs) + type_use_cache: @mut HashMap, + // Cache generated vtables + vtables: @mut HashMap, + // Cache of constant strings, + const_cstr_cache: @mut HashMap<@str, ValueRef>, + + // Reverse-direction for const ptrs cast from globals. + // Key is an int, cast from a ValueRef holding a *T, + // Val is a ValueRef holding a *[T]. + // + // Needed because LLVM loses pointer->pointee association + // when we ptrcast, and we have to ptrcast during translation + // of a [T] const because we form a slice, a [*T,int] pair, not + // a pointer to an LLVM array type. + const_globals: @mut HashMap, + + // Cache of emitted const values + const_values: @mut HashMap, + + // Cache of external const values + extern_const_values: @mut HashMap, + + module_data: @mut HashMap<~str, ValueRef>, + lltypes: @mut HashMap, + llsizingtypes: @mut HashMap, + adt_reprs: @mut HashMap, + names: namegen, + next_addrspace: addrspace_gen, + symbol_hasher: @mut hash::State, + type_hashcodes: @mut HashMap, + type_short_names: @mut HashMap, + all_llvm_symbols: @mut HashSet<@str>, + tcx: ty::ctxt, + maps: astencode::Maps, + stats: @mut Stats, + upcalls: @upcall::Upcalls, + tydesc_type: TypeRef, + int_type: TypeRef, + float_type: TypeRef, + opaque_vec_type: TypeRef, + builder: BuilderRef_res, + shape_cx: shape::Ctxt, + crate_map: ValueRef, + // Set when at least one function uses GC. Needed so that + // decl_gc_metadata knows whether to link to the module metadata, which + // is not emitted by LLVM's GC pass when no functions use GC. + uses_gc: @mut bool, + dbg_cx: Option, + do_not_commit_warning_issued: @mut bool, + reachable_map: @mut HashSet, +} // Types used for llself. pub struct ValSelfData { diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index c2a25d80998a..64d6bbec87c4 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -37,7 +37,6 @@ pub mod foreign; pub mod reflect; pub mod debuginfo; pub mod type_use; -pub mod reachable; pub mod machine; pub mod adt; pub mod asm; diff --git a/src/librustc/middle/trans/reachable.rs b/src/librustc/middle/trans/reachable.rs deleted file mode 100644 index e950c24c49e8..000000000000 --- a/src/librustc/middle/trans/reachable.rs +++ /dev/null @@ -1,246 +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. - -// Finds items that are externally reachable, to determine which items -// need to have their metadata (and possibly their AST) serialized. -// All items that can be referred to through an exported name are -// reachable, and when a reachable thing is inline or generic, it -// makes all other generics or inline functions that it references -// reachable as well. - -use core::prelude::*; - -use middle::resolve; -use middle::ty; -use middle::typeck; - -use core::hashmap::HashSet; -use syntax::ast; -use syntax::ast::*; -use syntax::ast_util::def_id_of_def; -use syntax::attr; -use syntax::codemap; -use syntax::print::pprust::expr_to_str; -use syntax::{visit, ast_map}; - -pub type map = @HashSet; - -struct ctx<'self> { - exp_map2: resolve::ExportMap2, - tcx: ty::ctxt, - method_map: typeck::method_map, - rmap: &'self mut HashSet, -} - -pub fn find_reachable(crate_mod: &_mod, exp_map2: resolve::ExportMap2, - tcx: ty::ctxt, method_map: typeck::method_map) -> map { - let mut rmap = HashSet::new(); - { - let cx = @mut ctx { - exp_map2: exp_map2, - tcx: tcx, - method_map: method_map, - rmap: &mut rmap - }; - traverse_public_mod(cx, ast::crate_node_id, crate_mod); - traverse_all_resources_and_impls(cx, crate_mod); - } - return @rmap; -} - -fn traverse_exports(cx: @mut ctx, mod_id: node_id) -> bool { - let mut found_export = false; - match cx.exp_map2.find(&mod_id) { - Some(ref exp2s) => { - for (*exp2s).iter().advance |e2| { - found_export = true; - traverse_def_id(cx, e2.def_id) - }; - } - None => () - } - return found_export; -} - -fn traverse_def_id(cx: @mut ctx, did: def_id) { - if did.crate != local_crate { return; } - match cx.tcx.items.find(&did.node) { - None => (), // This can happen for self, for example - Some(&ast_map::node_item(item, _)) => traverse_public_item(cx, item), - Some(&ast_map::node_method(_, impl_id, _)) => traverse_def_id(cx, impl_id), - Some(&ast_map::node_foreign_item(item, _, _, _)) => { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - cx.rmap.insert(item.id); - } - Some(&ast_map::node_variant(ref v, _, _)) => { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - cx.rmap.insert(v.node.id); - } - _ => () - } -} - -fn traverse_public_mod(cx: @mut ctx, mod_id: node_id, m: &_mod) { - if !traverse_exports(cx, mod_id) { - // No exports, so every local item is exported - for m.items.iter().advance |item| { - traverse_public_item(cx, *item); - } - } -} - -fn traverse_public_item(cx: @mut ctx, item: @item) { - { - // FIXME #6021: naming rmap shouldn't be necessary - let cx = &mut *cx; - let rmap: &mut HashSet = cx.rmap; - if rmap.contains(&item.id) { return; } - rmap.insert(item.id); - } - - match item.node { - item_mod(ref m) => traverse_public_mod(cx, item.id, m), - item_foreign_mod(ref nm) => { - if !traverse_exports(cx, item.id) { - for nm.items.iter().advance |item| { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - cx.rmap.insert(item.id); - } - } - } - item_fn(_, _, _, ref generics, ref blk) => { - if generics.ty_params.len() > 0u || - attr::find_inline_attr(item.attrs) != attr::ia_none { - traverse_inline_body(cx, blk); - } - } - item_impl(ref generics, _, _, ref ms) => { - for ms.iter().advance |m| { - if generics.ty_params.len() > 0u || - m.generics.ty_params.len() > 0u || - attr::find_inline_attr(m.attrs) != attr::ia_none - { - { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - cx.rmap.insert(m.id); - } - traverse_inline_body(cx, &m.body); - } - } - } - item_struct(ref struct_def, _) => { - for struct_def.ctor_id.iter().advance |&ctor_id| { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - cx.rmap.insert(ctor_id); - } - } - item_ty(t, _) => { - traverse_ty(t, (cx, - visit::mk_vt(@visit::Visitor {visit_ty: traverse_ty, - ..*visit::default_visitor()}))) - } - item_static(*) | - item_enum(*) | item_trait(*) => (), - item_mac(*) => fail!("item macros unimplemented") - } -} - -fn traverse_ty<'a>(ty: @Ty, (cx, v): (@mut ctx<'a>, visit::vt<@mut ctx<'a>>)) { - { - let cx = &mut *cx; // FIXME(#6269) reborrow @mut to &mut - if cx.rmap.contains(&ty.id) { return; } - cx.rmap.insert(ty.id); - } - - match ty.node { - ty_path(p, _bounds, p_id) => { - match cx.tcx.def_map.find(&p_id) { - // Kind of a hack to check this here, but I'm not sure what else - // to do - Some(&def_prim_ty(_)) => { /* do nothing */ } - Some(&d) => traverse_def_id(cx, def_id_of_def(d)), - None => { /* do nothing -- but should we fail here? */ } - } - for p.types.iter().advance |t| { - (v.visit_ty)(*t, (cx, v)); - } - } - _ => visit::visit_ty(ty, (cx, v)) - } -} - -fn traverse_inline_body(cx: @mut ctx, body: &blk) { - fn traverse_expr<'a>(e: @expr, (cx, v): (@mut ctx<'a>, - visit::vt<@mut ctx<'a>>)) { - match e.node { - expr_path(_) => { - match cx.tcx.def_map.find(&e.id) { - Some(&d) => { - traverse_def_id(cx, def_id_of_def(d)); - } - None => cx.tcx.sess.span_bug( - e.span, - fmt!("Unbound node id %? while traversing %s", - e.id, - expr_to_str(e, cx.tcx.sess.intr()))) - } - } - expr_method_call(*) => { - match cx.method_map.find(&e.id) { - Some(&typeck::method_map_entry { - origin: typeck::method_static(did), - _ - }) => { - traverse_def_id(cx, did); - } - Some(_) => {} - None => { - cx.tcx.sess.span_bug(e.span, "expr_method_call not in \ - method map"); - } - } - } - _ => () - } - visit::visit_expr(e, (cx, v)); - } - // Don't ignore nested items: for example if a generic fn contains a - // generic impl (as in deque::create), we need to monomorphize the - // impl as well - fn traverse_item(i: @item, (cx, _v): (@mut ctx, visit::vt<@mut ctx>)) { - traverse_public_item(cx, i); - } - visit::visit_block(body, (cx, visit::mk_vt(@visit::Visitor { - visit_expr: traverse_expr, - visit_item: traverse_item, - ..*visit::default_visitor() - }))); -} - -fn traverse_all_resources_and_impls(cx: @mut ctx, crate_mod: &_mod) { - visit::visit_mod( - crate_mod, - codemap::dummy_sp(), - 0, - (cx, - visit::mk_vt(@visit::Visitor { - visit_expr: |_e, (_cx, _v)| { }, - visit_item: |i, (cx, v)| { - visit::visit_item(i, (cx, v)); - match i.node { - item_impl(*) => { - traverse_public_item(cx, i); - } - _ => () - } - }, - ..*visit::default_visitor() - }))); -} diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 1da76644244f..b4a710e15b88 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -791,10 +791,6 @@ impl FnCtxt { ast_ty_to_ty(self, self, ast_t) } - pub fn expr_to_str(&self, expr: @ast::expr) -> ~str { - expr.repr(self.tcx()) - } - pub fn pat_to_str(&self, pat: @ast::pat) -> ~str { pat.repr(self.tcx()) } @@ -3293,6 +3289,9 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt, ast::def_self_ty(*) => { fcx.ccx.tcx.sess.span_bug(sp, "expected value but found self ty"); } + ast::def_method(*) => { + fcx.ccx.tcx.sess.span_bug(sp, "expected value but found method"); + } } } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 94520b6faca6..5065a475a405 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -81,10 +81,20 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { }))); } -impl CrateCtxt { +pub trait ToTy { fn to_ty( - &self, rs: &RS, ast_ty: &ast::Ty) -> ty::t - { + &self, + rs: &RS, + ast_ty: &ast::Ty) + -> ty::t; +} + +impl ToTy for CrateCtxt { + fn to_ty( + &self, + rs: &RS, + ast_ty: &ast::Ty) + -> ty::t { ast_ty_to_ty(self, rs, ast_ty) } } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 884f72b57f08..7a4ea0999efa 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -64,7 +64,8 @@ use middle::typeck::infer::glb::Glb; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; -use middle::typeck::infer::{cres, InferCtxt, ures}; +use middle::typeck::infer::unify::{InferCtxtMethods, UnifyInferCtxtMethods}; +use middle::typeck::infer::{InferCtxt, cres, ures}; use util::common::indent; use core::result::{iter_vec2, map_vec2}; diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 658fd67ee585..ed19310d5d69 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -71,15 +71,53 @@ impl LatticeValue for ty::t { } } -impl CombineFields { - pub fn var_sub_var>>(&self, - a_id: - V, - b_id: - V) - -> - ures { +pub trait CombineFieldsLatticeMethods { + fn var_sub_var>>(&self, + a_id: V, + b_id: V) + -> ures; + /// make variable a subtype of T + fn var_sub_t>>( + &self, + a_id: V, + b: T) + -> ures; + fn t_sub_var>>( + &self, + a: T, + b_id: V) + -> ures; + fn merge_bnd( + &self, + a: &Bound, + b: &Bound, + lattice_op: LatticeOp) + -> cres>; + fn set_var_to_merged_bounds>>( + &self, + v_id: V, + a: &Bounds, + b: &Bounds, + rank: uint) + -> ures; + fn bnds( + &self, + a: &Bound, + b: &Bound) + -> ures; +} + +impl CombineFieldsLatticeMethods for CombineFields { + fn var_sub_var>>( + &self, + a_id: V, + b_id: V) + -> ures { /*! * * Make one variable a subtype of another variable. This is a @@ -127,12 +165,12 @@ impl CombineFields { } /// make variable a subtype of T - pub fn var_sub_t>>(&self, - a_id: V, - b: T) - -> ures - { + fn var_sub_t>>( + &self, + a_id: V, + b: T) + -> ures { /*! * * Make a variable (`a_id`) a subtype of the concrete type `b` */ @@ -151,12 +189,12 @@ impl CombineFields { a_id, a_bounds, b_bounds, node_a.rank) } - pub fn t_sub_var>>(&self, - a: T, - b_id: V) - -> ures - { + fn t_sub_var>>( + &self, + a: T, + b_id: V) + -> ures { /*! * * Make a concrete type (`a`) a subtype of the variable `b_id` */ @@ -175,12 +213,12 @@ impl CombineFields { b_id, a_bounds, b_bounds, node_b.rank) } - pub fn merge_bnd(&self, - a: &Bound, - b: &Bound, - lattice_op: - LatticeOp) - -> cres> { + fn merge_bnd( + &self, + a: &Bound, + b: &Bound, + lattice_op: LatticeOp) + -> cres> { /*! * * Combines two bounds into a more general bound. */ @@ -202,14 +240,14 @@ impl CombineFields { } } - pub fn set_var_to_merged_bounds>>( - &self, - v_id: V, - a: &Bounds, - b: &Bounds, - rank: uint) - -> ures { + fn set_var_to_merged_bounds>>( + &self, + v_id: V, + a: &Bounds, + b: &Bounds, + rank: uint) + -> ures { /*! * * Updates the bounds for the variable `v_id` to be the intersection @@ -264,10 +302,10 @@ impl CombineFields { uok() } - pub fn bnds(&self, - a: &Bound, - b: &Bound) - -> ures { + fn bnds(&self, + a: &Bound, + b: &Bound) + -> ures { debug!("bnds(%s <: %s)", a.inf_str(self.infcx), b.inf_str(self.infcx)); let _r = indenter(); diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs index ab52ef36978a..1311907eed2e 100644 --- a/src/librustc/middle/typeck/infer/resolve.rs +++ b/src/librustc/middle/typeck/infer/resolve.rs @@ -54,7 +54,7 @@ use middle::ty; use middle::typeck::infer::{Bounds, cyclic_ty, fixup_err, fres, InferCtxt}; use middle::typeck::infer::{region_var_bound_by_region_var, unresolved_ty}; use middle::typeck::infer::to_str::InferStr; -use middle::typeck::infer::unify::Root; +use middle::typeck::infer::unify::{Root, UnifyInferCtxtMethods}; use util::common::{indent, indenter}; use util::ppaux::ty_to_str; diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 4462d43015cf..eb912aa2dda4 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -18,6 +18,7 @@ use middle::typeck::infer::combine::*; use middle::typeck::infer::cres; use middle::typeck::infer::glb::Glb; use middle::typeck::infer::InferCtxt; +use middle::typeck::infer::lattice::CombineFieldsLatticeMethods; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; use util::common::{indent, indenter}; diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index 371d389f712c..a185633a7ac7 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -40,9 +40,31 @@ pub trait UnifyVid { -> &'v mut ValsAndBindings; } -impl InferCtxt { - pub fn get>(&mut self, vid: V) - -> Node { +pub trait UnifyInferCtxtMethods { + fn get>( + &mut self, + vid: V) + -> Node; + fn set>( + &mut self, + vid: V, + new_v: VarValue); + fn unify>( + &mut self, + node_a: &Node, + node_b: &Node) + -> (V, uint); +} + +impl UnifyInferCtxtMethods for InferCtxt { + fn get>( + &mut self, + vid: V) + -> Node { /*! * * Find the root node for `vid`. This uses the standard @@ -84,10 +106,11 @@ impl InferCtxt { } } - pub fn set>(&mut self, - vid: V, - new_v: VarValue) { + fn set>( + &mut self, + vid: V, + new_v: VarValue) { /*! * * Sets the value for `vid` to `new_v`. `vid` MUST be a root node! @@ -102,11 +125,12 @@ impl InferCtxt { vb.vals.insert(vid.to_uint(), new_v); } - pub fn unify>(&mut self, - node_a: &Node, - node_b: &Node) - -> (V, uint) { + fn unify>( + &mut self, + node_a: &Node, + node_b: &Node) + -> (V, uint) { // Rank optimization: if you don't know what it is, check // out @@ -155,14 +179,31 @@ pub fn mk_err(a_is_expected: bool, } } -impl InferCtxt { - pub fn simple_vars>>(&mut self, - a_is_expected: - bool, - a_id: V, - b_id: V) - -> ures { +pub trait InferCtxtMethods { + fn simple_vars>>( + &mut self, + a_is_expected: bool, + a_id: V, + b_id: V) + -> ures; + fn simple_var_t>>( + &mut self, + a_is_expected: bool, + a_id: V, + b: T) + -> ures; +} + +impl InferCtxtMethods for InferCtxt { + fn simple_vars>>( + &mut self, + a_is_expected: bool, + a_id: V, + b_id: V) + -> ures { /*! * * Unifies two simple variables. Because simple variables do @@ -194,13 +235,13 @@ impl InferCtxt { return uok(); } - pub fn simple_var_t>>(&mut self, - a_is_expected - : bool, - a_id: V, - b: T) - -> ures { + fn simple_var_t>>( + &mut self, + a_is_expected: bool, + a_id: V, + b: T) + -> ures { /*! * * Sets the value of the variable `a_id` to `b`. Because diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index a27838b5d11e..957cf02ed77e 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -80,6 +80,7 @@ pub mod middle { pub mod moves; pub mod entry; pub mod effect; + pub mod reachable; } pub mod front { diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index d70428e73385..ca13ba39d59c 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -185,7 +185,20 @@ impl<'self> PkgScript<'self> { } -impl Ctx { +pub trait CtxMethods { + fn run(&self, cmd: &str, args: ~[~str]); + fn do_cmd(&self, _cmd: &str, _pkgname: &str); + fn build(&self, workspace: &Path, pkgid: &PkgId); + fn clean(&self, workspace: &Path, id: &PkgId); + fn info(&self); + fn install(&self, workspace: &Path, id: &PkgId); + fn prefer(&self, _id: &str, _vers: Option<~str>); + fn test(&self); + fn uninstall(&self, _id: &str, _vers: Option<~str>); + fn unprefer(&self, _id: &str, _vers: Option<~str>); +} + +impl CtxMethods for Ctx { fn run(&self, cmd: &str, args: ~[~str]) { match cmd { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 6059ba5cbddd..b3b696a9a603 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -335,8 +335,8 @@ mod stat { } } - -impl Path { +#[cfg(target_os = "win32")] +impl WindowsPath { pub fn stat(&self) -> Option { unsafe { do str::as_c_str(self.to_str()) |buf| { @@ -349,12 +349,35 @@ impl Path { } } - #[cfg(unix)] - pub fn lstat(&self) -> Option { + pub fn exists(&self) -> bool { + match self.stat() { + None => false, + Some(_) => true, + } + } + + pub fn get_size(&self) -> Option { + match self.stat() { + None => None, + Some(ref st) => Some(st.st_size as i64), + } + } + + pub fn get_mode(&self) -> Option { + match self.stat() { + None => None, + Some(ref st) => Some(st.st_mode as uint), + } + } +} + +#[cfg(not(target_os = "win32"))] +impl PosixPath { + pub fn stat(&self) -> Option { unsafe { - do str::as_c_str(self.to_str()) |buf| { + do str::as_c_str(self.to_str()) |buf| { let mut st = stat::arch::default_stat(); - match libc::lstat(buf, &mut st) { + match libc::stat(buf, &mut st) { 0 => Some(st), _ => None, } @@ -396,7 +419,7 @@ impl Path { #[cfg(target_os = "freebsd")] #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] -impl Path { +impl PosixPath { pub fn get_atime(&self) -> Option<(i64, int)> { match self.stat() { None => None, @@ -428,9 +451,24 @@ impl Path { } } +#[cfg(unix)] +impl PosixPath { + pub fn lstat(&self) -> Option { + unsafe { + do str::as_c_str(self.to_str()) |buf| { + let mut st = stat::arch::default_stat(); + match libc::lstat(buf, &mut st) { + 0 => Some(st), + _ => None, + } + } + } + } +} + #[cfg(target_os = "freebsd")] #[cfg(target_os = "macos")] -impl Path { +impl PosixPath { pub fn get_birthtime(&self) -> Option<(i64, int)> { match self.stat() { None => None, @@ -443,7 +481,7 @@ impl Path { } #[cfg(target_os = "win32")] -impl Path { +impl WindowsPath { pub fn get_atime(&self) -> Option<(i64, int)> { match self.stat() { None => None, diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 07a67ca3b1e6..9c94f36fba3f 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -859,7 +859,8 @@ pub mod raw { /// invalidated later. pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str { let s = s as *u8; - let mut (curr, len) = (s, 0u); + let mut curr = s; + let mut len = 0u; while *curr != 0u8 { len += 1u; curr = ptr::offset(s, len); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 265e9e444e94..8e1c51caf7c1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -205,7 +205,8 @@ pub enum def { def_struct(def_id), def_typaram_binder(node_id), /* struct, impl or trait with ty params */ def_region(node_id), - def_label(node_id) + def_label(node_id), + def_method(def_id /* method */, Option /* trait */), } @@ -1047,7 +1048,7 @@ pub struct trait_ref { pub enum visibility { public, private, inherited } impl visibility { - fn inherit_from(&self, parent_visibility: visibility) -> visibility { + pub fn inherit_from(&self, parent_visibility: visibility) -> visibility { match self { &inherited => parent_visibility, &public | &private => *self diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 4ffaba090610..6761736d2f37 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -59,7 +59,7 @@ pub fn def_id_of_def(d: def) -> def_id { def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) | def_foreign_mod(id) | def_static(id, _) | def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | - def_use(id) | def_struct(id) | def_trait(id) => { + def_use(id) | def_struct(id) | def_trait(id) | def_method(id, _) => { id } def_arg(id, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id) diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index e003e2b27e9a..04f62f357490 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -51,251 +51,3 @@ pub fn token_to_str(token: &token::Token) -> ~str { token::to_str(get_ident_interner(), token) } -impl Parser { - // convert a token to a string using self's reader - pub fn token_to_str(&self, token: &token::Token) -> ~str { - token::to_str(get_ident_interner(), token) - } - - // convert the current token to a string using self's reader - pub fn this_token_to_str(&self) -> ~str { - self.token_to_str(self.token) - } - - pub fn unexpected_last(&self, t: &token::Token) -> ! { - self.span_fatal( - *self.last_span, - fmt!( - "unexpected token: `%s`", - self.token_to_str(t) - ) - ); - } - - pub fn unexpected(&self) -> ! { - self.fatal( - fmt!( - "unexpected token: `%s`", - self.this_token_to_str() - ) - ); - } - - // expect and consume the token t. Signal an error if - // the next token is not t. - pub fn expect(&self, t: &token::Token) { - if *self.token == *t { - self.bump(); - } else { - self.fatal( - fmt!( - "expected `%s` but found `%s`", - self.token_to_str(t), - self.this_token_to_str() - ) - ) - } - } - - pub fn parse_ident(&self) -> ast::ident { - self.check_strict_keywords(); - self.check_reserved_keywords(); - match *self.token { - token::IDENT(i, _) => { - self.bump(); - i - } - token::INTERPOLATED(token::nt_ident(*)) => { - self.bug("ident interpolation not converted to real token"); - } - _ => { - self.fatal( - fmt!( - "expected ident, found `%s`", - self.this_token_to_str() - ) - ); - } - } - } - - pub fn parse_path_list_ident(&self) -> ast::path_list_ident { - let lo = self.span.lo; - let ident = self.parse_ident(); - let hi = self.last_span.hi; - spanned(lo, hi, ast::path_list_ident_ { name: ident, - id: self.get_id() }) - } - - // consume token 'tok' if it exists. Returns true if the given - // token was present, false otherwise. - pub fn eat(&self, tok: &token::Token) -> bool { - return if *self.token == *tok { self.bump(); true } else { false }; - } - - pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - token::is_keyword(kw, self.token) - } - - // if the next token is the given keyword, eat it and return - // true. Otherwise, return false. - pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool { - let is_kw = match *self.token { - token::IDENT(sid, false) => kw.to_ident().name == sid.name, - _ => false - }; - if is_kw { self.bump() } - is_kw - } - - // if the given word is not a keyword, signal an error. - // if the next token is not the given word, signal an error. - // otherwise, eat it. - pub fn expect_keyword(&self, kw: keywords::Keyword) { - if !self.eat_keyword(kw) { - self.fatal( - fmt!( - "expected `%s`, found `%s`", - self.id_to_str(kw.to_ident()), - self.this_token_to_str() - ) - ); - } - } - - // signal an error if the given string is a strict keyword - pub fn check_strict_keywords(&self) { - if token::is_strict_keyword(self.token) { - self.span_err(*self.last_span, - fmt!("found `%s` in ident position", self.this_token_to_str())); - } - } - - // signal an error if the current token is a reserved keyword - pub fn check_reserved_keywords(&self) { - if token::is_reserved_keyword(self.token) { - self.fatal(fmt!("`%s` is a reserved keyword", self.this_token_to_str())); - } - } - - // expect and consume a GT. if a >> is seen, replace it - // with a single > and continue. If a GT is not seen, - // signal an error. - pub fn expect_gt(&self) { - if *self.token == token::GT { - self.bump(); - } else if *self.token == token::BINOP(token::SHR) { - self.replace_token( - token::GT, - self.span.lo + BytePos(1u), - self.span.hi - ); - } else { - let mut s: ~str = ~"expected `"; - s.push_str(self.token_to_str(&token::GT)); - s.push_str("`, found `"); - s.push_str(self.this_token_to_str()); - s.push_str("`"); - self.fatal(s); - } - } - - // parse a sequence bracketed by '<' and '>', stopping - // before the '>'. - pub fn parse_seq_to_before_gt(&self, - sep: Option, - f: &fn(&Parser) -> T) - -> OptVec { - let mut first = true; - let mut v = opt_vec::Empty; - while *self.token != token::GT - && *self.token != token::BINOP(token::SHR) { - match sep { - Some(ref t) => { - if first { first = false; } - else { self.expect(t); } - } - _ => () - } - v.push(f(self)); - } - return v; - } - - pub fn parse_seq_to_gt(&self, - sep: Option, - f: &fn(&Parser) -> T) - -> OptVec { - let v = self.parse_seq_to_before_gt(sep, f); - self.expect_gt(); - return v; - } - - // parse a sequence, including the closing delimiter. The function - // f must consume tokens until reaching the next separator or - // closing bracket. - pub fn parse_seq_to_end(&self, - ket: &token::Token, - sep: SeqSep, - f: &fn(&Parser) -> T) - -> ~[T] { - let val = self.parse_seq_to_before_end(ket, sep, f); - self.bump(); - val - } - - // parse a sequence, not including the closing delimiter. The function - // f must consume tokens until reaching the next separator or - // closing bracket. - pub fn parse_seq_to_before_end(&self, - ket: &token::Token, - sep: SeqSep, - f: &fn(&Parser) -> T) - -> ~[T] { - let mut first: bool = true; - let mut v: ~[T] = ~[]; - while *self.token != *ket { - match sep.sep { - Some(ref t) => { - if first { first = false; } - else { self.expect(t); } - } - _ => () - } - if sep.trailing_sep_allowed && *self.token == *ket { break; } - v.push(f(self)); - } - return v; - } - - // parse a sequence, including the closing delimiter. The function - // f must consume tokens until reaching the next separator or - // closing bracket. - pub fn parse_unspanned_seq(&self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: &fn(&Parser) -> T) - -> ~[T] { - self.expect(bra); - let result = self.parse_seq_to_before_end(ket, sep, f); - self.bump(); - result - } - - // NB: Do not use this function unless you actually plan to place the - // spanned list in the AST. - pub fn parse_seq(&self, - bra: &token::Token, - ket: &token::Token, - sep: SeqSep, - f: &fn(&Parser) -> T) - -> spanned<~[T]> { - let lo = self.span.lo; - self.expect(bra); - let result = self.parse_seq_to_before_end(ket, sep, f); - let hi = self.span.hi; - self.bump(); - spanned(lo, hi, result) - } -} diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 7f2d06ee1e41..fff4c125af62 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -73,7 +73,26 @@ impl to_bytes::IterBytes for ObsoleteSyntax { } } -impl Parser { +pub trait ParserObsoleteMethods { + /// Reports an obsolete syntax non-fatal error. + fn obsolete(&self, sp: span, kind: ObsoleteSyntax); + // Reports an obsolete syntax non-fatal error, and returns + // a placeholder expression + fn obsolete_expr(&self, sp: span, kind: ObsoleteSyntax) -> @expr; + fn report(&self, + sp: span, + kind: ObsoleteSyntax, + kind_str: &str, + desc: &str); + fn token_is_obsolete_ident(&self, ident: &str, token: &Token) -> bool; + fn is_obsolete_ident(&self, ident: &str) -> bool; + fn eat_obsolete_ident(&self, ident: &str) -> bool; + fn try_parse_obsolete_struct_ctor(&self) -> bool; + fn try_parse_obsolete_with(&self) -> bool; + fn try_parse_obsolete_priv_section(&self, attrs: &[attribute]) -> bool; +} + +impl ParserObsoleteMethods for Parser { /// Reports an obsolete syntax non-fatal error. pub fn obsolete(&self, sp: span, kind: ObsoleteSyntax) { let (kind_str, desc) = match kind { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a7c46d609cae..64bdfd4a4d33 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -64,7 +64,7 @@ use codemap::{span, BytePos, spanned, mk_sp}; use codemap; use parse::attr::parser_attr; use parse::classify; -use parse::common::{seq_sep_none}; +use parse::common::{SeqSep, seq_sep_none}; use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed}; use parse::lexer::reader; use parse::lexer::TokenAndSpan; @@ -84,7 +84,7 @@ use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType}; use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl}; use parse::obsolete::{ObsoleteMutWithMultipleBindings}; -use parse::obsolete::{ObsoletePatternCopyKeyword}; +use parse::obsolete::{ObsoletePatternCopyKeyword, ParserObsoleteMethods}; use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident}; use parse::token::{is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents}; @@ -274,6 +274,253 @@ impl Drop for Parser { } impl Parser { + // convert a token to a string using self's reader + pub fn token_to_str(&self, token: &token::Token) -> ~str { + token::to_str(get_ident_interner(), token) + } + + // convert the current token to a string using self's reader + pub fn this_token_to_str(&self) -> ~str { + self.token_to_str(self.token) + } + + pub fn unexpected_last(&self, t: &token::Token) -> ! { + self.span_fatal( + *self.last_span, + fmt!( + "unexpected token: `%s`", + self.token_to_str(t) + ) + ); + } + + pub fn unexpected(&self) -> ! { + self.fatal( + fmt!( + "unexpected token: `%s`", + self.this_token_to_str() + ) + ); + } + + // expect and consume the token t. Signal an error if + // the next token is not t. + pub fn expect(&self, t: &token::Token) { + if *self.token == *t { + self.bump(); + } else { + self.fatal( + fmt!( + "expected `%s` but found `%s`", + self.token_to_str(t), + self.this_token_to_str() + ) + ) + } + } + + pub fn parse_ident(&self) -> ast::ident { + self.check_strict_keywords(); + self.check_reserved_keywords(); + match *self.token { + token::IDENT(i, _) => { + self.bump(); + i + } + token::INTERPOLATED(token::nt_ident(*)) => { + self.bug("ident interpolation not converted to real token"); + } + _ => { + self.fatal( + fmt!( + "expected ident, found `%s`", + self.this_token_to_str() + ) + ); + } + } + } + + pub fn parse_path_list_ident(&self) -> ast::path_list_ident { + let lo = self.span.lo; + let ident = self.parse_ident(); + let hi = self.last_span.hi; + spanned(lo, hi, ast::path_list_ident_ { name: ident, + id: self.get_id() }) + } + + // consume token 'tok' if it exists. Returns true if the given + // token was present, false otherwise. + pub fn eat(&self, tok: &token::Token) -> bool { + return if *self.token == *tok { self.bump(); true } else { false }; + } + + pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { + token::is_keyword(kw, self.token) + } + + // if the next token is the given keyword, eat it and return + // true. Otherwise, return false. + pub fn eat_keyword(&self, kw: keywords::Keyword) -> bool { + let is_kw = match *self.token { + token::IDENT(sid, false) => kw.to_ident().name == sid.name, + _ => false + }; + if is_kw { self.bump() } + is_kw + } + + // if the given word is not a keyword, signal an error. + // if the next token is not the given word, signal an error. + // otherwise, eat it. + pub fn expect_keyword(&self, kw: keywords::Keyword) { + if !self.eat_keyword(kw) { + self.fatal( + fmt!( + "expected `%s`, found `%s`", + *self.id_to_str(kw.to_ident()), + self.this_token_to_str() + ) + ); + } + } + + // signal an error if the given string is a strict keyword + pub fn check_strict_keywords(&self) { + if token::is_strict_keyword(self.token) { + self.span_err(*self.last_span, + fmt!("found `%s` in ident position", self.this_token_to_str())); + } + } + + // signal an error if the current token is a reserved keyword + pub fn check_reserved_keywords(&self) { + if token::is_reserved_keyword(self.token) { + self.fatal(fmt!("`%s` is a reserved keyword", self.this_token_to_str())); + } + } + + // expect and consume a GT. if a >> is seen, replace it + // with a single > and continue. If a GT is not seen, + // signal an error. + pub fn expect_gt(&self) { + if *self.token == token::GT { + self.bump(); + } else if *self.token == token::BINOP(token::SHR) { + self.replace_token( + token::GT, + self.span.lo + BytePos(1u), + self.span.hi + ); + } else { + let mut s: ~str = ~"expected `"; + s.push_str(self.token_to_str(&token::GT)); + s.push_str("`, found `"); + s.push_str(self.this_token_to_str()); + s.push_str("`"); + self.fatal(s); + } + } + + // parse a sequence bracketed by '<' and '>', stopping + // before the '>'. + pub fn parse_seq_to_before_gt(&self, + sep: Option, + f: &fn(&Parser) -> T) + -> OptVec { + let mut first = true; + let mut v = opt_vec::Empty; + while *self.token != token::GT + && *self.token != token::BINOP(token::SHR) { + match sep { + Some(ref t) => { + if first { first = false; } + else { self.expect(t); } + } + _ => () + } + v.push(f(self)); + } + return v; + } + + pub fn parse_seq_to_gt(&self, + sep: Option, + f: &fn(&Parser) -> T) + -> OptVec { + let v = self.parse_seq_to_before_gt(sep, f); + self.expect_gt(); + return v; + } + + // parse a sequence, including the closing delimiter. The function + // f must consume tokens until reaching the next separator or + // closing bracket. + pub fn parse_seq_to_end(&self, + ket: &token::Token, + sep: SeqSep, + f: &fn(&Parser) -> T) + -> ~[T] { + let val = self.parse_seq_to_before_end(ket, sep, f); + self.bump(); + val + } + + // parse a sequence, not including the closing delimiter. The function + // f must consume tokens until reaching the next separator or + // closing bracket. + pub fn parse_seq_to_before_end(&self, + ket: &token::Token, + sep: SeqSep, + f: &fn(&Parser) -> T) + -> ~[T] { + let mut first: bool = true; + let mut v: ~[T] = ~[]; + while *self.token != *ket { + match sep.sep { + Some(ref t) => { + if first { first = false; } + else { self.expect(t); } + } + _ => () + } + if sep.trailing_sep_allowed && *self.token == *ket { break; } + v.push(f(self)); + } + return v; + } + + // parse a sequence, including the closing delimiter. The function + // f must consume tokens until reaching the next separator or + // closing bracket. + pub fn parse_unspanned_seq(&self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: &fn(&Parser) -> T) + -> ~[T] { + self.expect(bra); + let result = self.parse_seq_to_before_end(ket, sep, f); + self.bump(); + result + } + + // NB: Do not use this function unless you actually plan to place the + // spanned list in the AST. + pub fn parse_seq(&self, + bra: &token::Token, + ket: &token::Token, + sep: SeqSep, + f: &fn(&Parser) -> T) + -> spanned<~[T]> { + let lo = self.span.lo; + self.expect(bra); + let result = self.parse_seq_to_before_end(ket, sep, f); + let hi = self.span.hi; + self.bump(); + spanned(lo, hi, result) + } + // advance the parser by one token pub fn bump(&self) { *self.last_span = copy *self.span; From 89eb9951958dc2cd652645cea5badf4bb9edc6f9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 14 Jun 2013 19:40:11 -0700 Subject: [PATCH 243/336] librustc: Fix merge fallout. --- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/reachable.rs | 16 ++++++++-------- src/librustc/middle/resolve.rs | 6 +++--- src/librustc/middle/trans/asm.rs | 2 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/common.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 10 ++++------ src/librustc/middle/typeck/check/regionck.rs | 19 ++++++++----------- src/libstd/path.rs | 2 +- src/libstd/str.rs | 6 ++++-- src/libsyntax/ext/pipes/pipec.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- 12 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index b1967752e45c..5ff52b1859ad 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1155,7 +1155,7 @@ fn encode_info_for_items(ecx: &EncodeContext, ast_map::path_to_str( *pt, token::get_ident_interner()), - *token::ident_to_str(&ni.ident)); + token::ident_to_str(&ni.ident)); let mut ebml_w = copy ebml_w; // See above diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 1361f2c245af..106c1d85cd77 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -109,7 +109,7 @@ impl ReachableContext { let reachable_symbols = self.reachable_symbols; let worklist = self.worklist; let visitor = visit::mk_vt(@Visitor { - visit_item: |item, _, visitor| { + visit_item: |item, (_, visitor)| { match item.node { item_fn(*) => { reachable_symbols.insert(item.id); @@ -184,13 +184,13 @@ impl ReachableContext { } if item.vis == public { - visit::visit_item(item, (), visitor) + visit::visit_item(item, ((), visitor)) } }, .. *visit::default_visitor() }); - visit::visit_crate(crate, (), visitor) + visit::visit_crate(crate, ((), visitor)) } // Returns true if the given def ID represents a local item that is @@ -256,7 +256,7 @@ impl ReachableContext { let (worklist, method_map) = (self.worklist, self.method_map); let (tcx, reachable_symbols) = (self.tcx, self.reachable_symbols); visit::mk_vt(@visit::Visitor { - visit_expr: |expr, _, visitor| { + visit_expr: |expr, (_, visitor)| { match expr.node { expr_path(_) => { let def = match tcx.def_map.find(&expr.id) { @@ -300,7 +300,7 @@ impl ReachableContext { _ => {} } - visit::visit_expr(expr, (), visitor) + visit::visit_expr(expr, ((), visitor)) }, ..*visit::default_visitor() }) @@ -325,7 +325,7 @@ impl ReachableContext { Some(&ast_map::node_item(item, _)) => { match item.node { item_fn(_, _, _, _, ref search_block) => { - visit::visit_block(search_block, (), visitor) + visit::visit_block(search_block, ((), visitor)) } _ => { self.tcx.sess.span_bug(item.span, @@ -342,12 +342,12 @@ impl ReachableContext { worklist?!") } provided(ref method) => { - visit::visit_block(&method.body, (), visitor) + visit::visit_block(&method.body, ((), visitor)) } } } Some(&ast_map::node_method(ref method, _, _)) => { - visit::visit_block(&method.body, (), visitor) + visit::visit_block(&method.body, ((), visitor)) } Some(_) => { let ident_interner = token::get_ident_interner(); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 224cf7c32a87..7cf13c671b21 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1299,7 +1299,7 @@ impl Resolver { } item_impl(_, Some(_), ty, ref methods) => { - visit_item(item, parent, visitor); + visit_item(item, (parent, visitor)); } item_trait(_, _, ref methods) => { @@ -1349,7 +1349,7 @@ impl Resolver { match ty_m.explicit_self.node { sty_static => {} _ => { - method_names.insert(ident); + method_names.insert(ident, ()); } } } @@ -2054,7 +2054,7 @@ impl Resolver { } else { result.push_str("::") } - result.push_str(*self.session.str_of(*ident)); + result.push_str(self.session.str_of(*ident)); }; return result; } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index b208592d113f..a1d1b737f31f 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -98,7 +98,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { if !ia.clobbers.is_empty() && !clobbers.is_empty() { clobbers = fmt!("%s,%s", ia.clobbers, clobbers); } else { - clobbers.push_str(*ia.clobbers); + clobbers.push_str(ia.clobbers); }; // Add the clobbers to our constraints list diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 53d0118aa0e6..661b19480e05 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2890,7 +2890,7 @@ pub fn trans_crate(sess: session::Session, emap2: resolve::ExportMap2, reachable_map: @mut HashSet, maps: astencode::Maps) - -> (ContextRef, ModuleRef, LinkMeta) { + -> (ModuleRef, LinkMeta) { let mut symbol_hasher = hash::default_state(); let link_meta = link::build_link_meta(sess, crate, output, &mut symbol_hasher); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 94a314862cbb..04bce4c02a81 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1046,7 +1046,7 @@ pub fn path_str(sess: session::Session, p: &[path_elt]) -> ~str { } else { r.push_str("::") } - r.push_str(*sess.str_of(s)); + r.push_str(sess.str_of(s)); } } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index b4a710e15b88..d224d182950d 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -799,9 +799,8 @@ impl FnCtxt { match self.inh.node_types.find(&ex.id) { Some(&t) => t, None => { - self.tcx().sess.bug( - fmt!("no type for %s in fcx %s", - self.expr_to_str(ex), self.tag())); + self.tcx().sess.bug(fmt!("no type for expr in fcx %s", + self.tag())); } } } @@ -1141,7 +1140,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, expected: Option, unifier: &fn()) { - debug!(">> typechecking %s", fcx.expr_to_str(expr)); + debug!(">> typechecking"); fn check_method_argument_types( fcx: @mut FnCtxt, @@ -1730,8 +1729,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ty::mk_closure(tcx, fn_ty_copy) }; - debug!("check_expr_fn_with_unifier %s fty=%s", - fcx.expr_to_str(expr), + debug!("check_expr_fn_with_unifier fty=%s", fcx.infcx().ty_to_str(fty)); fcx.write_ty(expr.id, fty); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 69d4d82d15f2..df81ebd48aa2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -230,7 +230,7 @@ fn constrain_bindings_in_pat(pat: @ast::pat, rcx: @mut Rcx) { } fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { - debug!("regionck::visit_expr(e=%s)", rcx.fcx.expr_to_str(expr)); + debug!("regionck::visit_expr(e=?)"); let has_method_map = rcx.fcx.inh.method_map.contains_key(&expr.id); @@ -520,8 +520,7 @@ fn constrain_derefs(rcx: @mut Rcx, let tcx = rcx.fcx.tcx(); let r_deref_expr = ty::re_scope(deref_expr.id); for uint::range(0, derefs) |i| { - debug!("constrain_derefs(deref_expr=%s, derefd_ty=%s, derefs=%?/%?", - rcx.fcx.expr_to_str(deref_expr), + debug!("constrain_derefs(deref_expr=?, derefd_ty=%s, derefs=%?/%?", rcx.fcx.infcx().ty_to_str(derefd_ty), i, derefs); @@ -576,8 +575,7 @@ fn constrain_index(rcx: @mut Rcx, let tcx = rcx.fcx.tcx(); - debug!("constrain_index(index_expr=%s, indexed_ty=%s", - rcx.fcx.expr_to_str(index_expr), + debug!("constrain_index(index_expr=?, indexed_ty=%s", rcx.fcx.infcx().ty_to_str(indexed_ty)); let r_index_expr = ty::re_scope(index_expr.id); @@ -808,7 +806,7 @@ pub mod guarantor { * to the lifetime of its guarantor (if any). */ - debug!("guarantor::for_addr_of(base=%s)", rcx.fcx.expr_to_str(base)); + debug!("guarantor::for_addr_of(base=?)"); let guarantor = guarantor(rcx, base); link(rcx, expr.span, expr.id, guarantor); @@ -842,8 +840,7 @@ pub mod guarantor { * region pointers. */ - debug!("guarantor::for_autoref(expr=%s, autoref=%?)", - rcx.fcx.expr_to_str(expr), autoref); + debug!("guarantor::for_autoref(autoref=%?)", autoref); let mut expr_ct = categorize_unadjusted(rcx, expr); debug!(" unadjusted cat=%?", expr_ct.cat); @@ -970,7 +967,7 @@ pub mod guarantor { * `&expr`). */ - debug!("guarantor(expr=%s)", rcx.fcx.expr_to_str(expr)); + debug!("guarantor()"); match expr.node { ast::expr_unary(_, ast::deref, b) => { let cat = categorize(rcx, b); @@ -1034,7 +1031,7 @@ pub mod guarantor { } fn categorize(rcx: @mut Rcx, expr: @ast::expr) -> ExprCategorization { - debug!("categorize(expr=%s)", rcx.fcx.expr_to_str(expr)); + debug!("categorize()"); let mut expr_ct = categorize_unadjusted(rcx, expr); debug!("before adjustments, cat=%?", expr_ct.cat); @@ -1086,7 +1083,7 @@ pub mod guarantor { fn categorize_unadjusted(rcx: @mut Rcx, expr: @ast::expr) -> ExprCategorizationType { - debug!("categorize_unadjusted(expr=%s)", rcx.fcx.expr_to_str(expr)); + debug!("categorize_unadjusted()"); let guarantor = { if rcx.fcx.inh.method_map.contains_key(&expr.id) { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index b3b696a9a603..9b4a3270f28a 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -21,7 +21,7 @@ use cmp::Eq; use iterator::IteratorUtil; use libc; use option::{None, Option, Some}; -use str::{Str, StrSlice, StrVector}; +use str::{OwnedStr, Str, StrSlice, StrVector}; use str; use to_str::ToStr; use ascii::{AsciiCast, AsciiStr}; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 9c94f36fba3f..3c512d9bfd29 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1427,7 +1427,8 @@ impl<'self> StrSlice<'self> for &'self str { fn slice_chars(&self, begin: uint, end: uint) -> &'self str { assert!(begin <= end); // not sure how to use the iterators for this nicely. - let mut (position, count) = (0, 0); + let mut position = 0; + let mut count = 0; let l = self.len(); while count < begin && position < l { position = self.char_range_at(position).next; @@ -1575,7 +1576,8 @@ impl<'self> StrSlice<'self> for &'self str { * The original string with all occurances of `from` replaced with `to` */ pub fn replace(&self, from: &str, to: &str) -> ~str { - let mut (result, last_end) = (~"", 0); + let mut result = ~""; + let mut last_end = 0; for self.matches_index_iter(from).advance |(start, end)| { result.push_str(unsafe{raw::slice_bytes(*self, last_end, start)}); result.push_str(to); diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 8e1276d52d1d..3044cd50b344 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -98,7 +98,7 @@ impl gen_send for message { } body.push_str(fmt!("let message = %s(%s);\n", name, - vec::append_one(arg_names.map(|x| cx.str_of(*x)), ~"s") + vec::append_one(arg_names.map(|x| cx.str_of(*x)), @"s") .connect(", "))); if !try { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 64bdfd4a4d33..f1b5c4d16be9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -378,7 +378,7 @@ impl Parser { self.fatal( fmt!( "expected `%s`, found `%s`", - *self.id_to_str(kw.to_ident()), + self.id_to_str(kw.to_ident()).to_str(), self.this_token_to_str() ) ); From e015bee2866a802f17c84bd6d3a06212945a9d17 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 18 Jun 2013 09:39:16 -0700 Subject: [PATCH 244/336] Rewrite each_path to allow performance improvements in the future. Instead of determining paths from the path tag, we iterate through modules' children recursively in the metadata. This will allow for lazy external module resolution. --- src/libextra/sync.rs | 2 +- src/librustc/metadata/common.rs | 4 + src/librustc/metadata/csearch.rs | 16 +- src/librustc/metadata/decoder.rs | 321 +++++++++++++++++------- src/librustc/metadata/encoder.rs | 210 ++++++++++++---- src/librustc/middle/reachable.rs | 69 +++-- src/librustc/middle/resolve.rs | 22 +- src/librustc/middle/trans/base.rs | 21 +- src/librustc/middle/trans/common.rs | 79 +----- src/librustc/middle/trans/context.rs | 16 +- src/librustc/middle/typeck/check/mod.rs | 2 + src/librustc/middle/typeck/coherence.rs | 150 +++++------ src/libstd/char.rs | 1 + src/libstd/os.rs | 6 +- src/libstd/rand.rs | 1 + src/libstd/str.rs | 21 +- src/libstd/unstable/extfmt.rs | 1 + 17 files changed, 578 insertions(+), 364 deletions(-) diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 56168f923ad7..3908b61381b7 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -381,7 +381,7 @@ impl Sem<~[Waitqueue]> { // The only other places that condvars get built are rwlock.write_cond() // and rwlock_write_mode. pub fn access_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { - do self.access { + do self.access_waitqueue { blk(&Condvar { sem: self, order: Nothing }) } } diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index f487c73372fa..e7725436f2b4 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -176,6 +176,10 @@ pub static tag_item_method_tps: uint = 0x7b; pub static tag_item_method_fty: uint = 0x7c; pub static tag_item_method_transformed_self_ty: uint = 0x7d; +pub static tag_mod_child: uint = 0x7e; +pub static tag_misc_info: uint = 0x7f; +pub static tag_misc_info_crate_items: uint = 0x80; + pub struct LinkMeta { name: @str, vers: @str, diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index bfc5d512b370..4ede9f96f1f4 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -97,18 +97,14 @@ pub fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id) return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx) } -pub fn get_impls_for_mod(cstore: @mut cstore::CStore, def: ast::def_id, - name: Option) - -> @~[@resolve::Impl] { - let cdata = cstore::get_crate_data(cstore, def.crate); - do decoder::get_impls_for_mod(cstore.intr, cdata, def.node, name) |cnum| { - cstore::get_crate_data(cstore, cnum) - } +/// Returns information about the given implementation. +pub fn get_impl(cstore: @mut cstore::CStore, impl_def_id: ast::def_id) + -> resolve::Impl { + let cdata = cstore::get_crate_data(cstore, impl_def_id.crate); + decoder::get_impl(cstore.intr, cdata, impl_def_id.node) } -pub fn get_method(tcx: ty::ctxt, - def: ast::def_id) -> ty::Method -{ +pub fn get_method(tcx: ty::ctxt, def: ast::def_id) -> ty::Method { let cdata = cstore::get_crate_data(tcx.cstore, def.crate); decoder::get_method(tcx.cstore.intr, cdata, def.node, tcx) } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b11badd65cc8..2ebaa2b739fc 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -458,64 +458,192 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool { return true; } -/// Iterates over all the paths in the given crate. -pub fn each_path(intr: @ident_interner, - cdata: cmd, - get_crate_data: GetCrateDataCb, - f: &fn(&str, def_like, ast::visibility) -> bool) - -> bool { - // FIXME #4572: This function needs to be nuked, as it's impossible to make fast. - // It's the source of most of the performance problems when compiling small crates. +struct EachItemContext<'self> { + intr: @ident_interner, + cdata: cmd, + get_crate_data: GetCrateDataCb<'self>, + path_builder: &'self mut ~str, + callback: &'self fn(&str, def_like, ast::visibility) -> bool, +} - let root = reader::Doc(cdata.data); - let items = reader::get_doc(root, tag_items); - let items_data = reader::get_doc(items, tag_items_data); +impl<'self> EachItemContext<'self> { + // Pushes the given name and returns the old length. + fn push_name(&mut self, string: &str) -> uint { + let path_len = self.path_builder.len(); + if path_len != 0 { + self.path_builder.push_str("::") + } + self.path_builder.push_str(string); + path_len + } - // First, go through all the explicit items. - for reader::tagged_docs(items_data, tag_items_data_item) |item_doc| { - let path = ast_map::path_to_str(item_path(item_doc), intr); - let path_is_empty = path.is_empty(); - if !path_is_empty { - // Extract the def ID. - let def_id = item_def_id(item_doc, cdata); + // Pops the given name. + fn pop_name(&mut self, old_len: uint) { + // XXX(pcwalton): There's no safe function to do this. :( + unsafe { + str::raw::set_len(self.path_builder, old_len) + } + } - // Construct the def for this item. - debug!("(each_path) yielding explicit item: %s", path); - let def_like = item_to_def_like(item_doc, def_id, cdata.cnum); - - let vis = item_visibility(item_doc); - - // Hand the information off to the iteratee. - if !f(path, def_like, vis) { - return false; + fn process_item_and_pop_name(&mut self, + doc: ebml::Doc, + def_id: ast::def_id, + old_len: uint) + -> bool { + let def_like = item_to_def_like(doc, def_id, self.cdata.cnum); + match def_like { + dl_def(def) => { + debug!("(iterating over each item of a module) processing \ + `%s` (def %?)", + *self.path_builder, + def); + } + _ => { + debug!("(iterating over each item of a module) processing \ + `%s` (%d:%d)", + *self.path_builder, + def_id.crate, + def_id.node); } } - // If this is a module, find the reexports. - for each_reexport(item_doc) |reexport_doc| { - let def_id_doc = - reader::get_doc(reexport_doc, - tag_items_data_item_reexport_def_id); - let def_id = reader::with_doc_data(def_id_doc, parse_def_id); - let def_id = translate_def_id(cdata, def_id); + let vis = item_visibility(doc); - let reexport_name_doc = - reader::get_doc(reexport_doc, - tag_items_data_item_reexport_name); - let reexport_name = reexport_name_doc.as_str_slice(); + let mut continue = (self.callback)(*self.path_builder, def_like, vis); - let reexport_path; - if path_is_empty { - reexport_path = reexport_name.to_owned(); - } else { - reexport_path = path + "::" + reexport_name; + let family = item_family(doc); + if family == ForeignMod { + // These are unnamed; pop the name now. + self.pop_name(old_len) + } + + if continue { + // Recurse if necessary. + match family { + Mod | ForeignMod | Trait | Impl => { + continue = self.each_item_of_module(def_id); + } + Freeze | Struct | UnsafeFn | Fn | PureFn | ForeignFn | + UnsafeStaticMethod | StaticMethod | PureStaticMethod | Type | + ForeignType | Variant | Enum | PublicField | PrivateField | + InheritedField => {} } + } - // This reexport may be in yet another crate - let other_crates_items = if def_id.crate == cdata.cnum { - items + if family != ForeignMod { + self.pop_name(old_len) + } + + continue + } + + fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool { + // This item might not be in this crate. If it's not, look it up. + let (cdata, items) = if def_id.crate == self.cdata.cnum { + let items = reader::get_doc(reader::Doc(self.cdata.data), + tag_items); + (self.cdata, items) + } else { + let crate_data = (self.get_crate_data)(def_id.crate); + let root = reader::Doc(crate_data.data); + (crate_data, reader::get_doc(root, tag_items)) + }; + + // Look up the item. + let item_doc = match maybe_find_item(def_id.node, items) { + None => return false, + Some(item_doc) => item_doc, + }; + + self.each_child_of_module_or_crate(item_doc) + } + + fn each_child_of_module_or_crate(&mut self, item_doc: ebml::Doc) -> bool { + let mut continue = true; + + // Iterate over all children. + for reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| { + let child_def_id = reader::with_doc_data(child_info_doc, + parse_def_id); + let child_def_id = translate_def_id(self.cdata, child_def_id); + + // This item may be in yet another crate, if it was the child of + // a reexport. + let other_crates_items = if child_def_id.crate == + self.cdata.cnum { + reader::get_doc(reader::Doc(self.cdata.data), tag_items) } else { - let crate_data = get_crate_data(def_id.crate); + let crate_data = (self.get_crate_data)(child_def_id.crate); + let root = reader::Doc(crate_data.data); + reader::get_doc(root, tag_items) + }; + + debug!("(iterating over each item of a module) looking up item \ + %d:%d in `%s`, crate %d", + child_def_id.crate, + child_def_id.node, + *self.path_builder, + self.cdata.cnum); + + // Get the item. + match maybe_find_item(child_def_id.node, other_crates_items) { + None => {} + Some(child_item_doc) => { + // Push the name. + let child_name = item_name(self.intr, child_item_doc); + debug!("(iterating over each item of a module) pushing \ + name `%s` onto `%s`", + token::ident_to_str(&child_name), + *self.path_builder); + let old_len = + self.push_name(token::ident_to_str(&child_name)); + + // Process this item. + continue = self.process_item_and_pop_name(child_item_doc, + child_def_id, + old_len); + + if !continue { + break + } + } + } + } + + if !continue { + return false + } + + // Iterate over reexports. + for each_reexport(item_doc) |reexport_doc| { + let def_id_doc = reader::get_doc( + reexport_doc, + tag_items_data_item_reexport_def_id); + let orig_def_id = reader::with_doc_data(def_id_doc, parse_def_id); + + // NB: was "cdata" + let def_id = translate_def_id(self.cdata, orig_def_id); + + let name_doc = reader::get_doc(reexport_doc, + tag_items_data_item_reexport_name); + let name = name_doc.as_str_slice(); + + // Push the name. + debug!("(iterating over each item of a module) pushing \ + reexported name `%s` onto `%s` (crate %d, orig %d, \ + in crate %d)", + name, + *self.path_builder, + def_id.crate, + orig_def_id.crate, + self.cdata.cnum); + let old_len = self.push_name(name); + + // This reexport may be in yet another crate. + let other_crates_items = if def_id.crate == self.cdata.cnum { + reader::get_doc(reader::Doc(self.cdata.data), tag_items) + } else { + let crate_data = (self.get_crate_data)(def_id.crate); let root = reader::Doc(crate_data.data); reader::get_doc(root, tag_items) }; @@ -523,29 +651,53 @@ pub fn each_path(intr: @ident_interner, // Get the item. match maybe_find_item(def_id.node, other_crates_items) { None => {} - Some(item_doc) => { - // Construct the def for this item. - let def_like = item_to_def_like(item_doc, - def_id, - cdata.cnum); - - // Hand the information off to the iteratee. - debug!("(each_path) yielding reexported \ - item: %s", reexport_path); - - if (!f(reexport_path, def_like, ast::public)) { - return false; - } + Some(reexported_item_doc) => { + continue = self.process_item_and_pop_name( + reexported_item_doc, + def_id, + old_len); } } - } - } - return true; + if !continue { + break + } + } + + continue + } } -pub fn get_item_path(cdata: cmd, id: ast::node_id) - -> ast_map::path { +/// Iterates over all the paths in the given crate. +pub fn each_path(intr: @ident_interner, + cdata: cmd, + get_crate_data: GetCrateDataCb, + f: &fn(&str, def_like, ast::visibility) -> bool) + -> bool { + // FIXME #4572: This function needs to be nuked, as it's impossible to + // make fast. It's the source of most of the performance problems when + // compiling small crates. + + let root_doc = reader::Doc(cdata.data); + let misc_info_doc = reader::get_doc(root_doc, tag_misc_info); + let crate_items_doc = reader::get_doc(misc_info_doc, + tag_misc_info_crate_items); + + let mut path_builder = ~""; + + let mut context = EachItemContext { + intr: intr, + cdata: cdata, + get_crate_data: get_crate_data, + path_builder: &mut path_builder, + callback: f, + }; + + // Iterate over all top-level crate items. + context.each_child_of_module_or_crate(crate_items_doc) +} + +pub fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path { item_path(lookup_item(id, cdata.data)) } @@ -661,35 +813,20 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc, rslt } -pub fn get_impls_for_mod(intr: @ident_interner, - cdata: cmd, - m_id: ast::node_id, - name: Option, - get_cdata: &fn(ast::crate_num) -> cmd) - -> @~[@resolve::Impl] { +/// Returns information about the given implementation. +pub fn get_impl(intr: @ident_interner, cdata: cmd, impl_id: ast::node_id) + -> resolve::Impl { let data = cdata.data; - let mod_item = lookup_item(m_id, data); - let mut result = ~[]; - for reader::tagged_docs(mod_item, tag_mod_impl) |doc| { - let did = reader::with_doc_data(doc, parse_def_id); - let local_did = translate_def_id(cdata, did); - debug!("(get impls for mod) getting did %? for '%?'", - local_did, name); - // The impl may be defined in a different crate. Ask the caller - // to give us the metadata - let impl_cdata = get_cdata(local_did.crate); - let impl_data = impl_cdata.data; - let item = lookup_item(local_did.node, impl_data); - let nm = item_name(intr, item); - if match name { Some(n) => { n == nm } None => { true } } { - let base_tps = item_ty_param_count(item); - result.push(@resolve::Impl { - did: local_did, ident: nm, - methods: item_impl_methods(intr, impl_cdata, item, base_tps) - }); - }; + let impl_item = lookup_item(impl_id, data); + let base_tps = item_ty_param_count(impl_item); + resolve::Impl { + did: ast::def_id { + crate: cdata.cnum, + node: impl_id, + }, + ident: item_name(intr, impl_item), + methods: item_impl_methods(intr, cdata, impl_item, base_tps), } - @result } pub fn get_method_name_and_explicit_self( diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5ff52b1859ad..187f2a99ed4c 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -22,7 +22,7 @@ use middle; use util::ppaux::ty_to_str; use core::hash::HashUtil; -use core::hashmap::HashMap; +use core::hashmap::{HashMap, HashSet}; use core::int; use core::io; use core::str; @@ -64,7 +64,8 @@ pub struct EncodeParams<'self> { discrim_symbols: &'self HashMap, link_meta: &'self LinkMeta, cstore: @mut cstore::CStore, - encode_inlined_item: encode_inlined_item<'self> + encode_inlined_item: encode_inlined_item<'self>, + reachable: @mut HashSet, } struct Stats { @@ -73,6 +74,7 @@ struct Stats { dep_bytes: uint, lang_item_bytes: uint, link_args_bytes: uint, + misc_bytes: uint, item_bytes: uint, index_bytes: uint, zero_bytes: uint, @@ -91,7 +93,8 @@ pub struct EncodeContext<'self> { link_meta: &'self LinkMeta, cstore: &'self cstore::CStore, encode_inlined_item: encode_inlined_item<'self>, - type_abbrevs: abbrev_map + type_abbrevs: abbrev_map, + reachable: @mut HashSet, } pub fn reachable(ecx: &EncodeContext, id: node_id) -> bool { @@ -470,45 +473,50 @@ fn encode_reexported_static_methods(ecx: &EncodeContext, } } -fn encode_info_for_mod(ecx: &EncodeContext, - ebml_w: &mut writer::Encoder, - md: &_mod, - id: node_id, - path: &[ast_map::path_elt], - name: ident) { - ebml_w.start_tag(tag_items_data_item); - encode_def_id(ebml_w, local_def(id)); - encode_family(ebml_w, 'm'); - encode_name(ecx, ebml_w, name); - debug!("(encoding info for module) encoding info for module ID %d", id); - - // Encode info about all the module children. - for md.items.iter().advance |item| { - match item.node { - item_impl(*) => { - let (ident, did) = (item.ident, item.id); - debug!("(encoding info for module) ... encoding impl %s \ - (%?/%?)", - ecx.tcx.sess.str_of(ident), - did, - ast_map::node_id_to_str(ecx.tcx.items, did, token::get_ident_interner())); - - ebml_w.start_tag(tag_mod_impl); - ebml_w.wr_str(def_to_str(local_def(did))); - ebml_w.end_tag(); +/// Iterates through "auxiliary node IDs", which are node IDs that describe +/// top-level items that are sub-items of the given item. Specifically: +/// +/// * For enums, iterates through the node IDs of the variants. +/// +/// * For newtype structs, iterates through the node ID of the constructor. +fn each_auxiliary_node_id(item: @item, callback: &fn(node_id) -> bool) + -> bool { + let mut continue = true; + match item.node { + item_enum(ref enum_def, _) => { + for enum_def.variants.each |variant| { + continue = callback(variant.node.id); + if !continue { + break + } } - _ => {} // FIXME #4573: Encode these too. } + item_struct(struct_def, _) => { + // If this is a newtype struct, return the constructor. + match struct_def.ctor_id { + Some(ctor_id) if struct_def.fields.len() > 0 && + struct_def.fields[0].node.kind == + ast::unnamed_field => { + continue = callback(ctor_id); + } + _ => {} + } + } + _ => {} } - encode_path(ecx, ebml_w, path, ast_map::path_mod(name)); + continue +} - // Encode the reexports of this module. +fn encode_reexports(ecx: &EncodeContext, + ebml_w: &mut writer::Encoder, + id: node_id, + path: &[ast_map::path_elt]) { debug!("(encoding info for module) encoding reexports for %d", id); match ecx.reexports2.find(&id) { Some(ref exports) => { debug!("(encoding info for module) found reexports for %d", id); - for exports.iter().advance |exp| { + for exports.each |exp| { debug!("(encoding info for module) reexport '%s' for %d", exp.name, id); ebml_w.start_tag(tag_items_data_item_reexport); @@ -527,6 +535,57 @@ fn encode_info_for_mod(ecx: &EncodeContext, id); } } +} + +fn encode_info_for_mod(ecx: &EncodeContext, + ebml_w: &mut writer::Encoder, + md: &_mod, + id: node_id, + path: &[ast_map::path_elt], + name: ident, + vis: visibility) { + ebml_w.start_tag(tag_items_data_item); + encode_def_id(ebml_w, local_def(id)); + encode_family(ebml_w, 'm'); + encode_name(ecx, ebml_w, name); + debug!("(encoding info for module) encoding info for module ID %d", id); + + // Encode info about all the module children. + for md.items.iter().advance |item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(item.id))); + ebml_w.end_tag(); + + for each_auxiliary_node_id(*item) |auxiliary_node_id| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id))); + ebml_w.end_tag(); + } + + match item.node { + item_impl(*) => { + let (ident, did) = (item.ident, item.id); + debug!("(encoding info for module) ... encoding impl %s \ + (%?/%?)", + ecx.tcx.sess.str_of(ident), + did, + ast_map::node_id_to_str(ecx.tcx.items, did, token::get_ident_interner())); + + ebml_w.start_tag(tag_mod_impl); + ebml_w.wr_str(def_to_str(local_def(did))); + ebml_w.end_tag(); + } + _ => {} + } + } + + encode_path(ecx, ebml_w, path, ast_map::path_mod(name)); + + // Encode the reexports of this module, if this module is public. + if vis == public { + debug!("(encoding info for module) encoding reexports for %d", id); + encode_reexports(ecx, ebml_w, id, path); + } ebml_w.end_tag(); } @@ -799,6 +858,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); + encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); ebml_w.end_tag(); @@ -811,6 +871,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let tps_len = generics.ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); + encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); encode_attributes(ebml_w, item.attrs); if tps_len > 0u || should_inline(item.attrs) { @@ -822,15 +883,29 @@ fn encode_info_for_item(ecx: &EncodeContext, } item_mod(ref m) => { add_to_index(); - encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident); + encode_info_for_mod(ecx, + ebml_w, + m, + item.id, + path, + item.ident, + item.vis); } - item_foreign_mod(_) => { + item_foreign_mod(ref fm) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); encode_family(ebml_w, 'n'); encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); + + // Encode all the items in this module. + for fm.items.each |foreign_item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(foreign_item.id))); + ebml_w.end_tag(); + } + ebml_w.end_tag(); } item_ty(_, ref generics) => { @@ -998,6 +1073,10 @@ fn encode_info_for_item(ecx: &EncodeContext, ebml_w.start_tag(tag_item_trait_method); encode_def_id(ebml_w, method_def_id); ebml_w.end_tag(); + + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(method_def_id)); + ebml_w.end_tag(); } encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); for super_traits.iter().advance |ast_trait_ref| { @@ -1091,6 +1170,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_family(ebml_w, purity_fn_family(purity)); encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); + encode_name(ecx, ebml_w, nitem.ident); if abi.is_intrinsic() { (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem)); } else { @@ -1107,6 +1187,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); + encode_name(ecx, ebml_w, nitem.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident)); } } @@ -1120,9 +1201,13 @@ fn encode_info_for_items(ecx: &EncodeContext, let index = @mut ~[]; ebml_w.start_tag(tag_items_data); index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() }); - encode_info_for_mod(ecx, ebml_w, &crate.node.module, - crate_node_id, [], - syntax::parse::token::special_idents::invalid); + encode_info_for_mod(ecx, + ebml_w, + &crate.node.module, + crate_node_id, + [], + syntax::parse::token::special_idents::invalid, + public); let items = ecx.tcx.items; // See comment in `encode_side_tables_for_ii` in astencode @@ -1416,6 +1501,30 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.end_tag(); } +fn encode_misc_info(ecx: &EncodeContext, + crate: &crate, + ebml_w: &mut writer::Encoder) { + ebml_w.start_tag(tag_misc_info); + ebml_w.start_tag(tag_misc_info_crate_items); + for crate.node.module.items.each |&item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(item.id))); + ebml_w.end_tag(); + + for each_auxiliary_node_id(item) |auxiliary_node_id| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id))); + ebml_w.end_tag(); + } + } + + // Encode reexports for the root module. + encode_reexports(ecx, ebml_w, 0, []); + + ebml_w.end_tag(); + ebml_w.end_tag(); +} + fn encode_crate_dep(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, dep: decoder::crate_dep) { @@ -1455,15 +1564,25 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { dep_bytes: 0, lang_item_bytes: 0, link_args_bytes: 0, + misc_bytes: 0, item_bytes: 0, index_bytes: 0, zero_bytes: 0, total_bytes: 0, n_inlines: 0 }; - let EncodeParams{item_symbols, diag, tcx, reexports2, - discrim_symbols, cstore, encode_inlined_item, - link_meta, _} = parms; + let EncodeParams { + item_symbols, + diag, + tcx, + reexports2, + discrim_symbols, + cstore, + encode_inlined_item, + link_meta, + reachable, + _ + } = parms; let type_abbrevs = @mut HashMap::new(); let stats = @mut stats; let ecx = EncodeContext { @@ -1476,7 +1595,8 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { link_meta: link_meta, cstore: cstore, encode_inlined_item: encode_inlined_item, - type_abbrevs: type_abbrevs + type_abbrevs: type_abbrevs, + reachable: reachable, }; let mut ebml_w = writer::Encoder(wr as @io::Writer); @@ -1502,6 +1622,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { encode_link_args(&ecx, &mut ebml_w); ecx.stats.link_args_bytes = *wr.pos - i; + // Encode miscellaneous info. + i = *wr.pos; + encode_misc_info(&ecx, crate, &mut ebml_w); + ecx.stats.misc_bytes = *wr.pos - i; + // Encode and index the items. ebml_w.start_tag(tag_items); i = *wr.pos; @@ -1529,6 +1654,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { io::println(fmt!(" dep bytes: %u", ecx.stats.dep_bytes)); io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes)); io::println(fmt!(" link args bytes: %u", ecx.stats.link_args_bytes)); + io::println(fmt!(" misc bytes: %u", ecx.stats.misc_bytes)); io::println(fmt!(" item bytes: %u", ecx.stats.item_bytes)); io::println(fmt!(" index bytes: %u", ecx.stats.index_bytes)); io::println(fmt!(" zero bytes: %u", ecx.stats.zero_bytes)); diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 106c1d85cd77..12ddd3710458 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -77,6 +77,15 @@ fn trait_method_might_be_inlined(trait_method: &trait_method) -> bool { } } +// The context we're in. If we're in a public context, then public symbols are +// marked reachable. If we're in a private context, then only trait +// implementations are marked reachable. +#[deriving(Eq)] +enum PrivacyContext { + PublicContext, + PrivateContext, +} + // Information needed while computing reachability. struct ReachableContext { // The type context. @@ -109,25 +118,31 @@ impl ReachableContext { let reachable_symbols = self.reachable_symbols; let worklist = self.worklist; let visitor = visit::mk_vt(@Visitor { - visit_item: |item, (_, visitor)| { + visit_item: |item, (privacy_context, visitor): + (PrivacyContext, visit::vt)| { match item.node { item_fn(*) => { - reachable_symbols.insert(item.id); + if privacy_context == PublicContext { + reachable_symbols.insert(item.id); + } if item_might_be_inlined(item) { worklist.push(item.id) } } item_struct(ref struct_def, _) => { match struct_def.ctor_id { - None => {} - Some(ctor_id) => { + Some(ctor_id) if + privacy_context == PublicContext => { reachable_symbols.insert(ctor_id); } + Some(_) | None => {} } } item_enum(ref enum_def, _) => { - for enum_def.variants.each |variant| { - reachable_symbols.insert(variant.node.id); + if privacy_context == PublicContext { + for enum_def.variants.each |variant| { + reachable_symbols.insert(variant.node.id); + } } } item_impl(ref generics, trait_ref, _, ref methods) => { @@ -137,9 +152,15 @@ impl ReachableContext { // treating implementations of reachable or cross- // crate traits as reachable. + let should_be_considered_public = |method: @method| { + (method.vis == public && + privacy_context == PublicContext) || + trait_ref.is_some() + }; + // Mark all public methods as reachable. - for methods.each |method| { - if method.vis == public || trait_ref.is_some() { + for methods.each |&method| { + if should_be_considered_public(method) { reachable_symbols.insert(method.id); } } @@ -147,9 +168,8 @@ impl ReachableContext { if generics_require_inlining(generics) { // If the impl itself has generics, add all public // symbols to the worklist. - for methods.each |method| { - if method.vis == public || - trait_ref.is_some() { + for methods.each |&method| { + if should_be_considered_public(method) { worklist.push(method.id) } } @@ -161,8 +181,7 @@ impl ReachableContext { let attrs = &method.attrs; if generics_require_inlining(generics) || attributes_specify_inlining(*attrs) || - method.vis == public || - trait_ref.is_some() { + should_be_considered_public(*method) { worklist.push(method.id) } } @@ -170,27 +189,31 @@ impl ReachableContext { } item_trait(_, _, ref trait_methods) => { // Mark all provided methods as reachable. - for trait_methods.each |trait_method| { - match *trait_method { - provided(method) => { - reachable_symbols.insert(method.id); - worklist.push(method.id) + if privacy_context == PublicContext { + for trait_methods.each |trait_method| { + match *trait_method { + provided(method) => { + reachable_symbols.insert(method.id); + worklist.push(method.id) + } + required(_) => {} } - required(_) => {} } } } _ => {} } - if item.vis == public { - visit::visit_item(item, ((), visitor)) + if item.vis == public && privacy_context == PublicContext { + visit::visit_item(item, (PublicContext, visitor)) + } else { + visit::visit_item(item, (PrivateContext, visitor)) } }, .. *visit::default_visitor() }); - visit::visit_crate(crate, ((), visitor)) + visit::visit_crate(crate, (PublicContext, visitor)) } // Returns true if the given def ID represents a local item that is @@ -247,7 +270,7 @@ impl ReachableContext { } } Some(_) => false, - None => tcx.sess.bug("def ID not in def map?!"), + None => false // This will happen for default methods. } } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 7cf13c671b21..17c984c8a33c 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -654,7 +654,17 @@ impl NameBindings { Some(ref type_def) => { match (*type_def).type_def { Some(type_def) => Some(type_def), - None => None, + None => { + match type_def.module_def { + Some(module) => { + match module.def_id { + Some(did) => Some(def_mod(did)), + None => None, + } + } + None => None, + } + } } } } @@ -3149,12 +3159,14 @@ impl Resolver { Some(def_id) if def_id.crate == local_crate => { // OK. Continue. debug!("(recording exports for module subtree) recording \ - exports for local module"); + exports for local module `%s`", + self.module_to_str(module_)); } None => { // Record exports for the root module. debug!("(recording exports for module subtree) recording \ - exports for root module"); + exports for root module `%s`", + self.module_to_str(module_)); } Some(_) => { // Bail out. @@ -5037,6 +5049,9 @@ impl Resolver { self.trait_map.insert(expr.id, @mut traits); } expr_method_call(_, _, ident, _, _, _) => { + debug!("(recording candidate traits for expr) recording \ + traits for %d", + expr.id); let traits = self.search_for_traits_containing_method(ident); self.trait_map.insert(expr.id, @mut traits); } @@ -5112,7 +5127,6 @@ impl Resolver { debug!("(searching for traits containing method) looking for '%s'", self.session.str_of(name)); - let mut found_traits = ~[]; let mut search_module = self.current_module; match self.method_map.find(&name) { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 661b19480e05..df7f73a52436 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -64,7 +64,7 @@ use util::ppaux::{Repr, ty_to_str}; use middle::trans::type_::Type; use core::hash; -use core::hashmap::{HashMap}; +use core::hashmap::{HashMap, HashSet}; use core::int; use core::io; use core::libc::c_uint; @@ -2509,7 +2509,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { variant)) } }; - if !exprt { + if !exprt && !ccx.reachable.contains(&id) { lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage); } ccx.item_vals.insert(id, val); @@ -2816,13 +2816,13 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_ encoder::EncodeParams { diag: diag, tcx: cx.tcx, - reachable: cx.reachable, reexports2: cx.exp_map2, item_symbols: item_symbols, discrim_symbols: discrim_symbols, link_meta: link_meta, cstore: cx.sess.cstore, - encode_inlined_item: ie + encode_inlined_item: ie, + reachable: cx.reachable, } } @@ -2890,7 +2890,7 @@ pub fn trans_crate(sess: session::Session, emap2: resolve::ExportMap2, reachable_map: @mut HashSet, maps: astencode::Maps) - -> (ModuleRef, LinkMeta) { + -> (ContextRef, ModuleRef, LinkMeta) { let mut symbol_hasher = hash::default_state(); let link_meta = link::build_link_meta(sess, crate, output, &mut symbol_hasher); @@ -2911,8 +2911,15 @@ pub fn trans_crate(sess: session::Session, // sess.bug("couldn't enable multi-threaded LLVM"); // } - let ccx = @mut CrateContext::new(sess, llmod_id, tcx, emap2, maps, - symbol_hasher, link_meta, reachable); + let ccx = @mut CrateContext::new(sess, + llmod_id, + tcx, + emap2, + maps, + symbol_hasher, + link_meta, + reachable_map); + { let _icx = push_ctxt("data"); trans_constants(ccx, crate); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 04bce4c02a81..a7ffa8e13b02 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -117,84 +117,7 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res { } } -pub type ExternMap = @mut HashMap<@str, ValueRef>; - -// Crate context. Every crate we compile has one of these. -pub struct CrateContext { - sess: session::Session, - llmod: ModuleRef, - td: TargetData, - tn: @TypeNames, - externs: ExternMap, - intrinsics: HashMap<&'static str, ValueRef>, - item_vals: @mut HashMap, - exp_map2: resolve::ExportMap2, - item_symbols: @mut HashMap, - link_meta: LinkMeta, - enum_sizes: @mut HashMap, - discrims: @mut HashMap, - discrim_symbols: @mut HashMap, - tydescs: @mut HashMap, - // Set when running emit_tydescs to enforce that no more tydescs are - // created. - finished_tydescs: @mut bool, - // Track mapping of external ids to local items imported for inlining - external: @mut HashMap>, - // Cache instances of monomorphized functions - monomorphized: @mut HashMap, - monomorphizing: @mut HashMap, - // Cache computed type parameter uses (see type_use.rs) - type_use_cache: @mut HashMap, - // Cache generated vtables - vtables: @mut HashMap, - // Cache of constant strings, - const_cstr_cache: @mut HashMap<@str, ValueRef>, - - // Reverse-direction for const ptrs cast from globals. - // Key is an int, cast from a ValueRef holding a *T, - // Val is a ValueRef holding a *[T]. - // - // Needed because LLVM loses pointer->pointee association - // when we ptrcast, and we have to ptrcast during translation - // of a [T] const because we form a slice, a [*T,int] pair, not - // a pointer to an LLVM array type. - const_globals: @mut HashMap, - - // Cache of emitted const values - const_values: @mut HashMap, - - // Cache of external const values - extern_const_values: @mut HashMap, - - module_data: @mut HashMap<~str, ValueRef>, - lltypes: @mut HashMap, - llsizingtypes: @mut HashMap, - adt_reprs: @mut HashMap, - names: namegen, - next_addrspace: addrspace_gen, - symbol_hasher: @mut hash::State, - type_hashcodes: @mut HashMap, - type_short_names: @mut HashMap, - all_llvm_symbols: @mut HashSet<@str>, - tcx: ty::ctxt, - maps: astencode::Maps, - stats: @mut Stats, - upcalls: @upcall::Upcalls, - tydesc_type: TypeRef, - int_type: TypeRef, - float_type: TypeRef, - opaque_vec_type: TypeRef, - builder: BuilderRef_res, - shape_cx: shape::Ctxt, - crate_map: ValueRef, - // Set when at least one function uses GC. Needed so that - // decl_gc_metadata knows whether to link to the module metadata, which - // is not emitted by LLVM's GC pass when no functions use GC. - uses_gc: @mut bool, - dbg_cx: Option, - do_not_commit_warning_issued: @mut bool, - reachable_map: @mut HashSet, -} +pub type ExternMap = HashMap<@str, ValueRef>; // Types used for llself. pub struct ValSelfData { diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 7046c8b9f41b..9b81fc406b7c 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -21,7 +21,6 @@ use middle::resolve; use middle::trans::adt; use middle::trans::base; use middle::trans::debuginfo; -use middle::trans::reachable; use middle::trans::type_use; use middle::ty; @@ -48,7 +47,7 @@ pub struct CrateContext { intrinsics: HashMap<&'static str, ValueRef>, item_vals: HashMap, exp_map2: resolve::ExportMap2, - reachable: reachable::map, + reachable: @mut HashSet, item_symbols: HashMap, link_meta: LinkMeta, enum_sizes: HashMap, @@ -115,10 +114,15 @@ pub struct CrateContext { } impl CrateContext { - pub fn new(sess: session::Session, name: &str, tcx: ty::ctxt, - emap2: resolve::ExportMap2, maps: astencode::Maps, - symbol_hasher: hash::State, link_meta: LinkMeta, - reachable: reachable::map) -> CrateContext { + pub fn new(sess: session::Session, + name: &str, + tcx: ty::ctxt, + emap2: resolve::ExportMap2, + maps: astencode::Maps, + symbol_hasher: hash::State, + link_meta: LinkMeta, + reachable: @mut HashSet) + -> CrateContext { unsafe { let llcx = llvm::LLVMContextCreate(); set_task_llcx(llcx); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index d224d182950d..4c1c8e5c2c8a 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1393,6 +1393,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, method_map.insert(expr.id, (*entry)); } None => { + debug!("(checking method call) failing expr is %d", expr.id); + fcx.type_error_message(expr.span, |actual| { fmt!("type `%s` does not implement any method in scope \ diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index c3abf47f9e29..9de7315d0e71 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -17,7 +17,7 @@ use core::prelude::*; use metadata::csearch::{each_path, get_impl_trait}; -use metadata::csearch::{get_impls_for_mod}; +use metadata::csearch; use metadata::cstore::{CStore, iter_crate_data}; use metadata::decoder::{dl_def, dl_field, dl_impl}; use middle::resolve::{Impl, MethodInfo}; @@ -855,92 +855,67 @@ impl CoherenceChecker { // External crate handling - pub fn add_impls_for_module(&self, - impls_seen: &mut HashSet, - crate_store: @mut CStore, - module_def_id: def_id) { - let implementations = get_impls_for_mod(crate_store, - module_def_id, - None); - for implementations.iter().advance |implementation| { - debug!("coherence: adding impl from external crate: %s", - ty::item_path_str(self.crate_context.tcx, - implementation.did)); + pub fn add_external_impl(&self, + impls_seen: &mut HashSet, + crate_store: @mut CStore, + impl_def_id: def_id) { + let implementation = csearch::get_impl(crate_store, impl_def_id); - // Make sure we don't visit the same implementation - // multiple times. - if !impls_seen.insert(implementation.did) { - // Skip this one. - loop; - } - // Good. Continue. + debug!("coherence: adding impl from external crate: %s", + ty::item_path_str(self.crate_context.tcx, implementation.did)); - let self_type = lookup_item_type(self.crate_context.tcx, - implementation.did); - let associated_traits = get_impl_trait(self.crate_context.tcx, - implementation.did); + // Make sure we don't visit the same implementation multiple times. + if !impls_seen.insert(implementation.did) { + // Skip this one. + return + } + // Good. Continue. - // Do a sanity check to make sure that inherent methods have base - // types. - - if associated_traits.is_none() { - match get_base_type_def_id(self.inference_context, - dummy_sp(), - self_type.ty) { - None => { - let session = self.crate_context.tcx.sess; - session.bug(fmt!( - "no base type for external impl \ - with no trait: %s (type %s)!", - session.str_of(implementation.ident), - ty_to_str(self.crate_context.tcx,self_type.ty))); - } - Some(_) => { - // Nothing to do. - } - } - } - - let mut implementation = *implementation; - - // Record all the trait methods. - for associated_traits.iter().advance |trait_ref| { - self.instantiate_default_methods(implementation.did, - &**trait_ref); - // Could we avoid these copies when we don't need them? - let mut methods = /*bad?*/ copy implementation.methods; - self.add_provided_methods_to_impl( - &mut methods, - &trait_ref.def_id, - &implementation.did); - implementation = @Impl { methods: methods, - .. *implementation }; - - - self.add_trait_method(trait_ref.def_id, implementation); - } - - // Add the implementation to the mapping from - // implementation to base type def ID, if there is a base - // type for this implementation. + let self_type = lookup_item_type(self.crate_context.tcx, + implementation.did); + let associated_traits = get_impl_trait(self.crate_context.tcx, + implementation.did); + // Do a sanity check to make sure that inherent methods have base + // types. + if associated_traits.is_none() { match get_base_type_def_id(self.inference_context, - dummy_sp(), - self_type.ty) { + dummy_sp(), + self_type.ty) { None => { - // Nothing to do. + let session = self.crate_context.tcx.sess; + session.bug(fmt!("no base type for external impl with no \ + trait: %s (type %s)!", + session.str_of(implementation.ident), + ty_to_str(self.crate_context.tcx, + self_type.ty))); } - Some(base_type_def_id) => { - // inherent methods apply to `impl Type` but not - // `impl Trait for Type`: - if associated_traits.is_none() { - self.add_inherent_method(base_type_def_id, - implementation); - } + Some(_) => {} // Nothing to do. + } + } - self.base_type_def_ids.insert(implementation.did, - base_type_def_id); + // Record all the trait methods. + let implementation = @implementation; + for associated_traits.iter().advance |trait_ref| { + self.add_trait_method(trait_ref.def_id, implementation); + } + + // Add the implementation to the mapping from implementation to base + // type def ID, if there is a base type for this implementation. + match get_base_type_def_id(self.inference_context, + dummy_sp(), + self_type.ty) { + None => {} // Nothing to do. + Some(base_type_def_id) => { + // inherent methods apply to `impl Type` but not + // `impl Trait for Type`: + if associated_traits.is_none() { + self.add_inherent_method(base_type_def_id, + implementation); } + + self.base_type_def_ids.insert(implementation.did, + base_type_def_id); } } } @@ -952,22 +927,17 @@ impl CoherenceChecker { let crate_store = self.crate_context.tcx.sess.cstore; do iter_crate_data(crate_store) |crate_number, _crate_metadata| { - self.add_impls_for_module(&mut impls_seen, - crate_store, - def_id { crate: crate_number, - node: 0 }); - for each_path(crate_store, crate_number) |_, def_like, _| { match def_like { - dl_def(def_mod(def_id)) => { - self.add_impls_for_module(&mut impls_seen, - crate_store, - def_id); + dl_def(def_trait(def_id)) => { + self.add_default_methods_for_external_trait(def_id); } - dl_def(_) | dl_impl(_) | dl_field => { - // Skip this. - loop; + dl_impl(def_id) => { + self.add_external_impl(&mut impls_seen, + crate_store, + def_id) } + dl_def(_) | dl_field => loop, // Skip this. } } } diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 797fd9e8c020..8f0870af5133 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -10,6 +10,7 @@ //! Utilities for manipulating the char type +use container::Container; use option::{None, Option, Some}; use str; use str::{StrSlice, OwnedStr}; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 7d848184493f..590292d0d327 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -29,6 +29,7 @@ #[allow(missing_doc)]; use cast; +use container::Container; use io; use iterator::IteratorUtil; use libc; @@ -1500,7 +1501,10 @@ mod tests { fn test_getenv_big() { let mut s = ~""; let mut i = 0; - while i < 100 { s += "aaaaaaaaaa"; i += 1; } + while i < 100 { + s = s + "aaaaaaaaaa"; + i += 1; + } let n = make_rand_name(); setenv(n, s); debug!(copy s); diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 8a6c05ce6e2a..5baff8aee68d 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -42,6 +42,7 @@ fn main () { use cast; use cmp; +use container::Container; use int; use iterator::IteratorUtil; use local_data; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 3c512d9bfd29..2144afc0fbd1 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -1140,6 +1140,17 @@ impl<'self> Str for @str { } } +impl<'self> Container for &'self str { + #[inline] + fn len(&self) -> uint { + do as_buf(*self) |_p, n| { n - 1u } + } + #[inline] + fn is_empty(&self) -> bool { + self.len() == 0 + } +} + #[allow(missing_doc)] pub trait StrSlice<'self> { fn contains<'a>(&self, needle: &'a str) -> bool; @@ -1158,10 +1169,8 @@ pub trait StrSlice<'self> { fn any_line_iter(&self) -> AnyLineIterator<'self>; fn word_iter(&self) -> WordIterator<'self>; fn ends_with(&self, needle: &str) -> bool; - fn is_empty(&self) -> bool; fn is_whitespace(&self) -> bool; fn is_alphanumeric(&self) -> bool; - fn len(&self) -> uint; fn char_len(&self) -> uint; fn slice(&self, begin: uint, end: uint) -> &'self str; @@ -1362,9 +1371,6 @@ impl<'self> StrSlice<'self> for &'self str { self.split_iter(char::is_whitespace).filter(|s| !s.is_empty()) } - /// Returns true if the string has length 0 - #[inline] - fn is_empty(&self) -> bool { self.len() == 0 } /** * Returns true if the string contains only whitespace * @@ -1379,11 +1385,6 @@ impl<'self> StrSlice<'self> for &'self str { */ #[inline] fn is_alphanumeric(&self) -> bool { self.iter().all(char::is_alphanumeric) } - /// Returns the size in bytes not counting the null terminator - #[inline] - fn len(&self) -> uint { - do as_buf(*self) |_p, n| { n - 1u } - } /// Returns the number of characters that a string holds #[inline] fn char_len(&self) -> uint { self.iter().len_() } diff --git a/src/libstd/unstable/extfmt.rs b/src/libstd/unstable/extfmt.rs index 87bd25bdad32..624062a7ec40 100644 --- a/src/libstd/unstable/extfmt.rs +++ b/src/libstd/unstable/extfmt.rs @@ -94,6 +94,7 @@ use iterator::IteratorUtil; #[doc(hidden)] pub mod ct { use char; + use container::Container; use prelude::*; use str; From bb830558d13a8090988141c90ed49b16895c944a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 25 Jun 2013 18:25:27 -0700 Subject: [PATCH 245/336] librustc: Fix merge fallout and test cases. --- src/libextra/crypto/digest.rs | 4 +- src/libextra/terminfo/parm.rs | 3 +- src/librustc/driver/session.rs | 8 +- src/librustc/metadata/encoder.rs | 8 +- src/librustc/middle/reachable.rs | 10 +- src/librustc/middle/resolve.rs | 2 +- src/librustc/middle/trans/build.rs | 2 +- src/librustc/middle/trans/cabi_x86_64.rs | 6 +- src/librustc/middle/ty.rs | 2 +- src/librustc/middle/typeck/check/method.rs | 11 +- src/librustc/middle/typeck/coherence.rs | 19 +- src/librustc/util/ppaux.rs | 4 +- src/librusti/rusti.rc | 666 ++++++++++++++++++ src/librustpkg/tests.rs | 2 +- src/libstd/to_str.rs | 2 +- src/libsyntax/parse/token.rs | 2 +- .../compile-fail/closure-bounds-subtype.rs | 4 +- .../compile-fail/impl-duplicate-methods.rs | 2 +- .../compile-fail/trait-bounds-cant-coerce.rs | 8 +- .../trait-bounds-not-on-bare-trait.rs | 2 +- .../trait-bounds-not-on-struct.rs | 2 +- .../compile-fail/trait-duplicate-methods.rs | 2 +- .../compile-fail/trait-or-new-type-instead.rs | 2 +- .../closure-bounds-can-capture-chan.rs | 2 +- src/test/run-pass/trait-bounds-basic.rs | 6 +- src/test/run-pass/trait-default-method-xc.rs | 8 +- 26 files changed, 743 insertions(+), 46 deletions(-) create mode 100644 src/librusti/rusti.rc diff --git a/src/libextra/crypto/digest.rs b/src/libextra/crypto/digest.rs index 8fd44bfc9abc..c4fb03a7a7de 100644 --- a/src/libextra/crypto/digest.rs +++ b/src/libextra/crypto/digest.rs @@ -49,9 +49,9 @@ fn to_hex(rr: &[u8]) -> ~str { for rr.iter().advance() |b| { let hex = uint::to_str_radix(*b as uint, 16u); if hex.len() == 1 { - s += "0"; + s.push_char('0'); } - s += hex; + s.push_str(hex); } return s; } diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs index dca890ddf516..5180a71939c3 100644 --- a/src/libextra/terminfo/parm.rs +++ b/src/libextra/terminfo/parm.rs @@ -470,13 +470,14 @@ priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> { FormatHex|FormatHEX => 16, FormatString => util::unreachable() }; - let mut (s,_) = match op { + let (s,_) = match op { FormatDigit => { let sign = if flags.sign { SignAll } else { SignNeg }; to_str_bytes_common(&d, radix, false, sign, DigAll) } _ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll) }; + let mut s = s; if flags.precision > s.len() { let mut s_ = vec::with_capacity(flags.precision); let n = flags.precision - s.len(); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index b5eb351a8a58..ec86b43ffa3c 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -403,8 +403,12 @@ mod test { fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate { let mut attrs = ~[]; - if with_bin { attrs += [make_crate_type_attr(@"bin")]; } - if with_lib { attrs += [make_crate_type_attr(@"lib")]; } + if with_bin { + attrs.push(make_crate_type_attr(@"bin")); + } + if with_lib { + attrs.push(make_crate_type_attr(@"lib")); + } @codemap::respan(codemap::dummy_sp(), ast::crate_ { module: ast::_mod { view_items: ~[], items: ~[] }, attrs: attrs, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 187f2a99ed4c..e394c8dcf92f 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -484,7 +484,7 @@ fn each_auxiliary_node_id(item: @item, callback: &fn(node_id) -> bool) let mut continue = true; match item.node { item_enum(ref enum_def, _) => { - for enum_def.variants.each |variant| { + for enum_def.variants.iter().advance |variant| { continue = callback(variant.node.id); if !continue { break @@ -516,7 +516,7 @@ fn encode_reexports(ecx: &EncodeContext, match ecx.reexports2.find(&id) { Some(ref exports) => { debug!("(encoding info for module) found reexports for %d", id); - for exports.each |exp| { + for exports.iter().advance |exp| { debug!("(encoding info for module) reexport '%s' for %d", exp.name, id); ebml_w.start_tag(tag_items_data_item_reexport); @@ -900,7 +900,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); // Encode all the items in this module. - for fm.items.each |foreign_item| { + for fm.items.iter().advance |foreign_item| { ebml_w.start_tag(tag_mod_child); ebml_w.wr_str(def_to_str(local_def(foreign_item.id))); ebml_w.end_tag(); @@ -1506,7 +1506,7 @@ fn encode_misc_info(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.start_tag(tag_misc_info); ebml_w.start_tag(tag_misc_info_crate_items); - for crate.node.module.items.each |&item| { + for crate.node.module.items.iter().advance |&item| { ebml_w.start_tag(tag_mod_child); ebml_w.wr_str(def_to_str(local_def(item.id))); ebml_w.end_tag(); diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 12ddd3710458..fe7eccf9d594 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -140,7 +140,7 @@ impl ReachableContext { } item_enum(ref enum_def, _) => { if privacy_context == PublicContext { - for enum_def.variants.each |variant| { + for enum_def.variants.iter().advance |variant| { reachable_symbols.insert(variant.node.id); } } @@ -159,7 +159,7 @@ impl ReachableContext { }; // Mark all public methods as reachable. - for methods.each |&method| { + for methods.iter().advance |&method| { if should_be_considered_public(method) { reachable_symbols.insert(method.id); } @@ -168,7 +168,7 @@ impl ReachableContext { if generics_require_inlining(generics) { // If the impl itself has generics, add all public // symbols to the worklist. - for methods.each |&method| { + for methods.iter().advance |&method| { if should_be_considered_public(method) { worklist.push(method.id) } @@ -176,7 +176,7 @@ impl ReachableContext { } else { // Otherwise, add only public methods that have // generics to the worklist. - for methods.each |method| { + for methods.iter().advance |method| { let generics = &method.generics; let attrs = &method.attrs; if generics_require_inlining(generics) || @@ -190,7 +190,7 @@ impl ReachableContext { item_trait(_, _, ref trait_methods) => { // Mark all provided methods as reachable. if privacy_context == PublicContext { - for trait_methods.each |trait_method| { + for trait_methods.iter().advance |trait_method| { match *trait_method { provided(method) => { reachable_symbols.insert(method.id); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 17c984c8a33c..aa7033221cf2 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1240,7 +1240,7 @@ impl Resolver { // Create the module and add all methods. match *ty { Ty { - node: ty_path(path, _), + node: ty_path(path, _, _), _ } if path.idents.len() == 1 => { let name = path_to_ident(path); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index e48a98cd90c0..dc32a3b4e2c8 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -616,7 +616,7 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { // we care about. if ixs.len() < 16 { let mut small_vec = [ C_i32(0), ..16 ]; - for ixs.eachi |i, &ix| { + for ixs.iter().enumerate().advance |(i, &ix)| { small_vec[i] = C_i32(ix as i32) } InBoundsGEP(cx, base, small_vec.slice(0, ixs.len())) diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 755075c17e9c..6c264e637a60 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -39,7 +39,11 @@ enum RegClass { Memory } -impl Type { +trait TypeMethods { + fn is_reg_ty(&self) -> bool; +} + +impl TypeMethods for Type { fn is_reg_ty(&self) -> bool { match self.kind() { Integer | Pointer | Float | Double => true, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 212f78c47568..f88c59988626 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1908,7 +1908,7 @@ impl TypeContents { // this assertion. assert!(self.intersects(TC_OWNED_POINTER)); } - let tc = TC_MANAGED + TC_DTOR + TypeContents::owned(cx); + let tc = TC_MANAGED + TC_DTOR + TypeContents::sendable(cx); self.intersects(tc) } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 8c3315e49b45..4bebca3c9a8b 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1088,16 +1088,19 @@ impl<'self> LookupContext<'self> { _ => {} } - return match candidate.method_ty.explicit_self { + let result = match candidate.method_ty.explicit_self { sty_static => { + debug!("(is relevant?) explicit self is static"); false } sty_value => { + debug!("(is relevant?) explicit self is by-value"); self.fcx.can_mk_subty(rcvr_ty, candidate.rcvr_ty).is_ok() } sty_region(_, m) => { + debug!("(is relevant?) explicit self is a region"); match ty::get(rcvr_ty).sty { ty::ty_rptr(_, mt) => { mutability_matches(mt.mutbl, m) && @@ -1109,6 +1112,7 @@ impl<'self> LookupContext<'self> { } sty_box(m) => { + debug!("(is relevant?) explicit self is a box"); match ty::get(rcvr_ty).sty { ty::ty_box(mt) => { mutability_matches(mt.mutbl, m) && @@ -1120,6 +1124,7 @@ impl<'self> LookupContext<'self> { } sty_uniq(m) => { + debug!("(is relevant?) explicit self is a unique pointer"); match ty::get(rcvr_ty).sty { ty::ty_uniq(mt) => { mutability_matches(mt.mutbl, m) && @@ -1131,6 +1136,10 @@ impl<'self> LookupContext<'self> { } }; + debug!("(is relevant?) %s", if result { "yes" } else { "no" }); + + return result; + fn mutability_matches(self_mutbl: ast::mutability, candidate_mutbl: ast::mutability) -> bool { //! True if `self_mutbl <: candidate_mutbl` diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 9de7315d0e71..a537d0cc72c5 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -895,8 +895,22 @@ impl CoherenceChecker { } // Record all the trait methods. - let implementation = @implementation; + let mut implementation = @implementation; for associated_traits.iter().advance |trait_ref| { + self.instantiate_default_methods(implementation.did, + *trait_ref); + + // XXX(sully): We could probably avoid this copy if there are no + // default methods. + let mut methods = copy implementation.methods; + self.add_provided_methods_to_impl(&mut methods, + &trait_ref.def_id, + &implementation.did); + implementation = @Impl { + methods: methods, + ..*implementation + }; + self.add_trait_method(trait_ref.def_id, implementation); } @@ -929,9 +943,6 @@ impl CoherenceChecker { do iter_crate_data(crate_store) |crate_number, _crate_metadata| { for each_path(crate_store, crate_number) |_, def_like, _| { match def_like { - dl_def(def_trait(def_id)) => { - self.add_default_methods_for_external_trait(def_id); - } dl_impl(def_id) => { self.add_external_impl(&mut impls_seen, crate_store, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 58dc121959ed..548eebaea0be 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -488,7 +488,9 @@ pub fn parameterized(cx: ctxt, } }; - strs += vec::map(tps, |t| ty_to_str(cx, *t)); + for tps.iter().advance |t| { + strs.push(ty_to_str(cx, *t)) + } if strs.len() > 0u { fmt!("%s<%s>", base, strs.connect(",")) diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc new file mode 100644 index 000000000000..5873f361ad73 --- /dev/null +++ b/src/librusti/rusti.rc @@ -0,0 +1,666 @@ +// 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-pre", + 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)] +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/librustpkg/tests.rs b/src/librustpkg/tests.rs index 8d8628c77181..83dcde48b3a8 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -248,7 +248,7 @@ fn command_line_test_output(args: &[~str]) -> ~[~str] { let p_output = command_line_test(args, &os::getcwd()); let test_output = str::from_bytes(p_output.output); for test_output.split_iter('\n').advance |s| { - result += [s.to_owned()]; + result.push(s.to_owned()); } result } diff --git a/src/libstd/to_str.rs b/src/libstd/to_str.rs index dcd02744cf90..77701acd33e2 100644 --- a/src/libstd/to_str.rs +++ b/src/libstd/to_str.rs @@ -55,7 +55,7 @@ impl ToStr for HashMap { fn to_str(&self) -> ~str { let mut acc = ~"{"; let mut first = true; - for self.iter().advance |key, value| { + for self.iter().advance |(key, value)| { if first { first = false; } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 18e6c1817991..793626f0e180 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -563,7 +563,7 @@ pub mod keywords { // Strict keywords As, Break, - Freeze, + Const, Copy, Do, Else, diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs index 6ffdd0f541e1..0c9220d18ab7 100644 --- a/src/test/compile-fail/closure-bounds-subtype.rs +++ b/src/test/compile-fail/closure-bounds-subtype.rs @@ -8,7 +8,7 @@ fn take_copyable(_: &fn:Copy()) { fn take_copyable_owned(_: &fn:Copy+Send()) { } -fn take_const_owned(_: &fn:Const+Owned()) { +fn take_const_owned(_: &fn:Freeze+Send()) { } fn give_any(f: &fn:()) { @@ -33,7 +33,7 @@ fn give_copyable_owned(f: &fn:Copy+Send()) { take_any(f); take_copyable(f); take_copyable_owned(f); - take_const_owned(f); //~ ERROR expected bounds `Owned+Const` but found bounds `Copy+Owned` + take_const_owned(f); //~ ERROR expected bounds `Send+Freeze` but found bounds `Copy+Send` } fn main() {} diff --git a/src/test/compile-fail/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs index ec766e5ce9b9..c6ce4d04e108 100644 --- a/src/test/compile-fail/impl-duplicate-methods.rs +++ b/src/test/compile-fail/impl-duplicate-methods.rs @@ -11,7 +11,7 @@ struct Foo; impl Foo { fn orange(&self){} - fn orange(&self){} //~ ERROR error: duplicate definition of method `orange` + fn orange(&self){} //~ ERROR error: duplicate definition of value `orange` } fn main() {} diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs index adaea1de9bd0..a96da398f5a1 100644 --- a/src/test/compile-fail/trait-bounds-cant-coerce.rs +++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs @@ -11,14 +11,14 @@ trait Foo { } -fn a(_x: ~Foo:Owned) { +fn a(_x: ~Foo:Send) { } -fn b(_x: ~Foo:Owned+Copy) { +fn b(_x: ~Foo:Send+Copy) { } -fn c(x: ~Foo:Const+Owned) { - b(x); //~ ERROR expected bounds `Copy+Owned` +fn c(x: ~Foo:Freeze+Send) { + b(x); //~ ERROR expected bounds `Copy+Send` } fn d(x: ~Foo:) { diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs index e9cc9575003d..d7c98ec4e9d2 100644 --- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs +++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs @@ -13,7 +13,7 @@ trait Foo { // This should emit the less confusing error, not the more confusing one. -fn foo(_x: Foo:Owned) { //~ERROR reference to trait `Foo` where a type is expected +fn foo(_x: Foo:Send) { //~ERROR reference to trait `Foo` where a type is expected } fn main() { } diff --git a/src/test/compile-fail/trait-bounds-not-on-struct.rs b/src/test/compile-fail/trait-bounds-not-on-struct.rs index 45bb5e29a884..ebffd0303e04 100644 --- a/src/test/compile-fail/trait-bounds-not-on-struct.rs +++ b/src/test/compile-fail/trait-bounds-not-on-struct.rs @@ -10,6 +10,6 @@ struct Foo; -fn foo(_x: ~Foo:Owned) { } //~ ERROR kind bounds can only be used on trait types +fn foo(_x: ~Foo:Send) { } //~ ERROR kind bounds can only be used on trait types fn main() { } diff --git a/src/test/compile-fail/trait-duplicate-methods.rs b/src/test/compile-fail/trait-duplicate-methods.rs index e2ba5267eba8..ba8101d16ab0 100644 --- a/src/test/compile-fail/trait-duplicate-methods.rs +++ b/src/test/compile-fail/trait-duplicate-methods.rs @@ -10,7 +10,7 @@ trait Foo { fn orange(&self); - fn orange(&self); //~ ERROR error: duplicate definition of method `orange` + fn orange(&self); //~ ERROR error: duplicate definition of value `orange` } fn main() {} diff --git a/src/test/compile-fail/trait-or-new-type-instead.rs b/src/test/compile-fail/trait-or-new-type-instead.rs index f687a6f97024..c44887593ab3 100644 --- a/src/test/compile-fail/trait-or-new-type-instead.rs +++ b/src/test/compile-fail/trait-or-new-type-instead.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: implement a trait or new type instead +// error-pattern: found value name used as a type impl Option { pub fn foo(&self) { } } diff --git a/src/test/run-pass/closure-bounds-can-capture-chan.rs b/src/test/run-pass/closure-bounds-can-capture-chan.rs index 26bea0e51415..95b0c9d79b7c 100644 --- a/src/test/run-pass/closure-bounds-can-capture-chan.rs +++ b/src/test/run-pass/closure-bounds-can-capture-chan.rs @@ -10,7 +10,7 @@ use std::comm; -fn foo(blk: ~fn:Owned()) { +fn foo(blk: ~fn:Send()) { blk(); } diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs index 5bfbf84d8aca..e0d60d62bb58 100644 --- a/src/test/run-pass/trait-bounds-basic.rs +++ b/src/test/run-pass/trait-bounds-basic.rs @@ -14,14 +14,14 @@ trait Foo { fn a(_x: ~Foo:) { } -fn b(_x: ~Foo:Owned) { +fn b(_x: ~Foo:Send) { } -fn c(x: ~Foo:Const+Owned) { +fn c(x: ~Foo:Freeze+Send) { a(x); } -fn d(x: ~Foo:Owned+Copy) { +fn d(x: ~Foo:Send+Copy) { b(x); } diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index e6e5b8605a16..f6c119c4faeb 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -44,12 +44,12 @@ fn main () { let a = thing { x: 0 }; let b = thing { x: 1 }; - assert_eq!(0i.g(), 10); + //assert_eq!(0i.g(), 10); assert_eq!(a.g(), 10); assert_eq!(a.h(), 10); - assert_eq!(0i.thing(3.14, 1), (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 +59,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)); From 3625781cfe20db713158236f5d03e0c249f5137f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 25 Jun 2013 19:19:38 -0700 Subject: [PATCH 246/336] librustc: Fix more merge fallout. --- src/libextra/arena.rs | 20 +++++++++++++++----- src/librustc/metadata/decoder.rs | 8 ++++---- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/reachable.rs | 3 ++- src/librustc/middle/resolve.rs | 4 ++-- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 79e09c32030b..2f18b0562e0f 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -229,15 +229,25 @@ impl Arena { fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint) -> (*u8, *u8) { unsafe { - let head = transmute_mut_region(&mut self.head); + let start; + let end; + let tydesc_start; + let after_tydesc; + + { + let head = transmute_mut_region(&mut self.head); + + tydesc_start = head.fill; + after_tydesc = head.fill + sys::size_of::<*TyDesc>(); + start = round_up_to(after_tydesc, align); + end = start + n_bytes; + } - let tydesc_start = head.fill; - let after_tydesc = head.fill + sys::size_of::<*TyDesc>(); - let start = round_up_to(after_tydesc, align); - let end = start + n_bytes; if end > at_vec::capacity(self.head.data) { return self.alloc_nonpod_grow(n_bytes, align); } + + let head = transmute_mut_region(&mut self.head); head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>()); //debug!("idx = %u, size = %u, align = %u, fill = %u", diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 2ebaa2b739fc..ba8df3a60383 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -523,10 +523,10 @@ impl<'self> EachItemContext<'self> { Mod | ForeignMod | Trait | Impl => { continue = self.each_item_of_module(def_id); } - Freeze | Struct | UnsafeFn | Fn | PureFn | ForeignFn | - UnsafeStaticMethod | StaticMethod | PureStaticMethod | Type | - ForeignType | Variant | Enum | PublicField | PrivateField | - InheritedField => {} + ImmStatic | MutStatic | Struct | UnsafeFn | Fn | PureFn | + ForeignFn | UnsafeStaticMethod | StaticMethod | + PureStaticMethod | Type | ForeignType | Variant | Enum | + PublicField | PrivateField | InheritedField => {} } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index f93cb265d785..52c01fa76476 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -452,7 +452,7 @@ impl mem_categorization_ctxt { ast::def_trait(_) | ast::def_ty(_) | ast::def_prim_ty(_) | ast::def_ty_param(*) | ast::def_struct(*) | ast::def_typaram_binder(*) | ast::def_region(_) | - ast::def_label(_) | ast::def_self_ty(*) => { + ast::def_label(_) | ast::def_self_ty(*) | ast::def_method(*) => { @cmt_ { id:id, span:span, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index fe7eccf9d594..88bd9c1f6f4a 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -396,7 +396,8 @@ impl ReachableContext { // this properly would result in the necessity of computing *type* // reachability, which might result in a compile time loss. fn mark_destructors_reachable(&self) { - for self.tcx.destructor_for_type.each |_, destructor_def_id| { + for self.tcx.destructor_for_type.iter().advance + |(_, destructor_def_id)| { if destructor_def_id.crate == local_crate { self.reachable_symbols.insert(destructor_def_id.node); } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index aa7033221cf2..b2bfd9d1661b 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3240,8 +3240,8 @@ impl Resolver { pub fn add_exports_for_module(@mut self, exports2: &mut ~[Export2], module_: @mut Module) { - for module_.import_resolutions.iter().advance |ident, - importresolution| { + for module_.import_resolutions.iter().advance |(ident, + importresolution)| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", self.session.str_of(*ident)); From f6a27cbda273d5d39af953bca12990cc4930382c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 26 Jun 2013 15:54:51 -0700 Subject: [PATCH 247/336] libextra: Fix even more merge fallout. --- src/libextra/ebml.rs | 3 ++- src/libextra/num/bigint.rs | 2 -- src/libextra/test.rs | 3 --- src/libextra/timer.rs | 1 - src/libstd/task/spawn.rs | 1 - 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index fad04b772eb7..d401710a466d 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -94,7 +94,6 @@ pub mod reader { use serialize; - use core::prelude::*; use core::cast::transmute; use core::int; use core::io; @@ -106,6 +105,8 @@ pub mod reader { #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] + use core::option::{None, Option, Some}; + use core::ptr::offset; use core::unstable::intrinsics::bswap32; // ebml reading diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index b0fa715fdd81..002d8a7f9567 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -382,8 +382,6 @@ impl Integer for BigUint { while m >= b { let (d0, d_unit, b_unit) = div_estimate(&m, &b, n); let mut d0 = d0; - let mut d_unit = d_unit; - let mut b_unit = b_unit; let mut prod = b * d0; while prod > m { // FIXME(#6050): overloaded operators force moves with generic types diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 672c4cd648cf..209b46809ce3 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -751,9 +751,6 @@ impl BenchHarness { } pub mod bench { - use core::prelude::*; - - use core::vec; use test::{BenchHarness, BenchSamples}; pub fn benchmark(f: &fn(&mut BenchHarness)) -> BenchSamples { diff --git a/src/libextra/timer.rs b/src/libextra/timer.rs index 79451db8b171..e23f9113319d 100644 --- a/src/libextra/timer.rs +++ b/src/libextra/timer.rs @@ -125,7 +125,6 @@ pub fn recv_timeout(iotask: &IoTask, -> Option { let (timeout_po, timeout_ch) = stream::<()>(); let mut timeout_po = timeout_po; - let mut timeout_ch = timeout_ch; delayed_send(iotask, msecs, &timeout_ch, ()); // XXX: Workaround due to ports and channels not being &mut. They should diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index da3dc6b2a2e5..8f06fede0572 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -637,7 +637,6 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let result: ~fn() = || { // Agh. Get move-mode items into the closure. FIXME (#2829) let (notify_chan, child_arc, ancestors) = child_data.take(); - let mut child_arc = child_arc; let mut ancestors = ancestors; // Child task runs this code. From f25f466afe7d4d94d711e4f288fd39ab72f1cc61 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 27 Jun 2013 11:16:53 -0700 Subject: [PATCH 248/336] librustc: Fix even *more* merge fallout! --- src/librustc/metadata/decoder.rs | 8 ++++---- src/librustc/middle/ty.rs | 8 ++++---- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustpkg/rustpkg.rs | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index ba8df3a60383..69faf519bc28 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -523,10 +523,10 @@ impl<'self> EachItemContext<'self> { Mod | ForeignMod | Trait | Impl => { continue = self.each_item_of_module(def_id); } - ImmStatic | MutStatic | Struct | UnsafeFn | Fn | PureFn | - ForeignFn | UnsafeStaticMethod | StaticMethod | - PureStaticMethod | Type | ForeignType | Variant | Enum | - PublicField | PrivateField | InheritedField => {} + ImmStatic | MutStatic | Struct | UnsafeFn | Fn | ForeignFn | + UnsafeStaticMethod | StaticMethod | Type | ForeignType | + Variant | Enum | PublicField | PrivateField | + InheritedField => {} } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f88c59988626..175529be2062 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2293,11 +2293,11 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { BoundCopy if store == UniqTraitStore => TC_NONCOPY_TRAIT, BoundCopy => TC_NONE, // @Trait/&Trait are copyable either way - BoundStatic if bounds.contains_elem(BoundOwned) - => TC_NONE, // Owned bound implies static bound. + BoundStatic if bounds.contains_elem(BoundSend) + => TC_NONE, // Send bound implies static bound. BoundStatic => TC_BORROWED_POINTER, // Useful for "@Trait:'static" - BoundOwned => TC_NON_OWNED, - BoundConst => TC_MUTABLE, + BoundSend => TC_NON_SENDABLE, + BoundFreeze => TC_MUTABLE, BoundSized => TC_NONE, // don't care if interior is sized }; } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 70df9877162e..3d0cbec8b1a6 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -790,7 +790,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option { - let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundOwned); set + let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundSend); set } // @Trait is sugar for @Trait:'static. // &'static Trait is sugar for &'static Trait:'static. diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index ca13ba39d59c..550a3411b5dd 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -192,6 +192,7 @@ pub trait CtxMethods { fn clean(&self, workspace: &Path, id: &PkgId); fn info(&self); fn install(&self, workspace: &Path, id: &PkgId); + fn install_no_build(&self, workspace: &Path, id: &PkgId); fn prefer(&self, _id: &str, _vers: Option<~str>); fn test(&self); fn uninstall(&self, _id: &str, _vers: Option<~str>); From 10bcb60e8f8520c11e34758e290a21534425dee6 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 27 Jun 2013 15:07:16 -0700 Subject: [PATCH 249/336] librustc: Fix even *MORE* merge fallout! --- src/librustc/middle/lang_items.rs | 4 ++-- src/libstd/os.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 3418fc649da0..08e55df5b368 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -295,9 +295,9 @@ impl<'self> LanguageItemCollector<'self> { -> LanguageItemCollector<'a> { let mut item_refs = HashMap::new(); - item_refs.insert(@"const", FreezeTraitLangItem as uint); + item_refs.insert(@"freeze", FreezeTraitLangItem as uint); item_refs.insert(@"copy", CopyTraitLangItem as uint); - item_refs.insert(@"owned", SendTraitLangItem as uint); + item_refs.insert(@"send", SendTraitLangItem as uint); item_refs.insert(@"sized", SizedTraitLangItem as uint); item_refs.insert(@"drop", DropTraitLangItem as uint); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 590292d0d327..400a93ee28f4 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -146,7 +146,7 @@ pub mod win32 { pub fn as_utf16_p(s: &str, f: &fn(*u16) -> T) -> T { let mut t = s.to_utf16(); // Null terminate before passing on. - t += [0u16]; + t.push(0u16); vec::as_imm_buf(t, |buf, _len| f(buf)) } } From fae4a9e5ba36202dc8036cf90a7dd8ace4c1336a Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 28 Jun 2013 16:00:30 +1200 Subject: [PATCH 250/336] Rename Const/Owned in more places --- src/librustc/middle/typeck/astconv.rs | 2 +- src/test/compile-fail/trait-bounds-sugar.rs | 10 +++++----- src/test/run-pass/trait-bounds-in-arc.rs | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 3d0cbec8b1a6..07fb23fea48a 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -788,7 +788,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option { let mut set = ty::EmptyBuiltinBounds(); set.add(ty::BoundSend); set } diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs index 8c641f4c850d..68a0ae900142 100644 --- a/src/test/compile-fail/trait-bounds-sugar.rs +++ b/src/test/compile-fail/trait-bounds-sugar.rs @@ -13,7 +13,7 @@ trait Foo { } -fn a(_x: ~Foo) { // should be same as ~Foo:Owned +fn a(_x: ~Foo) { // should be same as ~Foo:Send } fn b(_x: @Foo) { // should be same as ~Foo:'static @@ -22,15 +22,15 @@ fn b(_x: @Foo) { // should be same as ~Foo:'static fn c(_x: &'static Foo) { // should be same as &'static Foo:'static } -fn d(x: ~Foo:Const) { - a(x); //~ ERROR expected bounds `Owned` +fn d(x: ~Foo:Freeze) { + a(x); //~ ERROR expected bounds `Send` } -fn e(x: @Foo:Const) { +fn e(x: @Foo:Freeze) { b(x); //~ ERROR expected bounds `'static` } -fn f(x: &'static Foo:Const) { +fn f(x: &'static Foo:Freeze) { c(x); //~ ERROR expected bounds `'static` } diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 585c2185a7ec..a3b2ea02db35 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -9,7 +9,7 @@ // except according to those terms. // Tests that a heterogeneous list of existential types can be put inside an ARC -// and shared between tasks as long as all types fulfill Const+Owned. +// and shared between tasks as long as all types fulfill Freeze+Send. // xfail-fast @@ -64,10 +64,10 @@ fn main() { let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" }; let dogge2 = Dogge { bark_decibels: 55, tricks_known: 11, name: ~"albert_einstein" }; let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" }; - let arc = arc::ARC(~[~catte as ~Pet:Const+Owned, - ~dogge1 as ~Pet:Const+Owned, - ~fishe as ~Pet:Const+Owned, - ~dogge2 as ~Pet:Const+Owned]); + let arc = arc::ARC(~[~catte as ~Pet:Freeze+Send, + ~dogge1 as ~Pet:Freeze+Send, + ~fishe as ~Pet:Freeze+Send, + ~dogge2 as ~Pet:Freeze+Send]); let (p1,c1) = comm::stream(); let arc1 = cell::Cell::new(arc.clone()); do task::spawn { check_legs(arc1.take()); c1.send(()); } @@ -82,21 +82,21 @@ fn main() { p3.recv(); } -fn check_legs(arc: arc::ARC<~[~Pet:Const+Owned]>) { +fn check_legs(arc: arc::ARC<~[~Pet:Freeze+Send]>) { let mut legs = 0; for arc.get().iter().advance |pet| { legs += pet.num_legs(); } assert!(legs == 12); } -fn check_names(arc: arc::ARC<~[~Pet:Const+Owned]>) { +fn check_names(arc: arc::ARC<~[~Pet:Freeze+Send]>) { for arc.get().iter().advance |pet| { do pet.name |name| { assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8); } } } -fn check_pedigree(arc: arc::ARC<~[~Pet:Const+Owned]>) { +fn check_pedigree(arc: arc::ARC<~[~Pet:Freeze+Send]>) { for arc.get().iter().advance |pet| { assert!(pet.of_good_pedigree()); } From 8f5cb92f89a48fd47b0eff6fa72aa2f0b18188b3 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Fri, 28 Jun 2013 08:05:11 -0400 Subject: [PATCH 251/336] Fix threadring --- src/test/bench/shootout-threadring.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index a67bbb05dfb5..97168de5d43e 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -13,7 +13,9 @@ use std::os; fn start(n_tasks: int, token: int) { - let mut (p, ch1) = stream(); + let (p, ch1) = stream(); + let mut p = p; + let mut ch1 = ch1; ch1.send(token); // XXX could not get this to work with a range closure let mut i = 2; From d600601162d8a28b0a7e4eeaba81d0c2cee2e226 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Fri, 28 Jun 2013 08:51:31 -0400 Subject: [PATCH 252/336] Add each_parent to WindowsPath --- src/libstd/path.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9b4a3270f28a..a5e82c31d790 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -508,6 +508,14 @@ impl WindowsPath { } } } + + /// Execute a function on p as well as all of its ancestors + pub fn each_parent(&self, f: &fn(&Path)) { + if !self.components.is_empty() { + f(self); + self.pop().each_parent(f); + } + } } impl ToStr for PosixPath { From 4f044891a5457acb06338c78f9aa58d8b4c9d53f Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Fri, 28 Jun 2013 14:10:06 -0400 Subject: [PATCH 253/336] Fix merge fallout --- src/libextra/ebml.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index d401710a466d..69eb9afad853 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -97,11 +97,6 @@ pub mod reader { use core::cast::transmute; use core::int; use core::io; - use core::str; - - #[cfg(target_arch = "x86")] - #[cfg(target_arch = "x86_64")] - use core::ptr::offset; #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] From a2227f9e0c295c3582683129a8511d7660b644a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Fri, 28 Jun 2013 21:28:58 +0200 Subject: [PATCH 254/336] librustc: don't skip ahead when computing register types of SSEFloatVectors Also fixes an unrelated typo (found by comparing to the original code of the clay project) and some cleanup. Fixes #7415. --- src/librustc/middle/trans/cabi_x86_64.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 73323634c2b6..24b413eb4336 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -122,11 +122,10 @@ fn classify_ty(ty: Type) -> ~[RegClass] { Float => 4, Double => 8, Struct => { + let str_tys = ty.field_types(); if ty.is_packed() { - let str_tys = ty.field_types(); str_tys.iter().fold(0, |s, t| s + ty_size(*t)) } else { - let str_tys = ty.field_types(); let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); align(size, ty) } @@ -236,9 +235,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { let mut i = 0u; let ty_kind = ty.kind(); let e = cls.len(); - if cls.len() > 2u && - (ty_kind == Struct || - ty_kind == Array) { + if cls.len() > 2u && (ty_kind == Struct || ty_kind == Array) { if cls[i].is_sse() { i += 1u; while i < e { @@ -265,7 +262,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { return; } if cls[i] == SSEUp { - cls[i] = SSEInt; + cls[i] = SSEDv; } else if cls[i].is_sse() { i += 1; while i != e && cls[i] == SSEUp { i += 1u; } @@ -283,7 +280,6 @@ fn classify_ty(ty: Type) -> ~[RegClass] { let mut cls = vec::from_elem(words, NoClass); if words > 4 { all_mem(cls); - let cls = cls; return cls; } classify(ty, cls, 0, 0); @@ -312,8 +308,8 @@ fn llreg_ty(cls: &[RegClass]) -> Type { tys.push(Type::i64()); } SSEFv => { - let vec_len = llvec_len(cls.tailn(i + 1u)) * 2u; - let vec_ty = Type::vector(&Type::f32(), vec_len as u64); + let vec_len = llvec_len(cls.tailn(i + 1u)); + let vec_ty = Type::vector(&Type::f32(), (vec_len * 2u) as u64); tys.push(vec_ty); i += vec_len; loop; From 2bdc88b6526f806156a6342ae75a80d99ea6e378 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 28 Jun 2013 17:14:28 -0400 Subject: [PATCH 255/336] copy the optimization passes from clang --- src/librustc/back/passes.rs | 163 ++++++++++++++++++++---------------- src/test/bench/noise.rs | 8 +- 2 files changed, 95 insertions(+), 76 deletions(-) diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index fa261a977f59..d2b4c87c7441 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -60,90 +60,109 @@ impl PassManager { } } -pub fn create_standard_passes(level:OptLevel) -> ~[~str] { - let mut passes = ~[~"strip-dead-prototypes"]; +pub fn create_standard_passes(level: OptLevel) -> ~[~str] { + let mut passes = ~[]; - if level == No { + // mostly identical to clang 3.3, all differences are documented with comments + + if level != No { + passes.push(~"targetlibinfo"); + passes.push(~"no-aa"); + // "tbaa" omitted, we don't emit clang-style type-based alias analysis information + passes.push(~"basicaa"); + passes.push(~"globalopt"); + passes.push(~"ipsccp"); + passes.push(~"deadargelim"); + passes.push(~"instcombine"); + passes.push(~"simplifycfg"); + } + + passes.push(~"basiccg"); + + if level != No { + passes.push(~"prune-eh"); + } + + passes.push(~"inline-cost"); + + if level == No || level == Less { passes.push(~"always-inline"); - return passes; + } else { + passes.push(~"inline"); } - passes.push(~"targetlibinfo"); - - passes.push(~"scev-aa"); - passes.push(~"basicaa"); - - passes.push(~"instcombine"); - passes.push(~"simplifycfg"); - passes.push(~"scalarrepl-ssa"); - passes.push(~"early-cse"); - - passes.push(~"globalopt"); - passes.push(~"ipsccp"); - passes.push(~"deadargelim"); - passes.push(~"instcombine"); - passes.push(~"simplifycfg"); - - passes.push(~"prune-eh"); - - passes.push(~"inline"); - - passes.push(~"functionattrs"); - - if level == Aggressive { - passes.push(~"argpromotion"); + if level != No { + passes.push(~"functionattrs"); + if level == Aggressive { + passes.push(~"argpromotion"); + } + passes.push(~"sroa"); + passes.push(~"domtree"); + passes.push(~"early-cse"); + passes.push(~"simplify-libcalls"); + passes.push(~"lazy-value-info"); + passes.push(~"jump-threading"); + passes.push(~"correlated-propagation"); + passes.push(~"simplifycfg"); + passes.push(~"instcombine"); + passes.push(~"tailcallelim"); + passes.push(~"simplifycfg"); + passes.push(~"reassociate"); + passes.push(~"domtree"); + passes.push(~"loops"); + passes.push(~"loop-simplify"); + passes.push(~"lcssa"); + passes.push(~"loop-rotate"); + passes.push(~"licm"); + passes.push(~"lcssa"); + passes.push(~"loop-unswitch"); + passes.push(~"instcombine"); + passes.push(~"scalar-evolution"); + passes.push(~"loop-simplify"); + passes.push(~"lcssa"); + passes.push(~"indvars"); + passes.push(~"loop-idiom"); + passes.push(~"loop-deletion"); + if level == Aggressive { + passes.push(~"loop-simplify"); + passes.push(~"lcssa"); + passes.push(~"loop-vectorize"); + passes.push(~"loop-simplify"); + passes.push(~"lcssa"); + passes.push(~"scalar-evolution"); + passes.push(~"loop-simplify"); + passes.push(~"lcssa"); + } + if level != Less { + passes.push(~"loop-unroll"); + passes.push(~"memdep"); + passes.push(~"gvn"); + } + passes.push(~"memdep"); + passes.push(~"memcpyopt"); + passes.push(~"sccp"); + passes.push(~"instcombine"); + passes.push(~"lazy-value-info"); + passes.push(~"jump-threading"); + passes.push(~"correlated-propagation"); + passes.push(~"domtree"); + passes.push(~"memdep"); + passes.push(~"dse"); + passes.push(~"adce"); + passes.push(~"simplifycfg"); + passes.push(~"instcombine"); + // clang does `strip-dead-prototypes` here, since it does not emit them } - passes.push(~"scalarrepl-ssa"); - passes.push(~"early-cse"); - passes.push(~"simplify-libcalls"); - passes.push(~"jump-threading"); - passes.push(~"correlated-propagation"); - passes.push(~"simplifycfg"); - passes.push(~"instcombine"); - - passes.push(~"tailcallelim"); - passes.push(~"simplifycfg"); - passes.push(~"reassociate"); - passes.push(~"loop-rotate"); - passes.push(~"licm"); - - passes.push(~"lcssa"); - passes.push(~"loop-unswitch"); - - passes.push(~"instcombine"); - passes.push(~"indvars"); - passes.push(~"loop-idiom"); - passes.push(~"loop-deletion"); - - if level == Aggressive { - passes.push(~"loop-vectorize"); - } - - passes.push(~"loop-unroll"); - - if level != Less { - passes.push(~"gvn"); - } - - passes.push(~"memcpyopt"); - passes.push(~"sccp"); - - passes.push(~"instcombine"); - passes.push(~"jump-threading"); - passes.push(~"correlated-propagation"); - passes.push(~"dse"); - - passes.push(~"adce"); - passes.push(~"simplifycfg"); - passes.push(~"instsimplify"); + // rustc emits dead prototypes, so always ask LLVM to strip them + passes.push(~"strip-dead-prototypes"); if level != Less { passes.push(~"globaldce"); passes.push(~"constmerge"); } - return passes; + passes } pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~str]) { diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 25bdf7dc3fef..b65a6429f2c6 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -118,10 +118,10 @@ fn main() { }; }; - /*for int::range(0, 256) |y| { + for int::range(0, 256) |y| { for int::range(0, 256) |x| { - io::print(symbols[pixels[y*256+x] / 0.2f32 as int]); + print(symbols[pixels[y*256+x] / 0.2f32 as int]); } - io::println(""); - }*/ + println(""); + } } From 47afb33981c7f20d33e04b938c4362f4da12529a Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Tue, 25 Jun 2013 13:27:47 -0700 Subject: [PATCH 256/336] Add Float to llvm::type_to_str. --- src/librustc/lib/llvm.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index d7f33dcf0d0a..042984ffcf3b 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2161,6 +2161,7 @@ impl TypeNames { match kind { Void => ~"Void", Half => ~"Half", + Float => ~"Float", Double => ~"Double", X86_FP80 => ~"X86_FP80", FP128 => ~"FP128", From 050d0e6b29d19978584f6e389f53612497b7e41e Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Tue, 25 Jun 2013 13:27:54 -0700 Subject: [PATCH 257/336] Add a depth counter to llvm::type_to_str to work around infinite llvm types. --- src/librustc/lib/llvm.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 042984ffcf3b..41349d9c085c 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2149,12 +2149,17 @@ impl TypeNames { self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) } - pub fn type_to_str(&self, ty: Type) -> ~str { + // We have a depth count, because we seem to make infinite types. + pub fn type_to_str_depth(&self, ty: Type, depth: int) -> ~str { match self.find_name(&ty) { option::Some(name) => return name.to_owned(), None => () } + if depth == 0 { + return ~"###"; + } + unsafe { let kind = ty.kind(); @@ -2176,24 +2181,25 @@ impl TypeNames { Function => { let out_ty = ty.return_type(); let args = ty.func_params(); - let args = args.map(|&ty| self.type_to_str(ty)).connect(", "); - let out_ty = self.type_to_str(out_ty); + let args = + args.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", "); + let out_ty = self.type_to_str_depth(out_ty, depth-1); fmt!("fn(%s) -> %s", args, out_ty) } Struct => { let tys = ty.field_types(); - let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", "); + let tys = tys.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", "); fmt!("{%s}", tys) } Array => { let el_ty = ty.element_type(); - let el_ty = self.type_to_str(el_ty); + let el_ty = self.type_to_str_depth(el_ty, depth-1); let len = ty.array_length(); fmt!("[%s x %u]", el_ty, len) } Pointer => { let el_ty = ty.element_type(); - let el_ty = self.type_to_str(el_ty); + let el_ty = self.type_to_str_depth(el_ty, depth-1); fmt!("*%s", el_ty) } _ => fail!("Unknown Type Kind (%u)", kind as uint) @@ -2201,6 +2207,10 @@ impl TypeNames { } } + pub fn type_to_str(&self, ty: Type) -> ~str { + self.type_to_str_depth(ty, 30) + } + pub fn val_to_str(&self, val: ValueRef) -> ~str { unsafe { let ty = Type::from_ref(llvm::LLVMTypeOf(val)); From a9e51f5f701d8104be0adfb50f5d409f8bf233ff Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Tue, 25 Jun 2013 14:07:44 -0700 Subject: [PATCH 258/336] Make default method handling not choke on self region params. Closes #7341. --- src/librustc/middle/trans/callee.rs | 7 ++++++- src/libstd/vec.rs | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 3405db8e52f6..27f1c4d039da 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -233,7 +233,12 @@ pub fn trans_fn_ref_with_vtables( // Polytype of the function item (may have type params) let fn_tpt = ty::lookup_item_type(tcx, def_id); - let substs = ty::substs { self_r: None, self_ty: None, + // For simplicity, we want to use the Subst trait when composing + // substitutions for default methods. The subst trait does + // substitutions with regions, though, so we put a dummy self + // region parameter in to keep it from failing. This is a hack. + let substs = ty::substs { self_r: Some(ty::re_empty), + self_ty: None, tps: /*bad*/ type_params.to_owned() }; diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index aa4d632a4827..8555d99255d5 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2346,6 +2346,7 @@ impl FromIter for ~[T]{ } } +#[cfg(stage0)] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let mut xs = ~[]; @@ -2356,7 +2357,8 @@ impl> FromIterator for ~[A] { } } -/* FIXME: #7341 - ICE + +#[cfg(not(stage0))] impl> FromIterator for ~[A] { pub fn from_iterator(iterator: &mut T) -> ~[A] { let (lower, _) = iterator.size_hint(); @@ -2367,7 +2369,7 @@ impl> FromIterator for ~[A] { xs } } -*/ + #[cfg(test)] mod tests { From 817f98085f2332b604f0a2da5127f29c8fabc41f Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Thu, 20 Jun 2013 09:29:24 -0700 Subject: [PATCH 259/336] Make calling methods parameterized on the trait work from default methods. This is done by adding a new notion of "vtable_self". We do not yet properly handle super traits. Closes #7183. --- src/librustc/middle/astencode.rs | 18 +++++++- src/librustc/middle/trans/base.rs | 1 + src/librustc/middle/trans/callee.rs | 31 ++++++++++++-- src/librustc/middle/trans/common.rs | 22 +++++++++- src/librustc/middle/trans/meth.rs | 41 ++++++++++--------- src/librustc/middle/trans/monomorphize.rs | 5 ++- src/librustc/middle/typeck/check/vtable.rs | 15 ++++++- src/librustc/middle/typeck/check/writeback.rs | 5 ++- src/librustc/middle/typeck/mod.rs | 10 ++++- 9 files changed, 117 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 70e94844319e..c1d553b04541 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -632,6 +632,13 @@ fn encode_vtable_origin(ecx: &e::EncodeContext, } } } + typeck::vtable_self(def_id) => { + do ebml_w.emit_enum_variant("vtable_self", 2u, 1u) |ebml_w| { + do ebml_w.emit_enum_variant_arg(0u) |ebml_w| { + ebml_w.emit_def_id(def_id) + } + } + } } } } @@ -652,7 +659,9 @@ impl vtable_decoder_helpers for reader::Decoder { fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext) -> typeck::vtable_origin { do self.read_enum("vtable_origin") |this| { - do this.read_enum_variant(["vtable_static", "vtable_param"]) + do this.read_enum_variant(["vtable_static", + "vtable_param", + "vtable_self"]) |this, i| { match i { 0 => { @@ -678,6 +687,13 @@ impl vtable_decoder_helpers for reader::Decoder { } ) } + 2 => { + typeck::vtable_self( + do this.read_enum_variant_arg(0u) |this| { + this.read_def_id(xcx) + } + ) + } // hard to avoid - user input _ => fail!("bad enum variant") } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index df7f73a52436..8e8270320c69 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -461,6 +461,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext, &tsubsts, None, None, + None, None); val diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 27f1c4d039da..dc18c6b17ee5 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -245,8 +245,9 @@ pub fn trans_fn_ref_with_vtables( // We need to do a bunch of special handling for default methods. // We need to modify the def_id and our substs in order to monomorphize // the function. - let (def_id, opt_impl_did, substs) = match tcx.provided_method_sources.find(&def_id) { - None => (def_id, None, substs), + let (def_id, opt_impl_did, substs, self_vtable) = + match tcx.provided_method_sources.find(&def_id) { + None => (def_id, None, substs, None), Some(source) => { // There are two relevant substitutions when compiling // default methods. First, there is the substitution for @@ -266,6 +267,26 @@ pub fn trans_fn_ref_with_vtables( default methods"); let method = ty::method(tcx, source.method_id); + // Get all of the type params for the receiver + let param_defs = method.generics.type_param_defs; + let receiver_substs = + type_params.initn(param_defs.len()).to_owned(); + let receiver_vtables = match vtables { + None => @~[], + Some(call_vtables) => { + let num_method_vtables = + ty::count_traits_and_supertraits(tcx, *param_defs); + @call_vtables.initn(num_method_vtables).to_owned() + } + }; + + let self_vtable = + typeck::vtable_static(source.impl_id, receiver_substs, + receiver_vtables); + + // XXX: I think that if the *trait* has vtables on it, + // it is all over + // Compute the first substitution let first_subst = make_substs_for_receiver_types( tcx, source.impl_id, trait_ref, method); @@ -279,7 +300,8 @@ pub fn trans_fn_ref_with_vtables( first_subst.repr(tcx), new_substs.repr(tcx)); - (source.method_id, Some(source.impl_id), new_substs) + (source.method_id, Some(source.impl_id), + new_substs, Some(self_vtable)) } }; @@ -326,7 +348,8 @@ pub fn trans_fn_ref_with_vtables( let (val, must_cast) = monomorphize::monomorphic_fn(ccx, def_id, &substs, - vtables, opt_impl_did, Some(ref_id)); + vtables, self_vtable, + opt_impl_did, Some(ref_id)); let mut val = val; if must_cast && ref_id != 0 { // Monotype of the REFERENCE to the function (type params diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index a7ffa8e13b02..b9e1ba7a8d9a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -132,7 +132,8 @@ pub struct param_substs { tys: ~[ty::t], vtables: Option, type_param_defs: @~[ty::TypeParameterDef], - self_ty: Option + self_ty: Option, + self_vtable: Option } impl param_substs { @@ -981,7 +982,11 @@ pub fn monomorphize_type(bcx: block, t: ty::t) -> ty::t { Some(substs) => { ty::subst_tps(bcx.tcx(), substs.tys, substs.self_ty, t) } - _ => { assert!(!ty::type_has_params(t)); t } + _ => { + assert!(!ty::type_has_params(t)); + assert!(!ty::type_has_self(t)); + t + } } } @@ -1063,6 +1068,19 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) } } } + typeck::vtable_self(_trait_id) => { + match fcx.param_substs { + Some(@param_substs + {self_vtable: Some(ref self_vtable), _}) => { + copy *self_vtable + } + _ => { + tcx.sess.bug(fmt!( + "resolve_vtable_in_fn_ctxt: asked to lookup but \ + no self_vtable in the fn_ctxt!")) + } + } + } } } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index fc0c9c06c450..5087fcca7886 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -139,7 +139,6 @@ pub fn trans_self_arg(bcx: block, // Compute the type of self. let self_ty = monomorphize_type(bcx, mentry.self_ty); - let result = trans_arg_expr(bcx, self_ty, mentry.self_mode, @@ -174,21 +173,6 @@ pub fn trans_method_callee(bcx: block, // Replace method_self with method_static here. let mut origin = mentry.origin; match origin { - typeck::method_self(trait_id, method_index) => { - // Get the ID of the impl we're inside. - let impl_def_id = bcx.fcx.impl_id.get(); - - debug!("impl_def_id is %?", impl_def_id); - - // Get the ID of the method we're calling. - let method_name = - ty::trait_method(tcx, trait_id, method_index).ident; - let method_id = - method_with_name_or_default(bcx.ccx(), - impl_def_id, - method_name); - origin = typeck::method_static(method_id); - } typeck::method_super(trait_id, method_index) => { // is the self type for this method call let self_ty = node_id_type(bcx, this.id); @@ -213,6 +197,7 @@ pub fn trans_method_callee(bcx: block, impl_id, method_name)); } + typeck::method_self(*) | typeck::method_static(*) | typeck::method_param(*) | typeck::method_trait(*) => {} } @@ -250,6 +235,21 @@ pub fn trans_method_callee(bcx: block, None => fail!("trans_method_callee: missing param_substs") } } + + typeck::method_self(trait_id, method_index) => { + match bcx.fcx.param_substs { + Some(@param_substs + {self_vtable: Some(ref vtbl), _}) => { + trans_monomorphized_callee(bcx, callee_id, this, mentry, + trait_id, method_index, + copy *vtbl) + } + _ => { + fail!("trans_method_callee: missing self_vtable") + } + } + } + typeck::method_trait(_, off, store) => { trans_trait_callee(bcx, callee_id, @@ -258,9 +258,9 @@ pub fn trans_method_callee(bcx: block, store, mentry.explicit_self) } - typeck::method_self(*) | typeck::method_super(*) => { - fail!("method_self or method_super should have been handled \ - above") + typeck::method_super(*) => { + fail!("method_super should have been handled \ + above") } } } @@ -460,6 +460,9 @@ pub fn trans_monomorphized_callee(bcx: block, typeck::vtable_param(*) => { fail!("vtable_param left in monomorphized function's vtable substs"); } + typeck::vtable_self(*) => { + fail!("vtable_self left in monomorphized function's vtable substs"); + } }; } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 586dfd7e98a0..06dec1995d94 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -43,6 +43,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, fn_id: ast::def_id, real_substs: &ty::substs, vtables: Option, + self_vtable: Option, impl_did_opt: Option, ref_id: Option) -> (ValueRef, bool) @@ -165,6 +166,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, let mut pt = /* bad */copy (*pt); pt.push(elt); let s = mangle_exported_name(ccx, /*bad*/copy pt, mono_ty); + debug!("monomorphize_fn mangled to %s", s); let mk_lldecl = || { let lldecl = decl_internal_cdecl_fn(ccx.llmod, /*bad*/copy s, llfty); @@ -176,7 +178,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, tys: substs, vtables: vtables, type_param_defs: tpt.generics.type_param_defs, - self_ty: real_substs.self_ty + self_ty: real_substs.self_ty, + self_vtable: self_vtable }); let lldecl = match map_node { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index bd78e9cc5fb4..a886e06139ec 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -17,8 +17,8 @@ use middle::typeck::check::{structurally_resolved_type}; use middle::typeck::infer::fixup_err_to_str; use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type}; use middle::typeck::infer; -use middle::typeck::{CrateCtxt, vtable_origin, vtable_param, vtable_res}; -use middle::typeck::vtable_static; +use middle::typeck::{CrateCtxt, vtable_origin, vtable_res}; +use middle::typeck::{vtable_static, vtable_param, vtable_self}; use middle::subst::Subst; use util::common::indenter; use util::ppaux::tys_to_str; @@ -237,6 +237,17 @@ fn lookup_vtable(vcx: &VtableContext, } } + ty::ty_self(trait_id) => { + debug!("trying to find %? vtable for type %?", + trait_ref.def_id, trait_id); + + if trait_id == trait_ref.def_id { + let vtable = vtable_self(trait_id); + debug!("found self vtable: %?", vtable); + return Some(vtable); + } + } + _ => { let mut found = ~[]; diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index dd9d68beb1fd..73710978ad49 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -20,7 +20,7 @@ use middle::typeck::check::{FnCtxt, SelfInfo}; use middle::typeck::infer::{force_all, resolve_all, resolve_region}; use middle::typeck::infer::resolve_type; use middle::typeck::infer; -use middle::typeck::{vtable_origin, vtable_static, vtable_param}; +use middle::typeck::{vtable_origin, vtable_static, vtable_param, vtable_self}; use middle::typeck::method_map_entry; use middle::typeck::write_substs_to_tcx; use middle::typeck::write_ty_to_tcx; @@ -104,6 +104,9 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) { &vtable_param(n, b) => { vtable_param(n, b) } + &vtable_self(def_id) => { + vtable_self(def_id) + } } } } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index d834998d4ee2..3511844bb9f4 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -154,7 +154,12 @@ pub enum vtable_origin { The first uint is the param number (identifying T in the example), and the second is the bound number (identifying baz) */ - vtable_param(uint, uint) + vtable_param(uint, uint), + + /* + Dynamic vtable, comes from self. + */ + vtable_self(ast::def_id) } impl Repr for vtable_origin { @@ -171,6 +176,9 @@ impl Repr for vtable_origin { vtable_param(x, y) => { fmt!("vtable_param(%?, %?)", x, y) } + vtable_self(def_id) => { + fmt!("vtable_self(%?)", def_id) + } } } } From 57ee34c2bf66a26527959b0a1dc2b7e23638e67b Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Sat, 22 Jun 2013 15:49:41 -0700 Subject: [PATCH 260/336] Actually resolve trait bounds on impls. Closes #7266. --- src/librustc/middle/typeck/check/mod.rs | 1 + src/librustc/middle/typeck/check/vtable.rs | 27 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 4c1c8e5c2c8a..23266767124c 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -609,6 +609,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) { for ms.iter().advance |m| { check_method(ccx, *m); } + vtable::resolve_impl(ccx, it); } ast::item_trait(_, _, ref trait_methods) => { for (*trait_methods).iter().advance |trait_method| { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index a886e06139ec..03348d5a1dc0 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -478,6 +478,12 @@ pub fn location_info_for_expr(expr: @ast::expr) -> LocationInfo { id: expr.id } } +pub fn location_info_for_item(item: @ast::item) -> LocationInfo { + LocationInfo { + span: item.span, + id: item.id + } +} pub fn early_resolve_expr(ex: @ast::expr, fcx: @mut FnCtxt, @@ -661,6 +667,27 @@ fn resolve_expr(ex: @ast::expr, visit::visit_expr(ex, (fcx, v)); } +pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) { + let def_id = ast_util::local_def(impl_item.id); + match ty::impl_trait_ref(ccx.tcx, def_id) { + None => {}, + Some(trait_ref) => { + let infcx = infer::new_infer_ctxt(ccx.tcx); + let vcx = VtableContext { ccx: ccx, infcx: infcx }; + let trait_def = ty::lookup_trait_def(ccx.tcx, trait_ref.def_id); + + let vtbls = lookup_vtables(&vcx, + &location_info_for_item(impl_item), + *trait_def.generics.type_param_defs, + &trait_ref.substs, + false); + + // FIXME(#7450): Doesn't work cross crate + ccx.vtable_map.insert(impl_item.id, vtbls); + } + } +} + // Detect points where a trait-bounded type parameter is // instantiated, resolve the impls for the parameters. pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::blk) { From 649b26f7c64a573b2d1ee03a0b866dd351510338 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Wed, 26 Jun 2013 17:20:53 -0700 Subject: [PATCH 261/336] Rework vtable_res to not be flattened. It is now a list of the resolutions for each param. --- src/librustc/middle/astencode.rs | 10 ++- src/librustc/middle/trans/callee.rs | 26 +++++- src/librustc/middle/trans/common.rs | 11 +-- src/librustc/middle/trans/meth.rs | 85 +++++-------------- src/librustc/middle/trans/monomorphize.rs | 12 +-- src/librustc/middle/typeck/check/vtable.rs | 7 +- src/librustc/middle/typeck/check/writeback.rs | 12 ++- src/librustc/middle/typeck/mod.rs | 3 +- 8 files changed, 76 insertions(+), 90 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index c1d553b04541..16e3bd34cdde 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -599,8 +599,10 @@ fn encode_vtable_res(ecx: &e::EncodeContext, // ty::t doesn't work, and there is no way (atm) to have // hand-written encoding routines combine with auto-generated // ones. perhaps we should fix this. - do ebml_w.emit_from_vec(*dr) |ebml_w, vtable_origin| { - encode_vtable_origin(ecx, ebml_w, vtable_origin) + do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| { + do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| { + encode_vtable_origin(ecx, ebml_w, vtable_origin) + } } } @@ -653,7 +655,9 @@ trait vtable_decoder_helpers { impl vtable_decoder_helpers for reader::Decoder { fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext) -> typeck::vtable_res { - @self.read_to_vec(|this| this.read_vtable_origin(xcx)) + @self.read_to_vec(|this| + @this.read_to_vec(|this| + this.read_vtable_origin(xcx))) } fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index dc18c6b17ee5..7032b559f76f 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -17,6 +17,7 @@ // closure. use core::prelude::*; +use core::vec; use back::abi; use driver::session; @@ -274,9 +275,7 @@ pub fn trans_fn_ref_with_vtables( let receiver_vtables = match vtables { None => @~[], Some(call_vtables) => { - let num_method_vtables = - ty::count_traits_and_supertraits(tcx, *param_defs); - @call_vtables.initn(num_method_vtables).to_owned() + @call_vtables.initn(param_defs.len()).to_owned() } }; @@ -305,6 +304,27 @@ pub fn trans_fn_ref_with_vtables( } }; + // XXX: this is *completely* bad and wrong. I feel bad. Handling + // of vtables is currently bogus for default methods, and changing + // to an unflattented representation of vtables causes this to + // show up in cases that it did not previously. We need to make + // the vtables list be the same length as the substs. There is + // nothing right about this. I really need to emphasize just how + // wrong it is: it is completely wrong. + // XXX: bad. + // This will be fixed in the next commit. + let vtables = do vtables.map |vtbls| { + if vtbls.len() < substs.tps.len() { + @(vec::from_elem(substs.tps.len() - vtbls.len(), @~[]) + + **vtbls) + } else if vtbls.len() > substs.tps.len() { + @vtbls.tailn(vtbls.len() - substs.tps.len()).to_owned() + } else { + *vtbls + } + }; + + // Check whether this fn has an inlined copy and, if so, redirect // def_id to the local id of the inlined copy. let def_id = { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b9e1ba7a8d9a..b30510062389 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1035,7 +1035,8 @@ pub fn node_vtables(bcx: block, id: ast::node_id) pub fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res) -> typeck::vtable_res { - @vec::map(*vts, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d)) + @vec::map(*vts, |ds| + @vec::map(**ds, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d))) } // Apply the typaram substitutions in the fn_ctxt to a vtable. This should @@ -1090,13 +1091,7 @@ pub fn find_vtable(tcx: ty::ctxt, ps: ¶m_substs, debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)", n_param, n_bound, ps.repr(tcx)); - // Vtables are stored in a flat array, finding the right one is - // somewhat awkward - let first_n_type_param_defs = ps.type_param_defs.slice(0, n_param); - let vtables_to_skip = - ty::count_traits_and_supertraits(tcx, first_n_type_param_defs); - let vtable_off = vtables_to_skip + n_bound; - /*bad*/ copy ps.vtables.get()[vtable_off] + /*bad*/ copy ps.vtables.get()[n_param][n_bound] } pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 5087fcca7886..11ae094b799f 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -292,15 +292,9 @@ pub fn trans_static_method_callee(bcx: block, // // So when we see a call to this function foo, we have to figure // out which impl the `Trait` bound on the type `self` was - // bound to. Due to the fact that we use a flattened list of - // impls, one per bound, this means we have to total up the bounds - // found on the type parametesr T1...Tn to find the index of the - // one we are interested in. - let bound_index = { - let trait_def = ty::lookup_trait_def(bcx.tcx(), trait_id); - ty::count_traits_and_supertraits( - bcx.tcx(), *trait_def.generics.type_param_defs) - }; + // bound to. + let bound_index = ty::lookup_trait_def(bcx.tcx(), trait_id). + generics.type_param_defs.len(); let mname = if method_id.crate == ast::local_crate { match bcx.tcx().items.get_copy(&method_id.node) { @@ -322,17 +316,17 @@ pub fn trans_static_method_callee(bcx: block, let vtbls = resolve_vtables_in_fn_ctxt( bcx.fcx, ccx.maps.vtable_map.get_copy(&callee_id)); - match vtbls[bound_index] { + match vtbls[bound_index][0] { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t))); let mth_id = method_with_name_or_default(bcx.ccx(), impl_did, mname); - let callee_substs = combine_impl_and_methods_tps( - bcx, mth_id, impl_did, callee_id, *rcvr_substs); - let callee_origins = combine_impl_and_methods_origins( - bcx, mth_id, impl_did, callee_id, rcvr_origins); + let (callee_substs, callee_origins) = + combine_impl_and_methods_tps( + bcx, mth_id, impl_did, callee_id, + *rcvr_substs, rcvr_origins); let FnData {llfn: lval} = trans_fn_ref_with_vtables(bcx, @@ -428,10 +422,10 @@ pub fn trans_monomorphized_callee(bcx: block, // create a concatenated set of substitutions which includes // those from the impl and those from the method: - let callee_substs = combine_impl_and_methods_tps( - bcx, mth_id, impl_did, callee_id, *rcvr_substs); - let callee_origins = combine_impl_and_methods_origins( - bcx, mth_id, impl_did, callee_id, rcvr_origins); + let (callee_substs, callee_origins) = + combine_impl_and_methods_tps( + bcx, mth_id, impl_did, callee_id, + *rcvr_substs, rcvr_origins); // translate the function let callee = trans_fn_ref_with_vtables(bcx, @@ -471,8 +465,9 @@ pub fn combine_impl_and_methods_tps(bcx: block, mth_did: ast::def_id, impl_did: ast::def_id, callee_id: ast::node_id, - rcvr_substs: &[ty::t]) - -> ~[ty::t] { + rcvr_substs: &[ty::t], + rcvr_origins: typeck::vtable_res) + -> (~[ty::t], typeck::vtable_res) { /*! * * Creates a concatenated set of substitutions which includes @@ -501,52 +496,18 @@ pub fn combine_impl_and_methods_tps(bcx: block, debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t))); debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t))); - return ty_substs; -} -pub fn combine_impl_and_methods_origins(bcx: block, - mth_did: ast::def_id, - impl_did: ast::def_id, - callee_id: ast::node_id, - rcvr_origins: typeck::vtable_res) - -> typeck::vtable_res { - /*! - * - * Similar to `combine_impl_and_methods_tps`, but for vtables. - * This is much messier because of the flattened layout we are - * currently using (for some reason that I fail to understand). - * The proper fix is described in #3446. - */ - - - // Find the bounds for the method, which are the tail of the - // bounds found in the item type, as the item type combines the - // rcvr + method bounds. - let ccx = bcx.ccx(); - let tcx = bcx.tcx(); - let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did); - let ty::ty_param_bounds_and_ty { - generics: r_m_generics, - _ - } = ty::lookup_item_type(tcx, mth_did); - let n_r_m_tps = r_m_generics.type_param_defs.len(); // rcvr + method tps - let m_type_param_defs = - r_m_generics.type_param_defs.slice(n_r_m_tps - n_m_tps, n_r_m_tps); - - // Flatten out to find the number of vtables the method expects. - let m_vtables = ty::count_traits_and_supertraits(tcx, m_type_param_defs); - - // Find the vtables we computed at type check time and monomorphize them + // Now, do the same work for the vtables. The vtables might not + // exist, in which case we need to make them. let r_m_origins = match node_vtables(bcx, callee_id) { Some(vt) => vt, - None => @~[] + None => @vec::from_elem(node_substs.len(), @~[]) }; + let vtables + = @vec::append(rcvr_origins.to_owned(), + r_m_origins.tailn(r_m_origins.len() - n_m_tps)); - // Extract those that belong to method: - let m_origins = r_m_origins.tailn(r_m_origins.len() - m_vtables); - - // Combine rcvr + method to find the final result: - @vec::append(/*bad*/copy *rcvr_origins, m_origins) + return (ty_substs, vtables); } @@ -845,7 +806,7 @@ pub fn trans_trait_cast(bcx: block, bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); // Store the vtable into the pair or triple. - let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0]; + let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0][0]; let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig); let vtable = get_vtable(bcx, v_ty, orig); Store(bcx, vtable, PointerCast(bcx, diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 06dec1995d94..3011f0c5d844 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -340,14 +340,10 @@ pub fn make_mono_id(ccx: @mut CrateContext, param_uses: Option<@~[type_use::type_uses]>) -> mono_id { let precise_param_ids = match vtables { Some(vts) => { - let item_ty = ty::lookup_item_type(ccx.tcx, item); - let mut i = 0; - vec::map_zip(*item_ty.generics.type_param_defs, substs, |type_param_def, subst| { - let mut v = ~[]; - for type_param_def.bounds.trait_bounds.iter().advance |_bound| { - v.push(meth::vtable_id(ccx, &vts[i])); - i += 1; - } + debug!("make_mono_id vtables=%s substs=%s", + vts.repr(ccx.tcx), substs.repr(ccx.tcx)); + vec::map_zip(*vts, substs, |vtable, subst| { + let v = vtable.map(|vt| meth::vtable_id(ccx, vt)); (*subst, if !v.is_empty() { Some(@v) } else { None }) }) } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 03348d5a1dc0..0bf20f9fbcb9 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -90,6 +90,7 @@ fn lookup_vtables(vcx: &VtableContext, let mut i = 0u; for substs.tps.iter().advance |ty| { // ty is the value supplied for the type parameter A... + let mut param_result = ~[]; for ty::each_bound_trait_and_supertraits( tcx, type_param_defs[i].bounds) |trait_ref| @@ -106,7 +107,7 @@ fn lookup_vtables(vcx: &VtableContext, debug!("after subst: %s", trait_ref.repr(tcx)); match lookup_vtable(vcx, location_info, *ty, &trait_ref, is_early) { - Some(vtable) => result.push(vtable), + Some(vtable) => param_result.push(vtable), None => { vcx.tcx().sess.span_fatal( location_info.span, @@ -117,6 +118,7 @@ fn lookup_vtables(vcx: &VtableContext, } } } + result.push(@param_result); i += 1u; } debug!("lookup_vtables result(\ @@ -600,7 +602,8 @@ pub fn early_resolve_expr(ex: @ast::expr, // vtable (that is: "ex has vtable // ") if !is_early { - insert_vtables(fcx, ex.id, @~[vtable]); + insert_vtables(fcx, ex.id, + @~[@~[vtable]]); } } None => { diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 73710978ad49..e2efdc51fcad 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -20,7 +20,8 @@ use middle::typeck::check::{FnCtxt, SelfInfo}; use middle::typeck::infer::{force_all, resolve_all, resolve_region}; use middle::typeck::infer::resolve_type; use middle::typeck::infer; -use middle::typeck::{vtable_origin, vtable_static, vtable_param, vtable_self}; +use middle::typeck::{vtable_res, vtable_origin}; +use middle::typeck::{vtable_static, vtable_param, vtable_self}; use middle::typeck::method_map_entry; use middle::typeck::write_substs_to_tcx; use middle::typeck::write_ty_to_tcx; @@ -84,7 +85,7 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) { match fcx.inh.vtable_map.find(&id) { None => {} Some(origins) => { - let r_origins = @origins.map(|o| resolve_origin(fcx, sp, o)); + let r_origins = resolve_origins(fcx, sp, *origins); let vtable_map = fcx.ccx.vtable_map; vtable_map.insert(id, r_origins); debug!("writeback::resolve_vtable_map_entry(id=%d, vtables=%?)", @@ -92,13 +93,18 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) { } } + fn resolve_origins(fcx: @mut FnCtxt, sp: span, + vtbls: vtable_res) -> vtable_res { + @vtbls.map(|os| @os.map(|o| resolve_origin(fcx, sp, o))) + } + fn resolve_origin(fcx: @mut FnCtxt, sp: span, origin: &vtable_origin) -> vtable_origin { match origin { &vtable_static(def_id, ref tys, origins) => { let r_tys = resolve_type_vars_in_types(fcx, sp, *tys); - let r_origins = @origins.map(|o| resolve_origin(fcx, sp, o)); + let r_origins = resolve_origins(fcx, sp, origins); vtable_static(def_id, r_tys, r_origins) } &vtable_param(n, b) => { diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 3511844bb9f4..98f7af4bfd4d 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -135,8 +135,9 @@ pub struct method_map_entry { // of the method to be invoked pub type method_map = @mut HashMap; +pub type vtable_param_res = @~[vtable_origin]; // Resolutions for bounds of all parameters, left to right, for a given path. -pub type vtable_res = @~[vtable_origin]; +pub type vtable_res = @~[vtable_param_res]; pub enum vtable_origin { /* From 0252693db21f48a516f9a36cdeb8b2dd7e33bd02 Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Fri, 28 Jun 2013 11:18:09 -0700 Subject: [PATCH 262/336] Improve handling of trait bounds on a trait in default methods. This is work on #7460. It does not properly handle certain cross crate situations, because we don't properly export vtable resolution information. --- src/librustc/middle/trans/callee.rs | 96 +++++++++++++++++++---------- src/librustc/middle/trans/common.rs | 36 ++++++++--- 2 files changed, 93 insertions(+), 39 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 7032b559f76f..4c07f88f16eb 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -195,6 +195,58 @@ pub fn trans_fn_ref_with_vtables_to_callee( type_params, vtables))} } +fn get_impl_resolutions(bcx: block, + impl_id: ast::def_id) + -> typeck::vtable_res { + if impl_id.crate == ast::local_crate { + *bcx.ccx().maps.vtable_map.get(&impl_id.node) + } else { + // XXX: This is a temporary hack to work around not properly + // exporting information about resolutions for impls. + // This doesn't actually work if the trait has param bounds, + // but it does allow us to survive the case when it does not. + let trait_ref = ty::impl_trait_ref(bcx.tcx(), impl_id).get(); + @vec::from_elem(trait_ref.substs.tps.len(), @~[]) + } +} + +fn resolve_default_method_vtables(bcx: block, + impl_id: ast::def_id, + method: &ty::Method, + substs: &ty::substs, + impl_vtables: Option) + -> typeck::vtable_res { + + // Get the vtables that the impl implements the trait at + let trait_vtables = get_impl_resolutions(bcx, impl_id); + + // Build up a param_substs that we are going to resolve the + // trait_vtables under. + let param_substs = Some(@param_substs { + tys: copy substs.tps, + self_ty: substs.self_ty, + vtables: impl_vtables, + self_vtable: None + }); + + let trait_vtables_fixed = resolve_vtables_under_param_substs( + bcx.tcx(), param_substs, trait_vtables); + + // Now we pull any vtables for parameters on the actual method. + let num_method_vtables = method.generics.type_param_defs.len(); + let method_vtables = match impl_vtables { + Some(vtables) => { + let num_impl_type_parameters = + vtables.len() - num_method_vtables; + vtables.tailn(num_impl_type_parameters).to_owned() + }, + None => vec::from_elem(num_method_vtables, @~[]) + }; + + @(*trait_vtables_fixed + method_vtables) +} + + pub fn trans_fn_ref_with_vtables( bcx: block, // def_id: ast::def_id, // def id of fn @@ -246,9 +298,9 @@ pub fn trans_fn_ref_with_vtables( // We need to do a bunch of special handling for default methods. // We need to modify the def_id and our substs in order to monomorphize // the function. - let (def_id, opt_impl_did, substs, self_vtable) = + let (def_id, opt_impl_did, substs, self_vtable, vtables) = match tcx.provided_method_sources.find(&def_id) { - None => (def_id, None, substs, None), + None => (def_id, None, substs, None, vtables), Some(source) => { // There are two relevant substitutions when compiling // default methods. First, there is the substitution for @@ -282,49 +334,31 @@ pub fn trans_fn_ref_with_vtables( let self_vtable = typeck::vtable_static(source.impl_id, receiver_substs, receiver_vtables); - - // XXX: I think that if the *trait* has vtables on it, - // it is all over - // Compute the first substitution let first_subst = make_substs_for_receiver_types( tcx, source.impl_id, trait_ref, method); // And compose them let new_substs = first_subst.subst(tcx, &substs); + + + let vtables = + resolve_default_method_vtables(bcx, source.impl_id, + method, &new_substs, vtables); + debug!("trans_fn_with_vtables - default method: \ substs = %s, trait_subst = %s, \ - first_subst = %s, new_subst = %s", + first_subst = %s, new_subst = %s, \ + self_vtable = %s, vtables = %s", substs.repr(tcx), trait_ref.substs.repr(tcx), - first_subst.repr(tcx), new_substs.repr(tcx)); - + first_subst.repr(tcx), new_substs.repr(tcx), + self_vtable.repr(tcx), vtables.repr(tcx)); (source.method_id, Some(source.impl_id), - new_substs, Some(self_vtable)) + new_substs, Some(self_vtable), Some(vtables)) } }; - // XXX: this is *completely* bad and wrong. I feel bad. Handling - // of vtables is currently bogus for default methods, and changing - // to an unflattented representation of vtables causes this to - // show up in cases that it did not previously. We need to make - // the vtables list be the same length as the substs. There is - // nothing right about this. I really need to emphasize just how - // wrong it is: it is completely wrong. - // XXX: bad. - // This will be fixed in the next commit. - let vtables = do vtables.map |vtbls| { - if vtbls.len() < substs.tps.len() { - @(vec::from_elem(substs.tps.len() - vtbls.len(), @~[]) + - **vtbls) - } else if vtbls.len() > substs.tps.len() { - @vtbls.tailn(vtbls.len() - substs.tps.len()).to_owned() - } else { - *vtbls - } - }; - - // Check whether this fn has an inlined copy and, if so, redirect // def_id to the local id of the inlined copy. let def_id = { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b30510062389..653687ea39f9 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1035,18 +1035,37 @@ pub fn node_vtables(bcx: block, id: ast::node_id) pub fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res) -> typeck::vtable_res { - @vec::map(*vts, |ds| - @vec::map(**ds, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d))) + resolve_vtables_under_param_substs(fcx.ccx.tcx, + fcx.param_substs, + vts) } +pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt, + param_substs: Option<@param_substs>, + vts: typeck::vtable_res) + -> typeck::vtable_res { + @vec::map(*vts, |ds| + @vec::map(**ds, |d| + resolve_vtable_under_param_substs(tcx, param_substs, copy *d))) +} + + // Apply the typaram substitutions in the fn_ctxt to a vtable. This should // eliminate any vtable_params. pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) -> typeck::vtable_origin { - let tcx = fcx.ccx.tcx; + resolve_vtable_under_param_substs(fcx.ccx.tcx, + fcx.param_substs, + vt) +} + +pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt, + param_substs: Option<@param_substs>, + vt: typeck::vtable_origin) + -> typeck::vtable_origin { match vt { typeck::vtable_static(trait_id, tys, sub) => { - let tys = match fcx.param_substs { + let tys = match param_substs { Some(substs) => { do vec::map(tys) |t| { ty::subst_tps(tcx, substs.tys, substs.self_ty, *t) @@ -1054,11 +1073,12 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) } _ => tys }; - typeck::vtable_static(trait_id, tys, - resolve_vtables_in_fn_ctxt(fcx, sub)) + typeck::vtable_static( + trait_id, tys, + resolve_vtables_under_param_substs(tcx, param_substs, sub)) } typeck::vtable_param(n_param, n_bound) => { - match fcx.param_substs { + match param_substs { Some(substs) => { find_vtable(tcx, substs, n_param, n_bound) } @@ -1070,7 +1090,7 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin) } } typeck::vtable_self(_trait_id) => { - match fcx.param_substs { + match param_substs { Some(@param_substs {self_vtable: Some(ref self_vtable), _}) => { copy *self_vtable From 59431187284b377bdffdf16eda01c9239359592e Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Thu, 27 Jun 2013 17:43:34 -0700 Subject: [PATCH 263/336] Drop an unused field from param_substs. --- src/librustc/middle/trans/common.rs | 8 +++----- src/librustc/middle/trans/monomorphize.rs | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 653687ea39f9..94a618b2d85e 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -130,9 +130,8 @@ pub struct ValSelfData { // will only be set in the case of default methods. pub struct param_substs { tys: ~[ty::t], - vtables: Option, - type_param_defs: @~[ty::TypeParameterDef], self_ty: Option, + vtables: Option, self_vtable: Option } @@ -144,10 +143,9 @@ impl param_substs { } fn param_substs_to_str(this: ¶m_substs, tcx: ty::ctxt) -> ~str { - fmt!("param_substs {tys:%s, vtables:%s, type_param_defs:%s}", + fmt!("param_substs {tys:%s, vtables:%s}", this.tys.repr(tcx), - this.vtables.repr(tcx), - this.type_param_defs.repr(tcx)) + this.vtables.repr(tcx)) } impl Repr for param_substs { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 3011f0c5d844..cc6ca55ccc74 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -177,7 +177,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, let psubsts = Some(@param_substs { tys: substs, vtables: vtables, - type_param_defs: tpt.generics.type_param_defs, self_ty: real_substs.self_ty, self_vtable: self_vtable }); From c05165bf93e05a8473461716579c47355bd1659d Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Fri, 28 Jun 2013 11:11:47 -0700 Subject: [PATCH 264/336] Drop the impl_id field from fn_ctxt. --- src/librustc/middle/trans/base.rs | 14 ++------------ src/librustc/middle/trans/closure.rs | 1 - src/librustc/middle/trans/common.rs | 3 --- src/librustc/middle/trans/foreign.rs | 2 -- src/librustc/middle/trans/inline.rs | 1 - src/librustc/middle/trans/meth.rs | 7 ++----- src/librustc/middle/trans/monomorphize.rs | 17 +++-------------- 7 files changed, 7 insertions(+), 38 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 8e8270320c69..efa69ab5e625 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1545,17 +1545,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, llfndecl: ValueRef, id: ast::node_id, output_type: ty::t, - impl_id: Option, param_substs: Option<@param_substs>, sp: Option) -> fn_ctxt { for param_substs.iter().advance |p| { p.validate(); } - debug!("new_fn_ctxt_w_id(path=%s, id=%?, impl_id=%?, \ + debug!("new_fn_ctxt_w_id(path=%s, id=%?, \ param_substs=%s)", path_str(ccx.sess, path), id, - impl_id, param_substs.repr(ccx.tcx)); let llbbs = mk_standard_basic_blocks(llfndecl); @@ -1584,7 +1582,6 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, lllocals: @mut HashMap::new(), llupvars: @mut HashMap::new(), id: id, - impl_id: impl_id, param_substs: param_substs, span: sp, path: path, @@ -1605,7 +1602,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext, output_type: ty::t, sp: Option) -> fn_ctxt { - new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, None, sp) + new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp) } // NB: must keep 4 fns in sync: @@ -1774,7 +1771,6 @@ pub fn trans_closure(ccx: @mut CrateContext, self_arg: self_arg, param_substs: Option<@param_substs>, id: ast::node_id, - impl_id: Option, attributes: &[ast::attribute], output_type: ty::t, maybe_load_env: &fn(fn_ctxt), @@ -1792,7 +1788,6 @@ pub fn trans_closure(ccx: @mut CrateContext, llfndecl, id, output_type, - impl_id, param_substs, Some(body.span)); let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); @@ -1851,7 +1846,6 @@ pub fn trans_fn(ccx: @mut CrateContext, self_arg: self_arg, param_substs: Option<@param_substs>, id: ast::node_id, - impl_id: Option, attrs: &[ast::attribute]) { let do_time = ccx.sess.trans_stats(); let start = if do_time { time::get_time() } @@ -1871,7 +1865,6 @@ pub fn trans_fn(ccx: @mut CrateContext, self_arg, param_substs, id, - impl_id, attrs, output_type, |fcx| { @@ -1921,7 +1914,6 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, llfndecl, variant.node.id, enum_ty, - None, param_substs, None); @@ -2001,7 +1993,6 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, llfndecl, ctor_id, tup_ty, - None, param_substs, None); @@ -2081,7 +2072,6 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { no_self, None, item.id, - None, item.attrs); } else { for body.node.stmts.iter().advance |stmt| { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 3ce52a63171e..ad68ffb402e1 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -444,7 +444,6 @@ pub fn trans_expr_fn(bcx: block, no_self, /*bad*/ copy bcx.fcx.param_substs, user_id, - None, [], real_return_type, |fcx| load_environment(fcx, cdata_ty, cap_vars, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 94a618b2d85e..7624fb13903f 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -222,9 +222,6 @@ pub struct fn_ctxt_ { // a user-defined function. id: ast::node_id, - // The def_id of the impl we're inside, or None if we aren't inside one. - impl_id: Option, - // If this function is being monomorphized, this contains the type // substitutions used. param_substs: Option<@param_substs>, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 6263ffb318eb..7672f3b615d0 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -555,7 +555,6 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, decl, item.id, output_type, - None, Some(substs), Some(item.span)); @@ -1183,7 +1182,6 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, no_self, None, id, - None, []); return llfndecl; } diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 01849ac6e8f1..11c02f165b6f 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -127,7 +127,6 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, self_kind, None, mth.id, - Some(impl_did), []); } local_def(mth.id) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 11ae094b799f..f145f83f13c2 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -68,8 +68,7 @@ pub fn trans_impl(ccx: @mut CrateContext, path, *method, None, - llfn, - ast_util::local_def(id)); + llfn); } } } @@ -90,8 +89,7 @@ pub fn trans_method(ccx: @mut CrateContext, path: path, method: &ast::method, param_substs: Option<@param_substs>, - llfn: ValueRef, - impl_id: ast::def_id) { + llfn: ValueRef) { // figure out how self is being passed let self_arg = match method.explicit_self.node { ast::sty_static => { @@ -127,7 +125,6 @@ pub fn trans_method(ccx: @mut CrateContext, self_arg, param_substs, method.id, - Some(impl_id), []); } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index cc6ca55ccc74..92d8192aee62 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -196,7 +196,6 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, no_self, psubsts, fn_id.node, - None, []); d } @@ -224,27 +223,17 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, } d } - ast_map::node_method(mth, supplied_impl_did, _) => { + ast_map::node_method(mth, _, _) => { // XXX: What should the self type be here? let d = mk_lldecl(); set_inline_hint_if_appr(/*bad*/copy mth.attrs, d); - - // Override the impl def ID if necessary. - let impl_did; - match impl_did_opt { - None => impl_did = supplied_impl_did, - Some(override_impl_did) => impl_did = override_impl_did - } - - meth::trans_method(ccx, pt, mth, psubsts, d, impl_did); + meth::trans_method(ccx, pt, mth, 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); - debug!("monomorphic_fn impl_did_opt is %?", impl_did_opt); - meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, d, - impl_did_opt.get()); + meth::trans_method(ccx, /*bad*/copy *pt, mth, psubsts, d); d } ast_map::node_struct_ctor(struct_def, _, _) => { From 9340fd5ce0d7bd0f1bbfbda73944920bcc1364eb Mon Sep 17 00:00:00 2001 From: Michael Sullivan Date: Fri, 28 Jun 2013 17:47:44 -0700 Subject: [PATCH 265/336] Add tests for some default method things. --- src/test/compile-fail/impl-bounds-checking.rs | 24 ++++++++++ src/test/run-pass/bug-7183-generics.rs | 45 +++++++++++++++++++ .../run-pass/trait-with-bounds-default.rs | 41 +++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 src/test/compile-fail/impl-bounds-checking.rs create mode 100644 src/test/run-pass/bug-7183-generics.rs create mode 100644 src/test/run-pass/trait-with-bounds-default.rs diff --git a/src/test/compile-fail/impl-bounds-checking.rs b/src/test/compile-fail/impl-bounds-checking.rs new file mode 100644 index 000000000000..00c415a860d4 --- /dev/null +++ b/src/test/compile-fail/impl-bounds-checking.rs @@ -0,0 +1,24 @@ +// 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. + +pub trait Clone2 { + fn clone(&self) -> Self; +} + + +trait Getter { + fn get(&self) -> T; +} + +impl Getter for int { //~ ERROR failed to find an implementation of trait Clone2 for int + fn get(&self) -> int { *self } +} + +fn main() { } diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs new file mode 100644 index 000000000000..4fc5587e7f36 --- /dev/null +++ b/src/test/run-pass/bug-7183-generics.rs @@ -0,0 +1,45 @@ +// 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. + +#[allow(default_methods)] +trait Speak { + fn say(&self, s:&str) -> ~str; + fn hi(&self) -> ~str { hello(self) } +} + +fn hello(s:&S) -> ~str{ + s.say("hello") +} + +impl Speak for int { + fn say(&self, s:&str) -> ~str { + fmt!("%s: %d", s, *self) + } +} + +impl Speak for Option { + fn say(&self, s:&str) -> ~str { + match *self { + None => fmt!("%s - none", s), + Some(ref x) => { ~"something!" + x.say(s) } + } + } +} + + +fn main() { + assert_eq!(3.hi(), ~"hello: 3"); + 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"); +} diff --git a/src/test/run-pass/trait-with-bounds-default.rs b/src/test/run-pass/trait-with-bounds-default.rs new file mode 100644 index 000000000000..b3ddbbb9dc11 --- /dev/null +++ b/src/test/run-pass/trait-with-bounds-default.rs @@ -0,0 +1,41 @@ +// 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. + +pub trait Clone2 { + /// Returns a copy of the value. The contents of owned pointers + /// are copied to maintain uniqueness, while the contents of + /// managed pointers are not copied. + fn clone(&self) -> Self; +} + +#[allow(default_methods)] +trait Getter { + fn do_get(&self) -> T; + + fn do_get2(&self) -> (T, T) { + let x = self.do_get(); + (x.clone(), x.clone()) + } + +} + +impl Getter for int { + fn do_get(&self) -> int { *self } +} + +impl Getter for Option { + fn do_get(&self) -> T { self.get_ref().clone() } +} + + +fn main() { + assert_eq!(3.do_get2(), (3, 3)); + assert_eq!(Some(~"hi").do_get2(), (~"hi", ~"hi")); +} From 647b4a6bcd921507943a60fcc413f4ae69b2609c Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 29 Jun 2013 04:53:52 +0200 Subject: [PATCH 266/336] Optimize str::each_split_within when it is called with large limits --- src/libstd/str.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 2144afc0fbd1..acf136689dc6 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -434,10 +434,17 @@ pub fn each_split_within<'a>(ss: &'a str, let mut last_start = 0; let mut last_end = 0; let mut state = A; + let mut fake_i = ss.len(); + let mut lim = lim; let mut cont = true; let slice: &fn() = || { cont = it(ss.slice(slice_start, last_end)) }; + // if the limit is larger than the string, lower it to save cycles + if (lim >= fake_i) { + lim = fake_i; + } + let machine: &fn((uint, char)) -> bool = |(i, c)| { let whitespace = if char::is_whitespace(c) { Ws } else { Cr }; let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim }; @@ -466,7 +473,6 @@ pub fn each_split_within<'a>(ss: &'a str, ss.iter().enumerate().advance(machine); // Let the automaton 'run out' by supplying trailing whitespace - let mut fake_i = ss.len(); while cont && match state { B | C => true, A => false } { machine((fake_i, ' ')); fake_i += 1; @@ -2299,6 +2305,7 @@ mod tests { use libc; use ptr; use str::*; + use uint; use vec; use vec::{ImmutableVector, CopyableVector}; use cmp::{TotalOrd, Less, Equal, Greater}; @@ -2444,6 +2451,8 @@ mod tests { t("hello", 15, [~"hello"]); t("\nMary had a little lamb\nLittle lamb\n", 15, [~"Mary had a", ~"little lamb", ~"Little lamb"]); + t("\nMary had a little lamb\nLittle lamb\n", uint::max_value, + [~"Mary had a little lamb\nLittle lamb"]); } #[test] From 4af7ebcd8f72356880abccc411a1632e8f07e1c1 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 28 Jun 2013 14:33:58 -0700 Subject: [PATCH 267/336] Rename #[non_sendable] to #[no_send] --- src/libextra/rc.rs | 4 ++-- src/librustc/middle/ty.rs | 4 ++-- src/test/compile-fail/non_owned-enum.rs | 2 +- src/test/compile-fail/non_owned-struct.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 009d68ac0260..31fed541bb12 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -36,7 +36,7 @@ struct RcBox { /// Immutable reference counted pointer type #[unsafe_no_drop_flag] -#[non_sendable] +#[no_send] pub struct Rc { priv ptr: *mut RcBox, } @@ -168,7 +168,7 @@ struct RcMutBox { /// Mutable reference counted pointer type #[non_owned] -#[non_sendable] +#[no_send] #[mutable] #[unsafe_no_drop_flag] pub struct RcMut { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 175529be2062..03a73c847ee6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1969,7 +1969,7 @@ static TC_ONCE_CLOSURE: TypeContents = TypeContents{bits: 0b0001_0000_0000}; /// An enum with no variants. static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000}; -/// Contains a type marked with `#[non_sendable]` +/// Contains a type marked with `#[no_send]` static TC_NON_SENDABLE: TypeContents = TypeContents{bits: 0b0100_0000_0000}; /// Is a bare vector, str, function, trait, etc (only relevant at top level). @@ -2207,7 +2207,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { if has_attr(cx, did, "mutable") { tc = tc + TC_MUTABLE; } - if has_attr(cx, did, "non_sendable") { + if has_attr(cx, did, "no_send") { tc = tc + TC_NON_SENDABLE; } tc diff --git a/src/test/compile-fail/non_owned-enum.rs b/src/test/compile-fail/non_owned-enum.rs index 20b571ad6141..b436bfb8b0fd 100644 --- a/src/test/compile-fail/non_owned-enum.rs +++ b/src/test/compile-fail/non_owned-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[non_sendable] +#[no_send] enum Foo { A } fn bar(_: T) {} diff --git a/src/test/compile-fail/non_owned-struct.rs b/src/test/compile-fail/non_owned-struct.rs index d4b8e6755a12..542c3aa212bb 100644 --- a/src/test/compile-fail/non_owned-struct.rs +++ b/src/test/compile-fail/non_owned-struct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[non_sendable] +#[no_send] struct Foo { a: int } fn bar(_: T) {} From 22b7eb38024afc38dbcfaa18796371b7d6b5b1d0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 28 Jun 2013 14:36:33 -0700 Subject: [PATCH 268/336] Rename #[mutable] to #[no_freeze] --- src/libextra/arc.rs | 3 ++- src/libextra/arena.rs | 3 ++- src/libextra/rc.rs | 3 ++- src/librustc/middle/ty.rs | 2 +- src/libstd/cell.rs | 3 ++- src/test/compile-fail/mutable-enum.rs | 2 +- src/test/compile-fail/mutable-struct.rs | 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 2fb03fecb598..30067c92300c 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -276,7 +276,8 @@ struct RWARCInner { lock: RWlock, failed: bool, data: T } * * Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested. */ -#[mutable] +#[mutable] // XXX remove after snap +#[no_freeze] struct RWARC { x: UnsafeAtomicRcBox>, } diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 2f18b0562e0f..2c6e7a30448c 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -65,7 +65,8 @@ struct Chunk { is_pod: bool, } -#[mutable] +#[mutable] // XXX remove after snap +#[no_freeze] pub struct Arena { // The head is separated out from the list as a unbenchmarked // microoptimization, to avoid needing to case on the list to diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 31fed541bb12..613c0b1ae417 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -169,7 +169,8 @@ struct RcMutBox { /// Mutable reference counted pointer type #[non_owned] #[no_send] -#[mutable] +#[mutable] // XXX remove after snap +#[no_freeze] #[unsafe_no_drop_flag] pub struct RcMut { priv ptr: *mut RcMutBox, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 03a73c847ee6..f1172fb1da65 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2204,7 +2204,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { } fn apply_tc_attr(cx: ctxt, did: def_id, mut tc: TypeContents) -> TypeContents { - if has_attr(cx, did, "mutable") { + if has_attr(cx, did, "no_freeze") { tc = tc + TC_MUTABLE; } if has_attr(cx, did, "no_send") { diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index e1d2b246dd37..53ea11f2b059 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -22,7 +22,8 @@ A dynamic, mutable location. Similar to a mutable option type, but friendlier. */ -#[mutable] +#[mutable] // XXX remove after snap +#[no_freeze] #[deriving(Clone, DeepClone, Eq)] #[allow(missing_doc)] pub struct Cell { diff --git a/src/test/compile-fail/mutable-enum.rs b/src/test/compile-fail/mutable-enum.rs index db2172b2e570..35842a53a315 100644 --- a/src/test/compile-fail/mutable-enum.rs +++ b/src/test/compile-fail/mutable-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[mutable] +#[no_freeze] enum Foo { A } fn bar(_: T) {} diff --git a/src/test/compile-fail/mutable-struct.rs b/src/test/compile-fail/mutable-struct.rs index 8511bcdcd350..6f29fcfd96d2 100644 --- a/src/test/compile-fail/mutable-struct.rs +++ b/src/test/compile-fail/mutable-struct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[mutable] +#[no_freeze] struct Foo { a: int } fn bar(_: T) {} From 28a3613a1da0f73da52b9becc7c0d973abdf122e Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 28 Jun 2013 20:09:22 -0400 Subject: [PATCH 269/336] fix zsh completion for lint and debug flags this correctly makes them accept 1 argument, and auto-completes the comma-separated list of lint flags --- src/etc/zsh/_rust | 71 ++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/etc/zsh/_rust b/src/etc/zsh/_rust index faa21a296169..86dcbab93fde 100644 --- a/src/etc/zsh/_rust +++ b/src/etc/zsh/_rust @@ -29,36 +29,30 @@ _rustc_opts_switches=( --target'[Target triple cpu-manufacturer-kernel\[-os\] to compile]' --target-feature'[Target specific attributes (llc -mattr=help for detail)]' --android-cross-path'[The path to the Android NDK]' - {-W,--warn}'[Set lint warnings]' - {-A,--allow}'[Set lint allowed]' - {-D,--deny}'[Set lint denied]' - {-F,--forbid}'[Set lint forbidden]' - -Z'[Set internal debugging options]' {-v,--version}'[Print version info and exit]' ) - _rustc_opts_lint=( - 'path-statement:path statements with no effect' - 'deprecated-pattern:warn about deprecated uses of pattern bindings' - 'non-implicitly-copyable-typarams:passing non implicitly copyable types as copy type params' - 'missing-trait-doc:detects missing documentation for traits' - 'missing-struct-doc:detects missing documentation for structs' - 'ctypes:proper use of core::libc types in foreign modules' - 'implicit-copies:implicit copies of non implicitly copyable data' - "unused-mut:detect mut variables which don't need to be mutable" - 'unused-imports:imports that are never used' - 'heap-memory:use of any (~ type or @ type) heap memory' - 'default-methods:allow default methods' - 'unused-variable:detect variables which are not used in any way' - 'dead-assignment:detect assignments that will never be read' - 'unrecognized-lint:unrecognized lint attribute' - 'type-limits:comparisons made useless by limits of the types involved' - 'unused-unsafe:unnecessary use of an `unsafe` block' - 'while-true:suggest using loop { } instead of while(true) { }' - 'non-camel-case-types:types, variants and traits should have camel case names' - 'managed-heap-memory:use of managed (@ type) heap memory' - 'unnecessary-allocation:detects unnecessary allocations that can be eliminated' - 'owned-heap-memory:use of owned (~ type) heap memory' + 'path-statement[path statements with no effect]' + 'deprecated-pattern[warn about deprecated uses of pattern bindings]' + 'non-implicitly-copyable-typarams[passing non implicitly copyable types as copy type params]' + 'missing-trait-doc[detects missing documentation for traits]' + 'missing-struct-doc[detects missing documentation for structs]' + 'ctypes[proper use of core::libc types in foreign modules]' + 'implicit-copies[implicit copies of non implicitly copyable data]' + "unused-mut[detect mut variables which don't need to be mutable]" + 'unused-imports[imports that are never used]' + 'heap-memory[use of any (~ type or @ type) heap memory]' + 'default-methods[allow default methods]' + 'unused-variable[detect variables which are not used in any way]' + 'dead-assignment[detect assignments that will never be read]' + 'unrecognized-lint[unrecognized lint attribute]' + 'type-limits[comparisons made useless by limits of the types involved]' + 'unused-unsafe[unnecessary use of an `unsafe` block]' + 'while-true[suggest using loop { } instead of while(true) { }]' + 'non-camel-case-types[types, variants and traits should have camel case names]' + 'managed-heap-memory[use of managed (@ type) heap memory]' + 'unnecessary-allocation[detects unnecessary allocations that can be eliminated]' + 'owned-heap-memory[use of owned (~ type) heap memory]' ) _rustc_opts_debug=( @@ -90,13 +84,20 @@ _rustc_opts_debug=( 'lint-llvm:Run the LLVM lint pass on the pre-optimization IR' ) -_rustc() { - case $words[2] in - -[WADF]) _describe 'options' _rustc_opts_lint ;; - -Z) _describe 'options' _rustc_opts_debug ;; - -) _arguments -s -w : "$_rustc_opts_switches[@]" ;; - *) _files -g "*.rs" ;; - esac +_rustc_opts_fun_lint(){ + _values -s , 'options' \ + "$_rustc_opts_lint[@]" } -_rustc "$@" +_rustc_opts_fun_debug(){ + _describe 'options' _rustc_opts_debug +} + +_arguments -s : \ + '(-W --warn)'{-W,--warn}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \ + '(-A --allow)'{-A,--allow}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \ + '(-D --deny)'{-D,--deny}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \ + '(-F --forbid)'{-F,--forbid}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \ + '*-Z[Set internal debugging options]:debug options:_rustc_opts_fun_debug' \ + "$_rustc_opts_switches[@]" \ + '*::files:_files -g "*.rs"' From a0c31ece9dba3665e0a44650ea492ae6f3e5604a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 28 Jun 2013 19:29:50 +0200 Subject: [PATCH 270/336] Remove unused variable --- src/librustpkg/path_util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index c0425b4d2606..f0a3f24c307b 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -40,7 +40,6 @@ static path_entry_separator: &'static str = ":"; /// DIR/.rust for any DIR that's the current working directory /// or an ancestor of it pub fn rust_path() -> ~[Path] { - let env_path: ~str = os::getenv("RUST_PATH").get_or_default(~""); let mut env_rust_path: ~[Path] = match os::getenv("RUST_PATH") { Some(env_path) => { let env_path_components: ~[&str] = From ee7307e6cb9e942fc1ef27109bfbc6fbf730ee3c Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Fri, 28 Jun 2013 20:29:04 -0700 Subject: [PATCH 271/336] Smarter warning in extra::term::Terminal.reset() Don't spew a warn!() in reset() if num_colors is 0, because non-color-supporting terminals are legit. Use debug!() there instead. Continue spewing warn!() if we believe the terminal to support colors. Use a better warning when the `op` capability can't be found. --- src/libextra/term.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 880b89f2bbe1..d448a1588a67 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -120,13 +120,15 @@ impl Terminal { pub fn reset(&self) { let mut vars = Variables::new(); let s = do self.ti.strings.find_equiv(&("op")) - .map_consume_default(Err(~"can't find op")) |&op| { + .map_consume_default(Err(~"can't find terminfo capability `op`")) |&op| { expand(op, [], &mut vars) }; if s.is_ok() { self.out.write(s.unwrap()); - } else { + } else if self.num_colors > 0 { warn!("%s", s.unwrap_err()); + } else { + debug!("%s", s.unwrap_err()); } } From b9cf6a33d2b5c0006f780c01bcaae4047551eb75 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Fri, 28 Jun 2013 13:52:37 +0200 Subject: [PATCH 272/336] iterator: UnfoldrIterator::new should have function argument last To match Rust conventions and enable use of `do` etc, make sure the closure is the last argument to the `new` method. --- src/libstd/iterator.rs | 4 ++-- src/test/run-pass/unfoldr-cross-crate.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 78940143f4e3..765bf3b36f28 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -983,7 +983,7 @@ impl<'self, A, St> UnfoldrIterator<'self, A, St> { /// Creates a new iterator with the specified closure as the "iterator /// function" and an initial state to eventually pass to the iterator #[inline] - pub fn new<'a>(f: &'a fn(&mut St) -> Option, initial_state: St) + pub fn new<'a>(initial_state: St, f: &'a fn(&mut St) -> Option) -> UnfoldrIterator<'a, A, St> { UnfoldrIterator { f: f, @@ -1174,7 +1174,7 @@ mod tests { } } - let mut it = UnfoldrIterator::new(count, 0); + let mut it = UnfoldrIterator::new(0, count); let mut i = 0; for it.advance |counted| { assert_eq!(counted, i); diff --git a/src/test/run-pass/unfoldr-cross-crate.rs b/src/test/run-pass/unfoldr-cross-crate.rs index 4e98543ae826..7fcae90a8d11 100644 --- a/src/test/run-pass/unfoldr-cross-crate.rs +++ b/src/test/run-pass/unfoldr-cross-crate.rs @@ -24,7 +24,7 @@ fn main() { } } - let mut it = UnfoldrIterator::new(count, 0); + let mut it = UnfoldrIterator::new(0, count); let mut i = 0; for it.advance |counted| { assert_eq!(counted, i); From 51beba6cf91ef8fcc06a32482c78bfc59b37bd73 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Sat, 29 Jun 2013 14:06:42 +0900 Subject: [PATCH 273/336] libextra: unused import fix for android AGAIN --- src/libextra/ebml.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 69eb9afad853..4634a7db05e3 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -97,11 +97,14 @@ pub mod reader { use core::cast::transmute; use core::int; use core::io; + use core::option::{None, Option, Some}; #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] - use core::option::{None, Option, Some}; use core::ptr::offset; + + #[cfg(target_arch = "x86")] + #[cfg(target_arch = "x86_64")] use core::unstable::intrinsics::bswap32; // ebml reading From 21cc0ccea10bb9d1b83612d26c8e62d06fe365a1 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Sat, 29 Jun 2013 14:07:24 +0900 Subject: [PATCH 274/336] librustc: fix #7467 for android --- src/librustc/middle/trans/meth.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index fc0c9c06c450..7d6a5b5fef9c 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -28,7 +28,7 @@ use middle::trans::type_of::*; use middle::ty; use middle::typeck; use util::common::indenter; -use util::ppaux::{Repr, ty_to_str}; +use util::ppaux::Repr; use middle::trans::type_::Type; @@ -36,7 +36,6 @@ use core::vec; use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_util; use syntax::{ast, ast_map}; -use syntax::parse::token; /** The main "translation" pass for methods. Generates code @@ -755,10 +754,9 @@ pub fn make_vtable(ccx: &mut CrateContext, components.push(ptr) } - let name = fmt!("%s_vtable_%u", ty_to_str(ccx.tcx, tydesc.ty), token::gensym("vtable")); - let tbl = C_struct(components); - let vt_gvar = do name.as_c_str |buf| { + let vtable = ccx.sess.str_of(gensym_name("vtable")); + let vt_gvar = do vtable.as_c_str |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf) }; llvm::LLVMSetInitializer(vt_gvar, tbl); From e0788c7f523dc13609179b8f40c09af5c8668df6 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Sat, 29 Jun 2013 03:54:09 -0400 Subject: [PATCH 275/336] xfail-fast once fn run-pass tests --- src/test/run-pass/once-move-out-on-heap.rs | 2 ++ src/test/run-pass/once-move-out-on-stack.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/run-pass/once-move-out-on-heap.rs b/src/test/run-pass/once-move-out-on-heap.rs index 8846abb47fc7..38b23fd128d4 100644 --- a/src/test/run-pass/once-move-out-on-heap.rs +++ b/src/test/run-pass/once-move-out-on-heap.rs @@ -10,6 +10,8 @@ // Testing guarantees provided by once functions. +// xfail-fast + extern mod extra; use extra::arc; use std::util; diff --git a/src/test/run-pass/once-move-out-on-stack.rs b/src/test/run-pass/once-move-out-on-stack.rs index fb8a45172943..e881f5766736 100644 --- a/src/test/run-pass/once-move-out-on-stack.rs +++ b/src/test/run-pass/once-move-out-on-stack.rs @@ -10,6 +10,8 @@ // Testing guarantees provided by once functions. +// xfail-fast + // compile-flags:-Z once-fns extern mod extra; use extra::arc; From 5784c0912f99a4bfeb75909fab0cf9bb6bef794f Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 21 Jun 2013 18:52:53 -0400 Subject: [PATCH 276/336] Change taskgroup key type to fn:Copy in prep for noncopyable stack closures. --- src/libextra/sort.rs | 2 +- src/libstd/local_data.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/parse/token.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 5377dfadbaa1..6befd49e8afd 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -1202,7 +1202,7 @@ mod big_tests { struct LVal<'self> { val: uint, - key: &'self fn(@uint), + key: &'self fn:Copy(@uint), } #[unsafe_destructor] diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index 33b4e3f1963a..c5f2c8ae584d 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -46,7 +46,7 @@ use task::local_data_priv::{local_get, local_pop, local_modify, local_set, Handl * * These two cases aside, the interface is safe. */ -pub type LocalDataKey<'self,T> = &'self fn(v: @T); +pub type LocalDataKey<'self,T> = &'self fn:Copy(v: @T); /** * Remove a task-local data value from the table, returning the diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 6761736d2f37..7ea19611b51b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -704,7 +704,7 @@ pub fn new_sctable_internal() -> SCTable { pub fn get_sctable() -> @mut SCTable { unsafe { let sctable_key = (cast::transmute::<(uint, uint), - &fn(v: @@mut SCTable)>( + &fn:Copy(v: @@mut SCTable)>( (-4 as uint, 0u))); match local_data::local_data_get(sctable_key) { None => { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 793626f0e180..c98062cf3bd7 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -484,7 +484,7 @@ pub fn get_ident_interner() -> @ident_interner { unsafe { let key = (cast::transmute::<(uint, uint), - &fn(v: @@::parse::token::ident_interner)>( + &fn:Copy(v: @@::parse::token::ident_interner)>( (-3 as uint, 0u))); match local_data::local_data_get(key) { Some(interner) => *interner, From 75b80bad638a40c0a969fabf897f0ef13fe567b7 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 21 Jun 2013 20:01:17 -0400 Subject: [PATCH 277/336] Use more deriving(IterBytes) in libsyntax. --- src/libsyntax/ast.rs | 265 +++++++++++------------------------ src/libsyntax/ast_util.rs | 9 -- src/libsyntax/codemap.rs | 53 +------ src/libsyntax/opt_vec.rs | 2 +- src/libsyntax/parse/token.rs | 6 +- 5 files changed, 93 insertions(+), 242 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8e1c51caf7c1..bc432c4c7b0b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -17,17 +17,14 @@ use parse::token::{interner_get, str_to_ident}; use std::hashmap::HashMap; use std::option::Option; -use std::to_bytes::IterBytes; -use std::to_bytes; use std::to_str::ToStr; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; - // an identifier contains a Name (index into the interner // table) and a SyntaxContext to track renaming and // macro expansion per Flatt et al., "Macros // That Work Together" -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct ident { name: Name, ctxt: SyntaxContext } /// Construct an identifier with the given name and an empty context: @@ -57,7 +54,7 @@ pub struct SCTable { pub static empty_ctxt : uint = 0; pub static illegal_ctxt : uint = 1; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum SyntaxContext_ { EmptyCtxt, Mark (Mrk,SyntaxContext), @@ -86,42 +83,28 @@ impl Encodable for ident { } } +#[deriving(IterBytes)] impl Decodable for ident { fn decode(d: &mut D) -> ident { str_to_ident(d.read_str()) } } -impl to_bytes::IterBytes for ident { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.name.iter_bytes(lsb0, f) - } -} - // Functions may or may not have names. pub type fn_ident = Option; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Lifetime { id: node_id, span: span, ident: ident } -impl to_bytes::IterBytes for Lifetime { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.id.iter_bytes(lsb0, f) && - self.span.iter_bytes(lsb0, f) && - self.ident.iter_bytes(lsb0, f) - } -} - // a "Path" is essentially Rust's notion of a name; // for instance: core::cmp::Eq . It's represented // as a sequence of identifiers, along with a bunch // of supporting information. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Path { span: span, global: bool, @@ -134,7 +117,7 @@ pub type crate_num = int; pub type node_id = int; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct def_id { crate: crate_num, node: node_id, @@ -143,7 +126,7 @@ pub struct def_id { pub static local_crate: crate_num = 0; pub static crate_node_id: node_id = 0; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and @@ -153,14 +136,14 @@ pub enum TyParamBound { RegionTyParamBound } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyParam { ident: ident, id: node_id, bounds: @OptVec } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Generics { lifetimes: OptVec, ty_params: OptVec @@ -178,7 +161,7 @@ impl Generics { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum def { def_fn(def_id, purity), def_static_method(/* method */ def_id, @@ -216,7 +199,7 @@ pub type crate_cfg = ~[@meta_item]; pub type crate = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct crate_ { module: _mod, attrs: ~[attribute], @@ -225,7 +208,7 @@ pub struct crate_ { pub type meta_item = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum meta_item_ { meta_word(@str), meta_list(@str, ~[@meta_item]), @@ -234,7 +217,7 @@ pub enum meta_item_ { pub type blk = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct blk_ { view_items: ~[@view_item], stmts: ~[@stmt], @@ -243,40 +226,26 @@ pub struct blk_ { rules: blk_check_mode, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct pat { id: node_id, node: pat_, span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct field_pat { ident: ident, pat: @pat, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum binding_mode { bind_by_ref(mutability), bind_infer } -impl to_bytes::IterBytes for binding_mode { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - bind_by_ref(ref m) => { - 0u8.iter_bytes(lsb0, f) && m.iter_bytes(lsb0, f) - } - - bind_infer => { - 1u8.iter_bytes(lsb0, f) - } - } - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum pat_ { pat_wild, // A pat_ident may either be a new bound variable, @@ -301,28 +270,16 @@ pub enum pat_ { pat_vec(~[@pat], Option<@pat>, ~[@pat]) } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mutability { m_mutbl, m_imm, m_const, } -impl to_bytes::IterBytes for mutability { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum Sigil { BorrowedSigil, OwnedSigil, ManagedSigil } -impl to_bytes::IterBytes for Sigil { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as uint).iter_bytes(lsb0, f) - } -} - impl ToStr for Sigil { fn to_str(&self) -> ~str { match *self { @@ -333,7 +290,7 @@ impl ToStr for Sigil { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) vstore_fixed(Option), // [1,2,3,4] @@ -342,7 +299,7 @@ pub enum vstore { vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum expr_vstore { expr_vstore_uniq, // ~[1,2,3,4] expr_vstore_box, // @[1,2,3,4] @@ -351,7 +308,7 @@ pub enum expr_vstore { expr_vstore_mut_slice, // &mut [1,2,3,4] } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum binop { add, subtract, @@ -373,7 +330,7 @@ pub enum binop { gt, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum unop { box(mutability), uniq(mutability), @@ -384,7 +341,7 @@ pub enum unop { pub type stmt = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum stmt_ { // could be an item or a local (let) binding: stmt_decl(@decl, node_id), @@ -401,7 +358,7 @@ pub enum stmt_ { // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct local_ { is_mutbl: bool, ty: @Ty, @@ -414,7 +371,7 @@ pub type local = spanned; pub type decl = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum decl_ { // a local (let) binding: decl_local(@local), @@ -422,14 +379,14 @@ pub enum decl_ { decl_item(@item), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arm { pats: ~[@pat], guard: Option<@expr>, body: blk, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct field_ { ident: ident, expr: @expr, @@ -437,10 +394,10 @@ pub struct field_ { pub type field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum blk_check_mode { default_blk, unsafe_blk, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct expr { id: node_id, node: expr_, @@ -460,14 +417,14 @@ impl expr { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum CallSugar { NoSugar, DoSugar, ForSugar } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), @@ -538,7 +495,7 @@ pub enum expr_ { // else knows what to do with them, so you'll probably get a syntax // error. // -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] #[doc="For macro invocations; parsing is delegated to the macro"] pub enum token_tree { // a single token @@ -611,7 +568,7 @@ pub enum token_tree { // pub type matcher = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum matcher_ { // match one token match_tok(::parse::token::Token), @@ -624,14 +581,14 @@ pub enum matcher_ { pub type mac = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mac_ { mac_invoc_tt(@Path,~[token_tree]), // new macro-invocation } pub type lit = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum lit_ { lit_str(@str), lit_int(i64, int_ty), @@ -645,13 +602,13 @@ pub enum lit_ { // NB: If you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct mt { ty: @Ty, mutbl: mutability, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct ty_field_ { ident: ident, mt: mt, @@ -659,7 +616,7 @@ pub struct ty_field_ { pub type ty_field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct ty_method { ident: ident, attrs: ~[attribute], @@ -671,7 +628,7 @@ pub struct ty_method { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] // A trait method is either required (meaning it doesn't have an // implementation, just a signature) or provided (meaning it has a default // implementation). @@ -680,7 +637,7 @@ pub enum trait_method { provided(@method), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } impl ToStr for int_ty { @@ -689,13 +646,7 @@ impl ToStr for int_ty { } } -impl to_bytes::IterBytes for int_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } impl ToStr for uint_ty { @@ -704,13 +655,7 @@ impl ToStr for uint_ty { } } -impl to_bytes::IterBytes for uint_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum float_ty { ty_f, ty_f32, ty_f64, } impl ToStr for float_ty { @@ -719,14 +664,8 @@ impl ToStr for float_ty { } } -impl to_bytes::IterBytes for float_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - // NB Eq method appears below. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Ty { id: node_id, node: ty_, @@ -734,7 +673,7 @@ pub struct Ty { } // Not represented directly in the AST, referred to by name through a ty_path. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum prim_ty { ty_int(int_ty), ty_uint(uint_ty), @@ -743,12 +682,13 @@ pub enum prim_ty { ty_bool, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum Onceness { Once, Many } +#[deriving(IterBytes)] impl ToStr for Onceness { fn to_str(&self) -> ~str { match *self { @@ -758,13 +698,7 @@ impl ToStr for Onceness { } } -impl to_bytes::IterBytes for Onceness { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as uint).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyClosure { sigil: Sigil, region: Option<@Lifetime>, @@ -779,7 +713,7 @@ pub struct TyClosure { bounds: Option>, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyBareFn { purity: purity, abis: AbiSet, @@ -787,7 +721,7 @@ pub struct TyBareFn { decl: fn_decl } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum ty_ { ty_nil, ty_bot, /* bottom type */ @@ -808,19 +742,13 @@ pub enum ty_ { ty_infer, } -impl to_bytes::IterBytes for Ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.span.lo.iter_bytes(lsb0, f) && self.span.hi.iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum asm_dialect { asm_att, asm_intel } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct inline_asm { asm: @str, clobbers: @str, @@ -831,7 +759,7 @@ pub struct inline_asm { dialect: asm_dialect } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arg { is_mutbl: bool, ty: @Ty, @@ -839,20 +767,21 @@ pub struct arg { id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct fn_decl { inputs: ~[arg], output: @Ty, cf: ret_style, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum purity { unsafe_fn, // declared with "unsafe fn" impure_fn, // declared with "fn" extern_fn, // declared with "extern fn" } +#[deriving(IterBytes)] impl ToStr for purity { fn to_str(&self) -> ~str { match *self { @@ -863,26 +792,14 @@ impl ToStr for purity { } } -impl to_bytes::IterBytes for purity { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum ret_style { noreturn, // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) return_val, // everything else } -impl to_bytes::IterBytes for ret_style { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum explicit_self_ { sty_static, // no self sty_value, // `self` @@ -891,27 +808,9 @@ pub enum explicit_self_ { sty_uniq(mutability) // `~self` } -impl to_bytes::IterBytes for explicit_self_ { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - sty_static => 0u8.iter_bytes(lsb0, f), - sty_value => 1u8.iter_bytes(lsb0, f), - sty_region(ref lft, ref mutbl) => { - 2u8.iter_bytes(lsb0, f) && lft.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - sty_box(ref mutbl) => { - 3u8.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - sty_uniq(ref mutbl) => { - 4u8.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - } - } -} - pub type explicit_self = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct method { ident: ident, attrs: ~[attribute], @@ -926,17 +825,17 @@ pub struct method { vis: visibility, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct _mod { view_items: ~[@view_item], items: ~[@item], } // Foreign mods can be named or anonymous -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_mod_sort { named, anonymous } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct foreign_mod { sort: foreign_mod_sort, abis: AbiSet, @@ -944,24 +843,24 @@ pub struct foreign_mod { items: ~[@foreign_item], } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_arg { ty: @Ty, id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum variant_kind { tuple_variant_kind(~[variant_arg]), struct_variant_kind(@struct_def), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct enum_def { variants: ~[variant], } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_ { name: ident, attrs: ~[attribute], @@ -973,7 +872,7 @@ pub struct variant_ { pub type variant = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct path_list_ident_ { name: ident, id: node_id, @@ -983,7 +882,7 @@ pub type path_list_ident = spanned; pub type view_path = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum view_path_ { // quux = foo::bar::baz @@ -1000,7 +899,7 @@ pub enum view_path_ { view_path_list(@Path, ~[path_list_ident], node_id) } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct view_item { node: view_item_, attrs: ~[attribute], @@ -1008,7 +907,7 @@ pub struct view_item { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum view_item_ { view_item_extern_mod(ident, ~[@meta_item], node_id), view_item_use(~[@view_path]), @@ -1020,11 +919,11 @@ pub type attribute = spanned; // Distinguishes between attributes that decorate items and attributes that // are contained as statements within items. These two cases need to be // distinguished for pretty-printing. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum attr_style { attr_outer, attr_inner, } // doc-comments are promoted to attributes that have is_sugared_doc = true -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct attribute_ { style: attr_style, value: @meta_item, @@ -1038,13 +937,13 @@ pub struct attribute_ { If this impl is an item_impl, the impl_id is redundant (it could be the same as the impl's node id). */ -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct trait_ref { path: @Path, ref_id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum visibility { public, private, inherited } impl visibility { @@ -1056,7 +955,7 @@ impl visibility { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct struct_field_ { kind: struct_field_kind, id: node_id, @@ -1066,13 +965,13 @@ pub struct struct_field_ { pub type struct_field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum struct_field_kind { named_field(ident, visibility), unnamed_field // element of a tuple-like struct } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct struct_def { fields: ~[@struct_field], /* fields, not including ctor */ /* ID of the constructor. This is only used for tuple- or enum-like @@ -1084,7 +983,7 @@ pub struct struct_def { FIXME (#3300): Should allow items to be anonymous. Right now we just use dummy names for anon items. */ -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct item { ident: ident, attrs: ~[attribute], @@ -1094,7 +993,7 @@ pub struct item { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum item_ { item_static(@Ty, mutability, @expr), item_fn(fn_decl, purity, AbiSet, Generics, blk), @@ -1112,7 +1011,7 @@ pub enum item_ { item_mac(mac), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct foreign_item { ident: ident, attrs: ~[attribute], @@ -1122,7 +1021,7 @@ pub struct foreign_item { vis: visibility, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), foreign_item_static(@Ty, /* is_mutbl */ bool), @@ -1131,7 +1030,7 @@ pub enum foreign_item_ { // The data we save and restore about an inlined item or method. This is not // part of the AST that we parse from a file, but it becomes part of the tree // that we trans. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 7ea19611b51b..6e21ceb64c43 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -19,7 +19,6 @@ use visit; use std::hashmap::HashMap; use std::int; use std::option; -use std::to_bytes; use std::cast; use std::local_data; @@ -194,14 +193,6 @@ pub fn is_call_expr(e: @expr) -> bool { match e.node { expr_call(*) => true, _ => false } } -// This makes def_id hashable -impl to_bytes::IterBytes for def_id { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.crate.iter_bytes(lsb0, f) && self.node.iter_bytes(lsb0, f) - } -} - pub fn block_from_expr(e: @expr) -> blk { let blk_ = default_block(~[], option::Some::<@expr>(e), e.id); return spanned {node: blk_, span: e.span}; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 5efc96e16b53..bcf617c56ae1 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -22,7 +22,6 @@ source code snippets, etc. */ use std::cmp; -use std::to_bytes; use std::uint; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -32,12 +31,12 @@ pub trait Pos { } /// A byte offset -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct BytePos(uint); /// A character offset. Because of multibyte utf8 characters, a byte offset /// is not equivalent to a character offset. The CodeMap will convert BytePos /// values to CharPos values as necessary. -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct CharPos(uint); // XXX: Lots of boilerplate in these impls, but so far my attempts to fix @@ -67,12 +66,6 @@ impl Sub for BytePos { } } -impl to_bytes::IterBytes for BytePos { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (**self).iter_bytes(lsb0, f) - } -} - impl Pos for CharPos { fn from_uint(n: uint) -> CharPos { CharPos(n) } fn to_uint(&self) -> uint { **self } @@ -85,12 +78,6 @@ impl cmp::Ord for CharPos { fn gt(&self, other: &CharPos) -> bool { **self > **other } } -impl to_bytes::IterBytes for CharPos { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (**self).iter_bytes(lsb0, f) - } -} - impl Add for CharPos { fn add(&self, rhs: &CharPos) -> CharPos { CharPos(**self + **rhs) @@ -109,13 +96,14 @@ are *absolute* positions from the beginning of the codemap, not positions relative to FileMaps. Methods on the CodeMap can be used to relate spans back to the original source. */ +#[deriving(IterBytes)] pub struct span { lo: BytePos, hi: BytePos, expn_info: Option<@ExpnInfo> } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct spanned { node: T, span: span } impl cmp::Eq for span { @@ -138,14 +126,6 @@ impl Decodable for span { } } -impl to_bytes::IterBytes for span { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.lo.iter_bytes(lsb0, f) && - self.hi.iter_bytes(lsb0, f) && - self.expn_info.iter_bytes(lsb0, f) - } -} - pub fn spanned(lo: BytePos, hi: BytePos, t: T) -> spanned { respan(mk_sp(lo, hi), t) } @@ -191,40 +171,21 @@ pub struct LocWithOpt { // used to be structural records. Better names, anyone? pub struct FileMapAndLine {fm: @FileMap, line: uint} pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} +#[deriving(IterBytes)] pub struct NameAndSpan {name: @str, span: Option} -impl to_bytes::IterBytes for NameAndSpan { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.name.iter_bytes(lsb0, f) && self.span.iter_bytes(lsb0, f) - } -} - +#[deriving(IterBytes)] pub struct CallInfo { call_site: span, callee: NameAndSpan } -impl to_bytes::IterBytes for CallInfo { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.call_site.iter_bytes(lsb0, f) && self.callee.iter_bytes(lsb0, f) - } -} - /// Extra information for tracking macro expansion of spans +#[deriving(IterBytes)] pub enum ExpnInfo { ExpandedFrom(CallInfo) } -impl to_bytes::IterBytes for ExpnInfo { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ExpandedFrom(ref call_info) => { - 0u8.iter_bytes(lsb0, f) && call_info.iter_bytes(lsb0, f) - } - } - } -} - pub type FileName = @str; pub struct FileLines diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index fe050fc99f19..bf8c5ae462bf 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -18,7 +18,7 @@ use std::vec::VecIterator; -#[deriving(Encodable, Decodable)] +#[deriving(Encodable, Decodable,IterBytes)] pub enum OptVec { Empty, Vec(~[T]) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index c98062cf3bd7..94147825da49 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -22,7 +22,7 @@ use std::local_data; use std::rand; use std::rand::RngUtil; -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] pub enum binop { PLUS, MINUS, @@ -36,7 +36,7 @@ pub enum binop { SHR, } -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] pub enum Token { /* Expression-operator symbols. */ EQ, @@ -97,7 +97,7 @@ pub enum Token { EOF, } -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] /// For interpolation during macro expansion. pub enum nonterminal { nt_item(@ast::item), From 89110fdf55c000096fc24a78d35256544c7b523f Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 21 Jun 2013 20:37:03 -0400 Subject: [PATCH 278/336] Use more deriving(IterBytes) in librustc. --- src/librustc/middle/trans/common.rs | 42 +--- src/librustc/middle/ty.rs | 229 ++---------------- .../middle/typeck/infer/region_inference.rs | 27 +-- 3 files changed, 23 insertions(+), 275 deletions(-) diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 7624fb13903f..b255f2ca78c7 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -36,6 +36,8 @@ use core::cast; use core::hashmap::{HashMap}; use core::libc::{c_uint, c_longlong, c_ulonglong}; use core::to_bytes; +use core::str; +use core::vec::raw::to_ptr; use core::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; @@ -860,7 +862,7 @@ pub fn is_null(val: ValueRef) -> bool { } // Used to identify cached monomorphized functions and vtables -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub enum mono_param_id { mono_precise(ty::t, Option<@~[mono_id]>), mono_any, @@ -870,7 +872,7 @@ pub enum mono_param_id { datum::DatumMode), } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub enum MonoDataClass { MonoBits, // Anything not treated differently from arbitrary integer data MonoNonNull, // Non-null pointers (used for optional-pointer optimization) @@ -895,7 +897,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass { } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct mono_id_ { def: ast::def_id, params: ~[mono_param_id], @@ -904,40 +906,6 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; -impl to_bytes::IterBytes for mono_param_id { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - mono_precise(t, ref mids) => { - 0u8.iter_bytes(lsb0, f) && - ty::type_id(t).iter_bytes(lsb0, f) && - mids.iter_bytes(lsb0, f) - } - - mono_any => 1u8.iter_bytes(lsb0, f), - - mono_repr(ref a, ref b, ref c, ref d) => { - 2u8.iter_bytes(lsb0, f) && - a.iter_bytes(lsb0, f) && - b.iter_bytes(lsb0, f) && - c.iter_bytes(lsb0, f) && - d.iter_bytes(lsb0, f) - } - } - } -} - -impl to_bytes::IterBytes for MonoDataClass { - fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for mono_id_ { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.def.iter_bytes(lsb0, f) && self.params.iter_bytes(lsb0, f) - } -} - pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); return build::Select(cx, cond, b, a); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f1172fb1da65..a990e4c70a94 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,7 @@ use syntax; // Data types -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct field { ident: ast::ident, mt: mt @@ -96,13 +96,13 @@ impl Method { } } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct mt { ty: t, mutbl: ast::mutability, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable, IterBytes)] pub enum vstore { vstore_fixed(uint), vstore_uniq, @@ -133,7 +133,7 @@ pub struct field_ty { // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct creader_cache_key { cnum: int, pos: uint, @@ -142,14 +142,6 @@ pub struct creader_cache_key { type creader_cache = @mut HashMap; -impl to_bytes::IterBytes for creader_cache_key { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.cnum.iter_bytes(lsb0, f) && - self.pos.iter_bytes(lsb0, f) && - self.len.iter_bytes(lsb0, f) - } -} - struct intern_key { sty: *sty, } @@ -168,6 +160,8 @@ impl cmp::Eq for intern_key { } } +// NB: Do not replace this with #[deriving(IterBytes)], as above. (Figured +// this out the hard way.) impl to_bytes::IterBytes for intern_key { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { unsafe { @@ -372,14 +366,14 @@ pub fn type_has_regions(t: t) -> bool { } pub fn type_id(t: t) -> uint { get(t).id } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct BareFnTy { purity: ast::purity, abis: AbiSet, sig: FnSig } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct ClosureTy { purity: ast::purity, sigil: ast::Sigil, @@ -396,32 +390,13 @@ pub struct ClosureTy { * - `lifetimes` is the list of region names bound in this fn. * - `inputs` is the list of arguments and their modes. * - `output` is the return type. */ -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct FnSig { bound_lifetime_names: OptVec, inputs: ~[t], output: t } -impl to_bytes::IterBytes for BareFnTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.purity.iter_bytes(lsb0, f) && - self.abis.iter_bytes(lsb0, f) && - self.sig.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for ClosureTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.purity.iter_bytes(lsb0, f) && - self.sigil.iter_bytes(lsb0, f) && - self.onceness.iter_bytes(lsb0, f) && - self.region.iter_bytes(lsb0, f) && - self.sig.iter_bytes(lsb0, f) && - self.bounds.iter_bytes(lsb0, f) - } -} - #[deriving(Eq, IterBytes)] pub struct param_ty { idx: uint, @@ -526,7 +501,7 @@ type opt_region = Option; * - `self_ty` is the type to which `self` should be remapped, if any. The * `self` type is rather funny in that it can only appear on traits and is * always substituted away to the implementing type for a trait. */ -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct substs { self_r: opt_region, self_ty: Option, @@ -582,7 +557,7 @@ mod primitives { // NB: If you change this, you'll probably want to change the corresponding // AST structure in libsyntax/ast.rs as well. -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum sty { ty_nil, ty_bot, @@ -714,62 +689,33 @@ impl CLike for BuiltinBound { } } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct TyVid(uint); -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct IntVid(uint); -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct FloatVid(uint); -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable, IterBytes)] pub struct RegionVid { id: uint } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum InferTy { TyVar(TyVid), IntVar(IntVid), FloatVar(FloatVid) } -impl to_bytes::IterBytes for InferTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - TyVar(ref tv) => { - 0u8.iter_bytes(lsb0, f) && tv.iter_bytes(lsb0, f) - } - IntVar(ref iv) => { - 1u8.iter_bytes(lsb0, f) && iv.iter_bytes(lsb0, f) - } - FloatVar(ref fv) => { - 2u8.iter_bytes(lsb0, f) && fv.iter_bytes(lsb0, f) - } - } - } -} - -#[deriving(Encodable, Decodable)] +#[deriving(Encodable, Decodable, IterBytes)] pub enum InferRegion { ReVar(RegionVid), ReSkolemized(uint, bound_region) } -impl to_bytes::IterBytes for InferRegion { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ReVar(ref rv) => { - 0u8.iter_bytes(lsb0, f) && rv.iter_bytes(lsb0, f) - } - ReSkolemized(ref v, _) => { - 1u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f) - } - } - } -} - impl cmp::Eq for InferRegion { fn eq(&self, other: &InferRegion) -> bool { match ((*self), *other) { @@ -849,30 +795,6 @@ impl ToStr for IntVarValue { } } -impl to_bytes::IterBytes for TyVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for IntVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for FloatVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for RegionVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - pub struct TypeParameterDef { def_id: ast::def_id, bounds: @ParamBounds @@ -2744,123 +2666,6 @@ impl cmp::TotalEq for bound_region { } } -impl to_bytes::IterBytes for vstore { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - vstore_fixed(ref u) => { - 0u8.iter_bytes(lsb0, f) && u.iter_bytes(lsb0, f) - } - vstore_uniq => 1u8.iter_bytes(lsb0, f), - vstore_box => 2u8.iter_bytes(lsb0, f), - - vstore_slice(ref r) => { - 3u8.iter_bytes(lsb0, f) && r.iter_bytes(lsb0, f) - } - } - } -} - -impl to_bytes::IterBytes for substs { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.self_r.iter_bytes(lsb0, f) && - self.self_ty.iter_bytes(lsb0, f) && - self.tps.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for mt { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.ty.iter_bytes(lsb0, f) && self.mutbl.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for field { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.ident.iter_bytes(lsb0, f) && self.mt.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for FnSig { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.inputs.iter_bytes(lsb0, f) && self.output.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for sty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ty_nil => 0u8.iter_bytes(lsb0, f), - ty_bool => 1u8.iter_bytes(lsb0, f), - - ty_int(ref t) => 2u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_uint(ref t) => 3u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_float(ref t) => 4u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_estr(ref v) => 5u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f), - - ty_enum(ref did, ref substs) => { - 6u8.iter_bytes(lsb0, f) && - did.iter_bytes(lsb0, f) && - substs.iter_bytes(lsb0, f) - } - - ty_box(ref mt) => 7u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_evec(ref mt, ref v) => { - 8u8.iter_bytes(lsb0, f) && - mt.iter_bytes(lsb0, f) && - v.iter_bytes(lsb0, f) - } - - ty_unboxed_vec(ref mt) => 9u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_tup(ref ts) => 10u8.iter_bytes(lsb0, f) && ts.iter_bytes(lsb0, f), - - ty_bare_fn(ref ft) => 12u8.iter_bytes(lsb0, f) && ft.iter_bytes(lsb0, f), - - ty_self(ref did) => 13u8.iter_bytes(lsb0, f) && did.iter_bytes(lsb0, f), - - ty_infer(ref v) => 14u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f), - - ty_param(ref p) => 15u8.iter_bytes(lsb0, f) && p.iter_bytes(lsb0, f), - - ty_type => 16u8.iter_bytes(lsb0, f), - ty_bot => 17u8.iter_bytes(lsb0, f), - - ty_ptr(ref mt) => 18u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_uniq(ref mt) => 19u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_trait(ref did, ref substs, ref v, ref mutbl, bounds) => { - 20u8.iter_bytes(lsb0, f) && - did.iter_bytes(lsb0, f) && - substs.iter_bytes(lsb0, f) && - v.iter_bytes(lsb0, f) && - mutbl.iter_bytes(lsb0, f) && - bounds.iter_bytes(lsb0, f) - } - - ty_opaque_closure_ptr(ref ck) => 21u8.iter_bytes(lsb0, f) && ck.iter_bytes(lsb0, f), - - ty_opaque_box => 22u8.iter_bytes(lsb0, f), - - ty_struct(ref did, ref substs) => { - 23u8.iter_bytes(lsb0, f) && did.iter_bytes(lsb0, f) && substs.iter_bytes(lsb0, f) - } - - ty_rptr(ref r, ref mt) => { - 24u8.iter_bytes(lsb0, f) && r.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f) - } - - ty_err => 25u8.iter_bytes(lsb0, f), - - ty_closure(ref ct) => 26u8.iter_bytes(lsb0, f) && ct.iter_bytes(lsb0, f), - } - } -} - pub fn node_id_to_trait_ref(cx: ctxt, id: ast::node_id) -> @ty::TraitRef { match cx.trait_refs.find(&id) { Some(&t) => t, diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 0aad161a6788..4380711b78e8 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -548,43 +548,18 @@ use util::ppaux::note_and_explain_region; use core::cell::Cell; use core::hashmap::{HashMap, HashSet}; -use core::to_bytes; use core::uint; use core::vec; use syntax::codemap::span; use syntax::ast; -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] enum Constraint { ConstrainVarSubVar(RegionVid, RegionVid), ConstrainRegSubVar(Region, RegionVid), ConstrainVarSubReg(RegionVid, Region) } -impl to_bytes::IterBytes for Constraint { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ConstrainVarSubVar(ref v0, ref v1) => { - 0u8.iter_bytes(lsb0, f) && - v0.iter_bytes(lsb0, f) && - v1.iter_bytes(lsb0, f) - } - - ConstrainRegSubVar(ref ra, ref va) => { - 1u8.iter_bytes(lsb0, f) && - ra.iter_bytes(lsb0, f) && - va.iter_bytes(lsb0, f) - } - - ConstrainVarSubReg(ref va, ref ra) => { - 2u8.iter_bytes(lsb0, f) && - va.iter_bytes(lsb0, f) && - ra.iter_bytes(lsb0, f) - } - } - } -} - #[deriving(Eq, IterBytes)] struct TwoRegions { a: Region, From ff4ab9e147b0be4126b8b70ca6ab27173a46077a Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 21 Jun 2013 20:08:35 -0400 Subject: [PATCH 279/336] 'Borrow' stack closures rather than copying them (e.g., "|x|f(x)"), in prep for making them noncopyable. --- src/libextra/fun_treemap.rs | 4 +- src/libextra/rope.rs | 4 +- src/libextra/sort.rs | 7 ++-- src/libextra/sync.rs | 12 +++--- src/libextra/test.rs | 6 +-- src/libextra/treemap.rs | 12 +++--- src/libextra/workcache.rs | 2 +- src/librustc/metadata/filesearch.rs | 2 +- src/librustc/metadata/tydecode.rs | 40 +++++++++---------- src/librustc/middle/borrowck/move_data.rs | 2 +- src/librustc/middle/mem_categorization.rs | 16 ++++---- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/ty.rs | 24 +++++------ .../middle/typeck/check/regionmanip.rs | 12 +++--- src/librustc/middle/typeck/infer/mod.rs | 4 +- src/libstd/hashmap.rs | 5 ++- src/libstd/iterator.rs | 2 +- src/libstd/os.rs | 2 +- src/libstd/str.rs | 4 +- src/libstd/task/spawn.rs | 4 ++ src/libstd/to_bytes.rs | 9 +++-- src/libstd/trie.rs | 6 +-- src/libstd/vec.rs | 8 ++-- src/libsyntax/ast_util.rs | 10 ++--- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/deriving/iter_bytes.rs | 12 ++++-- src/libsyntax/ext/deriving/rand.rs | 2 +- .../compile-fail/regions-creating-enums.rs | 4 +- 28 files changed, 118 insertions(+), 101 deletions(-) diff --git a/src/libextra/fun_treemap.rs b/src/libextra/fun_treemap.rs index eb8c27e9902b..5906e809c985 100644 --- a/src/libextra/fun_treemap.rs +++ b/src/libextra/fun_treemap.rs @@ -66,9 +66,9 @@ pub fn traverse(m: Treemap, f: &fn(&K, &V)) { // matches to me, so I changed it. but that may be a // de-optimization -- tjc Node(@ref k, @ref v, left, right) => { - traverse(left, f); + traverse(left, |k,v| f(k,v)); f(k, v); - traverse(right, f); + traverse(right, |k,v| f(k,v)); } } } diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index fed73256c002..71393ff9fae2 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -1078,7 +1078,7 @@ pub mod node { pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool { return loop_leaves(node,|leaf| { - leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(it) + leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(|c| it(c)) }); } @@ -1101,7 +1101,7 @@ pub mod node { loop { match (*current) { Leaf(x) => return it(x), - Concat(ref x) => if loop_leaves(x.left, it) { //non tail call + Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call current = x.right; //tail call } else { return false; diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 6befd49e8afd..10dbe2326d76 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -42,7 +42,8 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { let mid = v_len / 2 + begin; let a = (begin, mid); let b = (mid, end); - return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le)); + return merge(|x,y| le(x,y), merge_sort_(v, a, |x,y| le(x,y)), + merge_sort_(v, b, |x,y| le(x,y))); } fn merge(le: Le, a: &[T], b: &[T]) -> ~[T] { @@ -83,10 +84,10 @@ fn qsort(arr: &mut [T], left: uint, right: uint, compare_func: Le) { if right > left { let pivot = (left + right) / 2u; - let new_pivot = part::(arr, left, right, pivot, compare_func); + let new_pivot = part::(arr, left, right, pivot, |x,y| compare_func(x,y)); if new_pivot != 0u { // Need to do this check before recursing due to overflow - qsort::(arr, left, new_pivot - 1u, compare_func); + qsort::(arr, left, new_pivot - 1u, |x,y| compare_func(x,y)); } qsort::(arr, new_pivot + 1u, right, compare_func); } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 3908b61381b7..9c6be901d980 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -563,7 +563,9 @@ impl RWlock { (&self.order_lock).acquire(); do (&self.access_lock).access_waitqueue { (&self.order_lock).release(); - task::rekillable(blk) + do task::rekillable { + blk() + } } } } @@ -1182,12 +1184,12 @@ mod tests { Write => x.write(blk), Downgrade => do x.write_downgrade |mode| { - (&mode).write(blk); + do mode.write { blk() }; }, DowngradeRead => do x.write_downgrade |mode| { let mode = x.downgrade(mode); - (&mode).read(blk); + do mode.read { blk() }; }, } } @@ -1340,10 +1342,10 @@ mod tests { fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) { if downgrade { do x.write_downgrade |mode| { - (&mode).write_cond(blk) + do mode.write_cond |c| { blk(c) } } } else { - x.write_cond(blk) + do x.write_cond |c| { blk(c) } } } let x = ~RWlock(); diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 209b46809ce3..50ca96e6e21d 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -678,7 +678,7 @@ impl BenchHarness { // Initial bench run to get ballpark figure. let mut n = 1_u64; - self.bench_n(n, f); + self.bench_n(n, |x| f(x)); while n < 1_000_000_000 && self.ns_elapsed() < 1_000_000_000 { @@ -694,7 +694,7 @@ impl BenchHarness { n = u64::max(u64::min(n+n/2, 100*last), last+1); n = round_up(n); - self.bench_n(n, f); + self.bench_n(n, |x| f(x)); } } @@ -714,7 +714,7 @@ impl BenchHarness { magnitude * 2); let samples = do vec::from_fn(n_samples) |_| { - self.bench_n(n_iter as u64, f); + self.bench_n(n_iter as u64, |x| f(x)); self.ns_per_iter() as f64 }; diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 4622b8c72848..d546b48f8175 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -511,14 +511,14 @@ impl TreeNode { fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, f: &fn(&'r K, &'r V) -> bool) -> bool { - node.iter().advance(|x| each(&x.left, f) && f(&x.key, &x.value) && - each(&x.right, f)) + node.iter().advance(|x| each(&x.left, |k,v| f(k,v)) && f(&x.key, &x.value) && + each(&x.right, |k,v| f(k,v))) } fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, f: &fn(&'r K, &'r V) -> bool) -> bool { - node.iter().advance(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) && - each_reverse(&x.left, f)) + node.iter().advance(|x| each_reverse(&x.right, |k,v| f(k,v)) && f(&x.key, &x.value) && + each_reverse(&x.left, |k,v| f(k,v))) } fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, @@ -527,9 +527,9 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, match *node { Some(~TreeNode{key: ref key, value: ref mut value, left: ref mut left, right: ref mut right, _}) => { - if !mutate_values(left, f) { return false } + if !mutate_values(left, |k,v| f(k,v)) { return false } if !f(key, value) { return false } - if !mutate_values(right, f) { return false } + if !mutate_values(right, |k,v| f(k,v)) { return false } } None => return false } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 567f9eda2fba..4d4f3c3a49b0 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -107,7 +107,7 @@ struct WorkKey { impl to_bytes::IterBytes for WorkKey { #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f) + self.kind.iter_bytes(lsb0, |b| f(b)) && self.name.iter_bytes(lsb0, |b| f(b)) } } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 6268932ba995..abfb5f7d4d4b 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -48,7 +48,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, debug!("filesearch: searching additional lib search paths [%?]", self.addl_lib_search_paths.len()); // a little weird - self.addl_lib_search_paths.iter().advance(f); + self.addl_lib_search_paths.iter().advance(|path| f(path)); debug!("filesearch: searching target lib path"); if !f(&make_target_lib_path(self.sysroot, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 1ec5c983f624..227865810734 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -189,11 +189,11 @@ fn parse_trait_store(st: &mut PState) -> ty::TraitStore { fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs { let self_r = parse_opt(st, |st| parse_region(st) ); - let self_ty = parse_opt(st, |st| parse_ty(st, conv) ); + let self_ty = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)) ); assert_eq!(next(st), '['); let mut params: ~[ty::t] = ~[]; - while peek(st) != ']' { params.push(parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); } st.pos = st.pos + 1u; return ty::substs { @@ -270,8 +270,8 @@ fn parse_str(st: &mut PState, term: char) -> ~str { } fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef { - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); ty::TraitRef {def_id: def, substs: substs} } @@ -301,18 +301,18 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'c' => return ty::mk_char(), 't' => { assert_eq!(next(st), '['); - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_enum(st.tcx, def, substs); } 'x' => { assert_eq!(next(st), '['); - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); let store = parse_trait_store(st); let mt = parse_mutability(st); - let bounds = parse_bounds(st, conv); + let bounds = parse_bounds(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_trait(st.tcx, def, substs, store, mt, bounds.builtin_bounds); } @@ -346,7 +346,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'T' => { assert_eq!(next(st), '['); let mut params = ~[]; - while peek(st) != ']' { params.push(parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); } st.pos = st.pos + 1u; return ty::mk_tup(st.tcx, params); } @@ -380,15 +380,15 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { } } '"' => { - let _ = parse_def(st, TypeWithId, conv); - let inner = parse_ty(st, conv); + let _ = parse_def(st, TypeWithId, |x,y| conv(x,y)); + let inner = parse_ty(st, |x,y| conv(x,y)); inner } 'B' => ty::mk_opaque_box(st.tcx), 'a' => { assert_eq!(next(st), '['); - let did = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let did = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_struct(st.tcx, did, substs); } @@ -473,8 +473,8 @@ fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy { let purity = parse_purity(next(st)); let onceness = parse_onceness(next(st)); let region = parse_region(st); - let bounds = parse_bounds(st, conv); - let sig = parse_sig(st, conv); + let bounds = parse_bounds(st, |x,y| conv(x,y)); + let sig = parse_sig(st, |x,y| conv(x,y)); ty::ClosureTy { purity: purity, sigil: sigil, @@ -500,7 +500,7 @@ fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig { assert_eq!(next(st), '['); let mut inputs = ~[]; while peek(st) != ']' { - inputs.push(parse_ty(st, conv)); + inputs.push(parse_ty(st, |x,y| conv(x,y))); } st.pos += 1u; // eat the ']' let ret_ty = parse_ty(st, conv); @@ -544,8 +544,8 @@ pub fn parse_type_param_def_data(data: &[u8], start: uint, } fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef { - ty::TypeParameterDef {def_id: parse_def(st, NominalType, conv), - bounds: @parse_bounds(st, conv)} + ty::TypeParameterDef {def_id: parse_def(st, NominalType, |x,y| conv(x,y)), + bounds: @parse_bounds(st, |x,y| conv(x,y))} } fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { @@ -571,7 +571,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { param_bounds.builtin_bounds.add(ty::BoundSized); } 'I' => { - param_bounds.trait_bounds.push(@parse_trait_ref(st, conv)); + param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y))); } '.' => { return param_bounds; diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 7396dc1bd7bf..623dbbd61b24 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -411,7 +411,7 @@ impl MoveData { let mut p = self.path(index).first_child; while p != InvalidMovePathIndex { - if !self.each_extending_path(p, f) { + if !self.each_extending_path(p, |x| f(x)) { return false; } p = self.path(p).next_sibling; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 52c01fa76476..a2907e991209 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -890,7 +890,7 @@ impl mem_categorization_ctxt { pat, downcast_cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(subcmt, subpat, op); + self.cat_pattern(subcmt, subpat, |x,y| op(x,y)); } } Some(&ast::def_fn(*)) | @@ -901,12 +901,12 @@ impl mem_categorization_ctxt { self.cat_imm_interior( pat, cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(cmt_field, subpat, op); + self.cat_pattern(cmt_field, subpat, |x,y| op(x,y)); } } Some(&ast::def_static(*)) => { for subpats.iter().advance |&subpat| { - self.cat_pattern(cmt, subpat, op); + self.cat_pattern(cmt, subpat, |x,y| op(x,y)); } } _ => { @@ -930,7 +930,7 @@ impl mem_categorization_ctxt { for field_pats.iter().advance |fp| { let field_ty = self.pat_ty(fp.pat); // see (*) let cmt_field = self.cat_field(pat, cmt, fp.ident, field_ty); - self.cat_pattern(cmt_field, fp.pat, op); + self.cat_pattern(cmt_field, fp.pat, |x,y| op(x,y)); } } @@ -942,7 +942,7 @@ impl mem_categorization_ctxt { self.cat_imm_interior( pat, cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(subcmt, subpat, op); + self.cat_pattern(subcmt, subpat, |x,y| op(x,y)); } } @@ -956,15 +956,15 @@ impl mem_categorization_ctxt { ast::pat_vec(ref before, slice, ref after) => { let elt_cmt = self.cat_index(pat, cmt, 0); for before.iter().advance |&before_pat| { - self.cat_pattern(elt_cmt, before_pat, op); + self.cat_pattern(elt_cmt, before_pat, |x,y| op(x,y)); } for slice.iter().advance |&slice_pat| { let slice_ty = self.pat_ty(slice_pat); let slice_cmt = self.cat_rvalue(pat, slice_ty); - self.cat_pattern(slice_cmt, slice_pat, op); + self.cat_pattern(slice_cmt, slice_pat, |x,y| op(x,y)); } for after.iter().advance |&after_pat| { - self.cat_pattern(elt_cmt, after_pat, op); + self.cat_pattern(elt_cmt, after_pat, |x,y| op(x,y)); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index efa69ab5e625..d9fea1213468 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -674,7 +674,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, int::to_str(variant.disr_val)); let variant_cx = iter_variant(variant_cx, repr, av, *variant, - substs.tps, f); + substs.tps, |x,y,z| f(x,y,z)); match adt::trans_case(cx, repr, variant.disr_val) { _match::single_result(r) => { AddCase(llswitch, r.val, variant_cx.llbb) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a990e4c70a94..9f9127663af7 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1241,15 +1241,15 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { } ty_enum(_, ref substs) | ty_struct(_, ref substs) | ty_trait(_, ref substs, _, _, _) => { - for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, f); } + for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, |x| f(x)); } } - ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, f); } } + ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, |x| f(x)); } } ty_bare_fn(ref ft) => { - for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, |x| f(x)); } maybe_walk_ty(ft.sig.output, f); } ty_closure(ref ft) => { - for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, |x| f(x)); } maybe_walk_ty(ft.sig.output, f); } } @@ -1331,7 +1331,7 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty { // Folds types from the bottom up. pub fn fold_ty(cx: ctxt, t0: t, fldop: &fn(t) -> t) -> t { - let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), fldop)); + let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), |t| fldop(t))); fldop(mk_t(cx, sty)) } @@ -1345,8 +1345,8 @@ pub fn walk_regions_and_ty( fold_regions_and_ty( cx, ty, |r| { walkr(r); r }, - |t| { walk_regions_and_ty(cx, t, walkr, walkt); t }, - |t| { walk_regions_and_ty(cx, t, walkr, walkt); t }); + |t| { walk_regions_and_ty(cx, t, |r| walkr(r), |t| walkt(t)); t }, + |t| { walk_regions_and_ty(cx, t, |r| walkr(r), |t| walkt(t)); t }); } } @@ -1426,8 +1426,8 @@ pub fn fold_regions( fold_regions_and_ty( cx, ty, |r| fldr(r, in_fn), - |t| do_fold(cx, t, true, fldr), - |t| do_fold(cx, t, in_fn, fldr)) + |t| do_fold(cx, t, true, |r,b| fldr(r,b)), + |t| do_fold(cx, t, in_fn, |r,b| fldr(r,b))) } do_fold(cx, ty, false, fldr) } @@ -2374,7 +2374,7 @@ pub fn type_structurally_contains(cx: ctxt, for (*enum_variants(cx, did)).iter().advance |variant| { for variant.args.iter().advance |aty| { let sty = subst(cx, substs, *aty); - if type_structurally_contains(cx, sty, test) { return true; } + if type_structurally_contains(cx, sty, |x| test(x)) { return true; } } } return false; @@ -2383,14 +2383,14 @@ pub fn type_structurally_contains(cx: ctxt, let r = lookup_struct_fields(cx, did); for r.iter().advance |field| { let ft = lookup_field_type(cx, did, field.id, substs); - if type_structurally_contains(cx, ft, test) { return true; } + if type_structurally_contains(cx, ft, |x| test(x)) { return true; } } return false; } ty_tup(ref ts) => { for ts.iter().advance |tt| { - if type_structurally_contains(cx, *tt, test) { return true; } + if type_structurally_contains(cx, *tt, |x| test(x)) { return true; } } return false; } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 160737142c8c..fb79a7c3c994 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -112,7 +112,7 @@ pub fn replace_bound_regions_in_fn_sig( // kinds of types. This had already caused me several // bugs so I decided to switch over. do ty::fold_regions(tcx, *ty) |r, in_fn| { - if !in_fn { isr = append_isr(isr, to_r, r); } + if !in_fn { isr = append_isr(isr, |br| to_r(br), r); } r }; @@ -211,18 +211,18 @@ pub fn relate_nested_regions( match ty::get(ty).sty { ty::ty_rptr(r, ref mt) | ty::ty_evec(ref mt, ty::vstore_slice(r)) => { - relate(*the_stack, r, relate_op); + relate(*the_stack, r, |x,y| relate_op(x,y)); the_stack.push(r); - walk_ty(tcx, the_stack, mt.ty, relate_op); + walk_ty(tcx, the_stack, mt.ty, |x,y| relate_op(x,y)); the_stack.pop(); } _ => { ty::fold_regions_and_ty( tcx, ty, - |r| { relate(*the_stack, r, relate_op); r }, - |t| { walk_ty(tcx, the_stack, t, relate_op); t }, - |t| { walk_ty(tcx, the_stack, t, relate_op); t }); + |r| { relate( *the_stack, r, |x,y| relate_op(x,y)); r }, + |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t }, + |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t }); } } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 1bfe452f25e0..3e2d4a71dfbe 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -582,7 +582,7 @@ impl InferCtxt { debug!("commit()"); do indent { - let r = self.try(f); + let r = self.try(|| f()); self.ty_var_bindings.bindings.truncate(0); self.int_var_bindings.bindings.truncate(0); @@ -836,6 +836,6 @@ pub fn fold_regions_in_sig( fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig { do ty::fold_sig(fn_sig) |t| { - ty::fold_regions(tcx, t, fldr) + ty::fold_regions(tcx, t, |r, in_fn| fldr(r, in_fn)) } } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index bfa0f2fa124d..7f9fb6ad9380 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -671,7 +671,7 @@ impl Set for HashSet { fn symmetric_difference(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.difference(other, f) && other.difference(self, f) + self.difference(other, |t| f(t)) && other.difference(self, |t| f(t)) } /// Visit the values representing the intersection @@ -681,7 +681,8 @@ impl Set for HashSet { /// Visit the values representing the union fn union(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.iter().advance(f) && other.iter().advance(|v| self.contains(v) || f(v)) + self.iter().advance(|t| f(t)) && + other.iter().advance(|v| self.contains(v) || f(v)) } } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 765bf3b36f28..976ca8bae7a8 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -964,7 +964,7 @@ impl<'self, A, T: Iterator, B, U: Iterator> Iterator for return Some(x) } } - match self.iter.next().map_consume(self.f) { + match self.iter.next().map_consume(|x| (self.f)(x)) { None => return None, next => self.subiter = next, } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 400a93ee28f4..1fbcda12dce1 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -595,7 +595,7 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool { let r = list_dir(p); r.iter().advance(|q| { let path = &p.push(*q); - f(path) && (!path_is_dir(path) || walk_dir(path, f)) + f(path) && (!path_is_dir(path) || walk_dir(path, |p| f(p))) }) } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 2144afc0fbd1..e47800d70c6b 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -463,7 +463,7 @@ pub fn each_split_within<'a>(ss: &'a str, cont }; - ss.iter().enumerate().advance(machine); + ss.iter().enumerate().advance(|x| machine(x)); // Let the automaton 'run out' by supplying trailing whitespace let mut fake_i = ss.len(); @@ -761,7 +761,7 @@ impl<'self> StrUtil for &'self str { // NB: len includes the trailing null. assert!(len > 0); if unsafe { *(ptr::offset(buf,len-1)) != 0 } { - to_owned(self).as_c_str(f) + to_owned(self).as_c_str(|s| f(s)) } else { f(buf as *libc::c_char) } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 8f06fede0572..c932a9660c2f 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -230,11 +230,15 @@ fn each_ancestor(list: &mut AncestorList, // 'do_continue' - Did the forward_blk succeed at this point? (i.e., // should we recurse? or should our callers unwind?) + let forward_blk = Cell::new(forward_blk); + // The map defaults to None, because if ancestors is None, we're at // the end of the list, which doesn't make sense to coalesce. return do (**ancestors).map_default((None,false)) |ancestor_arc| { // NB: Takes a lock! (this ancestor node) do access_ancestors(ancestor_arc) |nobe| { + // Argh, but we couldn't give it to coalesce() otherwise. + let forward_blk = forward_blk.take(); // Check monotonicity assert!(last_generation > nobe.generation); /*##########################################################* diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 6f0c615d007c..d6e92dd679ea 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -232,7 +232,8 @@ impl IterBytes for (A,B) { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { - (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) } + (ref a, ref b) => { a.iter_bytes(lsb0, |b| f(b)) && + b.iter_bytes(lsb0, |b| f(b)) } } } } @@ -242,7 +243,9 @@ impl IterBytes for (A,B,C) { fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { (ref a, ref b, ref c) => { - a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) && c.iter_bytes(lsb0, f) + a.iter_bytes(lsb0, |b| f(b)) && + b.iter_bytes(lsb0, |b| f(b)) && + c.iter_bytes(lsb0, |b| f(b)) } } } @@ -296,7 +299,7 @@ impl IterBytes for Option { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { - Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f), + Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)), None => 1u8.iter_bytes(lsb0, f) } } diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 8f70c75439a0..b9b03ea56619 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -251,7 +251,7 @@ impl TrieNode { fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { - Internal(ref x) => if !x.each(f) { return false }, + Internal(ref x) => if !x.each(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () } @@ -262,7 +262,7 @@ impl TrieNode { fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { - Internal(ref x) => if !x.each_reverse(f) { return false }, + Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () } @@ -273,7 +273,7 @@ impl TrieNode { fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool { for self.children.mut_iter().advance |child| { match *child { - Internal(ref mut x) => if !x.mutate_values(f) { + Internal(ref mut x) => if !x.mutate_values(|i,t| f(i,t)) { return false }, External(k, ref mut v) => if !f(&k, v) { return false }, diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 8555d99255d5..4e7943f7cfd2 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -191,7 +191,7 @@ pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut start = 0u; let mut result = ~[]; while start < ln { - match position_between(v, start, ln, f) { + match position_between(v, start, ln, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(start, i).to_owned()); @@ -215,7 +215,7 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while start < ln && count > 0u { - match position_between(v, start, ln, f) { + match position_between(v, start, ln, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(start, i).to_owned()); @@ -240,7 +240,7 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut end = ln; let mut result = ~[]; while end > 0 { - match rposition_between(v, 0, end, f) { + match rposition_between(v, 0, end, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1, end).to_owned()); @@ -265,7 +265,7 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while end > 0u && count > 0u { - match rposition_between(v, 0u, end, f) { + match rposition_between(v, 0u, end, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1u, end).to_owned()); diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 6e21ceb64c43..9439f45be21b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -535,18 +535,18 @@ pub fn walk_pat(pat: @pat, it: &fn(@pat) -> bool) -> bool { match pat.node { pat_ident(_, _, Some(p)) => walk_pat(p, it), pat_struct(_, ref fields, _) => { - fields.iter().advance(|f| walk_pat(f.pat, it)) + fields.iter().advance(|f| walk_pat(f.pat, |p| it(p))) } pat_enum(_, Some(ref s)) | pat_tup(ref s) => { - s.iter().advance(|&p| walk_pat(p, it)) + s.iter().advance(|&p| walk_pat(p, |p| it(p))) } pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } pat_vec(ref before, ref slice, ref after) => { - before.iter().advance(|&p| walk_pat(p, it)) && - slice.iter().advance(|&p| walk_pat(p, it)) && - after.iter().advance(|&p| walk_pat(p, it)) + before.iter().advance(|&p| walk_pat(p, |p| it(p))) && + slice.iter().advance(|&p| walk_pat(p, |p| it(p))) && + after.iter().advance(|&p| walk_pat(p, |p| it(p))) } pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _) | pat_enum(_, _) => { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 282a28ff9e07..78fdb99753d4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -509,7 +509,7 @@ impl MapChain{ } }, ConsMapChain (~ref mut map, rest) => { - if satisfies_pred(map,&n,pred) { + if satisfies_pred(map,&n,|v|pred(v)) { map.insert(key,ext); } else { rest.insert_into_frame(key,ext,n,pred) diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 8403234f8925..15fb6ee9ff77 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -43,15 +43,21 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt, } fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { - let lsb0_f = match substr.nonself_args { - [l, f] => ~[l, f], + let (lsb0, f)= match substr.nonself_args { + [l, f] => (l, f), _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`") }; + // Build the "explicitly borrowed" stack closure, "|_buf| f(_buf)". + let blk_arg = cx.ident_of("_buf"); + let borrowed_f = + cx.lambda_expr_1(span, cx.expr_call(span, f, ~[cx.expr_ident(span, blk_arg)]), + blk_arg); + let iter_bytes_ident = substr.method_ident; let call_iterbytes = |thing_expr| { cx.expr_method_call(span, thing_expr, iter_bytes_ident, - copy lsb0_f) + ~[lsb0, borrowed_f]) }; let mut exprs = ~[]; let fields; diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index dfbc028ddf6a..19aa29a62a9c 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -99,7 +99,7 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { (ident, ref summary) => { cx.arm(span, ~[ pat ], - rand_thing(cx, span, ident, summary, rand_call)) + rand_thing(cx, span, ident, summary, || rand_call())) } } }; diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 2ab0c14b49b6..c2d8427d5eb3 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -33,8 +33,8 @@ fn map_nums(x: &ast, f: &fn(uint) -> uint) -> &ast { return &num(f(x)); //~ ERROR borrowed value does not live long enough } add(x, y) => { - let m_x = map_nums(x, f); - let m_y = map_nums(y, f); + let m_x = map_nums(x, |z| f(z)); + let m_y = map_nums(y, |z| f(z)); return &add(m_x, m_y); //~ ERROR borrowed value does not live long enough } } From 98c169e4e594fda871628edc4b9c82a56072c0df Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 20:31:29 -0400 Subject: [PATCH 280/336] Make librust satisfy noncopyable stack closures --- src/librust/rust.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 68427745ff59..ba5e592b605c 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -57,13 +57,13 @@ impl ValidUsage { } enum Action<'self> { - Call(&'self fn(args: &[~str]) -> ValidUsage), - CallMain(&'static str, &'self fn()), + Call(&'self fn:Copy(args: &[~str]) -> ValidUsage), + CallMain(&'static str, &'self fn:Copy()), } enum UsageSource<'self> { UsgStr(&'self str), - UsgCall(&'self fn()), + UsgCall(&'self fn:Copy()), } struct Command<'self> { From d4722e53332a854228a2db6a682da5e0017fe73e Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Fri, 21 Jun 2013 17:58:21 -0400 Subject: [PATCH 281/336] Trade stack closure copyability for type soundness. --- src/librustc/middle/kind.rs | 37 ++++++++++++++++++--------- src/librustc/middle/ty.rs | 13 ++++++++-- src/test/compile-fail/kindck-owned.rs | 2 +- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index f0c091ac53ca..d4b91ed589d0 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -171,7 +171,7 @@ fn with_appropriate_checker(cx: Context, id: node_id, // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); - check_freevar_bounds(cx, fv.span, var_t, bounds); + check_freevar_bounds(cx, fv.span, var_t, bounds, None); } fn check_for_box(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { @@ -182,13 +182,18 @@ fn with_appropriate_checker(cx: Context, id: node_id, // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); - check_freevar_bounds(cx, fv.span, var_t, bounds); + check_freevar_bounds(cx, fv.span, var_t, bounds, None); } - fn check_for_block(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_block(cx: Context, fv: &freevar_entry, + bounds: ty::BuiltinBounds, region: ty::Region) { let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); - check_freevar_bounds(cx, fv.span, var_t, bounds); + // FIXME(#3569): Figure out whether the implicit borrow is actually + // mutable. Currently we assume all upvars are referenced mutably. + let implicit_borrowed_type = ty::mk_mut_rptr(cx.tcx, region, var_t); + check_freevar_bounds(cx, fv.span, implicit_borrowed_type, + bounds, Some(var_t)); } fn check_for_bare(cx: Context, fv: @freevar_entry) { @@ -205,8 +210,9 @@ fn with_appropriate_checker(cx: Context, id: node_id, ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, bounds: bounds, _}) => { b(|cx, fv| check_for_box(cx, fv, bounds)) } - ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, _}) => { - b(|cx, fv| check_for_block(cx, fv, bounds)) + ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, + region: region, _}) => { + b(|cx, fv| check_for_block(cx, fv, bounds, region)) } ty::ty_bare_fn(_) => { b(check_for_bare) @@ -366,14 +372,21 @@ pub fn check_typaram_bounds(cx: Context, } pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, - bounds: ty::BuiltinBounds) + bounds: ty::BuiltinBounds, referenced_ty: Option) { do check_builtin_bounds(cx, ty, bounds) |missing| { - cx.tcx.sess.span_err( - sp, - fmt!("cannot capture variable of type `%s`, which does not fulfill \ - `%s`, in a bounded closure", - ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx))); + // Will be Some if the freevar is implicitly borrowed (stack closure). + // Emit a less mysterious error message in this case. + match referenced_ty { + Some(rty) => cx.tcx.sess.span_err(sp, + fmt!("cannot implicitly borrow variable of type `%s` in a bounded \ + stack closure (implicit reference does not fulfill `%s`)", + ty_to_str(cx.tcx, rty), missing.user_string(cx.tcx))), + None => cx.tcx.sess.span_err(sp, + fmt!("cannot capture variable of type `%s`, which does \ + not fulfill `%s`, in a bounded closure", + ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx))), + } cx.tcx.sess.span_note( sp, fmt!("this closure's environment must satisfy `%s`", diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9f9127663af7..b8ee1eee26e1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1828,7 +1828,9 @@ impl TypeContents { // Currently all noncopyable existentials are 2nd-class types // behind owned pointers. With dynamically-sized types, remove // this assertion. - assert!(self.intersects(TC_OWNED_POINTER)); + assert!(self.intersects(TC_OWNED_POINTER) || + // (...or stack closures without a copy bound.) + self.intersects(TC_BORROWED_POINTER)); } let tc = TC_MANAGED + TC_DTOR + TypeContents::sendable(cx); self.intersects(tc) @@ -2194,7 +2196,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ast::Once => TC_ONCE_CLOSURE, ast::Many => TC_NONE }; - st + rt + ot + // Prevent noncopyable types captured in the environment from being copied. + let ct = if cty.bounds.contains_elem(BoundCopy) || + cty.sigil == ast::ManagedSigil { + TC_NONE + } else { + TC_NONCOPY_TRAIT + }; + st + rt + ot + ct } fn trait_contents(store: TraitStore, mutbl: ast::mutability, diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index 3f859b7dc84e..848fd95a5607 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -29,6 +29,6 @@ fn main() { copy2(boxed); let owned: ~fn() = || {}; copy2(owned); //~ ERROR does not fulfill `Copy` - let borrowed: &fn() = || {}; + let borrowed: &fn:Copy() = || {}; copy2(borrowed); //~ ERROR does not fulfill `'static` } From d7544fe987104ad0a82b1929b819cfd7e2321bb2 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Mon, 24 Jun 2013 20:02:24 -0400 Subject: [PATCH 282/336] Add two tests for the case of the recurring closure. --- .../the-case-of-the-recurring-closure-2.rs | 44 +++++++++++++++++++ .../the-case-of-the-recurring-closure.rs | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/test/compile-fail/the-case-of-the-recurring-closure-2.rs create mode 100644 src/test/compile-fail/the-case-of-the-recurring-closure.rs diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs new file mode 100644 index 000000000000..bfb1e910495d --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs @@ -0,0 +1,44 @@ +// 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. + +// Tests correct kind-checking of the reason stack closures without the :Copy +// bound must be noncopyable. For details see +// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ + +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, bool) +} + +fn innocent_looking_victim() { + let mut x = Some(~"hello"); + do conspirator |f, writer| { + if writer { + x = None; //~ ERROR cannot implicitly borrow + } else { + match x { + Some(ref msg) => { + (f.c)(f, true); + println(fmt!("%?", msg)); + }, + None => fail!("oops"), + } + } + } +} + +fn conspirator(f: &fn:Copy(&R, bool)) { + let r = R {c: f}; + f(&r, false) +} + +fn main() { innocent_looking_victim() } diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure.rs b/src/test/compile-fail/the-case-of-the-recurring-closure.rs new file mode 100644 index 000000000000..f05c30c3355e --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure.rs @@ -0,0 +1,44 @@ +// 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. + +// Tests correct kind-checking of the reason stack closures without the :Copy +// bound must be noncopyable. For details see +// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ + +struct R<'self> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: &'self fn(&R, bool) +} + +fn innocent_looking_victim() { + let mut x = Some(~"hello"); + do conspirator |f, writer| { + if writer { + x = None; + } else { + match x { + Some(ref msg) => { + (f.c)(f, true); + println(fmt!("%?", msg)); + }, + None => fail!("oops"), + } + } + } +} + +fn conspirator(f: &fn(&R, bool)) { + let r = R {c: f}; + f(&r, false) //~ ERROR use of moved value +} + +fn main() { innocent_looking_victim() } From 08a5278bb5cd11d7a4f986db627a585bdad878d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 25 Jun 2013 22:01:37 +0200 Subject: [PATCH 283/336] Add missing argument to a debug! call in trans_arg_expr --- src/librustc/middle/trans/callee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 4c07f88f16eb..8ef55f89d817 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -930,7 +930,7 @@ pub fn trans_arg_expr(bcx: block, ByRef(_) => val = scratch.val, } } else { - debug!("by copy arg with type %s"); + debug!("by copy arg with type %s", bcx.ty_to_str(arg_datum.ty)); match arg_datum.mode { ByRef(_) => val = Load(bcx, arg_datum.val), ByValue => val = arg_datum.val, From 2a40c5db469b5065f64c69ae7874f162ff2669a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 29 Jun 2013 16:43:39 +0200 Subject: [PATCH 284/336] Avoid extra casts for "self" arguments "self" is always passed as an opaque box, so there's no point in using the concrete self type when translating the argument. All it does it causing the value to be casted back to an opaque box right away. --- src/librustc/middle/trans/callee.rs | 9 +-------- src/librustc/middle/trans/meth.rs | 29 +++++++---------------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 8ef55f89d817..6d139130e2be 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -615,10 +615,7 @@ pub fn trans_call_inner(in_cx: block, } Method(d) => { // Weird but true: we pass self in the *environment* slot! - let llself = PointerCast(bcx, - d.llself, - Type::opaque_box(ccx).ptr_to()); - (d.llfn, llself) + (d.llfn, d.llself) } Closure(d) => { // Closures are represented as (llfn, llclosure) pair: @@ -944,10 +941,6 @@ pub fn trans_arg_expr(bcx: block, if formal_arg_ty != arg_datum.ty { // this could happen due to e.g. subtyping let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, &formal_arg_ty); - let llformal_arg_ty = match self_mode { - ty::ByRef => llformal_arg_ty.ptr_to(), - ty::ByCopy => llformal_arg_ty, - }; debug!("casting actual type (%s) to match formal (%s)", bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty)); val = PointerCast(bcx, val, llformal_arg_ty); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 0b051662781e..fa32dd5b93ef 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -133,8 +133,8 @@ pub fn trans_self_arg(bcx: block, let _icx = push_ctxt("impl::trans_self_arg"); let mut temp_cleanups = ~[]; - // Compute the type of self. - let self_ty = monomorphize_type(bcx, mentry.self_ty); + // self is passed as an opaque box in the environment slot + let self_ty = ty::mk_opaque_box(bcx.tcx()); let result = trans_arg_expr(bcx, self_ty, mentry.self_mode, @@ -576,7 +576,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, let llbox = Load(bcx, GEPi(bcx, llpair, [0u, abi::trt_field_box])); // Munge `llself` appropriately for the type of `self` in the method. - let self_mode; match explicit_self { ast::sty_static => { bcx.tcx().sess.bug("shouldn't see static method here"); @@ -597,12 +596,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, llself = llbox; } } - - let llscratch = alloca(bcx, val_ty(llself)); - Store(bcx, llself, llscratch); - llself = llscratch; - - self_mode = ty::ByRef; } ast::sty_box(_) => { // Bump the reference count on the box. @@ -615,12 +608,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, ty::BoxTraitStore => llself = llbox, _ => bcx.tcx().sess.bug("@self receiver with non-@Trait") } - - let llscratch = alloca(bcx, val_ty(llself)); - Store(bcx, llself, llscratch); - llself = llscratch; - - self_mode = ty::ByRef; } ast::sty_uniq(_) => { // Pass the unique pointer. @@ -628,15 +615,13 @@ pub fn trans_trait_callee_from_llval(bcx: block, ty::UniqTraitStore => llself = llbox, _ => bcx.tcx().sess.bug("~self receiver with non-~Trait") } - - let llscratch = alloca(bcx, val_ty(llself)); - Store(bcx, llself, llscratch); - llself = llscratch; - - self_mode = ty::ByRef; } } + let llscratch = alloca(bcx, val_ty(llself)); + Store(bcx, llself, llscratch); + llself = PointerCast(bcx, llscratch, Type::opaque_box(ccx).ptr_to()); + // Load the function from the vtable and cast it to the expected type. debug!("(translating trait callee) loading method"); let llcallee_ty = type_of_fn_from_ty(ccx, callee_ty); @@ -652,7 +637,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, llfn: mptr, llself: llself, self_ty: ty::mk_opaque_box(bcx.tcx()), - self_mode: self_mode, + self_mode: ty::ByRef, explicit_self: explicit_self /* XXX: Some(llbox) */ }) From 1662bd371c22ba5d476c0c9024fdd99534fc7867 Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Fri, 28 Jun 2013 18:32:26 -0400 Subject: [PATCH 285/336] Great renaming: propagate throughout the rest of the codebase --- src/libextra/arc.rs | 18 +++-- src/libextra/arena.rs | 21 +++--- src/libextra/base64.rs | 7 +- src/libextra/bitv.rs | 17 +++-- src/libextra/c_vec.rs | 9 ++- src/libextra/comm.rs | 9 ++- src/libextra/crypto/digest.rs | 5 +- src/libextra/crypto/sha1.rs | 3 +- src/libextra/crypto/sha2.rs | 3 +- src/libextra/dbg.rs | 6 +- src/libextra/deque.rs | 21 +++--- src/libextra/dlist.rs | 4 +- src/libextra/ebml.rs | 25 ++++--- src/libextra/extra.rs | 29 +++----- src/libextra/fileinput.rs | 20 +++--- src/libextra/flate.rs | 13 ++-- src/libextra/flatpipes.rs | 70 +++++++++---------- src/libextra/fun_treemap.rs | 5 +- src/libextra/future.rs | 17 +++-- src/libextra/getopts.rs | 21 +++--- src/libextra/io_util.rs | 8 +-- src/libextra/json.rs | 24 +++---- src/libextra/list.rs | 3 +- src/libextra/md4.rs | 5 +- src/libextra/net_ip.rs | 23 +++--- src/libextra/net_tcp.rs | 42 ++++++----- src/libextra/net_url.rs | 15 ++-- src/libextra/num/bigint.rs | 37 +++++----- src/libextra/num/complex.rs | 7 +- src/libextra/num/rational.rs | 12 ++-- src/libextra/par.rs | 11 ++- src/libextra/priority_queue.rs | 7 +- src/libextra/rc.rs | 13 ++-- src/libextra/rl.rs | 9 ++- src/libextra/rope.rs | 25 +++---- src/libextra/semver.rs | 15 ++-- src/libextra/serialize.rs | 11 ++- src/libextra/smallintmap.rs | 15 ++-- src/libextra/sort.rs | 33 ++++----- src/libextra/stats.rs | 9 ++- src/libextra/sync.rs | 24 +++---- src/libextra/task_pool.rs | 13 ++-- src/libextra/tempfile.rs | 28 ++++---- src/libextra/term.rs | 5 +- src/libextra/terminfo/parm.rs | 9 ++- src/libextra/terminfo/parser/compiled.rs | 7 +- src/libextra/terminfo/searcher.rs | 9 ++- src/libextra/terminfo/terminfo.rs | 2 +- src/libextra/test.rs | 39 +++++------ src/libextra/time.rs | 19 +++-- src/libextra/timer.rs | 28 ++++---- src/libextra/treemap.rs | 11 ++- src/libextra/uv_global_loop.rs | 21 +++--- src/libextra/uv_iotask.rs | 11 ++- src/libextra/uv_ll.rs | 28 ++++---- src/libextra/workcache.rs | 25 ++++--- src/librust/rust.rs | 21 ++---- src/librustc/back/link.rs | 47 ++++++------- src/librustc/back/passes.rs | 5 +- src/librustc/back/rpath.rs | 16 ++--- src/librustc/driver/driver.rs | 12 ++-- src/librustc/driver/session.rs | 3 +- src/librustc/front/config.rs | 5 +- src/librustc/front/std_inject.rs | 3 +- src/librustc/front/test.rs | 3 +- src/librustc/lib/llvm.rs | 11 ++- src/librustc/metadata/common.rs | 3 +- src/librustc/metadata/creader.rs | 5 +- src/librustc/metadata/csearch.rs | 3 +- src/librustc/metadata/cstore.rs | 5 +- src/librustc/metadata/decoder.rs | 15 ++-- src/librustc/metadata/encoder.rs | 17 +++-- src/librustc/metadata/filesearch.rs | 9 ++- src/librustc/metadata/loader.rs | 17 +++-- src/librustc/metadata/tydecode.rs | 5 +- src/librustc/metadata/tyencode.rs | 9 ++- src/librustc/middle/astencode.rs | 9 ++- src/librustc/middle/borrowck/check_loans.rs | 5 +- .../borrowck/gather_loans/gather_moves.rs | 1 - .../middle/borrowck/gather_loans/lifetime.rs | 1 - .../middle/borrowck/gather_loans/mod.rs | 1 - .../borrowck/gather_loans/restrictions.rs | 3 +- src/librustc/middle/borrowck/mod.rs | 9 ++- src/librustc/middle/borrowck/move_data.rs | 5 +- src/librustc/middle/check_const.rs | 1 - src/librustc/middle/check_match.rs | 5 +- src/librustc/middle/const_eval.rs | 7 +- src/librustc/middle/dataflow.rs | 11 ++- src/librustc/middle/entry.rs | 3 +- src/librustc/middle/freevars.rs | 3 +- src/librustc/middle/kind.rs | 1 - src/librustc/middle/lang_items.rs | 3 +- src/librustc/middle/lint.rs | 27 ++++--- src/librustc/middle/liveness.rs | 13 ++-- src/librustc/middle/mem_categorization.rs | 3 +- src/librustc/middle/moves.rs | 5 +- src/librustc/middle/pat_util.rs | 3 +- src/librustc/middle/privacy.rs | 3 +- src/librustc/middle/reachable.rs | 5 +- src/librustc/middle/region.rs | 3 +- src/librustc/middle/resolve.rs | 11 ++- src/librustc/middle/subst.rs | 1 - src/librustc/middle/trans/_match.rs | 7 +- src/librustc/middle/trans/adt.rs | 10 +-- src/librustc/middle/trans/asm.rs | 3 +- src/librustc/middle/trans/base.rs | 31 ++++---- src/librustc/middle/trans/build.rs | 11 ++- src/librustc/middle/trans/cabi.rs | 6 +- src/librustc/middle/trans/cabi_arm.rs | 4 +- src/librustc/middle/trans/cabi_mips.rs | 7 +- src/librustc/middle/trans/cabi_x86.rs | 1 - src/librustc/middle/trans/cabi_x86_64.rs | 8 +-- src/librustc/middle/trans/callee.rs | 3 - src/librustc/middle/trans/closure.rs | 5 +- src/librustc/middle/trans/common.rs | 17 +++-- src/librustc/middle/trans/consts.rs | 5 +- src/librustc/middle/trans/context.rs | 9 ++- src/librustc/middle/trans/controlflow.rs | 5 +- src/librustc/middle/trans/datum.rs | 3 +- src/librustc/middle/trans/debuginfo.rs | 17 +++-- src/librustc/middle/trans/expr.rs | 7 +- src/librustc/middle/trans/foreign.rs | 5 +- src/librustc/middle/trans/glue.rs | 7 +- src/librustc/middle/trans/inline.rs | 3 +- src/librustc/middle/trans/meth.rs | 3 +- src/librustc/middle/trans/monomorphize.rs | 3 +- src/librustc/middle/trans/reflect.rs | 6 +- src/librustc/middle/trans/tvec.rs | 2 +- src/librustc/middle/trans/type_.rs | 7 +- src/librustc/middle/trans/type_of.rs | 1 - src/librustc/middle/trans/type_use.rs | 6 +- src/librustc/middle/trans/write_guard.rs | 1 - src/librustc/middle/ty.rs | 21 +++--- src/librustc/middle/typeck/astconv.rs | 5 +- src/librustc/middle/typeck/check/_match.rs | 3 +- src/librustc/middle/typeck/check/demand.rs | 4 +- src/librustc/middle/typeck/check/method.rs | 9 ++- src/librustc/middle/typeck/check/mod.rs | 11 ++- src/librustc/middle/typeck/check/regionck.rs | 8 +-- .../middle/typeck/check/regionmanip.rs | 1 - src/librustc/middle/typeck/check/vtable.rs | 5 +- src/librustc/middle/typeck/check/writeback.rs | 1 - src/librustc/middle/typeck/coherence.rs | 9 ++- src/librustc/middle/typeck/collect.rs | 5 +- src/librustc/middle/typeck/infer/coercion.rs | 1 - src/librustc/middle/typeck/infer/combine.rs | 5 +- src/librustc/middle/typeck/infer/glb.rs | 1 - src/librustc/middle/typeck/infer/lattice.rs | 1 - src/librustc/middle/typeck/infer/lub.rs | 1 - src/librustc/middle/typeck/infer/mod.rs | 5 +- .../middle/typeck/infer/region_inference.rs | 9 ++- src/librustc/middle/typeck/infer/resolve.rs | 3 +- src/librustc/middle/typeck/infer/sub.rs | 1 - src/librustc/middle/typeck/infer/to_str.rs | 3 +- src/librustc/middle/typeck/infer/unify.rs | 1 - src/librustc/middle/typeck/mod.rs | 5 +- src/librustc/middle/typeck/rscope.rs | 3 +- src/librustc/rustc.rs | 42 +++++------ src/librustc/util/common.rs | 5 +- src/librustc/util/enum_set.rs | 6 +- src/librustc/util/ppaux.rs | 3 +- src/librustdoc/astsrv.rs | 7 +- src/librustdoc/attr_parser.rs | 2 - src/librustdoc/attr_pass.rs | 4 +- src/librustdoc/config.rs | 22 +++--- src/librustdoc/demo.rs | 1 - src/librustdoc/desc_to_brief_pass.rs | 4 +- src/librustdoc/doc.rs | 3 +- src/librustdoc/extract.rs | 3 +- src/librustdoc/fold.rs | 3 +- src/librustdoc/markdown_index_pass.rs | 2 - src/librustdoc/markdown_pass.rs | 8 +-- src/librustdoc/markdown_writer.rs | 20 +++--- src/librustdoc/page_pass.rs | 5 +- src/librustdoc/parse.rs | 1 - src/librustdoc/pass.rs | 1 - src/librustdoc/path_pass.rs | 1 - src/librustdoc/prune_private_pass.rs | 3 +- src/librustdoc/rustdoc.rs | 20 +----- src/librustdoc/sectionalize_pass.rs | 4 +- src/librustdoc/text_pass.rs | 4 +- src/librustdoc/trim_pass.rs | 2 +- src/librustdoc/tystr_pass.rs | 4 +- src/librustdoc/unindent_pass.rs | 3 +- src/librustdoc/util.rs | 1 - src/librustpkg/api.rs | 10 +-- src/librustpkg/conditions.rs | 2 +- src/librustpkg/context.rs | 3 +- src/librustpkg/crate.rs | 4 +- src/librustpkg/messages.rs | 4 +- src/librustpkg/package_id.rs | 1 - src/librustpkg/package_path.rs | 10 +-- src/librustpkg/package_source.rs | 6 +- src/librustpkg/path_util.rs | 9 ++- src/librustpkg/rustpkg.rs | 29 +++----- src/librustpkg/search.rs | 1 - src/librustpkg/tests.rs | 9 ++- .../fail/src/no-inferred-crates/src/zzyzx.rs | 2 +- .../testsuite/pass/src/hello-world/main.rs | 2 +- src/librustpkg/usage.rs | 2 +- src/librustpkg/util.rs | 5 +- src/librustpkg/version.rs | 3 +- src/librustpkg/workspace.rs | 2 +- 203 files changed, 808 insertions(+), 1086 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 30067c92300c..924283fa8de1 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -39,15 +39,14 @@ #[allow(missing_doc)]; -use core::prelude::*; use sync; use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars}; -use core::cast; -use core::unstable::sync::UnsafeAtomicRcBox; -use core::task; -use core::borrow; +use std::cast; +use std::unstable::sync::UnsafeAtomicRcBox; +use std::task; +use std::borrow; /// As sync::condvar, a mechanism for unlock-and-descheduling and signaling. pub struct Condvar<'self> { @@ -514,14 +513,13 @@ impl<'self, T:Freeze + Send> RWReadMode<'self, T> { #[cfg(test)] mod tests { - use core::prelude::*; use arc::*; - use core::cell::Cell; - use core::comm; - use core::task; - use core::uint; + use std::cell::Cell; + use std::comm; + use std::task; + use std::uint; #[test] fn manually_share_arc() { diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs index 2c6e7a30448c..f378384c5645 100644 --- a/src/libextra/arena.rs +++ b/src/libextra/arena.rs @@ -34,22 +34,21 @@ #[allow(missing_doc)]; -use core::prelude::*; use list::{MutList, MutCons, MutNil}; -use core::at_vec; -use core::cast::{transmute, transmute_mut, transmute_mut_region}; -use core::cast; -use core::ptr; -use core::sys; -use core::uint; -use core::vec; -use core::unstable::intrinsics; -use core::unstable::intrinsics::{TyDesc}; +use std::at_vec; +use std::cast::{transmute, transmute_mut, transmute_mut_region}; +use std::cast; +use std::ptr; +use std::sys; +use std::uint; +use std::vec; +use std::unstable::intrinsics; +use std::unstable::intrinsics::{TyDesc}; #[cfg(not(stage0))] -use core::unstable::intrinsics::{get_tydesc}; +use std::unstable::intrinsics::{get_tydesc}; #[cfg(stage0)] unsafe fn get_tydesc() -> *TyDesc { diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index 392e7ff29a22..a53a22ee831d 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -10,9 +10,8 @@ //! Base64 binary-to-text encoding -use core::prelude::*; -use core::vec; +use std::vec; /// A trait for converting a value to base64 encoding. pub trait ToBase64 { @@ -199,7 +198,7 @@ impl<'self> FromBase64 for &'self str { * Convert any base64 encoded string (literal, `@`, `&`, or `~`) * to the byte values it encodes. * - * You can use the `from_bytes` function in `core::str` + * You can use the `from_bytes` function in `std::str` * to turn a `[u8]` into a string with characters corresponding to those values. * * # Example @@ -210,7 +209,7 @@ impl<'self> FromBase64 for &'self str { * extern mod extra; * use extra::base64::ToBase64; * use extra::base64::FromBase64; - * use core::str; + * use std::str; * * fn main () { * let hello_str = "Hello, World".to_base64(); diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 4fe7761bf18d..ca1deaf33ee2 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -10,12 +10,11 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::cmp; -use core::ops; -use core::uint; -use core::vec; +use std::cmp; +use std::ops; +use std::uint; +use std::vec; struct SmallBitv { /// only the lowest nbits of this value are used. the rest is undefined. @@ -868,10 +867,10 @@ mod tests { use bitv::*; use bitv; - use core::uint; - use core::vec; - use core::rand; - use core::rand::Rng; + use std::uint; + use std::vec; + use std::rand; + use std::rand::Rng; static bench_bits : uint = 1 << 14; diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index 79ef5bf2b7ea..c6e7b5b0aa7c 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -36,10 +36,9 @@ * still held if needed. */ -use core::prelude::*; -use core::option; -use core::ptr; +use std::option; +use std::ptr; /** * The type representing a foreign chunk of memory @@ -150,8 +149,8 @@ mod tests { use c_vec::*; - use core::libc::*; - use core::libc; + use std::libc::*; + use std::libc; fn malloc(n: size_t) -> CVec { unsafe { diff --git a/src/libextra/comm.rs b/src/libextra/comm.rs index 2cb2128db5f7..44581efc6f07 100644 --- a/src/libextra/comm.rs +++ b/src/libextra/comm.rs @@ -16,12 +16,11 @@ Higher level communication abstractions. #[allow(missing_doc)]; -use core::prelude::*; -use core::comm::{GenericChan, GenericSmartChan, GenericPort}; -use core::comm::{Chan, Port, Selectable, Peekable}; -use core::comm; -use core::pipes; +use std::comm::{GenericChan, GenericSmartChan, GenericPort}; +use std::comm::{Chan, Port, Selectable, Peekable}; +use std::comm; +use std::pipes; /// An extension of `pipes::stream` that allows both sending and receiving. pub struct DuplexStream { diff --git a/src/libextra/crypto/digest.rs b/src/libextra/crypto/digest.rs index c4fb03a7a7de..26e8b80d8e3c 100644 --- a/src/libextra/crypto/digest.rs +++ b/src/libextra/crypto/digest.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::uint; -use core::vec; +use std::uint; +use std::vec; /** * The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2 diff --git a/src/libextra/crypto/sha1.rs b/src/libextra/crypto/sha1.rs index 5a67e08c1900..238e4a4d238d 100644 --- a/src/libextra/crypto/sha1.rs +++ b/src/libextra/crypto/sha1.rs @@ -22,7 +22,6 @@ * the `reset` method. */ -use core::prelude::*; use digest::Digest; @@ -241,7 +240,7 @@ impl Digest for Sha1 { #[cfg(test)] mod tests { - use core::vec; + use std::vec; use digest::{Digest, DigestUtil}; use sha1::Sha1; diff --git a/src/libextra/crypto/sha2.rs b/src/libextra/crypto/sha2.rs index e9c6ac722124..4b120c7b1184 100644 --- a/src/libextra/crypto/sha2.rs +++ b/src/libextra/crypto/sha2.rs @@ -8,9 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::uint; +use std::uint; use digest::Digest; diff --git a/src/libextra/dbg.rs b/src/libextra/dbg.rs index 43c4aecdd27f..1f424b23430c 100644 --- a/src/libextra/dbg.rs +++ b/src/libextra/dbg.rs @@ -12,17 +12,17 @@ #[allow(missing_doc)]; -use core::cast::transmute; +use std::cast::transmute; #[cfg(stage0)] use intrinsic::{get_tydesc}; #[cfg(not(stage0))] -use core::unstable::intrinsics::{get_tydesc}; +use std::unstable::intrinsics::{get_tydesc}; pub mod rustrt { #[cfg(stage0)] use intrinsic::{TyDesc}; #[cfg(not(stage0))] - use core::unstable::intrinsics::{TyDesc}; + use std::unstable::intrinsics::{TyDesc}; #[abi = "cdecl"] pub extern { diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index c70c87b6ea13..2b599d06dafe 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -9,12 +9,11 @@ // except according to those terms. //! A double-ended queue implemented as a circular buffer -use core::prelude::*; -use core::uint; -use core::util::replace; -use core::vec; -use core::cast::transmute; +use std::uint; +use std::util::replace; +use std::vec; +use std::cast::transmute; static initial_capacity: uint = 32u; // 2^5 @@ -254,8 +253,8 @@ fn get<'r, T>(elts: &'r [Option], i: uint) -> &'r T { #[cfg(test)] mod tests { use super::*; - use core::cmp::Eq; - use core::kinds::Copy; + use std::cmp::Eq; + use std::kinds::Copy; use core; #[test] @@ -463,12 +462,12 @@ mod tests { #[test] fn test_iter() { let mut d = Deque::new(); - for core::int::range(0,5) |i| { + for std::int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]); - for core::int::range(6,9) |i| { + for std::int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]); @@ -477,12 +476,12 @@ mod tests { #[test] fn test_rev_iter() { let mut d = Deque::new(); - for core::int::range(0,5) |i| { + for std::int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]); - for core::int::range(6,9) |i| { + for std::int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index ee86340e47be..e7dcb0fd7cee 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -18,9 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ -use core::prelude::*; -use core::managed; +use std::managed; pub type DListLink = Option<@mut DListNode>; @@ -522,7 +521,6 @@ impl DList { #[cfg(test)] mod tests { - use core::prelude::*; use super::*; diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 4634a7db05e3..c79b012cfc5b 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -10,9 +10,8 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::str; +use std::str; // Simple Extensible Binary Markup Language (ebml) reader and writer on a // cursor model. See the specification here: @@ -94,18 +93,18 @@ pub mod reader { use serialize; - use core::cast::transmute; - use core::int; - use core::io; - use core::option::{None, Option, Some}; + use std::cast::transmute; + use std::int; + use std::io; + use std::option::{None, Option, Some}; #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] - use core::ptr::offset; + use std::ptr::offset; #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] - use core::unstable::intrinsics::bswap32; + use std::unstable::intrinsics::bswap32; // ebml reading @@ -378,7 +377,7 @@ pub mod reader { fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } fn read_uint(&mut self) -> uint { let v = doc_as_u64(self.next_doc(EsUint)); - if v > (::core::uint::max_value as u64) { + if v > (::std::uint::max_value as u64) { fail!("uint %? too large for this architecture", v); } v as uint @@ -611,8 +610,8 @@ pub mod reader { pub mod writer { use super::*; - use core::cast; - use core::io; + use std::cast; + use std::io; // ebml writing pub struct Encoder { @@ -957,8 +956,8 @@ mod tests { use serialize::Encodable; use serialize; - use core::io; - use core::option::{None, Option, Some}; + use std::io; + use std::option::{None, Option, Some}; #[test] fn test_option_int() { diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index 11aebdf467ff..dae1487092ba 100644 --- a/src/libextra/extra.rs +++ b/src/libextra/extra.rs @@ -32,13 +32,9 @@ Rust extras are part of the standard Rust distribution. #[deny(non_camel_case_types)]; #[deny(missing_doc)]; -#[no_std]; +use std::str::{StrSlice, OwnedStr}; -extern mod core(name = "std", vers = "0.7-pre"); - -use core::str::{StrSlice, OwnedStr}; - -pub use core::os; +pub use std::os; pub mod uv_ll; @@ -135,21 +131,16 @@ pub mod serialize; // 'extra' so that macro-expanded references to extra::serialize and such // can be resolved within libextra. #[doc(hidden)] -pub mod std { +pub mod extra { pub use serialize; pub use test; // For bootstrapping. - pub use core::clone; - pub use core::condition; - pub use core::cmp; - pub use core::sys; - pub use core::unstable; - pub use core::str; - pub use core::os; -} -#[doc(hidden)] -pub mod extra { - pub use serialize; - pub use test; + pub use std::clone; + pub use std::condition; + pub use std::cmp; + pub use std::sys; + pub use std::unstable; + pub use std::str; + pub use std::os; } diff --git a/src/libextra/fileinput.rs b/src/libextra/fileinput.rs index 7a1e925a15dc..5367da2fa8d4 100644 --- a/src/libextra/fileinput.rs +++ b/src/libextra/fileinput.rs @@ -57,14 +57,14 @@ For more complicated uses (e.g. if one needs to pause iteration and resume it later), a `FileInput` instance can be constructed via the `from_vec`, `from_vec_raw` and `from_args` functions. -Once created, the `each_line` (from the `core::io::ReaderUtil` trait) +Once created, the `each_line` (from the `std::io::ReaderUtil` trait) and `each_line_state` methods allow one to iterate on the lines; the latter provides more information about the position within the iteration to the caller. It is possible (and safe) to skip lines and files using the `read_line` and `next_file` methods. Also, `FileInput` implements -`core::io::Reader`, and the state will be updated correctly while +`std::io::Reader`, and the state will be updated correctly while using any of those methods. E.g. the following program reads until an empty line, pauses for user @@ -96,12 +96,11 @@ total line count). #[allow(missing_doc)]; -use core::prelude::*; -use core::io::ReaderUtil; -use core::io; -use core::os; -use core::vec; +use std::io::ReaderUtil; +use std::io; +use std::os; +use std::vec; /** A summary of the internal state of a `FileInput` object. `line_num` @@ -410,13 +409,12 @@ pub fn input_vec_state(files: ~[Option], #[cfg(test)] mod test { - use core::prelude::*; use super::{FileInput, pathify, input_vec, input_vec_state}; - use core::io; - use core::uint; - use core::vec; + use std::io; + use std::uint; + use std::vec; fn make_file(path : &Path, contents: &[~str]) { let file = io::file_writer(path, [io::Create, io::Truncate]).get(); diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 0fde03b69cbf..b83177fff0bc 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -16,12 +16,12 @@ Simple compression #[allow(missing_doc)]; -use core::libc::{c_void, size_t, c_int}; -use core::libc; -use core::vec; +use std::libc::{c_void, size_t, c_int}; +use std::libc; +use std::vec; pub mod rustrt { - use core::libc::{c_int, c_void, size_t}; + use std::libc::{c_int, c_void, size_t}; #[link_name = "rustrt"] pub extern { @@ -83,9 +83,8 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { #[cfg(test)] mod tests { use super::*; - use core::rand; - use core::rand::RngUtil; - use core::prelude::*; + use std::rand; + use std::rand::RngUtil; #[test] #[allow(non_implicitly_copyable_typarams)] diff --git a/src/libextra/flatpipes.rs b/src/libextra/flatpipes.rs index d5e43e85a140..e8bdc951ca4e 100644 --- a/src/libextra/flatpipes.rs +++ b/src/libextra/flatpipes.rs @@ -49,14 +49,13 @@ block the scheduler thread, so will their pipes. #[allow(missing_doc)]; -use core::prelude::*; // The basic send/recv interface FlatChan and PortChan will implement -use core::io; -use core::comm::GenericChan; -use core::comm::GenericPort; -use core::sys::size_of; -use core::vec; +use std::io; +use std::comm::GenericChan; +use std::comm::GenericPort; +use std::sys::size_of; +use std::vec; /** A FlatPort, consisting of a `BytePort` that receives byte vectors, @@ -95,9 +94,9 @@ pub mod serial { use flatpipes::bytepipes::{PipeBytePort, PipeByteChan}; use flatpipes::{FlatPort, FlatChan}; - use core::io::{Reader, Writer}; - use core::comm::{Port, Chan}; - use core::comm; + use std::io::{Reader, Writer}; + use std::comm::{Port, Chan}; + use std::comm; pub type ReaderPort = FlatPort< T, DeserializingUnflattener, @@ -172,16 +171,15 @@ POD are not equivelant. */ pub mod pod { - use core::prelude::*; use flatpipes::flatteners::{PodUnflattener, PodFlattener}; use flatpipes::bytepipes::{ReaderBytePort, WriterByteChan}; use flatpipes::bytepipes::{PipeBytePort, PipeByteChan}; use flatpipes::{FlatPort, FlatChan}; - use core::io::{Reader, Writer}; - use core::comm::{Port, Chan}; - use core::comm; + use std::io::{Reader, Writer}; + use std::comm::{Port, Chan}; + use std::comm; pub type ReaderPort = FlatPort, ReaderBytePort>; @@ -337,7 +335,6 @@ impl,C:ByteChan> FlatChan { pub mod flatteners { - use core::prelude::*; use ebml; use flatpipes::{Flattener, Unflattener}; @@ -345,12 +342,12 @@ pub mod flatteners { use json; use serialize::{Encoder, Decoder, Encodable, Decodable}; - use core::cast; - use core::io::{Writer, Reader, ReaderUtil}; - use core::io; - use core::ptr; - use core::sys::size_of; - use core::vec; + use std::cast; + use std::io::{Writer, Reader, ReaderUtil}; + use std::io; + use std::ptr; + use std::sys::size_of; + use std::vec; // FIXME #4074: Copy + Send != POD pub struct PodUnflattener { @@ -509,13 +506,12 @@ pub mod flatteners { } pub mod bytepipes { - use core::prelude::*; use flatpipes::{ByteChan, BytePort}; - use core::comm::{Port, Chan}; - use core::comm; - use core::io::{Writer, Reader, ReaderUtil}; + use std::comm::{Port, Chan}; + use std::comm; + use std::io::{Writer, Reader, ReaderUtil}; pub struct ReaderBytePort { reader: R @@ -583,12 +579,12 @@ pub mod bytepipes { impl BytePort for PipeBytePort { fn try_recv(&self, count: uint) -> Option<~[u8]> { if self.buf.len() >= count { - let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); + let mut bytes = ::std::util::replace(&mut *self.buf, ~[]); *self.buf = bytes.slice(count, bytes.len()).to_owned(); bytes.truncate(count); return Some(bytes); } else if !self.buf.is_empty() { - let mut bytes = ::core::util::replace(&mut *self.buf, ~[]); + let mut bytes = ::std::util::replace(&mut *self.buf, ~[]); assert!(count > bytes.len()); match self.try_recv(count - bytes.len()) { Some(rest) => { @@ -637,7 +633,6 @@ pub mod bytepipes { #[cfg(test)] mod test { - use core::prelude::*; use flatpipes::{Flattener, Unflattener}; use flatpipes::bytepipes::*; @@ -647,11 +642,11 @@ mod test { use flatpipes::{BytePort, FlatChan, FlatPort}; use net::tcp::TcpSocketBuf; - use core::comm; - use core::int; - use core::io::BytesWriter; - use core::result; - use core::task; + use std::comm; + use std::int; + use std::io::BytesWriter; + use std::result; + use std::task; #[test] #[ignore(reason = "ebml failure")] @@ -772,7 +767,7 @@ mod test { writer_chan: WriterChanFactory, port: uint) { - use core::cell::Cell; + use std::cell::Cell; use net::ip; use net::tcp; use uv; @@ -871,17 +866,16 @@ mod test { // Tests that the different backends behave the same when the // binary streaming protocol is broken mod broken_protocol { - use core::prelude::*; use flatpipes::{BytePort, FlatPort}; use flatpipes::flatteners::PodUnflattener; use flatpipes::pod; use io_util::BufReader; - use core::comm; - use core::io; - use core::sys; - use core::task; + use std::comm; + use std::io; + use std::sys; + use std::task; type PortLoader

= ~fn(~[u8]) -> FlatPort, P>; diff --git a/src/libextra/fun_treemap.rs b/src/libextra/fun_treemap.rs index 5906e809c985..4461a4dba5fd 100644 --- a/src/libextra/fun_treemap.rs +++ b/src/libextra/fun_treemap.rs @@ -19,10 +19,9 @@ * of features. */ -use core::prelude::*; -use core::cmp::{Eq, Ord}; -use core::option::{Some, None}; +use std::cmp::{Eq, Ord}; +use std::option::{Some, None}; pub type Treemap = @TreeNode; diff --git a/src/libextra/future.rs b/src/libextra/future.rs index 00f4cc3989be..3ef71e1731b2 100644 --- a/src/libextra/future.rs +++ b/src/libextra/future.rs @@ -25,13 +25,12 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::cast; -use core::cell::Cell; -use core::comm::{PortOne, oneshot, send_one, recv_one}; -use core::task; -use core::util::replace; +use std::cast; +use std::cell::Cell; +use std::comm::{PortOne, oneshot, send_one, recv_one}; +use std::task; +use std::util::replace; #[doc = "The future type"] pub struct Future { @@ -151,9 +150,9 @@ pub fn spawn(blk: ~fn() -> A) -> Future { mod test { use future::*; - use core::cell::Cell; - use core::comm::{oneshot, send_one}; - use core::task; + use std::cell::Cell; + use std::comm::{oneshot, send_one}; + use std::task; #[test] fn test_from_value() { diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index fa064e6330e7..21fe676ef792 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -81,14 +81,13 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::cmp::Eq; -use core::result::{Err, Ok}; -use core::result; -use core::option::{Some, None}; -use core::str; -use core::vec; +use std::cmp::Eq; +use std::result::{Err, Ok}; +use std::result; +use std::option::{Some, None}; +use std::str; +use std::vec; #[deriving(Eq)] pub enum Name { @@ -466,8 +465,8 @@ pub mod groups { use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req}; use getopts::{Short, Yes}; - use core::str; - use core::vec; + use std::str; + use std::vec; /** one group of options, e.g., both -h and --help, along with * their shared description and properties @@ -681,8 +680,8 @@ mod tests { use getopts::groups::OptGroup; use getopts::*; - use core::result::{Err, Ok}; - use core::result; + use std::result::{Err, Ok}; + use std::result; fn check_fail_type(f: Fail_, ft: FailType) { match f { diff --git a/src/libextra/io_util.rs b/src/libextra/io_util.rs index 11dea1c3a708..afefca8ae65b 100644 --- a/src/libextra/io_util.rs +++ b/src/libextra/io_util.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::io::{Reader, BytesReader}; -use core::io; -use core::cast; +use std::io::{Reader, BytesReader}; +use std::io; +use std::cast; /// An implementation of the io::Reader interface which reads a buffer of bytes pub struct BufReader { @@ -31,7 +31,7 @@ impl BufReader { fn as_bytes_reader(&self, f: &fn(&BytesReader) -> A) -> A { // XXX FIXME(#5723) - let bytes = ::core::util::id::<&[u8]>(self.buf); + let bytes = ::std::util::id::<&[u8]>(self.buf); let bytes: &'static [u8] = unsafe { cast::transmute(bytes) }; // Recreating the BytesReader state every call since // I can't get the borrowing to work correctly diff --git a/src/libextra/json.rs b/src/libextra/json.rs index a71be18174ab..758815442466 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -16,16 +16,15 @@ //! json serialization -use core::prelude::*; -use core::char; -use core::float; -use core::hashmap::HashMap; -use core::io::{WriterUtil, ReaderUtil}; -use core::io; -use core::str; -use core::to_str; -use core::vec; +use std::char; +use std::float; +use std::hashmap::HashMap; +use std::io::{WriterUtil, ReaderUtil}; +use std::io; +use std::str; +use std::to_str; +use std::vec; use serialize::Encodable; use serialize; @@ -1356,13 +1355,12 @@ impl to_str::ToStr for Error { #[cfg(test)] mod tests { - use core::prelude::*; use super::*; - use core::hashmap::HashMap; - use core::io; - use core::result; + use std::hashmap::HashMap; + use std::io; + use std::result; use std::serialize::Decodable; diff --git a/src/libextra/list.rs b/src/libextra/list.rs index 34c35e0d7fde..86b01cf157d8 100644 --- a/src/libextra/list.rs +++ b/src/libextra/list.rs @@ -10,7 +10,6 @@ //! A standard, garbage-collected linked list. -use core::prelude::*; #[deriving(Eq)] @@ -181,7 +180,7 @@ mod tests { use list::*; use list; - use core::option; + use std::option; #[test] fn test_is_empty() { diff --git a/src/libextra/md4.rs b/src/libextra/md4.rs index 3be7394b46d0..6b08fea580f9 100644 --- a/src/libextra/md4.rs +++ b/src/libextra/md4.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::uint; -use core::vec; +use std::uint; +use std::vec; struct Quad { a: u32, diff --git a/src/libextra/net_ip.rs b/src/libextra/net_ip.rs index fc3c765999bc..d18aac684813 100644 --- a/src/libextra/net_ip.rs +++ b/src/libextra/net_ip.rs @@ -12,13 +12,12 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::libc; -use core::comm::{stream, SharedChan}; -use core::ptr; -use core::result; -use core::str; +use std::libc; +use std::comm::{stream, SharedChan}; +use std::ptr; +use std::result; +use std::str; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; @@ -149,16 +148,15 @@ pub fn get_addr(node: &str, iotask: &iotask) } pub mod v4 { - use core::prelude::*; use net::ip::{IpAddr, Ipv4, ParseAddrErr}; use uv::ll; use uv_ip4_addr = uv::ll::ip4_addr; use uv_ip4_name = uv::ll::ip4_name; - use core::cast::transmute; - use core::result; - use core::uint; + use std::cast::transmute; + use std::result; + use std::uint; /** * Convert a str to `ip_addr` @@ -248,13 +246,12 @@ pub mod v4 { } } pub mod v6 { - use core::prelude::*; use net::ip::{IpAddr, Ipv6, ParseAddrErr}; use uv_ip6_addr = uv::ll::ip6_addr; use uv_ip6_name = uv::ll::ip6_name; - use core::result; + use std::result; /** * Convert a str to `ip_addr` @@ -371,7 +368,7 @@ mod test { use net_ip::v6; use uv; - use core::result; + use std::result; #[test] fn test_ip_ipv4_parse_and_format_ip() { diff --git a/src/libextra/net_tcp.rs b/src/libextra/net_tcp.rs index f3f6ffde6603..6a22950ec04b 100644 --- a/src/libextra/net_tcp.rs +++ b/src/libextra/net_tcp.rs @@ -13,7 +13,6 @@ #[allow(missing_doc)]; -use core::prelude::*; use future; use future_spawn = future::spawn; @@ -22,18 +21,18 @@ use uv; use uv::iotask; use uv::iotask::IoTask; -use core::io; -use core::libc::size_t; -use core::libc; -use core::comm::{stream, Port, SharedChan}; -use core::ptr; -use core::result::{Result}; -use core::result; -use core::uint; -use core::vec; +use std::io; +use std::libc::size_t; +use std::libc; +use std::comm::{stream, Port, SharedChan}; +use std::ptr; +use std::result::{Result}; +use std::result; +use std::uint; +use std::vec; pub mod rustrt { - use core::libc; + use std::libc; #[nolink] pub extern { @@ -360,7 +359,7 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) * # Returns * * * A `Result` instance that will either contain a - * `core::comm::Port>` that the user can read + * `std::comm::Port>` that the user can read * (and * optionally, loop on) from until `read_stop` is called, or a * `TcpErrData` record */ @@ -619,7 +618,7 @@ pub fn accept(new_conn: TcpNewConnection) * callback's arguments are: * * `new_conn` - an opaque type that can be passed to * `net::tcp::accept` in order to be converted to a `TcpSocket`. - * * `kill_ch` - channel of type `core::comm::Chan>`. + * * `kill_ch` - channel of type `std::comm::Chan>`. * this channel can be used to send a message to cause `listen` to begin * closing the underlying libuv data structures. * @@ -683,7 +682,7 @@ fn listen_common(host_ip: ip::IpAddr, // will defeat a move sigil, as is done to the host_ip // arg above.. this same pattern works w/o complaint in // tcp::connect (because the iotask::interact cb isn't - // nested within a core::comm::listen block) + // nested within a std::comm::listen block) let loc_ip = copy(host_ip); do iotask::interact(iotask) |loop_ptr| { unsafe { @@ -1429,7 +1428,6 @@ struct TcpBufferedSocketData { #[cfg(test)] mod test { - use core::prelude::*; use net::ip; use net::tcp::{GenericListenErr, TcpConnectErrData, TcpListenErrData}; @@ -1438,12 +1436,12 @@ mod test { use uv::iotask::IoTask; use uv; - use core::cell::Cell; - use core::comm::{stream, SharedChan}; - use core::io; - use core::result; - use core::str; - use core::task; + use std::cell::Cell; + use std::comm::{stream, SharedChan}; + use std::io; + use std::result; + use std::str; + use std::task; // FIXME don't run on fbsd or linux 32 bit (#2064) #[cfg(target_os="win32")] @@ -1745,7 +1743,7 @@ mod test { } pub fn impl_tcp_socket_impl_reader_handles_eof() { - use core::io::{Reader,ReaderUtil}; + use std::io::{Reader,ReaderUtil}; let hl_loop = &uv::global_loop::get(); let server_ip = "127.0.0.1"; diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index a60f51e751e1..9ac58efe7930 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -12,14 +12,13 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::cmp::Eq; -use core::io::{Reader, ReaderUtil}; -use core::io; -use core::hashmap::HashMap; -use core::to_bytes; -use core::uint; +use std::cmp::Eq; +use std::io::{Reader, ReaderUtil}; +use std::io; +use std::hashmap::HashMap; +use std::to_bytes; +use std::uint; #[deriving(Clone, Eq)] struct Url { @@ -803,7 +802,7 @@ mod tests { use net_url::*; - use core::hashmap::HashMap; + use std::hashmap::HashMap; #[test] fn test_url_parse() { diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 002d8a7f9567..fd61c4f6bfc6 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -18,13 +18,12 @@ A BigInt is a combination of BigUint and Sign. #[allow(missing_doc)]; -use core::prelude::*; -use core::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; -use core::int; -use core::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable}; -use core::str; -use core::uint; -use core::vec; +use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; +use std::int; +use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable}; +use std::str; +use std::uint; +use std::vec; /** A BigDigit is a BigUint's composing element. @@ -1148,16 +1147,15 @@ impl BigInt { #[cfg(test)] mod biguint_tests { - use core::prelude::*; use super::*; - use core::cmp::{Less, Equal, Greater}; - use core::int; - use core::num::{IntConvertible, Zero, One, FromStrRadix}; - use core::str; - use core::uint; - use core::vec; + use std::cmp::{Less, Equal, Greater}; + use std::int; + use std::num::{IntConvertible, Zero, One, FromStrRadix}; + use std::str; + use std::uint; + use std::vec; #[test] fn test_from_slice() { @@ -1623,15 +1621,14 @@ mod biguint_tests { #[cfg(test)] mod bigint_tests { - use core::prelude::*; use super::*; - use core::cmp::{Less, Equal, Greater}; - use core::int; - use core::num::{IntConvertible, Zero, One, FromStrRadix}; - use core::uint; - use core::vec; + use std::cmp::{Less, Equal, Greater}; + use std::int; + use std::num::{IntConvertible, Zero, One, FromStrRadix}; + use std::uint; + use std::vec; #[test] fn test_from_biguint() { diff --git a/src/libextra/num/complex.rs b/src/libextra/num/complex.rs index 3a63549cf3ac..915523443fbc 100644 --- a/src/libextra/num/complex.rs +++ b/src/libextra/num/complex.rs @@ -11,9 +11,8 @@ //! Complex numbers. -use core::prelude::*; -use core::num::{Zero,One,ToStrRadix}; +use std::num::{Zero,One,ToStrRadix}; // FIXME #1284: handle complex NaN & infinity etc. This // probably doesn't map to C's _Complex correctly. @@ -193,7 +192,7 @@ impl ToStrRadix for Cmplx { #[cfg(test)] mod test { use super::*; - use core::num::{Zero,One,Real}; + use std::num::{Zero,One,Real}; pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f }; pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f }; @@ -287,7 +286,7 @@ mod test { mod arith { use super::*; - use core::num::Zero; + use std::num::Zero; #[test] fn test_add() { diff --git a/src/libextra/num/rational.rs b/src/libextra/num/rational.rs index 339d35e25936..6733599d1ea2 100644 --- a/src/libextra/num/rational.rs +++ b/src/libextra/num/rational.rs @@ -10,11 +10,10 @@ //! Rational numbers -use core::prelude::*; -use core::cmp; -use core::from_str::FromStr; -use core::num::{Zero,One,ToStrRadix,FromStrRadix,Round}; +use std::cmp; +use std::from_str::FromStr; +use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round}; use super::bigint::BigInt; /// Represents the ratio between 2 numbers. @@ -277,11 +276,10 @@ impl #[cfg(test)] mod test { - use core::prelude::*; use super::*; - use core::num::{Zero,One,FromStrRadix,IntConvertible}; - use core::from_str::FromStr; + use std::num::{Zero,One,FromStrRadix,IntConvertible}; + use std::from_str::FromStr; pub static _0 : Rational = Ratio { numer: 0, denom: 1}; pub static _1 : Rational = Ratio { numer: 1, denom: 1}; diff --git a/src/libextra/par.rs b/src/libextra/par.rs index a3014cf8894b..665633eedf85 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -8,13 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::cast; -use core::ptr; -use core::sys; -use core::uint; -use core::vec; +use std::cast; +use std::ptr; +use std::sys; +use std::uint; +use std::vec; use future_spawn = future::spawn; /** diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index fbb4be0febb3..4c1163f3d50c 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -12,11 +12,10 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::unstable::intrinsics::{move_val_init, init}; -use core::util::{replace, swap}; -use core::vec; +use std::unstable::intrinsics::{move_val_init, init}; +use std::util::{replace, swap}; +use std::vec; /// A priority queue implemented with a binary heap pub struct PriorityQueue { diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 613c0b1ae417..86080b343c78 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -21,13 +21,12 @@ cycle cannot be created with `Rc` because there is no way to modify it after */ -use core::prelude::*; -use core::cast; -use core::libc::{c_void, size_t, malloc, free}; -use core::ptr; -use core::sys; -use core::unstable::intrinsics; +use std::cast; +use std::libc::{c_void, size_t, malloc, free}; +use std::ptr; +use std::sys; +use std::unstable::intrinsics; struct RcBox { value: T, @@ -104,7 +103,7 @@ impl DeepClone for Rc { #[cfg(test)] mod test_rc { use super::*; - use core::cell::Cell; + use std::cell::Cell; #[test] fn test_clone() { diff --git a/src/libextra/rl.rs b/src/libextra/rl.rs index 040adcc443d9..693e3ecb53fb 100644 --- a/src/libextra/rl.rs +++ b/src/libextra/rl.rs @@ -11,14 +11,13 @@ // FIXME #3921. This is unsafe because linenoise uses global mutable // state without mutexes. -use core::prelude::*; -use core::libc::{c_char, c_int}; -use core::local_data; -use core::str; +use std::libc::{c_char, c_int}; +use std::local_data; +use std::str; pub mod rustrt { - use core::libc::{c_char, c_int}; + use std::libc::{c_char, c_int}; pub extern { pub unsafe fn linenoise(prompt: *c_char) -> *c_char; diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index 71393ff9fae2..8374c1a86e31 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -35,11 +35,10 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::uint; -use core::vec; -use core::str; +use std::uint; +use std::vec; +use std::str; /// The type of ropes. pub type Rope = node::Root; @@ -447,7 +446,6 @@ pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{ pub mod iterator { pub mod leaf { - use core::prelude::*; use rope::{Rope, node}; @@ -462,7 +460,6 @@ pub mod iterator { } } pub mod char { - use core::prelude::*; use rope::{Rope, node}; @@ -558,13 +555,12 @@ pub fn char_at(rope: Rope, pos: uint) -> char { Section: Implementation */ pub mod node { - use core::prelude::*; use rope::node; - use core::cast; - use core::uint; - use core::vec; + use std::cast; + use std::uint; + use std::vec; /// Implementation of type `rope` pub enum Root { @@ -1141,11 +1137,10 @@ pub mod node { } pub mod leaf_iterator { - use core::prelude::*; use rope::node::{Concat, Leaf, Node, height}; - use core::vec; + use std::vec; pub struct T { stack: ~[@Node], @@ -1184,7 +1179,6 @@ pub mod node { } pub mod char_iterator { - use core::prelude::*; use rope::node::{Leaf, Node}; use rope::node::leaf_iterator; @@ -1267,12 +1261,11 @@ pub mod node { #[cfg(test)] mod tests { - use core::prelude::*; use rope::*; - use core::uint; - use core::vec; + use std::uint; + use std::vec; //Utility function, used for sanity check fn rope_to_string(r: Rope) -> ~str { diff --git a/src/libextra/semver.rs b/src/libextra/semver.rs index cb372dd920da..6361de127193 100644 --- a/src/libextra/semver.rs +++ b/src/libextra/semver.rs @@ -12,15 +12,14 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::char; -use core::cmp; -use core::io::{ReaderUtil}; -use core::io; -use core::option::{Option, Some, None}; -use core::to_str::ToStr; -use core::uint; +use std::char; +use std::cmp; +use std::io::{ReaderUtil}; +use std::io; +use std::option::{Option, Some, None}; +use std::to_str::ToStr; +use std::uint; #[deriving(Eq)] pub enum Identifier { diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 3d35d1332b2f..66b178f49f7f 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -17,13 +17,12 @@ Core encoding and decoding interfaces. #[allow(missing_doc)]; #[forbid(non_camel_case_types)]; -use core::prelude::*; -use core::at_vec; -use core::hashmap::{HashMap, HashSet}; -use core::trie::{TrieMap, TrieSet}; -use core::uint; -use core::vec; +use std::at_vec; +use std::hashmap::{HashMap, HashSet}; +use std::trie::{TrieMap, TrieSet}; +use std::uint; +use std::vec; use deque::Deque; use dlist::DList; use treemap::{TreeMap, TreeSet}; diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 1d163922955d..e32c688da379 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -15,13 +15,12 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::cmp; -use core::container::{Container, Mutable, Map, Set}; -use core::uint; -use core::util::replace; -use core::vec; +use std::cmp; +use std::container::{Container, Mutable, Map, Set}; +use std::uint; +use std::util::replace; +use std::vec; #[allow(missing_doc)] pub struct SmallIntMap { @@ -287,7 +286,6 @@ impl SmallIntSet { #[cfg(test)] mod tests { - use core::prelude::*; use super::SmallIntMap; @@ -382,11 +380,10 @@ mod tests { #[cfg(test)] mod test_set { - use core::prelude::*; use super::SmallIntSet; - use core::vec; + use std::vec; #[test] fn test_disjoint() { diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 10dbe2326d76..36c12f314b70 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -10,12 +10,11 @@ //! Sorting methods -use core::prelude::*; -use core::cmp::{Eq, Ord}; -use core::uint; -use core::util::swap; -use core::vec; +use std::cmp::{Eq, Ord}; +use std::uint; +use std::util::swap; +use std::vec; type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool; @@ -791,12 +790,11 @@ mod test_qsort3 { #[cfg(test)] mod test_qsort { - use core::prelude::*; use sort::*; - use core::int; - use core::vec; + use std::int; + use std::vec; fn check_sort(v1: &mut [int], v2: &mut [int]) { let len = v1.len(); @@ -857,7 +855,6 @@ mod test_qsort { #[cfg(test)] mod tests { - use core::prelude::*; use sort::*; @@ -924,12 +921,11 @@ mod tests { #[cfg(test)] mod test_tim_sort { - use core::prelude::*; use sort::tim_sort; - use core::rand::RngUtil; - use core::rand; - use core::vec; + use std::rand::RngUtil; + use std::rand; + use std::vec; struct CVal { val: float, @@ -1019,15 +1015,14 @@ mod test_tim_sort { #[cfg(test)] mod big_tests { - use core::prelude::*; use sort::*; - use core::local_data; - use core::rand::RngUtil; - use core::rand; - use core::uint; - use core::vec; + use std::local_data; + use std::rand::RngUtil; + use std::rand; + use std::uint; + use std::vec; #[test] fn test_unique() { diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index 69f75037c7e4..8351e4db6b8c 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -10,12 +10,11 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::f64; -use core::cmp; -use core::num; -use core::vec; +use std::f64; +use std::cmp; +use std::num; +use std::vec; use sort; // NB: this can probably be rewritten in terms of num::Num diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 9c6be901d980..b9d25451a8a9 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -15,14 +15,13 @@ * in std. */ -use core::prelude::*; -use core::borrow; -use core::comm; -use core::task; -use core::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox}; -use core::unstable::atomics; -use core::util; +use std::borrow; +use std::comm; +use std::task; +use std::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox}; +use std::unstable::atomics; +use std::util; /**************************************************************************** * Internals @@ -803,15 +802,14 @@ impl<'self> RWlockReadMode<'self> { #[cfg(test)] mod tests { - use core::prelude::*; use sync::*; - use core::cast; - use core::cell::Cell; - use core::comm; - use core::result; - use core::task; + use std::cast; + use std::cell::Cell; + use std::comm; + use std::result; + use std::task; /************************************************************************ * Semaphore tests diff --git a/src/libextra/task_pool.rs b/src/libextra/task_pool.rs index 6a715d7b481b..49d5dd938695 100644 --- a/src/libextra/task_pool.rs +++ b/src/libextra/task_pool.rs @@ -13,15 +13,14 @@ /// A task pool abstraction. Useful for achieving predictable CPU /// parallelism. -use core::prelude::*; -use core::comm::Chan; -use core::comm; -use core::task::SchedMode; -use core::task; -use core::vec; +use std::comm::Chan; +use std::comm; +use std::task::SchedMode; +use std::task; +use std::vec; -#[cfg(test)] use core::task::SingleThreaded; +#[cfg(test)] use std::task::SingleThreaded; enum Msg { Execute(~fn(&T)), diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs index 39dcee5eff31..f8948f41101e 100644 --- a/src/libextra/tempfile.rs +++ b/src/libextra/tempfile.rs @@ -10,11 +10,10 @@ //! Temporary files and directories -use core::prelude::*; -use core::os; -use core::rand::RngUtil; -use core::rand; +use std::os; +use std::rand::RngUtil; +use std::rand; /// Attempts to make a temporary directory inside of `tmpdir` whose name will /// have the suffix `suffix`. If no directory can be created, None is returned. @@ -31,11 +30,10 @@ pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { #[cfg(test)] mod tests { - use core::prelude::*; use tempfile::mkdtemp; - use core::os; + use std::os; #[test] fn test_mkdtemp() { @@ -44,12 +42,12 @@ mod tests { assert!(p.to_str().ends_with("foobar")); } - // Ideally these would be in core::os but then core would need + // Ideally these would be in std::os but then core would need // to depend on std #[test] fn recursive_mkdir_rel() { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; - use core::os; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::os; let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel"). expect("recursive_mkdir_rel"); @@ -67,8 +65,8 @@ mod tests { #[test] fn recursive_mkdir_dot() { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; - use core::os; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::os; let dot = Path("."); assert!(os::mkdir_recursive(&dot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); @@ -78,8 +76,8 @@ mod tests { #[test] fn recursive_mkdir_rel_2() { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; - use core::os; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::os; let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2"). expect("recursive_mkdir_rel_2"); @@ -102,8 +100,8 @@ mod tests { // Ideally this would be in core, but needs mkdtemp #[test] pub fn test_rmdir_recursive_ok() { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; - use core::os; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::os; let rwx = (S_IRUSR | S_IWUSR | S_IXUSR) as i32; diff --git a/src/libextra/term.rs b/src/libextra/term.rs index d448a1588a67..e21e5c5fb585 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -12,11 +12,10 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::io; +use std::io; -#[cfg(not(target_os = "win32"))] use core::os; +#[cfg(not(target_os = "win32"))] use std::os; #[cfg(not(target_os = "win32"))] use terminfo::*; #[cfg(not(target_os = "win32"))] use terminfo::searcher::open; #[cfg(not(target_os = "win32"))] use terminfo::parser::compiled::parse; diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs index 5180a71939c3..f3edd81f9acd 100644 --- a/src/libextra/terminfo/parm.rs +++ b/src/libextra/terminfo/parm.rs @@ -10,10 +10,9 @@ //! Parameterized string expansion -use core::prelude::*; -use core::{char, vec, util}; -use core::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common}; -use core::iterator::IteratorUtil; +use std::{char, vec, util}; +use std::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common}; +use std::iterator::IteratorUtil; #[deriving(Eq)] enum States { @@ -549,7 +548,7 @@ priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> { #[cfg(test)] mod test { use super::*; - use core::result::Ok; + use std::result::Ok; #[test] fn test_basic_setabf() { diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 123a388900b8..2f36845d79b7 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -10,11 +10,10 @@ /// ncurses-compatible compiled terminfo format parsing (term(5)) -use core::prelude::*; -use core::{vec, int, str}; -use core::io::Reader; -use core::hashmap::HashMap; +use std::{vec, int, str}; +use std::io::Reader; +use std::hashmap::HashMap; use super::super::TermInfo; // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable. diff --git a/src/libextra/terminfo/searcher.rs b/src/libextra/terminfo/searcher.rs index da12a1c4203f..15aeeb3e6544 100644 --- a/src/libextra/terminfo/searcher.rs +++ b/src/libextra/terminfo/searcher.rs @@ -11,11 +11,10 @@ /// Implement ncurses-compatible database discovery /// Does not support hashed database, only filesystem! -use core::prelude::*; -use core::{os, str}; -use core::os::getenv; -use core::io::{file_reader, Reader}; -use path = core::path::Path; +use std::{os, str}; +use std::os::getenv; +use std::io::{file_reader, Reader}; +use path = std::path::Path; /// Return path to database entry for `term` pub fn get_dbpath_for_term(term: &str) -> Option<~path> { diff --git a/src/libextra/terminfo/terminfo.rs b/src/libextra/terminfo/terminfo.rs index 141a5b6bf7f9..0e0231ad3f44 100644 --- a/src/libextra/terminfo/terminfo.rs +++ b/src/libextra/terminfo/terminfo.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::hashmap::HashMap; +use std::hashmap::HashMap; /// A parsed terminfo entry. pub struct TermInfo { diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 50ca96e6e21d..886bb9293bba 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -15,7 +15,6 @@ // simplest interface possible for representing and running tests // while providing a base that other test frameworks may build off of. -use core::prelude::*; use getopts; use sort; @@ -23,22 +22,22 @@ use stats::Stats; use term; use time::precise_time_ns; -use core::comm::{stream, SharedChan}; -use core::either; -use core::io; -use core::num; -use core::option; -use core::rand::RngUtil; -use core::rand; -use core::result; -use core::task; -use core::to_str::ToStr; -use core::u64; -use core::uint; -use core::vec; +use std::comm::{stream, SharedChan}; +use std::either; +use std::io; +use std::num; +use std::option; +use std::rand::RngUtil; +use std::rand; +use std::result; +use std::task; +use std::to_str::ToStr; +use std::u64; +use std::uint; +use std::vec; pub mod rustrt { - use core::libc::size_t; + use std::libc::size_t; #[abi = "cdecl"] pub extern { @@ -573,7 +572,7 @@ pub fn run_test(force_ignore: bool, fn run_test_inner(desc: TestDesc, monitor_ch: SharedChan, testfn: ~fn()) { - let testfn_cell = ::core::cell::Cell::new(testfn); + let testfn_cell = ::std::cell::Cell::new(testfn); do task::spawn { let mut result_future = None; // task::future_result(builder); @@ -781,10 +780,10 @@ mod tests { StaticTestName, DynTestName, DynTestFn}; use test::{TestOpts, run_test}; - use core::either; - use core::comm::{stream, SharedChan}; - use core::option; - use core::vec; + use std::either; + use std::comm::{stream, SharedChan}; + use std::option; + use std::vec; #[test] pub fn do_not_run_ignored_tests() { diff --git a/src/libextra/time.rs b/src/libextra/time.rs index 931a42d3c537..e1f42934b390 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -10,12 +10,11 @@ #[allow(missing_doc)]; -use core::prelude::*; -use core::i32; -use core::int; -use core::io; -use core::str; +use std::i32; +use std::int; +use std::io; +use std::str; static NSEC_PER_SEC: i32 = 1_000_000_000_i32; @@ -862,11 +861,11 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str { mod tests { use time::*; - use core::float; - use core::os; - use core::result; - use core::result::{Err, Ok}; - use core::str; + use std::float; + use std::os; + use std::result; + use std::result::{Err, Ok}; + use std::str; fn test_get_time() { static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z diff --git a/src/libextra/timer.rs b/src/libextra/timer.rs index e23f9113319d..d957ac43801e 100644 --- a/src/libextra/timer.rs +++ b/src/libextra/timer.rs @@ -10,18 +10,17 @@ //! Utilities that leverage libuv's `uv_timer_*` API -use core::prelude::*; use uv; use uv::iotask; use uv::iotask::IoTask; -use core::cast::transmute; -use core::cast; -use core::comm::{stream, Chan, SharedChan, Port, select2i}; -use core::either; -use core::libc::c_void; -use core::libc; +use std::cast::transmute; +use std::cast; +use std::comm::{stream, Chan, SharedChan, Port, select2i}; +use std::either; +use std::libc::c_void; +use std::libc; /** * Wait for timeout period then send provided value over a channel @@ -111,7 +110,7 @@ pub fn sleep(iotask: &IoTask, msecs: uint) { * * * `iotask' - `uv::iotask` that the tcp request will run on * * msecs - an mount of time, in milliseconds, to wait to receive - * * wait_port - a `core::comm::port` to receive on + * * wait_port - a `std::comm::port` to receive on * * # Returns * @@ -176,16 +175,15 @@ extern fn delayed_send_close_cb(handle: *uv::ll::uv_timer_t) { #[cfg(test)] mod test { - use core::prelude::*; use timer::*; use uv; - use core::cell::Cell; - use core::pipes::{stream, SharedChan}; - use core::rand::RngUtil; - use core::rand; - use core::task; + use std::cell::Cell; + use std::pipes::{stream, SharedChan}; + use std::rand::RngUtil; + use std::rand; + use std::task; #[test] fn test_gl_timer_simple_sleep_test() { @@ -223,7 +221,7 @@ mod test { let ch = ch.clone(); let hl_loop_clone = hl_loop.clone(); do task::spawn { - use core::rand::*; + use std::rand::*; let mut rng = rng(); for times.times { sleep(&hl_loop_clone, rng.next() as uint % maxms); diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index d546b48f8175..1a21d549d6c6 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -12,10 +12,9 @@ //! trees. The only requirement for the types is that the key implements //! `TotalOrd`. -use core::prelude::*; -use core::uint; -use core::util::{swap, replace}; +use std::uint; +use std::util::{swap, replace}; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added @@ -689,12 +688,11 @@ fn remove(node: &mut Option<~TreeNode>, #[cfg(test)] mod test_treemap { - use core::prelude::*; use super::*; - use core::rand::RngUtil; - use core::rand; + use std::rand::RngUtil; + use std::rand; #[test] fn find_empty() { @@ -1010,7 +1008,6 @@ mod test_treemap { #[cfg(test)] mod test_set { - use core::prelude::*; use super::*; diff --git a/src/libextra/uv_global_loop.rs b/src/libextra/uv_global_loop.rs index f1dde1b8cb41..5501d73ac868 100644 --- a/src/libextra/uv_global_loop.rs +++ b/src/libextra/uv_global_loop.rs @@ -10,16 +10,15 @@ //! A process-wide libuv event loop for library use. -use core::prelude::*; use iotask = uv_iotask; use uv_iotask::{IoTask, spawn_iotask}; -use core::comm::Chan; -use core::option::{Some, None}; -use core::task::task; -use core::unstable::global::{global_data_clone_create, global_data_clone}; -use core::unstable::weak_task::weaken_task; +use std::comm::Chan; +use std::option::{Some, None}; +use std::task::task; +use std::unstable::global::{global_data_clone_create, global_data_clone}; +use std::unstable::weak_task::weaken_task; /** * Race-free helper to get access to a global task where a libuv @@ -126,11 +125,11 @@ mod test { use uv::ll; use uv_iotask::IoTask; - use core::libc; - use core::task; - use core::cast::transmute; - use core::libc::c_void; - use core::comm::{stream, SharedChan, Chan}; + use std::libc; + use std::task; + use std::cast::transmute; + use std::libc::c_void; + use std::comm::{stream, SharedChan, Chan}; extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) { unsafe { diff --git a/src/libextra/uv_iotask.rs b/src/libextra/uv_iotask.rs index 817dfa28aeed..0a564045d32f 100644 --- a/src/libextra/uv_iotask.rs +++ b/src/libextra/uv_iotask.rs @@ -17,14 +17,13 @@ #[allow(missing_doc)]; -use core::prelude::*; use ll = uv_ll; -use core::comm::{stream, Port, Chan, SharedChan}; -use core::libc::c_void; -use core::libc; -use core::task; +use std::comm::{stream, Port, Chan, SharedChan}; +use std::libc::c_void; +use std::libc; +use std::task; /// Used to abstract-away direct interaction with a libuv loop. pub struct IoTask { @@ -226,7 +225,7 @@ struct AhData { #[cfg(test)] fn impl_uv_iotask_async(iotask: &IoTask) { - use core::ptr; + use std::ptr; let async_handle = ll::async_t(); let ah_ptr: *ll::uv_async_t = &async_handle; diff --git a/src/libextra/uv_ll.rs b/src/libextra/uv_ll.rs index 58b477d4ccf4..db960f334fdc 100644 --- a/src/libextra/uv_ll.rs +++ b/src/libextra/uv_ll.rs @@ -33,14 +33,13 @@ #[allow(non_camel_case_types)]; // C types #[allow(missing_doc)]; -use core::prelude::*; -use core::libc::{c_void, size_t}; -use core::libc; -use core::ptr::to_unsafe_ptr; -use core::ptr; -use core::str; -use core::vec; +use std::libc::{c_void, size_t}; +use std::libc; +use std::ptr::to_unsafe_ptr; +use std::ptr; +use std::str; +use std::vec; pub type uv_handle_t = c_void; pub type uv_loop_t = c_void; @@ -362,7 +361,7 @@ pub struct uv_getaddrinfo_t { pub mod uv_ll_struct_stubgen { - use core::ptr; + use std::ptr; use super::{ uv_async_t, @@ -1228,16 +1227,15 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { #[cfg(test)] mod test { - use core::prelude::*; use super::*; - use core::comm::{SharedChan, stream, GenericChan, GenericPort}; - use core::libc; - use core::str; - use core::sys; - use core::task; - use core::vec; + use std::comm::{SharedChan, stream, GenericChan, GenericPort}; + use std::libc; + use std::str; + use std::sys; + use std::task; + use std::vec; enum tcp_read_data { tcp_read_eof, diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 4d4f3c3a49b0..503bd05b7337 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -10,7 +10,6 @@ #[allow(missing_doc)]; -use core::prelude::*; use digest::DigestUtil; use json; @@ -18,17 +17,17 @@ use sha1::Sha1; use serialize::{Encoder, Encodable, Decoder, Decodable}; use sort; -use core::cell::Cell; -use core::cmp; -use core::comm::{PortOne, oneshot, send_one, recv_one}; -use core::either::{Either, Left, Right}; -use core::hashmap::HashMap; -use core::io; -use core::result; -use core::run; -use core::task; -use core::to_bytes; -use core::util::replace; +use std::cell::Cell; +use std::cmp; +use std::comm::{PortOne, oneshot, send_one, recv_one}; +use std::either::{Either, Left, Right}; +use std::hashmap::HashMap; +use std::io; +use std::result; +use std::run; +use std::task; +use std::to_bytes; +use std::util::replace; /** * @@ -403,7 +402,7 @@ fn unwrap bool { match ot { @@ -537,7 +534,7 @@ pub fn build_link_meta(sess: Session, write_string(symbol_hasher, len_and_str(*dh)); } - // tjc: allocation is unfortunate; need to change core::hash + // tjc: allocation is unfortunate; need to change std::hash return truncated_hash_result(symbol_hasher).to_managed(); } @@ -618,7 +615,7 @@ pub fn symbol_hash(tcx: ty::ctxt, let mut hash = truncated_hash_result(symbol_hasher); // Prefix with _ so that it never blends into adjacent digits hash.unshift_char('_'); - // tjc: allocation is unfortunate; need to change core::hash + // tjc: allocation is unfortunate; need to change std::hash hash.to_managed() } diff --git a/src/librustc/back/passes.rs b/src/librustc/back/passes.rs index d2b4c87c7441..c1192707c1c1 100644 --- a/src/librustc/back/passes.rs +++ b/src/librustc/back/passes.rs @@ -8,9 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::str; -use core::io; +use std::str; +use std::io; use driver::session::{OptLevel, No, Less, Aggressive}; use driver::session::{Session}; diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index dce2b7fe3dfb..ab107a8bf250 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -8,17 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session; use metadata::cstore; use metadata::filesearch; -use core::hashmap::HashSet; -use core::os; -use core::uint; -use core::util; -use core::vec; +use std::hashmap::HashSet; +use std::os; +use std::uint; +use std::util; +use std::vec; fn not_win32(os: session::os) -> bool { os != session::os_win32 @@ -113,7 +112,7 @@ pub fn get_rpath_relative_to_output(os: session::os, output: &Path, lib: &Path) -> Path { - use core::os; + use std::os; assert!(not_win32(os)); @@ -195,8 +194,7 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { #[cfg(unix, test)] mod test { - use core::prelude::*; - use core::os; + use std::os; // FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then // these redundant #[cfg(test)] blocks can be removed diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 18693b52fc87..a32f54fe7bba 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::link; use back::{arm, x86, x86_64, mips}; @@ -24,11 +23,11 @@ use middle; use util::common::time; use util::ppaux; -use core::hashmap::HashMap; -use core::int; -use core::io; -use core::os; -use core::vec; +use std::hashmap::HashMap; +use std::int; +use std::io; +use std::os; +use std::vec; use extra::getopts::groups::{optopt, optmulti, optflag, optflagopt}; use extra::getopts::{opt_present}; use extra::getopts; @@ -951,7 +950,6 @@ pub fn list_metadata(sess: Session, path: &Path, out: @io::Writer) { #[cfg(test)] mod test { - use core::prelude::*; use driver::driver::{build_configuration, build_session}; use driver::driver::{build_session_options, optgroups, str_input}; diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 9459116307d8..ef0b6d646513 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::link; use back::target_strs; @@ -29,7 +28,7 @@ use syntax::abi; use syntax::parse::token; use syntax; -use core::hashmap::HashMap; +use std::hashmap::HashMap; #[deriving(Eq)] pub enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, } diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 43098b98ea3b..7d9fac5c6ae0 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::option; -use core::vec; +use std::option; +use std::vec; use syntax::{ast, fold, attr}; type in_cfg_pred = @fn(attrs: ~[ast::attribute]) -> bool; diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index a86e7c5e39b3..88ed39aae543 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session::Session; -use core::vec; +use std::vec; use syntax::ast; use syntax::attr; use syntax::codemap::dummy_sp; diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 97f1b3997ddc..cfd4df7403f6 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -10,12 +10,11 @@ // Code that generates a test runner to run all the tests in a crate -use core::prelude::*; use driver::session; use front::config; -use core::vec; +use std::vec; use syntax::ast_util::*; use syntax::attr; use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan}; diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 41349d9c085c..8ca8c12f4122 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::hashmap::HashMap; -use core::libc::{c_uint, c_ushort}; -use core::option; -use core::str; +use std::hashmap::HashMap; +use std::libc::{c_uint, c_ushort}; +use std::option; +use std::str; use middle::trans::type_::Type; @@ -268,7 +267,7 @@ pub mod llvm { use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; use super::{ValueRef, PassRef}; use super::debuginfo::*; - use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; + use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; #[link_args = "-Lrustllvm -lrustllvm"] #[link_name = "rustllvm"] diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index e7725436f2b4..ddd07c2cb272 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -7,8 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::cast; +use std::cast; // EBML enum definitions and utils shared by the encoder and decoder diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 5e36b8fddcc7..2a712b075647 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -10,14 +10,13 @@ //! Validates all used crates and extern libraries and loads their metadata -use core::prelude::*; use metadata::cstore; use metadata::decoder; use metadata::filesearch::FileSearch; use metadata::loader; -use core::hashmap::HashMap; +use std::hashmap::HashMap; use syntax::attr; use syntax::codemap::{span, dummy_sp}; use syntax::diagnostic::span_handler; @@ -75,7 +74,7 @@ fn dump_crates(crate_cache: &[cache_entry]) { fn warn_if_multiple_versions(e: @mut Env, diag: @span_handler, crate_cache: &[cache_entry]) { - use core::either::*; + use std::either::*; if crate_cache.len() != 0u { let name = loader::crate_name_from_metas( diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 4ede9f96f1f4..f336b0f4e4c5 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -10,7 +10,6 @@ // Searching for information from the cstore -use core::prelude::*; use metadata::common::*; use metadata::cstore; @@ -18,7 +17,7 @@ use metadata::decoder; use metadata; use middle::{ty, resolve}; -use core::vec; +use std::vec; use reader = extra::ebml::reader; use syntax::ast; use syntax::ast_map; diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index b0a955fef8f7..af5cc9136bdf 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -12,13 +12,12 @@ // The crate store - a central repo for information collected about external // crates and libraries -use core::prelude::*; use metadata::cstore; use metadata::decoder; -use core::hashmap::HashMap; -use core::vec; +use std::hashmap::HashMap; +use std::vec; use extra; use syntax::ast; use syntax::parse::token::ident_interner; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 69faf519bc28..a7a69effe651 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -10,7 +10,6 @@ // Decoding metadata from a single crate's metadata -use core::prelude::*; use metadata::cstore::crate_metadata; use metadata::common::*; @@ -23,13 +22,13 @@ use metadata::tydecode::{parse_ty_data, parse_def_id, parse_bare_fn_ty_data, parse_trait_ref_data}; use middle::{ty, resolve}; -use core::hash::HashUtil; -use core::int; -use core::io::WriterUtil; -use core::io; -use core::option; -use core::str; -use core::vec; +use std::hash::HashUtil; +use std::int; +use std::io::WriterUtil; +use std::io; +use std::option; +use std::str; +use std::vec; use extra::ebml::reader; use extra::ebml; use extra::serialize::Decodable; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index e394c8dcf92f..85fca077d88b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -10,7 +10,6 @@ // Metadata encoding -use core::prelude::*; use metadata::common::*; use metadata::cstore; @@ -21,13 +20,13 @@ use middle::ty; use middle; use util::ppaux::ty_to_str; -use core::hash::HashUtil; -use core::hashmap::{HashMap, HashSet}; -use core::int; -use core::io; -use core::str; -use core::uint; -use core::vec; +use std::hash::HashUtil; +use std::hashmap::{HashMap, HashSet}; +use std::int; +use std::io; +use std::str; +use std::uint; +use std::vec; use extra::flate; use extra::serialize::Encodable; use extra; @@ -46,7 +45,7 @@ use syntax::parse::token; use syntax; use writer = extra::ebml::writer; -use core::cast; +use std::cast; // used by astencode: type abbrev_map = @mut HashMap; diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index abfb5f7d4d4b..28866fd568a7 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::option; -use core::os; -use core::result; -use core::str; +use std::option; +use std::os; +use std::result; +use std::str; // A module for searching for libraries // FIXME (#2658): I'm not happy how this module turned out. Should diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 9e0d6fb8e3a6..31577e472678 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -10,7 +10,6 @@ //! Finds crate binaries and loads their metadata -use core::prelude::*; use lib::llvm::{False, llvm, mk_object_file, mk_section_iter}; use metadata::decoder; @@ -24,14 +23,14 @@ use syntax::parse::token::ident_interner; use syntax::print::pprust; use syntax::{ast, attr}; -use core::cast; -use core::io; -use core::option; -use core::os::consts::{macos, freebsd, linux, android, win32}; -use core::ptr; -use core::str; -use core::uint; -use core::vec; +use std::cast; +use std::io; +use std::option; +use std::os::consts::{macos, freebsd, linux, android, win32}; +use std::ptr; +use std::str; +use std::uint; +use std::vec; use extra::flate; pub enum os { diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 227865810734..c1fbde524c04 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -14,12 +14,11 @@ // tjc note: Would be great to have a `match check` macro equivalent // for some of these -use core::prelude::*; use middle::ty; -use core::str; -use core::uint; +use std::str; +use std::uint; use syntax::abi::AbiSet; use syntax::abi; use syntax::ast; diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index fb72617b743f..1295653f806c 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -10,15 +10,14 @@ // Type encoding -use core::prelude::*; use middle::ty::param_ty; use middle::ty; -use core::hashmap::HashMap; -use core::io::WriterUtil; -use core::io; -use core::uint; +use std::hashmap::HashMap; +use std::io::WriterUtil; +use std::io; +use std::uint; use syntax::abi::AbiSet; use syntax::ast; use syntax::ast::*; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 16e3bd34cdde..c6d7314f1cd9 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use c = metadata::common; use cstore = metadata::cstore; @@ -24,8 +23,8 @@ use middle::{ty, typeck, moves}; use middle; use util::ppaux::ty_to_str; -use core::at_vec; -use core::uint; +use std::at_vec; +use std::uint; use extra::ebml::reader; use extra::ebml; use extra::serialize; @@ -43,7 +42,7 @@ use syntax::parse::token; use syntax; use writer = extra::ebml::writer; -use core::cast; +use std::cast; #[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::print::pprust; @@ -1243,7 +1242,7 @@ fn mk_ctxt() -> @fake_ext_ctxt { #[cfg(test)] fn roundtrip(in_item: Option<@ast::item>) { - use core::io; + use std::io; let in_item = in_item.get(); let bytes = do io::with_bytes_writer |wr| { diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 5730eb0d9bd8..b2e303d40eec 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -17,10 +17,9 @@ // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -use core::prelude::*; -use core::hashmap::HashSet; -use core::uint; +use std::hashmap::HashSet; +use std::uint; use mc = middle::mem_categorization; use middle::borrowck::*; use middle::moves; diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index e950610cce6d..c9ea9e2be66e 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -12,7 +12,6 @@ * Computes moves. */ -use core::prelude::*; use mc = middle::mem_categorization; use middle::borrowck::*; use middle::borrowck::move_data::*; diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index 131ee5aa067b..05fc139305c4 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -11,7 +11,6 @@ //! This module implements the check that the lifetime of a borrow //! does not exceed the lifetime of the value being borrowed. -use core::prelude::*; use middle::borrowck::*; use mc = middle::mem_categorization; diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 9d8fdb062782..26fa4924ccb5 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -16,7 +16,6 @@ // their associated scopes. In phase two, checking loans, we will then make // sure that all of these loans are honored. -use core::prelude::*; use middle::borrowck::*; use middle::borrowck::move_data::MoveData; diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index 5f4251ad0a42..d5377aeb6183 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -10,9 +10,8 @@ //! Computes the restrictions that result from a borrow. -use core::prelude::*; -use core::vec; +use std::vec; use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index f22edd2e1d64..7d667c2043c1 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -10,7 +10,6 @@ /*! See doc.rs for a thorough explanation of the borrow checker */ -use core::prelude::*; use mc = middle::mem_categorization; use middle::ty; @@ -21,10 +20,10 @@ use middle::dataflow::DataFlowOperator; use util::common::stmt_set; use util::ppaux::{note_and_explain_region, Repr, UserString}; -use core::hashmap::{HashSet, HashMap}; -use core::io; -use core::ops::{BitOr, BitAnd}; -use core::result::{Result}; +use std::hashmap::{HashSet, HashMap}; +use std::io; +use std::ops::{BitOr, BitAnd}; +use std::result::{Result}; use syntax::ast; use syntax::ast_map; use syntax::visit; diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 623dbbd61b24..97fd6ca5cc43 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -15,10 +15,9 @@ comments in the section "Moves and initialization" and in `doc.rs`. */ -use core::prelude::*; -use core::hashmap::{HashMap, HashSet}; -use core::uint; +use std::hashmap::{HashMap, HashSet}; +use std::uint; use middle::borrowck::*; use middle::dataflow::DataFlowContext; use middle::dataflow::DataFlowOperator; diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 2c6ba79e96e4..66689944e7ca 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session::Session; use middle::resolve; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index e2ab3247c19c..ec5f5205760f 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::const_eval::{compare_const_vals, lookup_const_by_id}; use middle::const_eval::{eval_const_expr, const_val, const_bool}; @@ -19,8 +18,8 @@ use middle::typeck::method_map; use middle::moves; use util::ppaux::ty_to_str; -use core::uint; -use core::vec; +use std::uint; +use std::vec; use extra::sort; use syntax::ast::*; use syntax::ast_util::{unguarded_pat, walk_pat}; diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index df7de540ea9a..9d94a2de6933 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use metadata::csearch; use middle::astencode; @@ -18,9 +17,9 @@ use middle; use syntax::{ast, ast_map, ast_util, visit}; use syntax::ast::*; -use core::float; -use core::hashmap::{HashMap, HashSet}; -use core::vec; +use std::float; +use std::hashmap::{HashMap, HashSet}; +use std::vec; // // This pass classifies expressions by their constant-ness. diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 93202f3fd558..ac18a9b76cf9 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -16,13 +16,12 @@ * GEN and KILL bits for each expression. */ -use core::prelude::*; -use core::cast; -use core::io; -use core::uint; -use core::vec; -use core::hashmap::HashMap; +use std::cast; +use std::io; +use std::uint; +use std::vec; +use std::hashmap::HashMap; use syntax::ast; use syntax::ast_util; use syntax::ast_util::id_range; diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 904a7ec8c871..9bcfab0773ff 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session; use driver::session::Session; @@ -18,7 +17,7 @@ use syntax::codemap::span; use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item}; use syntax::attr::{attrs_contains_name}; use syntax::ast_map; -use core::util; +use std::util; struct EntryContext { session: Session, diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index c2f663ae23cd..ee7c35fb3d55 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -11,12 +11,11 @@ // A pass that annotates for each loops and functions with the free // variables that they contain. -use core::prelude::*; use middle::resolve; use middle::ty; -use core::hashmap::HashMap; +use std::hashmap::HashMap; use syntax::codemap::span; use syntax::{ast, ast_util, visit}; diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index d4b91ed589d0..a207985e64c8 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::freevars::freevar_entry; use middle::freevars; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 08e55df5b368..1549a6e998c7 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -19,7 +19,6 @@ // // * Functions called by the compiler itself. -use core::prelude::*; use driver::session::Session; use metadata::csearch::each_lang_item; @@ -30,7 +29,7 @@ use syntax::ast_util::local_def; use syntax::visit::{default_simple_visitor, mk_simple_visitor, SimpleVisitor}; use syntax::visit::visit_crate; -use core::hashmap::HashMap; +use std::hashmap::HashMap; pub enum LangItem { FreezeTraitLangItem, // 0 diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index ccbd006edec3..d0fd516778bb 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -8,25 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session; use middle::ty; use middle::pat_util; use util::ppaux::{ty_to_str}; -use core::char; -use core::cmp; -use core::hashmap::HashMap; -use core::i16; -use core::i32; -use core::i64; -use core::i8; -use core::u16; -use core::u32; -use core::u64; -use core::u8; -use core::vec; +use std::char; +use std::cmp; +use std::hashmap::HashMap; +use std::i16; +use std::i32; +use std::i64; +use std::i8; +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; @@ -139,7 +138,7 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ ("ctypes", LintSpec { lint: ctypes, - desc: "proper use of core::libc types in foreign modules", + desc: "proper use of std::libc types in foreign modules", default: warn }), diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 86b8b2943198..1e5e5453ee25 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -102,7 +102,6 @@ * to return explicitly. */ -use core::prelude::*; use middle::lint::{unused_variable, dead_assignment}; use middle::pat_util; @@ -110,12 +109,12 @@ use middle::ty; use middle::typeck; use middle::moves; -use core::cast::transmute; -use core::hashmap::HashMap; -use core::io; -use core::to_str; -use core::uint; -use core::vec; +use std::cast::transmute; +use std::hashmap::HashMap; +use std::io; +use std::to_str; +use std::uint; +use std::vec; use syntax::ast::*; use syntax::codemap::span; use syntax::parse::token::special_idents; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ad5951b39766..fd36858ba688 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -46,14 +46,13 @@ * then an index to jump forward to the relevant item. */ -use core::prelude::*; use middle::ty; use middle::typeck; use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::common::indenter; -use core::uint; +use std::uint; use syntax::ast::{m_imm, m_const, m_mutbl}; use syntax::ast; use syntax::codemap::span; diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index cd9d8738026b..c7d338b1976a 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -126,7 +126,6 @@ and so on. */ -use core::prelude::*; use middle::pat_util::{pat_bindings}; use middle::freevars; @@ -136,8 +135,8 @@ use util::ppaux; use util::ppaux::Repr; use util::common::indenter; -use core::at_vec; -use core::hashmap::{HashSet, HashMap}; +use std::at_vec; +use std::hashmap::{HashSet, HashMap}; use syntax::ast::*; use syntax::ast_util; use syntax::visit; diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 654d77b2a794..f6da8f392cc1 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::resolve; -use core::hashmap::HashMap; +use std::hashmap::HashMap; use syntax::ast::*; use syntax::ast_util::{path_to_ident, walk_pat}; use syntax::codemap::span; diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index c3241dca1b87..5e544dc06e3d 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -11,7 +11,6 @@ // A pass that checks to make sure private fields and methods aren't used // outside their scopes. -use core::prelude::*; use metadata::csearch; use middle::ty::{ty_struct, ty_enum}; @@ -20,7 +19,7 @@ use middle::typeck::{method_map, method_origin, method_param, method_self}; use middle::typeck::{method_super}; use middle::typeck::{method_static, method_trait}; -use core::util::ignore; +use std::util::ignore; use syntax::ast::{decl_item, def, def_fn, def_id, def_static_method}; use syntax::ast::{def_variant, expr_field, expr_method_call, expr_path}; use syntax::ast::{expr_struct, expr_unary, ident, inherited, item_enum}; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 88bd9c1f6f4a..53d0e8d3576a 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -15,14 +15,13 @@ // makes all other generics or inline functions that it references // reachable as well. -use core::prelude::*; -use core::iterator::IteratorUtil; +use std::iterator::IteratorUtil; use middle::resolve; use middle::ty; use middle::typeck; -use core::hashmap::HashSet; +use std::hashmap::HashSet; use syntax::ast::*; use syntax::ast; use syntax::ast_map; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 00a44904fed1..e4e554b65bf3 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,7 +17,6 @@ region parameterized. */ -use core::prelude::*; use driver::session::Session; use metadata::csearch; @@ -26,7 +25,7 @@ use middle::ty::{region_variance, rv_covariant, rv_invariant}; use middle::ty::{rv_contravariant, FreeRegion}; use middle::ty; -use core::hashmap::{HashMap, HashSet}; +use std::hashmap::{HashMap, HashSet}; use syntax::ast_map; use syntax::codemap::span; use syntax::print::pprust; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index b2bfd9d1661b..733ff9c14131 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session::Session; use metadata::csearch::{each_path, get_trait_method_def_ids}; @@ -40,11 +39,11 @@ use syntax::visit::{visit_foreign_item, visit_item}; use syntax::visit::{visit_mod, visit_ty, vt}; use syntax::opt_vec::OptVec; -use core::str; -use core::uint; -use core::vec; -use core::hashmap::{HashMap, HashSet}; -use core::util; +use std::str; +use std::uint; +use std::vec; +use std::hashmap::{HashMap, HashSet}; +use std::util; // Definition mapping pub type DefMap = @mut HashMap; diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index fba174c68405..e5f5315a19c2 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -10,7 +10,6 @@ // Type substitutions. -use core::prelude::*; use middle::ty; use util::ppaux::Repr; diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index c2e9c7b194b2..1d69b20f5c44 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -147,7 +147,6 @@ * */ -use core::prelude::*; use back::abi; use lib::llvm::{llvm, ValueRef, BasicBlockRef}; @@ -172,8 +171,8 @@ use middle::trans::type_of; use middle::ty; use util::common::indenter; -use core::hashmap::HashMap; -use core::vec; +use std::hashmap::HashMap; +use std::vec; use syntax::ast; use syntax::ast::ident; use syntax::ast_util::path_to_ident; @@ -304,7 +303,7 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id) adt::represent_node(bcx, pat_id)) } } - ::core::util::unreachable(); + ::std::util::unreachable(); } ast::def_fn(*) | ast::def_struct(_) => { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 9b7c7037f42a..5417d6f6cc66 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -44,10 +44,10 @@ * taken to it, implementing them for Rust seems difficult. */ -use core::container::Map; -use core::libc::c_ulonglong; -use core::option::{Option, Some, None}; -use core::vec; +use std::container::Map; +use std::libc::c_ulonglong; +use std::option::{Option, Some, None}; +use std::vec; use lib::llvm::{ValueRef, True, IntEQ, IntNE}; use middle::trans::_match; @@ -86,7 +86,7 @@ pub enum Repr { * it represents the other case, which is inhabited by at most one value * (and all other fields are undefined/unused). * - * For example, `core::option::Option` instantiated at a safe pointer type + * For example, `std::option::Option` instantiated at a safe pointer type * is represented such that `None` is a null pointer and `Some` is the * identity function. */ diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index a1d1b737f31f..99d4dbd25446 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -12,7 +12,6 @@ # Translation of inline assembly. */ -use core::prelude::*; use lib; use middle::trans::build::*; @@ -22,7 +21,7 @@ use middle::ty; use middle::trans::type_::Type; -use core::str; +use std::str; use syntax::ast; // Take an inline assembly expression and splat it out via LLVM diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d9fea1213468..b9c7b8ad0ab3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -23,7 +23,6 @@ // but many TypeRefs correspond to one ty::t; for instance, tup(int, int, // int) and rec(x=int, y=int, z=int) will have the same TypeRef. -use core::prelude::*; use back::link::{mangle_exported_name}; use back::{link, abi}; @@ -63,15 +62,15 @@ use util::ppaux::{Repr, ty_to_str}; use middle::trans::type_::Type; -use core::hash; -use core::hashmap::{HashMap, HashSet}; -use core::int; -use core::io; -use core::libc::c_uint; -use core::str; -use core::uint; -use core::vec; -use core::local_data; +use std::hash; +use std::hashmap::{HashMap, HashSet}; +use std::int; +use std::io; +use std::libc::c_uint; +use std::str; +use std::uint; +use std::vec; +use std::local_data; use extra::time; use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; @@ -800,10 +799,10 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) if need_invoke(bcx) { unsafe { debug!("invoking %x at %x", - ::core::cast::transmute(llfn), - ::core::cast::transmute(bcx.llbb)); + ::std::cast::transmute(llfn), + ::std::cast::transmute(bcx.llbb)); for llargs.iter().advance |&llarg| { - debug!("arg: %x", ::core::cast::transmute(llarg)); + debug!("arg: %x", ::std::cast::transmute(llarg)); } } let normal_bcx = sub_block(bcx, "normal return"); @@ -816,10 +815,10 @@ pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) } else { unsafe { debug!("calling %x at %x", - ::core::cast::transmute(llfn), - ::core::cast::transmute(bcx.llbb)); + ::std::cast::transmute(llfn), + ::std::cast::transmute(bcx.llbb)); for llargs.iter().advance |&llarg| { - debug!("arg: %x", ::core::cast::transmute(llarg)); + debug!("arg: %x", ::std::cast::transmute(llarg)); } } let llresult = Call(bcx, llfn, llargs); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index dc32a3b4e2c8..46a8cb306f8b 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; @@ -22,11 +21,11 @@ use syntax::codemap::span; use middle::trans::base; use middle::trans::type_::Type; -use core::cast; -use core::libc::{c_uint, c_ulonglong, c_char}; -use core::hashmap::HashMap; -use core::str; -use core::vec; +use std::cast; +use std::libc::{c_uint, c_ulonglong, c_char}; +use std::hashmap::HashMap; +use std::str; +use std::vec; pub fn terminate(cx: block, _: &str) { cx.terminated = true; diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 4526af2da0f4..4cbc9cd417f2 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -15,9 +15,9 @@ use middle::trans::common::*; use middle::trans::type_::Type; -use core::libc::c_uint; -use core::option; -use core::vec; +use std::libc::c_uint; +use std::option; +use std::vec; pub trait ABIInfo { fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType; diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 45fdda1990cc..7eac2df10b6c 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -14,8 +14,8 @@ use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; use middle::trans::type_::Type; -use core::option::{Option, None, Some}; -use core::uint; +use std::option::{Option, None, Some}; +use std::uint; fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 47f2fb8634c1..c95ae994cebe 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::libc::c_uint; -use core::uint; -use core::vec; +use std::libc::c_uint; +use std::uint; +use std::vec; use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::{Attribute, StructRetAttribute}; use middle::trans::context::task_llcx; diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 8131fd009eed..8c5a2e70484b 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session::{os_win32, os_macos}; use lib::llvm::*; diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 6c264e637a60..f1da63e1f173 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -18,10 +18,10 @@ use middle::trans::cabi::*; use middle::trans::type_::Type; -use core::option; -use core::option::Option; -use core::uint; -use core::vec; +use std::option; +use std::option::Option; +use std::uint; +use std::vec; #[deriving(Eq)] enum RegClass { diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 4c07f88f16eb..8f9451510afa 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -16,9 +16,6 @@ // and methods are represented as just a fn ptr and not a full // closure. -use core::prelude::*; -use core::vec; - use back::abi; use driver::session; use lib; diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index ad68ffb402e1..09b515f1918d 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::abi; use back::link::{mangle_internal_name_by_path_and_seq}; @@ -28,8 +27,8 @@ use util::ppaux::ty_to_str; use middle::trans::type_::Type; -use core::str; -use core::vec; +use std::str; +use std::vec; use syntax::ast; use syntax::ast_map::path_name; use syntax::ast_util; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b255f2ca78c7..fee44af5cc75 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -10,7 +10,6 @@ //! Code that is useful in various trans modules. -use core::prelude::*; use driver::session; use driver::session::Session; @@ -31,14 +30,14 @@ use util::ppaux::{Repr}; use middle::trans::type_::Type; -use core::cast::transmute; -use core::cast; -use core::hashmap::{HashMap}; -use core::libc::{c_uint, c_longlong, c_ulonglong}; -use core::to_bytes; -use core::str; -use core::vec::raw::to_ptr; -use core::vec; +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}; use syntax::codemap::span; diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index d7b6e9cf5a37..97572efedfdb 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::abi; use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True}; @@ -31,8 +30,8 @@ use util::ppaux::{Repr, ty_to_str}; use middle::trans::type_::Type; -use core::libc::c_uint; -use core::str; +use std::libc::c_uint; +use std::str; use syntax::{ast, ast_util, ast_map}; pub fn const_lit(cx: &mut CrateContext, e: &ast::expr, lit: ast::lit) diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 9b81fc406b7c..c2a32ae041e4 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::{upcall}; use driver::session; @@ -26,10 +25,10 @@ use middle::ty; use middle::trans::type_::Type; -use core::hash; -use core::hashmap::{HashMap, HashSet}; -use core::str; -use core::local_data; +use std::hash; +use std::hashmap::{HashMap, HashSet}; +use std::str; +use std::local_data; use extra::time; use syntax::ast; diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 862f455aeb6b..dc88ecbe936b 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::link; use lib; @@ -26,8 +25,8 @@ use util::ppaux; use middle::trans::type_::Type; -use core::str; -use core::vec; +use std::str; +use std::vec; use syntax::ast; use syntax::ast::ident; use syntax::ast_map::path_mod; diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index de56d9a05f15..0fe3dfe80c8c 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -87,7 +87,6 @@ * methods themselves. Most are only suitable for some types of * values. */ -use core::prelude::*; use lib; use lib::llvm::ValueRef; @@ -105,7 +104,7 @@ use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; -use core::uint; +use std::uint; use syntax::ast; use syntax::codemap::span; use syntax::parse::token::special_idents; diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 22448f577a35..ac5eb6b067c9 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -41,7 +41,6 @@ This file consists of three conceptual sections: */ -use core::prelude::*; use driver::session; use lib::llvm::llvm; @@ -54,14 +53,14 @@ use middle::trans; use middle::ty; use util::ppaux::ty_to_str; -use core::hashmap::HashMap; -use core::libc; -use core::libc::{c_uint, c_ulonglong}; -use core::cmp; -use core::ptr; -use core::str::as_c_str; -use core::sys; -use core::vec; +use std::hashmap::HashMap; +use std::libc; +use std::libc::{c_uint, c_ulonglong}; +use std::cmp; +use std::ptr; +use std::str::as_c_str; +use std::sys; +use std::vec; use syntax::codemap::span; use syntax::{ast, codemap, ast_util, ast_map}; use syntax::parse::token; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 353227307560..5a7e21d1fccb 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -119,7 +119,6 @@ lvalues are *never* stored by value. */ -use core::prelude::*; use back::abi; use lib::llvm::{ValueRef, llvm}; @@ -154,9 +153,9 @@ use util::ppaux::Repr; use middle::trans::type_::Type; -use core::cast::transmute; -use core::hashmap::HashMap; -use core::vec; +use std::cast::transmute; +use std::hashmap::HashMap; +use std::vec; use syntax::print::pprust::{expr_to_str}; use syntax::ast; use syntax::codemap; diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7672f3b615d0..bea702f938d9 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::{link, abi}; use lib::llvm::{ValueRef}; @@ -33,8 +32,8 @@ use middle::ty; use middle::ty::FnSig; use util::ppaux::ty_to_str; -use core::uint; -use core::vec; +use std::uint; +use std::vec; use syntax::codemap::span; use syntax::{ast, ast_util}; use syntax::{attr, ast_map}; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0172b7054659..7282e48f13d5 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -12,7 +12,6 @@ // // Code relating to taking, dropping, etc as well as type descriptors. -use core::prelude::*; use back::abi; use back::link::*; @@ -37,9 +36,9 @@ use util::ppaux::ty_to_short_str; use middle::trans::type_::Type; -use core::io; -use core::libc::c_uint; -use core::str; +use std::io; +use std::libc::c_uint; +use std::str; use extra::time; use syntax::ast; diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 11c02f165b6f..692987eedeb5 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use metadata::csearch; use middle::astencode; @@ -18,7 +17,7 @@ use middle::trans::common::*; use middle::ty; use util::ppaux::ty_to_str; -use core::vec; +use std::vec; use syntax::ast; use syntax::ast_map::path_name; use syntax::ast_util::local_def; diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 0b051662781e..02488084ea89 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::abi; use lib::llvm::llvm; @@ -32,7 +31,7 @@ use util::ppaux::Repr; use middle::trans::type_::Type; -use core::vec; +use std::vec; use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_util; use syntax::{ast, ast_map}; diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 92d8192aee62..4ae8554d7143 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use back::link::mangle_exported_name; use driver::session; @@ -31,7 +30,7 @@ use middle::ty::{FnSig}; use middle::typeck; use util::ppaux::{Repr,ty_to_str}; -use core::vec; +use std::vec; use syntax::ast; use syntax::ast_map; use syntax::ast_map::path_name; diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 16695ad59a07..9e227da49f83 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -25,9 +25,9 @@ use middle::trans::type_of::*; use middle::ty; use util::ppaux::ty_to_str; -use core::libc::c_uint; -use core::option::None; -use core::vec; +use std::libc::c_uint; +use std::option::None; +use std::vec; use syntax::ast::def_id; use syntax::ast; use syntax::ast_map::path_name; diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 1344bed96eec..4a9869ca0072 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -29,7 +29,7 @@ use util::ppaux::ty_to_str; use middle::trans::type_::Type; -use core::option::None; +use std::option::None; use syntax::ast; use syntax::codemap; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 64688ac41342..e52d33fc6e9a 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; @@ -21,10 +20,10 @@ use middle::trans::base; use syntax::ast; use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; -use core::vec; -use core::cast; +use std::vec; +use std::cast; -use core::libc::{c_uint}; +use std::libc::{c_uint}; #[deriving(Eq)] pub struct Type { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 3699314a1d2c..481f08ee192d 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::trans::adt; use middle::trans::common::*; diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index c636b7f48761..7ae1ba11142e 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -33,9 +33,9 @@ use middle::trans::inline; use middle::ty; use middle::typeck; -use core::option::{Some, None}; -use core::uint; -use core::vec; +use std::option::{Some, None}; +use std::uint; +use std::vec; use extra::list::{List, Cons, Nil}; use extra::list; use syntax::ast; diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index eb5376da6969..068ce4e2b33b 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -14,7 +14,6 @@ //! and for each in debugging (e.g., so you can use //! `RUST_LOG=rustc::middle::trans::write_guard`). -use core::prelude::*; use lib::llvm::ValueRef; use middle::borrowck::{RootInfo, root_map_key, DynaImm, DynaMut}; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b8ee1eee26e1..c34046179c4d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use driver::session; use metadata::csearch; @@ -27,16 +26,16 @@ use util::ppaux::{Repr, UserString}; use util::common::{indenter}; use util::enum_set::{EnumSet, CLike}; -use core::cast; -use core::cmp; -use core::hashmap::{HashMap, HashSet}; -use core::iter; -use core::ops; -use core::ptr::to_unsafe_ptr; -use core::to_bytes; -use core::u32; -use core::uint; -use core::vec; +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; +use std::u32; +use std::uint; +use std::vec; use syntax::ast::*; use syntax::ast_util::is_local; use syntax::ast_util; diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 07fb23fea48a..7c1ff259acc3 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -52,7 +52,6 @@ * an rptr (`&r.T`) use the region `r` that appears in the rptr. */ -use core::prelude::*; use middle::const_eval; use middle::ty::{substs}; @@ -63,8 +62,8 @@ use middle::typeck::rscope::{region_scope, RegionError}; use middle::typeck::rscope::RegionParamNames; use middle::typeck::lookup_def_tcx; -use core::result; -use core::vec; +use std::result; +use std::vec; use syntax::abi::AbiSet; use syntax::{ast, ast_util}; use syntax::codemap::span; diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 58a527f35018..c2bf4594d30e 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding, pat_is_const}; use middle::ty; @@ -18,7 +17,7 @@ use middle::typeck::check::{instantiate_path, lookup_def}; use middle::typeck::check::{structure_of, valid_range_bounds}; use middle::typeck::require_same_types; -use core::hashmap::{HashMap, HashSet}; +use std::hashmap::{HashMap, HashSet}; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs index 3fa551e4b057..7ca78068f070 100644 --- a/src/librustc/middle/typeck/check/demand.rs +++ b/src/librustc/middle/typeck/check/demand.rs @@ -13,8 +13,8 @@ use middle::ty; use middle::typeck::check::FnCtxt; use middle::typeck::infer; -use core::result::{Err, Ok}; -use core::result; +use std::result::{Err, Ok}; +use std::result; use syntax::ast; use syntax::codemap::span; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 4bebca3c9a8b..bb7bff920aa3 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -79,7 +79,6 @@ obtained the type `Foo`, we would never match this method. */ -use core::prelude::*; use middle::resolve; use middle::ty::*; @@ -95,10 +94,10 @@ use middle::typeck::{method_self, method_static, method_trait, method_super}; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; use util::common::indenter; -use core::hashmap::HashSet; -use core::result; -use core::uint; -use core::vec; +use std::hashmap::HashSet; +use std::result; +use std::uint; +use std::vec; use extra::list::Nil; use syntax::ast::{def_id, sty_value, sty_region, sty_box}; use syntax::ast::{sty_uniq, sty_static, node_id}; diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 23266767124c..bfd9e71eea08 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -76,7 +76,6 @@ type parameter). */ -use core::prelude::*; use middle::const_eval; use middle::pat_util::pat_id_map; @@ -111,11 +110,11 @@ use util::ppaux::{bound_region_ptr_to_str}; use util::ppaux; -use core::cast::transmute; -use core::hashmap::HashMap; -use core::result; -use core::util::replace; -use core::vec; +use std::cast::transmute; +use std::hashmap::HashMap; +use std::result; +use std::util::replace; +use std::vec; use extra::list::Nil; use syntax::abi::AbiSet; use syntax::ast::{provided, required}; diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index df81ebd48aa2..80faad15695c 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -27,7 +27,6 @@ this point a bit better. */ -use core::prelude::*; use middle::freevars::get_freevars; use middle::ty::{re_scope}; @@ -39,8 +38,8 @@ use middle::typeck::infer::resolve_type; use util::ppaux::{note_and_explain_region, ty_to_str, region_to_str}; use middle::pat_util; -use core::result; -use core::uint; +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}; use syntax::ast; @@ -788,7 +787,6 @@ pub mod guarantor { * but more special purpose. */ - use core::prelude::*; use middle::typeck::check::regionck::{Rcx, infallibly_mk_subr}; use middle::typeck::check::regionck::mk_subregion_due_to_derefence; @@ -797,7 +795,7 @@ pub mod guarantor { use syntax::codemap::span; use util::ppaux::{ty_to_str}; - use core::uint; + use std::uint; pub fn for_addr_of(rcx: @mut Rcx, expr: @ast::expr, base: @ast::expr) { /*! diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index fb79a7c3c994..02c003b7525e 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -10,7 +10,6 @@ // #[warn(deprecated_mode)]; -use core::prelude::*; use middle::ty; diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 0bf20f9fbcb9..bbd9c1f765bf 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty::param_ty; use middle::ty; @@ -24,8 +23,8 @@ use util::common::indenter; use util::ppaux::tys_to_str; use util::ppaux; -use core::hashmap::HashSet; -use core::result; +use std::hashmap::HashSet; +use std::result; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index e2efdc51fcad..e5248e01ed79 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -12,7 +12,6 @@ // unresolved type variables and replaces "ty_var" types with their // substitutions. -use core::prelude::*; use middle::pat_util; use middle::ty; diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index a537d0cc72c5..3483245706f3 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -14,7 +14,6 @@ // has at most one implementation for each type. Then we build a mapping from // each trait in the system to its implementations. -use core::prelude::*; use metadata::csearch::{each_path, get_impl_trait}; use metadata::csearch; @@ -52,10 +51,10 @@ use syntax::visit::{Visitor, SimpleVisitor}; use syntax::visit::{visit_mod}; use util::ppaux::ty_to_str; -use core::hashmap::{HashMap, HashSet}; -use core::result::Ok; -use core::uint; -use core::vec; +use std::hashmap::{HashMap, HashSet}; +use std::result::Ok; +use std::uint; +use std::vec; pub struct UniversalQuantificationResult { monotype: t, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 5065a475a405..3a4fa82906d1 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -30,7 +30,6 @@ are represented as `ty_param()` instances. */ -use core::prelude::*; use metadata::csearch; use middle::ty::{substs, ty_param_bounds_and_ty}; @@ -47,8 +46,8 @@ use util::common::pluralize; use util::ppaux; use util::ppaux::UserString; -use core::result; -use core::vec; +use std::result; +use std::vec; use syntax::abi::AbiSet; use syntax::ast::{RegionTyParamBound, TraitTyParamBound}; use syntax::ast; diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 18940bb89e14..63f882f5e541 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -64,7 +64,6 @@ we may want to adjust precisely when coercions occur. */ -use core::prelude::*; use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn}; use middle::ty::{AutoDerefRef}; diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 7a4ea0999efa..f80f022b5439 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -54,7 +54,6 @@ // terms of error reporting, although we do not do that properly right // now. -use core::prelude::*; use middle::ty::{FloatVar, FnSig, IntVar, TyVar}; use middle::ty::{IntType, UintType, substs}; @@ -68,8 +67,8 @@ use middle::typeck::infer::unify::{InferCtxtMethods, UnifyInferCtxtMethods}; use middle::typeck::infer::{InferCtxt, cres, ures}; use util::common::indent; -use core::result::{iter_vec2, map_vec2}; -use core::vec; +use std::result::{iter_vec2, map_vec2}; +use std::vec; use syntax::ast::{Onceness, purity}; use syntax::ast; use syntax::opt_vec; diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 47fb28f84845..0dd45919be14 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty::{BuiltinBounds}; use middle::ty::RegionVid; diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index ed19310d5d69..73e43c6c0762 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -32,7 +32,6 @@ * a lattice. */ -use core::prelude::*; use middle::ty::{RegionVid, TyVar, Vid}; use middle::ty; diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index c77bef835e4f..ad063be86146 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty::{BuiltinBounds}; use middle::ty::RegionVid; diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 3e2d4a71dfbe..28d943b58079 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -242,7 +242,6 @@ section on "Type Combining" below for details. */ -use core::prelude::*; pub use middle::ty::IntVarValue; pub use middle::typeck::infer::resolve::resolve_and_force_all_but_regions; @@ -267,8 +266,8 @@ use middle::typeck::isr_alist; use util::common::indent; use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str}; -use core::result; -use core::vec; +use std::result; +use std::vec; use extra::list::Nil; use extra::smallintmap::SmallIntMap; use syntax::ast::{m_imm, m_mutbl}; diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 4380711b78e8..bad4cb2fe877 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -536,7 +536,6 @@ more convincing in the future. */ -use core::prelude::*; use middle::ty; use middle::ty::{FreeRegion, Region, RegionVid}; @@ -546,10 +545,10 @@ use middle::typeck::infer::cres; use util::common::indenter; use util::ppaux::note_and_explain_region; -use core::cell::Cell; -use core::hashmap::{HashMap, HashSet}; -use core::uint; -use core::vec; +use std::cell::Cell; +use std::hashmap::{HashMap, HashSet}; +use std::uint; +use std::vec; use syntax::codemap::span; use syntax::ast; diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs index 1311907eed2e..2326e2e10efe 100644 --- a/src/librustc/middle/typeck/infer/resolve.rs +++ b/src/librustc/middle/typeck/infer/resolve.rs @@ -46,7 +46,6 @@ // future). If you want to resolve everything but one type, you are // probably better off writing `resolve_all - resolve_ivar`. -use core::prelude::*; use middle::ty::{FloatVar, FloatVid, IntVar, IntVid, RegionVid, TyVar, TyVid}; use middle::ty::{type_is_bot, IntType, UintType}; @@ -58,7 +57,7 @@ use middle::typeck::infer::unify::{Root, UnifyInferCtxtMethods}; use util::common::{indent, indenter}; use util::ppaux::ty_to_str; -use core::vec; +use std::vec; use syntax::ast; pub static resolve_nested_tvar: uint = 0b0000000001; diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index eb912aa2dda4..905e86a73f06 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty::{BuiltinBounds}; use middle::ty; diff --git a/src/librustc/middle/typeck/infer/to_str.rs b/src/librustc/middle/typeck/infer/to_str.rs index 364d8b2d052c..18594f35295a 100644 --- a/src/librustc/middle/typeck/infer/to_str.rs +++ b/src/librustc/middle/typeck/infer/to_str.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty::{FnSig, Vid}; use middle::ty::IntVarValue; @@ -18,7 +17,7 @@ use middle::typeck::infer::InferCtxt; use middle::typeck::infer::unify::{Redirect, Root, VarValue}; use util::ppaux::{mt_to_str, ty_to_str, trait_ref_to_str}; -use core::uint; +use std::uint; use syntax::ast; pub trait InferStr { diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs index a185633a7ac7..a7c3350d1d17 100644 --- a/src/librustc/middle/typeck/infer/unify.rs +++ b/src/librustc/middle/typeck/infer/unify.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use extra::smallintmap::SmallIntMap; diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 98f7af4bfd4d..4eaa0b69d9cc 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -48,7 +48,6 @@ independently: */ -use core::prelude::*; use driver::session; @@ -58,8 +57,8 @@ use util::common::time; use util::ppaux::Repr; use util::ppaux; -use core::hashmap::HashMap; -use core::result; +use std::hashmap::HashMap; +use std::result; use extra::list::List; use extra::list; use syntax::codemap::span; diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index dc9fc264f85d..91c875559fec 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use middle::ty; -use core::result; +use std::result; use syntax::ast; use syntax::codemap::span; use syntax::opt_vec::OptVec; diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 957cf02ed77e..9c0dfb465306 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -21,17 +21,9 @@ #[allow(non_camel_case_types)]; #[deny(deprecated_pattern)]; -#[no_core]; -#[no_std]; - -extern mod core(name = "std"); -extern mod extra(name = "extra"); +extern mod extra; extern mod syntax; -extern mod std(name = "std", vers = "0.7-pre"); - -use core::prelude::*; - use driver::driver::{host_triple, optgroups, early_error}; use driver::driver::{str_input, file_input, build_session_options}; use driver::driver::{build_session, build_configuration, parse_pretty}; @@ -40,13 +32,13 @@ use driver::driver::{compile_input}; use driver::session; use middle::lint; -use core::io; -use core::os; -use core::result; -use core::str; -use core::task; -use core::uint; -use core::vec; +use std::io; +use std::os; +use std::result; +use std::str; +use std::task; +use std::uint; +use std::vec; use extra::getopts::{groups, opt_present}; use extra::getopts; use syntax::codemap; @@ -120,15 +112,17 @@ pub mod lib { // A curious inner module that allows ::std::foo to be available in here for // macros. +/* mod std { - pub use core::cmp; - pub use core::os; - pub use core::str; - pub use core::sys; - pub use core::to_bytes; - pub use core::unstable; + pub use std::cmp; + pub use std::os; + pub use std::str; + pub use std::sys; + pub use std::to_bytes; + pub use std::unstable; pub use extra::serialize; } +*/ pub fn version(argv0: &str) { let mut vers = ~"unknown version"; @@ -193,7 +187,7 @@ pub fn describe_debug_flags() { pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) { // Don't display log spew by default. Can override with RUST_LOG. - ::core::logging::console_off(); + ::std::logging::console_off(); let mut args = /*bad*/copy *args; let binary = args.shift().to_managed(); @@ -305,7 +299,7 @@ fails without recording a fatal error then we've encountered a compiler bug and need to present an error. */ pub fn monitor(f: ~fn(diagnostic::Emitter)) { - use core::comm::*; + use std::comm::*; let (p, ch) = stream(); let ch = SharedChan::new(ch); let ch_capture = ch.clone(); diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 351519975adf..1e2e30548ee9 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -8,14 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use syntax::ast; use syntax::codemap::{span}; use syntax::visit; -use core::hashmap::HashSet; -use core::io; +use std::hashmap::HashSet; +use std::io; use extra; pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { diff --git a/src/librustc/util/enum_set.rs b/src/librustc/util/enum_set.rs index 3528f20cfb3c..2bdb6583b230 100644 --- a/src/librustc/util/enum_set.rs +++ b/src/librustc/util/enum_set.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; #[deriving(Eq, IterBytes)] pub struct EnumSet { @@ -96,10 +95,9 @@ impl BitAnd, EnumSet> for EnumSet { #[cfg(test)] mod test { - use core::prelude::*; - use core::cast; - use core::iter; + use std::cast; + use std::iter; use util::enum_set::*; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 548eebaea0be..074c73e5c0b8 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use metadata::encoder; use middle::ty::{ReSkolemized, ReVar}; @@ -32,7 +31,7 @@ use syntax::parse::token; use syntax::print::pprust; use syntax::{ast, ast_util}; -use core::vec; +use std::vec; /// Produces a string suitable for debugging output. pub trait Repr { diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs index 27ab3aca0209..9c586ae95d15 100644 --- a/src/librustdoc/astsrv.rs +++ b/src/librustdoc/astsrv.rs @@ -17,13 +17,12 @@ query AST-related information, shielding the rest of Rustdoc from its non-sendableness. */ -use core::prelude::*; use parse; -use core::cell::Cell; -use core::comm::{stream, SharedChan, Port}; -use core::task; +use std::cell::Cell; +use std::comm::{stream, SharedChan, Port}; +use std::task; use rustc::driver::driver; use rustc::driver::session::Session; use rustc::driver::session::{basic_options, options}; diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index 7b5a738f7dd2..7655e173e4e2 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -15,7 +15,6 @@ The attribute parser provides methods for pulling documentation out of an AST's attributes. */ -use core::prelude::*; use syntax::ast; use syntax::attr; @@ -71,7 +70,6 @@ pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { #[cfg(test)] mod test { - use core::prelude::*; use syntax::ast; use syntax; use super::{parse_hidden, parse_crate, parse_desc}; diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index a2e50d37fb63..3efebe854e48 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -16,7 +16,6 @@ corresponding AST nodes. The information gathered here is the basis of the natural-language documentation for a crate. */ -use core::prelude::*; use astsrv; use attr_parser; @@ -27,7 +26,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::vec; +use std::vec; use syntax::ast; use syntax::ast_map; @@ -235,7 +234,6 @@ fn fold_impl( #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass::run; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 52851b9100a4..dd929fb143b7 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -8,15 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::cell::Cell; -use core::os; -use core::result::Result; -use core::result; -use core::run::ProcessOutput; -use core::run; -use core::vec; +use std::cell::Cell; +use std::os; +use std::result::Result; +use std::result; +use std::run::ProcessOutput; +use std::run; +use std::vec; use extra::getopts; /// The type of document to output @@ -72,7 +71,7 @@ fn opts() -> ~[(getopts::Opt, ~str)] { } pub fn usage() { - use core::io::println; + use std::io::println; println("Usage: rustdoc [options] \n"); println("Options:\n"); @@ -245,11 +244,10 @@ pub fn maybe_find_pandoc( #[cfg(test)] mod test { - use core::prelude::*; use config::*; - use core::result; - use core::run::ProcessOutput; + use std::result; + use std::run::ProcessOutput; fn parse_config(args: &[~str]) -> Result { parse_config_(args, mock_process_output) diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs index 9cac958a113f..b6728e00fe41 100644 --- a/src/librustdoc/demo.rs +++ b/src/librustdoc/demo.rs @@ -21,7 +21,6 @@ * tests on this file */ -use core::prelude::*; /// The base price of a muffin on a non-holiday static price_of_a_muffin: float = 70f; diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs index dbaa5e8532cb..74d5d4674137 100644 --- a/src/librustdoc/desc_to_brief_pass.rs +++ b/src/librustdoc/desc_to_brief_pass.rs @@ -15,7 +15,6 @@ If the first paragraph of a long description is short enough then it is interpreted as the brief description. */ -use core::prelude::*; use astsrv; use doc::ItemUtils; @@ -24,7 +23,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::util; +use std::util; pub fn mk_pass() -> Pass { Pass { @@ -176,7 +175,6 @@ pub fn paragraphs(s: &str) -> ~[~str] { #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass; diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index 2fa4d3b63cd8..b45550c06e44 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -10,11 +10,10 @@ //! The document model -use core::prelude::*; use doc; -use core::vec; +use std::vec; pub type AstId = int; diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index b7b2b70769bb..c2127eae6253 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -10,13 +10,12 @@ //! Converts the Rust AST to the rustdoc document model -use core::prelude::*; use astsrv; use doc::ItemUtils; use doc; -use core::vec; +use std::vec; use syntax::ast; use syntax::parse::token::{ident_interner, ident_to_str}; use syntax::parse::token; diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 7cf616065d38..efb3e61e807f 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -8,13 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use doc; #[cfg(test)] use extract; #[cfg(test)] use parse; -use core::vec; +use std::vec; pub struct Fold { ctxt: T, diff --git a/src/librustdoc/markdown_index_pass.rs b/src/librustdoc/markdown_index_pass.rs index 3634155b8a3d..1e67f900822c 100644 --- a/src/librustdoc/markdown_index_pass.rs +++ b/src/librustdoc/markdown_index_pass.rs @@ -10,7 +10,6 @@ //! Build indexes as appropriate for the markdown pass -use core::prelude::*; use astsrv; use config; @@ -164,7 +163,6 @@ pub fn pandoc_header_id(header: &str) -> ~str { #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass; diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index e9deef6b2236..0705a5c17233 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -10,7 +10,6 @@ //! Generate markdown from a document tree -use core::prelude::*; use astsrv; use doc::ItemUtils; @@ -22,9 +21,9 @@ use markdown_writer::WriterFactory; use pass::Pass; use sort_pass; -use core::cell::Cell; -use core::str; -use core::vec; +use std::cell::Cell; +use std::str; +use std::vec; use syntax; pub fn mk_pass(writer_factory: WriterFactory) -> Pass { @@ -518,7 +517,6 @@ fn put_struct( #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass; diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index a093824e453b..9621ea0892b9 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -8,19 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use config; use doc::ItemUtils; use doc; -use core::comm::*; -use core::comm; -use core::io; -use core::result; -use core::run; -use core::str; -use core::task; +use std::comm::*; +use std::comm; +use std::io; +use std::result; +use std::run; +use std::str; +use std::task; use extra::future; pub enum WriteInstr { @@ -104,7 +103,7 @@ fn pandoc_writer( ]; do generic_writer |markdown| { - use core::io::WriterUtil; + use std::io::WriterUtil; debug!("pandoc cmd: %s", pandoc_cmd); debug!("pandoc args: %s", pandoc_args.connect(" ")); @@ -177,7 +176,7 @@ pub fn make_filename( } fn write_file(path: &Path, s: ~str) { - use core::io::WriterUtil; + use std::io::WriterUtil; match io::file_writer(path, [io::Create, io::Truncate]) { result::Ok(writer) => { @@ -225,7 +224,6 @@ fn future_writer() -> (Writer, future::Future<~str>) { #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use doc; diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 35a433ec9ded..508cf302ede5 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -15,7 +15,6 @@ Each page corresponds is a logical section. There may be pages for individual modules, pages for the crate, indexes, etc. */ -use core::prelude::*; use astsrv; use config; @@ -26,8 +25,8 @@ use fold; use pass::Pass; use util::NominalOp; -use core::comm::*; -use core::task; +use std::comm::*; +use std::task; use syntax::ast; #[cfg(test)] use doc::PageUtils; diff --git a/src/librustdoc/parse.rs b/src/librustdoc/parse.rs index 138e4d49156d..bf782c9d5f32 100644 --- a/src/librustdoc/parse.rs +++ b/src/librustdoc/parse.rs @@ -10,7 +10,6 @@ //! AST-parsing helpers -use core::prelude::*; use rustc::driver::driver::{file_input, str_input}; use rustc::driver::driver; diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs index 3654e2c76060..3497e9515c64 100644 --- a/src/librustdoc/pass.rs +++ b/src/librustdoc/pass.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; use astsrv; diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs index a7a36152ace3..55ce135f2777 100644 --- a/src/librustdoc/path_pass.rs +++ b/src/librustdoc/path_pass.rs @@ -10,7 +10,6 @@ //! Records the full path to items -use core::prelude::*; use astsrv; use doc::ItemUtils; diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs index 157f33fb170f..cb7da801e96e 100644 --- a/src/librustdoc/prune_private_pass.rs +++ b/src/librustdoc/prune_private_pass.rs @@ -10,7 +10,6 @@ //! Prune things that are private -use core::prelude::*; use extract; use syntax::ast; @@ -21,7 +20,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::util; +use std::util; pub fn mk_pass() -> Pass { Pass { diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index d02620229f5b..6d16b9759cc1 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -21,22 +21,17 @@ #[allow(non_implicitly_copyable_typarams)]; -#[no_std]; - -extern mod core(name = "std"); -extern mod extra(name = "extra"); - +extern mod extra; extern mod rustc; extern mod syntax; -use core::prelude::*; +use std::io; +use std::os; use config::Config; use doc::Item; use doc::ItemUtils; -use core::*; - pub mod pass; pub mod config; pub mod parse; @@ -66,15 +61,6 @@ pub mod escape_pass; pub mod prune_private_pass; pub mod util; -mod std { - pub use core::clone; - pub use core::cmp; - pub use core::os; - pub use core::str; - pub use core::sys; - pub use core::unstable; -} - pub fn main() { let args = os::args(); diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs index ba433bf479d2..4e297c36dd46 100644 --- a/src/librustdoc/sectionalize_pass.rs +++ b/src/librustdoc/sectionalize_pass.rs @@ -10,7 +10,6 @@ //! Breaks rustdocs into sections according to their headers -use core::prelude::*; use astsrv; use doc::ItemUtils; @@ -19,7 +18,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::iterator::IteratorUtil; +use std::iterator::IteratorUtil; pub fn mk_pass() -> Pass { Pass { @@ -162,7 +161,6 @@ fn parse_header<'a>(line: &'a str) -> Option<&'a str> { #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass; diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs index 6db582a60e98..58b7571305d2 100644 --- a/src/librustdoc/text_pass.rs +++ b/src/librustdoc/text_pass.rs @@ -10,7 +10,6 @@ //! Generic pass for performing an operation on all descriptions -use core::prelude::*; use astsrv; use doc::ItemUtils; @@ -20,7 +19,7 @@ use fold; use pass::Pass; use util::NominalOp; -use core::cell::Cell; +use std::cell::Cell; pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass { let op = Cell::new(op); @@ -139,7 +138,6 @@ fn fold_impl( #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use attr_pass; diff --git a/src/librustdoc/trim_pass.rs b/src/librustdoc/trim_pass.rs index 8bfa12ca0b5c..281a59c8cb7a 100644 --- a/src/librustdoc/trim_pass.rs +++ b/src/librustdoc/trim_pass.rs @@ -40,7 +40,7 @@ mod test { #[test] fn should_trim_text() { - use core::option::Some; + use std::option::Some; let doc = mk_doc(~"#[doc = \" desc \"] \ mod m { diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index 459daaa468f9..c3b02c91e749 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -10,7 +10,6 @@ //! Pulls type information out of the AST and attaches it to the document -use core::prelude::*; use astsrv; use doc::ItemUtils; @@ -21,7 +20,7 @@ use fold::Fold; use fold; use pass::Pass; -use core::vec; +use std::vec; use syntax::ast; use syntax::print::pprust; use syntax::parse::token; @@ -349,7 +348,6 @@ fn strip_struct_extra_stuff(item: @ast::item) -> @ast::item { #[cfg(test)] mod test { - use core::prelude::*; use astsrv; use doc; diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs index 2bcf04c0262e..7df6b3207802 100644 --- a/src/librustdoc/unindent_pass.rs +++ b/src/librustdoc/unindent_pass.rs @@ -19,9 +19,8 @@ instances where the string containing the doc comment is opened in the middle of a line, and each of the following lines is indented. */ -use core::prelude::*; -use core::uint; +use std::uint; use pass::Pass; use text_pass; diff --git a/src/librustdoc/util.rs b/src/librustdoc/util.rs index fe39ac6bc505..20e640874422 100644 --- a/src/librustdoc/util.rs +++ b/src/librustdoc/util.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; // Just a named container for our op, so it can have impls pub struct NominalOp { diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs index 9f8e925fa075..c36c6390a759 100644 --- a/src/librustpkg/api.rs +++ b/src/librustpkg/api.rs @@ -14,10 +14,10 @@ use package_id::*; use package_source::*; use version::Version; -use core::option::*; -use core::os; -use core::hashmap::*; -use core::path::*; +use std::option::*; +use std::os; +use std::hashmap::*; +use std::path::*; /// Convenience functions intended for calling from pkg.rs @@ -89,4 +89,4 @@ pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version fn mk_crate(p: Path) -> Crate { Crate { file: p, flags: ~[], cfgs: ~[] } -} \ No newline at end of file +} diff --git a/src/librustpkg/conditions.rs b/src/librustpkg/conditions.rs index caab16cd2917..c44563d87035 100644 --- a/src/librustpkg/conditions.rs +++ b/src/librustpkg/conditions.rs @@ -10,7 +10,7 @@ // Useful conditions -pub use core::path::Path; +pub use std::path::Path; pub use package_id::PkgId; condition! { diff --git a/src/librustpkg/context.rs b/src/librustpkg/context.rs index 4f67118e5205..230a0f915ac3 100644 --- a/src/librustpkg/context.rs +++ b/src/librustpkg/context.rs @@ -10,9 +10,8 @@ // Context data structure used by rustpkg -use core::prelude::*; -use core::hashmap::HashMap; +use std::hashmap::HashMap; pub struct Ctx { // Sysroot -- if this is None, uses rustc filesearch's diff --git a/src/librustpkg/crate.rs b/src/librustpkg/crate.rs index 5e8139063dec..5fe451260321 100644 --- a/src/librustpkg/crate.rs +++ b/src/librustpkg/crate.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::path::Path; -use core::vec; +use std::path::Path; +use std::vec; /// A crate is a unit of Rust code to be compiled into a binary or library pub struct Crate { diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index bde7aaeab8e4..43d727c2989a 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -9,8 +9,8 @@ // except according to those terms. use extra::term; -use core::io; -use core::result::*; +use std::io; +use std::result::*; pub fn note(msg: &str) { pretty_message(msg, "note: ", term::color::green, io::stdout()) diff --git a/src/librustpkg/package_id.rs b/src/librustpkg/package_id.rs index 3ff0a6073b6d..ebe2aa6f92a6 100644 --- a/src/librustpkg/package_id.rs +++ b/src/librustpkg/package_id.rs @@ -9,7 +9,6 @@ // except according to those terms. pub use package_path::{RemotePath, LocalPath, normalize, hash}; -use core::prelude::*; use version::{try_getting_version, Version, NoVersion, split_version}; /// Path-fragment identifier of a package such as diff --git a/src/librustpkg/package_path.rs b/src/librustpkg/package_path.rs index 161634be650c..a508d2ce1535 100644 --- a/src/librustpkg/package_path.rs +++ b/src/librustpkg/package_path.rs @@ -10,11 +10,11 @@ // rustpkg utilities having to do with local and remote paths -use core::path::Path; -use core::option::Some; -use core::hash; -use core::rt::io::Writer; -use core::hash::Streaming; +use std::path::Path; +use std::option::Some; +use std::hash; +use std::rt::io::Writer; +use std::hash::Streaming; /// Wrappers to prevent local and remote paths from getting confused /// (These will go away after #6407) diff --git a/src/librustpkg/package_source.rs b/src/librustpkg/package_source.rs index ebdea2537ac3..24c1bb9b200f 100644 --- a/src/librustpkg/package_source.rs +++ b/src/librustpkg/package_source.rs @@ -10,9 +10,9 @@ use target::*; use package_id::PkgId; -use core::path::Path; -use core::option::*; -use core::{os, run, str}; +use std::path::Path; +use std::option::*; +use std::{os, run, str}; use context::*; use crate::Crate; use messages::*; diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index f0a3f24c307b..6371d7263461 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -10,15 +10,14 @@ // rustpkg utilities having to do with paths and directories -use core::prelude::*; pub use package_path::{RemotePath, LocalPath, normalize}; pub use package_id::PkgId; pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install}; pub use version::{Version, NoVersion, split_version_general}; -use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; -use core::os::mkdir_recursive; -use core::os; -use core::iterator::IteratorUtil; +use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; +use std::os::mkdir_recursive; +use std::os; +use std::iterator::IteratorUtil; use messages::*; use package_id::*; diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 550a3411b5dd..d393ed695669 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -18,19 +18,19 @@ #[license = "MIT/ASL2"]; #[crate_type = "lib"]; -#[no_core]; -#[no_std]; - -extern mod core(name = "std"); -extern mod extra(name = "extra"); - +extern mod extra; extern mod rustc; extern mod syntax; -use core::prelude::*; -use core::*; -pub use core::path::Path; -use core::hashmap::HashMap; +use std::result; +use std::io; +use std::os; +use std::run; +use std::str; + +pub use std::path::Path; +use std::hashmap::HashMap; + use rustc::driver::{driver, session}; use rustc::metadata::filesearch; use extra::{getopts}; @@ -65,15 +65,6 @@ mod workspace; pub mod usage; -mod std { - pub use core::cmp; - pub use core::condition; - pub use core::os; - pub use core::str; - pub use core::sys; - pub use core::unstable; -} - /// A PkgScript represents user-supplied custom logic for /// special build hooks. This only exists for packages with /// an explicit package script. diff --git a/src/librustpkg/search.rs b/src/librustpkg/search.rs index e5ffc5c9d848..d04b2c8f3701 100644 --- a/src/librustpkg/search.rs +++ b/src/librustpkg/search.rs @@ -9,7 +9,6 @@ // except according to those terms. use path_util::installed_library_in_workspace; -use core::prelude::*; /// If a library with path `p` matching pkg_id's name exists under sroot_opt, /// return Some(p). Return None if there's no such path or if sroot_opt is None. diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 44a8e696bdea..0e2a4f33c72c 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -11,11 +11,10 @@ // rustpkg unit tests use context::Ctx; -use core::hashmap::HashMap; -use core::{io, libc, os, result, run, str, vec}; -use core::prelude::*; +use std::hashmap::HashMap; +use std::{io, libc, os, result, run, str, vec}; use extra::tempfile::mkdtemp; -use core::run::ProcessOutput; +use std::run::ProcessOutput; use package_path::*; use package_id::{PkgId}; use package_source::*; @@ -110,7 +109,7 @@ fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path { } fn is_rwx(p: &Path) -> bool { - use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; match p.get_mode() { None => return false, diff --git a/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs b/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs index c9c1f00fb082..0fd68ca3a204 100644 --- a/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs +++ b/src/librustpkg/testsuite/fail/src/no-inferred-crates/src/zzyzx.rs @@ -15,7 +15,7 @@ The test runner should check that, after `rustpkg build hello-world`: * testsuite/hello-world/build/ does not contain a library */ -use core::io; +use std::io; fn main() { io::println(~"Hello world!"); diff --git a/src/librustpkg/testsuite/pass/src/hello-world/main.rs b/src/librustpkg/testsuite/pass/src/hello-world/main.rs index 2ef387d96200..c8b2ce97c0c0 100644 --- a/src/librustpkg/testsuite/pass/src/hello-world/main.rs +++ b/src/librustpkg/testsuite/pass/src/hello-world/main.rs @@ -18,7 +18,7 @@ The test runner should check that, after `rustpkg build hello-world`: * testsuite/pass/hello-world/build is empty */ -use core::io; +use std::io; fn main() { io::println(~"Hello world!"); diff --git a/src/librustpkg/usage.rs b/src/librustpkg/usage.rs index 90c87210faaa..fee52c3c11f3 100644 --- a/src/librustpkg/usage.rs +++ b/src/librustpkg/usage.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::io; +use std::io; pub fn general() { io::println("Usage: rustpkg [options] [args..] diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index cb9bbf80ea8f..26e26add3dc2 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::{libc, os, result, str}; +use std::{libc, os, result, str}; use rustc::driver::{driver, session}; use rustc::metadata::filesearch; use extra::getopts::groups::getopts; @@ -418,4 +417,4 @@ mod test { // tjc: cheesy fn debug_flags() -> ~[~str] { ~[] } -// static debug_flags: ~[~str] = ~[~"-Z", ~"time-passes"]; \ No newline at end of file +// static debug_flags: ~[~str] = ~[~"-Z", ~"time-passes"]; diff --git a/src/librustpkg/version.rs b/src/librustpkg/version.rs index 1350751b74ce..1ec15c107c78 100644 --- a/src/librustpkg/version.rs +++ b/src/librustpkg/version.rs @@ -14,8 +14,7 @@ extern mod std; use extra::semver; -use core::prelude::*; -use core::{char, os, result, run, str}; +use std::{char, os, result, run, str}; use package_path::RemotePath; use extra::tempfile::mkdtemp; diff --git a/src/librustpkg/workspace.rs b/src/librustpkg/workspace.rs index bd576dc44a46..dd2cf445302a 100644 --- a/src/librustpkg/workspace.rs +++ b/src/librustpkg/workspace.rs @@ -12,7 +12,7 @@ use path_util::{rust_path, workspace_contains_package_id}; use package_id::PkgId; -use core::path::Path; +use std::path::Path; pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool { // Using the RUST_PATH, find workspaces that contain From 95d22a3c814ce050c55d94f5eb1651bea26a1a4b Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Sat, 29 Jun 2013 06:11:14 -0400 Subject: [PATCH 286/336] Fix merge fallout --- src/librustc/middle/trans/callee.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 8f9451510afa..852a41ee10cf 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -8,13 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! -// -// Handles translation of callees as well as other call-related -// things. Callees are a superset of normal rust values and sometimes -// have different representations. In particular, top-level fn items -// and methods are represented as just a fn ptr and not a full -// closure. +/*! + * + * Handles translation of callees as well as other call-related + * things. Callees are a superset of normal rust values and sometimes + * have different representations. In particular, top-level fn items + * and methods are represented as just a fn ptr and not a full + * closure. + */ + +use std::vec; use back::abi; use driver::session; From 71b1c6ab60b1279c81024f591ae571c75e4c6d3e Mon Sep 17 00:00:00 2001 From: Corey Richardson Date: Sat, 29 Jun 2013 11:01:25 -0400 Subject: [PATCH 287/336] Warning cleanup --- src/libextra/bitv.rs | 2 +- src/libextra/deque.rs | 10 +++++----- src/libextra/json.rs | 2 +- src/librustc/metadata/decoder.rs | 2 +- src/librustc/metadata/encoder.rs | 5 ----- src/librustc/middle/reachable.rs | 3 --- src/librustc/middle/resolve.rs | 2 +- src/librustc/middle/trans/callee.rs | 1 - src/librustc/middle/trans/expr.rs | 2 -- src/librustc/middle/typeck/coherence.rs | 2 +- src/librustc/middle/typeck/infer/combine.rs | 2 +- src/librustc/util/ppaux.rs | 2 -- src/libsyntax/parse/common.rs | 8 -------- 13 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index ca1deaf33ee2..521187ca3517 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -862,7 +862,7 @@ impl BitvSet { #[cfg(test)] mod tests { - use std::test::BenchHarness; + use extra::test::BenchHarness; use bitv::*; use bitv; diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index 2b599d06dafe..6074b2b5f547 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -255,7 +255,7 @@ mod tests { use super::*; use std::cmp::Eq; use std::kinds::Copy; - use core; + use std::int; #[test] fn test_simple() { @@ -462,12 +462,12 @@ mod tests { #[test] fn test_iter() { let mut d = Deque::new(); - for std::int::range(0,5) |i| { + for int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]); - for std::int::range(6,9) |i| { + for int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]); @@ -476,12 +476,12 @@ mod tests { #[test] fn test_rev_iter() { let mut d = Deque::new(); - for std::int::range(0,5) |i| { + for int::range(0,5) |i| { d.add_back(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]); - for std::int::range(6,9) |i| { + for int::range(6,9) |i| { d.add_front(i); } assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 758815442466..210921aa3d76 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -1362,7 +1362,7 @@ mod tests { use std::io; use std::result; - use std::serialize::Decodable; + use extra::serialize::Decodable; #[deriving(Eq, Encodable, Decodable)] enum Animal { diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index a7a69effe651..eeb22fa7ba9d 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -538,7 +538,7 @@ impl<'self> EachItemContext<'self> { fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool { // This item might not be in this crate. If it's not, look it up. - let (cdata, items) = if def_id.crate == self.cdata.cnum { + let (_cdata, items) = if def_id.crate == self.cdata.cnum { let items = reader::get_doc(reader::Doc(self.cdata.data), tag_items); (self.cdata, items) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 85fca077d88b..1a34d0c3d8c8 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -151,7 +151,6 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder, ecx: &EncodeContext, trait_ref: &ty::TraitRef, tag: uint) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, @@ -179,7 +178,6 @@ fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder, ecx: &EncodeContext, params: @~[ty::TypeParameterDef], tag: uint) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, @@ -212,7 +210,6 @@ fn encode_variant_id(ebml_w: &mut writer::Encoder, vid: def_id) { pub fn write_type(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, typ: ty::t) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, @@ -225,7 +222,6 @@ pub fn write_type(ecx: &EncodeContext, pub fn write_vstore(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, vstore: ty::vstore) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, @@ -258,7 +254,6 @@ fn encode_method_fty(ecx: &EncodeContext, typ: &ty::BareFnTy) { ebml_w.start_tag(tag_item_method_fty); - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 53d0e8d3576a..97bad93dc358 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -17,17 +17,14 @@ use std::iterator::IteratorUtil; -use middle::resolve; use middle::ty; use middle::typeck; use std::hashmap::HashSet; use syntax::ast::*; -use syntax::ast; use syntax::ast_map; use syntax::ast_util::def_id_of_def; use syntax::attr; -use syntax::codemap; use syntax::parse::token; use syntax::visit::Visitor; use syntax::visit; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 733ff9c14131..06147894d446 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1307,7 +1307,7 @@ impl Resolver { visit_item(item, (parent, visitor)); } - item_impl(_, Some(_), ty, ref methods) => { + item_impl(_, Some(_), _ty, ref _methods) => { visit_item(item, (parent, visitor)); } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 852a41ee10cf..ee89f229f2bb 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -9,7 +9,6 @@ // except according to those terms. /*! - * * Handles translation of callees as well as other call-related * things. Callees are a superset of normal rust values and sometimes * have different representations. In particular, top-level fn items diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 5a7e21d1fccb..3eac0f8b0983 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -909,8 +909,6 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let (bcx, base, len) = base_datum.get_vec_base_and_len(bcx, index_expr.span, index_expr.id, 0); - let mut bcx = bcx; - let mut base = base; let mut len = len; if ty::type_is_str(base_ty) { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 3483245706f3..8748d3dcd23b 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -36,7 +36,7 @@ use middle::typeck::infer::combine::Combine; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::{new_infer_ctxt, resolve_ivar}; use middle::typeck::infer::{resolve_nested_tvar, resolve_type}; -use syntax::ast::{crate, def_id, def_mod, def_struct, def_ty}; +use syntax::ast::{crate, def_id, def_struct, def_ty}; use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct}; use syntax::ast::{local_crate, method, trait_ref, ty_path}; use syntax::ast; diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index f80f022b5439..adc263cbc4d8 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -63,7 +63,7 @@ use middle::typeck::infer::glb::Glb; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; -use middle::typeck::infer::unify::{InferCtxtMethods, UnifyInferCtxtMethods}; +use middle::typeck::infer::unify::{InferCtxtMethods}; use middle::typeck::infer::{InferCtxt, cres, ures}; use util::common::indent; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 074c73e5c0b8..80344a9894fb 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -31,8 +31,6 @@ use syntax::parse::token; use syntax::print::pprust; use syntax::{ast, ast_util}; -use std::vec; - /// Produces a string suitable for debugging output. pub trait Repr { fn repr(&self, tcx: ctxt) -> ~str; diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 04f62f357490..12e32731fcc3 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -8,17 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast; -use codemap::{BytePos, spanned}; -use parse::lexer::reader; -use parse::parser::Parser; -use parse::token::keywords; use parse::token; use parse::token::{get_ident_interner}; -use opt_vec; -use opt_vec::OptVec; - // SeqSep : a sequence separator (token) // and whether a trailing separator is allowed. pub struct SeqSep { From b29c36867418ea551b23c767f45454eea4623d79 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 23 Jun 2013 20:44:11 -0700 Subject: [PATCH 288/336] Removing a lot of usage of '&const' --- src/libextra/arc.rs | 4 +- src/libextra/bitv.rs | 4 +- src/libextra/deque.rs | 4 +- src/libextra/flate.rs | 8 +-- src/libextra/treemap.rs | 8 +-- src/librustc/middle/lang_items.rs | 76 +++++++++++----------- src/librustc/middle/ty.rs | 4 +- src/librustc/middle/typeck/check/vtable.rs | 2 +- src/libstd/at_vec.rs | 6 +- src/libstd/hashmap.rs | 8 +-- src/libstd/io.rs | 6 +- src/libstd/option.rs | 4 +- src/libstd/ptr.rs | 18 ++--- src/libstd/str.rs | 8 +-- src/libstd/task/spawn.rs | 2 +- src/libstd/trie.rs | 8 +-- src/libstd/vec.rs | 72 ++++++-------------- 17 files changed, 105 insertions(+), 137 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 30067c92300c..13d159d8fed3 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -436,8 +436,8 @@ impl RWARC { // lock it. This wraps the unsafety, with the justification that the 'lock' // field is never overwritten; only 'failed' and 'data'. #[doc(hidden)] -fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { - unsafe { cast::transmute(&const (*state).lock) } +fn borrow_rwlock(state: *mut RWARCInner) -> *RWlock { + unsafe { cast::transmute(&(*state).lock) } } /// The "write permission" token used for RWARC.write_downgrade(). diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs index 4fe7761bf18d..92ee3fb43c68 100644 --- a/src/libextra/bitv.rs +++ b/src/libextra/bitv.rs @@ -705,8 +705,8 @@ impl cmp::Eq for BitvSet { } impl Container for BitvSet { - fn len(&const self) -> uint { self.size } - fn is_empty(&const self) -> bool { self.size == 0 } + fn len(&self) -> uint { self.size } + fn is_empty(&self) -> bool { self.size == 0 } } impl Mutable for BitvSet { diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index c70c87b6ea13..cf7b188cb1d9 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -28,10 +28,10 @@ pub struct Deque { impl Container for Deque { /// Return the number of elements in the deque - fn len(&const self) -> uint { self.nelts } + fn len(&self) -> uint { self.nelts } /// Return true if the deque contains no elements - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for Deque { diff --git a/src/libextra/flate.rs b/src/libextra/flate.rs index 0fde03b69cbf..fe8f4bee75e7 100644 --- a/src/libextra/flate.rs +++ b/src/libextra/flate.rs @@ -44,8 +44,8 @@ static lz_fast : c_int = 0x1; // LZ with only one probe static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal" static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best" -pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] { - do vec::as_const_buf(bytes) |b, len| { +pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] { + do vec::as_imm_buf(bytes) |b, len| { unsafe { let mut outsz : size_t = 0; let res = @@ -62,8 +62,8 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] { } } -pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { - do vec::as_const_buf(bytes) |b, len| { +pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] { + do vec::as_imm_buf(bytes) |b, len| { unsafe { let mut outsz : size_t = 0; let res = diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index d546b48f8175..fcee3a2b7968 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -87,10 +87,10 @@ impl Ord for TreeMap { impl Container for TreeMap { /// Return the number of elements in the map - fn len(&const self) -> uint { self.length } + fn len(&self) -> uint { self.length } /// Return true if the map contains no elements - fn is_empty(&const self) -> bool { self.root.is_none() } + fn is_empty(&self) -> bool { self.root.is_none() } } impl Mutable for TreeMap { @@ -265,11 +265,11 @@ impl Ord for TreeSet { impl Container for TreeSet { /// Return the number of elements in the set #[inline] - fn len(&const self) -> uint { self.map.len() } + fn len(&self) -> uint { self.map.len() } /// Return true if the set contains no elements #[inline] - fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&self) -> bool { self.map.is_empty() } } impl Mutable for TreeSet { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 08e55df5b368..b167a22992cf 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -152,122 +152,122 @@ impl LanguageItems { // FIXME #4621: Method macros sure would be nice here. - pub fn freeze_trait(&const self) -> def_id { + pub fn freeze_trait(&self) -> def_id { self.items[FreezeTraitLangItem as uint].get() } - pub fn copy_trait(&const self) -> def_id { + pub fn copy_trait(&self) -> def_id { self.items[CopyTraitLangItem as uint].get() } - pub fn send_trait(&const self) -> def_id { + pub fn send_trait(&self) -> def_id { self.items[SendTraitLangItem as uint].get() } - pub fn sized_trait(&const self) -> def_id { + pub fn sized_trait(&self) -> def_id { self.items[SizedTraitLangItem as uint].get() } - pub fn drop_trait(&const self) -> def_id { + pub fn drop_trait(&self) -> def_id { self.items[DropTraitLangItem as uint].get() } - pub fn add_trait(&const self) -> def_id { + pub fn add_trait(&self) -> def_id { self.items[AddTraitLangItem as uint].get() } - pub fn sub_trait(&const self) -> def_id { + pub fn sub_trait(&self) -> def_id { self.items[SubTraitLangItem as uint].get() } - pub fn mul_trait(&const self) -> def_id { + pub fn mul_trait(&self) -> def_id { self.items[MulTraitLangItem as uint].get() } - pub fn div_trait(&const self) -> def_id { + pub fn div_trait(&self) -> def_id { self.items[DivTraitLangItem as uint].get() } - pub fn rem_trait(&const self) -> def_id { + pub fn rem_trait(&self) -> def_id { self.items[RemTraitLangItem as uint].get() } - pub fn neg_trait(&const self) -> def_id { + pub fn neg_trait(&self) -> def_id { self.items[NegTraitLangItem as uint].get() } - pub fn not_trait(&const self) -> def_id { + pub fn not_trait(&self) -> def_id { self.items[NotTraitLangItem as uint].get() } - pub fn bitxor_trait(&const self) -> def_id { + pub fn bitxor_trait(&self) -> def_id { self.items[BitXorTraitLangItem as uint].get() } - pub fn bitand_trait(&const self) -> def_id { + pub fn bitand_trait(&self) -> def_id { self.items[BitAndTraitLangItem as uint].get() } - pub fn bitor_trait(&const self) -> def_id { + pub fn bitor_trait(&self) -> def_id { self.items[BitOrTraitLangItem as uint].get() } - pub fn shl_trait(&const self) -> def_id { + pub fn shl_trait(&self) -> def_id { self.items[ShlTraitLangItem as uint].get() } - pub fn shr_trait(&const self) -> def_id { + pub fn shr_trait(&self) -> def_id { self.items[ShrTraitLangItem as uint].get() } - pub fn index_trait(&const self) -> def_id { + pub fn index_trait(&self) -> def_id { self.items[IndexTraitLangItem as uint].get() } - pub fn eq_trait(&const self) -> def_id { + pub fn eq_trait(&self) -> def_id { self.items[EqTraitLangItem as uint].get() } - pub fn ord_trait(&const self) -> def_id { + pub fn ord_trait(&self) -> def_id { self.items[OrdTraitLangItem as uint].get() } - pub fn str_eq_fn(&const self) -> def_id { + pub fn str_eq_fn(&self) -> def_id { self.items[StrEqFnLangItem as uint].get() } - pub fn uniq_str_eq_fn(&const self) -> def_id { + pub fn uniq_str_eq_fn(&self) -> def_id { self.items[UniqStrEqFnLangItem as uint].get() } - pub fn annihilate_fn(&const self) -> def_id { + pub fn annihilate_fn(&self) -> def_id { self.items[AnnihilateFnLangItem as uint].get() } - pub fn log_type_fn(&const self) -> def_id { + pub fn log_type_fn(&self) -> def_id { self.items[LogTypeFnLangItem as uint].get() } - pub fn fail_fn(&const self) -> def_id { + pub fn fail_fn(&self) -> def_id { self.items[FailFnLangItem as uint].get() } - pub fn fail_bounds_check_fn(&const self) -> def_id { + pub fn fail_bounds_check_fn(&self) -> def_id { self.items[FailBoundsCheckFnLangItem as uint].get() } - pub fn exchange_malloc_fn(&const self) -> def_id { + pub fn exchange_malloc_fn(&self) -> def_id { self.items[ExchangeMallocFnLangItem as uint].get() } - pub fn exchange_free_fn(&const self) -> def_id { + pub fn exchange_free_fn(&self) -> def_id { self.items[ExchangeFreeFnLangItem as uint].get() } - pub fn malloc_fn(&const self) -> def_id { + pub fn malloc_fn(&self) -> def_id { self.items[MallocFnLangItem as uint].get() } - pub fn free_fn(&const self) -> def_id { + pub fn free_fn(&self) -> def_id { self.items[FreeFnLangItem as uint].get() } - pub fn borrow_as_imm_fn(&const self) -> def_id { + pub fn borrow_as_imm_fn(&self) -> def_id { self.items[BorrowAsImmFnLangItem as uint].get() } - pub fn borrow_as_mut_fn(&const self) -> def_id { + pub fn borrow_as_mut_fn(&self) -> def_id { self.items[BorrowAsMutFnLangItem as uint].get() } - pub fn return_to_mut_fn(&const self) -> def_id { + pub fn return_to_mut_fn(&self) -> def_id { self.items[ReturnToMutFnLangItem as uint].get() } - pub fn check_not_borrowed_fn(&const self) -> def_id { + pub fn check_not_borrowed_fn(&self) -> def_id { self.items[CheckNotBorrowedFnLangItem as uint].get() } - pub fn strdup_uniq_fn(&const self) -> def_id { + pub fn strdup_uniq_fn(&self) -> def_id { self.items[StrDupUniqFnLangItem as uint].get() } - pub fn record_borrow_fn(&const self) -> def_id { + pub fn record_borrow_fn(&self) -> def_id { self.items[RecordBorrowFnLangItem as uint].get() } - pub fn unrecord_borrow_fn(&const self) -> def_id { + pub fn unrecord_borrow_fn(&self) -> def_id { self.items[UnrecordBorrowFnLangItem as uint].get() } - pub fn start_fn(&const self) -> def_id { + pub fn start_fn(&self) -> def_id { self.items[StartFnLangItem as uint].get() } pub fn ty_desc(&const self) -> def_id { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b8ee1eee26e1..48e841353c08 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3696,14 +3696,14 @@ pub enum DtorKind { } impl DtorKind { - pub fn is_not_present(&const self) -> bool { + pub fn is_not_present(&self) -> bool { match *self { NoDtor => true, _ => false } } - pub fn is_present(&const self) -> bool { + pub fn is_present(&self) -> bool { !self.is_not_present() } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 0bf20f9fbcb9..a46d2f28b139 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -64,7 +64,7 @@ pub struct VtableContext { } impl VtableContext { - pub fn tcx(&const self) -> ty::ctxt { self.ccx.tcx } + pub fn tcx(&self) -> ty::ctxt { self.ccx.tcx } } fn has_trait_bounds(type_param_defs: &[ty::TypeParameterDef]) -> bool { diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 5a2f948600a8..325ce097cd5a 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -108,7 +108,7 @@ pub fn build_sized_opt(size: Option, /// Iterates over the `rhs` vector, copying each element and appending it to the /// `lhs`. Afterwards, the `lhs` is then returned for use again. #[inline] -pub fn append(lhs: @[T], rhs: &const [T]) -> @[T] { +pub fn append(lhs: @[T], rhs: &[T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { for lhs.iter().advance |x| { push(copy *x); } for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); } @@ -180,9 +180,9 @@ pub mod traits { use kinds::Copy; use ops::Add; - impl<'self,T:Copy> Add<&'self const [T],@[T]> for @[T] { + impl<'self,T:Copy> Add<&'self [T],@[T]> for @[T] { #[inline] - fn add(&self, rhs: & &'self const [T]) -> @[T] { + fn add(&self, rhs: & &'self [T]) -> @[T] { append(*self, (*rhs)) } } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 7f9fb6ad9380..35db229b65d3 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -282,10 +282,10 @@ impl HashMap { impl Container for HashMap { /// Return the number of elements in the map - fn len(&const self) -> uint { self.size } + fn len(&self) -> uint { self.size } /// Return true if the map contains no elements - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for HashMap { @@ -623,10 +623,10 @@ impl Eq for HashSet { impl Container for HashSet { /// Return the number of elements in the set - fn len(&const self) -> uint { self.map.len() } + fn len(&self) -> uint { self.map.len() } /// Return true if the set contains no elements - fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&self) -> bool { self.map.is_empty() } } impl Mutable for HashSet { diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 59ac58a514f3..40793ff1af7b 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1152,7 +1152,7 @@ impl Writer for Wrapper { impl Writer for *libc::FILE { fn write(&self, v: &[u8]) { unsafe { - do vec::as_const_buf(v) |vbuf, len| { + do vec::as_imm_buf(v) |vbuf, len| { let nout = libc::fwrite(vbuf as *c_void, 1, len as size_t, @@ -1203,9 +1203,9 @@ impl Writer for fd_t { fn write(&self, v: &[u8]) { unsafe { let mut count = 0u; - do vec::as_const_buf(v) |vbuf, len| { + do vec::as_imm_buf(v) |vbuf, len| { while count < len { - let vb = ptr::const_offset(vbuf, count) as *c_void; + let vb = ptr::offset(vbuf, count) as *c_void; let nout = libc::write(*self, vb, len as size_t); if nout < 0 as ssize_t { error!("error writing buffer"); diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 12ae2abd4a1f..643812312582 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -121,13 +121,13 @@ impl Option { /// Returns true if the option equals `none` #[inline] - pub fn is_none(&const self) -> bool { + pub fn is_none(&self) -> bool { match *self { None => true, Some(_) => false } } /// Returns true if the option contains some value #[inline] - pub fn is_some(&const self) -> bool { !self.is_none() } + pub fn is_some(&self) -> bool { !self.is_none() } /// Update an optional value by optionally running its content through a /// function that returns an option. diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 7f89d454be11..473f56ddd798 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -232,9 +232,9 @@ pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { #[allow(missing_doc)] pub trait RawPtr { - fn is_null(&const self) -> bool; - fn is_not_null(&const self) -> bool; - unsafe fn to_option(&const self) -> Option<&T>; + fn is_null(&self) -> bool; + fn is_not_null(&self) -> bool; + unsafe fn to_option(&self) -> Option<&T>; fn offset(&self, count: uint) -> Self; } @@ -242,11 +242,11 @@ pub trait RawPtr { impl RawPtr for *T { /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&const self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&const self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { is_not_null(*self) } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -259,7 +259,7 @@ impl RawPtr for *T { /// be pointing to invalid memory. /// #[inline] - unsafe fn to_option(&const self) -> Option<&T> { + unsafe fn to_option(&self) -> Option<&T> { if self.is_null() { None } else { Some(cast::transmute(*self)) } @@ -274,11 +274,11 @@ impl RawPtr for *T { impl RawPtr for *mut T { /// Returns true if the pointer is equal to the null pointer. #[inline] - fn is_null(&const self) -> bool { is_null(*self) } + fn is_null(&self) -> bool { is_null(*self) } /// Returns true if the pointer is not equal to the null pointer. #[inline] - fn is_not_null(&const self) -> bool { is_not_null(*self) } + fn is_not_null(&self) -> bool { is_not_null(*self) } /// /// Returns `None` if the pointer is null, or else returns the value wrapped @@ -291,7 +291,7 @@ impl RawPtr for *mut T { /// be pointing to invalid memory. /// #[inline] - unsafe fn to_option(&const self) -> Option<&T> { + unsafe fn to_option(&self) -> Option<&T> { if self.is_null() { None } else { Some(cast::transmute(*self)) } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index e47800d70c6b..a06d858e4243 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -569,7 +569,7 @@ Section: Misc */ /// Determines if a vector of bytes contains valid UTF-8 -pub fn is_utf8(v: &const [u8]) -> bool { +pub fn is_utf8(v: &[u8]) -> bool { let mut i = 0u; let total = v.len(); while i < total { @@ -815,7 +815,7 @@ pub mod raw { } /// Create a Rust string from a *u8 buffer of the given length - pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str { + 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| { ptr::copy_memory(vbuf, buf as *u8, len) @@ -838,8 +838,8 @@ pub mod raw { } /// Converts a vector of bytes to a new owned string. - pub unsafe fn from_bytes(v: &const [u8]) -> ~str { - do vec::as_const_buf(v) |buf, len| { + pub unsafe fn from_bytes(v: &[u8]) -> ~str { + do vec::as_imm_buf(v) |buf, len| { from_buf_len(buf, len) } } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index c932a9660c2f..190485a720aa 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -129,7 +129,7 @@ type TaskGroupInner<'self> = &'self mut Option; // A taskgroup is 'dead' when nothing can cause it to fail; only members can. fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { - (&const tg.members).is_empty() + tg.members.is_empty() } // A list-like structure by which taskgroups keep track of all ancestor groups diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index b9b03ea56619..8ce02d59ab15 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -35,11 +35,11 @@ pub struct TrieMap { impl Container for TrieMap { /// Return the number of elements in the map #[inline] - fn len(&const self) -> uint { self.length } + fn len(&self) -> uint { self.length } /// Return true if the map contains no elements #[inline] - fn is_empty(&const self) -> bool { self.len() == 0 } + fn is_empty(&self) -> bool { self.len() == 0 } } impl Mutable for TrieMap { @@ -179,11 +179,11 @@ pub struct TrieSet { impl Container for TrieSet { /// Return the number of elements in the set #[inline] - fn len(&const self) -> uint { self.map.len() } + fn len(&self) -> uint { self.map.len() } /// Return true if the set contains no elements #[inline] - fn is_empty(&const self) -> bool { self.map.is_empty() } + fn is_empty(&self) -> bool { self.map.is_empty() } } impl Mutable for TrieSet { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 4e7943f7cfd2..4196fbac0beb 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -64,7 +64,7 @@ pub mod rustrt { } /// Returns true if two vectors have the same length -pub fn same_length(xs: &const [T], ys: &const [U]) -> bool { +pub fn same_length(xs: &[T], ys: &[U]) -> bool { xs.len() == ys.len() } @@ -350,10 +350,7 @@ pub fn dedup(v: &mut ~[T]) { if v.len() < 1 { return; } let mut last_written = 0; let mut next_to_read = 1; - do as_const_buf(*v) |p, ln| { - // We have a mutable reference to v, so we can make arbitrary - // changes. (cf. push and pop) - let p = p as *mut T; + do as_mut_buf(*v) |p, ln| { // last_written < next_to_read <= ln while next_to_read < ln { // last_written < next_to_read < ln @@ -384,7 +381,7 @@ pub fn dedup(v: &mut ~[T]) { /// Iterates over the `rhs` vector, copying each element and appending it to the /// `lhs`. Afterwards, the `lhs` is then returned for use again. #[inline] -pub fn append(lhs: ~[T], rhs: &const [T]) -> ~[T] { +pub fn append(lhs: ~[T], rhs: &[T]) -> ~[T] { let mut v = lhs; v.push_all(rhs); v @@ -831,7 +828,7 @@ pub fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { /** * Convert two vectors to a vector of pairs, by reference. As zip(). */ -pub fn zip_slice(v: &const [T], u: &const [U]) +pub fn zip_slice(v: &[T], u: &[U]) -> ~[(T, U)] { let mut zipped = ~[]; let sz = v.len(); @@ -893,7 +890,7 @@ pub fn reverse(v: &mut [T]) { } /// Returns a vector with the order of elements reversed -pub fn reversed(v: &const [T]) -> ~[T] { +pub fn reversed(v: &[T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = v.len(); if i == 0 { return (rs); } else { i -= 1; } @@ -1003,16 +1000,6 @@ pub fn as_imm_buf(s: &[T], } } -/// Similar to `as_imm_buf` but passing a `*const T` -#[inline] -pub fn as_const_buf(s: &const [T], f: &fn(*const T, uint) -> U) -> U { - unsafe { - let v : *(*const T,uint) = transmute(&s); - let (buf,len) = *v; - f(buf, len / sys::nonzero_size_of::()) - } -} - /// 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 { @@ -1198,25 +1185,25 @@ pub mod traits { use ops::Add; use vec::append; - impl<'self,T:Copy> Add<&'self const [T],~[T]> for ~[T] { + impl<'self,T:Copy> Add<&'self [T],~[T]> for ~[T] { #[inline] - fn add(&self, rhs: & &'self const [T]) -> ~[T] { + fn add(&self, rhs: & &'self [T]) -> ~[T] { append(copy *self, (*rhs)) } } } -impl<'self, T> Container for &'self const [T] { +impl<'self, T> Container for &'self [T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_const_buf(*self, |_p, len| len == 0u) + as_imm_buf(*self, |_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_const_buf(*self, |_p, len| len) + as_imm_buf(*self, |_p, len| len) } } @@ -1224,13 +1211,13 @@ impl Container for ~[T] { /// Returns true if a vector contains no elements #[inline] fn is_empty(&self) -> bool { - as_const_buf(*self, |_p, len| len == 0u) + as_imm_buf(*self, |_p, len| len == 0u) } /// Returns the length of a vector #[inline] fn len(&self) -> uint { - as_const_buf(*self, |_p, len| len) + as_imm_buf(*self, |_p, len| len) } } @@ -1843,7 +1830,7 @@ impl Mutable for ~[T] { #[allow(missing_doc)] pub trait OwnedCopyableVector { - fn push_all(&mut self, rhs: &const [T]); + fn push_all(&mut self, rhs: &[T]); fn grow(&mut self, n: uint, initval: &T); fn grow_set(&mut self, index: uint, initval: &T, val: T); } @@ -1860,7 +1847,7 @@ impl OwnedCopyableVector for ~[T] { /// assert!(a == ~[1, 2, 3, 4]); /// ~~~ #[inline] - fn push_all(&mut self, rhs: &const [T]) { + fn push_all(&mut self, rhs: &[T]) { let new_len = self.len() + rhs.len(); self.reserve(new_len); @@ -2017,7 +2004,7 @@ pub mod raw { use ptr; use sys; use unstable::intrinsics; - use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, with_capacity}; + use vec::{UnboxedVecRepr, as_imm_buf, as_mut_buf, with_capacity}; use util; /// The internal representation of a (boxed) vector @@ -2065,15 +2052,6 @@ pub mod raw { } } - /** see `to_ptr()` */ - #[inline] - pub fn to_const_ptr(v: &const [T]) -> *const T { - unsafe { - let repr: **SliceRepr = transmute(&v); - transmute(&((**repr).data)) - } - } - /** see `to_ptr()` */ #[inline] pub fn to_mut_ptr(v: &mut [T]) -> *mut T { @@ -2113,8 +2091,8 @@ pub mod raw { * Unchecked vector indexing. */ #[inline] - pub unsafe fn get(v: &const [T], i: uint) -> T { - as_const_buf(v, |p, _len| copy *ptr::const_offset(p, i)) + pub unsafe fn get(v: &[T], i: uint) -> T { + as_imm_buf(v, |p, _len| copy *ptr::offset(p, i)) } /** @@ -2156,13 +2134,13 @@ pub mod raw { * may overlap. */ #[inline] - pub unsafe fn copy_memory(dst: &mut [T], src: &const [T], + pub unsafe fn copy_memory(dst: &mut [T], src: &[T], count: uint) { assert!(dst.len() >= count); assert!(src.len() >= count); do as_mut_buf(dst) |p_dst, _len_dst| { - do as_const_buf(src) |p_src, _len_src| { + do as_imm_buf(src) |p_src, _len_src| { ptr::copy_memory(p_dst, p_src, count) } } @@ -2238,7 +2216,7 @@ pub mod bytes { * may overlap. */ #[inline] - pub fn copy_memory(dst: &mut [u8], src: &const [u8], count: uint) { + pub fn copy_memory(dst: &mut [u8], src: &[u8], count: uint) { // Bound checks are done at vec::raw::copy_memory. unsafe { vec::raw::copy_memory(dst, src, count) } } @@ -3690,16 +3668,6 @@ mod tests { } } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_as_const_buf_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - do as_const_buf(v) |_buf, _i| { - fail!() - } - } - #[test] #[ignore(cfg(windows))] #[should_fail] From 3bad7129ebb13d7a4c0a7965aeb5bd536cc0f5f0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 23 Jun 2013 21:12:17 -0700 Subject: [PATCH 289/336] Remove mutability from unique boxes in the AST --- src/librustc/metadata/decoder.rs | 2 +- src/librustc/metadata/encoder.rs | 3 +-- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/meth.rs | 4 ++-- src/librustc/middle/trans/type_use.rs | 2 +- src/librustc/middle/typeck/astconv.rs | 4 ++-- src/librustc/middle/typeck/check/method.rs | 4 ++-- src/librustc/middle/typeck/check/mod.rs | 7 ++++--- src/libsyntax/ast.rs | 4 ++-- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/deriving/ty.rs | 2 +- src/libsyntax/parse/parser.rs | 12 ++++++++---- src/libsyntax/print/pprust.rs | 4 +--- 16 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 69faf519bc28..b08186349319 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -786,7 +786,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ { 's' => { return ast::sty_static; } 'v' => { return ast::sty_value; } '@' => { return ast::sty_box(get_mutability(string[1])); } - '~' => { return ast::sty_uniq(get_mutability(string[1])); } + '~' => { return ast::sty_uniq; } '&' => { // FIXME(#4846) expl. region return ast::sty_region(None, get_mutability(string[1])); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index e394c8dcf92f..7735a7e39561 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -630,9 +630,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic ebml_w.writer.write(&[ '@' as u8 ]); encode_mutability(ebml_w, m); } - sty_uniq(m) => { + sty_uniq => { ebml_w.writer.write(&[ '~' as u8 ]); - encode_mutability(ebml_w, m); } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 2c6ba79e96e4..8ad61fe1f61c 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -92,7 +92,7 @@ pub fn check_expr(sess: Session, if is_const { match e.node { expr_unary(_, deref, _) => { } - expr_unary(_, box(_), _) | expr_unary(_, uniq(_), _) => { + expr_unary(_, box(_), _) | expr_unary(_, uniq, _) => { sess.span_err(e.span, "disallowed operator in constant expression"); return; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 86b8b2943198..e431784f1e63 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -368,7 +368,7 @@ fn visit_fn(fk: &visit::fn_kind, match *fk { fk_method(_, _, method) => { match method.explicit_self.node { - sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => { + sty_value | sty_region(*) | sty_box(_) | sty_uniq => { fn_maps.add_variable(Arg(method.self_id, special_idents::self_)); } diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index d7b6e9cf5a37..6780c51e5062 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -340,7 +340,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef { let is_float = ty::type_is_fp(ty); return match u { ast::box(_) | - ast::uniq(_) | + ast::uniq | ast::deref => { let (dv, _dt) = const_deref(cx, te, ty, true); dv diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 353227307560..297a466c7cb0 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1314,7 +1314,7 @@ fn trans_unary_datum(bcx: block, trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap_managed) } - ast::uniq(_) => { + ast::uniq => { let heap = heap_for_unique(bcx, un_ty); trans_boxed_expr(bcx, un_ty, sub_expr, sub_ty, heap) } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 0b051662781e..75e9dbe48619 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -532,7 +532,7 @@ pub fn trans_trait_callee(bcx: block, let llpair = match explicit_self { ast::sty_region(*) => Load(bcx, llpair), ast::sty_static | ast::sty_value | - ast::sty_box(_) | ast::sty_uniq(_) => llpair + ast::sty_box(_) | ast::sty_uniq => llpair }; let callee_ty = node_id_type(bcx, callee_id); @@ -622,7 +622,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, self_mode = ty::ByRef; } - ast::sty_uniq(_) => { + ast::sty_uniq => { // Pass the unique pointer. match store { ty::UniqTraitStore => llself = llbox, diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index c636b7f48761..d8d539764620 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -278,7 +278,7 @@ pub fn mark_for_method_call(cx: &Context, e_id: node_id, callee_id: node_id) { pub fn mark_for_expr(cx: &Context, e: &expr) { match e.node { expr_vstore(_, _) | expr_vec(_, _) | expr_struct(*) | expr_tup(_) | - expr_unary(_, box(_), _) | expr_unary(_, uniq(_), _) | + expr_unary(_, box(_), _) | expr_unary(_, uniq, _) | expr_binary(_, add, _, _) | expr_copy(_) | expr_repeat(*) => { node_type_needs(cx, use_repr, e.id); } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 07fb23fea48a..1e236c620a0e 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -662,10 +662,10 @@ fn ty_of_method_or_bare_fn( ty::mt {ty: self_info.untransformed_self_ty, mutbl: mutability})) } - ast::sty_uniq(mutability) => { + ast::sty_uniq => { Some(ty::mk_uniq(this.tcx(), ty::mt {ty: self_info.untransformed_self_ty, - mutbl: mutability})) + mutbl: ast::m_imm})) } } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 4bebca3c9a8b..7489882ab768 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1123,11 +1123,11 @@ impl<'self> LookupContext<'self> { } } - sty_uniq(m) => { + sty_uniq => { debug!("(is relevant?) explicit self is a unique pointer"); match ty::get(rcvr_ty).sty { ty::ty_uniq(mt) => { - mutability_matches(mt.mutbl, m) && + mutability_matches(mt.mutbl, ast::m_imm) && self.fcx.can_mk_subty(mt.ty, candidate.rcvr_ty).is_ok() } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 23266767124c..0cd9aac37989 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2301,7 +2301,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, ast::expr_unary(callee_id, unop, oprnd) => { let exp_inner = do unpack_expected(fcx, expected) |sty| { match unop { - ast::box(_) | ast::uniq(_) => match *sty { + ast::box(_) | ast::uniq => match *sty { ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => Some(mt.ty), _ => None }, @@ -2318,9 +2318,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, oprnd_t = ty::mk_box(tcx, ty::mt {ty: oprnd_t, mutbl: mutbl}); } - ast::uniq(mutbl) => { + ast::uniq => { oprnd_t = ty::mk_uniq(tcx, - ty::mt {ty: oprnd_t, mutbl: mutbl}); + ty::mt {ty: oprnd_t, + mutbl: ast::m_imm}); } ast::deref => { let sty = structure_of(fcx, expr.span, oprnd_t); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc432c4c7b0b..2603cbb2dd7c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -333,7 +333,7 @@ pub enum binop { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum unop { box(mutability), - uniq(mutability), + uniq, deref, not, neg @@ -805,7 +805,7 @@ pub enum explicit_self_ { sty_value, // `self` sty_region(Option<@Lifetime>, mutability), // `&'lt self` sty_box(mutability), // `@self` - sty_uniq(mutability) // `~self` + sty_uniq // `~self` } pub type explicit_self = spanned; diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 9439f45be21b..ee7c7180f8db 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -135,7 +135,7 @@ pub fn is_shift_binop(b: binop) -> bool { pub fn unop_to_str(op: unop) -> ~str { match op { box(mt) => if mt == m_mutbl { ~"@mut " } else { ~"@" }, - uniq(mt) => if mt == m_mutbl { ~"~mut " } else { ~"~" }, + uniq => ~"~", deref => ~"*", not => ~"!", neg => ~"-" diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index a2f9aa58d99a..e210853bfb4d 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -248,7 +248,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option) let self_ty = respan( span, match *ptr { - Send => ast::sty_uniq(ast::m_imm), + Send => ast::sty_uniq, Managed(mutbl) => ast::sty_box(mutbl), Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| @cx.lifetime(span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f1b5c4d16be9..cc0baa28e20d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2071,9 +2071,8 @@ impl Parser { ex = match e.node { expr_vec(*) | expr_lit(@codemap::spanned { node: lit_str(_), span: _}) | - expr_repeat(*) - if m == m_imm => expr_vstore(e, expr_vstore_uniq), - _ => self.mk_unary(uniq(m), e) + expr_repeat(*) => expr_vstore(e, expr_vstore_uniq), + _ => self.mk_unary(uniq, e) }; } _ => return self.parse_dot_or_call_expr() @@ -3366,7 +3365,12 @@ impl Parser { maybe_parse_explicit_self(sty_box, self) } token::TILDE => { - maybe_parse_explicit_self(sty_uniq, self) + maybe_parse_explicit_self(|mutability| { + if mutability != m_imm { + self.obsolete(*self.last_span, ObsoleteMutOwnedPointer); + } + sty_uniq + }, self) } token::IDENT(*) if self.is_self_ident() => { self.bump(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 9a1682bf063d..978561eaa67c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1653,6 +1653,7 @@ pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool { match explicit_self { ast::sty_static => { return false; } ast::sty_value => { word(s.s, "self"); } + ast::sty_uniq => { word(s.s, "~self"); } ast::sty_region(lt, m) => { word(s.s, "&"); print_opt_lifetime(s, lt); @@ -1662,9 +1663,6 @@ pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool { ast::sty_box(m) => { word(s.s, "@"); print_mutability(s, m); word(s.s, "self"); } - ast::sty_uniq(m) => { - word(s.s, "~"); print_mutability(s, m); word(s.s, "self"); - } } return true; } From ba922a4027f407dd28ab0e699837109ca99ff1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 29 Jun 2013 17:45:59 +0200 Subject: [PATCH 290/336] Fix handling of temp cleanups for the "self" argument The code that tried to revoke the cleanup for the self argument tried to use "llself" to do so, but the cleanup might actually be registered with a different ValueRef due to e.g. casting. Currently, this is worked around by early revocation of the cleanup for self in trans_self_arg. To handle this correctly, we have to put the ValueRef for the cleanup into the MethodData, so trans_call_inner can use it to revoke the cleanup when it's actually supposed to. --- src/librustc/middle/trans/callee.rs | 8 +++--- src/librustc/middle/trans/meth.rs | 40 +++++++++++++---------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 6d139130e2be..821f5c7950fe 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -62,6 +62,7 @@ pub struct FnData { pub struct MethodData { llfn: ValueRef, llself: ValueRef, + temp_cleanup: Option, self_ty: ty::t, self_mode: ty::SelfMode, explicit_self: ast::explicit_self_ @@ -646,9 +647,10 @@ pub fn trans_call_inner(in_cx: block, // Now that the arguments have finished evaluating, we need to revoke // the cleanup for the self argument, if it exists match callee.data { - Method(d) if d.self_mode == ty::ByCopy || - d.explicit_self == ast::sty_value => { - revoke_clean(bcx, d.llself); + Method(d) => { + for d.temp_cleanup.iter().advance |&v| { + revoke_clean(bcx, v); + } } _ => {} } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index fa32dd5b93ef..3884a2d03f67 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -129,28 +129,20 @@ pub fn trans_method(ccx: @mut CrateContext, pub fn trans_self_arg(bcx: block, base: @ast::expr, + temp_cleanups: &mut ~[ValueRef], mentry: typeck::method_map_entry) -> Result { let _icx = push_ctxt("impl::trans_self_arg"); - let mut temp_cleanups = ~[]; // self is passed as an opaque box in the environment slot let self_ty = ty::mk_opaque_box(bcx.tcx()); - let result = trans_arg_expr(bcx, - self_ty, - mentry.self_mode, - mentry.explicit_self, - base, - &mut temp_cleanups, - None, - DontAutorefArg); - - // FIXME(#3446)---this is wrong, actually. The temp_cleanups - // should be revoked only after all arguments have been passed. - for temp_cleanups.iter().advance |c| { - revoke_clean(bcx, *c) - } - - return result; + trans_arg_expr(bcx, + self_ty, + mentry.self_mode, + mentry.explicit_self, + base, + temp_cleanups, + None, + DontAutorefArg) } pub fn trans_method_callee(bcx: block, @@ -203,12 +195,14 @@ pub fn trans_method_callee(bcx: block, match origin { typeck::method_static(did) => { let callee_fn = callee::trans_fn_ref(bcx, did, callee_id); - let Result {bcx, val} = trans_self_arg(bcx, this, mentry); + let mut temp_cleanups = ~[]; + let Result {bcx, val} = trans_self_arg(bcx, this, &mut temp_cleanups, mentry); Callee { bcx: bcx, data: Method(MethodData { llfn: callee_fn.llfn, llself: val, + temp_cleanup: temp_cleanups.head_opt().map(|&v| *v), self_ty: node_id_type(bcx, this.id), self_mode: mentry.self_mode, explicit_self: mentry.explicit_self @@ -254,9 +248,8 @@ pub fn trans_method_callee(bcx: block, store, mentry.explicit_self) } - typeck::method_super(*) => { - fail!("method_super should have been handled \ - above") + typeck::method_super(*) => { + fail!("method_super should have been handled above") } } } @@ -413,8 +406,9 @@ pub fn trans_monomorphized_callee(bcx: block, bcx.ccx(), impl_did, mname); // obtain the `self` value: + let mut temp_cleanups = ~[]; let Result {bcx, val: llself_val} = - trans_self_arg(bcx, base, mentry); + trans_self_arg(bcx, base, &mut temp_cleanups, mentry); // create a concatenated set of substitutions which includes // those from the impl and those from the method: @@ -441,6 +435,7 @@ pub fn trans_monomorphized_callee(bcx: block, data: Method(MethodData { llfn: llfn_val, llself: llself_val, + temp_cleanup: temp_cleanups.head_opt().map(|&v| *v), self_ty: node_id_type(bcx, base.id), self_mode: mentry.self_mode, explicit_self: mentry.explicit_self @@ -636,6 +631,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, data: Method(MethodData { llfn: mptr, llself: llself, + temp_cleanup: None, self_ty: ty::mk_opaque_box(bcx.tcx()), self_mode: ty::ByRef, explicit_self: explicit_self From 765a2901d58625f5995c9cf4a32c85b6573e12b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 28 Jun 2013 01:40:27 +0200 Subject: [PATCH 291/336] Avoid double indirection for the "self" arg in methods Currently we pass all "self" arguments by reference, for the pointer variants this means that we end up with double indirection which causes a unnecessary performance hit. The fix itself is pretty straight-forward and just means that "self" needs to be handled like any other argument, except for by-value "self" which still needs to be passed by reference. This is because non-pointer types can't just be stuffed into the environment slot which is used to pass "self". What made things tricky is that there was also a bug in the typechecker where the method map entries are created. For type impls, that stored the base type instead of the actual self-type in the method map, e.g. Foo instead of &Foo for &self. That worked with pass-by-reference, but fails with pass-by-value which needs the real type. Code that makes use of methods seems to be about 10% faster with this change. Also, build times are reduced by about 4%. Fixes #4355, #4402, #5280, #4406 and #7285 --- src/librustc/middle/trans/asm.rs | 3 -- src/librustc/middle/trans/base.rs | 29 +++++++++--------- src/librustc/middle/trans/callee.rs | 33 ++++++++------------ src/librustc/middle/trans/common.rs | 2 +- src/librustc/middle/trans/glue.rs | 14 ++------- src/librustc/middle/trans/inline.rs | 6 ++-- src/librustc/middle/trans/meth.rs | 35 ++++++++++------------ src/librustc/middle/typeck/check/method.rs | 13 +++++--- 8 files changed, 57 insertions(+), 78 deletions(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index a1d1b737f31f..81a69dfca248 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -41,7 +41,6 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, out), ty::ByCopy, - ast::sty_static, out, &mut cleanups, None, @@ -57,7 +56,6 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, e), ty::ByCopy, - ast::sty_static, e, &mut cleanups, None, @@ -79,7 +77,6 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { callee::trans_arg_expr(bcx, expr_ty(bcx, in), ty::ByCopy, - ast::sty_static, in, &mut cleanups, None, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d9fea1213468..60f4096cf9e5 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1626,18 +1626,11 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt, let _icx = push_ctxt("create_llargs_for_fn_args"); match self_arg { - impl_self(tt) => { + impl_self(tt, self_mode) => { cx.llself = Some(ValSelfData { v: cx.llenv, t: tt, - is_owned: false - }); - } - impl_owned_self(tt) => { - cx.llself = Some(ValSelfData { - v: cx.llenv, - t: tt, - is_owned: true + is_copy: self_mode == ty::ByCopy }); } no_self => () @@ -1676,12 +1669,18 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, match fcx.llself { Some(slf) => { - let self_val = PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()); - fcx.llself = Some(ValSelfData {v: self_val, ..slf}); + let self_val = if slf.is_copy + && datum::appropriate_mode(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); + alloc + } else { + PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) + }; - if slf.is_owned { - add_clean(bcx, slf.v, slf.t); - } + fcx.llself = Some(ValSelfData {v: self_val, ..slf}); + add_clean(bcx, self_val, slf.t); } _ => {} } @@ -1758,7 +1757,7 @@ pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) { } } -pub enum self_arg { impl_self(ty::t), impl_owned_self(ty::t), no_self, } +pub enum self_arg { impl_self(ty::t, ty::SelfMode), no_self, } // trans_closure: Builds an LLVM function out of a source function. // If the function closes over its environment a closure will be diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 821f5c7950fe..ffeb4f2754af 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -65,7 +65,6 @@ pub struct MethodData { temp_cleanup: Option, self_ty: ty::t, self_mode: ty::SelfMode, - explicit_self: ast::explicit_self_ } pub enum CalleeData { @@ -645,7 +644,7 @@ pub fn trans_call_inner(in_cx: block, // Now that the arguments have finished evaluating, we need to revoke - // the cleanup for the self argument, if it exists + // the cleanup for the self argument match callee.data { Method(d) => { for d.temp_cleanup.iter().advance |&v| { @@ -771,7 +770,6 @@ pub fn trans_args(cx: block, trans_arg_expr(bcx, arg_tys[i], ty::ByCopy, - ast::sty_static, *arg_expr, &mut temp_cleanups, if i == last { ret_flag } else { None }, @@ -805,7 +803,6 @@ pub enum AutorefArg { pub fn trans_arg_expr(bcx: block, formal_arg_ty: ty::t, self_mode: ty::SelfMode, - ex_self: ast::explicit_self_, arg_expr: @ast::expr, temp_cleanups: &mut ~[ValueRef], ret_flag: Option, @@ -813,10 +810,9 @@ pub fn trans_arg_expr(bcx: block, let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); - debug!("trans_arg_expr(formal_arg_ty=(%s), explicit_self=%? self_mode=%?, arg_expr=%s, \ + debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \ ret_flag=%?)", formal_arg_ty.repr(bcx.tcx()), - ex_self, self_mode, arg_expr.repr(bcx.tcx()), ret_flag.map(|v| bcx.val_to_str(*v))); @@ -876,9 +872,15 @@ pub fn trans_arg_expr(bcx: block, val = arg_datum.to_ref_llval(bcx); } DontAutorefArg => { - match (self_mode, ex_self) { - (ty::ByRef, ast::sty_value) => { - debug!("by value self with type %s, storing to scratch", + match self_mode { + ty::ByRef => { + // This assertion should really be valid, but because + // the explicit self code currently passes by-ref, it + // does not hold. + // + //assert !bcx.ccx().maps.moves_map.contains_key( + // &arg_expr.id); + debug!("by ref arg with type %s, storing to scratch", bcx.ty_to_str(arg_datum.ty)); let scratch = scratch_datum(bcx, arg_datum.ty, false); @@ -895,18 +897,7 @@ pub fn trans_arg_expr(bcx: block, val = scratch.to_ref_llval(bcx); } - (ty::ByRef, _) => { - // This assertion should really be valid, but because - // the explicit self code currently passes by-ref, it - // does not hold. - // - //assert !bcx.ccx().maps.moves_map.contains_key( - // &arg_expr.id); - debug!("by ref arg with type %s", - bcx.ty_to_str(arg_datum.ty)); - val = arg_datum.to_ref_llval(bcx); - } - (ty::ByCopy, _) => { + ty::ByCopy => { if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) || arg_datum.appropriate_mode().is_by_ref() { debug!("by copy arg with type %s, storing to scratch", diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b255f2ca78c7..229cacef2fed 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -125,7 +125,7 @@ pub type ExternMap = HashMap<@str, ValueRef>; pub struct ValSelfData { v: ValueRef, t: ty::t, - is_owned: bool + is_copy: bool, } // Here `self_ty` is the real type of the self parameter to this method. It diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0172b7054659..9ca174d3f2de 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -425,12 +425,7 @@ pub fn trans_struct_drop_flag(bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast: // just consist of the environment (self) assert_eq!(params.len(), 1); - // Take a reference to the class (because it's using the Drop trait), - // do so now. - let llval = alloca(bcx, val_ty(v0)); - Store(bcx, v0, llval); - - let self_arg = PointerCast(bcx, llval, params[0]); + let self_arg = PointerCast(bcx, v0, params[0]); let args = ~[self_arg]; Call(bcx, dtor_addr, args); @@ -465,12 +460,7 @@ pub fn trans_struct_drop(mut bcx: block, t: ty::t, v0: ValueRef, dtor_did: ast:: // just consist of the environment (self) assert_eq!(params.len(), 1); - // Take a reference to the class (because it's using the Drop trait), - // do so now. - let llval = alloca(bcx, val_ty(v0)); - Store(bcx, v0, llval); - - let self_arg = PointerCast(bcx, llval, params[0]); + let self_arg = PointerCast(bcx, v0, params[0]); let args = ~[self_arg]; Call(bcx, dtor_addr, args); diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 11c02f165b6f..0d7b5d5ed5af 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -12,7 +12,7 @@ use core::prelude::*; use metadata::csearch; use middle::astencode; -use middle::trans::base::{push_ctxt,impl_owned_self, impl_self, no_self}; +use middle::trans::base::{push_ctxt, impl_self, no_self}; use middle::trans::base::{trans_item, get_item_val, trans_fn}; use middle::trans::common::*; use middle::ty; @@ -114,8 +114,8 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, debug!("calling inline trans_fn with self_ty %s", ty_to_str(ccx.tcx, self_ty)); match mth.explicit_self.node { - ast::sty_value => impl_owned_self(self_ty), - _ => impl_self(self_ty), + ast::sty_value => impl_self(self_ty, ty::ByRef), + _ => impl_self(self_ty, ty::ByCopy), } } }; diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 3884a2d03f67..845ca34ce541 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -20,6 +20,7 @@ use middle::trans::build::*; use middle::trans::callee::*; use middle::trans::callee; use middle::trans::common::*; +use middle::trans::datum::*; use middle::trans::expr::{SaveIn, Ignore}; use middle::trans::expr; use middle::trans::glue; @@ -107,10 +108,8 @@ pub fn trans_method(ccx: @mut CrateContext, debug!("calling trans_fn with self_ty %s", self_ty.repr(ccx.tcx)); match method.explicit_self.node { - ast::sty_value => impl_owned_self(self_ty), - _ => { - impl_self(self_ty) - } + ast::sty_value => impl_self(self_ty, ty::ByRef), + _ => impl_self(self_ty, ty::ByCopy), } } }; @@ -138,7 +137,6 @@ pub fn trans_self_arg(bcx: block, trans_arg_expr(bcx, self_ty, mentry.self_mode, - mentry.explicit_self, base, temp_cleanups, None, @@ -205,7 +203,6 @@ pub fn trans_method_callee(bcx: block, temp_cleanup: temp_cleanups.head_opt().map(|&v| *v), self_ty: node_id_type(bcx, this.id), self_mode: mentry.self_mode, - explicit_self: mentry.explicit_self }) } } @@ -438,7 +435,6 @@ pub fn trans_monomorphized_callee(bcx: block, temp_cleanup: temp_cleanups.head_opt().map(|&v| *v), self_ty: node_id_type(bcx, base.id), self_mode: mentry.self_mode, - explicit_self: mentry.explicit_self }) } } @@ -568,7 +564,8 @@ pub fn trans_trait_callee_from_llval(bcx: block, // necessary: let mut llself; debug!("(translating trait callee) loading second index from pair"); - let llbox = Load(bcx, GEPi(bcx, llpair, [0u, abi::trt_field_box])); + let llboxptr = GEPi(bcx, llpair, [0u, abi::trt_field_box]); + let llbox = Load(bcx, llboxptr); // Munge `llself` appropriately for the type of `self` in the method. match explicit_self { @@ -580,8 +577,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, called on objects"); } ast::sty_region(*) => { - // As before, we need to pass a pointer to a pointer to the - // payload. match store { ty::BoxTraitStore | ty::UniqTraitStore => { @@ -596,7 +591,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Bump the reference count on the box. debug!("(translating trait callee) callee type is `%s`", bcx.ty_to_str(callee_ty)); - bcx = glue::take_ty(bcx, llbox, callee_ty); + glue::incr_refcnt_of_boxed(bcx, llbox); // Pass a pointer to the box. match store { @@ -610,12 +605,15 @@ pub fn trans_trait_callee_from_llval(bcx: block, ty::UniqTraitStore => llself = llbox, _ => bcx.tcx().sess.bug("~self receiver with non-~Trait") } + + zero_mem(bcx, llboxptr, ty::mk_opaque_box(bcx.tcx())); } } - let llscratch = alloca(bcx, val_ty(llself)); - Store(bcx, llself, llscratch); - llself = PointerCast(bcx, llscratch, Type::opaque_box(ccx).ptr_to()); + llself = PointerCast(bcx, llself, Type::opaque_box(ccx).ptr_to()); + let scratch = scratch_datum(bcx, ty::mk_opaque_box(bcx.tcx()), false); + Store(bcx, llself, scratch.val); + scratch.add_clean(bcx); // Load the function from the vtable and cast it to the expected type. debug!("(translating trait callee) loading method"); @@ -630,11 +628,10 @@ pub fn trans_trait_callee_from_llval(bcx: block, bcx: bcx, data: Method(MethodData { llfn: mptr, - llself: llself, - temp_cleanup: None, - self_ty: ty::mk_opaque_box(bcx.tcx()), - self_mode: ty::ByRef, - explicit_self: explicit_self + llself: scratch.to_value_llval(bcx), + temp_cleanup: Some(scratch.val), + self_ty: scratch.ty, + self_mode: ty::ByCopy, /* XXX: Some(llbox) */ }) }; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 4bebca3c9a8b..2fb8209ecf2a 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -976,9 +976,7 @@ impl<'self> LookupContext<'self> { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty}); debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty)); - // FIXME(#7411): We always pass self by-ref since we stuff it in the environment slot. - // Eventually that should not be the case - let self_mode = ty::ByRef; + let self_mode = get_mode_from_explicit_self(candidate.method_ty.explicit_self); // before we only checked whether self_ty could be a subtype // of rcvr_ty; now we actually make it so (this may cause @@ -998,7 +996,7 @@ impl<'self> LookupContext<'self> { self.fcx.write_ty(self.callee_id, fty); self.fcx.write_substs(self.callee_id, all_substs); method_map_entry { - self_ty: candidate.rcvr_ty, + self_ty: rcvr_ty, self_mode: self_mode, explicit_self: candidate.method_ty.explicit_self, origin: candidate.origin, @@ -1253,3 +1251,10 @@ impl<'self> LookupContext<'self> { self.tcx().sess.bug(s) } } + +pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode { + match explicit_self { + sty_value => ty::ByRef, + _ => ty::ByCopy, + } +} From d820355213d433c85ef49bae03022d754ca2f5d5 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 29 Jun 2013 02:43:51 -0400 Subject: [PATCH 292/336] fix code block syntax in two docstrings --- src/libstd/iterator.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 976ca8bae7a8..55eae8f8fae1 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -356,20 +356,20 @@ pub trait IteratorUtil { /// /// # Example /// - /// --- {.rust} + /// ~~~ {.rust} /// let xs = [-3, 0, 1, 5, -10]; /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); - /// --- + /// ~~~ fn max_by(&mut self, f: &fn(&A) -> B) -> Option; /// Return the element that gives the minimum value from the specfied function /// /// # Example /// - /// --- {.rust} + /// ~~~ {.rust} /// let xs = [-3, 0, 1, 5, -10]; /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); - /// --- + /// ~~~ fn min_by(&mut self, f: &fn(&A) -> B) -> Option; } From eee7accedb4b529dac67b2a50c4e25e3f47777d8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 28 Jun 2013 20:34:06 +0200 Subject: [PATCH 293/336] Add -v/--version support to rust binary --- src/librust/rust.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librust/rust.rs b/src/librust/rust.rs index ba5e592b605c..6542afe678b1 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -238,6 +238,12 @@ fn usage() { pub fn main() { let os_args = os::args(); + + if (os_args.len() > 1 && (os_args[1] == ~"-v" || os_args[1] == ~"--version")) { + rustc::version(os_args[0]); + unsafe { exit(0); } + } + let args = os_args.tail(); if !args.is_empty() { From 052f28a8083c624a8f0a892893f9a059906e15c5 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 28 Jun 2013 23:44:55 -0400 Subject: [PATCH 294/336] minor vec cleanup * hide the rustrt module in the docs * remove the useless `traits` module wrapping the `Add` impl --- src/libstd/vec.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 4196fbac0beb..cff4ac10145c 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -23,6 +23,7 @@ use iter::FromIter; use kinds::Copy; use libc; use num::Zero; +use ops::Add; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; @@ -40,6 +41,7 @@ use util; #[cfg(not(test))] use cmp::Equiv; +#[doc(hidden)] pub mod rustrt { use libc; use vec::raw; @@ -1180,16 +1182,10 @@ impl Ord for @[T] { } #[cfg(not(test))] -pub mod traits { - use kinds::Copy; - use ops::Add; - use vec::append; - - impl<'self,T:Copy> Add<&'self [T],~[T]> for ~[T] { - #[inline] - fn add(&self, rhs: & &'self [T]) -> ~[T] { - append(copy *self, (*rhs)) - } +impl<'self,T:Copy> Add<&'self [T], ~[T]> for ~[T] { + #[inline] + fn add(&self, rhs: & &'self [T]) -> ~[T] { + append(copy *self, (*rhs)) } } From 7bcde87d1baccc857f766d01444e3dd172d92226 Mon Sep 17 00:00:00 2001 From: jihyun Date: Fri, 28 Jun 2013 09:27:56 +0900 Subject: [PATCH 295/336] Fixes #7377 --- src/librustc/middle/resolve.rs | 21 +++++++++++++++++++ .../compile-fail/struct-fields-decl-dupe.rs | 17 +++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/compile-fail/struct-fields-decl-dupe.rs diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index e06fd8f97179..78fb924452a5 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3886,6 +3886,27 @@ impl Resolver { generics: &Generics, fields: &[@struct_field], visitor: ResolveVisitor) { + let mut ident_map = HashMap::new::(); + for fields.iter().advance |&field| { + match field.node.kind { + named_field(ident, _) => { + match ident_map.find(&ident) { + Some(&prev_field) => { + let ident_str = self.session.str_of(ident); + self.session.span_err(field.span, + fmt!("field `%s` is already declared", ident_str)); + self.session.span_note(prev_field.span, + "Previously declared here"); + }, + None => { + ident_map.insert(ident, field); + } + } + } + _ => () + } + } + // If applicable, create a rib for the type parameters. do self.with_type_parameter_rib(HasTypeParameters (generics, id, 0, diff --git a/src/test/compile-fail/struct-fields-decl-dupe.rs b/src/test/compile-fail/struct-fields-decl-dupe.rs new file mode 100644 index 000000000000..78216d5f4af6 --- /dev/null +++ b/src/test/compile-fail/struct-fields-decl-dupe.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. + +struct BuildData { + foo: int, + foo: int, //~ ERROR field `foo` is already declared +} + +fn main() { +} From 0a3f6bc1302dc43c5e5671611b36e7959d7381a5 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Sun, 30 Jun 2013 12:54:17 +0900 Subject: [PATCH 296/336] mk: clean-llvm for cross-compile --- mk/clean.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/clean.mk b/mk/clean.mk index 32dd3902b1fe..fcb6a2b42902 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -20,7 +20,7 @@ CLEAN_STAGE_RULES = \ clean$(stage)_T_$(target)_H_$(host)))) CLEAN_LLVM_RULES = \ - $(foreach target, $(CFG_TARGET_TRIPLES), \ + $(foreach target, $(CFG_HOST_TRIPLES), \ clean-llvm$(target)) .PHONY: clean clean-all clean-misc clean-llvm From b883d6a54c460f8357b1107b3599108eb1f8580b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 29 Jun 2013 22:35:04 -0400 Subject: [PATCH 297/336] simplify the exchange allocator * stop using an atomic counter, this has a significant cost and valgrind will already catch these leaks * remove the extra layer of function calls * remove the assert of non-null in free, freeing null is well defined but throwing a failure from free will not be * stop initializing the `prev`/`next` pointers * abort on out-of-memory, failing won't necessarily work --- src/libstd/os.rs | 6 +- src/libstd/rt/global_heap.rs | 94 ++++++++++++--------------- src/libstd/unstable/exchange_alloc.rs | 83 ----------------------- src/libstd/unstable/lang.rs | 17 ----- src/rt/rust_exchange_alloc.cpp | 16 ----- src/rt/rust_exchange_alloc.h | 6 -- src/rt/rust_kernel.cpp | 1 - src/rt/rustrt.def.in | 1 - 8 files changed, 44 insertions(+), 180 deletions(-) delete mode 100644 src/libstd/unstable/exchange_alloc.rs diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 1fbcda12dce1..9b74754d7110 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -730,7 +730,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { #[cfg(windows)] unsafe fn get_list(p: &Path) -> ~[~str] { use libc::consts::os::extra::INVALID_HANDLE_VALUE; - use libc::wcslen; + use libc::{wcslen, free}; use libc::funcs::extra::kernel32::{ FindFirstFileW, FindNextFileW, @@ -739,7 +739,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { use os::win32::{ as_utf16_p }; - use rt::global_heap::{malloc_raw, free_raw}; + use rt::global_heap::malloc_raw; #[nolink] extern { unsafe fn rust_list_dir_wfd_size() -> libc::size_t; @@ -772,7 +772,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { ::cast::transmute(wfd_ptr)); } FindClose(find_handle); - free_raw(wfd_ptr); + free(wfd_ptr) } strings } diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 1e9f9aab8345..3994b722f592 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -8,62 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use sys::{size_of}; -use libc::{c_void, size_t, uintptr_t}; -use c_malloc = libc::malloc; -use c_free = libc::free; +use libc::{c_char, c_void, size_t, uintptr_t, free, malloc}; use managed::raw::{BoxHeaderRepr, BoxRepr}; -use cast::transmute; -use unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc}; -use ptr::null; +use unstable::intrinsics::TyDesc; +use sys::size_of; -pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { - assert!(td.is_not_null()); - - let total_size = get_box_size(size, (*td).align); - let p = c_malloc(total_size as size_t); - assert!(p.is_not_null()); - - let box: &mut BoxRepr = transmute(p); - box.header.ref_count = -1; // Exchange values not ref counted - box.header.type_desc = td; - box.header.prev = null(); - box.header.next = null(); - - let exchange_count = &mut *exchange_count_ptr(); - atomic_xadd(exchange_count, 1); - - return transmute(box); -} -/** -Thin wrapper around libc::malloc, none of the box header -stuff in exchange_alloc::malloc -*/ -pub unsafe fn malloc_raw(size: uint) -> *c_void { - let p = c_malloc(size as size_t); - if p.is_null() { - fail!("Failure in malloc_raw: result ptr is null"); - } - p -} - -pub unsafe fn free(ptr: *c_void) { - let exchange_count = &mut *exchange_count_ptr(); - atomic_xsub(exchange_count, 1); - - assert!(ptr.is_not_null()); - c_free(ptr); -} -///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw -pub unsafe fn free_raw(ptr: *c_void) { - c_free(ptr); +extern { + #[rust_stack] + fn abort(); } fn get_box_size(body_size: uint, body_align: uint) -> uint { let header_size = size_of::(); // FIXME (#2699): This alignment calculation is suspicious. Is it right? let total_size = align_to(header_size, body_align) + body_size; - return total_size; + total_size } // Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power @@ -73,11 +32,40 @@ fn align_to(size: uint, align: uint) -> uint { (size + align - 1) & !(align - 1) } -fn exchange_count_ptr() -> *mut int { - // XXX: Need mutable globals - unsafe { transmute(&rust_exchange_count) } +/// A wrapper around libc::malloc, aborting on out-of-memory +pub unsafe fn malloc_raw(size: uint) -> *c_void { + let p = malloc(size as size_t); + if p.is_null() { + // we need a non-allocating way to print an error here + abort(); + } + p } -extern { - static rust_exchange_count: uintptr_t; +// FIXME #4942: Make these signatures agree with exchange_alloc's signatures +#[lang="exchange_malloc"] +#[inline] +pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { + let td = td as *TyDesc; + let size = size as uint; + + assert!(td.is_not_null()); + + let total_size = get_box_size(size, (*td).align); + let p = malloc_raw(total_size as uint); + + let box: *mut BoxRepr = p as *mut BoxRepr; + (*box).header.ref_count = -1; // Exchange values not ref counted + (*box).header.type_desc = td; + + box as *c_char +} + +// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from +// inside a landing pad may corrupt the state of the exception handler. +#[cfg(not(test))] +#[lang="exchange_free"] +#[inline] +pub unsafe fn exchange_free(ptr: *c_char) { + free(ptr as *c_void); } diff --git a/src/libstd/unstable/exchange_alloc.rs b/src/libstd/unstable/exchange_alloc.rs deleted file mode 100644 index 5c47901df480..000000000000 --- a/src/libstd/unstable/exchange_alloc.rs +++ /dev/null @@ -1,83 +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. - -use sys::size_of; -use libc::{c_void, size_t}; -use c_malloc = libc::malloc; -use c_free = libc::free; -use managed::raw::{BoxHeaderRepr, BoxRepr}; -use cast::transmute; -use unstable::intrinsics::{atomic_xadd,atomic_xsub}; -use ptr::null; -#[cfg(stage0)] -use intrinsic::TyDesc; -#[cfg(not(stage0))] -use unstable::intrinsics::TyDesc; - -pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void { - assert!(td.is_not_null()); - - let total_size = get_box_size(size, (*td).align); - let p = c_malloc(total_size as size_t); - assert!(p.is_not_null()); - - let box: &mut BoxRepr = transmute(p); - box.header.ref_count = -1; // Exchange values not ref counted - box.header.type_desc = td; - box.header.prev = null(); - box.header.next = null(); - - let exchange_count = &mut *rust_get_exchange_count_ptr(); - atomic_xadd(exchange_count, 1); - - return transmute(box); -} -/** -Thin wrapper around libc::malloc, none of the box header -stuff in exchange_alloc::malloc -*/ -pub unsafe fn malloc_raw(size: uint) -> *c_void { - let p = c_malloc(size as size_t); - if p.is_null() { - fail!("Failure in malloc_raw: result ptr is null"); - } - p -} - -pub unsafe fn free(ptr: *c_void) { - let exchange_count = &mut *rust_get_exchange_count_ptr(); - atomic_xsub(exchange_count, 1); - - assert!(ptr.is_not_null()); - c_free(ptr); -} -///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw -pub unsafe fn free_raw(ptr: *c_void) { - c_free(ptr); -} - -fn get_box_size(body_size: uint, body_align: uint) -> uint { - let header_size = size_of::(); - // FIXME (#2699): This alignment calculation is suspicious. Is it right? - let total_size = align_to(header_size, body_align) + body_size; - return total_size; -} - -// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power -// of two. -fn align_to(size: uint, align: uint) -> uint { - assert!(align != 0); - (size + align - 1) & !(align - 1) -} - -extern { - #[rust_stack] - fn rust_get_exchange_count_ptr() -> *mut int; -} diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index d37579b0c47c..fddd847af341 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -22,7 +22,6 @@ use rt::task::Task; use rt::local::Local; use option::{Option, Some, None}; use io; -use rt::global_heap; #[allow(non_camel_case_types)] pub type rust_task = c_void; @@ -150,13 +149,6 @@ unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) { } } -// FIXME #4942: Make these signatures agree with exchange_alloc's signatures -#[lang="exchange_malloc"] -#[inline] -pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { - transmute(global_heap::malloc(transmute(td), transmute(size))) -} - /// Because this code is so perf. sensitive, use a static constant so that /// debug printouts are compiled out most of the time. static ENABLE_DEBUG: bool = false; @@ -228,15 +220,6 @@ impl DebugPrints for io::fd_t { } } -// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from -// inside a landing pad may corrupt the state of the exception handler. If a -// problem occurs, call exit instead. -#[lang="exchange_free"] -#[inline] -pub unsafe fn exchange_free(ptr: *c_char) { - global_heap::free(transmute(ptr)) -} - #[lang="malloc"] pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char { match context() { diff --git a/src/rt/rust_exchange_alloc.cpp b/src/rt/rust_exchange_alloc.cpp index 89257dc9f6e4..658d97031ce0 100644 --- a/src/rt/rust_exchange_alloc.cpp +++ b/src/rt/rust_exchange_alloc.cpp @@ -15,16 +15,10 @@ #include #include -extern uintptr_t rust_exchange_count; -uintptr_t rust_exchange_count = 0; - void * rust_exchange_alloc::malloc(size_t size) { void *value = ::malloc(size); assert(value); - - sync::increment(rust_exchange_count); - return value; } @@ -37,15 +31,5 @@ rust_exchange_alloc::realloc(void *ptr, size_t size) { void rust_exchange_alloc::free(void *ptr) { - sync::decrement(rust_exchange_count); ::free(ptr); } - -void -rust_check_exchange_count_on_exit() { - if (rust_exchange_count != 0) { - printf("exchange heap not empty on exit\n"); - printf("%d dangling allocations\n", (int)rust_exchange_count); - abort(); - } -} diff --git a/src/rt/rust_exchange_alloc.h b/src/rt/rust_exchange_alloc.h index 767caf013234..9699ef6b5e9d 100644 --- a/src/rt/rust_exchange_alloc.h +++ b/src/rt/rust_exchange_alloc.h @@ -21,10 +21,4 @@ class rust_exchange_alloc { void free(void *mem); }; -extern "C" uintptr_t * -rust_get_exchange_count_ptr(); - -void -rust_check_exchange_count_on_exit(); - #endif diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index c1c40222f1a3..583f836c0d66 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -211,7 +211,6 @@ rust_kernel::run() { assert(osmain_driver != NULL); osmain_driver->start_main_loop(); sched_reaper.join(); - rust_check_exchange_count_on_exit(); return rval; } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index a4876618c971..b572f1aba6a5 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -196,7 +196,6 @@ rust_register_exit_function rust_get_global_data_ptr rust_inc_kernel_live_count rust_dec_kernel_live_count -rust_exchange_count rust_get_rt_tls_key swap_registers rust_readdir From b91416214ed0e24b780dec8608a122b6b3a943f5 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 29 Jun 2013 22:36:27 -0400 Subject: [PATCH 298/336] add a contains_managed intrinsic --- src/librustc/middle/trans/foreign.rs | 6 ++++++ src/librustc/middle/trans/type_use.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 2 +- src/libstd/unstable/intrinsics.rs | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7672f3b615d0..5dcd6927fa10 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -751,6 +751,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), fcx.llretptr.get()); } + "contains_managed" => { + let tp_ty = substs.tys[0]; + Store(bcx, + C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()), + fcx.llretptr.get()); + } "visit_tydesc" => { let td = get_param(decl, first_real_arg); let visitor = get_param(decl, first_real_arg + 1u); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index d8d539764620..5544751529ce 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -127,7 +127,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) "uninit" | "init" | "transmute" | "move_val" | "move_val_init" => use_repr, - "get_tydesc" | "needs_drop" => use_tydesc, + "get_tydesc" | "needs_drop" | "contains_managed" => use_tydesc, "visit_tydesc" | "forget" | "frame_address" | "morestack_addr" => 0, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 0cd9aac37989..8a280374ebf5 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3540,7 +3540,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { ty::mk_nil()) } "needs_drop" => (1u, ~[], ty::mk_bool()), - + "contains_managed" => (1u, ~[], ty::mk_bool()), "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 1254a5912932..500143fb5777 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -308,6 +308,10 @@ pub extern "rust-intrinsic" { /// Returns `true` if a type requires drop glue. pub fn needs_drop() -> bool; + /// Returns `true` if a type is managed (will be allocated on the local heap) + #[cfg(not(stage0))] + pub fn contains_managed() -> bool; + #[cfg(not(stage0))] pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); From 350a5c0b722038a3743058a7a824cfa6ac7094da Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 29 Jun 2013 22:40:40 -0400 Subject: [PATCH 299/336] vec: use contains_managed instead of box header --- src/libstd/vec.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 4196fbac0beb..009c84a4a6e9 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -34,7 +34,7 @@ use unstable::intrinsics; #[cfg(stage0)] use intrinsic::{get_tydesc}; #[cfg(not(stage0))] -use unstable::intrinsics::{get_tydesc}; +use unstable::intrinsics::{get_tydesc, contains_managed}; use vec; use util; @@ -1521,6 +1521,7 @@ impl OwnedVector for ~[T] { * * n - The number of elements to reserve space for */ #[inline] + #[cfg(stage0)] fn reserve(&mut self, n: uint) { // Only make the (slow) call into the runtime if we have to use managed; @@ -1538,6 +1539,33 @@ impl OwnedVector for ~[T] { } } + /** + * Reserves capacity for exactly `n` elements in the given vector. + * + * If the capacity for `self` is already equal to or greater than the requested + * capacity, then no action is taken. + * + * # Arguments + * + * * n - The number of elements to reserve space for + */ + #[inline] + #[cfg(not(stage0))] + fn reserve(&mut self, n: uint) { + // Only make the (slow) call into the runtime if we have to + if self.capacity() < n { + unsafe { + let ptr: **raw::VecRepr = cast::transmute(self); + let td = get_tydesc::(); + if contains_managed::() { + rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); + } else { + rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); + } + } + } + } + /** * Reserves capacity for at least `n` elements in the given vector. * From 5d46bcc0e40c51b8acbf708971c2ecc51c57c0a3 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 00:59:41 +1000 Subject: [PATCH 300/336] Remove vec::{rfind, rfind_between, find_between}, replaced by slices and iterator adapators. --- src/librustc/middle/trans/base.rs | 2 +- src/libstd/vec.rs | 119 ------------------------------ 2 files changed, 1 insertion(+), 120 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f210a9eb3b72..90d0ee251976 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1263,7 +1263,7 @@ pub fn cleanup_and_leave(bcx: block, let mut skip = 0; let mut dest = None; { - let r = vec::rfind((*inf).cleanup_paths, |cp| cp.target == leave); + 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); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index cff4ac10145c..07319cbd148c 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -652,44 +652,6 @@ pub fn contains(v: &[T], x: &T) -> bool { false } -/** - * Search for the first element that matches a given predicate within a range - * - * Apply function `f` to each element of `v` within the range - * [`start`, `end`). When function `f` returns true then an option containing - * the element is returned. If `f` matches no elements then none is returned. - */ -pub fn find_between(v: &[T], start: uint, end: uint, - f: &fn(t: &T) -> bool) -> Option { - position_between(v, start, end, f).map(|i| copy v[*i]) -} - -/** - * Search for the last element that matches a given predicate - * - * Apply function `f` to each element of `v` in reverse order. When function - * `f` returns true then an option containing the element is returned. If `f` - * matches no elements then none is returned. - */ -pub fn rfind(v: &[T], f: &fn(t: &T) -> bool) -> Option { - rfind_between(v, 0u, v.len(), f) -} - -/** - * Search for the last element that matches a given predicate within a range - * - * Apply function `f` to each element of `v` in reverse order within the range - * [`start`, `end`). When function `f` returns true then an option containing - * the element is returned. If `f` matches no elements then none is return. - */ -pub fn rfind_between(v: &[T], - start: uint, - end: uint, - f: &fn(t: &T) -> bool) - -> Option { - rposition_between(v, start, end, f).map(|i| copy v[*i]) -} - /// Find the first index containing a matching value pub fn position_elem(v: &[T], x: &T) -> Option { v.iter().position_(|y| *x == *y) @@ -1422,7 +1384,6 @@ impl<'self,T:Eq> ImmutableEqVector for &'self [T] { #[allow(missing_doc)] pub trait ImmutableCopyableVector { fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; - fn rfind(&self, f: &fn(t: &T) -> bool) -> Option; fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); unsafe fn unsafe_get(&self, elem: uint) -> T; } @@ -1441,18 +1402,6 @@ impl<'self,T:Copy> ImmutableCopyableVector for &'self [T] { filtered(*self, f) } - /** - * Search for the last element that matches a given predicate - * - * Apply function `f` to each element of `v` in reverse order. When - * function `f` returns true then an option containing the element is - * returned. If `f` matches no elements then none is returned. - */ - #[inline] - fn rfind(&self, f: &fn(t: &T) -> bool) -> Option { - rfind(*self, f) - } - /** * Partitions the vector into those that satisfies the predicate, and * those that do not. @@ -2964,34 +2913,6 @@ mod tests { assert!(position_between(v, 4u, 4u, f).is_none()); } - #[test] - fn test_find_between() { - assert!(find_between([], 0u, 0u, f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert!(find_between(v, 0u, 0u, f).is_none()); - assert!(find_between(v, 0u, 1u, f).is_none()); - assert_eq!(find_between(v, 0u, 2u, f), Some((1, 'b'))); - assert_eq!(find_between(v, 0u, 3u, f), Some((1, 'b'))); - assert_eq!(find_between(v, 0u, 4u, f), Some((1, 'b'))); - - assert!(find_between(v, 1u, 1u, f).is_none()); - assert_eq!(find_between(v, 1u, 2u, f), Some((1, 'b'))); - assert_eq!(find_between(v, 1u, 3u, f), Some((1, 'b'))); - assert_eq!(find_between(v, 1u, 4u, f), Some((1, 'b'))); - - assert!(find_between(v, 2u, 2u, f).is_none()); - assert!(find_between(v, 2u, 3u, f).is_none()); - assert_eq!(find_between(v, 2u, 4u, f), Some((3, 'b'))); - - assert!(find_between(v, 3u, 3u, f).is_none()); - assert_eq!(find_between(v, 3u, 4u, f), Some((3, 'b'))); - - assert!(find_between(v, 4u, 4u, f).is_none()); - } - #[test] fn test_rposition() { fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } @@ -3030,46 +2951,6 @@ mod tests { assert!(rposition_between(v, 4u, 4u, f).is_none()); } - #[test] - fn test_rfind() { - assert!(rfind([], f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert_eq!(rfind(v, f), Some((3, 'b'))); - assert!(rfind(v, g).is_none()); - } - - #[test] - fn test_rfind_between() { - assert!(rfind_between([], 0u, 0u, f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert!(rfind_between(v, 0u, 0u, f).is_none()); - assert!(rfind_between(v, 0u, 1u, f).is_none()); - assert_eq!(rfind_between(v, 0u, 2u, f), Some((1, 'b'))); - assert_eq!(rfind_between(v, 0u, 3u, f), Some((1, 'b'))); - assert_eq!(rfind_between(v, 0u, 4u, f), Some((3, 'b'))); - - assert!(rfind_between(v, 1u, 1u, f).is_none()); - assert_eq!(rfind_between(v, 1u, 2u, f), Some((1, 'b'))); - assert_eq!(rfind_between(v, 1u, 3u, f), Some((1, 'b'))); - assert_eq!(rfind_between(v, 1u, 4u, f), Some((3, 'b'))); - - assert!(rfind_between(v, 2u, 2u, f).is_none()); - assert!(rfind_between(v, 2u, 3u, f).is_none()); - assert_eq!(rfind_between(v, 2u, 4u, f), Some((3, 'b'))); - - assert!(rfind_between(v, 3u, 3u, f).is_none()); - assert_eq!(rfind_between(v, 3u, 4u, f), Some((3, 'b'))); - - assert!(rfind_between(v, 4u, 4u, f).is_none()); - } - #[test] fn test_bsearch_elem() { assert_eq!(bsearch_elem([1,2,3,4,5], &5), Some(4)); From 45940ed988ab2d04e1dbecceef440071b04c11a9 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 01:33:23 +1000 Subject: [PATCH 301/336] Remove vec::[r]position_between, replaced by slices & iterators. --- src/libextra/terminfo/parser/compiled.rs | 9 +- src/libstd/vec.rs | 110 ++--------------------- 2 files changed, 13 insertions(+), 106 deletions(-) diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs index 2f36845d79b7..063d26d1424b 100644 --- a/src/libextra/terminfo/parser/compiled.rs +++ b/src/libextra/terminfo/parser/compiled.rs @@ -291,12 +291,13 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> { // Find the offset of the NUL we want to go to - let nulpos = vec::position_between(string_table, offset as uint, - string_table_bytes as uint, |&b| b == 0); + let nulpos = string_table.slice(offset as uint, string_table_bytes as uint) + .iter().position_(|&b| b == 0); match nulpos { - Some(x) => { + Some(len) => { string_map.insert(name.to_owned(), - string_table.slice(offset as uint, x).to_owned()) + string_table.slice(offset as uint, + offset as uint + len).to_owned()) }, None => { return Err(~"invalid file: missing NUL in string_table"); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 07319cbd148c..a704e604aa28 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -193,11 +193,11 @@ pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut start = 0u; let mut result = ~[]; while start < ln { - match position_between(v, start, ln, |t| f(t)) { + match v.slice(start, ln).iter().position_(|t| f(t)) { None => break, Some(i) => { - result.push(v.slice(start, i).to_owned()); - start = i + 1u; + result.push(v.slice(start, start + i).to_owned()); + start += i + 1u; } } } @@ -217,7 +217,7 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while start < ln && count > 0u { - match position_between(v, start, ln, |t| f(t)) { + match v.slice(start, ln).iter().position_(|t| f(t)) { None => break, Some(i) => { result.push(v.slice(start, i).to_owned()); @@ -242,7 +242,7 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut end = ln; let mut result = ~[]; while end > 0 { - match rposition_between(v, 0, end, |t| f(t)) { + match v.slice(0, end).rposition(|t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1, end).to_owned()); @@ -267,7 +267,7 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while end > 0u && count > 0u { - match rposition_between(v, 0u, end, |t| f(t)) { + match v.slice(0, end).rposition(|t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1u, end).to_owned()); @@ -657,25 +657,6 @@ pub fn position_elem(v: &[T], x: &T) -> Option { v.iter().position_(|y| *x == *y) } -/** - * Find the first index matching some predicate within a range - * - * Apply function `f` to each element of `v` between the range - * [`start`, `end`). When function `f` returns true then an option containing - * the index is returned. If `f` matches no elements then none is returned. - */ -pub fn position_between(v: &[T], - start: uint, - end: uint, - f: &fn(t: &T) -> bool) - -> Option { - assert!(start <= end); - assert!(end <= v.len()); - let mut i = start; - while i < end { if f(&v[i]) { return Some::(i); } i += 1u; } - None -} - /// Find the last index containing a matching value pub fn rposition_elem(v: &[T], x: &T) -> Option { rposition(v, |y| *x == *y) @@ -689,31 +670,12 @@ pub fn rposition_elem(v: &[T], x: &T) -> Option { * matches no elements then none is returned. */ pub fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { - rposition_between(v, 0u, v.len(), f) -} - -/** - * Find the last index matching some predicate within a range - * - * Apply function `f` to each element of `v` in reverse order between the - * range [`start`, `end`). When function `f` returns true then an option - * containing the index is returned. If `f` matches no elements then none is - * returned. - */ -pub fn rposition_between(v: &[T], start: uint, end: uint, - f: &fn(t: &T) -> bool) -> Option { - assert!(start <= end); - assert!(end <= v.len()); - let mut i = end; - while i > start { - if f(&v[i - 1u]) { return Some::(i - 1u); } - i -= 1u; + for v.rev_iter().enumerate().advance |(i, t)| { + if f(t) { return Some(v.len() - i - 1); } } None } - - /** * Binary search a sorted vector with a comparator function. * @@ -2885,34 +2847,6 @@ mod tests { assert!(position_elem(v1, &4).is_none()); } - #[test] - fn test_position_between() { - assert!(position_between([], 0u, 0u, f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert!(position_between(v, 0u, 0u, f).is_none()); - assert!(position_between(v, 0u, 1u, f).is_none()); - assert_eq!(position_between(v, 0u, 2u, f), Some(1u)); - assert_eq!(position_between(v, 0u, 3u, f), Some(1u)); - assert_eq!(position_between(v, 0u, 4u, f), Some(1u)); - - assert!(position_between(v, 1u, 1u, f).is_none()); - assert_eq!(position_between(v, 1u, 2u, f), Some(1u)); - assert_eq!(position_between(v, 1u, 3u, f), Some(1u)); - assert_eq!(position_between(v, 1u, 4u, f), Some(1u)); - - assert!(position_between(v, 2u, 2u, f).is_none()); - assert!(position_between(v, 2u, 3u, f).is_none()); - assert_eq!(position_between(v, 2u, 4u, f), Some(3u)); - - assert!(position_between(v, 3u, 3u, f).is_none()); - assert_eq!(position_between(v, 3u, 4u, f), Some(3u)); - - assert!(position_between(v, 4u, 4u, f).is_none()); - } - #[test] fn test_rposition() { fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } @@ -2923,34 +2857,6 @@ mod tests { assert!(rposition(v, g).is_none()); } - #[test] - fn test_rposition_between() { - assert!(rposition_between([], 0u, 0u, f).is_none()); - - fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } - let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - - assert!(rposition_between(v, 0u, 0u, f).is_none()); - assert!(rposition_between(v, 0u, 1u, f).is_none()); - assert_eq!(rposition_between(v, 0u, 2u, f), Some(1u)); - assert_eq!(rposition_between(v, 0u, 3u, f), Some(1u)); - assert_eq!(rposition_between(v, 0u, 4u, f), Some(3u)); - - assert!(rposition_between(v, 1u, 1u, f).is_none()); - assert_eq!(rposition_between(v, 1u, 2u, f), Some(1u)); - assert_eq!(rposition_between(v, 1u, 3u, f), Some(1u)); - assert_eq!(rposition_between(v, 1u, 4u, f), Some(3u)); - - assert!(rposition_between(v, 2u, 2u, f).is_none()); - assert!(rposition_between(v, 2u, 3u, f).is_none()); - assert_eq!(rposition_between(v, 2u, 4u, f), Some(3u)); - - assert!(rposition_between(v, 3u, 3u, f).is_none()); - assert_eq!(rposition_between(v, 3u, 4u, f), Some(3u)); - - assert!(rposition_between(v, 4u, 4u, f).is_none()); - } - #[test] fn test_bsearch_elem() { assert_eq!(bsearch_elem([1,2,3,4,5], &5), Some(4)); From a890c2cbf1dd92d79ade5bd8f04142ae5511943f Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 02:08:32 +1000 Subject: [PATCH 302/336] Convert vec::{rposition, rposition_elem, position_elem, contains} to methods. --- src/libextra/smallintmap.rs | 10 ++- src/librustc/metadata/cstore.rs | 3 +- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/ty.rs | 6 +- src/librustc/middle/typeck/check/mod.rs | 4 +- src/librustc/middle/typeck/infer/resolve.rs | 3 +- src/librustpkg/tests.rs | 12 ++-- src/libstd/hashmap.rs | 10 +-- src/libstd/os.rs | 4 +- src/libstd/vec.rs | 68 ++++++++------------- src/test/bench/graph500-bfs.rs | 2 +- 11 files changed, 50 insertions(+), 74 deletions(-) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index e32c688da379..b07c05ad76a0 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -383,8 +383,6 @@ mod test_set { use super::SmallIntSet; - use std::vec; - #[test] fn test_disjoint() { let mut xs = SmallIntSet::new(); @@ -456,7 +454,7 @@ mod test_set { let mut i = 0; let expected = [3, 5, 11, 77]; for a.intersection(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -479,7 +477,7 @@ mod test_set { let mut i = 0; let expected = [1, 5, 11]; for a.difference(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -504,7 +502,7 @@ mod test_set { let mut i = 0; let expected = [1, 5, 11, 14, 22]; for a.symmetric_difference(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -533,7 +531,7 @@ mod test_set { let mut i = 0; let expected = [1, 3, 5, 9, 11, 13, 16, 19, 24]; for a.union(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index af5cc9136bdf..3413cd341ba4 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -17,7 +17,6 @@ use metadata::cstore; use metadata::decoder; use std::hashmap::HashMap; -use std::vec; use extra; use syntax::ast; use syntax::parse::token::ident_interner; @@ -91,7 +90,7 @@ pub fn iter_crate_data(cstore: &CStore, } pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) { - if !vec::contains(cstore.used_crate_files, lib) { + if !cstore.used_crate_files.contains(lib) { cstore.used_crate_files.push(copy *lib); } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index ec5f5205760f..c27b60477c09 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -363,7 +363,7 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, for m.iter().advance |r| { let r = pat_ctor_id(cx, r[0]); for r.iter().advance |id| { - if !vec::contains(found, id) { + if !found.contains(id) { found.push(/*bad*/copy *id); } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4ed21d73f3e7..8a6fff09c730 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2323,7 +2323,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { false } - ty_struct(ref did, _) if vec::contains(*seen, did) => { + ty_struct(ref did, _) if seen.contains(did) => { false } @@ -2339,7 +2339,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ts.iter().any_(|t| type_requires(cx, seen, r_ty, *t)) } - ty_enum(ref did, _) if vec::contains(*seen, did) => { + ty_enum(ref did, _) if seen.contains(did) => { false } @@ -3266,7 +3266,7 @@ pub fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) { if !type_needs_infer(rt) { return; } // Occurs check! - if vec::contains(vars_in_type(rt), &vid) { + if vars_in_type(rt).contains(&vid) { // Maybe this should be span_err -- however, there's an // assertion later on that the type doesn't contain // variables, so in this case we have to be sure to die. diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f50b38e6f6cf..d1edc1cd3630 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -985,7 +985,7 @@ pub fn do_autoderef(fcx: @mut FnCtxt, sp: span, t: ty::t) -> (ty::t, uint) { // concerned with this, as an error will be reported // on the enum definition as well because the enum is // not instantiable. - if vec::contains(enum_dids, did) { + if enum_dids.contains(did) { return (t1, autoderefs); } enum_dids.push(*did); @@ -3156,7 +3156,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, } } } - if vec::contains(*disr_vals, &*disr_val) { + if disr_vals.contains(&*disr_val) { ccx.tcx.sess.span_err(v.span, "discriminator value already exists"); } diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs index 2326e2e10efe..941431ce0e3d 100644 --- a/src/librustc/middle/typeck/infer/resolve.rs +++ b/src/librustc/middle/typeck/infer/resolve.rs @@ -57,7 +57,6 @@ use middle::typeck::infer::unify::{Root, UnifyInferCtxtMethods}; use util::common::{indent, indenter}; use util::ppaux::ty_to_str; -use std::vec; use syntax::ast; pub static resolve_nested_tvar: uint = 0b0000000001; @@ -204,7 +203,7 @@ impl ResolveState { } pub fn resolve_ty_var(&mut self, vid: TyVid) -> ty::t { - if vec::contains(self.v_seen, &vid) { + if self.v_seen.contains(&vid) { self.err = Some(cyclic_ty(vid)); return ty::mk_var(self.infcx.tcx, vid); } else { diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 0e2a4f33c72c..697a9f53f1b0 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -596,9 +596,9 @@ fn rust_path_contents() { let cwd = os::getcwd().push(".rust"); let parent = cwd.pop().pop().push(".rust"); let grandparent = cwd.pop().pop().pop().push(".rust"); - assert!(vec::contains(p, &cwd)); - assert!(vec::contains(p, &parent)); - assert!(vec::contains(p, &grandparent)); + assert!(p.contains(&cwd)); + assert!(p.contains(&parent)); + assert!(p.contains(&grandparent)); for p.iter().advance() |a_path| { assert!(!a_path.components.is_empty()); } @@ -609,9 +609,9 @@ fn rust_path_contents() { fn rust_path_parse() { os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i"); let paths = rust_path(); - assert!(vec::contains(paths, &Path("/g/h/i"))); - assert!(vec::contains(paths, &Path("/d/e/f"))); - assert!(vec::contains(paths, &Path("/a/b/c"))); + assert!(paths.contains(&Path("/g/h/i"))); + assert!(paths.contains(&Path("/d/e/f"))); + assert!(paths.contains(&Path("/a/b/c"))); os::unsetenv("RUST_PATH"); } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 35db229b65d3..85dca1154bc0 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -939,7 +939,7 @@ mod test_map { mod test_set { use super::*; use container::{Container, Map, Set}; - use vec; + use vec::ImmutableEqVector; use uint; #[test] @@ -1030,7 +1030,7 @@ mod test_set { let mut i = 0; let expected = [3, 5, 11, 77]; for a.intersection(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -1053,7 +1053,7 @@ mod test_set { let mut i = 0; let expected = [1, 5, 11]; for a.difference(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -1079,7 +1079,7 @@ mod test_set { let mut i = 0; let expected = [-2, 1, 5, 11, 14, 22]; for a.symmetric_difference(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); @@ -1109,7 +1109,7 @@ mod test_set { let mut i = 0; let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; for a.union(&b) |x| { - assert!(vec::contains(expected, x)); + assert!(expected.contains(x)); i += 1 } assert_eq!(i, expected.len()); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 1fbcda12dce1..6d13c662ee5d 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1544,10 +1544,10 @@ mod tests { let mut e = env(); setenv(n, "VALUE"); - assert!(!vec::contains(e, &(copy n, ~"VALUE"))); + assert!(!e.contains(&(copy n, ~"VALUE"))); e = env(); - assert!(vec::contains(e, &(n, ~"VALUE"))); + assert!(e.contains(&(n, ~"VALUE"))); } #[test] diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index a704e604aa28..e2b0c54b9a46 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -220,9 +220,9 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { match v.slice(start, ln).iter().position_(|t| f(t)) { None => break, Some(i) => { - result.push(v.slice(start, i).to_owned()); + result.push(v.slice(start, start + i).to_owned()); // Make sure to skip the separator. - start = i + 1u; + start += i + 1u; count -= 1u; } } @@ -646,36 +646,6 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { } } -/// Return true if a vector contains an element with the given value -pub fn contains(v: &[T], x: &T) -> bool { - for v.iter().advance |elt| { if *x == *elt { return true; } } - false -} - -/// Find the first index containing a matching value -pub fn position_elem(v: &[T], x: &T) -> Option { - v.iter().position_(|y| *x == *y) -} - -/// Find the last index containing a matching value -pub fn rposition_elem(v: &[T], x: &T) -> Option { - rposition(v, |y| *x == *y) -} - -/** - * Find the last index matching some predicate - * - * Apply function `f` to each element of `v` in reverse order. When function - * `f` returns true then an option containing the index is returned. If `f` - * matches no elements then none is returned. - */ -pub fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { - for v.rev_iter().enumerate().advance |(i, t)| { - if f(t) { return Some(v.len() - i - 1); } - } - None -} - /** * Binary search a sorted vector with a comparator function. * @@ -1265,11 +1235,14 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { * * Apply function `f` to each element of `v` in reverse order. When * function `f` returns true then an option containing the index is - * returned. If `f` matches no elements then none is returned. + * returned. If `f` matches no elements then None is returned. */ #[inline] fn rposition(&self, f: &fn(t: &T) -> bool) -> Option { - rposition(*self, f) + for self.rev_iter().enumerate().advance |(i, t)| { + if f(t) { return Some(self.len() - i - 1); } + } + None } /// Apply a function to each element of a vector and return the results @@ -1327,19 +1300,26 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { pub trait ImmutableEqVector { fn position_elem(&self, t: &T) -> Option; fn rposition_elem(&self, t: &T) -> Option; + fn contains(&self, x: &T) -> bool; } impl<'self,T:Eq> ImmutableEqVector for &'self [T] { /// Find the first index containing a matching value #[inline] fn position_elem(&self, x: &T) -> Option { - position_elem(*self, x) + self.iter().position_(|y| *x == *y) } /// Find the last index containing a matching value #[inline] fn rposition_elem(&self, t: &T) -> Option { - rposition_elem(*self, t) + self.rposition(|x| *x == *t) + } + + /// Return true if a vector contains an element with the given value + fn contains(&self, x: &T) -> bool { + for self.iter().advance |elt| { if *x == *elt { return true; } } + false } } @@ -2838,13 +2818,13 @@ mod tests { #[test] fn test_position_elem() { - assert!(position_elem([], &1).is_none()); + assert!([].position_elem(&1).is_none()); let v1 = ~[1, 2, 3, 3, 2, 5]; - assert_eq!(position_elem(v1, &1), Some(0u)); - assert_eq!(position_elem(v1, &2), Some(1u)); - assert_eq!(position_elem(v1, &5), Some(5u)); - assert!(position_elem(v1, &4).is_none()); + assert_eq!(v1.position_elem(&1), Some(0u)); + assert_eq!(v1.position_elem(&2), Some(1u)); + assert_eq!(v1.position_elem(&5), Some(5u)); + assert!(v1.position_elem(&4).is_none()); } #[test] @@ -2853,8 +2833,8 @@ mod tests { fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; - assert_eq!(rposition(v, f), Some(3u)); - assert!(rposition(v, g).is_none()); + assert_eq!(v.rposition(f), Some(3u)); + assert!(v.rposition(g).is_none()); } #[test] @@ -3417,7 +3397,7 @@ mod tests { fn test_rposition_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; let mut i = 0; - do rposition(v) |_elt| { + do v.rposition |_elt| { if i == 2 { fail!() } diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index d21888f12ec6..eeff4b71c0d2 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -341,7 +341,7 @@ fn validate(edges: ~[(node_id, node_id)], } else { while parent != root { - if vec::contains(path, &parent) { + if path.contains(&parent) { status = false; } From 9e83b2fe556aaf779261503c0910bf378e45dce4 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 02:54:03 +1000 Subject: [PATCH 303/336] Convert vec::{reverse, swap} to methods. --- src/libextra/priority_queue.rs | 2 +- src/libextra/sort.rs | 42 ++++----- src/libextra/test.rs | 2 +- src/libstd/num/strconv.rs | 5 +- src/libstd/rand.rs | 2 +- src/libstd/vec.rs | 86 ++++++++++--------- .../compile-fail/moves-based-on-type-exprs.rs | 4 +- .../run-pass/coerce-reborrow-mut-vec-arg.rs | 12 ++- .../run-pass/coerce-reborrow-mut-vec-rcvr.rs | 12 --- src/test/run-pass/swap-2.rs | 3 +- 10 files changed, 77 insertions(+), 93 deletions(-) diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 4c1163f3d50c..3d1ca4a9818b 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -107,7 +107,7 @@ impl PriorityQueue { let mut end = q.len(); while end > 1 { end -= 1; - vec::swap(q.data, 0, end); + q.data.swap(0, end); q.siftdown_range(0, end) } q.to_vec() diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 36c12f314b70..f59a2414aaeb 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -65,17 +65,17 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { fn part(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le) -> uint { - vec::swap(arr, pivot, right); + arr.swap(pivot, right); let mut storage_index: uint = left; let mut i: uint = left; while i < right { if compare_func(&arr[i], &arr[right]) { - vec::swap(arr, i, storage_index); + arr.swap(i, storage_index); storage_index += 1; } i += 1; } - vec::swap(arr, storage_index, right); + arr.swap(storage_index, right); return storage_index; } @@ -120,29 +120,29 @@ fn qsort3(arr: &mut [T], left: int, right: int) { j -= 1; } if i >= j { break; } - vec::swap(arr, i as uint, j as uint); + arr.swap(i as uint, j as uint); if arr[i] == v { p += 1; - vec::swap(arr, p as uint, i as uint); + arr.swap(p as uint, i as uint); } if v == arr[j] { q -= 1; - vec::swap(arr, j as uint, q as uint); + arr.swap(j as uint, q as uint); } } - vec::swap(arr, i as uint, right as uint); + arr.swap(i as uint, right as uint); j = i - 1; i += 1; let mut k: int = left; while k < p { - vec::swap(arr, k as uint, j as uint); + arr.swap(k as uint, j as uint); k += 1; j -= 1; if k == arr.len() as int { break; } } k = right - 1; while k > q { - vec::swap(arr, i as uint, k as uint); + arr.swap(i as uint, k as uint); k -= 1; i += 1; if k == 0 { break; } @@ -259,7 +259,7 @@ fn binarysort(array: &mut [T], start: uint) { fn reverse_slice(v: &mut [T], start: uint, end:uint) { let mut i = start; while i < end / 2 { - vec::swap(v, i, end - i - 1); + v.swap(i, end - i - 1); i += 1; } } @@ -479,7 +479,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - vec::swap(array, dest, c2); + array.swap(dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { @@ -501,7 +501,7 @@ impl MergeState { loop { assert!(len1 > 1 && len2 != 0); if array[c2] < tmp[c1] { - vec::swap(array, dest, c2); + array.swap(dest, c2); dest += 1; c2 += 1; len2 -= 1; count2 += 1; count1 = 0; if len2 == 0 { @@ -534,7 +534,7 @@ impl MergeState { dest += count1; c1 += count1; len1 -= count1; if len1 <= 1 { break_outer = true; break; } } - vec::swap(array, dest, c2); + array.swap(dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { break_outer = true; break; } @@ -589,7 +589,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - vec::swap(array, dest, c1); + array.swap(dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { @@ -613,7 +613,7 @@ impl MergeState { loop { assert!(len1 != 0 && len2 > 1); if tmp[c2] < array[c1] { - vec::swap(array, dest, c1); + array.swap(dest, c1); dest -= 1; c1 -= 1; len1 -= 1; count1 += 1; count2 = 0; if len1 == 0 { @@ -666,7 +666,7 @@ impl MergeState { copy_vec(array, dest+1, tmp.slice(c2+1, c2+1+count2)); if len2 <= 1 { break_outer = true; break; } } - vec::swap(array, dest, c1); + array.swap(dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { break_outer = true; break; } min_gallop -= 1; @@ -1049,7 +1049,7 @@ mod big_tests { fn makeRange(n: uint) -> ~[uint] { let one = do vec::from_fn(n) |i| { i }; let mut two = copy one; - vec::reverse(two); + two.reverse(); vec::append(two, one) } @@ -1073,7 +1073,7 @@ mod big_tests { tim_sort(arr); // *sort isSorted(arr); - vec::reverse(arr); + arr.reverse(); tim_sort(arr); // \sort isSorted(arr); @@ -1083,7 +1083,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - vec::swap(arr, i1, i2); + arr.swap(i1, i2); } tim_sort(arr); // 3sort isSorted(arr); @@ -1145,7 +1145,7 @@ mod big_tests { tim_sort(arr); // *sort isSorted(arr); - vec::reverse(arr); + arr.reverse(); tim_sort(arr); // \sort isSorted(arr); @@ -1155,7 +1155,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - vec::swap(arr, i1, i2); + arr.swap(i1, i2); } tim_sort(arr); // 3sort isSorted(arr); diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 886bb9293bba..1e1e53de9e89 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -449,7 +449,7 @@ fn run_tests(opts: &TestOpts, debug!("using %u test tasks", concurrency); let mut remaining = filtered_tests; - vec::reverse(remaining); + remaining.reverse(); let mut pending = 0; let (p, ch) = stream(); diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index a062838aacf0..2ddeb02b56af 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -18,8 +18,7 @@ use char; use str; use str::{StrSlice}; use kinds::Copy; -use vec; -use vec::{CopyableVector, ImmutableVector}; +use vec::{CopyableVector, ImmutableVector, MutableVector}; use vec::OwnedVector; use num::{NumCast, Zero, One, cast, pow_with_uint}; use f64; @@ -257,7 +256,7 @@ pub fn to_str_bytes_common () } - vec::reverse(buf); + buf.reverse(); // Remember start of the fractional digits. // Points one beyond end of buf if none get generated, diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 5baff8aee68d..5f96e38a55af 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -590,7 +590,7 @@ impl RngUtil for R { // invariant: elements with index >= i have been locked in place. i -= 1u; // lock element i in place. - vec::swap(values, i, self.gen_uint_range(0u, i + 1u)); + values.swap(i, self.gen_uint_range(0u, i + 1u)); } } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index e2b0c54b9a46..bb9b12a43cba 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -251,7 +251,7 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { } } result.push(v.slice(0u, end).to_owned()); - reverse(result); + result.reverse(); result } @@ -278,7 +278,7 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { } } result.push(v.slice(0u, end).to_owned()); - reverse(result); + result.reverse(); result } @@ -751,40 +751,10 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { w.push((v.pop(),u.pop())); i -= 1; } - reverse(w); + w.reverse(); w } -/** - * Swaps two elements in a vector - * - * # Arguments - * - * * v The input vector - * * a - The index of the first element - * * b - The index of the second element - */ -#[inline] -pub fn swap(v: &mut [T], a: uint, b: uint) { - unsafe { - // Can't take two mutable loans from one vector, so instead just cast - // them to their raw pointers to do the swap - let pa: *mut T = &mut v[a]; - let pb: *mut T = &mut v[b]; - ptr::swap_ptr(pa, pb); - } -} - -/// Reverse the order of elements in a vector, in place -pub fn reverse(v: &mut [T]) { - let mut i: uint = 0; - let ln = v.len(); - while i < ln / 2 { - swap(v, i, ln - i - 1); - i += 1; - } -} - /// Returns a vector with the order of elements reversed pub fn reversed(v: &[T]) -> ~[T] { let mut rs: ~[T] = ~[]; @@ -840,8 +810,8 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> } // swap indices[k] and indices[l]; sort indices[k+1..] // (they're just reversed) - vec::swap(indices, k, l); - reverse(indices.mut_slice(k+1, length)); + indices.swap(k, l); + indices.mut_slice(k+1, length).reverse(); // fixup permutation based on indices for uint::range(k, length) |i| { permutation[i] = copy values[indices[i]]; @@ -1598,7 +1568,7 @@ impl OwnedVector for ~[T] { self.push(x); let mut j = len; while j > i { - swap(*self, j, j - 1); + self.swap(j, j - 1); j -= 1; } } @@ -1611,7 +1581,7 @@ impl OwnedVector for ~[T] { let mut j = i; while j < len - 1 { - swap(*self, j, j + 1); + self.swap(j, j + 1); j += 1; } self.pop() @@ -1629,7 +1599,7 @@ impl OwnedVector for ~[T] { fail!("vec::swap_remove - index %u >= length %u", index, ln); } if index < ln - 1 { - swap(*self, index, ln - 1); + self.swap(index, ln - 1); } self.pop() } @@ -1660,7 +1630,7 @@ impl OwnedVector for ~[T] { if !f(&self[i]) { deleted += 1; } else if deleted > 0 { - swap(*self, i - deleted, i); + self.swap(i - deleted, i); } } @@ -1772,6 +1742,10 @@ pub trait MutableVector<'self, T> { fn mut_iter(self) -> VecMutIterator<'self, T>; fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>; + fn swap(self, a: uint, b: uint); + + fn reverse(self); + /** * Consumes `src` and moves as many elements as it can into `self` * from the range [start,end). @@ -1823,6 +1797,34 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } + /** + * Swaps two elements in a vector + * + * # Arguments + * + * * a - The index of the first element + * * b - The index of the second element + */ + fn swap(self, a: uint, b: uint) { + unsafe { + // Can't take two mutable loans from one vector, so instead just cast + // them to their raw pointers to do the swap + let pa: *mut T = &mut self[a]; + let pb: *mut T = &mut self[b]; + ptr::swap_ptr(pa, pb); + } + } + + /// Reverse the order of elements in a vector, in place + fn reverse(self) { + let mut i: uint = 0; + let ln = self.len(); + while i < ln / 2 { + self.swap(i, ln - i - 1); + i += 1; + } + } + #[inline] fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint { for self.mut_iter().zip(src.mut_slice(start, end).mut_iter()).advance |(a, b)| { @@ -2887,7 +2889,7 @@ mod tests { let mut v: ~[int] = ~[10, 20]; assert_eq!(v[0], 10); assert_eq!(v[1], 20); - reverse(v); + v.reverse(); assert_eq!(v[0], 20); assert_eq!(v[1], 10); let v2 = reversed::([10, 20]); @@ -2900,7 +2902,7 @@ mod tests { let v4 = reversed::([]); assert_eq!(v4, ~[]); let mut v3: ~[int] = ~[]; - reverse::(v3); + v3.reverse(); } #[test] @@ -3549,7 +3551,7 @@ mod tests { #[test] fn test_reverse_part() { let mut values = [1,2,3,4,5]; - reverse(values.mut_slice(1, 4)); + values.mut_slice(1, 4).reverse(); assert_eq!(values, [1,4,3,2,5]); } diff --git a/src/test/compile-fail/moves-based-on-type-exprs.rs b/src/test/compile-fail/moves-based-on-type-exprs.rs index 38718006d8b1..fec0f89adbaf 100644 --- a/src/test/compile-fail/moves-based-on-type-exprs.rs +++ b/src/test/compile-fail/moves-based-on-type-exprs.rs @@ -1,8 +1,6 @@ // Tests that references to move-by-default values trigger moves when // they occur as part of various kinds of expressions. -use std::vec; - struct Foo { f: A } fn guard(_s: ~str) -> bool {fail!()} fn touch(_a: &A) {} @@ -92,7 +90,7 @@ fn f110() { fn f120() { let mut x = ~[~"hi", ~"ho"]; - vec::swap(x, 0, 1); + x.swap(0, 1); touch(&x[0]); touch(&x[1]); } diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs index 3d216c1885f6..356c15961869 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs @@ -1,13 +1,11 @@ -use std::vec; - -trait Reverser { - fn reverse(&self); +fn reverse(v: &mut [uint]) { + v.reverse(); } fn bar(v: &mut [uint]) { - vec::reverse(v); - vec::reverse(v); - vec::reverse(v); + reverse(v); + reverse(v); + reverse(v); } pub fn main() { diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs index d62ed77fdab3..556d70f3c88a 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs @@ -1,15 +1,3 @@ -use std::vec; - -trait Reverser { - fn reverse(self); -} - -impl<'self> Reverser for &'self mut [uint] { - fn reverse(self) { - vec::reverse(self); - } -} - fn bar(v: &mut [uint]) { v.reverse(); v.reverse(); diff --git a/src/test/run-pass/swap-2.rs b/src/test/run-pass/swap-2.rs index cf3a465d812d..2ec2eb3c45b5 100644 --- a/src/test/run-pass/swap-2.rs +++ b/src/test/run-pass/swap-2.rs @@ -9,11 +9,10 @@ // except according to those terms. use std::util; -use std::vec; pub fn main() { let mut a: ~[int] = ~[0, 1, 2, 3, 4, 5, 6]; - vec::swap(a, 2, 4); + a.swap(2, 4); assert_eq!(a[2], 4); assert_eq!(a[4], 2); let mut n = 42; From 562dea1820e51f7e87cdeef4024eb9e58c7800d0 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 11:19:14 +1000 Subject: [PATCH 304/336] etc: update etc/unicode.py for the changes made to std::unicode. --- src/etc/unicode.py | 34 ++++++++++++++++++++++++---------- src/libstd/unicode.rs | 3 +-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/etc/unicode.py b/src/etc/unicode.py index afb3d1684808..191338b3cb4f 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -122,14 +122,14 @@ def ch_prefix(ix): def emit_bsearch_range_table(f): f.write(""" - pure fn bsearch_range_table(c: char, r: &[(char,char)]) -> bool { - use cmp::{EQ, LT, GT}; + fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { + use cmp::{Equal, Less, Greater}; use vec::bsearch; use option::None; (do bsearch(r) |&(lo,hi)| { - if lo <= c && c <= hi { EQ } - else if hi < c { LT } - else { GT } + if lo <= c && c <= hi { Equal } + else if hi < c { Less } + else { Greater } }) != None }\n\n """); @@ -140,7 +140,7 @@ def emit_property_module(f, mod, tbl): keys.sort() emit_bsearch_range_table(f); for cat in keys: - f.write(" const %s_table : &[(char,char)] = &[\n" % cat) + f.write(" static %s_table : &'static [(char,char)] = &[\n" % cat) ix = 0 for pair in tbl[cat]: f.write(ch_prefix(ix)) @@ -148,7 +148,7 @@ def emit_property_module(f, mod, tbl): ix += 1 f.write("\n ];\n\n") - f.write(" pub pure fn %s(c: char) -> bool {\n" % cat) + f.write(" pub fn %s(c: char) -> bool {\n" % cat) f.write(" bsearch_range_table(c, %s_table)\n" % cat) f.write(" }\n\n") f.write("}\n") @@ -159,7 +159,7 @@ def emit_property_module_old(f, mod, tbl): keys = tbl.keys() keys.sort() for cat in keys: - f.write(" pure fn %s(c: char) -> bool {\n" % cat) + f.write(" fn %s(c: char) -> bool {\n" % cat) f.write(" ret alt c {\n") prefix = ' ' for pair in tbl[cat]: @@ -236,8 +236,22 @@ rf = open(r, "w") (canon_decomp, compat_decomp, gencats) = load_unicode_data("UnicodeData.txt") -# Explain that the source code was generated by this script. -rf.write('// The following code was generated by "src/etc/unicode.py"\n\n') +# Preamble +rf.write('''// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// The following code was generated by "src/etc/unicode.py" + +#[allow(missing_doc)]; + +''') emit_property_module(rf, "general_category", gencats) diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index f8f56c75a295..fd95588d7129 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -1447,10 +1447,8 @@ pub mod general_category { } } - pub mod derived_property { - fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; use vec::bsearch; @@ -2641,4 +2639,5 @@ pub mod derived_property { pub fn XID_Start(c: char) -> bool { bsearch_range_table(c, XID_Start_table) } + } From faa8f8ff8b7e457f74d74533ebbc0d5a56cf5c72 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 13:35:25 +1000 Subject: [PATCH 305/336] Convert vec::{bsearch, bsearch_elem} to methods. --- src/etc/unicode.py | 4 +- src/libstd/prelude.rs | 2 +- src/libstd/unicode.rs | 8 +-- src/libstd/vec.rs | 151 ++++++++++++++++++++++-------------------- 4 files changed, 87 insertions(+), 78 deletions(-) diff --git a/src/etc/unicode.py b/src/etc/unicode.py index 191338b3cb4f..2a252f3f1f39 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -124,9 +124,9 @@ def emit_bsearch_range_table(f): f.write(""" fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; - use vec::bsearch; + use vec::ImmutableVector; use option::None; - (do bsearch(r) |&(lo,hi)| { + (do r.bsearch |&(lo,hi)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 13d19b276f59..c0049c7505d9 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -73,7 +73,7 @@ pub use tuple::{ImmutableTuple2, ImmutableTuple3, ImmutableTuple4, ImmutableTupl pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTuple9}; pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; pub use vec::{VectorVector, CopyableVector, ImmutableVector}; -pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; +pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector, MutableVector}; pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index fd95588d7129..1e2d5c76feaa 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -16,9 +16,9 @@ pub mod general_category { fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; - use vec::bsearch; + use vec::ImmutableVector; use option::None; - (do bsearch(r) |&(lo,hi)| { + (do r.bsearch |&(lo,hi)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } @@ -1451,9 +1451,9 @@ pub mod derived_property { fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; - use vec::bsearch; + use vec::ImmutableVector; use option::None; - (do bsearch(r) |&(lo,hi)| { + (do r.bsearch |&(lo,hi)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index bb9b12a43cba..d7480617c12e 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -646,44 +646,6 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { } } -/** - * Binary search a sorted vector with a comparator function. - * - * The comparator should implement an order consistent with the sort - * order of the underlying vector, returning an order code that indicates - * whether its argument is `Less`, `Equal` or `Greater` the desired target. - * - * Returns the index where the comparator returned `Equal`, or `None` if - * not found. - */ -pub fn bsearch(v: &[T], f: &fn(&T) -> Ordering) -> Option { - let mut base : uint = 0; - let mut lim : uint = v.len(); - - while lim != 0 { - let ix = base + (lim >> 1); - match f(&v[ix]) { - Equal => return Some(ix), - Less => { - base = ix + 1; - lim -= 1; - } - Greater => () - } - lim >>= 1; - } - return None; -} - -/** - * Binary search a sorted vector for a given element. - * - * Returns the index of the element or None if not found. - */ -pub fn bsearch_elem(v: &[T], x: &T) -> Option { - bsearch(v, |p| p.cmp(x)) -} - // FIXME: if issue #586 gets implemented, could have a postcondition // saying the two result lists have the same length -- or, could // return a nominal record with a constraint saying that, instead of @@ -1119,6 +1081,8 @@ pub trait ImmutableVector<'self, T> { 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; } /// Extension methods for vectors @@ -1264,6 +1228,35 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { let (ptr, _): (*T, uint) = transmute(*self); ptr.offset(index) } + + /** + * Binary search a sorted vector with a comparator function. + * + * The comparator should implement an order consistent with the sort + * order of the underlying vector, returning an order code that indicates + * whether its argument is `Less`, `Equal` or `Greater` the desired target. + * + * Returns the index where the comparator returned `Equal`, or `None` if + * not found. + */ + fn bsearch(&self, f: &fn(&T) -> Ordering) -> Option { + let mut base : uint = 0; + let mut lim : uint = self.len(); + + while lim != 0 { + let ix = base + (lim >> 1); + match f(&self[ix]) { + Equal => return Some(ix), + Less => { + base = ix + 1; + lim -= 1; + } + Greater => () + } + lim >>= 1; + } + return None; + } } #[allow(missing_doc)] @@ -1293,6 +1286,22 @@ impl<'self,T:Eq> ImmutableEqVector for &'self [T] { } } +#[allow(missing_doc)] +pub trait ImmutableTotalOrdVector { + fn bsearch_elem(&self, x: &T) -> Option; +} + +impl<'self, T: TotalOrd> ImmutableTotalOrdVector for &'self [T] { + /** + * Binary search a sorted vector for a given element. + * + * Returns the index of the element or None if not found. + */ + fn bsearch_elem(&self, x: &T) -> Option { + self.bsearch(|p| p.cmp(x)) + } +} + #[allow(missing_doc)] pub trait ImmutableCopyableVector { fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; @@ -2841,47 +2850,47 @@ mod tests { #[test] fn test_bsearch_elem() { - assert_eq!(bsearch_elem([1,2,3,4,5], &5), Some(4)); - assert_eq!(bsearch_elem([1,2,3,4,5], &4), Some(3)); - assert_eq!(bsearch_elem([1,2,3,4,5], &3), Some(2)); - assert_eq!(bsearch_elem([1,2,3,4,5], &2), Some(1)); - assert_eq!(bsearch_elem([1,2,3,4,5], &1), Some(0)); + assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4)); + assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3)); + assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2)); + assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1)); + assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0)); - assert_eq!(bsearch_elem([2,4,6,8,10], &1), None); - assert_eq!(bsearch_elem([2,4,6,8,10], &5), None); - assert_eq!(bsearch_elem([2,4,6,8,10], &4), Some(1)); - assert_eq!(bsearch_elem([2,4,6,8,10], &10), Some(4)); + assert_eq!([2,4,6,8,10].bsearch_elem(&1), None); + assert_eq!([2,4,6,8,10].bsearch_elem(&5), None); + assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1)); + assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4)); - assert_eq!(bsearch_elem([2,4,6,8], &1), None); - assert_eq!(bsearch_elem([2,4,6,8], &5), None); - assert_eq!(bsearch_elem([2,4,6,8], &4), Some(1)); - assert_eq!(bsearch_elem([2,4,6,8], &8), Some(3)); + assert_eq!([2,4,6,8].bsearch_elem(&1), None); + assert_eq!([2,4,6,8].bsearch_elem(&5), None); + assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1)); + assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3)); - assert_eq!(bsearch_elem([2,4,6], &1), None); - assert_eq!(bsearch_elem([2,4,6], &5), None); - assert_eq!(bsearch_elem([2,4,6], &4), Some(1)); - assert_eq!(bsearch_elem([2,4,6], &6), Some(2)); + assert_eq!([2,4,6].bsearch_elem(&1), None); + assert_eq!([2,4,6].bsearch_elem(&5), None); + assert_eq!([2,4,6].bsearch_elem(&4), Some(1)); + assert_eq!([2,4,6].bsearch_elem(&6), Some(2)); - assert_eq!(bsearch_elem([2,4], &1), None); - assert_eq!(bsearch_elem([2,4], &5), None); - assert_eq!(bsearch_elem([2,4], &2), Some(0)); - assert_eq!(bsearch_elem([2,4], &4), Some(1)); + assert_eq!([2,4].bsearch_elem(&1), None); + assert_eq!([2,4].bsearch_elem(&5), None); + assert_eq!([2,4].bsearch_elem(&2), Some(0)); + assert_eq!([2,4].bsearch_elem(&4), Some(1)); - assert_eq!(bsearch_elem([2], &1), None); - assert_eq!(bsearch_elem([2], &5), None); - assert_eq!(bsearch_elem([2], &2), Some(0)); + assert_eq!([2].bsearch_elem(&1), None); + assert_eq!([2].bsearch_elem(&5), None); + assert_eq!([2].bsearch_elem(&2), Some(0)); - assert_eq!(bsearch_elem([], &1), None); - assert_eq!(bsearch_elem([], &5), None); + assert_eq!([].bsearch_elem(&1), None); + assert_eq!([].bsearch_elem(&5), None); - assert!(bsearch_elem([1,1,1,1,1], &1) != None); - assert!(bsearch_elem([1,1,1,1,2], &1) != None); - assert!(bsearch_elem([1,1,1,2,2], &1) != None); - assert!(bsearch_elem([1,1,2,2,2], &1) != None); - assert_eq!(bsearch_elem([1,2,2,2,2], &1), Some(0)); + assert!([1,1,1,1,1].bsearch_elem(&1) != None); + assert!([1,1,1,1,2].bsearch_elem(&1) != None); + assert!([1,1,1,2,2].bsearch_elem(&1) != None); + assert!([1,1,2,2,2].bsearch_elem(&1) != None); + assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0)); - assert_eq!(bsearch_elem([1,2,3,4,5], &6), None); - assert_eq!(bsearch_elem([1,2,3,4,5], &0), None); + assert_eq!([1,2,3,4,5].bsearch_elem(&6), None); + assert_eq!([1,2,3,4,5].bsearch_elem(&0), None); } #[test] From 2eea642c3064e2de643cf155082f08dc141eafaa Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 13:41:09 +1000 Subject: [PATCH 306/336] Convert vec::dedup to a method. --- src/librustc/middle/check_match.rs | 2 +- src/libstd/prelude.rs | 2 +- src/libstd/vec.rs | 73 ++++++++++++++---------------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index c27b60477c09..8cb671a97f40 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -417,7 +417,7 @@ pub fn missing_ctor(cx: &MatchCheckCtxt, } } ); - vec::dedup(&mut sorted_vec_lens); + sorted_vec_lens.dedup(); let mut found_slice = false; let mut next = 0; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index c0049c7505d9..d560ce621eac 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -74,7 +74,7 @@ pub use tuple::{ImmutableTuple6, ImmutableTuple7, ImmutableTuple8, ImmutableTupl pub use tuple::{ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; pub use vec::{VectorVector, CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; -pub use vec::{OwnedVector, OwnedCopyableVector, MutableVector}; +pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector}; pub use io::{Reader, ReaderUtil, Writer, WriterUtil}; // Reexported runtime types diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index d7480617c12e..dab379962a0c 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -343,41 +343,6 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { } } -/** - * Remove consecutive repeated elements from a vector; if the vector is - * sorted, this removes all duplicates. - */ -pub fn dedup(v: &mut ~[T]) { - unsafe { - if v.len() < 1 { return; } - let mut last_written = 0; - let mut next_to_read = 1; - do as_mut_buf(*v) |p, ln| { - // last_written < next_to_read <= ln - while next_to_read < ln { - // last_written < next_to_read < ln - if *ptr::mut_offset(p, next_to_read) == - *ptr::mut_offset(p, last_written) { - ptr::replace_ptr(ptr::mut_offset(p, next_to_read), - intrinsics::uninit()); - } else { - last_written += 1; - // last_written <= next_to_read < ln - if next_to_read != last_written { - ptr::swap_ptr(ptr::mut_offset(p, last_written), - ptr::mut_offset(p, next_to_read)); - } - } - // last_written <= next_to_read < ln - next_to_read += 1; - // last_written < next_to_read <= ln - } - } - // last_written < next_to_read == ln - raw::set_len(v, last_written + 1); - } -} - // Appending /// Iterates over the `rhs` vector, copying each element and appending it to the @@ -1734,14 +1699,44 @@ impl OwnedCopyableVector for ~[T] { } #[allow(missing_doc)] -trait OwnedEqVector { +pub trait OwnedEqVector { fn dedup(&mut self); } impl OwnedEqVector for ~[T] { - #[inline] - fn dedup(&mut self) { - dedup(self) + /** + * Remove consecutive repeated elements from a vector; if the vector is + * sorted, this removes all duplicates. + */ + pub fn dedup(&mut self) { + unsafe { + if self.len() == 0 { return; } + let mut last_written = 0; + let mut next_to_read = 1; + do as_mut_buf(*self) |p, ln| { + // last_written < next_to_read <= ln + while next_to_read < ln { + // last_written < next_to_read < ln + if *ptr::mut_offset(p, next_to_read) == + *ptr::mut_offset(p, last_written) { + ptr::replace_ptr(ptr::mut_offset(p, next_to_read), + intrinsics::uninit()); + } else { + last_written += 1; + // last_written <= next_to_read < ln + if next_to_read != last_written { + ptr::swap_ptr(ptr::mut_offset(p, last_written), + ptr::mut_offset(p, next_to_read)); + } + } + // last_written <= next_to_read < ln + next_to_read += 1; + // last_written < next_to_read <= ln + } + } + // last_written < next_to_read == ln + raw::set_len(self, last_written + 1); + } } } From a396e1e2e95acc07f2804be2079d5b692753d4bb Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 14:02:20 +1000 Subject: [PATCH 307/336] Convert vec::{grow, grow_fn, grow_set} to methods. --- src/libextra/smallintmap.rs | 3 +- src/libstd/vec.rs | 109 +++++++++++++----------------- src/test/run-pass/issue-3563-3.rs | 4 +- 3 files changed, 48 insertions(+), 68 deletions(-) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index b07c05ad76a0..9cfe7cf5e4a1 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -20,7 +20,6 @@ use std::cmp; use std::container::{Container, Mutable, Map, Set}; use std::uint; use std::util::replace; -use std::vec; #[allow(missing_doc)] pub struct SmallIntMap { @@ -86,7 +85,7 @@ impl Map for SmallIntMap { let exists = self.contains_key(&key); let len = self.v.len(); if len <= key { - vec::grow_fn(&mut self.v, key - len + 1, |_| None); + self.v.grow_fn(key - len + 1, |_| None); } self.v[key] = Some(value); !exists diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index dab379962a0c..976a67ef4227 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -363,63 +363,6 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { v } -/** - * Expands a vector in place, initializing the new elements to a given value - * - * # Arguments - * - * * v - The vector to grow - * * n - The number of elements to add - * * initval - The value for the new elements - */ -pub fn grow(v: &mut ~[T], n: uint, initval: &T) { - let new_len = v.len() + n; - v.reserve_at_least(new_len); - let mut i: uint = 0u; - - while i < n { - v.push(copy *initval); - i += 1u; - } -} - -/** - * Expands a vector in place, initializing the new elements to the result of - * a function - * - * Function `init_op` is called `n` times with the values [0..`n`) - * - * # Arguments - * - * * v - The vector to grow - * * n - The number of elements to add - * * init_op - A function to call to retreive each appended element's - * value - */ -pub fn grow_fn(v: &mut ~[T], n: uint, op: &fn(uint) -> T) { - let new_len = v.len() + n; - v.reserve_at_least(new_len); - let mut i: uint = 0u; - while i < n { - v.push(op(i)); - i += 1u; - } -} - -/** - * Sets the value of a vector element at a given index, growing the vector as - * needed - * - * Sets the element at position `index` to `val`. If `index` is past the end - * of the vector, expands the vector by replicating `initval` to fill the - * intervening space. - */ -pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { - let l = v.len(); - if index >= l { grow(&mut *v, index - l + 1u, initval); } - v[index] = val; -} - // Functional utilities /// Apply a function to each element of a vector and return the results @@ -1648,9 +1591,26 @@ impl OwnedVector for ~[T] { (lefts, rights) } - #[inline] + /** + * Expands a vector in place, initializing the new elements to the result of + * a function + * + * Function `init_op` is called `n` times with the values [0..`n`) + * + * # Arguments + * + * * n - The number of elements to add + * * init_op - A function to call to retreive each appended element's + * value + */ fn grow_fn(&mut self, n: uint, op: &fn(uint) -> T) { - grow_fn(self, n, op); + let new_len = self.len() + n; + self.reserve_at_least(new_len); + let mut i: uint = 0u; + while i < n { + self.push(op(i)); + i += 1u; + } } } @@ -1687,14 +1647,37 @@ impl OwnedCopyableVector for ~[T] { } } - #[inline] + /** + * Expands a vector in place, initializing the new elements to a given value + * + * # Arguments + * + * * n - The number of elements to add + * * initval - The value for the new elements + */ fn grow(&mut self, n: uint, initval: &T) { - grow(self, n, initval); + let new_len = self.len() + n; + self.reserve_at_least(new_len); + let mut i: uint = 0u; + + while i < n { + self.push(copy *initval); + i += 1u; + } } - #[inline] + /** + * Sets the value of a vector element at a given index, growing the vector as + * needed + * + * Sets the element at position `index` to `val`. If `index` is past the end + * of the vector, expands the vector by replicating `initval` to fill the + * intervening space. + */ fn grow_set(&mut self, index: uint, initval: &T, val: T) { - grow_set(self, index, initval, val); + let l = self.len(); + if index >= l { self.grow(index - l + 1u, initval); } + self[index] = val; } } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index e574502a9fb7..a24800e4dbb2 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -69,9 +69,7 @@ fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt { // blank characters for each position in our canvas. let mut lines = do vec::build_sized(height) |push| { for height.times { - let mut line = ~[]; - vec::grow_set(&mut line, width-1, &'.', '.'); - push(line); + push(vec::from_elem(width, '.')); } }; From c0a20d2929a7c0d6af0de899198df4f26453d877 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sat, 29 Jun 2013 15:05:50 +1000 Subject: [PATCH 308/336] Remove vec::{map, mapi, zip_map} and the methods, except for .map, since this is very common, and the replacement (.iter().transform().collect()) is very ugly. --- src/compiletest/runtest.rs | 4 +- src/libextra/fileinput.rs | 9 +- src/libextra/getopts.rs | 6 +- src/libextra/num/bigint.rs | 10 +- src/libextra/par.rs | 6 +- src/libextra/semver.rs | 4 +- src/librustc/back/rpath.rs | 8 +- src/librustc/front/config.rs | 2 +- src/librustc/front/test.rs | 2 +- src/librustc/metadata/encoder.rs | 3 +- src/librustc/middle/check_match.rs | 4 +- src/librustc/middle/const_eval.rs | 9 +- src/librustc/middle/lint.rs | 7 +- src/librustc/middle/trans/adt.rs | 4 +- src/librustc/middle/trans/build.rs | 6 +- src/librustc/middle/trans/cabi.rs | 3 +- src/librustc/middle/trans/common.rs | 16 ++- src/librustc/middle/trans/expr.rs | 5 +- src/librustc/middle/trans/monomorphize.rs | 25 ++-- src/librustc/middle/ty.rs | 12 +- src/librustc/middle/typeck/astconv.rs | 4 +- src/librustc/middle/typeck/check/mod.rs | 6 +- src/librustc/middle/typeck/collect.rs | 4 +- .../middle/typeck/infer/region_inference.rs | 4 +- src/librustdoc/attr_pass.rs | 17 ++- src/librustdoc/extract.rs | 10 +- src/librustdoc/fold.rs | 30 ++-- src/librustdoc/tystr_pass.rs | 9 +- src/libstd/io.rs | 4 +- src/libstd/iterator.rs | 3 +- src/libstd/tuple.rs | 6 +- src/libstd/vec.rs | 131 +++--------------- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/deriving/decodable.rs | 8 +- src/libsyntax/ext/deriving/generic.rs | 11 +- src/libsyntax/ext/deriving/rand.rs | 4 +- src/libsyntax/ext/pipes/pipec.rs | 12 +- src/libsyntax/ext/source_util.rs | 5 +- src/libsyntax/ext/tt/macro_parser.rs | 3 +- src/libsyntax/fold.rs | 13 +- src/test/bench/graph500-bfs.rs | 10 +- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 15 +- src/test/compile-fail/lint-unused-imports.rs | 6 +- src/test/run-pass/block-arg.rs | 2 +- src/test/run-pass/block-vec-map_zip.rs | 20 --- src/test/run-pass/trait-to-str.rs | 6 +- 47 files changed, 184 insertions(+), 310 deletions(-) delete mode 100644 src/test/run-pass/block-vec-map_zip.rs diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 0e04be34c795..715f6d91e09d 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -345,9 +345,9 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError], fatal(~"process did not return an error status"); } - let prefixes = vec::map(expected_errors, |ee| { + let prefixes = expected_errors.iter().transform(|ee| { fmt!("%s:%u:", testfile.to_str(), ee.line) - }); + }).collect::<~[~str]>(); // Scan and extract our error/warning messages, // which look like: diff --git a/src/libextra/fileinput.rs b/src/libextra/fileinput.rs index 5367da2fa8d4..f91260f47528 100644 --- a/src/libextra/fileinput.rs +++ b/src/libextra/fileinput.rs @@ -100,7 +100,6 @@ total line count). use std::io::ReaderUtil; use std::io; use std::os; -use std::vec; /** A summary of the internal state of a `FileInput` object. `line_num` @@ -353,13 +352,13 @@ a literal `-`. */ // XXX: stupid, unclear name pub fn pathify(vec: &[~str], stdin_hyphen : bool) -> ~[Option] { - vec::map(vec, |&str : & ~str| { - if stdin_hyphen && str == ~"-" { + vec.iter().transform(|str| { + if stdin_hyphen && "-" == *str { None } else { - Some(Path(str)) + Some(Path(*str)) } - }) + }).collect() } /** diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index 21fe676ef792..1a494f36c646 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -592,9 +592,9 @@ pub mod groups { */ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str { - let desc_sep = ~"\n" + " ".repeat(24); + let desc_sep = "\n" + " ".repeat(24); - let rows = vec::map(opts, |optref| { + let mut rows = opts.iter().transform(|optref| { let OptGroup{short_name: short_name, long_name: long_name, hint: hint, @@ -669,7 +669,7 @@ pub mod groups { return str::to_owned(brief) + "\n\nOptions:\n" + - rows.connect("\n") + + rows.collect::<~[~str]>().connect("\n") + "\n\n"; } } // end groups module diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index fd61c4f6bfc6..9422ad0c9f2e 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -283,13 +283,13 @@ impl Mul for BigUint { if n == 1 { return copy *a; } let mut carry = 0; - let prod = do vec::map(a.data) |ai| { + let prod = do a.data.iter().transform |ai| { let (hi, lo) = BigDigit::from_uint( (*ai as uint) * (n as uint) + (carry as uint) ); carry = hi; lo - }; + }.collect::<~[BigDigit]>(); if carry == 0 { return BigUint::new(prod) }; return BigUint::new(prod + [carry]); } @@ -618,13 +618,13 @@ impl BigUint { if n_bits == 0 || self.is_zero() { return copy *self; } let mut carry = 0; - let shifted = do vec::map(self.data) |elem| { + let shifted = do self.data.iter().transform |elem| { let (hi, lo) = BigDigit::from_uint( (*elem as uint) << n_bits | (carry as uint) ); carry = hi; lo - }; + }.collect::<~[BigDigit]>(); if carry == 0 { return BigUint::new(shifted); } return BigUint::new(shifted + [carry]); } @@ -1172,7 +1172,7 @@ mod biguint_tests { #[test] fn test_cmp() { - let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ] + let data: ~[BigUint] = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ] .map(|v| BigUint::from_slice(*v)); for data.iter().enumerate().advance |(i, ni)| { for data.slice(i, data.len()).iter().enumerate().advance |(j0, nj)| { diff --git a/src/libextra/par.rs b/src/libextra/par.rs index 665633eedf85..2878a3ee1221 100644 --- a/src/libextra/par.rs +++ b/src/libextra/par.rs @@ -92,7 +92,7 @@ pub fn map( vec::concat(map_slices(xs, || { let f = fn_factory(); let result: ~fn(uint, &[A]) -> ~[B] = - |_, slice| vec::map(slice, |x| f(x)); + |_, slice| slice.iter().transform(|x| f(x)).collect(); result })) } @@ -104,9 +104,9 @@ pub fn mapi( let slices = map_slices(xs, || { let f = fn_factory(); let result: ~fn(uint, &[A]) -> ~[B] = |base, slice| { - vec::mapi(slice, |i, x| { + slice.iter().enumerate().transform(|(i, x)| { f(i + base, x) - }) + }).collect() }; result }); diff --git a/src/libextra/semver.rs b/src/libextra/semver.rs index 6361de127193..6c9453a5a3ba 100644 --- a/src/libextra/semver.rs +++ b/src/libextra/semver.rs @@ -78,12 +78,12 @@ impl ToStr for Version { let s = if self.pre.is_empty() { s } else { - s + "-" + self.pre.map(|i| i.to_str()).connect(".") + fmt!("%s-%s", s, self.pre.map(|i| i.to_str()).connect(".")) }; if self.build.is_empty() { s } else { - s + "+" + self.build.map(|i| i.to_str()).connect(".") + fmt!("%s+%s", s, self.build.map(|i| i.to_str()).connect(".")) } } } diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index ab107a8bf250..19dbb941e556 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -52,7 +52,7 @@ fn get_sysroot_absolute_rt_lib(sess: session::Session) -> Path { } pub fn rpaths_to_flags(rpaths: &[Path]) -> ~[~str] { - vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath.to_str())) + rpaths.iter().transform(|rpath| fmt!("-Wl,-rpath,%s",rpath.to_str())).collect() } fn get_rpaths(os: session::os, @@ -103,9 +103,7 @@ fn get_rpaths(os: session::os, fn get_rpaths_relative_to_output(os: session::os, output: &Path, libs: &[Path]) -> ~[Path] { - vec::map(libs, |a| { - get_rpath_relative_to_output(os, output, a) - }) + libs.iter().transform(|a| get_rpath_relative_to_output(os, output, a)).collect() } pub fn get_rpath_relative_to_output(os: session::os, @@ -163,7 +161,7 @@ pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { } fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] { - vec::map(libs, |a| get_absolute_rpath(a) ) + libs.iter().transform(|a| get_absolute_rpath(a)).collect() } pub fn get_absolute_rpath(lib: &Path) -> Path { diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 7d9fac5c6ae0..b1d4820f062e 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -90,7 +90,7 @@ fn fold_foreign_mod( ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)), + view_items: filtered_view_items.iter().transform(|x| fld.fold_view_item(*x)).collect(), items: filtered_items } } diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index cfd4df7403f6..6998410bae0e 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -117,7 +117,7 @@ fn fold_mod(cx: @mut TestCtxt, let mod_nomain = ast::_mod { view_items: /*bad*/copy m.view_items, - items: vec::map(m.items, |i| nomain(cx, *i)), + items: m.items.iter().transform(|i| nomain(cx, *i)).collect(), }; fold::noop_fold_mod(&mod_nomain, fld) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 71d7bea0af7b..77a8d1792dbc 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1441,8 +1441,7 @@ fn encode_crate_deps(ecx: &EncodeContext, expected_cnum += 1; } - // mut -> immutable hack for vec::map - deps.slice(0, deps.len()).to_owned() + deps } // We're just going to write a list of crate 'name-hash-version's, with diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 8cb671a97f40..72896258b2d3 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -642,13 +642,13 @@ pub fn specialize(cx: &MatchCheckCtxt, ty_to_str(cx.tcx, left_ty))); } } - let args = vec::map(class_fields, |class_field| { + let args = class_fields.iter().transform(|class_field| { match flds.iter().find_(|f| f.ident == class_field.ident) { Some(f) => f.pat, _ => wild() } - }); + }).collect(); Some(vec::append(args, vec::to_owned(r.tail()))) } } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 9d94a2de6933..bf91b6771dcd 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -19,7 +19,6 @@ use syntax::ast::*; use std::float; use std::hashmap::{HashMap, HashSet}; -use std::vec; // // This pass classifies expressions by their constant-ness. @@ -70,8 +69,8 @@ pub fn join(a: constness, b: constness) -> constness { } } -pub fn join_all(cs: &[constness]) -> constness { - cs.iter().fold(integral_const, |a, b| join(a, *b)) +pub fn join_all>(mut cs: It) -> constness { + cs.fold(integral_const, |a, b| join(a, b)) } pub fn classify(e: &expr, @@ -104,7 +103,7 @@ pub fn classify(e: &expr, ast::expr_tup(ref es) | ast::expr_vec(ref es, ast::m_imm) => { - join_all(vec::map(*es, |e| classify(*e, tcx))) + join_all(es.iter().transform(|e| classify(*e, tcx))) } ast::expr_vstore(e, vstore) => { @@ -118,7 +117,7 @@ pub fn classify(e: &expr, } ast::expr_struct(_, ref fs, None) => { - let cs = do vec::map((*fs)) |f| { + let cs = do fs.iter().transform |f| { classify(f.node.expr, tcx) }; join_all(cs) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index d0fd516778bb..ce09f790ef45 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -740,11 +740,10 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { } fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { - let tys = vec::map(decl.inputs, |a| a.ty ); - let r = vec::append_one(tys, decl.output); - for r.iter().advance |ty| { - check_ty(cx, *ty); + for decl.inputs.iter().advance |in| { + check_ty(cx, in.ty); } + check_ty(cx, decl.output) } match it.node { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 5417d6f6cc66..ab813c0ffc54 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -519,10 +519,10 @@ pub fn trans_const(ccx: &mut CrateContext, r: &Repr, discr: int, C_struct(build_const_struct(ccx, nonnull, vals)) } else { assert_eq!(vals.len(), 0); - let vals = do nonnull.fields.mapi |i, &ty| { + let vals = do nonnull.fields.iter().enumerate().transform |(i, &ty)| { let llty = type_of::sizing_type_of(ccx, ty); if i == ptrfield { C_null(llty) } else { C_undef(llty) } - }; + }.collect::<~[ValueRef]>(); C_struct(build_const_struct(ccx, nonnull, vals)) } } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 46a8cb306f8b..8535c84c5cb5 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -615,12 +615,12 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { // we care about. if ixs.len() < 16 { let mut small_vec = [ C_i32(0), ..16 ]; - for ixs.iter().enumerate().advance |(i, &ix)| { - small_vec[i] = C_i32(ix as i32) + for small_vec.mut_iter().zip(ixs.iter()).advance |(small_vec_e, &ix)| { + *small_vec_e = C_i32(ix as i32); } InBoundsGEP(cx, base, small_vec.slice(0, ixs.len())) } else { - let v = do vec::map(ixs) |i| { C_i32(*i as i32) }; + let v = do ixs.iter().transform |i| { C_i32(*i as i32) }.collect::<~[ValueRef]>(); count_insn(cx, "gepi"); InBoundsGEP(cx, base, v) } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 4cbc9cd417f2..d00479194308 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -17,7 +17,6 @@ use middle::trans::type_::Type; use std::libc::c_uint; use std::option; -use std::vec; pub trait ABIInfo { fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType; @@ -37,7 +36,7 @@ pub struct FnType { impl FnType { pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef { - let atys = vec::map(self.arg_tys, |t| t.ty); + let atys = self.arg_tys.iter().transform(|t| t.ty).collect::<~[Type]>(); let rty = self.ret_ty.ty; let fnty = Type::func(atys, &rty); let llfn = decl(fnty); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 539397c8b1a4..5be8c63dba10 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -980,9 +980,9 @@ pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] { match bcx.fcx.param_substs { Some(substs) => { - do vec::map(params) |t| { + do params.iter().transform |t| { ty::subst_tps(tcx, substs.tys, substs.self_ty, *t) - } + }.collect() } _ => params } @@ -1006,9 +1006,11 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt, param_substs: Option<@param_substs>, vts: typeck::vtable_res) -> typeck::vtable_res { - @vec::map(*vts, |ds| - @vec::map(**ds, |d| - resolve_vtable_under_param_substs(tcx, param_substs, copy *d))) + @vts.iter().transform(|ds| + @ds.iter().transform( + |d| resolve_vtable_under_param_substs(tcx, param_substs, copy *d)) + .collect::<~[typeck::vtable_origin]>()) + .collect::<~[typeck::vtable_param_res]>() } @@ -1029,9 +1031,9 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt, typeck::vtable_static(trait_id, tys, sub) => { let tys = match param_substs { Some(substs) => { - do vec::map(tys) |t| { + do tys.iter().transform |t| { ty::subst_tps(tcx, substs.tys, substs.self_ty, *t) - } + }.collect() } _ => tys }; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 1511f2541407..df197ded629e 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -588,8 +588,9 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, } ast::expr_tup(ref args) => { let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr)); - return trans_adt(bcx, repr, 0, args.mapi(|i, arg| (i, *arg)), - None, dest); + let numbered_fields: ~[(uint, @ast::expr)] = + args.iter().enumerate().transform(|(i, arg)| (i, *arg)).collect(); + return trans_adt(bcx, repr, 0, numbered_fields, None, dest); } ast::expr_lit(@codemap::spanned {node: ast::lit_str(s), _}) => { return tvec::trans_lit_str(bcx, expr, s, dest); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 4ae8554d7143..ad48c30747ed 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -30,7 +30,6 @@ use middle::ty::{FnSig}; use middle::typeck; use util::ppaux::{Repr,ty_to_str}; -use std::vec; use syntax::ast; use syntax::ast_map; use syntax::ast_map::path_name; @@ -62,12 +61,12 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); let _icx = push_ctxt("monomorphic_fn"); let mut must_cast = false; - let substs = vec::map(real_substs.tps, |t| { + let substs = real_substs.tps.iter().transform(|t| { match normalize_for_monomorphization(ccx.tcx, *t) { Some(t) => { must_cast = true; t } None => *t } - }); + }).collect::<~[ty::t]>(); for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); } for substs.iter().advance |s| { assert!(!ty::type_has_params(*s)); } @@ -325,22 +324,22 @@ pub fn make_mono_id(ccx: @mut CrateContext, vtables: Option, impl_did_opt: Option, param_uses: Option<@~[type_use::type_uses]>) -> mono_id { - let precise_param_ids = match vtables { + // 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 { Some(vts) => { debug!("make_mono_id vtables=%s substs=%s", vts.repr(ccx.tcx), substs.repr(ccx.tcx)); - vec::map_zip(*vts, substs, |vtable, subst| { + 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 }) - }) - } - None => { - vec::map(substs, |subst| (*subst, None)) + }).collect() } + None => substs.iter().transform(|subst| (*subst, None::<@~[mono_id]>)).collect() }; let param_ids = match param_uses { Some(ref uses) => { - vec::map_zip(precise_param_ids, **uses, |id, uses| { + 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) @@ -377,13 +376,13 @@ pub fn make_mono_id(ccx: @mut CrateContext, } } } - }) + }).collect() } None => { - precise_param_ids.map(|x| { + precise_param_ids.iter().transform(|x| { let (a, b) = copy *x; mono_precise(a, b) - }) + }).collect() } }; @mono_id_ {def: item, params: param_ids, impl_did_opt: impl_did_opt} diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8a6fff09c730..bbf548d2659a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3674,15 +3674,15 @@ pub fn substd_enum_variants(cx: ctxt, id: ast::def_id, substs: &substs) -> ~[VariantInfo] { - do vec::map(*enum_variants(cx, id)) |variant_info| { - let substd_args = vec::map(variant_info.args, - |aty| subst(cx, substs, *aty)); + do enum_variants(cx, id).iter().transform |variant_info| { + let substd_args = variant_info.args.iter() + .transform(|aty| subst(cx, substs, *aty)).collect(); let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty); @VariantInfo_{args: substd_args, ctor_ty: substd_ctor_ty, ../*bad*/copy **variant_info} - } + }.collect() } pub fn item_path_str(cx: ctxt, id: ast::def_id) -> ~str { @@ -3815,7 +3815,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] { _ }, _) => { let mut disr_val = -1; - @vec::map(enum_definition.variants, |variant| { + @enum_definition.variants.iter().transform(|variant| { match variant.node.kind { ast::tuple_variant_kind(ref args) => { let ctor_ty = node_id_to_type(cx, variant.node.id); @@ -3848,7 +3848,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] { fail!("struct variant kinds unimpl in enum_variants") } } - }) + }).collect() } _ => cx.sess.bug("tag_variants: id not bound to an enum") } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 1d9895d29503..4d2849c52105 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -718,14 +718,14 @@ pub fn ty_of_closure( let bound_lifetime_names = bound_lifetimes(this, lifetimes); let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names)); - let input_tys = do decl.inputs.mapi |i, a| { + let input_tys = do decl.inputs.iter().enumerate().transform |(i, a)| { let expected_arg_ty = do expected_sig.chain_ref |e| { // no guarantee that the correct number of expected args // were supplied if i < e.inputs.len() {Some(e.inputs[i])} else {None} }; 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 { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index d1edc1cd3630..91b8f01f3362 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1781,7 +1781,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, _ => () } - let tps = vec::map(tys, |ty| fcx.to_ty(*ty)); + let tps = tys.iter().transform(|ty| fcx.to_ty(*ty)).collect::<~[ty::t]>(); match method::lookup(fcx, expr, base, @@ -2766,7 +2766,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let mut bot_field = false; let mut err_field = false; - let elt_ts = do elts.mapi |i, e| { + let elt_ts = do elts.iter().enumerate().transform |(i, e)| { let opt_hint = match flds { Some(ref fs) if i < fs.len() => Some(fs[i]), _ => None @@ -2776,7 +2776,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, err_field = err_field || ty::type_is_error(t); bot_field = bot_field || ty::type_is_bot(t); t - }; + }.collect(); if bot_field { fcx.write_bot(id); } else if err_field { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 3a4fa82906d1..85bd2bc2d75e 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -712,7 +712,7 @@ pub fn convert_methods(ccx: &CrateCtxt, -> ~[ConvertedMethod] { let tcx = ccx.tcx; - return vec::map(ms, |m| { + return ms.iter().transform(|m| { let num_rcvr_ty_params = rcvr_ty_generics.type_param_defs.len(); let m_ty_generics = ty_generics(ccx, rcvr_ty_generics.region_param, &m.generics, @@ -742,7 +742,7 @@ pub fn convert_methods(ccx: &CrateCtxt, tcx.methods.insert(mty.def_id, mty); ConvertedMethod {mty: mty, id: m.id, span: m.span, body_id: m.body.node.id} - }); + }).collect(); fn ty_of_method(ccx: &CrateCtxt, m: &ast::method, diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index bad4cb2fe877..db17405fc266 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1478,7 +1478,7 @@ impl RegionVarBindings { // overlapping locations. let mut dup_vec = graph.nodes.map(|_| uint::max_value); - graph.nodes.mapi(|idx, node| { + graph.nodes.iter().enumerate().transform(|(idx, node)| { match node.value { Value(_) => { /* Inference successful */ @@ -1528,7 +1528,7 @@ impl RegionVarBindings { } node.value - }) + }).collect() } pub fn report_error_for_expanding_node(&mut self, diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index 3efebe854e48..2a9442fbe525 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -26,7 +26,6 @@ use fold::Fold; use fold; use pass::Pass; -use std::vec; use syntax::ast; use syntax::ast_map; @@ -124,7 +123,7 @@ fn fold_enum( let doc = fold::default_seq_fold_enum(fold, doc); doc::EnumDoc { - variants: do vec::map(doc.variants) |variant| { + variants: do doc.variants.iter().transform |variant| { let variant = copy *variant; let desc = { let variant = copy variant; @@ -153,7 +152,7 @@ fn fold_enum( desc: desc, .. variant } - }, + }.collect(), .. doc } } @@ -183,7 +182,7 @@ fn merge_method_attrs( ast_map::node_item(@ast::item { node: ast::item_trait(_, _, ref methods), _ }, _) => { - vec::map(*methods, |method| { + methods.iter().transform(|method| { match copy *method { ast::required(ty_m) => { (to_str(ty_m.ident), @@ -193,21 +192,21 @@ fn merge_method_attrs( (to_str(m.ident), attr_parser::parse_desc(copy m.attrs)) } } - }) + }).collect() } ast_map::node_item(@ast::item { node: ast::item_impl(_, _, _, ref methods), _ }, _) => { - vec::map(*methods, |method| { + methods.iter().transform(|method| { (to_str(method.ident), attr_parser::parse_desc(copy method.attrs)) - }) + }).collect() } _ => fail!("unexpected item") } }; - do vec::map_zip(docs, attrs) |doc, attrs| { + do docs.iter().zip(attrs.iter()).transform |(doc, attrs)| { assert!(doc.name == attrs.first()); let desc = attrs.second(); @@ -215,7 +214,7 @@ fn merge_method_attrs( desc: desc, .. copy *doc } - } + }.collect() } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index c2127eae6253..d5d2b4ce6286 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -186,7 +186,7 @@ fn enumdoc_from_enum( fn variantdocs_from_variants( variants: ~[ast::variant] ) -> ~[doc::VariantDoc] { - vec::map(variants, variantdoc_from_variant) + variants.iter().transform(variantdoc_from_variant).collect() } fn variantdoc_from_variant(variant: &ast::variant) -> doc::VariantDoc { @@ -203,7 +203,7 @@ fn traitdoc_from_trait( ) -> doc::TraitDoc { doc::TraitDoc { item: itemdoc, - methods: do vec::map(methods) |method| { + methods: do methods.iter().transform |method| { match copy *method { ast::required(ty_m) => { doc::MethodDoc { @@ -226,7 +226,7 @@ fn traitdoc_from_trait( } } } - } + }.collect() } } @@ -239,7 +239,7 @@ fn impldoc_from_impl( bounds_str: None, trait_types: ~[], self_ty: None, - methods: do vec::map(methods) |method| { + methods: do methods.iter().transform |method| { doc::MethodDoc { name: to_str(method.ident), brief: None, @@ -248,7 +248,7 @@ fn impldoc_from_impl( sig: None, implementation: doc::Provided, } - } + }.collect() } } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index efb3e61e807f..6510384ef01d 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -13,8 +13,6 @@ use doc; #[cfg(test)] use extract; #[cfg(test)] use parse; -use std::vec; - pub struct Fold { ctxt: T, fold_doc: FoldDoc, @@ -155,7 +153,7 @@ pub fn default_par_fold(ctxt: T) -> Fold { pub fn default_seq_fold_doc(fold: &Fold, doc: doc::Doc) -> doc::Doc { doc::Doc { - pages: do vec::map(doc.pages) |page| { + pages: do doc.pages.iter().transform |page| { match copy *page { doc::CratePage(doc) => { doc::CratePage((fold.fold_crate)(fold, doc)) @@ -164,7 +162,7 @@ pub fn default_seq_fold_doc(fold: &Fold, doc: doc::Doc) -> doc::Doc { doc::ItemPage(fold_ItemTag(fold, doc)) } } - }, + }.collect(), .. doc } } @@ -191,9 +189,9 @@ pub fn default_any_fold_mod( ) -> doc::ModDoc { doc::ModDoc { item: (fold.fold_item)(fold, copy doc.item), - items: vec::map(doc.items, |ItemTag| { + items: doc.items.iter().transform(|ItemTag| { fold_ItemTag(fold, copy *ItemTag) - }), + }).collect(), .. doc } } @@ -204,9 +202,9 @@ pub fn default_seq_fold_mod( ) -> doc::ModDoc { doc::ModDoc { item: (fold.fold_item)(fold, copy doc.item), - items: vec::map(doc.items, |ItemTag| { + items: doc.items.iter().transform(|ItemTag| { fold_ItemTag(fold, copy *ItemTag) - }), + }).collect(), .. doc } } @@ -217,9 +215,9 @@ pub fn default_par_fold_mod( ) -> doc::ModDoc { doc::ModDoc { item: (fold.fold_item)(fold, copy doc.item), - items: vec::map(doc.items, |ItemTag| { + items: doc.items.iter().transform(|ItemTag| { fold_ItemTag(fold, copy *ItemTag) - }), + }).collect(), .. doc } } @@ -230,9 +228,9 @@ pub fn default_any_fold_nmod( ) -> doc::NmodDoc { doc::NmodDoc { item: (fold.fold_item)(fold, copy doc.item), - fns: vec::map(doc.fns, |FnDoc| { + fns: doc.fns.iter().transform(|FnDoc| { (fold.fold_fn)(fold, copy *FnDoc) - }), + }).collect(), .. doc } } @@ -243,9 +241,9 @@ pub fn default_seq_fold_nmod( ) -> doc::NmodDoc { doc::NmodDoc { item: (fold.fold_item)(fold, copy doc.item), - fns: vec::map(doc.fns, |FnDoc| { + fns: doc.fns.iter().transform(|FnDoc| { (fold.fold_fn)(fold, copy *FnDoc) - }), + }).collect(), .. doc } } @@ -256,9 +254,9 @@ pub fn default_par_fold_nmod( ) -> doc::NmodDoc { doc::NmodDoc { item: (fold.fold_item)(fold, copy doc.item), - fns: vec::map(doc.fns, |FnDoc| { + fns: doc.fns.iter().transform(|FnDoc| { (fold.fold_fn)(fold, copy *FnDoc) - }), + }).collect(), .. doc } } diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs index c3b02c91e749..e40bdb532da9 100644 --- a/src/librustdoc/tystr_pass.rs +++ b/src/librustdoc/tystr_pass.rs @@ -20,7 +20,6 @@ use fold::Fold; use fold; use pass::Pass; -use std::vec; use syntax::ast; use syntax::print::pprust; use syntax::parse::token; @@ -114,7 +113,7 @@ fn fold_enum( let srv = fold.ctxt.clone(); doc::EnumDoc { - variants: do vec::map(doc.variants) |variant| { + variants: do doc.variants.iter().transform |variant| { let sig = { let variant = copy *variant; do astsrv::exec(srv.clone()) |ctxt| { @@ -139,7 +138,7 @@ fn fold_enum( sig: Some(sig), .. copy *variant } - }, + }.collect(), .. doc } } @@ -159,12 +158,12 @@ fn merge_methods( item_id: doc::AstId, docs: ~[doc::MethodDoc] ) -> ~[doc::MethodDoc] { - do vec::map(docs) |doc| { + do docs.iter().transform |doc| { doc::MethodDoc { sig: get_method_sig(srv.clone(), item_id, copy doc.name), .. copy *doc } - } + }.collect() } fn get_method_sig( diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 40793ff1af7b..bdcad15f45c4 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1912,7 +1912,9 @@ mod tests { if len <= ivals.len() { assert_eq!(res.len(), len); } - assert!(ivals.slice(0u, res.len()) == vec::map(res, |x| *x as int)); + for ivals.iter().zip(res.iter()).advance |(iv, c)| { + assert!(*iv == *c as int) + } } } let mut i = 0; diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 55eae8f8fae1..77befbf19aa9 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -85,8 +85,7 @@ pub trait IteratorUtil { // FIXME: #5898: should be called map /// Creates a new iterator which will apply the specified function to each - /// element returned by the first, yielding the mapped element instead. This - /// similar to the `vec::map` function. + /// element returned by the first, yielding the mapped element instead. /// /// # Example /// diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index fefd55c35415..457025462783 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -14,6 +14,8 @@ use kinds::Copy; use vec; +use vec::ImmutableVector; +use iterator::IteratorUtil; pub use self::inner::*; @@ -96,7 +98,7 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps for (&'self [A], &'self [B]) { fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { match *self { (ref a, ref b) => { - vec::map_zip(*a, *b, f) + a.iter().zip(b.iter()).transform(|(aa, bb)| f(aa, bb)).collect() } } } @@ -116,7 +118,7 @@ impl ExtendedTupleOps for (~[A], ~[B]) { fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { match *self { (ref a, ref b) => { - vec::map_zip(*a, *b, f) + a.iter().zip(b.iter()).transform(|(aa, bb)| f(aa, bb)).collect() } } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 976a67ef4227..65f962c36ef8 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -365,15 +365,6 @@ pub fn append_one(lhs: ~[T], x: T) -> ~[T] { // Functional utilities -/// Apply a function to each element of a vector and return the results -pub fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { - let mut result = with_capacity(v.len()); - for v.iter().advance |elem| { - result.push(f(elem)); - } - result -} - /// 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 @@ -388,16 +379,6 @@ pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { } result } - -/// Apply a function to each element of a vector and return the results -pub fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { - let mut i = 0; - do map(v) |e| { - i += 1; - f(i - 1, e) - } -} - /** * Apply a function to each element of a vector and return a concatenation * of each result vector @@ -408,23 +389,6 @@ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { result } -/** - * Apply a function to each pair of elements and return the results. - * Equivalent to `map(zip(v0, v1), f)`. - */ -pub fn map_zip(v0: &[T], v1: &[U], - f: &fn(t: &T, v: &U) -> V) -> ~[V] { - let v0_len = v0.len(); - if v0_len != v1.len() { fail!(); } - let mut u: ~[V] = ~[]; - let mut i = 0u; - while i < v0_len { - u.push(f(&v0[i], &v1[i])); - i += 1u; - } - u -} - pub fn filter_map( v: ~[T], f: &fn(t: T) -> Option) -> ~[U] @@ -983,14 +947,13 @@ pub trait ImmutableVector<'self, T> { fn last(&self) -> &'self T; fn last_opt(&self) -> Option<&'self T>; fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; - fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; - fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; - fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U]; 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]; } /// Extension methods for vectors @@ -1087,29 +1050,6 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { None } - /// Apply a function to each element of a vector and return the results - #[inline] - fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) } - - /** - * Apply a function to the index and value of each element in the vector - * and return the results - */ - fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U] { - mapi(*self, f) - } - - #[inline] - fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U] { - let mut r = ~[]; - let mut i = 0; - while i < self.len() { - r.push(f(&self[i])); - i += 1; - } - r - } - /** * Apply a function to each element of a vector and return a concatenation * of each result vector @@ -1165,6 +1105,13 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } return None; } + + /// Deprecated, use iterators where possible + /// (`self.iter().transform(f)`). Apply a function to each element + /// of a vector and return the results. + fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { + self.iter().transform(f).collect() + } } #[allow(missing_doc)] @@ -2101,7 +2048,7 @@ pub mod bytes { impl Clone for ~[A] { #[inline] fn clone(&self) -> ~[A] { - self.map(|item| item.clone()) + self.iter().transform(|item| item.clone()).collect() } } @@ -2648,16 +2595,16 @@ mod tests { #[test] fn test_map() { // Test on-stack map. - let mut v = ~[1u, 2u, 3u]; - let mut w = map(v, square_ref); + let v = &[1u, 2u, 3u]; + let mut w = v.map(square_ref); assert_eq!(w.len(), 3u); assert_eq!(w[0], 1u); assert_eq!(w[1], 4u); assert_eq!(w[2], 9u); // Test on-heap map. - v = ~[1u, 2u, 3u, 4u, 5u]; - w = map(v, square_ref); + let v = ~[1u, 2u, 3u, 4u, 5u]; + w = v.map(square_ref); assert_eq!(w.len(), 5u); assert_eq!(w[0], 1u); assert_eq!(w[1], 4u); @@ -2666,17 +2613,6 @@ mod tests { assert_eq!(w[4], 25u); } - #[test] - fn test_map_zip() { - fn times(x: &int, y: &int) -> int { *x * *y } - let f = times; - let v0 = ~[1, 2, 3, 4, 5]; - let v1 = ~[5, 4, 3, 2, 1]; - let u = map_zip::(v0, v1, f); - let mut i = 0; - while i < 5 { assert!(v0[i] * v1[i] == u[i]); i += 1; } - } - #[test] fn test_filter_mapped() { // Test on-stack filter-map. @@ -2708,7 +2644,7 @@ mod tests { 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) == - map(all_even, halve_for_sure)); + 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); @@ -2746,7 +2682,7 @@ mod tests { 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) == - map(all_even0, halve_for_sure)); + 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); @@ -3278,7 +3214,7 @@ mod tests { fn test_map_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; let mut i = 0; - do map(v) |_elt| { + do v.map |_elt| { if i == 2 { fail!() } @@ -3302,44 +3238,13 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_mapi_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do mapi(v) |_i, _elt| { - if i == 2 { - fail!() - } - i += 0; - ~[(~0, @0)] - }; - } - #[test] #[ignore(windows)] #[should_fail] fn test_flat_map_fail() { let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; let mut i = 0; - do map(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - ~[(~0, @0)] - }; - } - - #[test] - #[ignore(windows)] - #[should_fail] - #[allow(non_implicitly_copyable_typarams)] - fn test_map_zip_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do map_zip(v, v) |_elt1, _elt2| { + do flat_map(v) |_elt| { if i == 2 { fail!() } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index ee7c7180f8db..529d5bfe70b4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -814,7 +814,7 @@ mod test { // convert a list of uints to an @[ident] // (ignores the interner completely) fn uints_to_idents (uints: &~[uint]) -> @~[ident] { - @uints.map(|u|{ ident {name:*u, ctxt: empty_ctxt} }) + @uints.map(|u| ident {name:*u, ctxt: empty_ctxt}) } fn id (u : uint, s: SyntaxContext) -> ident { diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 77dbd96255d1..405f9e3438be 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -91,9 +91,9 @@ fn decodable_substructure(cx: @ExtCtxt, span: span, } } Right(ref fields) => { - let fields = do fields.mapi |i, f| { + let fields = do fields.iter().enumerate().transform |(i, f)| { cx.field_imm(span, *f, getarg(cx.str_of(*f), i)) - }; + }.collect(); cx.expr_struct_ident(span, substr.type_ident, fields) } }; @@ -133,9 +133,9 @@ fn decodable_substructure(cx: @ExtCtxt, span: span, } } Right(ref fields) => { - let fields = do fields.mapi |i, f| { + let fields = do fields.iter().enumerate().transform |(i, f)| { cx.field_imm(span, *f, getarg(i)) - }; + }.collect(); cx.expr_struct_ident(span, name, fields) } }; diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 10d9f878bc45..0e4fc9d96fa8 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -591,14 +591,14 @@ impl<'self> MethodDef<'self> { // transpose raw_fields let fields = match raw_fields { [self_arg, .. rest] => { - do self_arg.mapi |i, &(opt_id, field)| { + do self_arg.iter().enumerate().transform |(i, &(opt_id, field))| { let other_fields = do rest.map |l| { match &l[i] { &(_, ex) => ex } }; (opt_id, field, other_fields) - } + }.collect() } [] => { cx.span_bug(span, "No self arguments to non-static \ method in generic `deriving`") } @@ -745,10 +745,11 @@ impl<'self> MethodDef<'self> { } } let field_tuples = - do vec::map_zip(*self_vec, - enum_matching_fields) |&(id, self_f), &other| { + do self_vec.iter() + .zip(enum_matching_fields.iter()) + .transform |(&(id, self_f), &other)| { (id, self_f, other) - }; + }.collect(); substructure = EnumMatching(variant_index, variant, field_tuples); } None => { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 19aa29a62a9c..cc2050d9bd7a 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -91,7 +91,7 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { let rand_variant = cx.expr_binary(span, ast::rem, rv_call, variant_count); - let mut arms = do variants.mapi |i, id_sum| { + let mut arms = do variants.iter().enumerate().transform |(i, id_sum)| { let i_expr = cx.expr_uint(span, i); let pat = cx.pat_lit(span, i_expr); @@ -102,7 +102,7 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { rand_thing(cx, span, ident, summary, || rand_call())) } } - }; + }.collect::<~[ast::arm]>(); // _ => {} at the end. Should never occur arms.push(cx.arm_unreachable(span)); diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 3044cd50b344..0e24725ea990 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -54,8 +54,9 @@ impl gen_send for message { let next = this.proto.get_state(next_state.state); assert!(next_state.tys.len() == next.generics.ty_params.len()); - let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str())); - let args_ast = vec::map_zip(arg_names, *tys, |n, t| cx.arg(span, *n, *t)); + 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(); let pipe_ty = cx.ty_path( path(~[this.data_name()], span) @@ -133,11 +134,10 @@ impl gen_send for message { message(ref _id, span, ref tys, this, None) => { debug!("pipec: no next state"); - let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str())); + let arg_names = vec::from_fn(tys.len(), |i| "x_" + i.to_str()); - let args_ast = do vec::map_zip(arg_names, *tys) |n, t| { - cx.arg(span, cx.ident_of(*n), *t) - }; + let args_ast: ~[ast::arg] = arg_names.iter().zip(tys.iter()) + .transform(|(n, t)| cx.arg(span, cx.ident_of(*n), *t)).collect(); let args_ast = vec::append( ~[cx.arg(span, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 71dc82be4143..f6325c2eb2c1 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -21,7 +21,6 @@ use print::pprust; use std::io; use std::result; -use std::vec; // These macros all relate to the file system; they either return // the column/row/filename of the expression, or they include @@ -106,9 +105,7 @@ pub fn expand_include_bin(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) let file = get_single_str_from_tts(cx, sp, tts, "include_bin!"); match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) { result::Ok(src) => { - let u8_exprs = vec::map(src, |char| { - cx.expr_u8(sp, *char) - }); + let u8_exprs: ~[@ast::expr] = src.iter().transform(|char| cx.expr_u8(sp, *char)).collect(); base::MRExpr(cx.expr_vec(sp, u8_exprs)) } result::Err(ref e) => { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 7c69bdd01c81..cddba3583734 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -326,8 +326,7 @@ pub fn parse( cur_eis.push(new_ei); } - let matches = vec::map(ei.matches, // fresh, same size: - |_m| ~[]); + let matches = vec::from_elem(ei.matches.len(), ~[]); let ei_t = ei; cur_eis.push(~MatcherPos { elts: copy *matchers, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2fc111da453c..4e1451239962 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -699,7 +699,7 @@ 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: vec::map(m.view_items, |x| fld.fold_view_item(*x)), + 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)), } } @@ -708,8 +708,8 @@ fn noop_fold_foreign_mod(nm: &foreign_mod, fld: @ast_fold) -> foreign_mod { ast::foreign_mod { sort: nm.sort, abis: nm.abis, - view_items: vec::map(nm.view_items, |x| fld.fold_view_item(*x)), - items: vec::map(nm.items, |x| fld.fold_foreign_item(*x)), + 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(), } } @@ -728,8 +728,8 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { } struct_variant_kind(struct_def) => { kind = struct_variant_kind(@ast::struct_def { - fields: vec::map(struct_def.fields, - |f| fld.fold_struct_field(*f)), + fields: struct_def.fields.iter() + .transform(|f| fld.fold_struct_field(*f)).collect(), ctor_id: struct_def.ctor_id.map(|c| fld.new_id(*c)) }) } @@ -824,8 +824,7 @@ impl ast_fold for AstFoldFns { @view_item { @ast::view_item { node: (self.fold_view_item)(&x.node, self as @ast_fold), - attrs: vec::map(x.attrs, |a| - fold_attribute_(*a, self as @ast_fold)), + attrs: x.attrs.iter().transform(|a| fold_attribute_(*a, self as @ast_fold)).collect(), vis: x.vis, span: (self.new_span)(x.span), } diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index eeff4b71c0d2..bc5efc5fca1f 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -191,13 +191,13 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { // Do the BFS. info!("PBFS iteration %?", i); i += 1; - colors = do colors.mapi() |i, c| { + colors = do colors.iter().enumerate().transform |(i, c)| { let c : color = *c; match c { white => { let i = i as node_id; - let neighbors = copy graph[i]; + let neighbors = &graph[i]; let mut color = white; @@ -214,17 +214,17 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { gray(parent) => { black(parent) } black(parent) => { black(parent) } } - } + }.collect() } // Convert the results. - do vec::map(colors) |c| { + do colors.iter().transform |c| { match *c { white => { -1i64 } black(parent) => { parent } _ => { fail!("Found remaining gray nodes in BFS") } } - } + }.collect() } /// A parallel version of the bfs function. diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 49a3a3ec5d7d..deb2d4b300bc 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -152,7 +152,7 @@ fn rendezvous(nn: uint, set: ~[color]) { // these channels will allow us to talk to each creature by 'name'/index let to_creature: ~[Chan>] = - vec::mapi(set, |ii, col| { + set.iter().enumerate().transform(|(ii, col)| { // create each creature as a listener with a port, and // give us a channel to talk to each let ii = ii; @@ -166,7 +166,7 @@ fn rendezvous(nn: uint, set: ~[color]) { to_rendezvous_log.clone()); } to_creature - }); + }).collect(); let mut creatures_met = 0; diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index d26fe80e8a12..974cdb0a0ef6 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-pretty (extra blank line is inserted in vec::mapi call) +// xfail-pretty the `let to_child` line gets an extra newline // multi tasking k-nucleotide extern mod extra; @@ -163,14 +163,13 @@ fn main() { - // initialize each sequence sorter - let sizes = ~[1,2,3,4,6,12,18]; - let streams = vec::map(sizes, |_sz| Some(stream())); - let mut streams = streams; + // initialize each sequence sorter + let sizes = ~[1u,2,3,4,6,12,18]; + let mut streams = vec::from_fn(sizes.len(), |_| Some(stream::<~str>())); let mut from_child = ~[]; - let to_child = vec::mapi(sizes, |ii, sz| { + let to_child = do sizes.iter().zip(streams.mut_iter()).transform |(sz, stream_ref)| { let sz = *sz; - let stream = util::replace(&mut streams[ii], None); + let stream = util::replace(stream_ref, None); let (from_child_, to_parent_) = stream.unwrap(); from_child.push(from_child_); @@ -182,7 +181,7 @@ fn main() { }; to_child - }); + }.collect::<~[Chan<~[u8]>]>(); // latch stores true after we've started diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index 4a748cc56700..e61de0ac11f4 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, map}; //~ ERROR unused import +use std::vec::{filter, from_elem}; //~ ERROR unused import mod foo { pub struct Point{x: int, y: int} @@ -58,7 +58,5 @@ fn main() { let a = 3; ignore(a); io::stdout().write_str("a"); - let _a = do map([2]) |&x| { - x + 2 - }; + let _a = from_elem(0, 0); } diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index ff5d0e9f05c6..8ea2a88fa09a 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -28,7 +28,7 @@ pub fn main() { assert!(any_negative); // Higher precedence than unary operations: - let abs_v = do vec::map(v) |e| { e.abs() }; + 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() }); diff --git a/src/test/run-pass/block-vec-map_zip.rs b/src/test/run-pass/block-vec-map_zip.rs deleted file mode 100644 index 739dbab4d3af..000000000000 --- a/src/test/run-pass/block-vec-map_zip.rs +++ /dev/null @@ -1,20 +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. - -use std::vec; - -pub fn main() { - let v = - vec::map_zip(~[1, 2, 3, 4, 5], - ~[true, false, false, true, true], - |i, b| if *b { -(*i) } else { *i } ); - error!(v.clone()); - assert_eq!(v, ~[-1, 2, 3, -4, -5]); -} diff --git a/src/test/run-pass/trait-to-str.rs b/src/test/run-pass/trait-to-str.rs index 4029bd18338c..3e4cfdc105ca 100644 --- a/src/test/run-pass/trait-to-str.rs +++ b/src/test/run-pass/trait-to-str.rs @@ -15,7 +15,9 @@ extern mod std; use std::str::StrVector; -use std::{int, vec}; +use std::vec::ImmutableVector; +use std::iterator::IteratorUtil; +use std::int; trait to_str { fn to_str(&self) -> ~str; @@ -27,7 +29,7 @@ impl to_str for int { impl to_str for ~[T] { fn to_str(&self) -> ~str { - ~"[" + vec::map(*self, |e| e.to_str()).connect(", ") + "]" + fmt!("[%s]", self.iter().transform(|e| e.to_str()).collect::<~[~str]>().connect(", ")) } } From 8fe6fc11de4d6bfbffd8b961f5f1f24a338601d5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 28 Jun 2013 14:04:13 -0700 Subject: [PATCH 309/336] Change char::escape_{default,unicode} to take callbacks instead of allocating strings --- src/libstd/char.rs | 107 ++++++++++++++++++---------------- src/libstd/repr.rs | 6 +- src/libsyntax/parse/token.rs | 8 ++- src/libsyntax/print/pprust.rs | 8 ++- 4 files changed, 73 insertions(+), 56 deletions(-) diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 8f0870af5133..101ea67cf592 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -12,12 +12,11 @@ use container::Container; use option::{None, Option, Some}; -use str; -use str::{StrSlice, OwnedStr}; -use u32; -use uint; +use str::StrSlice; use unicode::{derived_property, general_category}; +#[cfg(test)] use str::OwnedStr; + #[cfg(not(test))] use cmp::{Eq, Ord}; #[cfg(not(test))] use num::Zero; @@ -202,21 +201,21 @@ pub fn from_digit(num: uint, radix: uint) -> Option { /// - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN` /// - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN` /// -pub fn escape_unicode(c: char) -> ~str { - let s = u32::to_str_radix(c as u32, 16u); - let (c, pad) = cond!( - (c <= '\xff') { ('x', 2u) } - (c <= '\uffff') { ('u', 4u) } - _ { ('U', 8u) } +pub fn escape_unicode(c: char, f: &fn(char)) { + // avoid calling str::to_str_radix because we don't really need to allocate + // here. + f('\\'); + let pad = cond!( + (c <= '\xff') { f('x'); 2 } + (c <= '\uffff') { f('u'); 4 } + _ { f('U'); 8 } ); - assert!(s.len() <= pad); - let mut out = ~"\\"; - out.push_str(str::from_char(c)); - for uint::range(s.len(), pad) |_| { - out.push_str("0"); + for int::range_step(4 * (pad - 1), -1, -4) |offset| { + match ((c as u32) >> offset) & 0xf { + i @ 0 .. 9 => { f('0' + i as char); } + i => { f('a' + (i - 10) as char); } + } } - out.push_str(s); - out } /// @@ -231,16 +230,16 @@ pub fn escape_unicode(c: char) -> ~str { /// - Any other chars in the range [0x20,0x7e] are not escaped. /// - Any other chars are given hex unicode escapes; see `escape_unicode`. /// -pub fn escape_default(c: char) -> ~str { +pub fn escape_default(c: char, f: &fn(char)) { match c { - '\t' => ~"\\t", - '\r' => ~"\\r", - '\n' => ~"\\n", - '\\' => ~"\\\\", - '\'' => ~"\\'", - '"' => ~"\\\"", - '\x20' .. '\x7e' => str::from_char(c), - _ => c.escape_unicode(), + '\t' => { f('\\'); f('t'); } + '\r' => { f('\\'); f('r'); } + '\n' => { f('\\'); f('n'); } + '\\' => { f('\\'); f('\\'); } + '\'' => { f('\\'); f('\''); } + '"' => { f('\\'); f('"'); } + '\x20' .. '\x7e' => { f(c); } + _ => c.escape_unicode(f), } } @@ -274,8 +273,8 @@ pub trait Char { fn is_digit_radix(&self, radix: uint) -> bool; fn to_digit(&self, radix: uint) -> Option; fn from_digit(num: uint, radix: uint) -> Option; - fn escape_unicode(&self) -> ~str; - fn escape_default(&self) -> ~str; + fn escape_unicode(&self, f: &fn(char)); + fn escape_default(&self, f: &fn(char)); fn len_utf8_bytes(&self) -> uint; } @@ -302,9 +301,9 @@ impl Char for char { fn from_digit(num: uint, radix: uint) -> Option { from_digit(num, radix) } - fn escape_unicode(&self) -> ~str { escape_unicode(*self) } + fn escape_unicode(&self, f: &fn(char)) { escape_unicode(*self, f) } - fn escape_default(&self) -> ~str { escape_default(*self) } + fn escape_default(&self, f: &fn(char)) { escape_default(*self, f) } fn len_utf8_bytes(&self) -> uint { len_utf8_bytes(*self) } } @@ -392,27 +391,37 @@ fn test_is_digit() { #[test] fn test_escape_default() { - assert_eq!('\n'.escape_default(), ~"\\n"); - assert_eq!('\r'.escape_default(), ~"\\r"); - assert_eq!('\''.escape_default(), ~"\\'"); - assert_eq!('"'.escape_default(), ~"\\\""); - assert_eq!(' '.escape_default(), ~" "); - assert_eq!('a'.escape_default(), ~"a"); - assert_eq!('~'.escape_default(), ~"~"); - assert_eq!('\x00'.escape_default(), ~"\\x00"); - assert_eq!('\x1f'.escape_default(), ~"\\x1f"); - assert_eq!('\x7f'.escape_default(), ~"\\x7f"); - assert_eq!('\xff'.escape_default(), ~"\\xff"); - assert_eq!('\u011b'.escape_default(), ~"\\u011b"); - assert_eq!('\U0001d4b6'.escape_default(), ~"\\U0001d4b6"); + fn string(c: char) -> ~str { + let mut result = ~""; + do escape_default(c) |c| { result.push_char(c); } + return result; + } + assert_eq!(string('\n'), ~"\\n"); + assert_eq!(string('\r'), ~"\\r"); + assert_eq!(string('\''), ~"\\'"); + assert_eq!(string('"'), ~"\\\""); + assert_eq!(string(' '), ~" "); + assert_eq!(string('a'), ~"a"); + assert_eq!(string('~'), ~"~"); + assert_eq!(string('\x00'), ~"\\x00"); + assert_eq!(string('\x1f'), ~"\\x1f"); + assert_eq!(string('\x7f'), ~"\\x7f"); + assert_eq!(string('\xff'), ~"\\xff"); + assert_eq!(string('\u011b'), ~"\\u011b"); + assert_eq!(string('\U0001d4b6'), ~"\\U0001d4b6"); } #[test] fn test_escape_unicode() { - assert_eq!('\x00'.escape_unicode(), ~"\\x00"); - assert_eq!('\n'.escape_unicode(), ~"\\x0a"); - assert_eq!(' '.escape_unicode(), ~"\\x20"); - assert_eq!('a'.escape_unicode(), ~"\\x61"); - assert_eq!('\u011b'.escape_unicode(), ~"\\u011b"); - assert_eq!('\U0001d4b6'.escape_unicode(), ~"\\U0001d4b6"); + fn string(c: char) -> ~str { + let mut result = ~""; + do escape_unicode(c) |c| { result.push_char(c); } + return result; + } + assert_eq!(string('\x00'), ~"\\x00"); + assert_eq!(string('\n'), ~"\\x0a"); + assert_eq!(string(' '), ~"\\x20"); + assert_eq!(string('a'), ~"\\x61"); + assert_eq!(string('\u011b'), ~"\\u011b"); + assert_eq!(string('\U0001d4b6'), ~"\\U0001d4b6"); } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index f39b5a00ed05..a96949d84c98 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -57,9 +57,9 @@ impl EscapedCharWriter for @Writer { '"' => self.write_str("\\\""), '\x20'..'\x7e' => self.write_char(ch), _ => { - // FIXME #4423: This is inefficient because it requires a - // malloc. - self.write_str(char::escape_unicode(ch)) + do char::escape_unicode(ch) |c| { + self.write_char(c); + } } } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 94147825da49..a50fa4168320 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -16,7 +16,6 @@ use util::interner::StrInterner; use util::interner; use std::cast; -use std::char; use std::cmp::Equiv; use std::local_data; use std::rand; @@ -166,7 +165,12 @@ pub fn to_str(in: @ident_interner, t: &Token) -> ~str { /* Literals */ LIT_INT(c, ast::ty_char) => { - ~"'" + char::escape_default(c as char) + "'" + let mut res = ~"'"; + do (c as char).escape_default |c| { + res.push_char(c); + } + res.push_char('\''); + res } LIT_INT(i, t) => { i.to_str() + ast_util::int_ty_to_str(t) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 978561eaa67c..5e685d85f95d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -27,7 +27,6 @@ use print::pp::{breaks, consistent, inconsistent, eof}; use print::pp; use print::pprust; -use std::char; use std::io; use std::u64; use std::uint; @@ -2016,7 +2015,12 @@ pub fn print_literal(s: @ps, lit: @ast::lit) { match lit.node { ast::lit_str(st) => print_string(s, st), ast::lit_int(ch, ast::ty_char) => { - word(s.s, ~"'" + char::escape_default(ch as char) + "'"); + let mut res = ~"'"; + do (ch as char).escape_default |c| { + res.push_char(c); + } + res.push_char('\''); + word(s.s, res); } ast::lit_int(i, t) => { if i < 0_i64 { From d3155faedee97cb916735573fbf067d6305ee730 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 28 Jun 2013 14:05:10 -0700 Subject: [PATCH 310/336] Specialize to_str_common for floats/integers in strconv This allows the integral paths to avoid allocations on the heap Closes #4424, #4423 --- src/libextra/terminfo/parm.rs | 16 ++- src/libstd/char.rs | 2 +- src/libstd/num/f32.rs | 22 ++-- src/libstd/num/f64.rs | 22 ++-- src/libstd/num/float.rs | 22 ++-- src/libstd/num/int_macros.rs | 27 +++-- src/libstd/num/strconv.rs | 196 ++++++++++++++++++++-------------- src/libstd/num/uint_macros.rs | 27 +++-- src/libstd/repr.rs | 78 +++++--------- src/libstd/str.rs | 35 +++++- 10 files changed, 250 insertions(+), 197 deletions(-) diff --git a/src/libextra/terminfo/parm.rs b/src/libextra/terminfo/parm.rs index f3edd81f9acd..b7d21ea0ee3f 100644 --- a/src/libextra/terminfo/parm.rs +++ b/src/libextra/terminfo/parm.rs @@ -11,7 +11,7 @@ //! Parameterized string expansion use std::{char, vec, util}; -use std::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common}; +use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common}; use std::iterator::IteratorUtil; #[deriving(Eq)] @@ -469,14 +469,20 @@ priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> { FormatHex|FormatHEX => 16, FormatString => util::unreachable() }; - let (s,_) = match op { + let mut s = ~[]; + match op { FormatDigit => { let sign = if flags.sign { SignAll } else { SignNeg }; - to_str_bytes_common(&d, radix, false, sign, DigAll) + do int_to_str_bytes_common(d, radix, sign) |c| { + s.push(c); + } + } + _ => { + do int_to_str_bytes_common(d as uint, radix, SignNone) |c| { + s.push(c); + } } - _ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll) }; - let mut s = s; if flags.precision > s.len() { let mut s_ = vec::with_capacity(flags.precision); let n = flags.precision - s.len(); diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 101ea67cf592..6a9555f4efcd 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -10,8 +10,8 @@ //! Utilities for manipulating the char type -use container::Container; use option::{None, Option, Some}; +use int; use str::StrSlice; use unicode::{derived_property, general_category}; diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 117a474ffd7d..0b6eb766b299 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -754,8 +754,8 @@ impl Float for f32 { /// #[inline] pub fn to_str(num: f32) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -768,8 +768,8 @@ pub fn to_str(num: f32) -> ~str { /// #[inline] pub fn to_str_hex(num: f32) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 16u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -789,8 +789,8 @@ pub fn to_str_hex(num: f32) -> ~str { /// #[inline] pub fn to_str_radix(num: f32, rdx: uint) -> ~str { - let (r, special) = strconv::to_str_common( - &num, rdx, true, strconv::SignNeg, strconv::DigAll); + let (r, special) = strconv::float_to_str_common( + num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!("number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -807,7 +807,7 @@ pub fn to_str_radix(num: f32, rdx: uint) -> ~str { /// #[inline] pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { - strconv::to_str_common(&num, rdx, true, + strconv::float_to_str_common(num, rdx, true, strconv::SignNeg, strconv::DigAll) } @@ -822,8 +822,8 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) { /// #[inline] pub fn to_str_exact(num: f32, dig: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r } @@ -838,8 +838,8 @@ pub fn to_str_exact(num: f32, dig: uint) -> ~str { /// #[inline] pub fn to_str_digits(num: f32, dig: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index e13dff1e6235..c39c7a3a57d2 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -796,8 +796,8 @@ impl Float for f64 { /// #[inline] pub fn to_str(num: f64) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -810,8 +810,8 @@ pub fn to_str(num: f64) -> ~str { /// #[inline] pub fn to_str_hex(num: f64) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 16u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -831,8 +831,8 @@ pub fn to_str_hex(num: f64) -> ~str { /// #[inline] pub fn to_str_radix(num: f64, rdx: uint) -> ~str { - let (r, special) = strconv::to_str_common( - &num, rdx, true, strconv::SignNeg, strconv::DigAll); + let (r, special) = strconv::float_to_str_common( + num, rdx, true, strconv::SignNeg, strconv::DigAll); if special { fail!("number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -849,7 +849,7 @@ pub fn to_str_radix(num: f64, rdx: uint) -> ~str { /// #[inline] pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { - strconv::to_str_common(&num, rdx, true, + strconv::float_to_str_common(num, rdx, true, strconv::SignNeg, strconv::DigAll) } @@ -864,8 +864,8 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) { /// #[inline] pub fn to_str_exact(num: f64, dig: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigExact(dig)); r } @@ -880,8 +880,8 @@ pub fn to_str_exact(num: f64, dig: uint) -> ~str { /// #[inline] pub fn to_str_digits(num: f64, dig: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigMax(dig)); r } diff --git a/src/libstd/num/float.rs b/src/libstd/num/float.rs index c583aeacf162..7a6e3042e7b7 100644 --- a/src/libstd/num/float.rs +++ b/src/libstd/num/float.rs @@ -101,8 +101,8 @@ pub mod consts { /// #[inline] pub fn to_str(num: float) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigAll); r } @@ -115,8 +115,8 @@ pub fn to_str(num: float) -> ~str { /// #[inline] pub fn to_str_hex(num: float) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 16u, true, strconv::SignNeg, strconv::DigAll); + let (r, _) = strconv::float_to_str_common( + num, 16u, true, strconv::SignNeg, strconv::DigAll); r } @@ -136,8 +136,8 @@ pub fn to_str_hex(num: float) -> ~str { /// #[inline] pub fn to_str_radix(num: float, radix: uint) -> ~str { - let (r, special) = strconv::to_str_common( - &num, radix, true, strconv::SignNeg, strconv::DigAll); + let (r, special) = strconv::float_to_str_common( + num, radix, true, strconv::SignNeg, strconv::DigAll); if special { fail!("number has a special value, \ try to_str_radix_special() if those are expected") } r @@ -154,7 +154,7 @@ pub fn to_str_radix(num: float, radix: uint) -> ~str { /// #[inline] pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { - strconv::to_str_common(&num, radix, true, + strconv::float_to_str_common(num, radix, true, strconv::SignNeg, strconv::DigAll) } @@ -169,8 +169,8 @@ pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) { /// #[inline] pub fn to_str_exact(num: float, digits: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigExact(digits)); r } @@ -185,8 +185,8 @@ pub fn to_str_exact(num: float, digits: uint) -> ~str { /// #[inline] pub fn to_str_digits(num: float, digits: uint) -> ~str { - let (r, _) = strconv::to_str_common( - &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits)); + let (r, _) = strconv::float_to_str_common( + num, 10u, true, strconv::SignNeg, strconv::DigMax(digits)); r } diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 845152f85525..f152d60cb7a3 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -17,6 +17,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated { use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; use prelude::*; +use str; pub use cmp::{min, max}; @@ -529,25 +530,33 @@ impl FromStrRadix for $T { /// Convert to a string as a byte slice in a given base. #[inline] pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { - let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, - strconv::SignNeg, strconv::DigAll); - f(buf) + // The radix can be as low as 2, so we need at least 64 characters for a + // base 2 number, and then we need another for a possible '-' character. + let mut buf = [0u8, ..65]; + let mut cur = 0; + do strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg) |i| { + buf[cur] = i; + cur += 1; + } + f(buf.slice(0, cur)) } /// Convert to a string in base 10. #[inline] pub fn to_str(num: $T) -> ~str { - let (buf, _) = strconv::to_str_common(&num, 10u, false, - strconv::SignNeg, strconv::DigAll); - buf + to_str_radix(num, 10u) } /// Convert to a string in a given base. #[inline] pub fn to_str_radix(num: $T, radix: uint) -> ~str { - let (buf, _) = strconv::to_str_common(&num, radix, false, - strconv::SignNeg, strconv::DigAll); - buf + let mut buf: ~[u8] = ~[]; + do strconv::int_to_str_bytes_common(num, radix, strconv::SignNeg) |i| { + buf.push(i); + } + // We know we generated valid utf-8, so we don't need to go through that + // check. + unsafe { str::raw::from_bytes_owned(buf) } } impl ToStr for $T { diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index a062838aacf0..1b1b82190d55 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -16,13 +16,13 @@ use ops::{Add, Sub, Mul, Div, Rem, Neg}; use option::{None, Option, Some}; use char; use str; -use str::{StrSlice}; +use str::StrSlice; use kinds::Copy; use vec; use vec::{CopyableVector, ImmutableVector}; use vec::OwnedVector; -use num::{NumCast, Zero, One, cast, pow_with_uint}; -use f64; +use num::{NumCast, Zero, One, cast, pow_with_uint, Integer}; +use num::{Round, Float, FPNaN, FPInfinite}; pub enum ExponentFormat { ExpNone, @@ -42,35 +42,6 @@ pub enum SignFormat { SignAll } -#[inline] -fn is_NaN(num: &T) -> bool { - *num != *num -} - -#[inline] -fn is_inf(num: &T) -> bool { - match NumStrConv::inf() { - None => false, - Some(n) => *num == n - } -} - -#[inline] -fn is_neg_inf(num: &T) -> bool { - match NumStrConv::neg_inf() { - None => false, - Some(n) => *num == n - } -} - -#[inline] -fn is_neg_zero>(num: &T) -> bool { - let _0: T = Zero::zero(); - let _1: T = One::one(); - - *num == _0 && is_neg_inf(&(_1 / *num)) -} - pub trait NumStrConv { fn NaN() -> Option; fn inf() -> Option; @@ -93,16 +64,9 @@ macro_rules! impl_NumStrConv_Floating (($t:ty) => ( fn neg_zero() -> Option<$t> { Some(-0.0 ) } #[inline] - fn round_to_zero(&self) -> $t { - ( if *self < 0.0 { f64::ceil(*self as f64) } - else { f64::floor(*self as f64) } - ) as $t - } - + fn round_to_zero(&self) -> $t { self.trunc() } #[inline] - fn fractional_part(&self) -> $t { - *self - self.round_to_zero() - } + fn fractional_part(&self) -> $t { self.fract() } } )) @@ -145,6 +109,87 @@ static negative_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]; +/** + * Converts an integral number to its string representation as a byte vector. + * This is meant to be a common base implementation for all integral string + * conversion functions like `to_str()` or `to_str_radix()`. + * + * # Arguments + * - `num` - The number to convert. Accepts any number that + * implements the numeric traits. + * - `radix` - Base to use. Accepts only the values 2-36. + * - `sign` - How to emit the sign. Options are: + * - `SignNone`: No sign at all. Basically emits `abs(num)`. + * - `SignNeg`: Only `-` on negative values. + * - `SignAll`: Both `+` on positive, and `-` on negative numbers. + * - `f` - a callback which will be invoked for each ascii character + * which composes the string representation of this integer + * + * # Return value + * A tuple containing the byte vector, and a boolean flag indicating + * whether it represents a special value like `inf`, `-inf`, `NaN` or not. + * It returns a tuple because there can be ambiguity between a special value + * and a number representation at higher bases. + * + * # Failure + * - Fails if `radix` < 2 or `radix` > 36. + */ +pub fn int_to_str_bytes_common+Neg+Rem+Mul>( + num: T, radix: uint, sign: SignFormat, f: &fn(u8)) { + assert!(2 <= radix && radix <= 36); + + let _0: T = Zero::zero(); + + let neg = num < _0; + let radix_gen: T = cast(radix); + + let mut deccum = num; + // This is just for integral types, the largest of which is a u64. The + // smallest base that we can have is 2, so the most number of digits we're + // ever going to have is 64 + let mut buf = [0u8, ..64]; + let mut cur = 0; + + // Loop at least once to make sure at least a `0` gets emitted. + loop { + // Calculate the absolute value of each digit instead of only + // doing it once for the whole number because a + // representable negative number doesn't necessary have an + // representable additive inverse of the same type + // (See twos complement). But we assume that for the + // numbers [-35 .. 0] we always have [0 .. 35]. + let current_digit_signed = deccum % radix_gen; + let current_digit = if current_digit_signed < _0 { + -current_digit_signed + } else { + current_digit_signed + }; + buf[cur] = match current_digit.to_u8() { + i @ 0..9 => '0' as u8 + i, + i => 'a' as u8 + (i - 10), + }; + cur += 1; + + deccum = deccum / radix_gen; + // No more digits to calculate for the non-fractional part -> break + if deccum == _0 { break; } + } + + // Decide what sign to put in front + match sign { + SignNeg | SignAll if neg => { f('-' as u8); } + SignAll => { f('+' as u8); } + _ => () + } + + // We built the number in reverse order, so un-reverse it here + while cur > 0 { + cur -= 1; + f(buf[cur]); + } +} + /** * Converts a number to its string representation as a byte vector. * This is meant to be a common base implementation for all numeric string @@ -176,44 +221,39 @@ static nan_buf: [u8, ..3] = ['N' as u8, 'a' as u8, 'N' as u8]; * # Failure * - Fails if `radix` < 2 or `radix` > 36. */ -pub fn to_str_bytes_common+Neg+Rem+Mul>( - num: &T, radix: uint, negative_zero: bool, + num: T, radix: uint, negative_zero: bool, sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) { - if (radix as int) < 2 { - fail!("to_str_bytes_common: radix %? to low, must lie in the range [2, 36]", radix); - } else if radix as int > 36 { - fail!("to_str_bytes_common: radix %? to high, must lie in the range [2, 36]", radix); - } + assert!(2 <= radix && radix <= 36); let _0: T = Zero::zero(); let _1: T = One::one(); - if is_NaN(num) { - return ("NaN".as_bytes().to_owned(), true); - } - else if is_inf(num){ - return match sign { - SignAll => ("+inf".as_bytes().to_owned(), true), - _ => ("inf".as_bytes().to_owned(), true) + match num.classify() { + FPNaN => { return ("NaN".as_bytes().to_owned(), true); } + FPInfinite if num > _0 => { + return match sign { + SignAll => ("+inf".as_bytes().to_owned(), true), + _ => ("inf".as_bytes().to_owned(), true) + }; } - } - else if is_neg_inf(num) { - return match sign { - SignNone => ("inf".as_bytes().to_owned(), true), - _ => ("-inf".as_bytes().to_owned(), true), + FPInfinite if num < _0 => { + return match sign { + SignNone => ("inf".as_bytes().to_owned(), true), + _ => ("-inf".as_bytes().to_owned(), true), + }; } + _ => {} } - let neg = *num < _0 || (negative_zero && is_neg_zero(num)); + let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity()); let mut buf: ~[u8] = ~[]; let radix_gen: T = cast(radix as int); - let mut deccum; - // First emit the non-fractional part, looping at least once to make // sure at least a `0` gets emitted. - deccum = num.round_to_zero(); + let mut deccum = num.trunc(); loop { // Calculate the absolute value of each digit instead of only // doing it once for the whole number because a @@ -221,16 +261,11 @@ pub fn to_str_bytes_common 0) { buf.push('.' as u8); let mut dig = 0u; @@ -286,18 +321,13 @@ pub fn to_str_bytes_common+Neg+Rem+Mul>( - num: &T, radix: uint, negative_zero: bool, +pub fn float_to_str_common+Neg+Rem+Mul>( + num: T, radix: uint, negative_zero: bool, sign: SignFormat, digits: SignificantDigits) -> (~str, bool) { - let (bytes, special) = to_str_bytes_common(num, radix, + let (bytes, special) = float_to_str_bytes_common(num, radix, negative_zero, sign, digits); (str::from_bytes(bytes), special) } diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 0dabe7fafa83..25e338fcd0f6 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -18,6 +18,7 @@ use num::BitCount; use num::{ToStrRadix, FromStrRadix}; use num::{Zero, One, strconv}; use prelude::*; +use str; pub use cmp::{min, max}; @@ -356,25 +357,33 @@ impl FromStrRadix for $T { /// Convert to a string as a byte slice in a given base. #[inline] pub fn to_str_bytes(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { - let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, - strconv::SignNeg, strconv::DigAll); - f(buf) + // The radix can be as low as 2, so we need at least 64 characters for a + // base 2 number. + let mut buf = [0u8, ..64]; + let mut cur = 0; + do strconv::int_to_str_bytes_common(n, radix, strconv::SignNone) |i| { + buf[cur] = i; + cur += 1; + } + f(buf.slice(0, cur)) } /// Convert to a string in base 10. #[inline] pub fn to_str(num: $T) -> ~str { - let (buf, _) = strconv::to_str_common(&num, 10u, false, - strconv::SignNeg, strconv::DigAll); - buf + to_str_radix(num, 10u) } /// Convert to a string in a given base. #[inline] pub fn to_str_radix(num: $T, radix: uint) -> ~str { - let (buf, _) = strconv::to_str_common(&num, radix, false, - strconv::SignNeg, strconv::DigAll); - buf + let mut buf = ~[]; + do strconv::int_to_str_bytes_common(num, radix, strconv::SignNone) |i| { + buf.push(i); + } + // We know we generated valid utf-8, so we don't need to go through that + // check. + unsafe { str::raw::from_bytes_owned(buf) } } impl ToStr for $T { diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index a96949d84c98..fdda65d3e95b 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -81,65 +81,35 @@ impl Repr for bool { } } -impl Repr for int { - fn write_repr(&self, writer: @Writer) { writer.write_int(*self); } -} -impl Repr for i8 { - fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); } -} -impl Repr for i16 { - fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); } -} -impl Repr for i32 { - fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); } -} -impl Repr for i64 { - // FIXME #4424: This can lose precision. - fn write_repr(&self, writer: @Writer) { writer.write_int(*self as int); } -} - -impl Repr for uint { - fn write_repr(&self, writer: @Writer) { writer.write_uint(*self); } -} -impl Repr for u8 { +macro_rules! int_repr(($ty:ident) => (impl Repr for $ty { fn write_repr(&self, writer: @Writer) { - writer.write_uint(*self as uint); + do ::$ty::to_str_bytes(*self, 10u) |bits| { + writer.write(bits); + } } -} -impl Repr for u16 { - fn write_repr(&self, writer: @Writer) { - writer.write_uint(*self as uint); - } -} -impl Repr for u32 { - fn write_repr(&self, writer: @Writer) { - writer.write_uint(*self as uint); - } -} -impl Repr for u64 { - // FIXME #4424: This can lose precision. - fn write_repr(&self, writer: @Writer) { - writer.write_uint(*self as uint); - } -} +})) -impl Repr for float { - // FIXME #4423: This mallocs. - fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); } -} -impl Repr for f32 { - // FIXME #4423 This mallocs. - fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); } -} -impl Repr for f64 { - // FIXME #4423: This mallocs. - fn write_repr(&self, writer: @Writer) { writer.write_str(self.to_str()); } -} +int_repr!(int) +int_repr!(i8) +int_repr!(i16) +int_repr!(i32) +int_repr!(i64) +int_repr!(uint) +int_repr!(u8) +int_repr!(u16) +int_repr!(u32) +int_repr!(u64) -impl Repr for char { - fn write_repr(&self, writer: @Writer) { writer.write_char(*self); } -} +macro_rules! num_repr(($ty:ident) => (impl Repr for $ty { + fn write_repr(&self, writer: @Writer) { + let s = self.to_str(); + writer.write(s.as_bytes()); + } +})) +num_repr!(float) +num_repr!(f32) +num_repr!(f64) // New implementation using reflect::MovePtr diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 8e0b3b6ad355..4115cad65594 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -54,7 +54,6 @@ Section: Creating a string * * Raises the `not_utf8` condition if invalid UTF-8 */ - pub fn from_bytes(vv: &[u8]) -> ~str { use str::not_utf8::cond; @@ -68,6 +67,25 @@ pub fn from_bytes(vv: &[u8]) -> ~str { } } +/** + * Consumes a vector of bytes to create a new utf-8 string + * + * # Failure + * + * Raises the `not_utf8` condition if invalid UTF-8 + */ +pub fn from_bytes_owned(vv: ~[u8]) -> ~str { + use str::not_utf8::cond; + + if !is_utf8(vv) { + let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get(); + cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u", + first_bad_byte as uint)) + } else { + return unsafe { raw::from_bytes_owned(vv) } + } +} + /** * Convert a vector of bytes to a UTF-8 string. * The vector needs to be one byte longer than the string, and end with a 0 byte. @@ -850,6 +868,13 @@ pub mod raw { } } + /// Converts an owned vector of bytes to a new owned string. This assumes + /// that the utf-8-ness of the vector has already been validated + pub unsafe fn from_bytes_owned(mut v: ~[u8]) -> ~str { + v.push(0u8); + cast::transmute(v) + } + /// Converts a vector of bytes to a string. /// The byte slice needs to contain valid utf8 and needs to be one byte longer than /// the string, if possible ending in a 0 byte. @@ -1472,7 +1497,9 @@ impl<'self> StrSlice<'self> for &'self str { let mut out: ~str = ~""; out.reserve_at_least(self.len()); for self.iter().advance |c| { - out.push_str(char::escape_default(c)); + do c.escape_default |c| { + out.push_char(c); + } } out } @@ -1482,7 +1509,9 @@ impl<'self> StrSlice<'self> for &'self str { let mut out: ~str = ~""; out.reserve_at_least(self.len()); for self.iter().advance |c| { - out.push_str(char::escape_unicode(c)); + do c.escape_unicode |c| { + out.push_char(c); + } } out } From ca835f482cebcd353db789e45f9cec72db1a24ed Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jun 2013 13:12:15 -0700 Subject: [PATCH 311/336] rustpkg: Ignore a test that's failing on the dist-snap bot --- src/librustpkg/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 0e2a4f33c72c..03548d56c127 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -545,6 +545,7 @@ fn rustpkg_local_pkg() { } #[test] +#[ignore] // XXX Failing on dist-linux bot fn package_script_with_default_build() { let dir = create_local_package(&PkgId::new("fancy-lib")); debug!("dir = %s", dir.to_str()); From 408eef0d89f4520b5ede7e5868a8ca1bc83795bc Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 29 Jun 2013 23:08:00 -0400 Subject: [PATCH 312/336] stop initializing ref_count in exchange_alloc this is never read anymore --- src/libstd/rt/global_heap.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 3994b722f592..5d4ac37055ca 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -43,6 +43,27 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void { } // FIXME #4942: Make these signatures agree with exchange_alloc's signatures +#[cfg(stage0, not(test))] +#[lang="exchange_malloc"] +#[inline] +pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { + let td = td as *TyDesc; + let size = size as uint; + + assert!(td.is_not_null()); + + let total_size = get_box_size(size, (*td).align); + let p = malloc_raw(total_size as uint); + + let box: *mut BoxRepr = p as *mut BoxRepr; + (*box).header.ref_count = -1; + (*box).header.type_desc = td; + + box as *c_char +} + +// FIXME #4942: Make these signatures agree with exchange_alloc's signatures +#[cfg(not(stage0), not(test))] #[lang="exchange_malloc"] #[inline] pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { @@ -55,7 +76,6 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { let p = malloc_raw(total_size as uint); let box: *mut BoxRepr = p as *mut BoxRepr; - (*box).header.ref_count = -1; // Exchange values not ref counted (*box).header.type_desc = td; box as *c_char From 7f3752c7f95a2439db774d977da0caa299ef48e6 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 00:30:19 -0400 Subject: [PATCH 313/336] managed: rm RC_EXCHANGE_UNIQUE constant this is no longer used, exchange allocations do not set ref_count --- src/libstd/managed.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs index b71b3b503c2a..2c9fcb2999f0 100644 --- a/src/libstd/managed.rs +++ b/src/libstd/managed.rs @@ -17,7 +17,6 @@ use ptr::to_unsafe_ptr; pub mod raw { use std::unstable::intrinsics::TyDesc; - pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint; pub static RC_MANAGED_UNIQUE : uint = (-2) as uint; pub static RC_IMMORTAL : uint = 0x77777777; From 45e2582e09dd97d01a01e351c47da210bd6803f3 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 00:49:57 -0400 Subject: [PATCH 314/336] stop copying the tydesc in unique box take glue the only user of the tydesc is ~fn, and it doesn't use this glue code --- src/librustc/middle/trans/closure.rs | 3 +++ src/librustc/middle/trans/uniq.rs | 10 +--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index ad68ffb402e1..d99b9b109efd 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -486,6 +486,9 @@ pub fn make_closure_glue( } } +// note: unique pointers no longer copy the type descriptor in the take glue, +// so we cannot delegate to the unique box take glue here without copying it +// ourselves pub fn make_opaque_cbox_take_glue( bcx: block, sigil: ast::Sigil, diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index d27d6efb2416..ada85c82b304 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -52,13 +52,5 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { } = malloc_unique(bcx, body_datum.ty); body_datum.copy_to(bcx, datum::INIT, dst_body); - // Copy the type descriptor - let src_tydesc_ptr = GEPi(bcx, src_box, - [0u, back::abi::box_field_tydesc]); - let dst_tydesc_ptr = GEPi(bcx, dst_box, - [0u, back::abi::box_field_tydesc]); - let td = Load(bcx, src_tydesc_ptr); - Store(bcx, td, dst_tydesc_ptr); - - return rslt(bcx, dst_box); + rslt(bcx, dst_box) } From 4a29d6eb3f20c2b7a05bb9c9c2f964da606e39ca Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 03:22:18 -0400 Subject: [PATCH 315/336] add a closure_exchange_malloc lang item this makes the exchange allocation header completely unused, and leaves it uninitialized --- src/librustc/middle/lang_items.rs | 120 ++++++++++++++------------- src/librustc/middle/trans/base.rs | 3 + src/librustc/middle/trans/closure.rs | 15 ++-- src/librustc/middle/trans/common.rs | 3 +- src/librustc/middle/trans/tvec.rs | 1 + src/libstd/rt/global_heap.rs | 14 ++++ 6 files changed, 93 insertions(+), 63 deletions(-) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index b167a22992cf..5496fd307999 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -33,63 +33,64 @@ use syntax::visit::visit_crate; use core::hashmap::HashMap; pub enum LangItem { - FreezeTraitLangItem, // 0 - CopyTraitLangItem, // 1 - SendTraitLangItem, // 2 - SizedTraitLangItem, // 3 + FreezeTraitLangItem, // 0 + CopyTraitLangItem, // 1 + SendTraitLangItem, // 2 + SizedTraitLangItem, // 3 - DropTraitLangItem, // 4 + DropTraitLangItem, // 4 - AddTraitLangItem, // 5 - SubTraitLangItem, // 6 - MulTraitLangItem, // 7 - DivTraitLangItem, // 8 - RemTraitLangItem, // 9 - NegTraitLangItem, // 10 - NotTraitLangItem, // 11 - BitXorTraitLangItem, // 11 - BitAndTraitLangItem, // 13 - BitOrTraitLangItem, // 14 - ShlTraitLangItem, // 15 - ShrTraitLangItem, // 16 - IndexTraitLangItem, // 17 + AddTraitLangItem, // 5 + SubTraitLangItem, // 6 + MulTraitLangItem, // 7 + DivTraitLangItem, // 8 + RemTraitLangItem, // 9 + NegTraitLangItem, // 10 + NotTraitLangItem, // 11 + BitXorTraitLangItem, // 11 + BitAndTraitLangItem, // 13 + BitOrTraitLangItem, // 14 + ShlTraitLangItem, // 15 + ShrTraitLangItem, // 16 + IndexTraitLangItem, // 17 - EqTraitLangItem, // 18 - OrdTraitLangItem, // 19 + EqTraitLangItem, // 18 + OrdTraitLangItem, // 19 - StrEqFnLangItem, // 20 - UniqStrEqFnLangItem, // 21 - AnnihilateFnLangItem, // 22 - LogTypeFnLangItem, // 23 - FailFnLangItem, // 24 - FailBoundsCheckFnLangItem, // 25 - ExchangeMallocFnLangItem, // 26 - ExchangeFreeFnLangItem, // 27 - MallocFnLangItem, // 28 - FreeFnLangItem, // 29 - BorrowAsImmFnLangItem, // 30 - BorrowAsMutFnLangItem, // 31 - ReturnToMutFnLangItem, // 32 - CheckNotBorrowedFnLangItem, // 33 - StrDupUniqFnLangItem, // 34 - RecordBorrowFnLangItem, // 35 - UnrecordBorrowFnLangItem, // 36 + StrEqFnLangItem, // 20 + UniqStrEqFnLangItem, // 21 + AnnihilateFnLangItem, // 22 + LogTypeFnLangItem, // 23 + 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 - StartFnLangItem, // 37 + StartFnLangItem, // 38 - TyDescStructLangItem, // 38 - TyVisitorTraitLangItem, // 39 - OpaqueStructLangItem, // 40 + TyDescStructLangItem, // 39 + TyVisitorTraitLangItem, // 40 + OpaqueStructLangItem, // 41 } pub struct LanguageItems { - items: [Option, ..41] + items: [Option, ..42] } impl LanguageItems { pub fn new() -> LanguageItems { LanguageItems { - items: [ None, ..41 ] + items: [ None, ..42 ] } } @@ -129,22 +130,23 @@ impl LanguageItems { 24 => "fail_", 25 => "fail_bounds_check", 26 => "exchange_malloc", - 27 => "exchange_free", - 28 => "malloc", - 29 => "free", - 30 => "borrow_as_imm", - 31 => "borrow_as_mut", - 32 => "return_to_mut", - 33 => "check_not_borrowed", - 34 => "strdup_uniq", - 35 => "record_borrow", - 36 => "unrecord_borrow", + 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", - 37 => "start", + 38 => "start", - 38 => "ty_desc", - 39 => "ty_visitor", - 40 => "opaque", + 39 => "ty_desc", + 40 => "ty_visitor", + 41 => "opaque", _ => "???" } @@ -237,6 +239,9 @@ impl LanguageItems { pub fn exchange_malloc_fn(&self) -> def_id { self.items[ExchangeMallocFnLangItem as uint].get() } + pub fn closure_exchange_malloc_fn(&self) -> def_id { + self.items[ClosureExchangeMallocFnLangItem as uint].get() + } pub fn exchange_free_fn(&self) -> def_id { self.items[ExchangeFreeFnLangItem as uint].get() } @@ -327,6 +332,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(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint); item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); item_refs.insert(@"malloc", MallocFnLangItem as uint); item_refs.insert(@"free", FreeFnLangItem as uint); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d9fea1213468..254cb279d2e3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -254,6 +254,9 @@ pub fn malloc_raw_dyn(bcx: block, 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()) + } }; // Grab the TypeRef type of box_ptr_ty. diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index d99b9b109efd..8405caa10a82 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -160,6 +160,14 @@ pub fn mk_closure_tys(tcx: ty::ctxt, return cdata_ty; } +fn heap_for_unique_closure(bcx: block, t: ty::t) -> heap { + if ty::type_contents(bcx.tcx(), t).contains_managed() { + heap_managed_unique + } else { + heap_exchange_closure + } +} + pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) -> Result { let _icx = push_ctxt("closure::allocate_cbox"); @@ -182,7 +190,7 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) malloc_raw(bcx, cdata_ty, heap_managed) } ast::OwnedSigil => { - malloc_raw(bcx, cdata_ty, heap_for_unique(bcx, cdata_ty)) + malloc_raw(bcx, cdata_ty, heap_for_unique_closure(bcx, cdata_ty)) } ast::BorrowedSigil => { let cbox_ty = tuplify_box_ty(tcx, cdata_ty); @@ -486,9 +494,6 @@ pub fn make_closure_glue( } } -// note: unique pointers no longer copy the type descriptor in the take glue, -// so we cannot delegate to the unique box take glue here without copying it -// ourselves pub fn make_opaque_cbox_take_glue( bcx: block, sigil: ast::Sigil, @@ -530,7 +535,7 @@ pub fn make_opaque_cbox_take_glue( let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, - bcx.tcx().lang_items.exchange_malloc_fn(), + bcx.tcx().lang_items.closure_exchange_malloc_fn(), [opaque_tydesc, sz], expr::SaveIn(rval)); let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index b255f2ca78c7..7638839f95f3 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -276,6 +276,7 @@ pub enum heap { heap_managed, heap_managed_unique, heap_exchange, + heap_exchange_closure } #[deriving(Eq)] @@ -385,7 +386,7 @@ 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 | heap_exchange_closure => { let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr); f } diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 1344bed96eec..456ae4195a92 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -321,6 +321,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_managed | heap_managed_unique => {} } diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 5d4ac37055ca..f669dc753d60 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -72,6 +72,20 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { assert!(td.is_not_null()); + let total_size = get_box_size(size, (*td).align); + malloc_raw(total_size as uint) as *c_char +} + +// FIXME: #7496 +#[cfg(not(test))] +#[lang="closure_exchange_malloc"] +#[inline] +pub unsafe fn closure_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { + let td = td as *TyDesc; + let size = size as uint; + + assert!(td.is_not_null()); + let total_size = get_box_size(size, (*td).align); let p = malloc_raw(total_size as uint); From 9b8c435c8e88a582877b953a1fde5ffd8ac66247 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jun 2013 15:02:52 -0700 Subject: [PATCH 316/336] More 0.7 release notes --- RELEASES.txt | 65 ++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/RELEASES.txt b/RELEASES.txt index 9ac4d650b43f..33f749d00103 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,54 +1,56 @@ Version 0.7 (July 2013) ----------------------- - * ??? changes, numerous bugfixes + * ~2000 changes, numerous bugfixes - * Syntax changes + * Language * `impl`s no longer accept a visibility qualifier. Put them on methods instead. - * `use mod` is no longer valid. - * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style - argument list. - * `Encodable`, `Decodable`, `Ord`, `TotalOrd`, `TotalEq`, `DeepClone`, - `Rand`, `Zero` and `ToStr` can all be automatically derived with - `#[deriving(...)]`. - * The `Durable` trait is replaced with the `'static` bounds. - * At long last, 'argument modes' no longer exist. - * The `bytes!` macro returns a vector of bytes for string, u8, char, - and unsuffixed integer literals. - * `#[static_assert]` makes compile-time assertions about static bools. - - * Semantic changes * The borrow checker has been rewritten with flow-sensitivity, fixing many bugs and inconveniences. * The `self` parameter no longer implicitly means `&'self self`, and can be explicitly marked with a lifetime. - * Structs with the `#[packed]` attribute have byte alignment and - no padding between fields. + * Overloadable compound operators (`+=`, etc.) have been temporarily + removed due to bugs. * The `for` loop protocol now requires `for`-iterators to return `bool` so they compose better. + * The `Durable` trait is replaced with the `'static` bounds. * Trait default methods work more often. + * Structs with the `#[packed]` attribute have byte alignment and + no padding between fields. * Type parameters bound by `Copy` must now be copied explicitly with the `copy` keyword. * It is now illegal to move out of a dereferenced unsafe pointer. * `Option<~T>` is now represented as a nullable pointer. * `@mut` does dynamic borrow checks correctly. - * Macros TODO * The `main` function is only detected at the topmost level of the crate. The `#[main]` attribute is still valid anywhere. * Struct fields may no longer be mutable. Use inherited mutability. - * The `#[non_owned]` attribute makes a type that would otherwise be - `Owned`, not. TODO this may change to non_send before 0.7 - * The `#[mutable]` attribute makes a type that would otherwise be - `Const`, note. TODO this may change to non_freeze before 0.7 + * The `#[no_send]` attribute makes a type that would otherwise be + `Send`, not. + * The `#[no_freeze]` attribute makes a type that would otherwise be + `Freeze`, not. * Unbounded recursion will abort the process after reaching the limit specified by the `RUST_MAX_STACK` environment variable (default: 1GB). * The `vecs_implicitly_copyable` lint mode has been removed. Vectors are never implicitly copyable. + * `#[static_assert]` makes compile-time assertions about static bools. + * At long last, 'argument modes' no longer exist. + * The rarely used `use mod` statement no longer exists. + + * Syntax extensions + * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style + argument list. + * `Encodable`, `Decodable`, `Ord`, `TotalOrd`, `TotalEq`, `DeepClone`, + `Rand`, `Zero` and `ToStr` can all be automatically derived with + `#[deriving(...)]`. + * The `bytes!` macro returns a vector of bytes for string, u8, char, + and unsuffixed integer literals. * Libraries * The `core` crate was renamed to `std`. * The `std` crate was renamed to `extra`. + * More and improved documentation. * std: `iterator` module for external iterator objects. * Many old-style (internal, higher-order function) iterators replaced by implementations of `Iterator`. @@ -91,8 +93,16 @@ Version 0.7 (July 2013) * extra: Implementation of fixed output size variations of SHA-2. * Tooling - * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks. - * `unused_mut` lint mode for identifying unused `mut` qualifiers. + * `unused_variable` lint mode for unused variables (default: warn). + * `unused_unsafe` lint mode for detecting unnecessary `unsafe` blocks + (default: warn). + * `unused_mut` lint mode for identifying unused `mut` qualifiers + (default: warn). + * `dead_assignment` lint mode for unread variables (default: warn). + * `unnecessary_allocation` lint mode detects some heap allocations that are + immediately borrowed so could be written without allocating (default: warn). + * `missing_doc` lint mode (default: allow). + * `unreachable_code` lint mode (default: warn). * The `rusti` command has been rewritten and a number of bugs addressed. * rustc outputs in color on more terminals. * rustc accepts a `--link-args` flag to pass arguments to the linker. @@ -101,12 +111,7 @@ Version 0.7 (July 2013) dynamic borrowcheck failures for debugging. * rustdoc has a nicer stylesheet. * Various improvements to rustdoc. - * Improvements to rustpkg (see the detailed release notes) - - * Other - * More and improved library documentation. - * Various improvements on ARM and Android. - * Various improvements to MIPS backend. + * Improvements to rustpkg (see the detailed release notes). Version 0.6 (April 2013) ------------------------ From a766a955a92dd162ebbcaef9ae0b9469ce1a326a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jun 2013 16:36:48 -0700 Subject: [PATCH 317/336] Bump version from 0.7-pre to 0.7 --- Makefile.in | 2 +- src/compiletest/compiletest.rs | 4 ++-- src/driver/driver.rs | 2 +- src/etc/kate/rust.xml | 2 +- src/libextra/extra.rs | 2 +- src/librust/rust.rs | 2 +- src/librustc/front/std_inject.rs | 2 +- src/librustc/front/test.rs | 2 +- src/librustc/rustc.rs | 2 +- src/librustdoc/rustdoc.rs | 2 +- src/librusti/rusti.rc | 2 +- src/librusti/rusti.rs | 2 +- src/librustpkg/rustpkg.rs | 2 +- src/libstd/std.rs | 2 +- src/libsyntax/syntax.rs | 2 +- src/test/run-pass/use.rs | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index de7ff1d69338..de30113ca4b6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -139,7 +139,7 @@ endif # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git -CFG_RELEASE = 0.7-pre +CFG_RELEASE = 0.7 CFG_VERSION = $(CFG_RELEASE) # windows exe's need numeric versions - don't use anything but # numbers and dots here diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index d858003c353e..82206f12fae2 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -15,8 +15,8 @@ #[no_core]; // XXX: Remove after snapshot #[no_std]; -extern mod core(name = "std", vers = "0.7-pre"); -extern mod extra(name = "extra", vers = "0.7-pre"); +extern mod core(name = "std", vers = "0.7"); +extern mod extra(name = "extra", vers = "0.7"); use core::prelude::*; use core::*; diff --git a/src/driver/driver.rs b/src/driver/driver.rs index ccedd3adbaa9..0f61ede4fc59 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -11,7 +11,7 @@ #[no_core]; #[no_std]; -extern mod core(name = "std", vers = "0.7-pre"); +extern mod core(name = "std", vers = "0.7"); #[cfg(rustpkg)] extern mod this(name = "rustpkg"); diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 44d0ce1a27fc..63f1e50fcaf6 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -7,7 +7,7 @@ ]> - + fn diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs index dae1487092ba..50c57b28d223 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-pre", + vers = "0.7", uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", url = "https://github.com/mozilla/rust/tree/master/src/libextra")]; diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 2380e748e308..30b980a2f858 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-pre", + vers = "0.7", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", url = "https://github.com/mozilla/rust/tree/master/src/rust")]; diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 88ed39aae543..735fe54f3480 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-pre"; +static STD_VERSION: &'static str = "0.7"; pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate) -> @ast::crate { diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index cfd4df7403f6..82283625d90d 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -271,7 +271,7 @@ mod __test { */ fn mk_std(cx: &TestCtxt) -> @ast::view_item { - let vers = ast::lit_str(@"0.7-pre"); + let vers = ast::lit_str(@"0.7"); let vers = nospan(vers); let mi = ast::meta_name_value(@"vers", vers); let mi = nospan(mi); diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 9c0dfb465306..a930570dd173 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-pre", + vers = "0.7", uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf", url = "https://github.com/mozilla/rust/tree/master/src/rustc")]; diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index 6d16b9759cc1..3659d24a254f 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-pre", + vers = "0.7", uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412", url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")]; diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 5873f361ad73..240247bd6d2e 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -44,7 +44,7 @@ */ #[link(name = "rusti", - vers = "0.7-pre", + vers = "0.7", uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index abb0cf271ec4..99281f4f5869 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -44,7 +44,7 @@ */ #[link(name = "rusti", - vers = "0.7-pre", + vers = "0.7", uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc", url = "https://github.com/mozilla/rust/tree/master/src/rusti")]; diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index d393ed695669..8ca8ae1b1edf 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-pre", + vers = "0.7", uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf", url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")]; diff --git a/src/libstd/std.rs b/src/libstd/std.rs index 13c54799fac4..f0f3bcdd4e96 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-pre", + vers = "0.7", uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8", url = "https://github.com/mozilla/rust/tree/master/src/libstd")]; diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 395017cef3b7..830ca5694553 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -14,7 +14,7 @@ */ #[link(name = "syntax", - vers = "0.7-pre", + vers = "0.7", uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")]; #[license = "MIT/ASL2"]; diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index d73eb6641fad..d73abc803cd5 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-pre"); +extern mod bar(name = "std", vers = "0.7"); use std::str; From 80ab87784108b1a26e9670a029283567b23cf1ad Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 22:12:26 -0400 Subject: [PATCH 318/336] global_heap: inline malloc_raw and add realloc_raw --- src/libstd/libc.rs | 2 +- src/libstd/rt/global_heap.rs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index 41b78afded1a..f4ea29b5c05e 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -1945,7 +1945,7 @@ pub mod funcs { #[fast_ffi] unsafe fn malloc(size: size_t) -> *c_void; #[fast_ffi] - unsafe fn realloc(p: *c_void, size: size_t) -> *c_void; + unsafe fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; #[fast_ffi] unsafe fn free(p: *c_void); unsafe fn abort() -> !; diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index f669dc753d60..a7fbed2dd70b 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use libc::{c_char, c_void, size_t, uintptr_t, free, malloc}; +use libc::{c_char, c_void, size_t, uintptr_t, free, malloc, realloc}; use managed::raw::{BoxHeaderRepr, BoxRepr}; use unstable::intrinsics::TyDesc; use sys::size_of; @@ -33,6 +33,7 @@ fn align_to(size: uint, align: uint) -> uint { } /// A wrapper around libc::malloc, aborting on out-of-memory +#[inline] pub unsafe fn malloc_raw(size: uint) -> *c_void { let p = malloc(size as size_t); if p.is_null() { @@ -42,6 +43,17 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void { p } +/// A wrapper around libc::realloc, aborting on out-of-memory +#[inline] +pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void { + let p = realloc(ptr, size as size_t); + if p.is_null() { + // we need a non-allocating way to print an error here + abort(); + } + p +} + // FIXME #4942: Make these signatures agree with exchange_alloc's signatures #[cfg(stage0, not(test))] #[lang="exchange_malloc"] From b731d96b4f2a8d5733e79a863c40632425456520 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 22:18:17 -0400 Subject: [PATCH 319/336] vec: implement exchange vector reserve in Rust --- src/libstd/vec.rs | 26 ++++++++++++++------------ src/rt/rust_builtin.cpp | 7 ------- src/rt/rustrt.def.in | 1 - 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 272ad0ac705f..310b7e6a1d47 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -22,12 +22,14 @@ use iterator::{FromIterator, Iterator, IteratorUtil}; use iter::FromIter; use kinds::Copy; use libc; +use libc::c_void; use num::Zero; use ops::Add; use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; use ptr::RawPtr; +use rt::global_heap::realloc_raw; use sys; use sys::size_of; use uint; @@ -52,12 +54,6 @@ pub mod rustrt { #[abi = "cdecl"] pub extern { - // These names are terrible. reserve_shared applies - // to ~[] and reserve_shared_actual applies to @[]. - #[fast_ffi] - unsafe fn vec_reserve_shared(t: *TyDesc, - v: **raw::VecRepr, - n: libc::size_t); #[fast_ffi] unsafe fn vec_reserve_shared_actual(t: *TyDesc, v: **raw::VecRepr, @@ -1523,13 +1519,16 @@ impl OwnedVector for ~[T] { use managed; if self.capacity() < n { unsafe { - let ptr: **raw::VecRepr = cast::transmute(self); + let ptr: *mut *mut raw::VecRepr = cast::transmute(self); let td = get_tydesc::(); if ((**ptr).box_header.ref_count == managed::raw::RC_MANAGED_UNIQUE) { - rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); + rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); } else { - rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); + let alloc = n * sys::nonzero_size_of::(); + *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::()) + as *mut raw::VecRepr; + (**ptr).unboxed.alloc = alloc; } } } @@ -1551,12 +1550,15 @@ impl OwnedVector for ~[T] { // Only make the (slow) call into the runtime if we have to if self.capacity() < n { unsafe { - let ptr: **raw::VecRepr = cast::transmute(self); + let ptr: *mut *mut raw::VecRepr = cast::transmute(self); let td = get_tydesc::(); if contains_managed::() { - rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t); + rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); } else { - rustrt::vec_reserve_shared(td, ptr, n as libc::size_t); + let alloc = n * sys::nonzero_size_of::(); + *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::()) + as *mut raw::VecRepr; + (**ptr).unboxed.alloc = alloc; } } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index de46d7b3e8ae..17f36e810cd1 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -75,13 +75,6 @@ vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp, reserve_vec_exact_shared(task, vp, n_elts * ty->size); } -// This is completely misnamed. -extern "C" CDECL void -vec_reserve_shared(type_desc* ty, rust_vec_box** vp, - size_t n_elts) { - reserve_vec_exact(vp, n_elts * ty->size); -} - extern "C" CDECL size_t rand_seed_size() { return rng_seed_size(); diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index b572f1aba6a5..0da04e34f495 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -55,7 +55,6 @@ rust_get_c_stack rust_log_str start_task vec_reserve_shared_actual -vec_reserve_shared task_clear_event_reject task_wait_event task_signal_event From 0d7799d3048eea4039d59c0cca98449e1c52a561 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 22:41:51 -0400 Subject: [PATCH 320/336] global_heap: inline get_box_size and align_to --- src/libstd/rt/global_heap.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index a7fbed2dd70b..1e0ad3352fef 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -18,6 +18,7 @@ extern { fn abort(); } +#[inline] fn get_box_size(body_size: uint, body_align: uint) -> uint { let header_size = size_of::(); // FIXME (#2699): This alignment calculation is suspicious. Is it right? @@ -27,6 +28,7 @@ fn get_box_size(body_size: uint, body_align: uint) -> uint { // Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power // of two. +#[inline] fn align_to(size: uint, align: uint) -> uint { assert!(align != 0); (size + align - 1) & !(align - 1) From 5b40f2ae5b4357a9488bd97da011bd07aebf6aaa Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 30 Jun 2013 23:30:40 -0400 Subject: [PATCH 321/336] pass exchange_malloc an alignment, not a tydesc --- src/librustc/middle/trans/base.rs | 52 +++++++++++++++++++++---------- src/libstd/rt/global_heap.rs | 9 ++---- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index cf671bdce677..411cbcbe9eb7 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -258,25 +258,43 @@ pub fn malloc_raw_dyn(bcx: block, } }; - // 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); + if heap == heap_exchange { + // 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); - // Get the tydesc for the body: - let static_ti = get_tydesc(ccx, t); - glue::lazily_emit_all_tydesc_glue(ccx, static_ti); + let llty_value = type_of::type_of(ccx, t); + let llalign = llalign_of_min(ccx, llty_value); - // Allocate space: - let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); - let rval = alloca(bcx, Type::i8p()); - let bcx = callee::trans_lang_call( - bcx, - langcall, - [tydesc, size], - expr::SaveIn(rval)); - let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); - maybe_set_managed_unique_rc(r.bcx, r.val, heap); - r + // Allocate space: + let rval = alloca(bcx, Type::i8p()); + let bcx = callee::trans_lang_call( + bcx, + langcall, + [C_i32(llalign as i32), size], + expr::SaveIn(rval)); + rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)) + } else { + // 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); + + // Get the tydesc for the body: + let static_ti = get_tydesc(ccx, t); + glue::lazily_emit_all_tydesc_glue(ccx, static_ti); + + // Allocate space: + let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); + let bcx = callee::trans_lang_call( + bcx, + langcall, + [tydesc, size], + expr::SaveIn(rval)); + let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty)); + maybe_set_managed_unique_rc(r.bcx, r.val, heap); + r + } } // malloc_raw: expects an unboxed type and returns a pointer to diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 1e0ad3352fef..1020580d52c0 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -80,13 +80,8 @@ 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(td: *c_char, size: uintptr_t) -> *c_char { - let td = td as *TyDesc; - let size = size as uint; - - assert!(td.is_not_null()); - - let total_size = get_box_size(size, (*td).align); +pub unsafe fn 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 } From d5c5ce3f8d07ba7f9059727a790ce19f7a1599b7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jun 2013 21:08:48 -0700 Subject: [PATCH 322/336] Update verison numbers in README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 65f5942fd161..f01ed1958c66 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ packages: Assuming you're on a relatively modern *nix system and have met the prerequisites, something along these lines should work. - $ curl -O http://static.rust-lang.org/dist/rust-0.6.tar.gz - $ tar -xzf rust-0.6.tar.gz - $ cd rust-0.6 + $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz + $ tar -xzf rust-0.7.tar.gz + $ cd rust-0.7 $ ./configure $ make && make install @@ -59,8 +59,8 @@ When complete, `make install` will place several programs into API-documentation tool, and `rustpkg`, the Rust package manager and build system. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust -[tarball]: http://static.rust-lang.org/dist/rust-0.6.tar.gz -[win-exe]: http://static.rust-lang.org/dist/rust-0.6-install.exe +[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz +[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe ## License From d387e787124218534c72356e142ac78384380c85 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Sun, 30 Jun 2013 22:15:03 +0900 Subject: [PATCH 323/336] librustc: back::link::sanitize support esacpe_utf8 --- src/librustc/back/link.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index cc062db4cb2c..7954bc834f5a 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -660,9 +660,9 @@ pub fn sanitize(s: &str) -> ~str { | '_' => result.push_char(c), _ => { - if c > 'z' && char::is_XID_continue(c) { - result.push_char(c); - } + let tstr = char::escape_unicode(c); + result.push_char('$'); + result.push_str(tstr.slice_from(1)); } } } From 567cf30450c4c1ff15938c9c6a2519440e47a00e Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Mon, 1 Jul 2013 16:11:32 +0900 Subject: [PATCH 324/336] librustc: apply changes of char::escape_unicode --- src/librustc/back/link.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 7954bc834f5a..61d39421b7fd 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -660,7 +660,8 @@ pub fn sanitize(s: &str) -> ~str { | '_' => result.push_char(c), _ => { - let tstr = char::escape_unicode(c); + let mut tstr = ~""; + do char::escape_unicode(c) |c| { tstr.push_char(c); } result.push_char('$'); result.push_str(tstr.slice_from(1)); } From 5183a6cc6c5bcd263ed7a31650351fc64b4412f4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 25 Jun 2013 23:46:26 -0700 Subject: [PATCH 325/336] Turn on using LLVM threadsafely --- src/librustc/middle/trans/base.rs | 10 ++-- src/librusti/rusti.rs | 83 ++++++++++++++++------------ src/librustpkg/tests.rs | 24 ++++---- src/rustllvm/llvm-auto-clean-trigger | 4 ++ 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index cf671bdce677..e649644e8b9c 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2883,6 +2883,10 @@ pub fn trans_crate(sess: session::Session, reachable_map: @mut HashSet, maps: astencode::Maps) -> (ContextRef, ModuleRef, LinkMeta) { + // Before we touch LLVM, make sure that multithreading is enabled. + if unsafe { !llvm::LLVMRustStartMultithreading() } { + sess.bug("couldn't enable multi-threaded LLVM"); + } let mut symbol_hasher = hash::default_state(); let link_meta = link::build_link_meta(sess, crate, output, &mut symbol_hasher); @@ -2897,12 +2901,6 @@ pub fn trans_crate(sess: session::Session, // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 let llmod_id = link_meta.name.to_owned() + ".rc"; - // FIXME(#6511): get LLVM building with --enable-threads so this - // function can be called - // if !llvm::LLVMRustStartMultithreading() { - // sess.bug("couldn't enable multi-threaded LLVM"); - // } - let ccx = @mut CrateContext::new(sess, llmod_id, tcx, diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 99281f4f5869..2cdcea203cad 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -528,6 +528,9 @@ mod tests { } } + // FIXME: #7220 rusti on 32bit mac doesn't work. + #[cfg(not(target_word_size="32"))] + #[cfg(not(target_os="macos"))] fn run_program(prog: &str) { let mut r = repl(); for prog.split_iter('\n').advance |cmd| { @@ -536,54 +539,55 @@ mod tests { r = result.expect(fmt!("the command '%s' failed", cmd)); } } + #[cfg(target_word_size="32", target_os="macos")] + fn run_program(_: &str) {} #[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"); + fn super_basic() { run_program(""); + } - debug!("regression test for #5937"); + #[test] + fn regression_5937() { run_program("use std::hashmap;"); + } - debug!("regression test for #5784"); + #[test] + fn regression_5784() { run_program("let a = 3;"); + } + #[test] #[ignore] + fn new_tasks() { // 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?\"); } - // "); + run_program(" + spawn( || println(\"Please don't segfault\") ); + do spawn { println(\"Please?\"); } + "); + } - debug!("inferred integers are usable"); + #[test] + fn inferred_integers_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"); + #[test] + fn local_variables_allow_shadowing() { run_program(" let a = 3; let a = 5; assert!(a == 5) "); + } - debug!("strings are usable"); + #[test] + fn string_usable() { run_program(" let a = ~\"\"; let b = \"\"; @@ -591,8 +595,10 @@ mod tests { let d = a + b + c; assert!(d.len() == 0); "); + } - debug!("vectors are usable"); + #[test] + fn vectors_usable() { run_program(" let a = ~[1, 2, 3]; let b = &[1, 2, 3]; @@ -601,15 +607,19 @@ mod tests { assert!(d.len() == 9); let e: &[int] = []; "); + } - debug!("structs are usable"); + #[test] + fn structs_usable() { run_program(" struct A{ a: int } let b = A{ a: 3 }; assert!(b.a == 3) "); + } - debug!("mutable variables"); + #[test] + fn mutable_variables_work() { run_program(" let mut a = 3; a = 5; @@ -618,29 +628,37 @@ mod tests { assert!(b.contains(&5)) assert!(b.len() == 1) "); + } - debug!("functions are cached"); + #[test] + fn functions_saved() { 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"); + #[test] + fn modules_saved() { run_program(" mod b { pub fn foo() -> uint { 3 } } assert!(b::foo() == 3) "); + } - debug!("multiple function definitions are allowed"); + #[test] + fn multiple_functions() { run_program(" fn f() {} fn f() {} f() "); + } - debug!("multiple item definitions are allowed"); + #[test] + fn multiple_items_same_name() { run_program(" fn f() {} mod f {} @@ -657,9 +675,6 @@ mod tests { } #[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); diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 03548d56c127..9c23327b6774 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -307,18 +307,10 @@ fn frob_source_file(workspace: &Path, pkgid: &PkgId) { } } -#[test] #[ignore] //FIXME(#7249) -fn test_all() { - // FIXME(#7071): these tests use rustc, so they can't be run in parallel - // until this issue is resolved - test_make_dir_rwx(); - test_install_valid(); - test_install_invalid(); - test_install_url(); - test_package_ids_must_be_relative_path_like(); - test_package_version(); -} +// FIXME(#7249): these tests fail on multi-platform builds, so for now they're +// only run one x86 +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_make_dir_rwx() { let temp = &os::tmpdir(); let dir = temp.push("quux"); @@ -331,6 +323,7 @@ fn test_make_dir_rwx() { assert!(os::remove_dir_recursive(&dir)); } +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_install_valid() { use path_util::installed_library_in_workspace; @@ -360,6 +353,7 @@ fn test_install_valid() { assert!(!os::path_exists(&bench)); } +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_install_invalid() { use conditions::nonexistent_package::cond; use cond1 = conditions::missing_pkg_files::cond; @@ -382,6 +376,7 @@ fn test_install_invalid() { assert!(error_occurred && error1_occurred); } +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_install_url() { let workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir"); let sysroot = test_sysroot(); @@ -417,6 +412,7 @@ fn test_install_url() { assert!(!os::path_exists(&bench)); } +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_package_ids_must_be_relative_path_like() { use conditions::bad_pkg_id::cond; @@ -457,6 +453,7 @@ fn test_package_ids_must_be_relative_path_like() { } +#[test] #[ignore(cfg(target_arch = "x86"))] fn test_package_version() { let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version"); match temp_pkg_id.version { @@ -479,9 +476,8 @@ fn test_package_version() { push("test_pkg_version"))); } -// FIXME #7006: Fails on linux for some reason -#[test] -#[ignore] +// FIXME #7006: Fails on linux/mac for some reason +#[test] #[ignore] fn test_package_request_version() { let temp_pkg_id = PkgId::new("github.com/catamorphism/test_pkg_version#0.3"); let temp = mk_empty_workspace(&LocalPath(Path("test_pkg_version")), &ExactRevision(~"0.3")); diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index e69de29bb2d1..fbd687778ae7 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -0,0 +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 From 9e6d5e152ee30c306afccfe9ede105acc6a0a278 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 23 May 2013 21:37:37 -0400 Subject: [PATCH 326/336] Defer reasoning about region relationships until after regionck. This patch makes error handling for region inference failures more uniform by not reporting *any* region errors until the reigon inference step. This requires threading through more information about what caused a region constraint, so that we can still give informative error messages. I have only taken partial advantage of this information: when region inference fails, we still report the same error we always did, despite the fact that we now know precisely what caused the various constriants and what the region variable represents, which we did not know before. This change is required not only to improve error messages but because the region hierarchy is not in fact fully known until regionck, because it is not clear where closure bodies fit in (our current treatment is unsound). Moreover, the relationships between free variables cannot be fully determined until type inference is otherwise complete. cc #3238. --- src/librustc/middle/typeck/check/_match.rs | 14 +- src/librustc/middle/typeck/check/demand.rs | 4 +- src/librustc/middle/typeck/check/method.rs | 17 +- src/librustc/middle/typeck/check/mod.rs | 64 ++- src/librustc/middle/typeck/check/regionck.rs | 182 ++----- src/librustc/middle/typeck/check/vtable.rs | 40 +- src/librustc/middle/typeck/coherence.rs | 26 +- src/librustc/middle/typeck/collect.rs | 3 +- src/librustc/middle/typeck/infer/coercion.rs | 12 +- src/librustc/middle/typeck/infer/combine.rs | 5 +- .../middle/typeck/infer/error_reporting.rs | 434 +++++++++++++++++ src/librustc/middle/typeck/infer/glb.rs | 13 +- src/librustc/middle/typeck/infer/lattice.rs | 2 +- src/librustc/middle/typeck/infer/lub.rs | 13 +- src/librustc/middle/typeck/infer/mod.rs | 365 +++++++++++--- .../middle/typeck/infer/region_inference.rs | 445 ++++++++++-------- src/librustc/middle/typeck/infer/sub.rs | 13 +- src/librustc/middle/typeck/mod.rs | 2 +- src/librustc/util/ppaux.rs | 19 + .../arc-rw-cond-shouldnt-escape.rs | 2 +- .../arc-rw-state-shouldnt-escape.rs | 5 +- .../arc-rw-write-mode-cond-shouldnt-escape.rs | 2 +- .../arc-rw-write-mode-shouldnt-escape.rs | 2 +- .../compile-fail/borrowck-move-by-capture.rs | 4 +- .../kindck-owned-trait-contains.rs | 10 +- src/test/compile-fail/regions-bounds.rs | 6 +- .../compile-fail/regions-escape-bound-fn-2.rs | 2 +- .../regions-escape-via-trait-or-not.rs | 2 +- .../regions-infer-at-fn-not-param.rs | 5 +- .../regions-infer-covariance-due-to-arg.rs | 1 + .../compile-fail/regions-infer-not-param.rs | 5 + .../regions-infer-paramd-indirect.rs | 1 + src/test/compile-fail/regions-nested-fns.rs | 1 + .../compile-fail/regions-ret-borrowed-1.rs | 2 + src/test/compile-fail/regions-ret-borrowed.rs | 2 + .../compile-fail/sync-cond-shouldnt-escape.rs | 2 +- .../sync-rwlock-cond-shouldnt-escape.rs | 2 +- ...-rwlock-write-mode-cond-shouldnt-escape.rs | 2 +- .../sync-rwlock-write-mode-shouldnt-escape.rs | 2 +- 39 files changed, 1211 insertions(+), 522 deletions(-) create mode 100644 src/librustc/middle/typeck/infer/error_reporting.rs diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index c2bf4594d30e..351d09b7ce5c 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -15,6 +15,7 @@ use middle::typeck::check::demand; use middle::typeck::check::{check_block, check_expr_has_type, FnCtxt}; use middle::typeck::check::{instantiate_path, lookup_def}; use middle::typeck::check::{structure_of, valid_range_bounds}; +use middle::typeck::infer; use middle::typeck::require_same_types; use std::hashmap::{HashMap, HashSet}; @@ -38,8 +39,6 @@ pub fn check_match(fcx: @mut FnCtxt, let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, arm.pats[0]), - match_region: ty::re_scope(expr.id), - block_region: ty::re_scope(arm.body.node.id) }; for arm.pats.iter().advance |p| { check_pat(&pcx, *p, pattern_ty);} @@ -93,8 +92,6 @@ pub fn check_match(fcx: @mut FnCtxt, pub struct pat_ctxt { fcx: @mut FnCtxt, map: PatIdMap, - match_region: ty::Region, // Region for the match as a whole - block_region: ty::Region, // Region for the block of the arm } pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path, @@ -442,8 +439,8 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { // then the type of x is &M T where M is the mutability // and T is the expected type let region_var = - fcx.infcx().next_region_var_with_lb( - pat.span, pcx.block_region); + fcx.infcx().next_region_var( + infer::PatternRegion(pat.span)); let mt = ty::mt {ty: expected, mutbl: mutbl}; let region_ty = ty::mk_rptr(tcx, region_var, mt); demand::eqtype(fcx, pat.span, region_ty, typ); @@ -544,9 +541,8 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) { } ast::pat_vec(ref before, slice, ref after) => { let default_region_var = - fcx.infcx().next_region_var_with_lb( - pat.span, pcx.block_region - ); + fcx.infcx().next_region_var( + infer::PatternRegion(pat.span)); let (elt_type, region_var) = match structure_of( fcx, pat.span, expected diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs index 7ca78068f070..cf29d3f7f1f5 100644 --- a/src/librustc/middle/typeck/check/demand.rs +++ b/src/librustc/middle/typeck/check/demand.rs @@ -35,7 +35,7 @@ pub fn suptype_with_fn(fcx: @mut FnCtxt, ty_a: ty::t, ty_b: ty::t, handle_err: &fn(span, ty::t, ty::t, &ty::type_err)) { // n.b.: order of actual, expected is reversed - match infer::mk_subty(fcx.infcx(), b_is_expected, sp, + match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp), ty_b, ty_a) { result::Ok(()) => { /* ok */ } result::Err(ref err) => { @@ -45,7 +45,7 @@ pub fn suptype_with_fn(fcx: @mut FnCtxt, } pub fn eqtype(fcx: @mut FnCtxt, sp: span, expected: ty::t, actual: ty::t) { - match infer::mk_eqty(fcx.infcx(), false, sp, actual, expected) { + match infer::mk_eqty(fcx.infcx(), false, infer::Misc(sp), actual, expected) { Ok(()) => { /* ok */ } Err(ref err) => { fcx.report_mismatched_types(sp, expected, actual, err); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 95584889218a..ee61399113a4 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -619,14 +619,18 @@ impl<'self> LookupContext<'self> { autoref: None})) } ty::ty_rptr(_, self_mt) => { - let region = self.infcx().next_region_var_nb(self.expr.span); + let region = + self.infcx().next_region_var( + infer::Autoref(self.expr.span)); (ty::mk_rptr(tcx, region, self_mt), ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: autoderefs+1, autoref: Some(ty::AutoPtr(region, self_mt.mutbl))})) } ty::ty_evec(self_mt, vstore_slice(_)) => { - let region = self.infcx().next_region_var_nb(self.expr.span); + let region = + self.infcx().next_region_var( + infer::Autoref(self.expr.span)); (ty::mk_evec(tcx, self_mt, vstore_slice(region)), ty::AutoDerefRef(ty::AutoDerefRef { autoderefs: autoderefs, @@ -758,7 +762,9 @@ impl<'self> LookupContext<'self> { -> Option { // This is hokey. We should have mutability inference as a // variable. But for now, try &const, then &, then &mut: - let region = self.infcx().next_region_var_nb(self.expr.span); + let region = + self.infcx().next_region_var( + infer::Autoref(self.expr.span)); for mutbls.iter().advance |mutbl| { let autoref_ty = mk_autoref_ty(*mutbl, region); match self.search_for_method(autoref_ty) { @@ -970,7 +976,8 @@ impl<'self> LookupContext<'self> { let (_, opt_transformed_self_ty, fn_sig) = replace_bound_regions_in_fn_sig( tcx, @Nil, Some(transformed_self_ty), &bare_fn_ty.sig, - |_br| self.fcx.infcx().next_region_var_nb(self.expr.span)); + |br| self.fcx.infcx().next_region_var( + infer::BoundRegionInFnCall(self.expr.span, br))); let transformed_self_ty = opt_transformed_self_ty.get(); let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty}); debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty)); @@ -982,7 +989,7 @@ impl<'self> LookupContext<'self> { // variables to unify etc). Since we checked beforehand, and // nothing has changed in the meantime, this unification // should never fail. - match self.fcx.mk_subty(false, self.self_expr.span, + match self.fcx.mk_subty(false, infer::Misc(self.self_expr.span), rcvr_ty, transformed_self_ty) { result::Ok(_) => (), result::Err(_) => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a6bc335bcdbc..b397181ddca6 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -467,8 +467,6 @@ pub fn check_fn(ccx: @mut CrateCtxt, let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, input.pat), - match_region: region, - block_region: region, }; _match::check_pat(&pcx, input.pat, *arg_ty); } @@ -686,9 +684,14 @@ impl FnCtxt { result::Ok(self.block_region()) } else { result::Err(RegionError { - msg: fmt!("named region `%s` not in scope here", - bound_region_ptr_to_str(self.tcx(), br)), - replacement: self.infcx().next_region_var_nb(span) + msg: { + fmt!("named region `%s` not in scope here", + bound_region_to_str(self.tcx(), br)) + }, + replacement: { + self.infcx().next_region_var( + infer::BoundRegionError(span)) + } }) } } @@ -698,7 +701,7 @@ impl FnCtxt { impl region_scope for FnCtxt { fn anon_region(&self, span: span) -> Result { - result::Ok(self.infcx().next_region_var_nb(span)) + result::Ok(self.infcx().next_region_var(infer::MiscVariable(span))) } fn self_region(&self, span: span) -> Result { self.search_in_scope_regions(span, ty::br_self) @@ -845,11 +848,11 @@ impl FnCtxt { pub fn mk_subty(&self, a_is_expected: bool, - span: span, + origin: infer::SubtypeOrigin, sub: ty::t, sup: ty::t) -> Result<(), ty::type_err> { - infer::mk_subty(self.infcx(), a_is_expected, span, sub, sup) + infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup) } pub fn can_mk_subty(&self, sub: ty::t, sup: ty::t) @@ -857,9 +860,16 @@ impl FnCtxt { infer::can_mk_subty(self.infcx(), sub, sup) } - pub fn mk_assignty(&self, expr: @ast::expr, sub: ty::t, sup: ty::t) + pub fn mk_assignty(&self, + expr: @ast::expr, + sub: ty::t, + sup: ty::t) -> Result<(), ty::type_err> { - match infer::mk_coercety(self.infcx(), false, expr.span, sub, sup) { + match infer::mk_coercety(self.infcx(), + false, + infer::ExprAssignable(expr), + sub, + sup) { Ok(None) => result::Ok(()), Err(ref e) => result::Err((*e)), Ok(Some(adjustment)) => { @@ -876,20 +886,19 @@ impl FnCtxt { pub fn mk_eqty(&self, a_is_expected: bool, - span: span, + origin: infer::SubtypeOrigin, sub: ty::t, sup: ty::t) -> Result<(), ty::type_err> { - infer::mk_eqty(self.infcx(), a_is_expected, span, sub, sup) + infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup) } pub fn mk_subr(&self, a_is_expected: bool, - span: span, + origin: infer::SubregionOrigin, sub: ty::Region, - sup: ty::Region) - -> Result<(), ty::type_err> { - infer::mk_subr(self.infcx(), a_is_expected, span, sub, sup) + sup: ty::Region) { + infer::mk_subr(self.infcx(), a_is_expected, origin, sub, sup) } pub fn with_region_lb(@mut self, lb: ast::node_id, f: &fn() -> R) @@ -905,7 +914,9 @@ impl FnCtxt { rp: Option, span: span) -> Option { - rp.map(|_rp| self.infcx().next_region_var_nb(span)) + rp.map( + |_| self.infcx().next_region_var( + infer::BoundRegionInTypeOrImpl(span))) } pub fn type_error_message(&self, @@ -1089,7 +1100,8 @@ pub fn impl_self_ty(vcx: &VtableContext, }; let self_r = if region_param.is_some() { - Some(vcx.infcx.next_region_var_nb(location_info.span)) + Some(vcx.infcx.next_region_var( + infer::BoundRegionInTypeOrImpl(location_info.span))) } else { None }; @@ -1352,7 +1364,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let (_, _, fn_sig) = replace_bound_regions_in_fn_sig( fcx.tcx(), @Nil, None, &fn_sig, - |_br| fcx.infcx().next_region_var_nb(call_expr.span)); + |br| fcx.infcx().next_region_var( + infer::BoundRegionInFnCall(call_expr.span, br))); // Call the generic checker. check_argument_types(fcx, call_expr.span, fn_sig.inputs, f, @@ -2085,7 +2098,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); let inner_ty = match expected_sty { Some(ty::ty_closure(ref fty)) => { - match fcx.mk_subty(false, expr.span, + match fcx.mk_subty(false, infer::Misc(expr.span), fty.sig.output, ty::mk_bool()) { result::Ok(_) => { ty::mk_closure(tcx, ty::ClosureTy { @@ -2395,7 +2408,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // Finally, borrowck is charged with guaranteeing that the // value whose address was taken can actually be made to live // as long as it needs to live. - let region = fcx.infcx().next_region_var_nb(expr.span); + let region = fcx.infcx().next_region_var( + infer::AddrOfRegion(expr.span)); let tm = ty::mt { ty: fcx.expr_ty(oprnd), mutbl: mutbl }; let oprnd_t = if ty::type_is_error(tm.ty) { @@ -2437,7 +2451,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, Some(t) => t, None => fcx.ret_ty }; match expr_opt { - None => match fcx.mk_eqty(false, expr.span, + None => match fcx.mk_eqty(false, infer::Misc(expr.span), ret_ty, ty::mk_nil()) { result::Ok(_) => { /* fall through */ } result::Err(_) => { @@ -2686,7 +2700,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let el = ty::sequence_element_type(fcx.tcx(), t1); infer::mk_eqty(fcx.infcx(), false, - sp, el, t2).is_ok() + infer::Misc(sp), el, t2).is_ok() } } @@ -2907,8 +2921,6 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) { let pcx = pat_ctxt { fcx: fcx, map: pat_id_map(tcx.def_map, local.node.pat), - match_region: region, - block_region: region, }; _match::check_pat(&pcx, local.node.pat, t); let pat_ty = fcx.node_ty(local.node.pat.id); @@ -3412,7 +3424,7 @@ pub fn ast_expr_vstore_to_vstore(fcx: @mut FnCtxt, ast::expr_vstore_uniq => ty::vstore_uniq, ast::expr_vstore_box | ast::expr_vstore_mut_box => ty::vstore_box, ast::expr_vstore_slice | ast::expr_vstore_mut_slice => { - let r = fcx.infcx().next_region_var_nb(e.span); + let r = fcx.infcx().next_region_var(infer::AddrOfSlice(e.span)); ty::vstore_slice(r) } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 80faad15695c..2e41649e4dbb 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/* +/*! The region check is a final pass that runs over the AST after we have inferred the type constraints but before we have actually finalized @@ -35,7 +35,9 @@ use middle::typeck::check::FnCtxt; 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 util::ppaux::{note_and_explain_region, ty_to_str, region_to_str}; +use middle::typeck::infer; +use util::ppaux::{note_and_explain_region, ty_to_str, + region_to_str}; use middle::pat_util; use std::result; @@ -224,7 +226,9 @@ fn constrain_bindings_in_pat(pat: @ast::pat, rcx: @mut Rcx) { // variable's type enclose at least the variable's scope. let encl_region = tcx.region_maps.encl_region(id); - constrain_regions_in_type_of_node(rcx, id, encl_region, span); + constrain_regions_in_type_of_node( + rcx, id, encl_region, + infer::BindingTypeIsNotValidAtDecl(span)); } } @@ -298,7 +302,8 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { // // FIXME(#6268) remove to support nested method calls constrain_regions_in_type_of_node( - rcx, expr.id, ty::re_scope(expr.id), expr.span); + rcx, expr.id, ty::re_scope(expr.id), + infer::AutoBorrow(expr.span)); } } _ => {} @@ -361,8 +366,11 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { match ty::get(target_ty).sty { ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _, _) => { let source_ty = rcx.fcx.expr_ty(source); - constrain_regions_in_type(rcx, trait_region, - expr.span, source_ty); + constrain_regions_in_type( + rcx, + trait_region, + infer::RelateObjectBound(expr.span), + source_ty); } _ => () } @@ -379,7 +387,8 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { // // FIXME(#6268) nested method calls requires that this rule change let ty0 = rcx.resolve_node_type(expr.id); - constrain_regions_in_type(rcx, ty::re_scope(expr.id), expr.span, ty0); + constrain_regions_in_type(rcx, ty::re_scope(expr.id), + infer::AddrOf(expr.span), ty0); } ast::expr_match(discr, ref arms) => { @@ -418,20 +427,8 @@ fn constrain_callee(rcx: @mut Rcx, match ty::get(callee_ty).sty { ty::ty_bare_fn(*) => { } ty::ty_closure(ref closure_ty) => { - match rcx.fcx.mk_subr(true, callee_expr.span, - call_region, closure_ty.region) { - result::Err(_) => { - tcx.sess.span_err( - callee_expr.span, - fmt!("cannot invoke closure outside of its lifetime")); - note_and_explain_region( - tcx, - "the closure is only valid for ", - closure_ty.region, - ""); - } - result::Ok(_) => {} - } + rcx.fcx.mk_subr(true, infer::InvokeClosure(callee_expr.span), + call_region, closure_ty.region); } _ => { // this should not happen, but it does if the program is @@ -479,7 +476,8 @@ fn constrain_call(rcx: @mut Rcx, // ensure that any regions appearing in the argument type are // valid for at least the lifetime of the function: constrain_regions_in_type_of_node( - rcx, arg_expr.id, callee_region, arg_expr.span); + rcx, arg_expr.id, callee_region, + infer::CallArg(arg_expr.span)); // unfortunately, there are two means of taking implicit // references, and we need to propagate constraints as a @@ -493,7 +491,7 @@ fn constrain_call(rcx: @mut Rcx, // as loop above, but for receiver for receiver.iter().advance |&r| { constrain_regions_in_type_of_node( - rcx, r.id, callee_region, r.span); + rcx, r.id, callee_region, infer::CallRcvr(r.span)); if implicitly_ref_args { guarantor::for_by_ref(rcx, r, callee_scope); } @@ -502,7 +500,8 @@ fn constrain_call(rcx: @mut Rcx, // constrain regions that may appear in the return type to be // valid for the function call: constrain_regions_in_type( - rcx, callee_region, call_expr.span, fn_sig.output); + rcx, callee_region, infer::CallReturn(call_expr.span), + fn_sig.output); } fn constrain_derefs(rcx: @mut Rcx, @@ -545,20 +544,8 @@ pub fn mk_subregion_due_to_derefence(rcx: @mut Rcx, deref_span: span, minimum_lifetime: ty::Region, maximum_lifetime: ty::Region) { - match rcx.fcx.mk_subr(true, deref_span, - minimum_lifetime, maximum_lifetime) { - result::Ok(*) => {} - result::Err(*) => { - rcx.tcx().sess.span_err( - deref_span, - fmt!("dereference of reference outside its lifetime")); - note_and_explain_region( - rcx.tcx(), - "the reference is only valid for ", - maximum_lifetime, - ""); - } - } + rcx.fcx.mk_subr(true, infer::DerefPointer(deref_span), + minimum_lifetime, maximum_lifetime) } @@ -581,19 +568,8 @@ fn constrain_index(rcx: @mut Rcx, match ty::get(indexed_ty).sty { ty::ty_estr(ty::vstore_slice(r_ptr)) | ty::ty_evec(_, ty::vstore_slice(r_ptr)) => { - match rcx.fcx.mk_subr(true, index_expr.span, r_index_expr, r_ptr) { - result::Ok(*) => {} - result::Err(*) => { - tcx.sess.span_err( - index_expr.span, - fmt!("index of slice outside its lifetime")); - note_and_explain_region( - tcx, - "the slice is only valid for ", - r_ptr, - ""); - } - } + rcx.fcx.mk_subr(true, infer::IndexSlice(index_expr.span), + r_index_expr, r_ptr); } _ => {} @@ -616,25 +592,8 @@ fn constrain_free_variables(rcx: @mut Rcx, let def = freevar.def; let en_region = encl_region_of_def(rcx.fcx, def); debug!("en_region = %s", en_region.repr(tcx)); - match rcx.fcx.mk_subr(true, freevar.span, - region, en_region) { - result::Ok(()) => {} - result::Err(_) => { - tcx.sess.span_err( - freevar.span, - "captured variable does not outlive the enclosing closure"); - note_and_explain_region( - tcx, - "captured variable is valid for ", - en_region, - ""); - note_and_explain_region( - tcx, - "closure is valid for ", - region, - ""); - } - } + rcx.fcx.mk_subr(true, infer::FreeVariable(freevar.span), + region, en_region); } } @@ -642,7 +601,7 @@ fn constrain_regions_in_type_of_node( rcx: @mut Rcx, id: ast::node_id, minimum_lifetime: ty::Region, - span: span) -> bool + origin: infer::SubregionOrigin) -> bool { //! Guarantees that any lifetimes which appear in the type of //! the node `id` (after applying adjustments) are valid for at @@ -655,18 +614,18 @@ fn constrain_regions_in_type_of_node( // report errors later on in the writeback phase. let ty0 = rcx.resolve_node_type(id); let adjustment = rcx.fcx.inh.adjustments.find_copy(&id); - let ty = ty::adjust_ty(tcx, span, ty0, adjustment); + let ty = ty::adjust_ty(tcx, origin.span(), ty0, adjustment); debug!("constrain_regions_in_type_of_node(\ ty=%s, ty0=%s, id=%d, minimum_lifetime=%?, adjustment=%?)", ty_to_str(tcx, ty), ty_to_str(tcx, ty0), id, minimum_lifetime, adjustment); - constrain_regions_in_type(rcx, minimum_lifetime, span, ty) + constrain_regions_in_type(rcx, minimum_lifetime, origin, ty) } fn constrain_regions_in_type( rcx: @mut Rcx, minimum_lifetime: ty::Region, - span: span, + origin: infer::SubregionOrigin, ty: ty::t) -> bool { /*! @@ -700,40 +659,14 @@ fn constrain_regions_in_type( // (e.g., the `&` in `fn(&T)`). Such regions need not be // constrained by `minimum_lifetime` as they are placeholders // for regions that are as-yet-unknown. + } else if r_sub == minimum_lifetime { + rcx.fcx.mk_subr( + true, origin, + r_sub, r_sup); } else { - match rcx.fcx.mk_subr(true, span, r_sub, r_sup) { - result::Err(_) => { - if r_sub == minimum_lifetime { - tcx.sess.span_err( - span, - fmt!("reference is not valid outside of its lifetime")); - note_and_explain_region( - tcx, - "the reference is only valid for ", - r_sup, - ""); - } else { - tcx.sess.span_err( - span, - fmt!("in type `%s`, pointer has a longer lifetime than \ - the data it references", - rcx.fcx.infcx().ty_to_str(ty))); - note_and_explain_region( - tcx, - "the pointer is valid for ", - r_sub, - ""); - note_and_explain_region( - tcx, - "but the referenced data is only valid for ", - r_sup, - ""); - } - rcx.errors_reported += 1u; - } - result::Ok(()) => { - } - } + rcx.fcx.mk_subr( + true, infer::ReferenceOutlivesReferent(ty, origin.span()), + r_sub, r_sup); } } @@ -788,8 +721,9 @@ pub mod guarantor { */ - use middle::typeck::check::regionck::{Rcx, infallibly_mk_subr}; + use middle::typeck::check::regionck::Rcx; use middle::typeck::check::regionck::mk_subregion_due_to_derefence; + use middle::typeck::infer; use middle::ty; use syntax::ast; use syntax::codemap::span; @@ -869,9 +803,11 @@ pub mod guarantor { rcx: @mut Rcx, expr: @ast::expr, sub_region: ty::Region, - sup_region: Option) { + sup_region: Option) + { for sup_region.iter().advance |r| { - infallibly_mk_subr(rcx, true, expr.span, sub_region, *r); + rcx.fcx.mk_subr(true, infer::Reborrow(expr.span), + sub_region, *r); } } } @@ -929,7 +865,7 @@ pub mod guarantor { let tcx = rcx.fcx.ccx.tcx; debug!("rptr_ty=%s", ty_to_str(tcx, rptr_ty)); let r = ty::ty_region(tcx, span, rptr_ty); - infallibly_mk_subr(rcx, true, span, r, bound); + rcx.fcx.mk_subr(true, infer::Reborrow(span), r, bound); } } @@ -1259,27 +1195,3 @@ pub mod guarantor { } } - -pub fn infallibly_mk_subr(rcx: @mut Rcx, - a_is_expected: bool, - span: span, - a: ty::Region, - b: ty::Region) { - /*! - * Constrains `a` to be a subregion of `b`. In many cases, we - * know that this can never yield an error due to the way that - * region inferencing works. Therefore just report a bug if we - * ever see `Err(_)`. - */ - - match rcx.fcx.mk_subr(a_is_expected, span, a, b) { - result::Ok(()) => {} - result::Err(e) => { - rcx.fcx.ccx.tcx.sess.span_bug( - span, - fmt!("Supposedly infallible attempt to \ - make %? < %? failed: %?", - a, b, e)); - } - } -} diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 7a3c02efebec..d90863344396 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -101,18 +101,18 @@ fn lookup_vtables(vcx: &VtableContext, // Substitute the values of the type parameters that may // appear in the bound. - let trait_ref = (*trait_ref).subst(tcx, substs); + let trait_ref = trait_ref.subst(tcx, substs); debug!("after subst: %s", trait_ref.repr(tcx)); - match lookup_vtable(vcx, location_info, *ty, &trait_ref, is_early) { + match lookup_vtable(vcx, location_info, *ty, trait_ref, is_early) { Some(vtable) => param_result.push(vtable), None => { vcx.tcx().sess.span_fatal( location_info.span, fmt!("failed to find an implementation of \ trait %s for %s", - vcx.infcx.trait_ref_to_str(&trait_ref), + vcx.infcx.trait_ref_to_str(trait_ref), vcx.infcx.ty_to_str(*ty))); } } @@ -152,8 +152,8 @@ fn fixup_substs(vcx: &VtableContext, location_info: &LocationInfo, fn relate_trait_refs(vcx: &VtableContext, location_info: &LocationInfo, - act_trait_ref: &ty::TraitRef, - exp_trait_ref: &ty::TraitRef) + act_trait_ref: @ty::TraitRef, + exp_trait_ref: @ty::TraitRef) { /*! * @@ -162,8 +162,11 @@ fn relate_trait_refs(vcx: &VtableContext, * error otherwise. */ - match infer::mk_sub_trait_refs(vcx.infcx, false, location_info.span, - act_trait_ref, exp_trait_ref) + match infer::mk_sub_trait_refs(vcx.infcx, + false, + infer::RelateTraitRefs(location_info.span), + act_trait_ref, + exp_trait_ref) { result::Ok(()) => {} // Ok. result::Err(ref err) => { @@ -191,7 +194,7 @@ fn relate_trait_refs(vcx: &VtableContext, fn lookup_vtable(vcx: &VtableContext, location_info: &LocationInfo, ty: ty::t, - trait_ref: &ty::TraitRef, + trait_ref: @ty::TraitRef, is_early: bool) -> Option { @@ -304,7 +307,8 @@ fn lookup_vtable(vcx: &VtableContext, } = impl_self_ty(vcx, location_info, im.did); match infer::mk_subty(vcx.infcx, false, - location_info.span, + infer::RelateSelfType( + location_info.span), ty, for_ty) { result::Err(_) => loop, @@ -337,11 +341,10 @@ fn lookup_vtable(vcx: &VtableContext, vcx.infcx.trait_ref_to_str(trait_ref), vcx.infcx.trait_ref_to_str(of_trait_ref)); - let of_trait_ref = - (*of_trait_ref).subst(tcx, &substs); + let of_trait_ref = of_trait_ref.subst(tcx, &substs); relate_trait_refs( vcx, location_info, - &of_trait_ref, trait_ref); + of_trait_ref, trait_ref); // Recall that trait_ref -- the trait type // we're casting to -- is the trait with @@ -450,7 +453,7 @@ fn fixup_ty(vcx: &VtableContext, fn connect_trait_tps(vcx: &VtableContext, location_info: &LocationInfo, impl_substs: &ty::substs, - trait_ref: &ty::TraitRef, + trait_ref: @ty::TraitRef, impl_did: ast::def_id) { let tcx = vcx.tcx(); @@ -461,8 +464,8 @@ fn connect_trait_tps(vcx: &VtableContext, "connect_trait_tps invoked on a type impl") }; - let impl_trait_ref = (*impl_trait_ref).subst(tcx, impl_substs); - relate_trait_refs(vcx, location_info, &impl_trait_ref, trait_ref); + let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs); + relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref); } fn insert_vtables(fcx: @mut FnCtxt, @@ -581,7 +584,7 @@ pub fn early_resolve_expr(ex: @ast::expr, ccx: fcx.ccx, infcx: fcx.infcx() }; - let target_trait_ref = ty::TraitRef { + let target_trait_ref = @ty::TraitRef { def_id: target_def_id, substs: ty::substs { tps: copy target_substs.tps, @@ -593,7 +596,7 @@ pub fn early_resolve_expr(ex: @ast::expr, lookup_vtable(&vcx, location_info, mt.ty, - &target_trait_ref, + target_trait_ref, is_early); match vtable_opt { Some(vtable) => { @@ -622,7 +625,8 @@ pub fn early_resolve_expr(ex: @ast::expr, ty::RegionTraitStore(rb)) => { infer::mk_subr(fcx.infcx(), false, - ex.span, + infer::RelateObjectBound( + ex.span), rb, ra); } diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 8748d3dcd23b..24ac63ac7b07 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -36,6 +36,7 @@ use middle::typeck::infer::combine::Combine; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::{new_infer_ctxt, resolve_ivar}; use middle::typeck::infer::{resolve_nested_tvar, resolve_type}; +use middle::typeck::infer; use syntax::ast::{crate, def_id, def_struct, def_ty}; use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct}; use syntax::ast::{local_crate, method, trait_ref, ty_path}; @@ -546,10 +547,10 @@ impl CoherenceChecker { pub fn universally_quantify_polytype(&self, polytype: ty_param_bounds_and_ty) -> UniversalQuantificationResult { - // NDM--this span is bogus. let self_region = polytype.generics.region_param.map( - |_r| self.inference_context.next_region_var_nb(dummy_sp())); + |_| self.inference_context.next_region_var( + infer::BoundRegionInCoherence)); let bounds_count = polytype.generics.type_param_defs.len(); let type_parameters = self.inference_context.next_ty_vars(bounds_count); @@ -580,11 +581,9 @@ impl CoherenceChecker { b: &'a UniversalQuantificationResult) -> bool { - let mut might_unify = true; - let _ = do self.inference_context.probe { - let result = self.inference_context.sub(true, dummy_sp()) - .tys(a.monotype, b.monotype); - if result.is_ok() { + match infer::can_mk_subty(self.inference_context, + a.monotype, b.monotype) { + Ok(_) => { // Check to ensure that each parameter binding respected its // kind bounds. let xs = [a, b]; @@ -604,8 +603,7 @@ impl CoherenceChecker { self.inference_context.tcx, resolved_ty) { - might_unify = false; - break; + return false; } } Err(*) => { @@ -615,13 +613,13 @@ impl CoherenceChecker { } } } - } else { - might_unify = false; + true } - result - }; - might_unify + Err(_) => { + false + } + } } pub fn get_self_type_for_implementation(&self, implementation: @Impl) diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 85bd2bc2d75e..de05aca61caf 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -615,7 +615,8 @@ pub fn compare_impl_method(tcx: ty::ctxt, }; debug!("trait_fty (post-subst): %s", trait_fty.repr(tcx)); - match infer::mk_subty(infcx, false, cm.span, impl_fty, trait_fty) { + match infer::mk_subty(infcx, false, infer::MethodCompatCheck(cm.span), + impl_fty, trait_fty) { result::Ok(()) => {} result::Err(ref terr) => { tcx.sess.span_err( diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 63f882f5e541..03d243797b32 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -70,7 +70,7 @@ use middle::ty::{AutoDerefRef}; use middle::ty::{vstore_slice, vstore_box, vstore_uniq}; use middle::ty::{mt}; use middle::ty; -use middle::typeck::infer::{CoerceResult, resolve_type}; +use middle::typeck::infer::{CoerceResult, resolve_type, Coercion}; use middle::typeck::infer::combine::CombineFields; use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; @@ -165,7 +165,7 @@ impl Coerce { } Err(e) => { self.infcx.tcx.sess.span_bug( - self.span, + self.trace.origin.span(), fmt!("Failed to resolve even without \ any force options: %?", e)); } @@ -189,7 +189,7 @@ impl Coerce { // yield. let sub = Sub(**self); - let r_borrow = self.infcx.next_region_var_nb(self.span); + let r_borrow = self.infcx.next_region_var(Coercion(self.trace)); let inner_ty = match *sty_a { ty::ty_box(mt_a) => mt_a.ty, @@ -227,7 +227,7 @@ impl Coerce { } }; - let r_a = self.infcx.next_region_var_nb(self.span); + let r_a = self.infcx.next_region_var(Coercion(self.trace)); let a_borrowed = ty::mk_estr(self.infcx.tcx, vstore_slice(r_a)); if_ok!(self.subtype(a_borrowed, b)); Ok(Some(@AutoDerefRef(AutoDerefRef { @@ -247,7 +247,7 @@ impl Coerce { b.inf_str(self.infcx)); let sub = Sub(**self); - let r_borrow = self.infcx.next_region_var_nb(self.span); + let r_borrow = self.infcx.next_region_var(Coercion(self.trace)); let ty_inner = match *sty_a { ty::ty_evec(mt, _) => mt.ty, _ => { @@ -285,7 +285,7 @@ impl Coerce { } }; - let r_borrow = self.infcx.next_region_var_nb(self.span); + let r_borrow = self.infcx.next_region_var(Coercion(self.trace)); let a_borrowed = ty::mk_closure( self.infcx.tcx, ty::ClosureTy { diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index adc263cbc4d8..8af454774b82 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -65,6 +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::{SubtypeOrigin, SubtypeTrace}; use util::common::indent; use std::result::{iter_vec2, map_vec2}; @@ -79,7 +80,7 @@ pub trait Combine { fn infcx(&self) -> @mut InferCtxt; fn tag(&self) -> ~str; fn a_is_expected(&self) -> bool; - fn span(&self) -> span; + fn trace(&self) -> SubtypeTrace; fn sub(&self) -> Sub; fn lub(&self) -> Lub; @@ -121,7 +122,7 @@ pub trait Combine { pub struct CombineFields { infcx: @mut InferCtxt, a_is_expected: bool, - span: span, + trace: SubtypeTrace, } pub fn expected_found( diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs new file mode 100644 index 000000000000..079a01beaa14 --- /dev/null +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -0,0 +1,434 @@ +// 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. + +/*! + +Error Reporting Code for the inference engine + +Because of the way inference, and in particular region inference, +works, it often happens that errors are not detected until far after +the relevant line of code has been type-checked. Therefore, there is +an elaborate system to track why a particular constraint in the +inference graph arose so that we can explain to the user what gave +rise to a patricular error. + +The basis of the system are the "origin" types. An "origin" is the +reason that a constraint or inference variable arose. There are +different "origin" enums for different kinds of constraints/variables +(e.g., `SubtypeOrigin`, `RegionVariableOrigin`). An origin always has +a span, but also more information so that we can generate a meaningful +error message. + +Having a catalogue of all the different reasons an error can arise is +also useful for other reasons, like cross-referencing FAQs etc, though +we are not really taking advantage of this yet. + +# Region Inference + +Region inference is particularly tricky because it always succeeds "in +the moment" and simply registers a constraint. Then, at the end, we +can compute the full graph and report errors, so we need to be able to +store and later report what gave rise to the conflicting constraints. + +# Subtype Trace + +Determing whether `T1 <: T2` often involves a number of subtypes and +subconstraints along the way. A "SubtypeTrace" is an extended version +of an origin that traces the types and other values that were being +compared. It is not necessarily comprehensive (in fact, at the time of +this writing it only tracks the root values being compared) but I'd +like to extend it to include significant "waypoints". For example, if +you are comparing `(T1, T2) <: (T3, T4)`, and the problem is that `T2 +<: T4` fails, I'd like the trace to include enough information to say +"in the 2nd element of the tuple". Similarly, failures when comparing +arguments or return types in fn types should be able to cite the +specific position, etc. + +# Reality vs plan + +Of course, there is still a LOT of code in typeck that has yet to be +ported to this system, and which relies on string concatenation at the +time of error detection. + +*/ + +use core::prelude::*; +use middle::ty; +use middle::ty::Region; +use middle::typeck::infer; +use middle::typeck::infer::InferCtxt; +use middle::typeck::infer::SubtypeTrace; +use middle::typeck::infer::SubtypeOrigin; +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; + +impl InferCtxt { + pub fn report_region_errors(@mut self, + errors: &OptVec) { + for errors.each |error| { + match *error { + ConcreteFailure(origin, sub, sup) => { + self.report_concrete_failure(origin, sub, sup); + } + + SubSupConflict(var_origin, + sub_origin, sub_r, + sup_origin, sup_r) => { + self.report_sub_sup_conflict(var_origin, + sub_origin, sub_r, + sup_origin, sup_r); + } + + SupSupConflict(var_origin, + origin1, r1, + origin2, r2) => { + self.report_sup_sup_conflict(var_origin, + origin1, r1, + origin2, r2); + } + } + } + } + + fn report_and_explain_type_error(@mut self, + trace: SubtypeTrace, + terr: &ty::type_err) { + let tcx = self.tcx; + + let expected_found_str = match self.values_str(&trace.values) { + Some(v) => v, + None => { + return; /* derived error */ + } + }; + + let message_root_str = match trace.origin { + infer::Misc(_) => "mismatched types", + infer::MethodCompatCheck(_) => "method not compatible with trait", + infer::ExprAssignable(_) => "mismatched types", + infer::RelateTraitRefs(_) => "mismatched traits", + infer::RelateSelfType(_) => "mismatched types" + }; + + self.tcx.sess.span_err( + trace.origin.span(), + fmt!("%s: %s (%s)", + message_root_str, + expected_found_str, + ty::type_err_to_str(tcx, terr))); + + ty::note_and_explain_type_err(self.tcx, terr); + } + + fn values_str(@mut self, values: &ValuePairs) -> Option<~str> { + /*! + * Returns a string of the form "expected `%s` but found `%s`", + * or None if this is a derived error. + */ + match *values { + infer::Types(ref exp_found) => { + self.expected_found_str(exp_found) + } + infer::TraitRefs(ref exp_found) => { + self.expected_found_str(exp_found) + } + } + } + + fn expected_found_str( + @mut self, + exp_found: &ty::expected_found) + -> Option<~str> + { + let expected = exp_found.expected.resolve(self); + if expected.contains_error() { + return None; + } + + let found = exp_found.found.resolve(self); + if found.contains_error() { + return None; + } + + Some(fmt!("expected `%s` but found `%s`", + expected.user_string(self.tcx), + found.user_string(self.tcx))) + } + + fn report_concrete_failure(@mut self, + origin: SubregionOrigin, + sub: Region, + sup: Region) { + match origin { + infer::Subtype(trace) => { + let terr = ty::terr_regions_does_not_outlive(sub, sup); + self.report_and_explain_type_error(trace, &terr); + } + infer::Reborrow(span) => { + self.tcx.sess.span_err( + span, + "lifetime of borrowed pointer outlines \ + lifetime of borrowed content..."); + note_and_explain_region( + self.tcx, + "...the borrowed pointer is valid for ", + sub, + "..."); + note_and_explain_region( + self.tcx, + "...but the borrowed content is only valid for ", + sup, + ""); + } + infer::InvokeClosure(span) => { + self.tcx.sess.span_err( + span, + "cannot invoke closure outside of its lifetime"); + note_and_explain_region( + self.tcx, + "the closure is only valid for ", + sup, + ""); + } + infer::DerefPointer(span) => { + self.tcx.sess.span_err( + span, + "dereference of reference outside its lifetime"); + note_and_explain_region( + self.tcx, + "the reference is only valid for ", + sup, + ""); + } + infer::FreeVariable(span) => { + self.tcx.sess.span_err( + span, + "captured variable does not outlive the enclosing closure"); + note_and_explain_region( + self.tcx, + "captured variable is valid for ", + sup, + ""); + note_and_explain_region( + self.tcx, + "closure is valid for ", + sub, + ""); + } + infer::IndexSlice(span) => { + self.tcx.sess.span_err( + span, + fmt!("index of slice outside its lifetime")); + note_and_explain_region( + self.tcx, + "the slice is only valid for ", + sup, + ""); + } + infer::RelateObjectBound(span) => { + self.tcx.sess.span_err( + span, + "lifetime of the source pointer does not outlive \ + lifetime bound of the object type"); + note_and_explain_region( + self.tcx, + "object type is valid for ", + sub, + ""); + note_and_explain_region( + self.tcx, + "source pointer is only valid for ", + sup, + ""); + } + infer::CallRcvr(span) => { + self.tcx.sess.span_err( + span, + "lifetime of method receiver does not outlive \ + the method call"); + note_and_explain_region( + self.tcx, + "the receiver is only valid for ", + sup, + ""); + } + infer::CallArg(span) => { + self.tcx.sess.span_err( + span, + "lifetime of function argument does not outlive \ + the function call"); + note_and_explain_region( + self.tcx, + "the function argument is only valid for ", + sup, + ""); + } + infer::CallReturn(span) => { + self.tcx.sess.span_err( + span, + "lifetime of return value does not outlive \ + the function call"); + note_and_explain_region( + self.tcx, + "the return value is only valid for ", + sup, + ""); + } + infer::AddrOf(span) => { + self.tcx.sess.span_err( + span, + "borrowed pointer is not valid \ + at the time of borrow"); + note_and_explain_region( + self.tcx, + "the borrow is only valid for ", + sup, + ""); + } + infer::AutoBorrow(span) => { + self.tcx.sess.span_err( + span, + "automatically borrowed pointer is not valid \ + at the time of borrow"); + note_and_explain_region( + self.tcx, + "the automatic borrow is only valid for ", + sup, + ""); + } + infer::BindingTypeIsNotValidAtDecl(span) => { + self.tcx.sess.span_err( + span, + "lifetime of variable does not enclose its declaration"); + note_and_explain_region( + self.tcx, + "the variable is only valid for ", + sup, + ""); + } + infer::ReferenceOutlivesReferent(ty, span) => { + self.tcx.sess.span_err( + origin.span(), + fmt!("in type `%s`, pointer has a longer lifetime than \ + the data it references", + ty.user_string(self.tcx))); + note_and_explain_region( + self.tcx, + "the pointer is valid for ", + sub, + ""); + note_and_explain_region( + self.tcx, + "but the referenced data is only valid for ", + sup, + ""); + } + } + } + + fn report_sub_sup_conflict(@mut self, + var_origin: RegionVariableOrigin, + sub_origin: SubregionOrigin, + sub_region: Region, + sup_origin: SubregionOrigin, + sup_region: Region) { + self.tcx.sess.span_err( + var_origin.span(), + fmt!("cannot infer an appropriate lifetime \ + due to conflicting requirements")); + + note_and_explain_region( + self.tcx, + "first, the lifetime cannot outlive ", + sup_region, + "..."); + + self.tcx.sess.span_note( + sup_origin.span(), + fmt!("...due to the following expression")); + + note_and_explain_region( + self.tcx, + "but, the lifetime must be valid for ", + sub_region, + "..."); + + self.tcx.sess.span_note( + sub_origin.span(), + fmt!("...due to the following expression")); + } + + fn report_sup_sup_conflict(@mut self, + var_origin: RegionVariableOrigin, + origin1: SubregionOrigin, + region1: Region, + origin2: SubregionOrigin, + region2: Region) { + self.tcx.sess.span_err( + var_origin.span(), + fmt!("cannot infer an appropriate lifetime \ + due to conflicting requirements")); + + note_and_explain_region( + self.tcx, + "first, the lifetime must be contained by ", + region1, + "..."); + + self.tcx.sess.span_note( + origin1.span(), + fmt!("...due to the following expression")); + + note_and_explain_region( + self.tcx, + "but, the lifetime must also be contained by ", + region2, + "..."); + + self.tcx.sess.span_note( + origin2.span(), + fmt!("...due to the following expression")); + } +} + +trait Resolvable { + fn resolve(&self, infcx: @mut InferCtxt) -> Self; + fn contains_error(&self) -> bool; +} + +impl Resolvable for ty::t { + fn resolve(&self, infcx: @mut InferCtxt) -> ty::t { + infcx.resolve_type_vars_if_possible(*self) + } + fn contains_error(&self) -> bool { + ty::type_is_error(*self) + } +} + +impl Resolvable for @ty::TraitRef { + fn resolve(&self, infcx: @mut InferCtxt) -> @ty::TraitRef { + @infcx.resolve_type_vars_in_trait_ref_if_possible(*self) + } + fn contains_error(&self) -> bool { + ty::trait_ref_contains_error(*self) + } +} + diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 0dd45919be14..46ccfd24eb56 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -18,6 +18,7 @@ use middle::typeck::infer::lub::Lub; use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{cres, InferCtxt}; +use middle::typeck::infer::{SubtypeTrace, Subtype}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::isr_alist; use syntax::ast; @@ -37,7 +38,7 @@ impl Combine for Glb { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"glb" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn span(&self) -> span { self.span } + fn trace(&self) -> SubtypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } @@ -127,9 +128,7 @@ impl Combine for Glb { a.inf_str(self.infcx), b.inf_str(self.infcx)); - do indent { - self.infcx.region_vars.glb_regions(self.span, a, b) - } + Ok(self.infcx.region_vars.glb_regions(Subtype(self.trace), a, b)) } fn contraregions(&self, a: ty::Region, b: ty::Region) @@ -181,11 +180,11 @@ impl Combine for Glb { // Instantiate each bound region with a fresh region variable. let (a_with_fresh, a_isr) = self.infcx.replace_bound_regions_with_fresh_regions( - self.span, a); + self.trace, a); let a_vars = var_ids(self, a_isr); let (b_with_fresh, b_isr) = self.infcx.replace_bound_regions_with_fresh_regions( - self.span, b); + self.trace, b); let b_vars = var_ids(self, b_isr); // Collect constraints. @@ -277,7 +276,7 @@ impl Combine for Glb { } this.infcx.tcx.sess.span_bug( - this.span, + this.trace.origin.span(), fmt!("could not find original bound region for %?", r)); } diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 73e43c6c0762..b1a6aefd1794 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -530,7 +530,7 @@ pub fn var_ids(this: &T, isr: isr_alist) -> ~[RegionVid] { ty::re_infer(ty::ReVar(r)) => { result.push(r); } r => { this.infcx().tcx.sess.span_bug( - this.span(), + this.trace().origin.span(), fmt!("Found non-region-vid: %?", r)); } } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index ad063be86146..5d896bdadba7 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -19,6 +19,7 @@ use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{cres, InferCtxt}; use middle::typeck::infer::fold_regions_in_sig; +use middle::typeck::infer::{SubtypeTrace, Subtype}; use middle::typeck::isr_alist; use util::common::indent; use util::ppaux::mt_to_str; @@ -44,7 +45,7 @@ impl Combine for Lub { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"lub" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn span(&self) -> span { self.span } + fn trace(&self) -> SubtypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } @@ -119,9 +120,7 @@ impl Combine for Lub { a.inf_str(self.infcx), b.inf_str(self.infcx)); - do indent { - self.infcx.region_vars.lub_regions(self.span, a, b) - } + Ok(self.infcx.region_vars.lub_regions(Subtype(self.trace), a, b)) } fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres { @@ -137,10 +136,10 @@ impl Combine for Lub { // Instantiate each bound region with a fresh region variable. let (a_with_fresh, a_isr) = self.infcx.replace_bound_regions_with_fresh_regions( - self.span, a); + self.trace, a); let (b_with_fresh, _) = self.infcx.replace_bound_regions_with_fresh_regions( - self.span, b); + self.trace, b); // Collect constraints. let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh)); @@ -196,7 +195,7 @@ impl Combine for Lub { } this.infcx.tcx.sess.span_bug( - this.span, + this.trace.origin.span(), fmt!("Region %? is not associated with \ any bound region from A!", r0)); } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 28d943b58079..29f24f2ce9a7 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -264,7 +264,8 @@ use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{ValsAndBindings, Root}; use middle::typeck::isr_alist; use util::common::indent; -use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str}; +use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr, + UserString}; use std::result; use std::vec; @@ -286,6 +287,7 @@ pub mod sub; pub mod to_str; pub mod unify; pub mod coercion; +pub mod error_reporting; pub type Bound = Option; pub struct Bounds { @@ -319,6 +321,127 @@ pub struct InferCtxt { region_vars: RegionVarBindings, } +/// Why did we require that the two types be related? +/// +/// See `error_reporting.rs` for more details +pub enum SubtypeOrigin { + // Not yet categorized in a better way + Misc(span), + + // Checking that method of impl is compatible with trait + MethodCompatCheck(span), + + // Checking that this expression can be assigned where it needs to be + ExprAssignable(@ast::expr), + + // Relating trait refs when resolving vtables + RelateTraitRefs(span), + + // Relating trait refs when resolving vtables + RelateSelfType(span), +} + +/// See `error_reporting.rs` for more details +pub enum ValuePairs { + Types(ty::expected_found), + TraitRefs(ty::expected_found<@ty::TraitRef>), +} + +/// The trace designates the path through inference that we took to +/// encounter an error or subtyping constraint. +/// +/// See `error_reporting.rs` for more details. +pub struct SubtypeTrace { + origin: SubtypeOrigin, + values: ValuePairs, +} + +/// The origin of a `r1 <= r2` constraint. +/// +/// See `error_reporting.rs` for more details +pub enum SubregionOrigin { + // Arose from a subtyping relation + Subtype(SubtypeTrace), + + // Invocation of closure must be within its lifetime + InvokeClosure(span), + + // Dereference of borrowed pointer must be within its lifetime + DerefPointer(span), + + // Closure bound must not outlive captured free variables + FreeVariable(span), + + // Index into slice must be within its lifetime + IndexSlice(span), + + // When casting `&'a T` to an `&'b Trait` object, + // relating `'a` to `'b` + RelateObjectBound(span), + + // Creating a pointer `b` to contents of another borrowed pointer + Reborrow(span), + + // (&'a &'b T) where a >= b + ReferenceOutlivesReferent(ty::t, span), + + // A `ref b` whose region does not enclose the decl site + BindingTypeIsNotValidAtDecl(span), + + // Regions appearing in a method receiver must outlive method call + CallRcvr(span), + + // Regions appearing in a function argument must outlive func call + CallArg(span), + + // Region in return type of invoked fn must enclose call + CallReturn(span), + + // Region resulting from a `&` expr must enclose the `&` expr + AddrOf(span), + + // An auto-borrow that does not enclose the expr where it occurs + AutoBorrow(span), +} + +/// Reasons to create a region inference variable +/// +/// See `error_reporting.rs` for more details +pub enum RegionVariableOrigin { + // Region variables created for ill-categorized reasons, + // mostly indicates places in need of refactoring + MiscVariable(span), + + // Regions created by a `&P` or `[...]` pattern + PatternRegion(span), + + // Regions created by `&` operator + AddrOfRegion(span), + + // Regions created by `&[...]` literal + AddrOfSlice(span), + + // Regions created as part of an autoref of a method receiver + Autoref(span), + + // Regions created as part of an automatic coercion + Coercion(SubtypeTrace), + + // Region variables created for bound regions + // in a function or method that is called + BoundRegionInFnCall(span, ty::bound_region), + + // Region variables created for bound regions + // when doing subtyping/lub/glb computations + BoundRegionInFnType(span, ty::bound_region), + + BoundRegionInTypeOrImpl(span), + + BoundRegionInCoherence, + + BoundRegionError(span), +} + pub enum fixup_err { unresolved_int_ty(IntVid), unresolved_ty(TyVid), @@ -366,14 +489,18 @@ pub fn new_infer_ctxt(tcx: ty::ctxt) -> @mut InferCtxt { pub fn mk_subty(cx: @mut InferCtxt, a_is_expected: bool, - span: span, + origin: SubtypeOrigin, a: ty::t, b: ty::t) -> ures { debug!("mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - cx.sub(a_is_expected, span).tys(a, b) + let trace = SubtypeTrace { + origin: origin, + values: Types(expected_found(a_is_expected, a, b)) + }; + cx.sub(a_is_expected, trace).tys(a, b) } }.to_ures() } @@ -382,35 +509,40 @@ pub fn can_mk_subty(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { debug!("can_mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.probe { - cx.sub(true, codemap::dummy_sp()).tys(a, b) + let trace = SubtypeTrace { + origin: Misc(codemap::dummy_sp()), + values: Types(expected_found(true, a, b)) + }; + cx.sub(true, trace).tys(a, b) } }.to_ures() } pub fn mk_subr(cx: @mut InferCtxt, a_is_expected: bool, - span: span, + origin: SubregionOrigin, a: ty::Region, - b: ty::Region) - -> ures { + b: ty::Region) { debug!("mk_subr(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); - do indent { - do cx.commit { - cx.sub(a_is_expected, span).regions(a, b) - } - }.to_ures() + cx.region_vars.start_snapshot(); + cx.region_vars.make_subregion(origin, a, b); + cx.region_vars.commit(); } pub fn mk_eqty(cx: @mut InferCtxt, a_is_expected: bool, - span: span, + origin: SubtypeOrigin, a: ty::t, b: ty::t) -> ures { debug!("mk_eqty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let suber = cx.sub(a_is_expected, span); + let trace = SubtypeTrace { + origin: origin, + values: Types(expected_found(a_is_expected, a, b)) + }; + let suber = cx.sub(a_is_expected, trace); eq_tys(&suber, a, b) } }.to_ures() @@ -418,31 +550,49 @@ pub fn mk_eqty(cx: @mut InferCtxt, pub fn mk_sub_trait_refs(cx: @mut InferCtxt, a_is_expected: bool, - span: span, - a: &ty::TraitRef, - b: &ty::TraitRef) + origin: SubtypeOrigin, + a: @ty::TraitRef, + b: @ty::TraitRef) -> ures { debug!("mk_sub_trait_refs(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let suber = cx.sub(a_is_expected, span); + let trace = SubtypeTrace { + origin: origin, + values: TraitRefs(expected_found(a_is_expected, a, b)) + }; + let suber = cx.sub(a_is_expected, trace); suber.trait_refs(a, b) } }.to_ures() } +fn expected_found(a_is_expected: bool, + a: T, + b: T) -> ty::expected_found { + if a_is_expected { + ty::expected_found {expected: a, found: b} + } else { + ty::expected_found {expected: b, found: a} + } +} + pub fn mk_coercety(cx: @mut InferCtxt, a_is_expected: bool, - span: span, + origin: SubtypeOrigin, a: ty::t, b: ty::t) -> CoerceResult { debug!("mk_coercety(%s -> %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - Coerce(cx.combine_fields(a_is_expected, span)).tys(a, b) + let trace = SubtypeTrace { + origin: origin, + values: Types(expected_found(a_is_expected, a, b)) + }; + Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b) } } } @@ -451,8 +601,11 @@ pub fn can_mk_coercety(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { debug!("can_mk_coercety(%s -> %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.probe { - let span = codemap::dummy_sp(); - Coerce(cx.combine_fields(true, span)).tys(a, b) + let trace = SubtypeTrace { + origin: Misc(codemap::dummy_sp()), + values: Types(expected_found(true, a, b)) + }; + Coerce(cx.combine_fields(true, trace)).tys(a, b) } }.to_ures() } @@ -535,15 +688,17 @@ struct Snapshot { } impl InferCtxt { - pub fn combine_fields(@mut self, a_is_expected: bool, span: span) + pub fn combine_fields(@mut self, + a_is_expected: bool, + trace: SubtypeTrace) -> CombineFields { CombineFields {infcx: self, a_is_expected: a_is_expected, - span: span} + trace: trace} } - pub fn sub(@mut self, a_is_expected: bool, span: span) -> Sub { - Sub(self.combine_fields(a_is_expected, span)) + pub fn sub(@mut self, a_is_expected: bool, trace: SubtypeTrace) -> Sub { + Sub(self.combine_fields(a_is_expected, trace)) } pub fn in_snapshot(&self) -> bool { @@ -663,31 +818,13 @@ impl InferCtxt { ty::mk_float_var(self.tcx, self.next_float_var_id()) } - pub fn next_region_var_nb(&mut self, span: span) -> ty::Region { - ty::re_infer(ty::ReVar(self.region_vars.new_region_var(span))) + pub fn next_region_var(&mut self, origin: RegionVariableOrigin) -> ty::Region { + ty::re_infer(ty::ReVar(self.region_vars.new_region_var(origin))) } - pub fn next_region_var_with_lb(&mut self, - span: span, - lb_region: ty::Region) - -> ty::Region { - let region_var = self.next_region_var_nb(span); - - // add lb_region as a lower bound on the newly built variable - assert!(self.region_vars.make_subregion(span, - lb_region, - region_var).is_ok()); - - return region_var; - } - - pub fn next_region_var(&mut self, span: span, scope_id: ast::node_id) - -> ty::Region { - self.next_region_var_with_lb(span, ty::re_scope(scope_id)) - } - - pub fn resolve_regions(&mut self) { - self.region_vars.resolve_regions(); + pub fn resolve_regions(@mut self) { + let errors = self.region_vars.resolve_regions(); + self.report_region_errors(&errors); // see error_reporting.rs } pub fn ty_to_str(@mut self, t: ty::t) -> ~str { @@ -809,17 +946,13 @@ impl InferCtxt { } pub fn replace_bound_regions_with_fresh_regions(&mut self, - span: span, + trace: SubtypeTrace, fsig: &ty::FnSig) - -> (ty::FnSig, - isr_alist) { + -> (ty::FnSig, isr_alist) { let(isr, _, fn_sig) = replace_bound_regions_in_fn_sig(self.tcx, @Nil, None, fsig, |br| { - // N.B.: The name of the bound region doesn't have anything to - // do with the region variable that's created for it. The - // only thing we're doing with `br` here is using it in the - // debug message. - let rvar = self.next_region_var_nb(span); + let rvar = self.next_region_var( + BoundRegionInFnType(trace.origin.span(), br)); debug!("Bound region %s maps to %?", bound_region_to_str(self.tcx, "", false, br), rvar); @@ -838,3 +971,121 @@ pub fn fold_regions_in_sig( ty::fold_regions(tcx, t, |r, in_fn| fldr(r, in_fn)) } } + +impl SubtypeTrace { + pub fn span(&self) -> span { + self.origin.span() + } +} + +impl Repr for SubtypeTrace { + fn repr(&self, tcx: ty::ctxt) -> ~str { + fmt!("SubtypeTrace(%s)", self.origin.repr(tcx)) + } +} + +impl SubtypeOrigin { + pub fn span(&self) -> span { + match *self { + MethodCompatCheck(span) => span, + ExprAssignable(expr) => expr.span, + Misc(span) => span, + RelateTraitRefs(span) => span, + RelateSelfType(span) => span, + } + } +} + +impl Repr for SubtypeOrigin { + fn repr(&self, tcx: ty::ctxt) -> ~str { + match *self { + MethodCompatCheck(a) => fmt!("MethodCompatCheck(%s)", a.repr(tcx)), + ExprAssignable(a) => fmt!("ExprAssignable(%s)", a.repr(tcx)), + Misc(a) => fmt!("Misc(%s)", a.repr(tcx)), + RelateTraitRefs(a) => fmt!("RelateTraitRefs(%s)", a.repr(tcx)), + RelateSelfType(a) => fmt!("RelateSelfType(%s)", a.repr(tcx)), + } + } +} + +impl SubregionOrigin { + pub fn span(&self) -> span { + match *self { + Subtype(a) => a.span(), + InvokeClosure(a) => a, + DerefPointer(a) => a, + FreeVariable(a) => a, + IndexSlice(a) => a, + RelateObjectBound(a) => a, + Reborrow(a) => a, + ReferenceOutlivesReferent(_, a) => a, + BindingTypeIsNotValidAtDecl(a) => a, + CallRcvr(a) => a, + CallArg(a) => a, + CallReturn(a) => a, + AddrOf(a) => a, + AutoBorrow(a) => a, + } + } +} + +impl Repr for SubregionOrigin { + fn repr(&self, tcx: ty::ctxt) -> ~str { + match *self { + Subtype(a) => fmt!("Subtype(%s)", a.repr(tcx)), + InvokeClosure(a) => fmt!("InvokeClosure(%s)", a.repr(tcx)), + DerefPointer(a) => fmt!("DerefPointer(%s)", a.repr(tcx)), + FreeVariable(a) => fmt!("FreeVariable(%s)", a.repr(tcx)), + IndexSlice(a) => fmt!("IndexSlice(%s)", a.repr(tcx)), + RelateObjectBound(a) => fmt!("RelateObjectBound(%s)", a.repr(tcx)), + Reborrow(a) => fmt!("Reborrow(%s)", a.repr(tcx)), + ReferenceOutlivesReferent(_, a) => fmt!("ReferenceOutlivesReferent(%s)", a.repr(tcx)), + BindingTypeIsNotValidAtDecl(a) => fmt!("BindingTypeIsNotValidAtDecl(%s)", a.repr(tcx)), + CallRcvr(a) => fmt!("CallRcvr(%s)", a.repr(tcx)), + CallArg(a) => fmt!("CallArg(%s)", a.repr(tcx)), + CallReturn(a) => fmt!("CallReturn(%s)", a.repr(tcx)), + AddrOf(a) => fmt!("AddrOf(%s)", a.repr(tcx)), + AutoBorrow(a) => fmt!("AutoBorrow(%s)", a.repr(tcx)), + } + } +} + +impl RegionVariableOrigin { + pub fn span(&self) -> span { + match *self { + MiscVariable(a) => a, + PatternRegion(a) => a, + AddrOfRegion(a) => a, + AddrOfSlice(a) => a, + Autoref(a) => a, + Coercion(a) => a.span(), + BoundRegionInFnCall(a, _) => a, + BoundRegionInFnType(a, _) => a, + BoundRegionInTypeOrImpl(a) => a, + BoundRegionInCoherence => codemap::dummy_sp(), + BoundRegionError(a) => a, + } + } +} + +impl Repr for RegionVariableOrigin { + fn repr(&self, tcx: ty::ctxt) -> ~str { + match *self { + MiscVariable(a) => fmt!("MiscVariable(%s)", a.repr(tcx)), + PatternRegion(a) => fmt!("PatternRegion(%s)", a.repr(tcx)), + AddrOfRegion(a) => fmt!("AddrOfRegion(%s)", a.repr(tcx)), + AddrOfSlice(a) => fmt!("AddrOfSlice(%s)", a.repr(tcx)), + Autoref(a) => fmt!("Autoref(%s)", a.repr(tcx)), + Coercion(a) => fmt!("Coercion(%s)", a.repr(tcx)), + BoundRegionInFnCall(a, b) => fmt!("BoundRegionInFnCall(%s,%s)", + a.repr(tcx), b.repr(tcx)), + BoundRegionInFnType(a, b) => fmt!("BoundRegionInFnType(%s,%s)", + a.repr(tcx), b.repr(tcx)), + BoundRegionInTypeOrImpl(a) => fmt!("BoundRegionInTypeOrImpl(%s)", + a.repr(tcx)), + BoundRegionInCoherence => fmt!("BoundRegionInCoherence"), + BoundRegionError(a) => fmt!("BoundRegionError(%s)", a.repr(tcx)), + } + } +} + diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index db17405fc266..82fbb6b8ce7e 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -542,8 +542,10 @@ use middle::ty::{FreeRegion, Region, RegionVid}; use middle::ty::{re_empty, re_static, re_infer, re_free, re_bound}; use middle::ty::{re_scope, ReVar, ReSkolemized, br_fresh}; 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; +use util::ppaux::{note_and_explain_region, Repr, UserString}; use std::cell::Cell; use std::hashmap::{HashMap, HashSet}; @@ -551,6 +553,8 @@ use std::uint; use std::vec; use syntax::codemap::span; use syntax::ast; +use syntax::opt_vec; +use syntax::opt_vec::OptVec; #[deriving(Eq,IterBytes)] enum Constraint { @@ -576,12 +580,37 @@ enum CombineMapType { Lub, Glb } +pub enum RegionResolutionError { + /// `ConcreteFailure(o, a, b)`: + /// + /// `o` requires that `a <= b`, but this does not hold + ConcreteFailure(SubregionOrigin, Region, Region), + + /// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`: + /// + /// Could not infer a value for `v` because `sub_r <= v` (due to + /// `sub_origin`) but `v <= sup_r` (due to `sup_origin`) and + /// `sub_r <= sup_r` does not hold. + SubSupConflict(RegionVariableOrigin, + SubregionOrigin, Region, + SubregionOrigin, Region), + + /// `SupSupConflict(v, origin1, r1, origin2, r2)`: + /// + /// Could not infer a value for `v` because `v <= r1` (due to + /// `origin1`) and `v <= r2` (due to `origin2`) and + /// `r1` and `r2` have no intersection. + SupSupConflict(RegionVariableOrigin, + SubregionOrigin, Region, + SubregionOrigin, Region), +} + type CombineMap = HashMap; pub struct RegionVarBindings { tcx: ty::ctxt, - var_spans: ~[span], - constraints: HashMap, + var_origins: ~[RegionVariableOrigin], + constraints: HashMap, lubs: CombineMap, glbs: CombineMap, skolemization_count: uint, @@ -606,7 +635,7 @@ pub struct RegionVarBindings { pub fn RegionVarBindings(tcx: ty::ctxt) -> RegionVarBindings { RegionVarBindings { tcx: tcx, - var_spans: ~[], + var_origins: ~[], values: Cell::new_empty(), constraints: HashMap::new(), lubs: HashMap::new(), @@ -647,8 +676,8 @@ impl RegionVarBindings { match undo_item { Snapshot => {} AddVar(vid) => { - assert_eq!(self.var_spans.len(), vid.to_uint() + 1); - self.var_spans.pop(); + assert_eq!(self.var_origins.len(), vid.to_uint() + 1); + self.var_origins.pop(); } AddConstraint(ref constraint) => { self.constraints.remove(constraint); @@ -664,18 +693,18 @@ impl RegionVarBindings { } pub fn num_vars(&mut self) -> uint { - self.var_spans.len() + self.var_origins.len() } - pub fn new_region_var(&mut self, span: span) -> RegionVid { + pub fn new_region_var(&mut self, origin: RegionVariableOrigin) -> RegionVid { let id = self.num_vars(); - self.var_spans.push(span); + self.var_origins.push(origin); let vid = RegionVid { id: id }; if self.in_snapshot() { self.undo_log.push(AddVar(vid)); } - debug!("created new region variable %? with span %?", - vid, self.tcx.sess.codemap.span_to_str(span)); + debug!("created new region variable %? with origin %?", + vid, origin.repr(self.tcx)); return vid; } @@ -705,109 +734,106 @@ impl RegionVarBindings { re_bound(br_fresh(sc)) } - pub fn add_constraint(&mut self, constraint: Constraint, span: span) { + pub fn add_constraint(&mut self, + constraint: Constraint, + origin: SubregionOrigin) { // cannot add constraints once regions are resolved assert!(self.values.is_empty()); debug!("RegionVarBindings: add_constraint(%?)", constraint); - if self.constraints.insert(constraint, span) { + if self.constraints.insert(constraint, origin) { if self.in_snapshot() { self.undo_log.push(AddConstraint(constraint)); } } } - pub fn make_subregion(&mut self, span: span, sub: Region, sup: Region) - -> cres<()> { + pub fn make_subregion(&mut self, + origin: SubregionOrigin, + sub: Region, + sup: Region) { // cannot add constraints once regions are resolved assert!(self.values.is_empty()); debug!("RegionVarBindings: make_subregion(%?, %?)", sub, sup); match (sub, sup) { (re_infer(ReVar(sub_id)), re_infer(ReVar(sup_id))) => { - self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), span); - Ok(()) + self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin); } (r, re_infer(ReVar(sup_id))) => { - self.add_constraint(ConstrainRegSubVar(r, sup_id), span); - Ok(()) + self.add_constraint(ConstrainRegSubVar(r, sup_id), origin); } (re_infer(ReVar(sub_id)), r) => { - self.add_constraint(ConstrainVarSubReg(sub_id, r), span); - Ok(()) + self.add_constraint(ConstrainVarSubReg(sub_id, r), origin); } (re_bound(br), _) => { self.tcx.sess.span_bug( - span, + origin.span(), fmt!("Cannot relate bound region as subregion: %?", br)); } (_, re_bound(br)) => { self.tcx.sess.span_bug( - span, + origin.span(), fmt!("Cannot relate bound region as superregion: %?", br)); } _ => { - if self.is_subregion_of(sub, sup) { - Ok(()) - } else { - Err(ty::terr_regions_does_not_outlive(sub, sup)) - } + self.add_constraint(ConstrainRegSubReg(sub, sup), origin); } } } - pub fn lub_regions(&mut self, span: span, a: Region, b: Region) - -> cres { + pub fn lub_regions(&mut self, + origin: SubregionOrigin, + a: Region, + b: Region) + -> Region { // cannot add constraints once regions are resolved assert!(self.values.is_empty()); debug!("RegionVarBindings: lub_regions(%?, %?)", a, b); match (a, b) { - (re_static, _) | (_, re_static) => { - Ok(re_static) // nothing lives longer than static - } + (re_static, _) | (_, re_static) => { + re_static // nothing lives longer than static + } - (re_infer(ReVar(*)), _) | (_, re_infer(ReVar(*))) => { - self.combine_vars( - Lub, a, b, span, - |this, old_r, new_r| this.make_subregion(span, old_r, new_r)) - } - - _ => { - Ok(self.lub_concrete_regions(a, b)) - } + _ => { + self.combine_vars( + Lub, a, b, origin, + |this, old_r, new_r| + this.make_subregion(origin, old_r, new_r)) + } } } - pub fn glb_regions(&mut self, span: span, a: Region, b: Region) - -> cres { + pub fn glb_regions(&mut self, + origin: SubregionOrigin, + a: Region, + b: Region) + -> Region { // cannot add constraints once regions are resolved assert!(self.values.is_empty()); debug!("RegionVarBindings: glb_regions(%?, %?)", a, b); match (a, b) { - (re_static, r) | (r, re_static) => { - // static lives longer than everything else - Ok(r) - } + (re_static, r) | (r, re_static) => { + // static lives longer than everything else + r + } - (re_infer(ReVar(*)), _) | (_, re_infer(ReVar(*))) => { - self.combine_vars( - Glb, a, b, span, - |this, old_r, new_r| this.make_subregion(span, new_r, old_r)) - } - - _ => { - self.glb_concrete_regions(a, b) - } + _ => { + self.combine_vars( + Glb, a, b, origin, + |this, old_r, new_r| + this.make_subregion(origin, new_r, old_r)) + } } } pub fn resolve_var(&mut self, rid: RegionVid) -> ty::Region { if self.values.is_empty() { self.tcx.sess.span_bug( - self.var_spans[rid.to_uint()], + self.var_origins[rid.to_uint()].span(), fmt!("Attempt to resolve region variable before values have \ been computed!")); } @@ -830,46 +856,41 @@ impl RegionVarBindings { } } + fn combine_map<'a>(&'a mut self, + t: CombineMapType) + -> &'a mut CombineMap + { + match t { + Glb => &mut self.glbs, + Lub => &mut self.lubs, + } + } + pub fn combine_vars(&mut self, t: CombineMapType, a: Region, b: Region, - span: span, + origin: SubregionOrigin, relate: &fn(this: &mut RegionVarBindings, old_r: Region, - new_r: Region) -> cres<()>) - -> cres { + new_r: Region)) + -> Region { let vars = TwoRegions { a: a, b: b }; - let c; - { - // FIXME (#3850): shouldn't need a scope, nor should this need to be - // done twice to get the maps out - { - let combines = match t { - Glb => &self.glbs, Lub => &self.lubs - }; - match combines.find(&vars) { - Some(&c) => return Ok(re_infer(ReVar(c))), - None => () - } - } - c = self.new_region_var(span); - { - let combines = match t { - Glb => &mut self.glbs, Lub => &mut self.lubs - }; - combines.insert(vars, c); + match self.combine_map(t).find(&vars) { + Some(&c) => { + return re_infer(ReVar(c)); } + None => {} } + let c = self.new_region_var(infer::MiscVariable(origin.span())); + self.combine_map(t).insert(vars, c); if self.in_snapshot() { self.undo_log.push(AddCombination(t, vars)); } - do relate(self, a, re_infer(ReVar(c))).then { - do relate(self, b, re_infer(ReVar(c))).then { - debug!("combine_vars() c=%?", c); - Ok(re_infer(ReVar(c))) - } - } + relate(self, a, re_infer(ReVar(c))); + relate(self, b, re_infer(ReVar(c))); + debug!("combine_vars() c=%?", c); + re_infer(ReVar(c)) } pub fn vars_created_since_snapshot(&mut self, snapshot: uint) @@ -924,6 +945,9 @@ impl RegionVarBindings { AddConstraint(ConstrainVarSubReg(ref a, ref b)) => { Some((re_infer(ReVar(*a)), *b)) } + AddConstraint(ConstrainRegSubReg(a, b)) => { + Some((a, b)) + } _ => { None } @@ -931,11 +955,11 @@ impl RegionVarBindings { match regs { None => {} - Some((ref r1, ref r2)) => { + Some((r1, r2)) => { result_set = - consider_adding_edge(result_set, &r, r1, r2); + consider_adding_edge(result_set, r, r1, r2); result_set = - consider_adding_edge(result_set, &r, r2, r1); + consider_adding_edge(result_set, r, r2, r1); } } @@ -948,14 +972,14 @@ impl RegionVarBindings { return result_set; fn consider_adding_edge(result_set: ~[Region], - r: &Region, - r1: &Region, - r2: &Region) -> ~[Region] + r: Region, + r1: Region, + r2: Region) -> ~[Region] { let mut result_set = result_set; - if *r == *r1 { // Clearly, this is potentially inefficient. + if r == r1 { // Clearly, this is potentially inefficient. if !result_set.iter().any_(|x| x == r2) { - result_set.push(*r2); + result_set.push(r2); } } return result_set; @@ -969,10 +993,12 @@ impl RegionVarBindings { constraints, assuming such values can be found; if they cannot, errors are reported. */ - pub fn resolve_regions(&mut self) { + pub fn resolve_regions(&mut self) -> OptVec { debug!("RegionVarBindings: resolve_regions()"); - let v = self.infer_variable_values(); + let mut errors = opt_vec::Empty; + let v = self.infer_variable_values(&mut errors); self.values.put_back(v); + errors } } @@ -994,7 +1020,7 @@ impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[v_id.to_uint()], + self.var_origins[v_id.to_uint()].span(), fmt!("lub_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1096,7 +1122,7 @@ impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[v_id.to_uint()], + self.var_origins[v_id.to_uint()].span(), fmt!("glb_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1173,9 +1199,11 @@ impl RegionVarBindings { } } - fn report_type_error(&mut self, span: span, terr: &ty::type_err) { + fn report_type_error(&mut self, + origin: SubregionOrigin, + terr: &ty::type_err) { let terr_str = ty::type_err_to_str(self.tcx, terr); - self.tcx.sess.span_err(span, terr_str); + self.tcx.sess.span_err(origin.span(), terr_str); } fn intersect_scopes(&self, @@ -1210,7 +1238,7 @@ enum Classification { Expanding, Contracting } enum GraphNodeValue { NoValue, Value(Region), ErrorValue } struct GraphNode { - span: span, + origin: RegionVariableOrigin, classification: Classification, value: GraphNodeValue, head_edge: [uint, ..2], @@ -1219,7 +1247,6 @@ struct GraphNode { struct GraphEdge { next_edge: [uint, ..2], constraint: Constraint, - span: span, } struct Graph { @@ -1227,20 +1254,23 @@ struct Graph { edges: ~[GraphEdge], } -struct SpannedRegion { +struct RegionAndOrigin { region: Region, - span: span, + origin: SubregionOrigin, } impl RegionVarBindings { - pub fn infer_variable_values(&mut self) -> ~[GraphNodeValue] { + fn infer_variable_values(&mut self, + errors: &mut OptVec) + -> ~[GraphNodeValue] { let mut graph = self.construct_graph(); self.expansion(&mut graph); self.contraction(&mut graph); - self.extract_values_and_report_conflicts(&graph) + self.collect_concrete_region_errors(&graph, errors); + self.extract_values_and_collect_conflicts(&graph, errors) } - pub fn construct_graph(&mut self) -> Graph { + fn construct_graph(&mut self) -> Graph { let num_vars = self.num_vars(); let num_edges = self.constraints.len(); @@ -1251,7 +1281,7 @@ impl RegionVarBindings { // those nodes that have a concrete region predecessor to // Expanding. classification: Contracting, - span: self.var_spans[var_idx], + origin: self.var_origins[var_idx], value: NoValue, head_edge: [uint::max_value, uint::max_value] } @@ -1259,11 +1289,10 @@ impl RegionVarBindings { // It would be nice to write this using map(): let mut edges = vec::with_capacity(num_edges); - for self.constraints.iter().advance |(constraint, span)| { + for self.constraints.iter().advance |(constraint, _)| { edges.push(GraphEdge { next_edge: [uint::max_value, uint::max_value], constraint: *constraint, - span: *span }); } @@ -1284,6 +1313,10 @@ impl RegionVarBindings { ConstrainVarSubReg(a_id, _) => { insert_edge(&mut graph, a_id, Outgoing, edge_idx); } + ConstrainRegSubReg(*) => { + // Relations between two concrete regions do not + // require an edge in the graph. + } } } @@ -1305,7 +1338,7 @@ impl RegionVarBindings { } } - pub fn expansion(&mut self, graph: &mut Graph) { + fn expansion(&mut self, graph: &mut Graph) { do iterate_until_fixed_point(~"Expansion", graph) |nodes, edge| { match edge.constraint { ConstrainRegSubVar(a_region, b_vid) => { @@ -1325,15 +1358,19 @@ impl RegionVarBindings { // This is a contraction constraint. Ignore it. false } + ConstrainRegSubReg(*) => { + // No region variables involved. Ignore. + false + } } } } - pub fn expand_node(&mut self, - a_region: Region, - b_vid: RegionVid, - b_node: &mut GraphNode) - -> bool { + fn expand_node(&mut self, + a_region: Region, + b_vid: RegionVid, + b_node: &mut GraphNode) + -> bool { debug!("expand_node(%?, %? == %?)", a_region, b_vid, b_node.value); @@ -1365,7 +1402,8 @@ impl RegionVarBindings { } } - pub fn contraction(&mut self, graph: &mut Graph) { + fn contraction(&mut self, + graph: &mut Graph) { do iterate_until_fixed_point(~"Contraction", graph) |nodes, edge| { match edge.constraint { ConstrainRegSubVar(*) => { @@ -1385,15 +1423,19 @@ impl RegionVarBindings { let a_node = &mut nodes[a_vid.to_uint()]; self.contract_node(a_vid, a_node, b_region) } + ConstrainRegSubReg(*) => { + // No region variables involved. Ignore. + false + } } } } - pub fn contract_node(&mut self, - a_vid: RegionVid, - a_node: &mut GraphNode, - b_region: Region) - -> bool { + fn contract_node(&mut self, + a_vid: RegionVid, + a_node: &mut GraphNode, + b_region: Region) + -> bool { debug!("contract_node(%? == %?/%?, %?)", a_vid, a_node.value, a_node.classification, b_region); @@ -1461,9 +1503,42 @@ impl RegionVarBindings { } } - pub fn extract_values_and_report_conflicts(&mut self, graph: &Graph) - -> ~[GraphNodeValue] { - debug!("extract_values_and_report_conflicts()"); + fn collect_concrete_region_errors( + &mut self, + graph: &Graph, + errors: &mut OptVec) + { + let num_edges = graph.edges.len(); + for uint::range(0, num_edges) |edge_idx| { + let edge = &graph.edges[edge_idx]; + let origin = self.constraints.get_copy(&edge.constraint); + + let (sub, sup) = match edge.constraint { + ConstrainVarSubVar(*) | + ConstrainRegSubVar(*) | + ConstrainVarSubReg(*) => { + loop; + } + ConstrainRegSubReg(sub, sup) => { + (sub, sup) + } + }; + + if self.is_subregion_of(sub, sup) { + loop; + } + + errors.push(ConcreteFailure(origin, sub, sup)); + } + } + + fn extract_values_and_collect_conflicts( + &mut self, + graph: &Graph, + errors: &mut OptVec) + -> ~[GraphNodeValue] + { + debug!("extract_values_and_collect_conflicts()"); // This is the best way that I have found to suppress // duplicate and related errors. Basically we keep a set of @@ -1516,12 +1591,12 @@ impl RegionVarBindings { let node_vid = RegionVid { id: idx }; match node.classification { Expanding => { - self.report_error_for_expanding_node( - graph, dup_vec, node_vid); + self.collect_error_for_expanding_node( + graph, dup_vec, node_vid, errors); } Contracting => { - self.report_error_for_contracting_node( - graph, dup_vec, node_vid); + self.collect_error_for_contracting_node( + graph, dup_vec, node_vid, errors); } } } @@ -1531,10 +1606,13 @@ impl RegionVarBindings { }).collect() } - pub fn report_error_for_expanding_node(&mut self, - graph: &Graph, - dup_vec: &mut [uint], - node_idx: RegionVid) { + fn collect_error_for_expanding_node( + &mut self, + graph: &Graph, + dup_vec: &mut [uint], + node_idx: RegionVid, + errors: &mut OptVec) + { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. let (lower_bounds, lower_dup) = @@ -1550,50 +1628,33 @@ impl RegionVarBindings { for upper_bounds.iter().advance |upper_bound| { if !self.is_subregion_of(lower_bound.region, upper_bound.region) { - - self.tcx.sess.span_err( - self.var_spans[node_idx.to_uint()], - fmt!("cannot infer an appropriate lifetime \ - due to conflicting requirements")); - - note_and_explain_region( - self.tcx, - "first, the lifetime cannot outlive ", - upper_bound.region, - "..."); - - self.tcx.sess.span_note( - upper_bound.span, - fmt!("...due to the following expression")); - - note_and_explain_region( - self.tcx, - "but, the lifetime must be valid for ", + errors.push(SubSupConflict( + self.var_origins[node_idx.to_uint()], + lower_bound.origin, lower_bound.region, - "..."); - - self.tcx.sess.span_note( - lower_bound.span, - fmt!("...due to the following expression")); - + upper_bound.origin, + upper_bound.region)); return; } } } self.tcx.sess.span_bug( - self.var_spans[node_idx.to_uint()], - fmt!("report_error_for_expanding_node() could not find error \ + self.var_origins[node_idx.to_uint()].span(), + fmt!("collect_error_for_expanding_node() could not find error \ for var %?, lower_bounds=%s, upper_bounds=%s", node_idx, lower_bounds.map(|x| x.region).repr(self.tcx), upper_bounds.map(|x| x.region).repr(self.tcx))); } - pub fn report_error_for_contracting_node(&mut self, - graph: &Graph, - dup_vec: &mut [uint], - node_idx: RegionVid) { + fn collect_error_for_contracting_node( + &mut self, + graph: &Graph, + dup_vec: &mut [uint], + node_idx: RegionVid, + errors: &mut OptVec) + { // Errors in contracting nodes result from two upper-bounds // that have no intersection. let (upper_bounds, dup_found) = @@ -1609,32 +1670,12 @@ impl RegionVarBindings { upper_bound_2.region) { Ok(_) => {} Err(_) => { - - self.tcx.sess.span_err( - self.var_spans[node_idx.to_uint()], - fmt!("cannot infer an appropriate lifetime \ - due to conflicting requirements")); - - note_and_explain_region( - self.tcx, - "first, the lifetime must be contained by ", + errors.push(SupSupConflict( + self.var_origins[node_idx.to_uint()], + upper_bound_1.origin, upper_bound_1.region, - "..."); - - self.tcx.sess.span_note( - upper_bound_1.span, - fmt!("...due to the following expression")); - - note_and_explain_region( - self.tcx, - "but, the lifetime must also be contained by ", - upper_bound_2.region, - "..."); - - self.tcx.sess.span_note( - upper_bound_2.span, - fmt!("...due to the following expression")); - + upper_bound_2.origin, + upper_bound_2.region)); return; } } @@ -1642,23 +1683,23 @@ impl RegionVarBindings { } self.tcx.sess.span_bug( - self.var_spans[node_idx.to_uint()], - fmt!("report_error_for_contracting_node() could not find error \ + self.var_origins[node_idx.to_uint()].span(), + fmt!("collect_error_for_contracting_node() could not find error \ for var %?, upper_bounds=%s", node_idx, upper_bounds.map(|x| x.region).repr(self.tcx))); } - pub fn collect_concrete_regions(&mut self, - graph: &Graph, - orig_node_idx: RegionVid, - dir: Direction, - dup_vec: &mut [uint]) - -> (~[SpannedRegion], bool) { + fn collect_concrete_regions(&mut self, + graph: &Graph, + orig_node_idx: RegionVid, + dir: Direction, + dup_vec: &mut [uint]) + -> (~[RegionAndOrigin], bool) { struct WalkState { set: HashSet, stack: ~[RegionVid], - result: ~[SpannedRegion], + result: ~[RegionAndOrigin], dup_found: bool } let mut state = WalkState { @@ -1720,17 +1761,19 @@ impl RegionVarBindings { ConstrainRegSubVar(region, _) | ConstrainVarSubReg(_, region) => { - state.result.push(SpannedRegion { + state.result.push(RegionAndOrigin { region: region, - span: edge.span + origin: this.constraints.get_copy(&edge.constraint) }); } + + ConstrainRegSubReg(*) => {} } } } } - pub fn each_edge(&mut self, + pub fn each_edge(&self, graph: &Graph, node_idx: RegionVid, dir: Direction, diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index 905e86a73f06..ea66f8601af4 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -20,6 +20,7 @@ use middle::typeck::infer::InferCtxt; use middle::typeck::infer::lattice::CombineFieldsLatticeMethods; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; +use middle::typeck::infer::{SubtypeTrace, Subtype}; use util::common::{indent, indenter}; use util::ppaux::bound_region_to_str; @@ -36,7 +37,7 @@ impl Combine for Sub { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"sub" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn span(&self) -> span { self.span } + fn trace(&self) -> SubtypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } @@ -62,12 +63,8 @@ impl Combine for Sub { self.tag(), a.inf_str(self.infcx), b.inf_str(self.infcx)); - do indent { - match self.infcx.region_vars.make_subregion(self.span, a, b) { - Ok(()) => Ok(a), - Err(ref e) => Err((*e)) - } - } + self.infcx.region_vars.make_subregion(Subtype(self.trace), a, b); + Ok(a) } fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres { @@ -170,7 +167,7 @@ impl Combine for Sub { // region variable. let (a_sig, _) = self.infcx.replace_bound_regions_with_fresh_regions( - self.span, a); + self.trace, a); // Second, we instantiate each bound region in the supertype with a // fresh concrete region. diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 4eaa0b69d9cc..bbcfc73853a1 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -263,7 +263,7 @@ pub fn require_same_types( } } - match infer::mk_eqty(l_infcx, t1_is_expected, span, t1, t2) { + match infer::mk_eqty(l_infcx, t1_is_expected, infer::Misc(span), t1, t2) { result::Ok(()) => true, result::Err(ref terr) => { l_tcx.sess.span_err(span, msg() + ": " + diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 80344a9894fb..1a0cdd6fa64f 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -608,6 +608,12 @@ impl Repr for @ast::pat { } } +impl Repr for ty::bound_region { + fn repr(&self, tcx: ctxt) -> ~str { + bound_region_to_str(tcx, *self) + } +} + impl Repr for ty::Region { fn repr(&self, tcx: ctxt) -> ~str { region_to_str(tcx, "", false, *self) @@ -793,6 +799,19 @@ impl Repr for ty::BuiltinBounds { } } +impl Repr for span { + fn repr(&self, tcx: ctxt) -> ~str { + tcx.sess.codemap.span_to_str(*self) + } +} + +impl UserString for @A { + fn user_string(&self, tcx: ctxt) -> ~str { + let this: &A = &**self; + this.user_string(tcx) + } +} + impl UserString for ty::BuiltinBounds { fn user_string(&self, tcx: ctxt) -> ~str { if self.is_empty() { ~"" } else { diff --git a/src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs b/src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs index 82868647e57d..b00b701191e2 100644 --- a/src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs +++ b/src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of return value does not outlive the function call extern mod extra; use extra::arc; fn main() { diff --git a/src/test/compile-fail/arc-rw-state-shouldnt-escape.rs b/src/test/compile-fail/arc-rw-state-shouldnt-escape.rs index 6bd32866f898..001e6cf922f6 100644 --- a/src/test/compile-fail/arc-rw-state-shouldnt-escape.rs +++ b/src/test/compile-fail/arc-rw-state-shouldnt-escape.rs @@ -8,14 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime extern mod extra; use extra::arc; fn main() { let x = ~arc::RWARC(1); - let mut y = None; + let mut y = None; //~ ERROR lifetime of variable does not enclose its declaration do x.write |one| { y = Some(one); } *y.unwrap() = 2; + //~^ ERROR lifetime of return value does not outlive the function call + //~^^ ERROR dereference of reference outside its lifetime } diff --git a/src/test/compile-fail/arc-rw-write-mode-cond-shouldnt-escape.rs b/src/test/compile-fail/arc-rw-write-mode-cond-shouldnt-escape.rs index 534475319033..59e899dbbf2e 100644 --- a/src/test/compile-fail/arc-rw-write-mode-cond-shouldnt-escape.rs +++ b/src/test/compile-fail/arc-rw-write-mode-cond-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of variable does not enclose its declaration extern mod extra; use extra::arc; fn main() { diff --git a/src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs b/src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs index decb7b8af9f3..2599fb4dfa0c 100644 --- a/src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs +++ b/src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of variable does not enclose its declaration extern mod extra; use extra::arc; fn main() { diff --git a/src/test/compile-fail/borrowck-move-by-capture.rs b/src/test/compile-fail/borrowck-move-by-capture.rs index 0efde1df6c22..4ee824d1d49a 100644 --- a/src/test/compile-fail/borrowck-move-by-capture.rs +++ b/src/test/compile-fail/borrowck-move-by-capture.rs @@ -1,6 +1,4 @@ -extern mod extra; - -fn main() { +pub fn main() { let foo = ~3; let _pfoo = &foo; let _f: @fn() -> int = || *foo + 5; diff --git a/src/test/compile-fail/kindck-owned-trait-contains.rs b/src/test/compile-fail/kindck-owned-trait-contains.rs index 6bb90bff228d..33e122867bb3 100644 --- a/src/test/compile-fail/kindck-owned-trait-contains.rs +++ b/src/test/compile-fail/kindck-owned-trait-contains.rs @@ -23,13 +23,13 @@ fn main() { // Error results because the type of is inferred to be // @repeat<&'blk int> where blk is the lifetime of the block below. - let y = { //~ ERROR reference is not valid + let y = { //~ ERROR lifetime of variable does not enclose its declaration let x: &'blk int = &3; repeater(@x) }; - assert!(3 == *(y.get())); //~ ERROR dereference of reference outside its lifetime - //~^ ERROR reference is not valid outside of its lifetime - //~^^ ERROR reference is not valid outside of its lifetime - //~^^^ ERROR reference is not valid outside of its lifetime + assert!(3 == *(y.get())); + //~^ ERROR dereference of reference outside its lifetime + //~^^ ERROR automatically borrowed pointer is not valid at the time of borrow + //~^^^ ERROR lifetime of return value does not outlive the function call //~^^^^ ERROR cannot infer an appropriate lifetime } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index 35ba38624380..f92ea7f18cec 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -16,11 +16,13 @@ struct an_enum<'self>(&'self int); struct a_class<'self> { x:&'self int } fn a_fn1<'a,'b>(e: an_enum<'a>) -> an_enum<'b> { - return e; //~ ERROR mismatched types: expected `an_enum<'b>` but found `an_enum<'a>` + return e; //~ ERROR mismatched types: expected `an_enum<'b> ` but found `an_enum<'a> ` + //~^ ERROR cannot infer an appropriate lifetime } fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> { - return e; //~ ERROR mismatched types: expected `a_class<'b>` but found `a_class<'a>` + return e; //~ ERROR mismatched types: expected `a_class<'b> ` but found `a_class<'a> ` + //~^ ERROR cannot infer an appropriate lifetime } fn a_fn4<'a,'b>() { diff --git a/src/test/compile-fail/regions-escape-bound-fn-2.rs b/src/test/compile-fail/regions-escape-bound-fn-2.rs index 9cee55643f89..305aa6852849 100644 --- a/src/test/compile-fail/regions-escape-bound-fn-2.rs +++ b/src/test/compile-fail/regions-escape-bound-fn-2.rs @@ -15,6 +15,6 @@ fn with_int(f: &fn(x: &int)) { fn main() { let mut x = None; - //~^ ERROR reference is not valid outside of its lifetime + //~^ ERROR lifetime of variable does not enclose its declaration with_int(|y| x = Some(y)); } diff --git a/src/test/compile-fail/regions-escape-via-trait-or-not.rs b/src/test/compile-fail/regions-escape-via-trait-or-not.rs index aa431d6b81c6..5b6dc1b2f4fb 100644 --- a/src/test/compile-fail/regions-escape-via-trait-or-not.rs +++ b/src/test/compile-fail/regions-escape-via-trait-or-not.rs @@ -23,7 +23,7 @@ fn with(f: &fn(x: &int) -> R) -> int { } fn return_it() -> int { - with(|o| o) //~ ERROR reference is not valid outside of its lifetime + with(|o| o) //~ ERROR lifetime of function argument does not outlive the function call } fn main() { diff --git a/src/test/compile-fail/regions-infer-at-fn-not-param.rs b/src/test/compile-fail/regions-infer-at-fn-not-param.rs index c8813b73e6b3..488d1f3940d6 100644 --- a/src/test/compile-fail/regions-infer-at-fn-not-param.rs +++ b/src/test/compile-fail/regions-infer-at-fn-not-param.rs @@ -20,7 +20,10 @@ struct not_parameterized2 { g: @fn() } -fn take1(p: parameterized1) -> parameterized1 { p } //~ ERROR mismatched types +fn take1(p: parameterized1) -> parameterized1 { p } +//~^ ERROR mismatched types +//~^^ ERROR cannot infer an appropriate lifetime + fn take3(p: not_parameterized1) -> not_parameterized1 { p } fn take4(p: not_parameterized2) -> not_parameterized2 { p } diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs index 85cc6e6ce248..c33ca2dab2ee 100644 --- a/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs +++ b/src/test/compile-fail/regions-infer-covariance-due-to-arg.rs @@ -22,6 +22,7 @@ fn to_same_lifetime<'r>(bi: covariant<'r>) { fn to_shorter_lifetime<'r>(bi: covariant<'r>) { let bj: covariant<'blk> = bi; //~ ERROR mismatched types + //~^ ERROR cannot infer an appropriate lifetime } fn to_longer_lifetime<'r>(bi: covariant<'r>) -> covariant<'static> { diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index a0ecb08a0895..fa853b82d9eb 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -23,6 +23,11 @@ struct indirect2<'self> { } fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types +//~^ ERROR cannot infer an appropriate lifetime + fn take_indirect1(p: indirect1) -> indirect1 { p } + fn take_indirect2(p: indirect2) -> indirect2 { p } //~ ERROR mismatched types +//~^ ERROR cannot infer an appropriate lifetime + fn main() {} diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs index e8d66ab297b7..0b4aa44010bd 100644 --- a/src/test/compile-fail/regions-infer-paramd-indirect.rs +++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs @@ -30,6 +30,7 @@ impl<'self> set_f<'self> for c<'self> { fn set_f_bad(&self, b: @b) { self.f = b; //~ ERROR mismatched types: expected `@@&'self int` but found `@@&int` + //~^ ERROR cannot infer an appropriate lifetime } } diff --git a/src/test/compile-fail/regions-nested-fns.rs b/src/test/compile-fail/regions-nested-fns.rs index 74399967446e..244e9cc06a1a 100644 --- a/src/test/compile-fail/regions-nested-fns.rs +++ b/src/test/compile-fail/regions-nested-fns.rs @@ -22,6 +22,7 @@ fn nested<'x>(x: &'x int) { ignore::<&fn<'z>(&'z int) -> &'z int>(|z| { if false { return x; } //~ ERROR mismatched types + //~^ ERROR cannot infer an appropriate lifetime if false { return ay; } return z; }); diff --git a/src/test/compile-fail/regions-ret-borrowed-1.rs b/src/test/compile-fail/regions-ret-borrowed-1.rs index a572d90313b6..542711687190 100644 --- a/src/test/compile-fail/regions-ret-borrowed-1.rs +++ b/src/test/compile-fail/regions-ret-borrowed-1.rs @@ -18,6 +18,8 @@ fn with<'a, R>(f: &fn(x: &'a int) -> R) -> R { fn return_it<'a>() -> &'a int { with(|o| o) //~ ERROR mismatched types + //~^ ERROR lifetime of return value does not outlive the function call + //~^^ ERROR cannot infer an appropriate lifetime } fn main() { diff --git a/src/test/compile-fail/regions-ret-borrowed.rs b/src/test/compile-fail/regions-ret-borrowed.rs index ec9a908ba987..4d646aa364a4 100644 --- a/src/test/compile-fail/regions-ret-borrowed.rs +++ b/src/test/compile-fail/regions-ret-borrowed.rs @@ -21,6 +21,8 @@ fn with(f: &fn(x: &int) -> R) -> R { fn return_it() -> &int { with(|o| o) //~ ERROR mismatched types + //~^ ERROR lifetime of return value does not outlive the function call + //~^^ ERROR cannot infer an appropriate lifetime } fn main() { diff --git a/src/test/compile-fail/sync-cond-shouldnt-escape.rs b/src/test/compile-fail/sync-cond-shouldnt-escape.rs index b22d4d3b2e2e..2006027e7970 100644 --- a/src/test/compile-fail/sync-cond-shouldnt-escape.rs +++ b/src/test/compile-fail/sync-cond-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of variable does not enclose its declaration extern mod extra; use extra::sync; diff --git a/src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs b/src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs index 518e67800d76..4108201f9115 100644 --- a/src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs +++ b/src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of method receiver does not outlive the method call extern mod extra; use extra::sync; fn main() { diff --git a/src/test/compile-fail/sync-rwlock-write-mode-cond-shouldnt-escape.rs b/src/test/compile-fail/sync-rwlock-write-mode-cond-shouldnt-escape.rs index 09b83887bcfd..43b4d9aabb87 100644 --- a/src/test/compile-fail/sync-rwlock-write-mode-cond-shouldnt-escape.rs +++ b/src/test/compile-fail/sync-rwlock-write-mode-cond-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of variable does not enclose its declaration extern mod extra; use extra::sync; fn main() { diff --git a/src/test/compile-fail/sync-rwlock-write-mode-shouldnt-escape.rs b/src/test/compile-fail/sync-rwlock-write-mode-shouldnt-escape.rs index 679c4a72598e..15af7be52468 100644 --- a/src/test/compile-fail/sync-rwlock-write-mode-shouldnt-escape.rs +++ b/src/test/compile-fail/sync-rwlock-write-mode-shouldnt-escape.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: reference is not valid outside of its lifetime +// error-pattern: lifetime of variable does not enclose its declaration extern mod extra; use extra::sync; fn main() { From 42344af71381b7f45de3570e322eaaee59d83229 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 5 Jun 2013 21:04:07 -0400 Subject: [PATCH 327/336] Correct handling of if/match, and make explicit computation of common supertypes. This was breaking with the change to regions because of the (now incorrect) assumpton that our inference code makes, which is that if a <: b succeeds, there is no need to compute the LUB/GLB. --- src/librustc/middle/typeck/check/_match.rs | 38 ++++--- src/librustc/middle/typeck/check/mod.rs | 103 +++++++----------- src/librustc/middle/typeck/infer/combine.rs | 6 +- .../middle/typeck/infer/error_reporting.rs | 18 +-- src/librustc/middle/typeck/infer/glb.rs | 4 +- src/librustc/middle/typeck/infer/lub.rs | 4 +- src/librustc/middle/typeck/infer/mod.rs | 92 ++++++++++++---- .../middle/typeck/infer/region_inference.rs | 2 + src/librustc/middle/typeck/infer/sub.rs | 4 +- src/test/compile-fail/if-branch-types.rs | 7 +- src/test/compile-fail/lub-if.rs | 52 +++++++++ src/test/compile-fail/lub-match.rs | 55 ++++++++++ 12 files changed, 265 insertions(+), 120 deletions(-) create mode 100644 src/test/compile-fail/lub-if.rs create mode 100644 src/test/compile-fail/lub-match.rs diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 351d09b7ce5c..45867ae77e08 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -30,8 +30,8 @@ pub fn check_match(fcx: @mut FnCtxt, arms: &[ast::arm]) { let tcx = fcx.ccx.tcx; - let pattern_ty = fcx.infcx().next_ty_var(); - check_expr_has_type(fcx, discrim, pattern_ty); + let discrim_ty = fcx.infcx().next_ty_var(); + check_expr_has_type(fcx, discrim, discrim_ty); // Typecheck the patterns first, so that we get types for all the // bindings. @@ -41,13 +41,20 @@ pub fn check_match(fcx: @mut FnCtxt, map: pat_id_map(tcx.def_map, arm.pats[0]), }; - for arm.pats.iter().advance |p| { check_pat(&pcx, *p, pattern_ty);} + for arm.pats.iter().advance |p| { check_pat(&pcx, *p, discrim_ty);} } + // The result of the match is the common supertype of all the + // arms. Start out the value as bottom, since it's the, well, + // bottom the type lattice, and we'll be moving up the lattice as + // we process each arm. (Note that any match with 0 arms is matching + // on any empty type and is therefore unreachable; should the flow + // of execution reach it, we will fail, so bottom is an appropriate + // type in that case) + let mut result_ty = ty::mk_bot(); + // Now typecheck the blocks. - let mut result_ty = fcx.infcx().next_ty_var(); - let mut arm_non_bot = false; - let mut saw_err = false; + let mut saw_err = ty::type_is_error(discrim_ty); for arms.iter().advance |arm| { let mut guard_err = false; let mut guard_bot = false; @@ -74,18 +81,22 @@ pub fn check_match(fcx: @mut FnCtxt, else if guard_bot { fcx.write_bot(arm.body.node.id); } - else if !ty::type_is_bot(bty) { - arm_non_bot = true; // If the match *may* evaluate to a non-_|_ - // expr, the whole thing is non-_|_ - } - demand::suptype(fcx, arm.body.span, result_ty, bty); + + result_ty = + infer::common_supertype( + fcx.infcx(), + infer::MatchExpression(expr.span), + true, // result_ty is "expected" here + result_ty, + bty); } + if saw_err { result_ty = ty::mk_err(); - } - else if !arm_non_bot { + } else if ty::type_is_bot(discrim_ty) { result_ty = ty::mk_bot(); } + fcx.write_ty(expr.id, result_ty); } @@ -647,3 +658,4 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, #[deriving(Eq)] enum PointerKind { Managed, Send, Borrowed } + diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index b397181ddca6..98db885ba422 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -848,7 +848,7 @@ impl FnCtxt { pub fn mk_subty(&self, a_is_expected: bool, - origin: infer::SubtypeOrigin, + origin: infer::TypeOrigin, sub: ty::t, sup: ty::t) -> Result<(), ty::type_err> { @@ -886,7 +886,7 @@ impl FnCtxt { pub fn mk_eqty(&self, a_is_expected: bool, - origin: infer::SubtypeOrigin, + origin: infer::TypeOrigin, sub: ty::t, sup: ty::t) -> Result<(), ty::type_err> { @@ -1436,27 +1436,42 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // A generic function for checking the then and else in an if // or if-check fn check_then_else(fcx: @mut FnCtxt, - thn: &ast::blk, - elsopt: Option<@ast::expr>, + cond_expr: @ast::expr, + then_blk: &ast::blk, + opt_else_expr: Option<@ast::expr>, id: ast::node_id, - _sp: span) { - let if_t = - match elsopt { - Some(els) => { - let if_t = fcx.infcx().next_ty_var(); - check_block(fcx, thn); - let thn_t = fcx.node_ty(thn.node.id); - demand::suptype(fcx, thn.span, if_t, thn_t); - check_expr_has_type(fcx, els, if_t); - if_t - } - None => { - check_block_no_value(fcx, thn); - ty::mk_nil() - } - }; + sp: span, + expected: Option) { + check_expr_has_type(fcx, cond_expr, ty::mk_bool()); - fcx.write_ty(id, if_t); + let branches_ty = match opt_else_expr { + Some(else_expr) => { + check_block_with_expected(fcx, then_blk, expected); + let then_ty = fcx.node_ty(then_blk.node.id); + check_expr_with_opt_hint(fcx, else_expr, expected); + let else_ty = fcx.expr_ty(else_expr); + infer::common_supertype(fcx.infcx(), + infer::IfExpression(sp), + true, + then_ty, + else_ty) + } + None => { + check_block_no_value(fcx, then_blk); + ty::mk_nil() + } + }; + + let cond_ty = fcx.expr_ty(cond_expr); + let if_ty = if ty::type_is_error(cond_ty) { + ty::mk_err() + } else if ty::type_is_bot(cond_ty) { + ty::mk_bot() + } else { + branches_ty + }; + + fcx.write_ty(id, if_ty); } fn lookup_op_method(fcx: @mut FnCtxt, @@ -2501,25 +2516,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_nil(id); } } - ast::expr_if(cond, ref thn, elsopt) => { - check_expr_has_type(fcx, cond, ty::mk_bool()); - check_then_else(fcx, thn, elsopt, id, expr.span); - let cond_ty = fcx.expr_ty(cond); - let then_ty = fcx.node_ty(thn.node.id); - let else_is_bot = elsopt.map_default(false, |els| { - ty::type_is_bot(fcx.expr_ty(*els))}); - if ty::type_is_error(cond_ty) || ty::type_is_error(then_ty) { - fcx.write_error(id); - } - else if elsopt.map_default(false, |els| { - ty::type_is_error(fcx.expr_ty(*els)) }) { - fcx.write_error(id); - } - else if ty::type_is_bot(cond_ty) || - (ty::type_is_bot(then_ty) && else_is_bot) { - fcx.write_bot(id); - } - // Other cases were handled by check_then_else + ast::expr_if(cond, ref then_blk, opt_else_expr) => { + check_then_else(fcx, cond, then_blk, opt_else_expr, + id, expr.span, expected); } ast::expr_while(cond, ref body) => { check_expr_has_type(fcx, cond, ty::mk_bool()); @@ -2547,30 +2546,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } ast::expr_match(discrim, ref arms) => { _match::check_match(fcx, expr, discrim, *arms); - let discrim_ty = fcx.expr_ty(discrim); - let arm_tys = arms.map(|a| fcx.node_ty(a.body.node.id)); - if ty::type_is_error(discrim_ty) || - arm_tys.iter().any_(|t| ty::type_is_error(*t)) { - fcx.write_error(id); - } - // keep in mind that `all` returns true in the empty vec case, - // which is what we want - else if ty::type_is_bot(discrim_ty) || - arm_tys.iter().all(|t| ty::type_is_bot(*t)) { - fcx.write_bot(id); - } - else { - // Find the first non-_|_ arm. - // We know there's at least one because we already checked - // for n=0 as well as all arms being _|_ in the previous - // `if`. - for arm_tys.iter().advance |arm_ty| { - if !ty::type_is_bot(*arm_ty) { - fcx.write_ty(id, *arm_ty); - break; - } - } - } } ast::expr_fn_block(ref decl, ref body) => { check_expr_fn(fcx, expr, None, diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 8af454774b82..f03f01732291 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::{SubtypeOrigin, SubtypeTrace}; +use middle::typeck::infer::{TypeOrigin, TypeTrace}; use util::common::indent; use std::result::{iter_vec2, map_vec2}; @@ -80,7 +80,7 @@ pub trait Combine { fn infcx(&self) -> @mut InferCtxt; fn tag(&self) -> ~str; fn a_is_expected(&self) -> bool; - fn trace(&self) -> SubtypeTrace; + fn trace(&self) -> TypeTrace; fn sub(&self) -> Sub; fn lub(&self) -> Lub; @@ -122,7 +122,7 @@ pub trait Combine { pub struct CombineFields { infcx: @mut InferCtxt, a_is_expected: bool, - trace: SubtypeTrace, + trace: TypeTrace, } pub fn expected_found( diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 079a01beaa14..7217f2979474 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -22,7 +22,7 @@ rise to a patricular error. The basis of the system are the "origin" types. An "origin" is the reason that a constraint or inference variable arose. There are different "origin" enums for different kinds of constraints/variables -(e.g., `SubtypeOrigin`, `RegionVariableOrigin`). An origin always has +(e.g., `TypeOrigin`, `RegionVariableOrigin`). An origin always has a span, but also more information so that we can generate a meaningful error message. @@ -40,7 +40,7 @@ store and later report what gave rise to the conflicting constraints. # Subtype Trace Determing whether `T1 <: T2` often involves a number of subtypes and -subconstraints along the way. A "SubtypeTrace" is an extended version +subconstraints along the way. A "TypeTrace" is an extended version of an origin that traces the types and other values that were being compared. It is not necessarily comprehensive (in fact, at the time of this writing it only tracks the root values being compared) but I'd @@ -64,8 +64,8 @@ use middle::ty; use middle::ty::Region; use middle::typeck::infer; use middle::typeck::infer::InferCtxt; -use middle::typeck::infer::SubtypeTrace; -use middle::typeck::infer::SubtypeOrigin; +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; @@ -108,8 +108,8 @@ impl InferCtxt { } } - fn report_and_explain_type_error(@mut self, - trace: SubtypeTrace, + pub fn report_and_explain_type_error(@mut self, + trace: TypeTrace, terr: &ty::type_err) { let tcx = self.tcx; @@ -125,7 +125,9 @@ impl InferCtxt { infer::MethodCompatCheck(_) => "method not compatible with trait", infer::ExprAssignable(_) => "mismatched types", infer::RelateTraitRefs(_) => "mismatched traits", - infer::RelateSelfType(_) => "mismatched types" + infer::RelateSelfType(_) => "mismatched types", + infer::MatchExpression(_) => "match arms have incompatible types", + infer::IfExpression(_) => "if and else have incompatible types", }; self.tcx.sess.span_err( @@ -179,7 +181,7 @@ impl InferCtxt { sup: Region) { match origin { infer::Subtype(trace) => { - let terr = ty::terr_regions_does_not_outlive(sub, sup); + let terr = ty::terr_regions_does_not_outlive(sup, sub); self.report_and_explain_type_error(trace, &terr); } infer::Reborrow(span) => { diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 46ccfd24eb56..fefbf2336c29 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -18,7 +18,7 @@ use middle::typeck::infer::lub::Lub; use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{cres, InferCtxt}; -use middle::typeck::infer::{SubtypeTrace, Subtype}; +use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::infer::fold_regions_in_sig; use middle::typeck::isr_alist; use syntax::ast; @@ -38,7 +38,7 @@ impl Combine for Glb { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"glb" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn trace(&self) -> SubtypeTrace { self.trace } + fn trace(&self) -> TypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 5d896bdadba7..efb1dc200b52 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -19,7 +19,7 @@ use middle::typeck::infer::sub::Sub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::{cres, InferCtxt}; use middle::typeck::infer::fold_regions_in_sig; -use middle::typeck::infer::{SubtypeTrace, Subtype}; +use middle::typeck::infer::{TypeTrace, Subtype}; use middle::typeck::isr_alist; use util::common::indent; use util::ppaux::mt_to_str; @@ -45,7 +45,7 @@ impl Combine for Lub { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"lub" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn trace(&self) -> SubtypeTrace { self.trace } + fn trace(&self) -> TypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 29f24f2ce9a7..f8563b4eb3d2 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -260,6 +260,7 @@ use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys}; use middle::typeck::infer::region_inference::{RegionVarBindings}; use middle::typeck::infer::resolve::{resolver}; use middle::typeck::infer::sub::Sub; +use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{ValsAndBindings, Root}; use middle::typeck::isr_alist; @@ -324,7 +325,7 @@ pub struct InferCtxt { /// Why did we require that the two types be related? /// /// See `error_reporting.rs` for more details -pub enum SubtypeOrigin { +pub enum TypeOrigin { // Not yet categorized in a better way Misc(span), @@ -339,6 +340,12 @@ pub enum SubtypeOrigin { // Relating trait refs when resolving vtables RelateSelfType(span), + + // Computing common supertype in a match expression + MatchExpression(span), + + // Computing common supertype in an if expression + IfExpression(span), } /// See `error_reporting.rs` for more details @@ -351,8 +358,8 @@ pub enum ValuePairs { /// encounter an error or subtyping constraint. /// /// See `error_reporting.rs` for more details. -pub struct SubtypeTrace { - origin: SubtypeOrigin, +pub struct TypeTrace { + origin: TypeOrigin, values: ValuePairs, } @@ -361,7 +368,7 @@ pub struct SubtypeTrace { /// See `error_reporting.rs` for more details pub enum SubregionOrigin { // Arose from a subtyping relation - Subtype(SubtypeTrace), + Subtype(TypeTrace), // Invocation of closure must be within its lifetime InvokeClosure(span), @@ -425,7 +432,7 @@ pub enum RegionVariableOrigin { Autoref(span), // Regions created as part of an automatic coercion - Coercion(SubtypeTrace), + Coercion(TypeTrace), // Region variables created for bound regions // in a function or method that is called @@ -487,16 +494,47 @@ pub fn new_infer_ctxt(tcx: ty::ctxt) -> @mut InferCtxt { } } +pub fn common_supertype(cx: @mut InferCtxt, + origin: TypeOrigin, + a_is_expected: bool, + a: ty::t, + b: ty::t) + -> ty::t { + /*! + * Computes the least upper-bound of `a` and `b`. If this is + * not possible, reports an error and returns ty::err. + */ + + debug!("common_supertype(%s, %s)", a.inf_str(cx), b.inf_str(cx)); + + let trace = TypeTrace { + origin: origin, + values: Types(expected_found(a_is_expected, a, b)) + }; + + let result = do cx.commit { + cx.lub(a_is_expected, trace).tys(a, b) + }; + + match result { + Ok(t) => t, + Err(ref err) => { + cx.report_and_explain_type_error(trace, err); + ty::mk_err() + } + } +} + pub fn mk_subty(cx: @mut InferCtxt, a_is_expected: bool, - origin: SubtypeOrigin, + origin: TypeOrigin, a: ty::t, b: ty::t) -> ures { debug!("mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: origin, values: Types(expected_found(a_is_expected, a, b)) }; @@ -509,7 +547,7 @@ pub fn can_mk_subty(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { debug!("can_mk_subty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.probe { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: Misc(codemap::dummy_sp()), values: Types(expected_found(true, a, b)) }; @@ -531,14 +569,14 @@ pub fn mk_subr(cx: @mut InferCtxt, pub fn mk_eqty(cx: @mut InferCtxt, a_is_expected: bool, - origin: SubtypeOrigin, + origin: TypeOrigin, a: ty::t, b: ty::t) -> ures { debug!("mk_eqty(%s <: %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: origin, values: Types(expected_found(a_is_expected, a, b)) }; @@ -550,7 +588,7 @@ pub fn mk_eqty(cx: @mut InferCtxt, pub fn mk_sub_trait_refs(cx: @mut InferCtxt, a_is_expected: bool, - origin: SubtypeOrigin, + origin: TypeOrigin, a: @ty::TraitRef, b: @ty::TraitRef) -> ures @@ -559,7 +597,7 @@ pub fn mk_sub_trait_refs(cx: @mut InferCtxt, a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: origin, values: TraitRefs(expected_found(a_is_expected, a, b)) }; @@ -581,14 +619,14 @@ fn expected_found(a_is_expected: bool, pub fn mk_coercety(cx: @mut InferCtxt, a_is_expected: bool, - origin: SubtypeOrigin, + origin: TypeOrigin, a: ty::t, b: ty::t) -> CoerceResult { debug!("mk_coercety(%s -> %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.commit { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: origin, values: Types(expected_found(a_is_expected, a, b)) }; @@ -601,7 +639,7 @@ pub fn can_mk_coercety(cx: @mut InferCtxt, a: ty::t, b: ty::t) -> ures { debug!("can_mk_coercety(%s -> %s)", a.inf_str(cx), b.inf_str(cx)); do indent { do cx.probe { - let trace = SubtypeTrace { + let trace = TypeTrace { origin: Misc(codemap::dummy_sp()), values: Types(expected_found(true, a, b)) }; @@ -690,17 +728,21 @@ struct Snapshot { impl InferCtxt { pub fn combine_fields(@mut self, a_is_expected: bool, - trace: SubtypeTrace) + trace: TypeTrace) -> CombineFields { CombineFields {infcx: self, a_is_expected: a_is_expected, trace: trace} } - pub fn sub(@mut self, a_is_expected: bool, trace: SubtypeTrace) -> Sub { + pub fn sub(@mut self, a_is_expected: bool, trace: TypeTrace) -> Sub { Sub(self.combine_fields(a_is_expected, trace)) } + pub fn lub(@mut self, a_is_expected: bool, trace: TypeTrace) -> Lub { + Lub(self.combine_fields(a_is_expected, trace)) + } + pub fn in_snapshot(&self) -> bool { self.region_vars.in_snapshot() } @@ -946,7 +988,7 @@ impl InferCtxt { } pub fn replace_bound_regions_with_fresh_regions(&mut self, - trace: SubtypeTrace, + trace: TypeTrace, fsig: &ty::FnSig) -> (ty::FnSig, isr_alist) { let(isr, _, fn_sig) = @@ -972,19 +1014,19 @@ pub fn fold_regions_in_sig( } } -impl SubtypeTrace { +impl TypeTrace { pub fn span(&self) -> span { self.origin.span() } } -impl Repr for SubtypeTrace { +impl Repr for TypeTrace { fn repr(&self, tcx: ty::ctxt) -> ~str { - fmt!("SubtypeTrace(%s)", self.origin.repr(tcx)) + fmt!("TypeTrace(%s)", self.origin.repr(tcx)) } } -impl SubtypeOrigin { +impl TypeOrigin { pub fn span(&self) -> span { match *self { MethodCompatCheck(span) => span, @@ -992,11 +1034,13 @@ impl SubtypeOrigin { Misc(span) => span, RelateTraitRefs(span) => span, RelateSelfType(span) => span, + MatchExpression(span) => span, + IfExpression(span) => span, } } } -impl Repr for SubtypeOrigin { +impl Repr for TypeOrigin { fn repr(&self, tcx: ty::ctxt) -> ~str { match *self { MethodCompatCheck(a) => fmt!("MethodCompatCheck(%s)", a.repr(tcx)), @@ -1004,6 +1048,8 @@ impl Repr for SubtypeOrigin { Misc(a) => fmt!("Misc(%s)", a.repr(tcx)), RelateTraitRefs(a) => fmt!("RelateTraitRefs(%s)", a.repr(tcx)), RelateSelfType(a) => fmt!("RelateSelfType(%s)", a.repr(tcx)), + MatchExpression(a) => fmt!("MatchExpression(%s)", a.repr(tcx)), + IfExpression(a) => fmt!("IfExpression(%s)", a.repr(tcx)), } } } diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 82fbb6b8ce7e..c674cbc0f63c 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1528,6 +1528,8 @@ impl RegionVarBindings { loop; } + debug!("ConcreteFailure: !(sub <= sup): sub=%?, sup=%?", + sub, sup); errors.push(ConcreteFailure(origin, sub, sup)); } } diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index ea66f8601af4..72178500b54e 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -20,7 +20,7 @@ use middle::typeck::infer::InferCtxt; use middle::typeck::infer::lattice::CombineFieldsLatticeMethods; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; -use middle::typeck::infer::{SubtypeTrace, Subtype}; +use middle::typeck::infer::{TypeTrace, Subtype}; use util::common::{indent, indenter}; use util::ppaux::bound_region_to_str; @@ -37,7 +37,7 @@ impl Combine for Sub { fn infcx(&self) -> @mut InferCtxt { self.infcx } fn tag(&self) -> ~str { ~"sub" } fn a_is_expected(&self) -> bool { self.a_is_expected } - fn trace(&self) -> SubtypeTrace { self.trace } + fn trace(&self) -> TypeTrace { self.trace } fn sub(&self) -> Sub { Sub(**self) } fn lub(&self) -> Lub { Lub(**self) } diff --git a/src/test/compile-fail/if-branch-types.rs b/src/test/compile-fail/if-branch-types.rs index 74baceb39d32..1c6dd0ef9f65 100644 --- a/src/test/compile-fail/if-branch-types.rs +++ b/src/test/compile-fail/if-branch-types.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:mismatched types - -fn main() { let x = if true { 10i } else { 10u }; } +fn main() { + let x = if true { 10i } else { 10u }; + //~^ ERROR if and else have incompatible types: expected `int` but found `uint` +} diff --git a/src/test/compile-fail/lub-if.rs b/src/test/compile-fail/lub-if.rs new file mode 100644 index 000000000000..358c61921470 --- /dev/null +++ b/src/test/compile-fail/lub-if.rs @@ -0,0 +1,52 @@ +// 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. + +// Test that we correctly consider the type of `match` to be the LUB +// of the various arms, particularly in the case where regions are +// involved. + +pub fn opt_str0<'a>(maybestr: &'a Option<~str>) -> &'a str { + if maybestr.is_none() { + "(none)" + } else { + let s: &'a str = *maybestr.get_ref(); + s + } +} + +pub fn opt_str1<'a>(maybestr: &'a Option<~str>) -> &'a str { + if maybestr.is_some() { + let s: &'a str = *maybestr.get_ref(); + s + } else { + "(none)" + } +} + +pub fn opt_str2<'a>(maybestr: &'a Option<~str>) -> &'static str { + if maybestr.is_none() { //~ ERROR mismatched types + "(none)" + } else { + let s: &'a str = *maybestr.get_ref(); + s + } +} + +pub fn opt_str3<'a>(maybestr: &'a Option<~str>) -> &'static str { + if maybestr.is_some() { //~ ERROR mismatched types + let s: &'a str = *maybestr.get_ref(); + s + } else { + "(none)" + } +} + + +fn main() {} \ No newline at end of file diff --git a/src/test/compile-fail/lub-match.rs b/src/test/compile-fail/lub-match.rs new file mode 100644 index 000000000000..2a61b72997d1 --- /dev/null +++ b/src/test/compile-fail/lub-match.rs @@ -0,0 +1,55 @@ +// 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. + +// Test that we correctly consider the type of `match` to be the LUB +// of the various arms, particularly in the case where regions are +// involved. + +pub fn opt_str0<'a>(maybestr: &'a Option<~str>) -> &'a str { + match *maybestr { + Some(ref s) => { + let s: &'a str = *s; + s + } + None => "(none)", + } +} + +pub fn opt_str1<'a>(maybestr: &'a Option<~str>) -> &'a str { + match *maybestr { + None => "(none)", + Some(ref s) => { + let s: &'a str = *s; + s + } + } +} + +pub fn opt_str2<'a>(maybestr: &'a Option<~str>) -> &'static str { + match *maybestr { //~ ERROR mismatched types + None => "(none)", + Some(ref s) => { + let s: &'a str = *s; + s + } + } +} + +pub fn opt_str3<'a>(maybestr: &'a Option<~str>) -> &'static str { + match *maybestr { //~ ERROR mismatched types + Some(ref s) => { + let s: &'a str = *s; + s + } + None => "(none)", + } +} + +fn main() {} \ No newline at end of file From 79ea26630d88ba71936f773616f28d7f47a08261 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 5 Jun 2013 21:17:07 -0400 Subject: [PATCH 328/336] move docs into doc.rs --- src/librustc/middle/typeck/infer/doc.rs | 233 +++++++++++++++++++++++ src/librustc/middle/typeck/infer/mod.rs | 235 +----------------------- 2 files changed, 235 insertions(+), 233 deletions(-) create mode 100644 src/librustc/middle/typeck/infer/doc.rs diff --git a/src/librustc/middle/typeck/infer/doc.rs b/src/librustc/middle/typeck/infer/doc.rs new file mode 100644 index 000000000000..16d0f2cc18b0 --- /dev/null +++ b/src/librustc/middle/typeck/infer/doc.rs @@ -0,0 +1,233 @@ +/*! + +# Type inference engine + +This is loosely based on standard HM-type inference, but with an +extension to try and accommodate subtyping. There is nothing +principled about this extension; it's sound---I hope!---but it's a +heuristic, ultimately, and does not guarantee that it finds a valid +typing even if one exists (in fact, there are known scenarios where it +fails, some of which may eventually become problematic). + +## Key idea + +The main change is that each type variable T is associated with a +lower-bound L and an upper-bound U. L and U begin as bottom and top, +respectively, but gradually narrow in response to new constraints +being introduced. When a variable is finally resolved to a concrete +type, it can (theoretically) select any type that is a supertype of L +and a subtype of U. + +There are several critical invariants which we maintain: + +- the upper-bound of a variable only becomes lower and the lower-bound + only becomes higher over time; +- the lower-bound L is always a subtype of the upper bound U; +- the lower-bound L and upper-bound U never refer to other type variables, + but only to types (though those types may contain type variables). + +> An aside: if the terms upper- and lower-bound confuse you, think of +> "supertype" and "subtype". The upper-bound is a "supertype" +> (super=upper in Latin, or something like that anyway) and the lower-bound +> is a "subtype" (sub=lower in Latin). I find it helps to visualize +> a simple class hierarchy, like Java minus interfaces and +> primitive types. The class Object is at the root (top) and other +> types lie in between. The bottom type is then the Null type. +> So the tree looks like: +> +> Object +> / \ +> String Other +> \ / +> (null) +> +> So the upper bound type is the "supertype" and the lower bound is the +> "subtype" (also, super and sub mean upper and lower in Latin, or something +> like that anyway). + +## Satisfying constraints + +At a primitive level, there is only one form of constraint that the +inference understands: a subtype relation. So the outside world can +say "make type A a subtype of type B". If there are variables +involved, the inferencer will adjust their upper- and lower-bounds as +needed to ensure that this relation is satisfied. (We also allow "make +type A equal to type B", but this is translated into "A <: B" and "B +<: A") + +As stated above, we always maintain the invariant that type bounds +never refer to other variables. This keeps the inference relatively +simple, avoiding the scenario of having a kind of graph where we have +to pump constraints along and reach a fixed point, but it does impose +some heuristics in the case where the user is relating two type +variables A <: B. + +Combining two variables such that variable A will forever be a subtype +of variable B is the trickiest part of the algorithm because there is +often no right choice---that is, the right choice will depend on +future constraints which we do not yet know. The problem comes about +because both A and B have bounds that can be adjusted in the future. +Let's look at some of the cases that can come up. + +Imagine, to start, the best case, where both A and B have an upper and +lower bound (that is, the bounds are not top nor bot respectively). In +that case, if we're lucky, A.ub <: B.lb, and so we know that whatever +A and B should become, they will forever have the desired subtyping +relation. We can just leave things as they are. + +### Option 1: Unify + +However, suppose that A.ub is *not* a subtype of B.lb. In +that case, we must make a decision. One option is to unify A +and B so that they are one variable whose bounds are: + + UB = GLB(A.ub, B.ub) + LB = LUB(A.lb, B.lb) + +(Note that we will have to verify that LB <: UB; if it does not, the +types are not intersecting and there is an error) In that case, A <: B +holds trivially because A==B. However, we have now lost some +flexibility, because perhaps the user intended for A and B to end up +as different types and not the same type. + +Pictorally, what this does is to take two distinct variables with +(hopefully not completely) distinct type ranges and produce one with +the intersection. + + B.ub B.ub + /\ / + A.ub / \ A.ub / + / \ / \ \ / + / X \ UB + / / \ \ / \ + / / / \ / / + \ \ / / \ / + \ X / LB + \ / \ / / \ + \ / \ / / \ + A.lb B.lb A.lb B.lb + + +### Option 2: Relate UB/LB + +Another option is to keep A and B as distinct variables but set their +bounds in such a way that, whatever happens, we know that A <: B will hold. +This can be achieved by ensuring that A.ub <: B.lb. In practice there +are two ways to do that, depicted pictorally here: + + Before Option #1 Option #2 + + B.ub B.ub B.ub + /\ / \ / \ + A.ub / \ A.ub /(B')\ A.ub /(B')\ + / \ / \ \ / / \ / / + / X \ __UB____/ UB / + / / \ \ / | | / + / / / \ / | | / + \ \ / / /(A')| | / + \ X / / LB ______LB/ + \ / \ / / / \ / (A')/ \ + \ / \ / \ / \ \ / \ + A.lb B.lb A.lb B.lb A.lb B.lb + +In these diagrams, UB and LB are defined as before. As you can see, +the new ranges `A'` and `B'` are quite different from the range that +would be produced by unifying the variables. + +### What we do now + +Our current technique is to *try* (transactionally) to relate the +existing bounds of A and B, if there are any (i.e., if `UB(A) != top +&& LB(B) != bot`). If that succeeds, we're done. If it fails, then +we merge A and B into same variable. + +This is not clearly the correct course. For example, if `UB(A) != +top` but `LB(B) == bot`, we could conceivably set `LB(B)` to `UB(A)` +and leave the variables unmerged. This is sometimes the better +course, it depends on the program. + +The main case which fails today that I would like to support is: + + fn foo(x: T, y: T) { ... } + + fn bar() { + let x: @mut int = @mut 3; + let y: @int = @3; + foo(x, y); + } + +In principle, the inferencer ought to find that the parameter `T` to +`foo(x, y)` is `@const int`. Today, however, it does not; this is +because the type variable `T` is merged with the type variable for +`X`, and thus inherits its UB/LB of `@mut int`. This leaves no +flexibility for `T` to later adjust to accommodate `@int`. + +### What to do when not all bounds are present + +In the prior discussion we assumed that A.ub was not top and B.lb was +not bot. Unfortunately this is rarely the case. Often type variables +have "lopsided" bounds. For example, if a variable in the program has +been initialized but has not been used, then its corresponding type +variable will have a lower bound but no upper bound. When that +variable is then used, we would like to know its upper bound---but we +don't have one! In this case we'll do different things depending on +how the variable is being used. + +## Transactional support + +Whenever we adjust merge variables or adjust their bounds, we always +keep a record of the old value. This allows the changes to be undone. + +## Regions + +I've only talked about type variables here, but region variables +follow the same principle. They have upper- and lower-bounds. A +region A is a subregion of a region B if A being valid implies that B +is valid. This basically corresponds to the block nesting structure: +the regions for outer block scopes are superregions of those for inner +block scopes. + +## Integral and floating-point type variables + +There is a third variety of type variable that we use only for +inferring the types of unsuffixed integer literals. Integral type +variables differ from general-purpose type variables in that there's +no subtyping relationship among the various integral types, so instead +of associating each variable with an upper and lower bound, we just +use simple unification. Each integer variable is associated with at +most one integer type. Floating point types are handled similarly to +integral types. + +## GLB/LUB + +Computing the greatest-lower-bound and least-upper-bound of two +types/regions is generally straightforward except when type variables +are involved. In that case, we follow a similar "try to use the bounds +when possible but otherwise merge the variables" strategy. In other +words, `GLB(A, B)` where `A` and `B` are variables will often result +in `A` and `B` being merged and the result being `A`. + +## Type coercion + +We have a notion of assignability which differs somewhat from +subtyping; in particular it may cause region borrowing to occur. See +the big comment later in this file on Type Coercion for specifics. + +### In conclusion + +I showed you three ways to relate `A` and `B`. There are also more, +of course, though I'm not sure if there are any more sensible options. +The main point is that there are various options, each of which +produce a distinct range of types for `A` and `B`. Depending on what +the correct values for A and B are, one of these options will be the +right choice: but of course we don't know the right values for A and B +yet, that's what we're trying to find! In our code, we opt to unify +(Option #1). + +# Implementation details + +We make use of a trait-like impementation strategy to consolidate +duplicated code between subtypes, GLB, and LUB computations. See the +section on "Type Combining" below for details. + +*/ \ No newline at end of file diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index f8563b4eb3d2..caeb65765c62 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -8,239 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -# Type inference engine - -This is loosely based on standard HM-type inference, but with an -extension to try and accommodate subtyping. There is nothing -principled about this extension; it's sound---I hope!---but it's a -heuristic, ultimately, and does not guarantee that it finds a valid -typing even if one exists (in fact, there are known scenarios where it -fails, some of which may eventually become problematic). - -## Key idea - -The main change is that each type variable T is associated with a -lower-bound L and an upper-bound U. L and U begin as bottom and top, -respectively, but gradually narrow in response to new constraints -being introduced. When a variable is finally resolved to a concrete -type, it can (theoretically) select any type that is a supertype of L -and a subtype of U. - -There are several critical invariants which we maintain: - -- the upper-bound of a variable only becomes lower and the lower-bound - only becomes higher over time; -- the lower-bound L is always a subtype of the upper bound U; -- the lower-bound L and upper-bound U never refer to other type variables, - but only to types (though those types may contain type variables). - -> An aside: if the terms upper- and lower-bound confuse you, think of -> "supertype" and "subtype". The upper-bound is a "supertype" -> (super=upper in Latin, or something like that anyway) and the lower-bound -> is a "subtype" (sub=lower in Latin). I find it helps to visualize -> a simple class hierarchy, like Java minus interfaces and -> primitive types. The class Object is at the root (top) and other -> types lie in between. The bottom type is then the Null type. -> So the tree looks like: -> -> Object -> / \ -> String Other -> \ / -> (null) -> -> So the upper bound type is the "supertype" and the lower bound is the -> "subtype" (also, super and sub mean upper and lower in Latin, or something -> like that anyway). - -## Satisfying constraints - -At a primitive level, there is only one form of constraint that the -inference understands: a subtype relation. So the outside world can -say "make type A a subtype of type B". If there are variables -involved, the inferencer will adjust their upper- and lower-bounds as -needed to ensure that this relation is satisfied. (We also allow "make -type A equal to type B", but this is translated into "A <: B" and "B -<: A") - -As stated above, we always maintain the invariant that type bounds -never refer to other variables. This keeps the inference relatively -simple, avoiding the scenario of having a kind of graph where we have -to pump constraints along and reach a fixed point, but it does impose -some heuristics in the case where the user is relating two type -variables A <: B. - -Combining two variables such that variable A will forever be a subtype -of variable B is the trickiest part of the algorithm because there is -often no right choice---that is, the right choice will depend on -future constraints which we do not yet know. The problem comes about -because both A and B have bounds that can be adjusted in the future. -Let's look at some of the cases that can come up. - -Imagine, to start, the best case, where both A and B have an upper and -lower bound (that is, the bounds are not top nor bot respectively). In -that case, if we're lucky, A.ub <: B.lb, and so we know that whatever -A and B should become, they will forever have the desired subtyping -relation. We can just leave things as they are. - -### Option 1: Unify - -However, suppose that A.ub is *not* a subtype of B.lb. In -that case, we must make a decision. One option is to unify A -and B so that they are one variable whose bounds are: - - UB = GLB(A.ub, B.ub) - LB = LUB(A.lb, B.lb) - -(Note that we will have to verify that LB <: UB; if it does not, the -types are not intersecting and there is an error) In that case, A <: B -holds trivially because A==B. However, we have now lost some -flexibility, because perhaps the user intended for A and B to end up -as different types and not the same type. - -Pictorally, what this does is to take two distinct variables with -(hopefully not completely) distinct type ranges and produce one with -the intersection. - - B.ub B.ub - /\ / - A.ub / \ A.ub / - / \ / \ \ / - / X \ UB - / / \ \ / \ - / / / \ / / - \ \ / / \ / - \ X / LB - \ / \ / / \ - \ / \ / / \ - A.lb B.lb A.lb B.lb - - -### Option 2: Relate UB/LB - -Another option is to keep A and B as distinct variables but set their -bounds in such a way that, whatever happens, we know that A <: B will hold. -This can be achieved by ensuring that A.ub <: B.lb. In practice there -are two ways to do that, depicted pictorally here: - - Before Option #1 Option #2 - - B.ub B.ub B.ub - /\ / \ / \ - A.ub / \ A.ub /(B')\ A.ub /(B')\ - / \ / \ \ / / \ / / - / X \ __UB____/ UB / - / / \ \ / | | / - / / / \ / | | / - \ \ / / /(A')| | / - \ X / / LB ______LB/ - \ / \ / / / \ / (A')/ \ - \ / \ / \ / \ \ / \ - A.lb B.lb A.lb B.lb A.lb B.lb - -In these diagrams, UB and LB are defined as before. As you can see, -the new ranges `A'` and `B'` are quite different from the range that -would be produced by unifying the variables. - -### What we do now - -Our current technique is to *try* (transactionally) to relate the -existing bounds of A and B, if there are any (i.e., if `UB(A) != top -&& LB(B) != bot`). If that succeeds, we're done. If it fails, then -we merge A and B into same variable. - -This is not clearly the correct course. For example, if `UB(A) != -top` but `LB(B) == bot`, we could conceivably set `LB(B)` to `UB(A)` -and leave the variables unmerged. This is sometimes the better -course, it depends on the program. - -The main case which fails today that I would like to support is: - - fn foo(x: T, y: T) { ... } - - fn bar() { - let x: @mut int = @mut 3; - let y: @int = @3; - foo(x, y); - } - -In principle, the inferencer ought to find that the parameter `T` to -`foo(x, y)` is `@const int`. Today, however, it does not; this is -because the type variable `T` is merged with the type variable for -`X`, and thus inherits its UB/LB of `@mut int`. This leaves no -flexibility for `T` to later adjust to accommodate `@int`. - -### What to do when not all bounds are present - -In the prior discussion we assumed that A.ub was not top and B.lb was -not bot. Unfortunately this is rarely the case. Often type variables -have "lopsided" bounds. For example, if a variable in the program has -been initialized but has not been used, then its corresponding type -variable will have a lower bound but no upper bound. When that -variable is then used, we would like to know its upper bound---but we -don't have one! In this case we'll do different things depending on -how the variable is being used. - -## Transactional support - -Whenever we adjust merge variables or adjust their bounds, we always -keep a record of the old value. This allows the changes to be undone. - -## Regions - -I've only talked about type variables here, but region variables -follow the same principle. They have upper- and lower-bounds. A -region A is a subregion of a region B if A being valid implies that B -is valid. This basically corresponds to the block nesting structure: -the regions for outer block scopes are superregions of those for inner -block scopes. - -## Integral and floating-point type variables - -There is a third variety of type variable that we use only for -inferring the types of unsuffixed integer literals. Integral type -variables differ from general-purpose type variables in that there's -no subtyping relationship among the various integral types, so instead -of associating each variable with an upper and lower bound, we just -use simple unification. Each integer variable is associated with at -most one integer type. Floating point types are handled similarly to -integral types. - -## GLB/LUB - -Computing the greatest-lower-bound and least-upper-bound of two -types/regions is generally straightforward except when type variables -are involved. In that case, we follow a similar "try to use the bounds -when possible but otherwise merge the variables" strategy. In other -words, `GLB(A, B)` where `A` and `B` are variables will often result -in `A` and `B` being merged and the result being `A`. - -## Type coercion - -We have a notion of assignability which differs somewhat from -subtyping; in particular it may cause region borrowing to occur. See -the big comment later in this file on Type Coercion for specifics. - -### In conclusion - -I showed you three ways to relate `A` and `B`. There are also more, -of course, though I'm not sure if there are any more sensible options. -The main point is that there are various options, each of which -produce a distinct range of types for `A` and `B`. Depending on what -the correct values for A and B are, one of these options will be the -right choice: but of course we don't know the right values for A and B -yet, that's what we're trying to find! In our code, we opt to unify -(Option #1). - -# Implementation details - -We make use of a trait-like impementation strategy to consolidate -duplicated code between subtypes, GLB, and LUB computations. See the -section on "Type Combining" below for details. - -*/ +/*! See doc.rs for documentation */ pub use middle::ty::IntVarValue; @@ -277,6 +45,7 @@ use syntax::ast; use syntax::codemap; use syntax::codemap::span; +pub mod doc; pub mod macros; pub mod combine; pub mod glb; From 9d48a7d55015da4820ea9dada682d727cacb074c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 6 Jun 2013 11:57:37 -0400 Subject: [PATCH 329/336] convert region_inference into a module, so I can attach docs --- src/librustc/middle/region.rs | 3 +++ src/librustc/middle/typeck/infer/mod.rs | 1 + .../infer/{region_inference.rs => region_inference/mod.rs} | 0 3 files changed, 4 insertions(+) rename src/librustc/middle/typeck/infer/{region_inference.rs => region_inference/mod.rs} (100%) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index e4e554b65bf3..f65d3ad464c4 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -15,6 +15,9 @@ pass builds up the `scope_map`, which describes the parent links in the region hierarchy. The second pass infers which types must be region parameterized. +Most of the documentation on regions can be found in +`middle/typeck/infer/region_inference.rs` + */ diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index caeb65765c62..bddd0276c6ab 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -51,6 +51,7 @@ pub mod combine; pub mod glb; pub mod lattice; pub mod lub; +#[path = "region_inference/mod.rs"] pub mod region_inference; pub mod resolve; pub mod sub; diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs similarity index 100% rename from src/librustc/middle/typeck/infer/region_inference.rs rename to src/librustc/middle/typeck/infer/region_inference/mod.rs From d7522fec1599d99ff7cff95c53850fd72e74979f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 6 Jun 2013 11:58:34 -0400 Subject: [PATCH 330/336] Move existing docs into doc.rs --- .../typeck/infer/region_inference/doc.rs | 537 ++++++++++++++++++ .../typeck/infer/region_inference/mod.rs | 532 +---------------- 2 files changed, 541 insertions(+), 528 deletions(-) create mode 100644 src/librustc/middle/typeck/infer/region_inference/doc.rs diff --git a/src/librustc/middle/typeck/infer/region_inference/doc.rs b/src/librustc/middle/typeck/infer/region_inference/doc.rs new file mode 100644 index 000000000000..0a288d40fa90 --- /dev/null +++ b/src/librustc/middle/typeck/infer/region_inference/doc.rs @@ -0,0 +1,537 @@ +// 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. + +/*! + +Region inference module. + +# Introduction + +Region inference uses a somewhat more involved algorithm than type +inference. It is not the most efficient thing ever written though it +seems to work well enough in practice (famous last words). The reason +that we use a different algorithm is because, unlike with types, it is +impractical to hand-annotate with regions (in some cases, there aren't +even the requisite syntactic forms). So we have to get it right, and +it's worth spending more time on a more involved analysis. Moreover, +regions are a simpler case than types: they don't have aggregate +structure, for example. + +Unlike normal type inference, which is similar in spirit to H-M and thus +works progressively, the region type inference works by accumulating +constraints over the course of a function. Finally, at the end of +processing a function, we process and solve the constraints all at +once. + +The constraints are always of one of three possible forms: + +- ConstrainVarSubVar(R_i, R_j) states that region variable R_i + must be a subregion of R_j +- ConstrainRegSubVar(R, R_i) states that the concrete region R + (which must not be a variable) must be a subregion of the varibale R_i +- ConstrainVarSubReg(R_i, R) is the inverse + +# Building up the constraints + +Variables and constraints are created using the following methods: + +- `new_region_var()` creates a new, unconstrained region variable; +- `make_subregion(R_i, R_j)` states that R_i is a subregion of R_j +- `lub_regions(R_i, R_j) -> R_k` returns a region R_k which is + the smallest region that is greater than both R_i and R_j +- `glb_regions(R_i, R_j) -> R_k` returns a region R_k which is + the greatest region that is smaller than both R_i and R_j + +The actual region resolution algorithm is not entirely +obvious, though it is also not overly complex. I'll explain +the algorithm as it currently works, then explain a somewhat +more complex variant that would probably scale better for +large graphs (and possibly all graphs). + +## Snapshotting + +It is also permitted to try (and rollback) changes to the graph. This +is done by invoking `start_snapshot()`, which returns a value. Then +later you can call `rollback_to()` which undoes the work. +Alternatively, you can call `commit()` which ends all snapshots. +Snapshots can be recursive---so you can start a snapshot when another +is in progress, but only the root snapshot can "commit". + +# Resolving constraints + +The constraint resolution algorithm is not super complex but also not +entirely obvious. Here I describe the problem somewhat abstractly, +then describe how the current code works, and finally describe a +better solution that is as of yet unimplemented. There may be other, +smarter ways of doing this with which I am unfamiliar and can't be +bothered to research at the moment. - NDM + +## The problem + +Basically our input is a directed graph where nodes can be divided +into two categories: region variables and concrete regions. Each edge +`R -> S` in the graph represents a constraint that the region `R` is a +subregion of the region `S`. + +Region variable nodes can have arbitrary degree. There is one region +variable node per region variable. + +Each concrete region node is associated with some, well, concrete +region: e.g., a free lifetime, or the region for a particular scope. +Note that there may be more than one concrete region node for a +particular region value. Moreover, because of how the graph is built, +we know that all concrete region nodes have either in-degree 1 or +out-degree 1. + +Before resolution begins, we build up the constraints in a hashmap +that maps `Constraint` keys to spans. During resolution, we construct +the actual `Graph` structure that we describe here. + +## Our current algorithm + +We divide region variables into two groups: Expanding and Contracting. +Expanding region variables are those that have a concrete region +predecessor (direct or indirect). Contracting region variables are +all others. + +We first resolve the values of Expanding region variables and then +process Contracting ones. We currently use an iterative, fixed-point +procedure (but read on, I believe this could be replaced with a linear +walk). Basically we iterate over the edges in the graph, ensuring +that, if the source of the edge has a value, then this value is a +subregion of the target value. If the target does not yet have a +value, it takes the value from the source. If the target already had +a value, then the resulting value is Least Upper Bound of the old and +new values. When we are done, each Expanding node will have the +smallest region that it could possibly have and still satisfy the +constraints. + +We next process the Contracting nodes. Here we again iterate over the +edges, only this time we move values from target to source (if the +source is a Contracting node). For each contracting node, we compute +its value as the GLB of all its successors. Basically contracting +nodes ensure that there is overlap between their successors; we will +ultimately infer the largest overlap possible. + +### A better algorithm + +Fixed-point iteration is not necessary. What we ought to do is first +identify and remove strongly connected components (SCC) in the graph. +Note that such components must consist solely of region variables; all +of these variables can effectively be unified into a single variable. + +Once SCCs are removed, we are left with a DAG. At this point, we can +walk the DAG in toplogical order once to compute the expanding nodes, +and again in reverse topological order to compute the contracting +nodes. The main reason I did not write it this way is that I did not +feel like implementing the SCC and toplogical sort algorithms at the +moment. + +# Skolemization and functions + +One of the trickiest and most subtle aspects of regions is dealing +with the fact that region variables are bound in function types. I +strongly suggest that if you want to understand the situation, you +read this paper (which is, admittedly, very long, but you don't have +to read the whole thing): + +http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/ + +Although my explanation will never compete with SPJ's (for one thing, +his is approximately 100 pages), I will attempt to explain the basic +problem and also how we solve it. Note that the paper only discusses +subtyping, not the computation of LUB/GLB. + +The problem we are addressing is that there is a kind of subtyping +between functions with bound region parameters. Consider, for +example, whether the following relation holds: + + fn(&'a int) <: &fn(&'b int)? (Yes, a => b) + +The answer is that of course it does. These two types are basically +the same, except that in one we used the name `a` and one we used +the name `b`. + +In the examples that follow, it becomes very important to know whether +a lifetime is bound in a function type (that is, is a lifetime +parameter) or appears free (is defined in some outer scope). +Therefore, from now on I will write the bindings explicitly, using a +notation like `fn(&'a int)` to indicate that `a` is a lifetime +parameter. + +Now let's consider two more function types. Here, we assume that the +`self` lifetime is defined somewhere outside and hence is not a +lifetime parameter bound by the function type (it "appears free"): + + fn(&'a int) <: &fn(&'self int)? (Yes, a => self) + +This subtyping relation does in fact hold. To see why, you have to +consider what subtyping means. One way to look at `T1 <: T2` is to +say that it means that it is always ok to treat an instance of `T1` as +if it had the type `T2`. So, with our functions, it is always ok to +treat a function that can take pointers with any lifetime as if it +were a function that can only take a pointer with the specific +lifetime `&self`. After all, `&self` is a lifetime, after all, and +the function can take values of any lifetime. + +You can also look at subtyping as the *is a* relationship. This amounts +to the same thing: a function that accepts pointers with any lifetime +*is a* function that accepts pointers with some specific lifetime. + +So, what if we reverse the order of the two function types, like this: + + fn(&'self int) <: &fn(&'a int)? (No) + +Does the subtyping relationship still hold? The answer of course is +no. In this case, the function accepts *only the lifetime `&self`*, +so it is not reasonable to treat it as if it were a function that +accepted any lifetime. + +What about these two examples: + + fn(&'a int, &'b int) <: &fn(&'a int, &'a int)? (Yes) + fn(&'a int, &'a int) <: &fn(&'a int, &'b int)? (No) + +Here, it is true that functions which take two pointers with any two +lifetimes can be treated as if they only accepted two pointers with +the same lifetime, but not the reverse. + +## The algorithm + +Here is the algorithm we use to perform the subtyping check: + +1. Replace all bound regions in the subtype with new variables +2. Replace all bound regions in the supertype with skolemized + equivalents. A "skolemized" region is just a new fresh region + name. +3. Check that the parameter and return types match as normal +4. Ensure that no skolemized regions 'leak' into region variables + visible from "the outside" + +Let's walk through some examples and see how this algorithm plays out. + +#### First example + +We'll start with the first example, which was: + + 1. fn(&'a T) <: &fn(&'b T)? Yes: a -> b + +After steps 1 and 2 of the algorithm we will have replaced the types +like so: + + 1. fn(&'A T) <: &fn(&'x T)? + +Here the upper case `&A` indicates a *region variable*, that is, a +region whose value is being inferred by the system. I also replaced +`&b` with `&x`---I'll use letters late in the alphabet (`x`, `y`, `z`) +to indicate skolemized region names. We can assume they don't appear +elsewhere. Note that neither the sub- nor the supertype bind any +region names anymore (as indicated by the absence of `<` and `>`). + +The next step is to check that the parameter types match. Because +parameters are contravariant, this means that we check whether: + + &'x T <: &'A T + +Region pointers are contravariant so this implies that + + &A <= &x + +must hold, where `<=` is the subregion relationship. Processing +*this* constrain simply adds a constraint into our graph that `&A <= +&x` and is considered successful (it can, for example, be satisfied by +choosing the value `&x` for `&A`). + +So far we have encountered no error, so the subtype check succeeds. + +#### The third example + +Now let's look first at the third example, which was: + + 3. fn(&'self T) <: &fn(&'b T)? No! + +After steps 1 and 2 of the algorithm we will have replaced the types +like so: + + 3. fn(&'self T) <: &fn(&'x T)? + +This looks pretty much the same as before, except that on the LHS +`&self` was not bound, and hence was left as-is and not replaced with +a variable. The next step is again to check that the parameter types +match. This will ultimately require (as before) that `&self` <= `&x` +must hold: but this does not hold. `self` and `x` are both distinct +free regions. So the subtype check fails. + +#### Checking for skolemization leaks + +You may be wondering about that mysterious last step in the algorithm. +So far it has not been relevant. The purpose of that last step is to +catch something like *this*: + + fn() -> fn(&'a T) <: &fn() -> fn(&'b T)? No. + +Here the function types are the same but for where the binding occurs. +The subtype returns a function that expects a value in precisely one +region. The supertype returns a function that expects a value in any +region. If we allow an instance of the subtype to be used where the +supertype is expected, then, someone could call the fn and think that +the return value has type `fn(&'b T)` when it really has type +`fn(&'a T)` (this is case #3, above). Bad. + +So let's step through what happens when we perform this subtype check. +We first replace the bound regions in the subtype (the supertype has +no bound regions). This gives us: + + fn() -> fn(&'A T) <: &fn() -> fn(&'b T)? + +Now we compare the return types, which are covariant, and hence we have: + + fn(&'A T) <: &fn(&'b T)? + +Here we skolemize the bound region in the supertype to yield: + + fn(&'A T) <: &fn(&'x T)? + +And then proceed to compare the argument types: + + &'x T <: &'A T + &A <= &x + +Finally, this is where it gets interesting! This is where an error +*should* be reported. But in fact this will not happen. The reason why +is that `A` is a variable: we will infer that its value is the fresh +region `x` and think that everything is happy. In fact, this behavior +is *necessary*, it was key to the first example we walked through. + +The difference between this example and the first one is that the variable +`A` already existed at the point where the skolemization occurred. In +the first example, you had two functions: + + fn(&'a T) <: &fn(&'b T) + +and hence `&A` and `&x` were created "together". In general, the +intention of the skolemized names is that they are supposed to be +fresh names that could never be equal to anything from the outside. +But when inference comes into play, we might not be respecting this +rule. + +So the way we solve this is to add a fourth step that examines the +constraints that refer to skolemized names. Basically, consider a +non-directed verison of the constraint graph. Let `Tainted(x)` be the +set of all things reachable from a skolemized variable `x`. +`Tainted(x)` should not contain any regions that existed before the +step at which the skolemization was performed. So this case here +would fail because `&x` was created alone, but is relatable to `&A`. + +## Computing the LUB and GLB + +The paper I pointed you at is written for Haskell. It does not +therefore considering subtyping and in particular does not consider +LUB or GLB computation. We have to consider this. Here is the +algorithm I implemented. + +First though, let's discuss what we are trying to compute in more +detail. The LUB is basically the "common supertype" and the GLB is +"common subtype"; one catch is that the LUB should be the +*most-specific* common supertype and the GLB should be *most general* +common subtype (as opposed to any common supertype or any common +subtype). + +Anyway, to help clarify, here is a table containing some +function pairs and their LUB/GLB: + +``` +Type 1 Type 2 LUB GLB +fn(&a) fn(&X) fn(&X) fn(&a) +fn(&A) fn(&X) -- fn(&a) +fn(&a, &b) fn(&x, &x) fn(&a, &a) fn(&a, &b) +fn(&a, &b, &a) fn(&x, &y, &y) fn(&a, &a, &a) fn(&a,&b,&c) +``` + +### Conventions + +I use lower-case letters (e.g., `&a`) for bound regions and upper-case +letters for free regions (`&A`). Region variables written with a +dollar-sign (e.g., `$a`). I will try to remember to enumerate the +bound-regions on the fn type as well (e.g., `fn(&a)`). + +### High-level summary + +Both the LUB and the GLB algorithms work in a similar fashion. They +begin by replacing all bound regions (on both sides) with fresh region +inference variables. Therefore, both functions are converted to types +that contain only free regions. We can then compute the LUB/GLB in a +straightforward way, as described in `combine.rs`. This results in an +interim type T. The algorithms then examine the regions that appear +in T and try to, in some cases, replace them with bound regions to +yield the final result. + +To decide whether to replace a region `R` that appears in `T` with a +bound region, the algorithms make use of two bits of information. +First is a set `V` that contains all region variables created as part +of the LUB/GLB computation. `V` will contain the region variables +created to replace the bound regions in the input types, but it also +contains 'intermediate' variables created to represent the LUB/GLB of +individual regions. Basically, when asked to compute the LUB/GLB of a +region variable with another region, the inferencer cannot oblige +immediately since the valuese of that variables are not known. +Therefore, it creates a new variable that is related to the two +regions. For example, the LUB of two variables `$x` and `$y` is a +fresh variable `$z` that is constrained such that `$x <= $z` and `$y +<= $z`. So `V` will contain these intermediate variables as well. + +The other important factor in deciding how to replace a region in T is +the function `Tainted($r)` which, for a region variable, identifies +all regions that the region variable is related to in some way +(`Tainted()` made an appearance in the subtype computation as well). + +### LUB + +The LUB algorithm proceeds in three steps: + +1. Replace all bound regions (on both sides) with fresh region + inference variables. +2. Compute the LUB "as normal", meaning compute the GLB of each + pair of argument types and the LUB of the return types and + so forth. Combine those to a new function type `F`. +3. Replace each region `R` that appears in `F` as follows: + - Let `V` be the set of variables created during the LUB + computational steps 1 and 2, as described in the previous section. + - If `R` is not in `V`, replace `R` with itself. + - If `Tainted(R)` contains a region that is not in `V`, + replace `R` with itself. + - Otherwise, select the earliest variable in `Tainted(R)` that originates + from the left-hand side and replace `R` with the bound region that + this variable was a replacement for. + +So, let's work through the simplest example: `fn(&A)` and `fn(&a)`. +In this case, `&a` will be replaced with `$a` and the interim LUB type +`fn($b)` will be computed, where `$b=GLB(&A,$a)`. Therefore, `V = +{$a, $b}` and `Tainted($b) = { $b, $a, &A }`. When we go to replace +`$b`, we find that since `&A \in Tainted($b)` is not a member of `V`, +we leave `$b` as is. When region inference happens, `$b` will be +resolved to `&A`, as we wanted. + +Let's look at a more complex one: `fn(&a, &b)` and `fn(&x, &x)`. In +this case, we'll end up with a (pre-replacement) LUB type of `fn(&g, +&h)` and a graph that looks like: + +``` + $a $b *--$x + \ \ / / + \ $h-* / + $g-----------* +``` + +Here `$g` and `$h` are fresh variables that are created to represent +the LUB/GLB of things requiring inference. This means that `V` and +`Tainted` will look like: + +``` +V = {$a, $b, $g, $h, $x} +Tainted($g) = Tainted($h) = { $a, $b, $h, $g, $x } +``` + +Therefore we replace both `$g` and `$h` with `$a`, and end up +with the type `fn(&a, &a)`. + +### GLB + +The procedure for computing the GLB is similar. The difference lies +in computing the replacements for the various variables. For each +region `R` that appears in the type `F`, we again compute `Tainted(R)` +and examine the results: + +1. If `R` is not in `V`, it is not replaced. +2. Else, if `Tainted(R)` contains only variables in `V`, and it + contains exactly one variable from the LHS and one variable from + the RHS, then `R` can be mapped to the bound version of the + variable from the LHS. +3. Else, if `Tainted(R)` contains no variable from the LHS and no + variable from the RHS, then `R` can be mapped to itself. +4. Else, `R` is mapped to a fresh bound variable. + +These rules are pretty complex. Let's look at some examples to see +how they play out. + +Out first example was `fn(&a)` and `fn(&X)`. In this case, `&a` will +be replaced with `$a` and we will ultimately compute a +(pre-replacement) GLB type of `fn($g)` where `$g=LUB($a,&X)`. +Therefore, `V={$a,$g}` and `Tainted($g)={$g,$a,&X}. To find the +replacement for `$g` we consult the rules above: +- Rule (1) does not apply because `$g \in V` +- Rule (2) does not apply because `&X \in Tainted($g)` +- Rule (3) does not apply because `$a \in Tainted($g)` +- Hence, by rule (4), we replace `$g` with a fresh bound variable `&z`. +So our final result is `fn(&z)`, which is correct. + +The next example is `fn(&A)` and `fn(&Z)`. In this case, we will again +have a (pre-replacement) GLB of `fn(&g)`, where `$g = LUB(&A,&Z)`. +Therefore, `V={$g}` and `Tainted($g) = {$g, &A, &Z}`. In this case, +by rule (3), `$g` is mapped to itself, and hence the result is +`fn($g)`. This result is correct (in this case, at least), but it is +indicative of a case that *can* lead us into concluding that there is +no GLB when in fact a GLB does exist. See the section "Questionable +Results" below for more details. + +The next example is `fn(&a, &b)` and `fn(&c, &c)`. In this case, as +before, we'll end up with `F=fn($g, $h)` where `Tainted($g) = +Tainted($h) = {$g, $h, $a, $b, $c}`. Only rule (4) applies and hence +we'll select fresh bound variables `y` and `z` and wind up with +`fn(&y, &z)`. + +For the last example, let's consider what may seem trivial, but is +not: `fn(&a, &a)` and `fn(&b, &b)`. In this case, we'll get `F=fn($g, +$h)` where `Tainted($g) = {$g, $a, $x}` and `Tainted($h) = {$h, $a, +$x}`. Both of these sets contain exactly one bound variable from each +side, so we'll map them both to `&a`, resulting in `fn(&a, &a)`, which +is the desired result. + +### Shortcomings and correctness + +You may be wondering whether this algorithm is correct. The answer is +"sort of". There are definitely cases where they fail to compute a +result even though a correct result exists. I believe, though, that +if they succeed, then the result is valid, and I will attempt to +convince you. The basic argument is that the "pre-replacement" step +computes a set of constraints. The replacements, then, attempt to +satisfy those constraints, using bound identifiers where needed. + +For now I will briefly go over the cases for LUB/GLB and identify +their intent: + +- LUB: + - The region variables that are substituted in place of bound regions + are intended to collect constraints on those bound regions. + - If Tainted(R) contains only values in V, then this region is unconstrained + and can therefore be generalized, otherwise it cannot. +- GLB: + - The region variables that are substituted in place of bound regions + are intended to collect constraints on those bound regions. + - If Tainted(R) contains exactly one variable from each side, and + only variables in V, that indicates that those two bound regions + must be equated. + - Otherwise, if Tainted(R) references any variables from left or right + side, then it is trying to combine a bound region with a free one or + multiple bound regions, so we need to select fresh bound regions. + +Sorry this is more of a shorthand to myself. I will try to write up something +more convincing in the future. + +#### Where are the algorithms wrong? + +- The pre-replacement computation can fail even though using a + bound-region would have succeeded. +- We will compute GLB(fn(fn($a)), fn(fn($b))) as fn($c) where $c is the + GLB of $a and $b. But if inference finds that $a and $b must be mapped + to regions without a GLB, then this is effectively a failure to compute + the GLB. However, the result `fn<$c>(fn($c))` is a valid GLB. + +*/ diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index c674cbc0f63c..b474b95d0fec 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -8,533 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Region inference module. - -# Introduction - -Region inference uses a somewhat more involved algorithm than type -inference. It is not the most efficient thing ever written though it -seems to work well enough in practice (famous last words). The reason -that we use a different algorithm is because, unlike with types, it is -impractical to hand-annotate with regions (in some cases, there aren't -even the requisite syntactic forms). So we have to get it right, and -it's worth spending more time on a more involved analysis. Moreover, -regions are a simpler case than types: they don't have aggregate -structure, for example. - -Unlike normal type inference, which is similar in spirit to H-M and thus -works progressively, the region type inference works by accumulating -constraints over the course of a function. Finally, at the end of -processing a function, we process and solve the constraints all at -once. - -The constraints are always of one of three possible forms: - -- ConstrainVarSubVar(R_i, R_j) states that region variable R_i - must be a subregion of R_j -- ConstrainRegSubVar(R, R_i) states that the concrete region R - (which must not be a variable) must be a subregion of the varibale R_i -- ConstrainVarSubReg(R_i, R) is the inverse - -# Building up the constraints - -Variables and constraints are created using the following methods: - -- `new_region_var()` creates a new, unconstrained region variable; -- `make_subregion(R_i, R_j)` states that R_i is a subregion of R_j -- `lub_regions(R_i, R_j) -> R_k` returns a region R_k which is - the smallest region that is greater than both R_i and R_j -- `glb_regions(R_i, R_j) -> R_k` returns a region R_k which is - the greatest region that is smaller than both R_i and R_j - -The actual region resolution algorithm is not entirely -obvious, though it is also not overly complex. I'll explain -the algorithm as it currently works, then explain a somewhat -more complex variant that would probably scale better for -large graphs (and possibly all graphs). - -## Snapshotting - -It is also permitted to try (and rollback) changes to the graph. This -is done by invoking `start_snapshot()`, which returns a value. Then -later you can call `rollback_to()` which undoes the work. -Alternatively, you can call `commit()` which ends all snapshots. -Snapshots can be recursive---so you can start a snapshot when another -is in progress, but only the root snapshot can "commit". - -# Resolving constraints - -The constraint resolution algorithm is not super complex but also not -entirely obvious. Here I describe the problem somewhat abstractly, -then describe how the current code works, and finally describe a -better solution that is as of yet unimplemented. There may be other, -smarter ways of doing this with which I am unfamiliar and can't be -bothered to research at the moment. - NDM - -## The problem - -Basically our input is a directed graph where nodes can be divided -into two categories: region variables and concrete regions. Each edge -`R -> S` in the graph represents a constraint that the region `R` is a -subregion of the region `S`. - -Region variable nodes can have arbitrary degree. There is one region -variable node per region variable. - -Each concrete region node is associated with some, well, concrete -region: e.g., a free lifetime, or the region for a particular scope. -Note that there may be more than one concrete region node for a -particular region value. Moreover, because of how the graph is built, -we know that all concrete region nodes have either in-degree 1 or -out-degree 1. - -Before resolution begins, we build up the constraints in a hashmap -that maps `Constraint` keys to spans. During resolution, we construct -the actual `Graph` structure that we describe here. - -## Our current algorithm - -We divide region variables into two groups: Expanding and Contracting. -Expanding region variables are those that have a concrete region -predecessor (direct or indirect). Contracting region variables are -all others. - -We first resolve the values of Expanding region variables and then -process Contracting ones. We currently use an iterative, fixed-point -procedure (but read on, I believe this could be replaced with a linear -walk). Basically we iterate over the edges in the graph, ensuring -that, if the source of the edge has a value, then this value is a -subregion of the target value. If the target does not yet have a -value, it takes the value from the source. If the target already had -a value, then the resulting value is Least Upper Bound of the old and -new values. When we are done, each Expanding node will have the -smallest region that it could possibly have and still satisfy the -constraints. - -We next process the Contracting nodes. Here we again iterate over the -edges, only this time we move values from target to source (if the -source is a Contracting node). For each contracting node, we compute -its value as the GLB of all its successors. Basically contracting -nodes ensure that there is overlap between their successors; we will -ultimately infer the largest overlap possible. - -### A better algorithm - -Fixed-point iteration is not necessary. What we ought to do is first -identify and remove strongly connected components (SCC) in the graph. -Note that such components must consist solely of region variables; all -of these variables can effectively be unified into a single variable. - -Once SCCs are removed, we are left with a DAG. At this point, we can -walk the DAG in toplogical order once to compute the expanding nodes, -and again in reverse topological order to compute the contracting -nodes. The main reason I did not write it this way is that I did not -feel like implementing the SCC and toplogical sort algorithms at the -moment. - -# Skolemization and functions - -One of the trickiest and most subtle aspects of regions is dealing -with the fact that region variables are bound in function types. I -strongly suggest that if you want to understand the situation, you -read this paper (which is, admittedly, very long, but you don't have -to read the whole thing): - -http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/ - -Although my explanation will never compete with SPJ's (for one thing, -his is approximately 100 pages), I will attempt to explain the basic -problem and also how we solve it. Note that the paper only discusses -subtyping, not the computation of LUB/GLB. - -The problem we are addressing is that there is a kind of subtyping -between functions with bound region parameters. Consider, for -example, whether the following relation holds: - - fn(&'a int) <: &fn(&'b int)? (Yes, a => b) - -The answer is that of course it does. These two types are basically -the same, except that in one we used the name `a` and one we used -the name `b`. - -In the examples that follow, it becomes very important to know whether -a lifetime is bound in a function type (that is, is a lifetime -parameter) or appears free (is defined in some outer scope). -Therefore, from now on I will write the bindings explicitly, using a -notation like `fn(&'a int)` to indicate that `a` is a lifetime -parameter. - -Now let's consider two more function types. Here, we assume that the -`self` lifetime is defined somewhere outside and hence is not a -lifetime parameter bound by the function type (it "appears free"): - - fn(&'a int) <: &fn(&'self int)? (Yes, a => self) - -This subtyping relation does in fact hold. To see why, you have to -consider what subtyping means. One way to look at `T1 <: T2` is to -say that it means that it is always ok to treat an instance of `T1` as -if it had the type `T2`. So, with our functions, it is always ok to -treat a function that can take pointers with any lifetime as if it -were a function that can only take a pointer with the specific -lifetime `&self`. After all, `&self` is a lifetime, after all, and -the function can take values of any lifetime. - -You can also look at subtyping as the *is a* relationship. This amounts -to the same thing: a function that accepts pointers with any lifetime -*is a* function that accepts pointers with some specific lifetime. - -So, what if we reverse the order of the two function types, like this: - - fn(&'self int) <: &fn(&'a int)? (No) - -Does the subtyping relationship still hold? The answer of course is -no. In this case, the function accepts *only the lifetime `&self`*, -so it is not reasonable to treat it as if it were a function that -accepted any lifetime. - -What about these two examples: - - fn(&'a int, &'b int) <: &fn(&'a int, &'a int)? (Yes) - fn(&'a int, &'a int) <: &fn(&'a int, &'b int)? (No) - -Here, it is true that functions which take two pointers with any two -lifetimes can be treated as if they only accepted two pointers with -the same lifetime, but not the reverse. - -## The algorithm - -Here is the algorithm we use to perform the subtyping check: - -1. Replace all bound regions in the subtype with new variables -2. Replace all bound regions in the supertype with skolemized - equivalents. A "skolemized" region is just a new fresh region - name. -3. Check that the parameter and return types match as normal -4. Ensure that no skolemized regions 'leak' into region variables - visible from "the outside" - -Let's walk through some examples and see how this algorithm plays out. - -#### First example - -We'll start with the first example, which was: - - 1. fn(&'a T) <: &fn(&'b T)? Yes: a -> b - -After steps 1 and 2 of the algorithm we will have replaced the types -like so: - - 1. fn(&'A T) <: &fn(&'x T)? - -Here the upper case `&A` indicates a *region variable*, that is, a -region whose value is being inferred by the system. I also replaced -`&b` with `&x`---I'll use letters late in the alphabet (`x`, `y`, `z`) -to indicate skolemized region names. We can assume they don't appear -elsewhere. Note that neither the sub- nor the supertype bind any -region names anymore (as indicated by the absence of `<` and `>`). - -The next step is to check that the parameter types match. Because -parameters are contravariant, this means that we check whether: - - &'x T <: &'A T - -Region pointers are contravariant so this implies that - - &A <= &x - -must hold, where `<=` is the subregion relationship. Processing -*this* constrain simply adds a constraint into our graph that `&A <= -&x` and is considered successful (it can, for example, be satisfied by -choosing the value `&x` for `&A`). - -So far we have encountered no error, so the subtype check succeeds. - -#### The third example - -Now let's look first at the third example, which was: - - 3. fn(&'self T) <: &fn(&'b T)? No! - -After steps 1 and 2 of the algorithm we will have replaced the types -like so: - - 3. fn(&'self T) <: &fn(&'x T)? - -This looks pretty much the same as before, except that on the LHS -`&self` was not bound, and hence was left as-is and not replaced with -a variable. The next step is again to check that the parameter types -match. This will ultimately require (as before) that `&self` <= `&x` -must hold: but this does not hold. `self` and `x` are both distinct -free regions. So the subtype check fails. - -#### Checking for skolemization leaks - -You may be wondering about that mysterious last step in the algorithm. -So far it has not been relevant. The purpose of that last step is to -catch something like *this*: - - fn() -> fn(&'a T) <: &fn() -> fn(&'b T)? No. - -Here the function types are the same but for where the binding occurs. -The subtype returns a function that expects a value in precisely one -region. The supertype returns a function that expects a value in any -region. If we allow an instance of the subtype to be used where the -supertype is expected, then, someone could call the fn and think that -the return value has type `fn(&'b T)` when it really has type -`fn(&'a T)` (this is case #3, above). Bad. - -So let's step through what happens when we perform this subtype check. -We first replace the bound regions in the subtype (the supertype has -no bound regions). This gives us: - - fn() -> fn(&'A T) <: &fn() -> fn(&'b T)? - -Now we compare the return types, which are covariant, and hence we have: - - fn(&'A T) <: &fn(&'b T)? - -Here we skolemize the bound region in the supertype to yield: - - fn(&'A T) <: &fn(&'x T)? - -And then proceed to compare the argument types: - - &'x T <: &'A T - &A <= &x - -Finally, this is where it gets interesting! This is where an error -*should* be reported. But in fact this will not happen. The reason why -is that `A` is a variable: we will infer that its value is the fresh -region `x` and think that everything is happy. In fact, this behavior -is *necessary*, it was key to the first example we walked through. - -The difference between this example and the first one is that the variable -`A` already existed at the point where the skolemization occurred. In -the first example, you had two functions: - - fn(&'a T) <: &fn(&'b T) - -and hence `&A` and `&x` were created "together". In general, the -intention of the skolemized names is that they are supposed to be -fresh names that could never be equal to anything from the outside. -But when inference comes into play, we might not be respecting this -rule. - -So the way we solve this is to add a fourth step that examines the -constraints that refer to skolemized names. Basically, consider a -non-directed verison of the constraint graph. Let `Tainted(x)` be the -set of all things reachable from a skolemized variable `x`. -`Tainted(x)` should not contain any regions that existed before the -step at which the skolemization was performed. So this case here -would fail because `&x` was created alone, but is relatable to `&A`. - -## Computing the LUB and GLB - -The paper I pointed you at is written for Haskell. It does not -therefore considering subtyping and in particular does not consider -LUB or GLB computation. We have to consider this. Here is the -algorithm I implemented. - -First though, let's discuss what we are trying to compute in more -detail. The LUB is basically the "common supertype" and the GLB is -"common subtype"; one catch is that the LUB should be the -*most-specific* common supertype and the GLB should be *most general* -common subtype (as opposed to any common supertype or any common -subtype). - -Anyway, to help clarify, here is a table containing some -function pairs and their LUB/GLB: - -``` -Type 1 Type 2 LUB GLB -fn(&a) fn(&X) fn(&X) fn(&a) -fn(&A) fn(&X) -- fn(&a) -fn(&a, &b) fn(&x, &x) fn(&a, &a) fn(&a, &b) -fn(&a, &b, &a) fn(&x, &y, &y) fn(&a, &a, &a) fn(&a,&b,&c) -``` - -### Conventions - -I use lower-case letters (e.g., `&a`) for bound regions and upper-case -letters for free regions (`&A`). Region variables written with a -dollar-sign (e.g., `$a`). I will try to remember to enumerate the -bound-regions on the fn type as well (e.g., `fn(&a)`). - -### High-level summary - -Both the LUB and the GLB algorithms work in a similar fashion. They -begin by replacing all bound regions (on both sides) with fresh region -inference variables. Therefore, both functions are converted to types -that contain only free regions. We can then compute the LUB/GLB in a -straightforward way, as described in `combine.rs`. This results in an -interim type T. The algorithms then examine the regions that appear -in T and try to, in some cases, replace them with bound regions to -yield the final result. - -To decide whether to replace a region `R` that appears in `T` with a -bound region, the algorithms make use of two bits of information. -First is a set `V` that contains all region variables created as part -of the LUB/GLB computation. `V` will contain the region variables -created to replace the bound regions in the input types, but it also -contains 'intermediate' variables created to represent the LUB/GLB of -individual regions. Basically, when asked to compute the LUB/GLB of a -region variable with another region, the inferencer cannot oblige -immediately since the valuese of that variables are not known. -Therefore, it creates a new variable that is related to the two -regions. For example, the LUB of two variables `$x` and `$y` is a -fresh variable `$z` that is constrained such that `$x <= $z` and `$y -<= $z`. So `V` will contain these intermediate variables as well. - -The other important factor in deciding how to replace a region in T is -the function `Tainted($r)` which, for a region variable, identifies -all regions that the region variable is related to in some way -(`Tainted()` made an appearance in the subtype computation as well). - -### LUB - -The LUB algorithm proceeds in three steps: - -1. Replace all bound regions (on both sides) with fresh region - inference variables. -2. Compute the LUB "as normal", meaning compute the GLB of each - pair of argument types and the LUB of the return types and - so forth. Combine those to a new function type `F`. -3. Replace each region `R` that appears in `F` as follows: - - Let `V` be the set of variables created during the LUB - computational steps 1 and 2, as described in the previous section. - - If `R` is not in `V`, replace `R` with itself. - - If `Tainted(R)` contains a region that is not in `V`, - replace `R` with itself. - - Otherwise, select the earliest variable in `Tainted(R)` that originates - from the left-hand side and replace `R` with the bound region that - this variable was a replacement for. - -So, let's work through the simplest example: `fn(&A)` and `fn(&a)`. -In this case, `&a` will be replaced with `$a` and the interim LUB type -`fn($b)` will be computed, where `$b=GLB(&A,$a)`. Therefore, `V = -{$a, $b}` and `Tainted($b) = { $b, $a, &A }`. When we go to replace -`$b`, we find that since `&A \in Tainted($b)` is not a member of `V`, -we leave `$b` as is. When region inference happens, `$b` will be -resolved to `&A`, as we wanted. - -Let's look at a more complex one: `fn(&a, &b)` and `fn(&x, &x)`. In -this case, we'll end up with a (pre-replacement) LUB type of `fn(&g, -&h)` and a graph that looks like: - -``` - $a $b *--$x - \ \ / / - \ $h-* / - $g-----------* -``` - -Here `$g` and `$h` are fresh variables that are created to represent -the LUB/GLB of things requiring inference. This means that `V` and -`Tainted` will look like: - -``` -V = {$a, $b, $g, $h, $x} -Tainted($g) = Tainted($h) = { $a, $b, $h, $g, $x } -``` - -Therefore we replace both `$g` and `$h` with `$a`, and end up -with the type `fn(&a, &a)`. - -### GLB - -The procedure for computing the GLB is similar. The difference lies -in computing the replacements for the various variables. For each -region `R` that appears in the type `F`, we again compute `Tainted(R)` -and examine the results: - -1. If `R` is not in `V`, it is not replaced. -2. Else, if `Tainted(R)` contains only variables in `V`, and it - contains exactly one variable from the LHS and one variable from - the RHS, then `R` can be mapped to the bound version of the - variable from the LHS. -3. Else, if `Tainted(R)` contains no variable from the LHS and no - variable from the RHS, then `R` can be mapped to itself. -4. Else, `R` is mapped to a fresh bound variable. - -These rules are pretty complex. Let's look at some examples to see -how they play out. - -Out first example was `fn(&a)` and `fn(&X)`. In this case, `&a` will -be replaced with `$a` and we will ultimately compute a -(pre-replacement) GLB type of `fn($g)` where `$g=LUB($a,&X)`. -Therefore, `V={$a,$g}` and `Tainted($g)={$g,$a,&X}. To find the -replacement for `$g` we consult the rules above: -- Rule (1) does not apply because `$g \in V` -- Rule (2) does not apply because `&X \in Tainted($g)` -- Rule (3) does not apply because `$a \in Tainted($g)` -- Hence, by rule (4), we replace `$g` with a fresh bound variable `&z`. -So our final result is `fn(&z)`, which is correct. - -The next example is `fn(&A)` and `fn(&Z)`. In this case, we will again -have a (pre-replacement) GLB of `fn(&g)`, where `$g = LUB(&A,&Z)`. -Therefore, `V={$g}` and `Tainted($g) = {$g, &A, &Z}`. In this case, -by rule (3), `$g` is mapped to itself, and hence the result is -`fn($g)`. This result is correct (in this case, at least), but it is -indicative of a case that *can* lead us into concluding that there is -no GLB when in fact a GLB does exist. See the section "Questionable -Results" below for more details. - -The next example is `fn(&a, &b)` and `fn(&c, &c)`. In this case, as -before, we'll end up with `F=fn($g, $h)` where `Tainted($g) = -Tainted($h) = {$g, $h, $a, $b, $c}`. Only rule (4) applies and hence -we'll select fresh bound variables `y` and `z` and wind up with -`fn(&y, &z)`. - -For the last example, let's consider what may seem trivial, but is -not: `fn(&a, &a)` and `fn(&b, &b)`. In this case, we'll get `F=fn($g, -$h)` where `Tainted($g) = {$g, $a, $x}` and `Tainted($h) = {$h, $a, -$x}`. Both of these sets contain exactly one bound variable from each -side, so we'll map them both to `&a`, resulting in `fn(&a, &a)`, which -is the desired result. - -### Shortcomings and correctness - -You may be wondering whether this algorithm is correct. The answer is -"sort of". There are definitely cases where they fail to compute a -result even though a correct result exists. I believe, though, that -if they succeed, then the result is valid, and I will attempt to -convince you. The basic argument is that the "pre-replacement" step -computes a set of constraints. The replacements, then, attempt to -satisfy those constraints, using bound identifiers where needed. - -For now I will briefly go over the cases for LUB/GLB and identify -their intent: - -- LUB: - - The region variables that are substituted in place of bound regions - are intended to collect constraints on those bound regions. - - If Tainted(R) contains only values in V, then this region is unconstrained - and can therefore be generalized, otherwise it cannot. -- GLB: - - The region variables that are substituted in place of bound regions - are intended to collect constraints on those bound regions. - - If Tainted(R) contains exactly one variable from each side, and - only variables in V, that indicates that those two bound regions - must be equated. - - Otherwise, if Tainted(R) references any variables from left or right - side, then it is trying to combine a bound region with a free one or - multiple bound regions, so we need to select fresh bound regions. - -Sorry this is more of a shorthand to myself. I will try to write up something -more convincing in the future. - -#### Where are the algorithms wrong? - -- The pre-replacement computation can fail even though using a - bound-region would have succeeded. -- We will compute GLB(fn(fn($a)), fn(fn($b))) as fn($c) where $c is the - GLB of $a and $b. But if inference finds that $a and $b must be mapped - to regions without a GLB, then this is effectively a failure to compute - the GLB. However, the result `fn<$c>(fn($c))` is a valid GLB. - -*/ +/*! See doc.rs */ use middle::ty; @@ -556,7 +30,9 @@ use syntax::ast; use syntax::opt_vec; use syntax::opt_vec::OptVec; -#[deriving(Eq,IterBytes)] +mod doc; + +#[deriving(Eq, IterBytes)] enum Constraint { ConstrainVarSubVar(RegionVid, RegionVid), ConstrainRegSubVar(Region, RegionVid), From e416c9fa17b6b6668e2c2b0b619466840a810931 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 16 Jun 2013 14:03:35 -0400 Subject: [PATCH 331/336] Adjust documentation to describe how closures and closure bounds affect things. --- .../typeck/infer/region_inference/doc.rs | 270 ++++++++++++++++-- 1 file changed, 253 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/typeck/infer/region_inference/doc.rs b/src/librustc/middle/typeck/infer/region_inference/doc.rs index 0a288d40fa90..df6d5dc1b206 100644 --- a/src/librustc/middle/typeck/infer/region_inference/doc.rs +++ b/src/librustc/middle/typeck/infer/region_inference/doc.rs @@ -12,6 +12,11 @@ Region inference module. +# Terminology + +Note that we use the terms region and lifetime interchangeably, +though the term `lifetime` is preferred. + # Introduction Region inference uses a somewhat more involved algorithm than type @@ -50,10 +55,7 @@ Variables and constraints are created using the following methods: the greatest region that is smaller than both R_i and R_j The actual region resolution algorithm is not entirely -obvious, though it is also not overly complex. I'll explain -the algorithm as it currently works, then explain a somewhat -more complex variant that would probably scale better for -large graphs (and possibly all graphs). +obvious, though it is also not overly complex. ## Snapshotting @@ -68,10 +70,9 @@ is in progress, but only the root snapshot can "commit". The constraint resolution algorithm is not super complex but also not entirely obvious. Here I describe the problem somewhat abstractly, -then describe how the current code works, and finally describe a -better solution that is as of yet unimplemented. There may be other, -smarter ways of doing this with which I am unfamiliar and can't be -bothered to research at the moment. - NDM +then describe how the current code works. There may be other, smarter +ways of doing this with which I am unfamiliar and can't be bothered to +research at the moment. - NDM ## The problem @@ -120,19 +121,254 @@ its value as the GLB of all its successors. Basically contracting nodes ensure that there is overlap between their successors; we will ultimately infer the largest overlap possible. -### A better algorithm +# The Region Hierarchy -Fixed-point iteration is not necessary. What we ought to do is first +## Without closures + +Let's first consider the region hierarchy without thinking about +closures, because they add a lot of complications. The region +hierarchy *basically* mirrors the lexical structure of the code. +There is a region for every piece of 'evaluation' that occurs, meaning +every expression, block, and pattern (patterns are considered to +"execute" by testing the value they are applied to and creating any +relevant bindings). So, for example: + + fn foo(x: int, y: int) { // -+ + // +------------+ // | + // | +-----+ // | + // | +-+ +-+ +-+ // | + // | | | | | | | // | + // v v v v v v v // | + let z = x + y; // | + ... // | + } // -+ + + fn bar() { ... } + +In this example, there is a region for the fn body block as a whole, +and then a subregion for the declaration of the local variable. +Within that, there are sublifetimes for the assignment pattern and +also the expression `x + y`. The expression itself has sublifetimes +for evaluating `x` and and `y`. + +## Function calls + +Function calls are a bit tricky. I will describe how we handle them +*now* and then a bit about how we can improve them (Issue #6268). + +Consider a function call like `func(expr1, expr2)`, where `func`, +`arg1`, and `arg2` are all arbitrary expressions. Currently, +we construct a region hierarchy like: + + +----------------+ + | | + +--+ +---+ +---+| + v v v v v vv + func(expr1, expr2) + +Here you can see that the call as a whole has a region and the +function plus arguments are subregions of that. As a side-effect of +this, we get a lot of spurious errors around nested calls, in +particular when combined with `&mut` functions. For example, a call +like this one + + self.foo(self.bar()) + +where both `foo` and `bar` are `&mut self` functions will always yield +an error. + +Here is a more involved example (which is safe) so we can see what's +going on: + + struct Foo { f: uint, g: uint } + ... + fn add(p: &mut uint, v: uint) { + *p += v; + } + ... + fn inc(p: &mut uint) -> uint { + *p += 1; *p + } + fn weird() { + let mut x: ~Foo = ~Foo { ... }; + 'a: add(&mut (*x).f, + 'b: inc(&mut (*x).f)) // (*) + } + +The important part is the line marked `(*)` which contains a call to +`add()`. The first argument is a mutable borrow of the field `f`. The +second argument also borrows the field `f`. Now, in the current borrow +checker, the first borrow is given the lifetime of the call to +`add()`, `'a`. The second borrow is given the lifetime of `'b` of the +call to `inc()`. Because `'b` is considered to be a sublifetime of +`'a`, an error is reported since there are two co-existing mutable +borrows of the same data. + +However, if we were to examine the lifetimes a bit more carefully, we +can see that this error is unnecessary. Let's examine the lifetimes +involved with `'a` in detail. We'll break apart all the steps involved +in a call expression: + + 'a: { + 'a_arg1: let a_temp1: ... = add; + 'a_arg2: let a_temp2: &'a mut uint = &'a mut (*x).f; + 'a_arg3: let a_temp3: uint = { + let b_temp1: ... = inc; + let b_temp2: &'b = &'b mut (*x).f; + 'b_call: b_temp1(b_temp2) + }; + 'a_call: a_temp1(a_temp2, a_temp3) // (**) + } + +Here we see that the lifetime `'a` includes a number of substatements. +In particular, there is this lifetime I've called `'a_call` that +corresponds to the *actual execution of the function `add()`*, after +all arguments have been evaluated. There is a corresponding lifetime +`'b_call` for the execution of `inc()`. If we wanted to be precise +about it, the lifetime of the two borrows should be `'a_call` and +`'b_call` respectively, since the borrowed pointers that were created +will not be dereferenced except during the execution itself. + +However, this model by itself is not sound. The reason is that +while the two borrowed pointers that are created will never be used +simultaneously, it is still true that the first borrowed pointer is +*created* before the second argument is evaluated, and so even though +it will not be *dereferenced* during the evaluation of the second +argument, it can still be *invalidated* by that evaluation. Consider +this similar but unsound example: + + struct Foo { f: uint, g: uint } + ... + fn add(p: &mut uint, v: uint) { + *p += v; + } + ... + fn consume(x: ~Foo) -> uint { + x.f + x.g + } + fn weird() { + let mut x: ~Foo = ~Foo { ... }; + 'a: add(&mut (*x).f, consume(x)) // (*) + } + +In this case, the second argument to `add` actually consumes `x`, thus +invalidating the first argument. + +So, for now, we exclude the `call` lifetimes from our model. +Eventually I would like to include them, but we will have to make the +borrow checker handle this situation correctly. In particular, if +there is a borrowed pointer created whose lifetime does not enclose +the borrow expression, we must issue sufficient restrictions to ensure +that the pointee remains valid. + +## Adding closures + +The other significant complication to the region hierarchy is +closures. I will describe here how closures should work, though some +of the work to implement this model is ongoing at the time of this +writing. + +The body of closures are type-checked along with the function that +creates them. However, unlike other expressions that appear within the +function body, it is not entirely obvious when a closure body executes +with respect to the other expressions. This is because the closure +body will execute whenever the closure is called; however, we can +never know precisely when the closure will be called, especially +without some sort of alias analysis. + +However, we can place some sort of limits on when the closure +executes. In particular, the type of every closure `fn:'r K` includes +a region bound `'r`. This bound indicates the maximum lifetime of that +closure; once we exit that region, the closure cannot be called +anymore. Therefore, we say that the lifetime of the closure body is a +sublifetime of the closure bound, but the closure body itself is unordered +with respect to other parts of the code. + +For example, consider the following fragment of code: + + 'a: { + let closure: fn:'a() = || 'b: { + 'c: ... + }; + 'd: ... + } + +Here we have four lifetimes, `'a`, `'b`, `'c`, and `'d`. The closure +`closure` is bounded by the lifetime `'a`. The lifetime `'b` is the +lifetime of the closure body, and `'c` is some statement within the +closure body. Finally, `'d` is a statement within the outer block that +created the closure. + +We can say that the closure body `'b` is a sublifetime of `'a` due to +the closure bound. By the usual lexical scoping conventions, the +statement `'c` is clearly a sublifetime of `'b`, and `'d` is a +sublifetime of `'d`. However, there is no ordering between `'c` and +`'d` per se (this kind of ordering between statements is actually only +an issue for dataflow; passes like the borrow checker must assume that +closures could execute at any time from the moment they are created +until they go out of scope). + +### Complications due to closure bound inference + +There is only one problem with the above model: in general, we do not +actually *know* the closure bounds during region inference! In fact, +closure bounds are almost always region variables! This is very tricky +because the inference system implicitly assumes that we can do things +like compute the LUB of two scoped lifetimes without needing to know +the values of any variables. + +Here is an example to illustrate the problem: + + fn identify(x: T) -> T { x } + + fn foo() { // 'foo is the function body + 'a: { + let closure = identity(|| 'b: { + 'c: ... + }); + 'd: closure(); + } + 'e: ...; + } + +In this example, the closure bound is not explicit. At compile time, +we will create a region variable (let's call it `V0`) to represent the +closure bound. + +The primary difficulty arises during the constraint propagation phase. +Imagine there is some variable with incoming edges from `'c` and `'d`. +This means that the value of the variable must be `LUB('c, +'d)`. However, without knowing what the closure bound `V0` is, we +can't compute the LUB of `'c` and `'d`! Any we don't know the closure +bound until inference is done. + +The solution is to rely on the fixed point nature of inference. +Basically, when we must compute `LUB('c, 'd)`, we just use the current +value for `V0` as the closure's bound. If `V0`'s binding should +change, then we will do another round of inference, and the result of +`LUB('c, 'd)` will change. + +One minor implication of this is that the graph does not in fact track +the full set of dependencies between edges. We cannot easily know +whether the result of a LUB computation will change, since there may +be indirect dependencies on other variables that are not reflected on +the graph. Therefore, we must *always* iterate over all edges when +doing the fixed point calculation, not just those adjacent to nodes +whose values have changed. + +Were it not for this requirement, we could in fact avoid fixed-point +iteration altogether. In that universe, we could instead first identify and remove strongly connected components (SCC) in the graph. Note that such components must consist solely of region variables; all of these variables can effectively be unified into a single variable. - -Once SCCs are removed, we are left with a DAG. At this point, we can -walk the DAG in toplogical order once to compute the expanding nodes, -and again in reverse topological order to compute the contracting -nodes. The main reason I did not write it this way is that I did not -feel like implementing the SCC and toplogical sort algorithms at the -moment. +Once SCCs are removed, we are left with a DAG. At this point, we +could walk the DAG in toplogical order once to compute the expanding +nodes, and again in reverse topological order to compute the +contracting nodes. However, as I said, this does not work given the +current treatment of closure bounds, but perhaps in the future we can +address this problem somehow and make region inference somewhat more +efficient. Note that this is solely a matter of performance, not +expressiveness. # Skolemization and functions From 4a0469e3d70868db7ab27841e57080cff8e546b3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 19 Jun 2013 12:32:56 -0400 Subject: [PATCH 332/336] Add copyright notice and kill broken test --- src/librustc/middle/typeck/infer/doc.rs | 10 ++++++++++ .../regions-free-region-ordering-incorrect.rs} | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) rename src/test/{run-pass/issue-4325.rs => compile-fail/regions-free-region-ordering-incorrect.rs} (60%) diff --git a/src/librustc/middle/typeck/infer/doc.rs b/src/librustc/middle/typeck/infer/doc.rs index 16d0f2cc18b0..11bfbc637169 100644 --- a/src/librustc/middle/typeck/infer/doc.rs +++ b/src/librustc/middle/typeck/infer/doc.rs @@ -1,3 +1,13 @@ +// 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. + /*! # Type inference engine diff --git a/src/test/run-pass/issue-4325.rs b/src/test/compile-fail/regions-free-region-ordering-incorrect.rs similarity index 60% rename from src/test/run-pass/issue-4325.rs rename to src/test/compile-fail/regions-free-region-ordering-incorrect.rs index 8e65c15f1c4a..c2bd64fddafc 100644 --- a/src/test/run-pass/issue-4325.rs +++ b/src/test/compile-fail/regions-free-region-ordering-incorrect.rs @@ -8,16 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test that free regions ordering only goes one way. That is, +// we have `&'a Node<'self, T>`, which implies that `'a <= 'self`, +// but not `'self <= 'a`. Hence returning `&self.val` (which has lifetime +// `'a`) where `'self` is expected yields an error. +// +// This test began its life as a test for issue #4325. + struct Node<'self, T> { val: T, next: Option<&'self Node<'self, T>> } impl<'self, T> Node<'self, T> { - fn get(&self) -> &'self T { + fn get<'a>(&'a self) -> &'self T { match self.next { Some(ref next) => next.get(), - None => &self.val + None => &self.val //~ ERROR cannot infer an appropriate lifetime } } } From ef5c439fb006875d3d54b3b100f5411efc2c40f3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 Jul 2013 20:43:42 -0400 Subject: [PATCH 333/336] Correct merge errors, broken tests --- src/librustc/middle/typeck/check/mod.rs | 2 +- .../middle/typeck/infer/error_reporting.rs | 42 +++++++++++++++++-- src/librustc/middle/typeck/infer/mod.rs | 1 + .../typeck/infer/region_inference/mod.rs | 5 ++- src/librustc/util/ppaux.rs | 2 +- src/test/compile-fail/regions-bounds.rs | 4 +- 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 98db885ba422..00ebca5abc14 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -686,7 +686,7 @@ impl FnCtxt { result::Err(RegionError { msg: { fmt!("named region `%s` not in scope here", - bound_region_to_str(self.tcx(), br)) + bound_region_ptr_to_str(self.tcx(), br)) }, replacement: { self.infcx().next_region_var( diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 7217f2979474..e533f019b469 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -59,7 +59,7 @@ time of error detection. */ -use core::prelude::*; +use std::prelude::*; use middle::ty; use middle::ty::Region; use middle::typeck::infer; @@ -80,10 +80,46 @@ use syntax::opt_vec::OptVec; use util::ppaux::UserString; use util::ppaux::note_and_explain_region; -impl InferCtxt { +pub trait ErrorReporting { + pub fn report_region_errors(@mut self, + errors: &OptVec); + + pub fn report_and_explain_type_error(@mut self, + trace: TypeTrace, + terr: &ty::type_err); + + fn values_str(@mut self, values: &ValuePairs) -> Option<~str>; + + fn expected_found_str( + @mut self, + exp_found: &ty::expected_found) + -> Option<~str>; + + fn report_concrete_failure(@mut self, + origin: SubregionOrigin, + sub: Region, + sup: Region); + + fn report_sub_sup_conflict(@mut self, + var_origin: RegionVariableOrigin, + sub_origin: SubregionOrigin, + sub_region: Region, + sup_origin: SubregionOrigin, + sup_region: Region); + + fn report_sup_sup_conflict(@mut self, + var_origin: RegionVariableOrigin, + origin1: SubregionOrigin, + region1: Region, + origin2: SubregionOrigin, + region2: Region); +} + + +impl ErrorReporting for InferCtxt { pub fn report_region_errors(@mut self, errors: &OptVec) { - for errors.each |error| { + for errors.iter().advance |error| { match *error { ConcreteFailure(origin, sub, sup) => { self.report_concrete_failure(origin, sub, sup); diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index bddd0276c6ab..3360edc6a467 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -31,6 +31,7 @@ use middle::typeck::infer::sub::Sub; use middle::typeck::infer::lub::Lub; use middle::typeck::infer::to_str::InferStr; use middle::typeck::infer::unify::{ValsAndBindings, Root}; +use middle::typeck::infer::error_reporting::ErrorReporting; use middle::typeck::isr_alist; use util::common::indent; use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr, diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index b474b95d0fec..96cb5d3c747c 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -36,7 +36,8 @@ mod doc; enum Constraint { ConstrainVarSubVar(RegionVid, RegionVid), ConstrainRegSubVar(Region, RegionVid), - ConstrainVarSubReg(RegionVid, Region) + ConstrainVarSubReg(RegionVid, Region), + ConstrainRegSubReg(Region, Region), } #[deriving(Eq, IterBytes)] @@ -454,7 +455,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/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1a0cdd6fa64f..628940711453 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -610,7 +610,7 @@ impl Repr for @ast::pat { impl Repr for ty::bound_region { fn repr(&self, tcx: ctxt) -> ~str { - bound_region_to_str(tcx, *self) + bound_region_ptr_to_str(tcx, *self) } } diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index f92ea7f18cec..ab2ac6cc0e5b 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -16,12 +16,12 @@ struct an_enum<'self>(&'self int); struct a_class<'self> { x:&'self int } fn a_fn1<'a,'b>(e: an_enum<'a>) -> an_enum<'b> { - return e; //~ ERROR mismatched types: expected `an_enum<'b> ` but found `an_enum<'a> ` + return e; //~ ERROR mismatched types: expected `an_enum<'b>` but found `an_enum<'a>` //~^ ERROR cannot infer an appropriate lifetime } fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> { - return e; //~ ERROR mismatched types: expected `a_class<'b> ` but found `a_class<'a> ` + return e; //~ ERROR mismatched types: expected `a_class<'b>` but found `a_class<'a>` //~^ ERROR cannot infer an appropriate lifetime } From 77b98247a26dcba11bd04f27ff8f5252ecd97df5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 1 Jul 2013 18:33:45 -0700 Subject: [PATCH 334/336] Ignore all rusti tests. #7541 --- src/librusti/rusti.rc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 240247bd6d2e..bbc4b9ff7197 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -511,7 +511,8 @@ pub fn main() { } } -#[cfg(test)] +//#[cfg(test)] +#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile mod tests { use std::io; use std::iterator::IteratorUtil; From 451c94343f2c49cfcc790816fd8587bfdc7ecfb8 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 1 Jul 2013 21:23:36 -0700 Subject: [PATCH 335/336] Ignore all rusti tests harder. #7541 --- src/librusti/rusti.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 2cdcea203cad..f91d99322390 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -511,7 +511,8 @@ pub fn main() { } } -#[cfg(test)] +//#[cfg(test)] +#[cfg(ignore)] // FIXME #7541 doesn't work under cross-compile mod tests { use std::io; use std::iterator::IteratorUtil; From a2db7c15ce9f586164cabb15d83fb3f6bbeb3cf5 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 2 Jul 2013 09:25:44 -0700 Subject: [PATCH 336/336] doc: Update links to 0.7 --- doc/tutorial.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index aa6e90826bbb..d3113703c7cc 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -99,9 +99,9 @@ If you've fulfilled those prerequisites, something along these lines should work. ~~~~ {.notrust} -$ curl -O http://static.rust-lang.org/dist/rust-0.6.tar.gz -$ tar -xzf rust-0.6.tar.gz -$ cd rust-0.6 +$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz +$ tar -xzf rust-0.7.tar.gz +$ cd rust-0.7 $ ./configure $ make && make install ~~~~ @@ -119,8 +119,8 @@ API-documentation tool; `rustpkg`, the Rust package manager; interface for them, and for a few common command line scenarios. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust -[tarball]: http://static.rust-lang.org/dist/rust-0.6.tar.gz -[win-exe]: http://static.rust-lang.org/dist/rust-0.6-install.exe +[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz +[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe ## Compiling your first program