From 48b6262b383365b7319ef76fa9c6d2c63c4d70e1 Mon Sep 17 00:00:00 2001 From: Jyun-Yan You Date: Sun, 5 May 2013 22:29:10 +0800 Subject: [PATCH 01/13] preliminary Linux ARM support --- mk/platform.mk | 26 ++++++++++++++++++++++++++ mk/rt.mk | 4 ++++ src/librustc/back/arm.rs | 2 +- src/rt/arch/arm/record_sp.S | 8 ++++++++ src/rt/rust_task.h | 3 +++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mk/platform.mk b/mk/platform.mk index e03b7c152478f..78ca57f9c62c0 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -239,6 +239,32 @@ CFG_RUN_arm-linux-androideabi= CFG_RUN_TARG_arm-linux-androideabi= RUSTC_FLAGS_arm-linux-androideabi :=--android-cross-path=$(CFG_ANDROID_CROSS_PATH) +# arm-unknown-linux-gnueabihf configuration +CC_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-gcc +CXX_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-g++ +CPP_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-gcc -E +AR_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-ar +CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so +CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so +CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM +CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC +CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti +CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g +CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list= +CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive +CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive +CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def +CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf = +CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabihf = +CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf := +CFG_WINDOWSY_arm-unknown-linux-gnueabihf := +CFG_UNIXY_arm-unknown-linux-gnueabihf := 1 +CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true +CFG_LDPATH_arm-unknown-linux-gnueabihf := +CFG_RUN_arm-unknown-linux-gnueabihf= +CFG_RUN_TARG_arm-unknown-linux-gnueabihf= +RUSTC_FLAGS_arm-unknown-linux-gnueabihf := --linker=$(CC_arm-unknown-linux-gnueabihf) + # mips-unknown-linux-gnu configuration CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++ diff --git a/mk/rt.mk b/mk/rt.mk index 30dda2fb276c9..e26d7ac517ecf 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -26,7 +26,11 @@ # Hack for passing flags into LIBUV, see below. LIBUV_FLAGS_i386 = -m32 -fPIC LIBUV_FLAGS_x86_64 = -m64 -fPIC +ifeq ($(OSTYPE_$(1)), linux-androideabi) LIBUV_FLAGS_arm = -fPIC -DANDROID -std=gnu99 +else +LIBUV_FLAGS_arm = -fPIC -std=gnu99 +endif LIBUV_FLAGS_mips = -fPIC -mips32r2 -msoft-float -mabi=32 # when we're doing a snapshot build, we intentionally degrade as many diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs index dfe5751f21b83..ff3c71da458a2 100644 --- a/src/librustc/back/arm.rs +++ b/src/librustc/back/arm.rs @@ -64,7 +64,7 @@ pub fn get_target_strs(target_os: session::os) -> target_strs::t { target_triple: match target_os { session::os_macos => ~"arm-apple-darwin", session::os_win32 => ~"arm-pc-mingw32", - session::os_linux => ~"arm-unknown-linux", + session::os_linux => ~"arm-unknown-linux-gnueabihf", session::os_android => ~"arm-linux-androideabi", session::os_freebsd => ~"arm-unknown-freebsd" }, diff --git a/src/rt/arch/arm/record_sp.S b/src/rt/arch/arm/record_sp.S index 95fce8746a118..8d5f24bc5a8c5 100644 --- a/src/rt/arch/arm/record_sp.S +++ b/src/rt/arch/arm/record_sp.S @@ -15,13 +15,21 @@ record_sp_limit: mrc p15, #0, r3, c13, c0, #3 +#if __ANDROID__ add r3, r3, #252 +#elif __linux__ + add r3, r3, #4 +#endif str r0, [r3] mov pc, lr get_sp_limit: mrc p15, #0, r3, c13, c0, #3 +#if __ANDROID__ add r3, r3, #252 +#elif __linux__ + add r3, r3, #4 +#endif ldr r0, [r3] mov pc, lr diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index fd4e8451b642a..6813e3b46c458 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -146,6 +146,9 @@ #ifdef __mips__ #define RED_ZONE_SIZE RZ_LINUX_32 #endif +#ifdef __arm__ +#define RED_ZONE_SIZE RZ_LINUX_32 +#endif #endif #ifdef __APPLE__ #ifdef __i386__ From f7e58ebe84513ed65b1694311f8c4f35e53e8c0e Mon Sep 17 00:00:00 2001 From: gifnksm Date: Fri, 17 May 2013 22:54:32 +0900 Subject: [PATCH 02/13] libcore: Add `IteratorUtil::to_vec()` method --- src/libcore/iterator.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 40c9637f692bc..3811d28b0302d 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -45,6 +45,7 @@ pub trait IteratorUtil { fn advance(&mut self, f: &fn(A) -> bool); #[cfg(not(stage0))] fn advance(&mut self, f: &fn(A) -> bool) -> bool; + fn to_vec(self) -> ~[A]; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -131,6 +132,14 @@ impl> IteratorUtil for T { } } } + + #[inline(always)] + fn to_vec(self) -> ~[A] { + let mut v = ~[]; + let mut it = self; + for it.advance() |x| { v.push(x); } + return v; + } } pub struct ChainIterator { From 9ffbe69234317859ca910fe5c419cacf4089d60b Mon Sep 17 00:00:00 2001 From: gifnksm Date: Fri, 17 May 2013 23:00:48 +0900 Subject: [PATCH 03/13] libcore: Add `IteratorUtil::filter_map` method --- src/libcore/iterator.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 3811d28b0302d..685b4fcac7fc3 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -34,6 +34,7 @@ pub trait IteratorUtil { // FIXME: #5898: should be called map fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>; fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>; + fn filter_map<'r, B>(self, f: &'r fn(A) -> Option) -> FilterMapIterator<'r, A, B, Self>; fn enumerate(self) -> EnumerateIterator; fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>; fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>; @@ -74,6 +75,11 @@ impl> IteratorUtil for T { FilterIterator{iter: self, predicate: predicate} } + #[inline(always)] + fn filter_map<'r, B>(self, f: &'r fn(A) -> Option) -> FilterMapIterator<'r, A, B, T> { + FilterMapIterator { iter: self, f: f } + } + #[inline(always)] fn enumerate(self) -> EnumerateIterator { EnumerateIterator{iter: self, count: 0} @@ -213,6 +219,28 @@ impl<'self, A, T: Iterator> Iterator for FilterIterator<'self, A, T> { } } +pub struct FilterMapIterator<'self, A, B, T> { + priv iter: T, + priv f: &'self fn(A) -> Option +} + +impl<'self, A, B, T: Iterator> Iterator for FilterMapIterator<'self, A, B, T> { + #[inline] + fn next(&mut self) -> Option { + loop { + match self.iter.next() { + None => { return None; } + Some(a) => { + match (self.f)(a) { + Some(b) => { return Some(b); } + None => { loop; } + } + } + } + } + } +} + pub struct EnumerateIterator { priv iter: T, priv count: uint @@ -432,6 +460,13 @@ mod tests { assert_eq!(i, expected.len()); } + #[test] + fn test_filter_map() { + let it = Counter::new(0u, 1u).take(10) + .filter_map(|x: uint| if x.is_even() { Some(x*x) } else { None }); + assert_eq!(it.to_vec(), ~[0*0, 2*2, 4*4, 6*6, 8*8]); + } + #[test] fn test_iterator_enumerate() { let xs = [0u, 1, 2, 3, 4, 5]; From 02945f1cb1524f5791dd244e63a8d9bb2d61ac77 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Fri, 17 May 2013 23:45:25 +0900 Subject: [PATCH 04/13] libcore: Add `IteratoUtil::nth`, `first`, `last` method --- src/libcore/iterator.rs | 81 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 685b4fcac7fc3..14d6083067a9d 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -47,6 +47,9 @@ pub trait IteratorUtil { #[cfg(not(stage0))] fn advance(&mut self, f: &fn(A) -> bool) -> bool; fn to_vec(self) -> ~[A]; + fn nth(&mut self, n: uint) -> A; + fn first(&mut self) -> A; + fn last(&mut self) -> A; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -146,6 +149,41 @@ impl> IteratorUtil for T { for it.advance() |x| { v.push(x); } return v; } + + /// Get `n`th element of an iterator. + #[inline(always)] + fn nth(&mut self, n: uint) -> A { + let mut i = n; + loop { + match self.next() { + Some(x) => { if i == 0 { return x; }} + None => { fail!("cannot get %uth element", n) } + } + i -= 1; + } + } + + // Get first elemet of an iterator. + #[inline(always)] + fn first(&mut self) -> A { + match self.next() { + Some(x) => x , + None => fail!("cannot get first element") + } + } + + // Get last element of an iterator. + // + // If the iterator have an infinite length, this method won't return. + #[inline(always)] + fn last(&mut self) -> A { + let mut elm = match self.next() { + Some(x) => x, + None => fail!("cannot get last element") + }; + for self.advance |e| { elm = e; } + return elm; + } } pub struct ChainIterator { @@ -567,4 +605,47 @@ mod tests { } assert_eq!(i, 10); } + + #[test] + fn test_iterator_nth() { + let v = &[0, 1, 2, 3, 4]; + for uint::range(0, v.len()) |i| { + assert_eq!(v.iter().nth(i), &v[i]); + } + } + + #[test] + #[should_fail] + fn test_iterator_nth_fail() { + let v = &[0, 1, 2, 3, 4]; + v.iter().nth(5); + } + + #[test] + fn test_iterator_first() { + let v = &[0, 1, 2, 3, 4]; + assert_eq!(v.iter().first(), &0); + assert_eq!(v.slice(2, 5).iter().first(), &2); + } + + #[test] + #[should_fail] + fn test_iterator_first_fail() { + let v: &[uint] = &[]; + v.iter().first(); + } + + #[test] + fn test_iterator_last() { + let v = &[0, 1, 2, 3, 4]; + assert_eq!(v.iter().last(), &4); + assert_eq!(v.slice(0, 1).iter().last(), &0); + } + + #[test] + #[should_fail] + fn test_iterator_last_fail() { + let v: &[uint] = &[]; + v.iter().last(); + } } From b4cea351ba9df84efbff56d7bd79cd52704592d6 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Fri, 17 May 2013 23:54:58 +0900 Subject: [PATCH 05/13] libcore: Add `IteratorUtil::fold`, `count` --- src/libcore/iterator.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 14d6083067a9d..58850190d8b1d 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -50,6 +50,8 @@ pub trait IteratorUtil { fn nth(&mut self, n: uint) -> A; fn first(&mut self) -> A; fn last(&mut self) -> A; + fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; + fn count(&mut self) -> uint; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -184,6 +186,23 @@ impl> IteratorUtil for T { for self.advance |e| { elm = e; } return elm; } + + /// Reduce an iterator to an accumulated value + #[inline] + fn fold(&mut self, init: B, f: &fn(B, A) -> B) -> B { + let mut accum = init; + loop { + match self.next() { + Some(x) => { accum = f(accum, x); } + None => { break; } + } + } + return accum; + } + + /// Count the number of an iterator elemenrs + #[inline(always)] + fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } } pub struct ChainIterator { @@ -648,4 +667,12 @@ mod tests { let v: &[uint] = &[]; v.iter().last(); } + + #[test] + fn test_iterator_count() { + 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); + } } From 54fbac505ed13c4afe193c8c4d6212df708e74d0 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sat, 18 May 2013 00:18:09 +0900 Subject: [PATCH 06/13] libcore: Add `AdditiveIterator`, `MultiplicativeIterator`, `OrdIterator` --- src/libcore/iterator.rs | 79 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index 58850190d8b1d..bf2864702963b 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -18,6 +18,7 @@ implementing the `Iterator` trait. */ use prelude::*; +use num::{Zero, One}; pub trait Iterator { /// Advance the iterator and return the next value. Return `None` when the end is reached. @@ -205,6 +206,51 @@ impl> IteratorUtil for T { fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } } +pub trait AdditiveIterator { + fn sum(&mut self) -> A; +} + +impl + Zero, T: Iterator> AdditiveIterator for T { + #[inline(always)] + fn sum(&mut self) -> A { self.fold(Zero::zero::(), |s, x| s + x) } +} + +pub trait MultiplicativeIterator { + fn product(&mut self) -> A; +} + +impl + One, T: Iterator> MultiplicativeIterator for T { + #[inline(always)] + fn product(&mut self) -> A { self.fold(One::one::(), |p, x| p * x) } +} + +pub trait OrdIterator { + fn max(&mut self) -> Option; + fn min(&mut self) -> Option; +} + +impl> OrdIterator for T { + #[inline(always)] + fn max(&mut self) -> Option { + self.fold(None, |max, x| { + match max { + None => Some(x), + Some(y) => Some(cmp::max(x, y)) + } + }) + } + + #[inline(always)] + fn min(&mut self) -> Option { + self.fold(None, |min, x| { + match min { + None => Some(x), + Some(y) => Some(cmp::min(x, y)) + } + }) + } +} + pub struct ChainIterator { priv a: T, priv b: U, @@ -675,4 +721,37 @@ mod tests { assert_eq!(v.slice(0, 10).iter().count(), 10); assert_eq!(v.slice(0, 0).iter().count(), 0); } + + #[test] + fn test_iterator_sum() { + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v.slice(0, 4).iter().transform(|&x| x).sum(), 6); + assert_eq!(v.iter().transform(|&x| x).sum(), 55); + assert_eq!(v.slice(0, 0).iter().transform(|&x| x).sum(), 0); + } + + #[test] + fn test_iterator_product() { + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v.slice(0, 4).iter().transform(|&x| x).product(), 0); + assert_eq!(v.slice(1, 5).iter().transform(|&x| x).product(), 24); + assert_eq!(v.slice(0, 0).iter().transform(|&x| x).product(), 1); + } + + #[test] + fn test_iterator_max() { + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v.slice(0, 4).iter().transform(|&x| x).max(), Some(3)); + assert_eq!(v.iter().transform(|&x| x).max(), Some(10)); + assert_eq!(v.slice(0, 0).iter().transform(|&x| x).max(), None); + } + + #[test] + fn test_iterator_min() { + let v = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert_eq!(v.slice(0, 4).iter().transform(|&x| x).min(), Some(0)); + assert_eq!(v.iter().transform(|&x| x).min(), Some(0)); + assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None); + } + } From 3122d8027bfb38b76a916ef0e7be850da62f6e0b Mon Sep 17 00:00:00 2001 From: gifnksm Date: Sat, 18 May 2013 00:24:43 +0900 Subject: [PATCH 07/13] libcore: Add `IteratorUtil::all`, `any` method --- src/libcore/iterator.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs index bf2864702963b..588bd0bde5343 100644 --- a/src/libcore/iterator.rs +++ b/src/libcore/iterator.rs @@ -53,6 +53,8 @@ pub trait IteratorUtil { fn last(&mut self) -> A; fn fold(&mut self, start: B, f: &fn(B, A) -> B) -> B; fn count(&mut self) -> uint; + fn all(&mut self, f: &fn(&A) -> bool) -> bool; + fn any(&mut self, f: &fn(&A) -> bool) -> bool; } /// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also @@ -204,6 +206,18 @@ impl> IteratorUtil for T { /// Count the number of an iterator elemenrs #[inline(always)] fn count(&mut self) -> uint { self.fold(0, |cnt, _x| cnt + 1) } + + #[inline(always)] + fn all(&mut self, f: &fn(&A) -> bool) -> bool { + for self.advance |x| { if !f(&x) { return false; } } + return true; + } + + #[inline(always)] + fn any(&mut self, f: &fn(&A) -> bool) -> bool { + for self.advance |x| { if f(&x) { return true; } } + return false; + } } pub trait AdditiveIterator { @@ -754,4 +768,21 @@ mod tests { assert_eq!(v.slice(0, 0).iter().transform(|&x| x).min(), None); } + #[test] + fn test_all() { + let v = ~&[1, 2, 3, 4, 5]; + assert!(v.iter().all(|&x| *x < 10)); + assert!(!v.iter().all(|&x| x.is_even())); + assert!(!v.iter().all(|&x| *x > 100)); + assert!(v.slice(0, 0).iter().all(|_| fail!())); + } + + #[test] + fn test_any() { + let v = ~&[1, 2, 3, 4, 5]; + assert!(v.iter().any(|&x| *x < 10)); + assert!(v.iter().any(|&x| x.is_even())); + assert!(!v.iter().any(|&x| *x > 100)); + assert!(!v.slice(0, 0).iter().any(|_| fail!())); + } } From f21fb3aff5c0dbc1129c99ef827150343b425da0 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 17 May 2013 17:27:44 -0700 Subject: [PATCH 08/13] rustc: Cleaning up bad copies and other XXXes --- src/librustc/middle/trans/build.rs | 2 +- src/librustc/middle/trans/closure.rs | 5 ++--- src/librustc/middle/trans/common.rs | 2 +- src/librustc/middle/trans/datum.rs | 2 +- src/librustc/middle/trans/expr.rs | 12 ++++++------ src/librustc/middle/trans/foreign.rs | 3 +-- src/librustc/middle/trans/glue.rs | 5 ++--- src/librustc/middle/trans/meth.rs | 13 ++++++------- src/librustc/middle/trans/monomorphize.rs | 10 ++++------ src/librustc/middle/trans/reflect.rs | 11 +++++------ src/librustc/middle/trans/type_of.rs | 7 +++---- src/librustc/middle/ty.rs | 4 ---- src/librustc/middle/typeck/check/method.rs | 4 ++-- src/librustc/middle/typeck/check/mod.rs | 1 - src/librustc/middle/typeck/infer/combine.rs | 4 +++- 15 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index e8853fd20e98b..38f8d271f08b3 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -602,7 +602,7 @@ 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() // -// XXX: Use a small-vector optimization to avoid allocations here. +// FIXME #6571: Use a small-vector optimization to avoid allocations here. 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"); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 0651d3443b56a..c6fa42cb8cbd3 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -137,7 +137,7 @@ pub fn mk_tuplified_uniq_cbox_ty(tcx: ty::ctxt, cdata_ty: ty::t) -> ty::t { // Given a closure ty, emits a corresponding tuple ty pub fn mk_closure_tys(tcx: ty::ctxt, - bound_values: ~[EnvValue]) + bound_values: &[EnvValue]) -> ty::t { // determine the types of the values in the env. Note that this // is the actual types that will be stored in the map, not the @@ -203,8 +203,7 @@ pub fn store_environment(bcx: block, let ccx = bcx.ccx(), tcx = ccx.tcx; // compute the shape of the closure - // XXX: Bad copy. - let cdata_ty = mk_closure_tys(tcx, copy bound_values); + let cdata_ty = mk_closure_tys(tcx, bound_values); // allocate closure in the heap let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, sigil, cdata_ty); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 8000484c0550f..547b54a6ef50f 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1325,7 +1325,7 @@ pub fn is_null(val: ValueRef) -> bool { // Used to identify cached monomorphized functions and vtables #[deriving(Eq)] pub enum mono_param_id { - mono_precise(ty::t, Option<~[mono_id]>), + mono_precise(ty::t, Option<@~[mono_id]>), mono_any, mono_repr(uint /* size */, uint /* align */, diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 8055d919ffd9a..13f02b8fcac1d 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -652,7 +652,7 @@ pub impl Datum { ByRef => { // Recast lv.val as a pointer to the newtype rather // than a pointer to the struct type. - // XXX: This isn't correct for structs with + // FIXME #6572: This isn't correct for structs with // destructors. ( Some(Datum { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 59526ffbe498d..3ed08eade33a4 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -576,7 +576,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, }; } ast::expr_struct(_, ref fields, base) => { - return trans_rec_or_struct(bcx, (*fields), base, expr.id, dest); + return trans_rec_or_struct(bcx, (*fields), base, expr.span, expr.id, dest); } ast::expr_tup(ref args) => { let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr)); @@ -721,7 +721,7 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr, } ast::def_struct(*) => { // Nothing to do here. - // XXX: May not be true in the case of classes with destructors. + // FIXME #6572: May not be true in the case of classes with destructors. return bcx; } _ => { @@ -1129,6 +1129,7 @@ pub fn with_field_tys(tcx: ty::ctxt, fn trans_rec_or_struct(bcx: block, fields: &[ast::field], base: Option<@ast::expr>, + expr_span: codemap::span, id: ast::node_id, dest: Dest) -> block { @@ -1167,8 +1168,7 @@ fn trans_rec_or_struct(bcx: block, } None => { if need_base.any(|b| *b) { - // XXX should be span bug - tcx.sess.bug(~"missing fields and no base expr") + tcx.sess.span_bug(expr_span, ~"missing fields and no base expr") } None } @@ -1232,8 +1232,8 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, temp_cleanups.push(dest); } for optbase.each |base| { - // XXX is it sound to use the destination's repr on the base? - // XXX would it ever be reasonable to be here with discr != 0? + // FIXME #6573: is it sound to use the destination's repr on the base? + // And, would it ever be reasonable to be here with discr != 0? let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base.expr)); for base.fields.each |&(i, t)| { let datum = do base_datum.get_element(bcx, t, ZeroMem) |srcval| { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index fd545ca2c6ea8..13d8f854fb20f 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -550,14 +550,13 @@ pub fn trans_intrinsic(ccx: @CrateContext, let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); - // XXX: Bad copy. let fcx = new_fn_ctxt_w_id(ccx, path, decl, item.id, output_type, None, - Some(copy substs), + Some(substs), Some(item.span)); // Set the fixed stack segment flag if necessary. diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 585d9d8420cd7..f8aa3eca28476 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -669,7 +669,7 @@ pub fn declare_tydesc(ccx: @CrateContext, t: ty::t) -> @mut tydesc_info { let llsize = llsize_of(ccx, llty); let llalign = llalign_of(ccx, llty); let addrspace = declare_tydesc_addrspace(ccx, t); - //XXX this triggers duplicate LLVM symbols + // FIXME #6574: this triggers duplicate LLVM symbols let name = @(if false /*ccx.sess.opts.debuginfo*/ { mangle_internal_name_by_type_only(ccx, t, "tydesc") } else { @@ -703,14 +703,13 @@ pub fn declare_generic_glue(ccx: @CrateContext, t: ty::t, llfnty: TypeRef, name: ~str) -> ValueRef { let _icx = ccx.insn_ctxt("declare_generic_glue"); let name = name; - //XXX this triggers duplicate LLVM symbols + // FIXME #6574 this triggers duplicate LLVM symbols let fn_nm = @(if false /*ccx.sess.opts.debuginfo*/ { mangle_internal_name_by_type_only(ccx, t, (~"glue_" + name)) } else { mangle_internal_name_by_seq(ccx, (~"glue_" + name)) }); debug!("%s is for type %s", *fn_nm, ppaux::ty_to_str(ccx.tcx, t)); - // XXX: Bad copy. note_unique_llvm_symbol(ccx, fn_nm); let llfn = decl_cdecl_fn(ccx.llmod, *fn_nm, llfnty); set_glue_inlining(llfn, t); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 6eb2540f1df65..337e2a13b1fde 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -401,7 +401,7 @@ pub fn method_with_name_or_default(ccx: @CrateContext, Some(pmis) => { for pmis.each |pmi| { if pmi.method_info.ident == name { - debug!("XXX %?", pmi.method_info.did); + debug!("pmi.method_info.did = %?", pmi.method_info.did); return pmi.method_info.did; } } @@ -734,15 +734,15 @@ pub fn trans_trait_callee_from_llval(bcx: block, } pub fn vtable_id(ccx: @CrateContext, - origin: typeck::vtable_origin) + origin: &typeck::vtable_origin) -> mono_id { match origin { - typeck::vtable_static(impl_id, substs, sub_vtables) => { + &typeck::vtable_static(impl_id, ref substs, sub_vtables) => { monomorphize::make_mono_id( ccx, impl_id, - substs, - if (*sub_vtables).len() == 0u { + *substs, + if sub_vtables.is_empty() { None } else { Some(sub_vtables) @@ -759,8 +759,7 @@ pub fn vtable_id(ccx: @CrateContext, pub fn get_vtable(ccx: @CrateContext, origin: typeck::vtable_origin) -> ValueRef { - // XXX: Bad copy. - let hash_id = vtable_id(ccx, copy origin); + let hash_id = vtable_id(ccx, &origin); match ccx.vtables.find(&hash_id) { Some(&val) => val, None => match origin { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index ccc906f2ee8af..40b92d336536c 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -70,8 +70,7 @@ pub fn monomorphic_fn(ccx: @CrateContext, for real_substs.each() |s| { assert!(!ty::type_has_params(*s)); } for substs.each() |s| { assert!(!ty::type_has_params(*s)); } let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); - // XXX: Bad copy. - let hash_id = make_mono_id(ccx, fn_id, copy substs, vtables, impl_did_opt, + let hash_id = make_mono_id(ccx, fn_id, substs, vtables, impl_did_opt, Some(param_uses)); if vec::any(hash_id.params, |p| match *p { mono_precise(_, _) => false, _ => true }) { @@ -350,10 +349,10 @@ pub fn make_mono_id(ccx: @CrateContext, 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| { - v.push(meth::vtable_id(ccx, /*bad*/copy vts[i])); + v.push(meth::vtable_id(ccx, &vts[i])); i += 1; } - (*subst, if !v.is_empty() { Some(v) } else { None }) + (*subst, if !v.is_empty() { Some(@v) } else { None }) }) } None => { @@ -369,8 +368,7 @@ pub fn make_mono_id(ccx: @CrateContext, } } else { match *id { - // XXX: Bad copy. - (a, copy b@Some(_)) => mono_precise(a, b), + (a, b@Some(_)) => mono_precise(a, b), (subst, None) => { if *uses == 0 { mono_any diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 1141e0c007fee..0e82de86bc6dd 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -84,7 +84,7 @@ pub impl Reflector { self.c_tydesc(mt.ty)] } - fn visit(&mut self, ty_name: ~str, args: ~[ValueRef]) { + 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), @@ -121,10 +121,9 @@ pub impl Reflector { fn bracketed(&mut self, bracket_name: ~str, - extra: ~[ValueRef], + extra: &[ValueRef], inner: &fn(&mut Reflector)) { - // XXX: Bad copy. - self.visit(~"enter_" + bracket_name, copy extra); + self.visit(~"enter_" + bracket_name, extra); inner(self); self.visit(~"leave_" + bracket_name, extra); } @@ -226,7 +225,7 @@ pub impl Reflector { self.c_uint(sigilval), self.c_uint(fty.sig.inputs.len()), self.c_uint(retval)]; - self.visit(~"enter_fn", copy extra); // XXX: Bad copy. + self.visit(~"enter_fn", extra); self.visit_sig(retval, &fty.sig); self.visit(~"leave_fn", extra); } @@ -241,7 +240,7 @@ pub impl Reflector { self.c_uint(sigilval), self.c_uint(fty.sig.inputs.len()), self.c_uint(retval)]; - self.visit(~"enter_fn", copy extra); // XXX: Bad copy. + self.visit(~"enter_fn", extra); self.visit_sig(retval, &fty.sig); self.visit(~"leave_fn", extra); } diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index dfbebd90c298b..8d5721aeb6512 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -45,7 +45,7 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t) if !output_is_immediate { atys.push(T_ptr(lloutputtype)); } else { - // XXX: Eliminate this. + // FIXME #6575: Eliminate this. atys.push(T_ptr(T_i8())); } @@ -200,7 +200,6 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { return llty; } - // XXX: This is a terrible terrible copy. let llty = match ty::get(t).sty { ty::ty_nil | ty::ty_bot => T_nil(), ty::ty_bool => T_bool(), @@ -219,7 +218,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { common::T_named_struct(llvm_type_name(cx, an_enum, did, - /*bad*/copy substs.tps)) + substs.tps)) } ty::ty_estr(ty::vstore_box) => { T_box_ptr(T_box(cx, T_vec(cx, T_i8()))) @@ -280,7 +279,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef { T_named_struct(llvm_type_name(cx, a_struct, did, - /*bad*/ copy substs.tps)) + substs.tps)) } } ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c51fba8a62b71..bb18948ce5d54 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -681,7 +681,6 @@ pub enum type_err { terr_trait_stores_differ(terr_vstore_kind, expected_found), terr_in_field(@type_err, ast::ident), terr_sorts(expected_found), - terr_self_substs, terr_integer_as_char, terr_int_mismatch(expected_found), terr_float_mismatch(expected_found), @@ -3722,9 +3721,6 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { values.found.user_string(cx)) } } - terr_self_substs => { - ~"inconsistent self substitution" // XXX this is more of a bug - } terr_integer_as_char => { fmt!("expected an integral type but found char") } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 9e8103f4527f6..7655212d9d64e 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -438,7 +438,7 @@ pub impl<'self> LookupContext<'self> { return; // inapplicable } ast::sty_region(_) => vstore_slice(r) - ast::sty_box(_) => vstore_box, // XXX NDM mutability + ast::sty_box(_) => vstore_box, // NDM mutability, as per #5762 ast::sty_uniq(_) => vstore_uniq } */ @@ -594,7 +594,7 @@ pub impl<'self> LookupContext<'self> { let method = ty::method(self.tcx(), provided_method_info.method_info.did); - // XXX: Needs to support generics. + // FIXME #4099 (?) Needs to support generics. let dummy_substs = substs { self_r: None, self_ty: None, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 8d32bb7f67756..6e272b9410f49 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1817,7 +1817,6 @@ 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| { - // XXX: Check visibility here. class_field_map.insert(field.ident, (field.id, false)); } diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 3c337d17f8684..0efecefa3580e 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -286,7 +286,9 @@ pub fn super_self_tys( // I think it should never happen that we unify two substs and // one of them has a self_ty and one doesn't...? I could be // wrong about this. - Err(ty::terr_self_substs) + this.infcx().tcx.sess.bug( + fmt!("substitution a had a self_ty and substitution b didn't, \ + or vice versa")); } } } From a10974da2db2e483f21e337f0c9a8a1e1c4c81ed Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sat, 18 May 2013 15:02:58 +1000 Subject: [PATCH 09/13] Use cond! macro where appropriate --- src/libcore/num/f32.rs | 16 ++++++++++++++-- src/libcore/num/f64.rs | 16 ++++++++++++++-- src/libcore/num/int-template.rs | 12 ++++++++++++ src/libcore/num/uint-template.rs | 12 ++++++++++++ src/libcore/unicode.rs | 28 ++++++++++++++++++++++++++-- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 4a3ec3528f28b..d580f7aa26c99 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -248,8 +248,7 @@ impl Orderable for f32 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) } } - /// Returns the number constrained within the range `mn <= self <= mx`. - /// If any of the numbers are `NaN` then `NaN` is returned. + #[cfg(stage0)] #[inline(always)] fn clamp(&self, mn: &f32, mx: &f32) -> f32 { if self.is_NaN() { *self } @@ -257,6 +256,19 @@ impl Orderable for f32 { else if !(*self >= *mn) { *mn } else { *self } } + + /// Returns the number constrained within the range `mn <= self <= mx`. + /// If any of the numbers are `NaN` then `NaN` is returned. + #[cfg(not(stage0))] + #[inline(always)] + fn clamp(&self, mn: &f32, mx: &f32) -> f32 { + cond!( + (self.is_NaN()) { *self } + (!(*self <= *mx)) { *mx } + (!(*self >= *mn)) { *mn } + _ { *self } + ) + } } impl Zero for f32 { diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index e370f43a0037e..d140df30c4273 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -270,8 +270,7 @@ impl Orderable for f64 { if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) } } - /// Returns the number constrained within the range `mn <= self <= mx`. - /// If any of the numbers are `NaN` then `NaN` is returned. + #[cfg(stage0)] #[inline(always)] fn clamp(&self, mn: &f64, mx: &f64) -> f64 { if self.is_NaN() { *self } @@ -279,6 +278,19 @@ impl Orderable for f64 { else if !(*self >= *mn) { *mn } else { *self } } + + /// Returns the number constrained within the range `mn <= self <= mx`. + /// If any of the numbers are `NaN` then `NaN` is returned. + #[cfg(not(stage0))] + #[inline(always)] + fn clamp(&self, mn: &f64, mx: &f64) -> f64 { + cond!( + (self.is_NaN()) { *self } + (!(*self <= *mx)) { *mx } + (!(*self >= *mn)) { *mn } + _ { *self } + ) + } } impl Zero for f64 { diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 348f72f9f0a74..d0e6174ec637d 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -187,11 +187,23 @@ impl Orderable for T { if *self > *other { *self } else { *other } } + #[cfg(stage0)] #[inline(always)] fn clamp(&self, mn: &T, mx: &T) -> T { if *self > *mx { *mx } else if *self < *mn { *mn } else { *self } } + + /// Returns the number constrained within the range `mn <= self <= mx`. + #[cfg(not(stage0))] + #[inline(always)] + fn clamp(&self, mn: &T, mx: &T) -> T { + cond!( + (*self > *mx) { *mx } + (*self < *mn) { *mn } + _ { *self } + ) + } } impl Zero for T { diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index da0815c264b06..f3e140945057c 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -153,11 +153,23 @@ impl Orderable for T { if *self > *other { *self } else { *other } } + #[cfg(stage0)] #[inline(always)] fn clamp(&self, mn: &T, mx: &T) -> T { if *self > *mx { *mx } else if *self < *mn { *mn } else { *self } } + + /// Returns the number constrained within the range `mn <= self <= mx`. + #[cfg(not(stage0))] + #[inline(always)] + fn clamp(&self, mn: &T, mx: &T) -> T { + cond!( + (*self > *mx) { *mx } + (*self < *mn) { *mn } + _ { *self } + ) + } } impl Zero for T { diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs index d6e2c5eee6aca..3b7fdcc85be2f 100644 --- a/src/libcore/unicode.rs +++ b/src/libcore/unicode.rs @@ -14,6 +14,7 @@ pub mod general_category { + #[cfg(stage0)] fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; use vec::bsearch; @@ -25,6 +26,18 @@ pub mod general_category { }) != None } + #[cfg(not(stage0))] + 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)| { cond!( + (lo <= c && c <= hi) { Equal } + (hi < c) { Less } + _ { Greater } + )}) != None + } + static Cc_table : &'static [(char,char)] = &[ ('\x00', '\x1f'), ('\x7f', '\x9f') @@ -1449,8 +1462,7 @@ pub mod general_category { } pub mod derived_property { - - + #[cfg(stage0)] fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use cmp::{Equal, Less, Greater}; use vec::bsearch; @@ -1462,6 +1474,18 @@ pub mod derived_property { }) != None } + #[cfg(not(stage0))] + 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)| { cond!( + (lo <= c && c <= hi) { Equal } + (hi < c) { Less } + _ { Greater } + )}) != None + } + static Alphabetic_table : &'static [(char,char)] = &[ ('\x41', '\x5a'), ('\x61', '\x7a'), From 728fe775a28b780d2bb26982992d5aab7623ba13 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sat, 18 May 2013 16:27:54 +1000 Subject: [PATCH 10/13] Use pattern-matching instead of conditionals where appropriate to improve code clarity --- src/libcore/bool.rs | 10 ++--- src/libcore/path.rs | 100 +++++++++++++++++++------------------------- src/libcore/str.rs | 84 ++++++++++++++++--------------------- 3 files changed, 81 insertions(+), 113 deletions(-) diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 76a8f456cd5f3..b3c0b8cad7a4e 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -49,12 +49,10 @@ pub fn is_false(v: bool) -> bool { !v } /// Parse logic value from `s` impl FromStr for bool { fn from_str(s: &str) -> Option { - if s == "true" { - Some(true) - } else if s == "false" { - Some(false) - } else { - None + match s { + "true" => Some(true), + "false" => Some(false), + _ => None, } } } diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 2015c5474be32..c359b657cd3d7 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -311,9 +311,10 @@ pub impl Path { unsafe { do str::as_c_str(self.to_str()) |buf| { let mut st = stat::arch::default_stat(); - let r = libc::stat(buf, &mut st); - - if r == 0 { Some(st) } else { None } + match libc::stat(buf, &mut st) { + 0 => Some(st), + _ => None, + } } } } @@ -323,9 +324,10 @@ pub impl Path { unsafe { do str::as_c_str(self.to_str()) |buf| { let mut st = stat::arch::default_stat(); - let r = libc::lstat(buf, &mut st); - - if r == 0 { Some(st) } else { None } + match libc::lstat(buf, &mut st) { + 0 => Some(st), + _ => None, + } } } } @@ -456,10 +458,9 @@ impl GenericPath for PosixPath { fn dirname(&self) -> ~str { let s = self.dir_path().to_str(); - if s.len() == 0 { - ~"." - } else { - s + match s.len() { + 0 => ~".", + _ => s, } } @@ -515,25 +516,18 @@ impl GenericPath for PosixPath { } fn with_filetype(&self, t: &str) -> PosixPath { - if t.len() == 0 { - match self.filestem() { - None => copy *self, - Some(ref s) => self.with_filename(*s) - } - } else { - let t = ~"." + str::to_owned(t); - match self.filestem() { - None => self.with_filename(t), - Some(ref s) => self.with_filename(*s + t) - } + match (t.len(), self.filestem()) { + (0, None) => copy *self, + (0, Some(ref s)) => self.with_filename(*s), + (_, None) => self.with_filename(fmt!(".%s", t)), + (_, Some(ref s)) => self.with_filename(fmt!("%s.%s", *s, t)), } } fn dir_path(&self) -> PosixPath { - if self.components.len() != 0 { - self.pop() - } else { - copy *self + match self.components.len() { + 0 => copy *self, + _ => self.pop(), } } @@ -638,26 +632,25 @@ impl GenericPath for WindowsPath { let device; let rest; - match windows::extract_drive_prefix(s) { - Some((ref d, ref r)) => { - host = None; - device = Some(copy *d); - rest = copy *r; - } - None => { - match windows::extract_unc_prefix(s) { - Some((ref h, ref r)) => { + match ( + windows::extract_drive_prefix(s), + windows::extract_unc_prefix(s), + ) { + (Some((ref d, ref r)), _) => { + host = None; + device = Some(copy *d); + rest = copy *r; + } + (None, Some((ref h, ref r))) => { host = Some(copy *h); device = None; rest = copy *r; - } - None => { + } + (None, None) => { host = None; device = None; rest = str::to_owned(s); - } } - } } let mut components = ~[]; @@ -673,10 +666,9 @@ impl GenericPath for WindowsPath { fn dirname(&self) -> ~str { let s = self.dir_path().to_str(); - if s.len() == 0 { - ~"." - } else { - s + match s.len() { + 0 => ~".", + _ => s, } } @@ -732,26 +724,18 @@ impl GenericPath for WindowsPath { } fn with_filetype(&self, t: &str) -> WindowsPath { - if t.len() == 0 { - match self.filestem() { - None => copy *self, - Some(ref s) => self.with_filename(*s) - } - } else { - let t = ~"." + str::to_owned(t); - match self.filestem() { - None => self.with_filename(t), - Some(ref s) => - self.with_filename(*s + t) - } + match (t.len(), self.filestem()) { + (0, None) => copy *self, + (0, Some(ref s)) => self.with_filename(*s), + (_, None) => self.with_filename(fmt!(".%s", t)), + (_, Some(ref s)) => self.with_filename(fmt!("%s.%s", *s, t)), } } fn dir_path(&self) -> WindowsPath { - if self.components.len() != 0 { - self.pop() - } else { - copy *self + match self.components.len() { + 0 => copy *self, + _ => self.pop(), } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index ec7177e52114e..59f769fd92d42 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -128,57 +128,43 @@ pub fn push_char(s: &mut ~str, ch: char) { let off = len; do as_buf(*s) |buf, _len| { let buf: *mut u8 = ::cast::transmute(buf); - if nb == 1u { - *ptr::mut_offset(buf, off) = - code as u8; - } else if nb == 2u { - *ptr::mut_offset(buf, off) = - (code >> 6u & 31u | tag_two_b) as u8; - *ptr::mut_offset(buf, off + 1u) = - (code & 63u | tag_cont) as u8; - } else if nb == 3u { - *ptr::mut_offset(buf, off) = - (code >> 12u & 15u | tag_three_b) as u8; - *ptr::mut_offset(buf, off + 1u) = - (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = - (code & 63u | tag_cont) as u8; - } else if nb == 4u { - *ptr::mut_offset(buf, off) = - (code >> 18u & 7u | tag_four_b) as u8; - *ptr::mut_offset(buf, off + 1u) = - (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = - (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = - (code & 63u | tag_cont) as u8; - } else if nb == 5u { - *ptr::mut_offset(buf, off) = - (code >> 24u & 3u | tag_five_b) as u8; - *ptr::mut_offset(buf, off + 1u) = - (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = - (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = - (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = - (code & 63u | tag_cont) as u8; - } else if nb == 6u { - *ptr::mut_offset(buf, off) = - (code >> 30u & 1u | tag_six_b) as u8; - *ptr::mut_offset(buf, off + 1u) = - (code >> 24u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = - (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = - (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = - (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 5u) = - (code & 63u | tag_cont) as u8; + match nb { + 1u => { + *ptr::mut_offset(buf, off) = code as u8; + } + 2u => { + *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8; + } + 3u => { + *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8; + } + 4u => { + *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8; + } + 5u => { + *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8; + } + 6u => { + *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8; + } + _ => {} } } - raw::set_len(s, new_len); } } From 60ea6d6957697ac6ced355e8a1db5ab6be439765 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sat, 18 May 2013 16:50:23 +1000 Subject: [PATCH 11/13] Convert various inner doc-comments to outer doc-comments --- src/libcore/cmp.rs | 3 +- src/libcore/either.rs | 62 +++++++++++++++--------------------------- src/libcore/managed.rs | 4 +-- src/libcore/option.rs | 16 ++++------- 4 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 80f1f05961a5d..ca9c49b2c0682 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -127,12 +127,11 @@ totalord_impl!(uint) totalord_impl!(char) +/// Compares (a1, b1) against (a2, b2), where the a values are more significant. pub fn cmp2( a1: &A, b1: &B, a2: &A, b2: &B) -> Ordering { - //! Compares (a1, b1) against (a2, b2), where the a values are more significant. - match a1.cmp(a2) { Less => Less, Greater => Greater, diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 8c16f5c64824f..ab52822849cfb 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -26,26 +26,22 @@ pub enum Either { Right(U) } +/// Applies a function based on the given either value +/// +/// If `value` is left(T) then `f_left` is applied to its contents, if +/// `value` is right(U) then `f_right` is applied to its contents, and the +/// result is returned. #[inline(always)] pub fn either(f_left: &fn(&T) -> V, f_right: &fn(&U) -> V, value: &Either) -> V { - /*! - * Applies a function based on the given either value - * - * If `value` is left(T) then `f_left` is applied to its contents, if - * `value` is right(U) then `f_right` is applied to its contents, and the - * result is returned. - */ - match *value { Left(ref l) => f_left(l), Right(ref r) => f_right(r) } } +/// Extracts from a vector of either all the left values pub fn lefts(eithers: &[Either]) -> ~[T] { - //! Extracts from a vector of either all the left values - do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { @@ -56,9 +52,8 @@ pub fn lefts(eithers: &[Either]) -> ~[T] { } } +/// Extracts from a vector of either all the right values pub fn rights(eithers: &[Either]) -> ~[U] { - //! Extracts from a vector of either all the right values - do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { @@ -69,15 +64,11 @@ pub fn rights(eithers: &[Either]) -> ~[U] { } } -pub fn partition(eithers: ~[Either]) - -> (~[T], ~[U]) { - /*! - * Extracts from a vector of either all the left values and right values - * - * Returns a structure containing a vector of left values and a vector of - * right values. - */ - +/// Extracts from a vector of either all the left values and right values +/// +/// Returns a structure containing a vector of left values and a vector of +/// right values. +pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { let mut lefts: ~[T] = ~[]; let mut rights: ~[U] = ~[]; do vec::consume(eithers) |_i, elt| { @@ -89,60 +80,51 @@ pub fn partition(eithers: ~[Either]) return (lefts, rights); } +/// Flips between left and right of a given either #[inline(always)] pub fn flip(eith: Either) -> Either { - //! Flips between left and right of a given either - match eith { Right(r) => Left(r), Left(l) => Right(l) } } +/// Converts either::t to a result::t +/// +/// Converts an `either` type to a `result` type, making the "right" choice +/// an ok result, and the "left" choice a fail #[inline(always)] -pub fn to_result(eith: Either) - -> Result { - /*! - * Converts either::t to a result::t - * - * Converts an `either` type to a `result` type, making the "right" choice - * an ok result, and the "left" choice a fail - */ - +pub fn to_result(eith: Either) -> Result { match eith { Right(r) => result::Ok(r), Left(l) => result::Err(l) } } +/// Checks whether the given value is a left #[inline(always)] pub fn is_left(eith: &Either) -> bool { - //! Checks whether the given value is a left - match *eith { Left(_) => true, _ => false } } +/// Checks whether the given value is a right #[inline(always)] pub fn is_right(eith: &Either) -> bool { - //! Checks whether the given value is a right - match *eith { Right(_) => true, _ => false } } +/// Retrieves the value in the left branch. Fails if the either is Right. #[inline(always)] pub fn unwrap_left(eith: Either) -> T { - //! Retrieves the value in the left branch. Fails if the either is Right. - match eith { Left(x) => x, Right(_) => fail!("either::unwrap_left Right") } } +/// Retrieves the value in the right branch. Fails if the either is Left. #[inline(always)] pub fn unwrap_right(eith: Either) -> U { - //! Retrieves the value in the right branch. Fails if the either is Left. - match eith { Right(x) => x, Left(_) => fail!("either::unwrap_right Left") diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index d2bb88ca30202..ecde1eb19179d 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -35,16 +35,16 @@ pub mod raw { } +/// Determine if two shared boxes point to the same object #[inline(always)] pub fn ptr_eq(a: @T, b: @T) -> bool { - //! Determine if two shared boxes point to the same object let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b); a_ptr == b_ptr } +/// Determine if two mutable shared boxes point to the same object #[inline(always)] pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { - //! Determine if two mutable shared boxes point to the same object let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b); a_ptr == b_ptr } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 5aee3077e4866..e1bd72f67f16f 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -182,12 +182,10 @@ pub impl Option { #[inline(always)] fn is_some(&const self) -> bool { !self.is_none() } + /// Update an optional value by optionally running its content through a + /// function that returns an option. #[inline(always)] fn chain(self, f: &fn(t: T) -> Option) -> Option { - /*! - * Update an optional value by optionally running its content through a - * function that returns an option. - */ match self { Some(t) => f(t), @@ -195,21 +193,17 @@ pub impl Option { } } + /// Returns the leftmost Some() value, or None if both are None. #[inline(always)] fn or(self, optb: Option) -> Option { - /*! - * Returns the leftmost Some() value, or None if both are None. - */ match self { Some(opta) => Some(opta), _ => optb } } - /** - * Update an optional value by optionally running its content by reference - * through a function that returns an option. - */ + /// Update an optional value by optionally running its content by reference + /// through a function that returns an option. #[inline(always)] fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option) -> Option { match *self { Some(ref x) => f(x), None => None } From ad6ee5f4e5f779d987ac7a35ce6f149039a45b15 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sat, 18 May 2013 16:52:11 +1000 Subject: [PATCH 12/13] Use four-space indentation, add trailing commas, and remove unnecessary uses of the return keyword --- src/libcore/either.rs | 26 +++++--- src/libcore/option.rs | 4 +- src/libcore/path.rs | 145 ++++++++++++++++++++++-------------------- 3 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/libcore/either.rs b/src/libcore/either.rs index ab52822849cfb..f89bb3b2f9064 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -35,8 +35,8 @@ pub enum Either { pub fn either(f_left: &fn(&T) -> V, f_right: &fn(&U) -> V, value: &Either) -> V { match *value { - Left(ref l) => f_left(l), - Right(ref r) => f_right(r) + Left(ref l) => f_left(l), + Right(ref r) => f_right(r) } } @@ -73,8 +73,8 @@ pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { let mut rights: ~[U] = ~[]; do vec::consume(eithers) |_i, elt| { match elt { - Left(l) => lefts.push(l), - Right(r) => rights.push(r) + Left(l) => lefts.push(l), + Right(r) => rights.push(r) } } return (lefts, rights); @@ -84,8 +84,8 @@ pub fn partition(eithers: ~[Either]) -> (~[T], ~[U]) { #[inline(always)] pub fn flip(eith: Either) -> Either { match eith { - Right(r) => Left(r), - Left(l) => Right(l) + Right(r) => Left(r), + Left(l) => Right(l) } } @@ -96,21 +96,27 @@ pub fn flip(eith: Either) -> Either { #[inline(always)] pub fn to_result(eith: Either) -> Result { match eith { - Right(r) => result::Ok(r), - Left(l) => result::Err(l) + Right(r) => result::Ok(r), + Left(l) => result::Err(l) } } /// Checks whether the given value is a left #[inline(always)] pub fn is_left(eith: &Either) -> bool { - match *eith { Left(_) => true, _ => false } + match *eith { + Left(_) => true, + _ => false + } } /// Checks whether the given value is a right #[inline(always)] pub fn is_right(eith: &Either) -> bool { - match *eith { Right(_) => true, _ => false } + match *eith { + Right(_) => true, + _ => false + } } /// Retrieves the value in the left branch. Fails if the either is Right. diff --git a/src/libcore/option.rs b/src/libcore/option.rs index e1bd72f67f16f..0212d4abd29d6 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -89,11 +89,11 @@ impl Ord for Option { } fn ge(&self, other: &Option) -> bool { - ! (self < other) + !(self < other) } fn gt(&self, other: &Option) -> bool { - ! (self <= other) + !(self <= other) } } diff --git a/src/libcore/path.rs b/src/libcore/path.rs index c359b657cd3d7..8a5d9c0416d07 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -452,8 +452,10 @@ impl GenericPath for PosixPath { components.push(s.to_owned()) } let is_absolute = (s.len() != 0 && s[0] == '/' as u8); - return PosixPath { is_absolute: is_absolute, - components: components } + PosixPath { + is_absolute: is_absolute, + components: components, + } } fn dirname(&self) -> ~str { @@ -466,40 +468,40 @@ impl GenericPath for PosixPath { fn filename(&self) -> Option<~str> { match self.components.len() { - 0 => None, - n => Some(copy self.components[n - 1]) + 0 => None, + n => Some(copy self.components[n - 1]), } } fn filestem(&self) -> Option<~str> { match self.filename() { - None => None, - Some(ref f) => { - match str::rfind_char(*f, '.') { - Some(p) => Some(f.slice(0, p).to_owned()), - None => Some(copy *f) + None => None, + Some(ref f) => { + match str::rfind_char(*f, '.') { + Some(p) => Some(f.slice(0, p).to_owned()), + None => Some(copy *f), + } } - } } } fn filetype(&self) -> Option<~str> { match self.filename() { - None => None, - Some(ref f) => { - match str::rfind_char(*f, '.') { - Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), - _ => None + None => None, + Some(ref f) => { + match str::rfind_char(*f, '.') { + Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), + _ => None, + } } - } } } fn with_dirname(&self, d: &str) -> PosixPath { let dpath = PosixPath(d); match self.filename() { - Some(ref f) => dpath.push(*f), - None => dpath + Some(ref f) => dpath.push(*f), + None => dpath, } } @@ -510,8 +512,8 @@ impl GenericPath for PosixPath { fn with_filestem(&self, s: &str) -> PosixPath { match self.filetype() { - None => self.with_filename(s), - Some(ref t) => self.with_filename(str::to_owned(s) + *t) + None => self.with_filename(s), + Some(ref t) => self.with_filename(str::to_owned(s) + *t), } } @@ -536,8 +538,10 @@ impl GenericPath for PosixPath { None => ~[], Some(ref f) => ~[copy *f] }; - return PosixPath { is_absolute: false, - components: cs } + PosixPath { + is_absolute: false, + components: cs, + } } fn push_rel(&self, other: &PosixPath) -> PosixPath { @@ -547,8 +551,10 @@ impl GenericPath for PosixPath { fn unsafe_join(&self, other: &PosixPath) -> PosixPath { if other.is_absolute { - PosixPath { is_absolute: true, - components: copy other.components } + PosixPath { + is_absolute: true, + components: copy other.components, + } } else { self.push_rel(other) } @@ -567,8 +573,10 @@ impl GenericPath for PosixPath { } v.push_all_move(ss); } - PosixPath { is_absolute: self.is_absolute, - components: v } + PosixPath { + is_absolute: self.is_absolute, + components: v, + } } fn push(&self, s: &str) -> PosixPath { @@ -586,19 +594,17 @@ impl GenericPath for PosixPath { if cs.len() != 0 { cs.pop(); } - return PosixPath { + PosixPath { is_absolute: self.is_absolute, - components: cs - } - //..self } + components: cs, + } //..self } } fn normalize(&self) -> PosixPath { - return PosixPath { + PosixPath { is_absolute: self.is_absolute, - components: normalize(self.components) - // ..self - } + components: normalize(self.components), + } // ..self } } fn is_absolute(&self) -> bool { @@ -658,10 +664,12 @@ impl GenericPath for WindowsPath { components.push(s.to_owned()) } let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0])); - return WindowsPath { host: host, - device: device, - is_absolute: is_absolute, - components: components } + WindowsPath { + host: host, + device: device, + is_absolute: is_absolute, + components: components, + } } fn dirname(&self) -> ~str { @@ -674,20 +682,20 @@ impl GenericPath for WindowsPath { fn filename(&self) -> Option<~str> { match self.components.len() { - 0 => None, - n => Some(copy self.components[n - 1]) + 0 => None, + n => Some(copy self.components[n - 1]), } } fn filestem(&self) -> Option<~str> { match self.filename() { - None => None, - Some(ref f) => { - match str::rfind_char(*f, '.') { - Some(p) => Some(f.slice(0, p).to_owned()), - None => Some(copy *f) + None => None, + Some(ref f) => { + match str::rfind_char(*f, '.') { + Some(p) => Some(f.slice(0, p).to_owned()), + None => Some(copy *f), + } } - } } } @@ -696,8 +704,8 @@ impl GenericPath for WindowsPath { None => None, Some(ref f) => { match str::rfind_char(*f, '.') { - Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), - _ => None + Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()), + _ => None, } } } @@ -706,8 +714,8 @@ impl GenericPath for WindowsPath { fn with_dirname(&self, d: &str) -> WindowsPath { let dpath = WindowsPath(d); match self.filename() { - Some(ref f) => dpath.push(*f), - None => dpath + Some(ref f) => dpath.push(*f), + None => dpath, } } @@ -718,8 +726,8 @@ impl GenericPath for WindowsPath { fn with_filestem(&self, s: &str) -> WindowsPath { match self.filetype() { - None => self.with_filename(s), - Some(ref t) => self.with_filename(str::to_owned(s) + *t) + None => self.with_filename(s), + Some(ref t) => self.with_filename(str::to_owned(s) + *t), } } @@ -740,14 +748,15 @@ impl GenericPath for WindowsPath { } fn file_path(&self) -> WindowsPath { - let cs = match self.filename() { - None => ~[], - Some(ref f) => ~[copy *f] - }; - return WindowsPath { host: None, - device: None, - is_absolute: false, - components: cs } + WindowsPath { + host: None, + device: None, + is_absolute: false, + components: match self.filename() { + None => ~[], + Some(ref f) => ~[copy *f], + } + } } fn push_rel(&self, other: &WindowsPath) -> WindowsPath { @@ -768,7 +777,7 @@ impl GenericPath for WindowsPath { host: Some(host), device: copy other.device, is_absolute: true, - components: copy other.components + components: copy other.components, }; } _ => {} @@ -781,7 +790,7 @@ impl GenericPath for WindowsPath { host: None, device: Some(device), is_absolute: true, - components: copy other.components + components: copy other.components, }; } _ => {} @@ -793,7 +802,7 @@ impl GenericPath for WindowsPath { host: copy self.host, device: copy self.device, is_absolute: self.is_absolute || other.is_absolute, - components: copy other.components + components: copy other.components, } } @@ -822,7 +831,7 @@ impl GenericPath for WindowsPath { v.push_all_move(ss); } // tedious, but as-is, we can't use ..self - return WindowsPath { + WindowsPath { host: copy self.host, device: copy self.device, is_absolute: self.is_absolute, @@ -837,7 +846,7 @@ impl GenericPath for WindowsPath { ss.push(s.to_owned()) } v.push_all_move(ss); - return WindowsPath { components: v, ..copy *self } + WindowsPath { components: v, ..copy *self } } fn pop(&self) -> WindowsPath { @@ -845,16 +854,16 @@ impl GenericPath for WindowsPath { if cs.len() != 0 { cs.pop(); } - return WindowsPath { + WindowsPath { host: copy self.host, device: copy self.device, is_absolute: self.is_absolute, - components: cs + components: cs, } } fn normalize(&self) -> WindowsPath { - return WindowsPath { + WindowsPath { host: copy self.host, device: match self.device { None => None, From 6742f91192da67324b33cf882383a283a2599f7b Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Sat, 18 May 2013 18:59:16 +1000 Subject: [PATCH 13/13] Create tuple element accessor traits --- src/libcore/prelude.rs | 2 + src/libcore/tuple.rs | 165 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 4ed648161fc22..77371b6336848 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -52,6 +52,8 @@ pub use from_str::{FromStr}; pub use to_bytes::IterBytes; pub use to_str::{ToStr, ToStrConsume}; pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps}; +pub use tuple::{Tuple2, Tuple3, Tuple4, Tuple5, Tuple6, Tuple7, Tuple8, Tuple9}; +pub use tuple::{Tuple10, Tuple11, Tuple12}; pub use vec::{CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector, MutableVector}; diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index b29a4e55426df..810ef75ad6a31 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -246,6 +246,154 @@ impl Ord for (A, B, C) { fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self)) } } +// Tuple element accessor traits + +macro_rules! n_tuple( + ($name:ident: $($method:ident : $T:ident),+) => ( + pub trait $name<$($T),+> { + $(fn $method(&self) -> $T;)+ + } + ) +) + +n_tuple!(Tuple2: _0:A, _1:B) +n_tuple!(Tuple3: _0:A, _1:B, _2:C) +n_tuple!(Tuple4: _0:A, _1:B, _2:C, _3:D) +n_tuple!(Tuple5: _0:A, _1:B, _2:C, _3:D, _4:E) +n_tuple!(Tuple6: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F) +n_tuple!(Tuple7: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G) +n_tuple!(Tuple8: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G, _7:H) +n_tuple!(Tuple9: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G, _7:H, _8:I) +n_tuple!(Tuple10: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G, _7:H, _8:I, _9:J) +n_tuple!(Tuple11: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G, _7:H, _8:I, _9:J, _10:K) +n_tuple!(Tuple12: _0:A, _1:B, _2:C, _3:D, _4:E, _5:F, _6:G, _7:H, _8:I, _9:J, _10:K, _11:L) + +// Tuple element accessor trait implementations + +macro_rules! impl_n_tuple( + ($name:ident: $($method:ident -> $T:ident { $accessor:pat => $t:expr })+) => ( + impl<$($T:Copy),+> $name<$($T),+> for ($($T),+) { + $( + fn $method(&self) -> $T { + match *self { + $accessor => $t + } + } + )+ + } + ) +) + +impl_n_tuple!(Tuple2: + _0 -> A { (a,_) => a } + _1 -> B { (_,b) => b } +) + +impl_n_tuple!(Tuple3: + _0 -> A { (a,_,_) => a } + _1 -> B { (_,b,_) => b } + _2 -> C { (_,_,c) => c } +) + +impl_n_tuple!(Tuple4: + _0 -> A { (a,_,_,_) => a } + _1 -> B { (_,b,_,_) => b } + _2 -> C { (_,_,c,_) => c } + _3 -> D { (_,_,_,d) => d } +) + +impl_n_tuple!(Tuple5: + _0 -> A { (a,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_) => b } + _2 -> C { (_,_,c,_,_) => c } + _3 -> D { (_,_,_,d,_) => d } + _4 -> E { (_,_,_,_,e) => e } +) + +impl_n_tuple!(Tuple6: + _0 -> A { (a,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_) => d } + _4 -> E { (_,_,_,_,e,_) => e } + _5 -> F { (_,_,_,_,_,f) => f } +) + +impl_n_tuple!(Tuple7: + _0 -> A { (a,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_) => f } + _6 -> G { (_,_,_,_,_,_,g) => g } +) + +impl_n_tuple!(Tuple8: + _0 -> A { (a,_,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_,_) => f } + _6 -> G { (_,_,_,_,_,_,g,_) => g } + _7 -> H { (_,_,_,_,_,_,_,h) => h } +) + +impl_n_tuple!(Tuple9: + _0 -> A { (a,_,_,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_,_,_) => f } + _6 -> G { (_,_,_,_,_,_,g,_,_) => g } + _7 -> H { (_,_,_,_,_,_,_,h,_) => h } + _8 -> I { (_,_,_,_,_,_,_,_,i) => i } +) + +impl_n_tuple!(Tuple10: + _0 -> A { (a,_,_,_,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_,_,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_,_,_,_) => f } + _6 -> G { (_,_,_,_,_,_,g,_,_,_) => g } + _7 -> H { (_,_,_,_,_,_,_,h,_,_) => h } + _8 -> I { (_,_,_,_,_,_,_,_,i,_) => i } + _9 -> J { (_,_,_,_,_,_,_,_,_,j) => j } +) + +impl_n_tuple!(Tuple11: + _0 -> A { (a,_,_,_,_,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_,_,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_,_,_,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_,_,_,_,_) => f } + _6 -> G { (_,_,_,_,_,_,g,_,_,_,_) => g } + _7 -> H { (_,_,_,_,_,_,_,h,_,_,_) => h } + _8 -> I { (_,_,_,_,_,_,_,_,i,_,_) => i } + _9 -> J { (_,_,_,_,_,_,_,_,_,j,_) => j } + _10 -> K { (_,_,_,_,_,_,_,_,_,_,k) => k } +) + +impl_n_tuple!(Tuple12: + _0 -> A { (a,_,_,_,_,_,_,_,_,_,_,_) => a } + _1 -> B { (_,b,_,_,_,_,_,_,_,_,_,_) => b } + _2 -> C { (_,_,c,_,_,_,_,_,_,_,_,_) => c } + _3 -> D { (_,_,_,d,_,_,_,_,_,_,_,_) => d } + _4 -> E { (_,_,_,_,e,_,_,_,_,_,_,_) => e } + _5 -> F { (_,_,_,_,_,f,_,_,_,_,_,_) => f } + _6 -> G { (_,_,_,_,_,_,g,_,_,_,_,_) => g } + _7 -> H { (_,_,_,_,_,_,_,h,_,_,_,_) => h } + _8 -> I { (_,_,_,_,_,_,_,_,i,_,_,_) => i } + _9 -> J { (_,_,_,_,_,_,_,_,_,j,_,_) => j } + _10 -> K { (_,_,_,_,_,_,_,_,_,_,k,_) => k } + _11 -> L { (_,_,_,_,_,_,_,_,_,_,_,l) => l } +) + #[test] fn test_tuple_ref() { let x = (~"foo", ~"bar"); @@ -268,3 +416,20 @@ fn test_clone() { assert!(a.first() == b.first()); assert!(a.second() == b.second()); } + +#[test] +fn test_n_tuple() { + let t = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64); + assert_eq!(t._0(), 0u8); + assert_eq!(t._1(), 1u16); + assert_eq!(t._2(), 2u32); + assert_eq!(t._3(), 3u64); + assert_eq!(t._4(), 4u); + assert_eq!(t._5(), 5i8); + assert_eq!(t._6(), 6i16); + assert_eq!(t._7(), 7i32); + assert_eq!(t._8(), 8i64); + assert_eq!(t._9(), 9i); + assert_eq!(t._10(), 10f32); + assert_eq!(t._11(), 11f64); +}