about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-02 07:19:33 +0000
committerbors <bors@rust-lang.org>2015-04-02 07:19:33 +0000
commitcf00fc4da984481a75229ce1e40f339f292d2166 (patch)
tree460e4d59504435411421cf261c5735a726f16942 /src/libcore
parent2e3b0c051dca9880bf66b5366dccd2e0bb424b99 (diff)
parente3b7e6caa25bffcffe6b04f550f551e1ae086f6b (diff)
downloadrust-cf00fc4da984481a75229ce1e40f339f292d2166.tar.gz
rust-cf00fc4da984481a75229ce1e40f339f292d2166.zip
Auto merge of #23963 - alexcrichton:rollup, r=alexcrichton

Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/atomic.rs4
-rw-r--r--src/libcore/cell.rs2
-rw-r--r--src/libcore/fmt/mod.rs13
-rw-r--r--src/libcore/fmt/num.rs2
-rw-r--r--src/libcore/fmt/rt/v1.rs10
-rw-r--r--src/libcore/marker.rs7
-rw-r--r--src/libcore/num/mod.rs6
-rw-r--r--src/libcore/num/wrapping.rs52
-rw-r--r--src/libcore/ops.rs52
-rw-r--r--src/libcore/raw.rs6
-rw-r--r--src/libcore/simd.rs20
-rw-r--r--src/libcore/str/mod.rs4
12 files changed, 126 insertions, 52 deletions
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 8c396a4e7fb..ed35e095492 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -122,7 +122,7 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 /// Rust's memory orderings are [the same as
 /// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync).
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Ordering {
     /// No ordering constraints, only atomic operations.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -161,7 +161,7 @@ pub const ATOMIC_USIZE_INIT: AtomicUsize =
         AtomicUsize { v: UnsafeCell { value: 0, } };
 
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
-const UINT_TRUE: usize = -1;
+const UINT_TRUE: usize = !0;
 
 impl AtomicBool {
     /// Creates a new `AtomicBool`.
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 906c87f3ffd..76e09eedbdf 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -287,7 +287,7 @@ pub enum BorrowState {
 // (will not outgrow its range since `usize` is the size of the address space)
 type BorrowFlag = usize;
 const UNUSED: BorrowFlag = 0;
-const WRITING: BorrowFlag = -1;
+const WRITING: BorrowFlag = !0;
 
 impl<T> RefCell<T> {
     /// Creates a new `RefCell` containing `value`.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 3f8bbeb1feb..be804327663 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -14,6 +14,7 @@
 
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use char::CharExt;
+use clone::Clone;
 use iter::Iterator;
 use marker::{Copy, PhantomData, Sized};
 use mem;
@@ -53,7 +54,7 @@ pub type Result = result::Result<(), Error>;
 /// occurred. Any extra information must be arranged to be transmitted through
 /// some other means.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct Error;
 
 /// A collection of methods that are required to format a message into a stream.
@@ -140,6 +141,12 @@ pub struct ArgumentV1<'a> {
     formatter: fn(&Void, &mut Formatter) -> Result,
 }
 
+impl<'a> Clone for ArgumentV1<'a> {
+    fn clone(&self) -> ArgumentV1<'a> {
+        *self
+    }
+}
+
 impl<'a> ArgumentV1<'a> {
     #[inline(never)]
     fn show_usize(x: &usize, f: &mut Formatter) -> Result {
@@ -174,7 +181,7 @@ impl<'a> ArgumentV1<'a> {
 }
 
 // flags available in the v1 format of format_args
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[allow(dead_code)] // SignMinus isn't currently used
 enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, }
 
@@ -221,7 +228,7 @@ impl<'a> Arguments<'a> {
 /// macro validates the format string at compile-time so usage of the `write`
 /// and `format` functions can be safely performed.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Arguments<'a> {
     // Format string pieces to print.
     pieces: &'a [&'a str],
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index f3f5a0b70cb..76c975902aa 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -139,7 +139,7 @@ impl GenericRadix for Radix {
 /// A helper type for formatting radixes.
 #[unstable(feature = "core",
            reason = "may be renamed or move to a different module")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct RadixFmt<T, R>(T, R);
 
 /// Constructs a radix formatter in the range of `2..36`.
diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs
index 7f6dea905da..d56ec6a74d4 100644
--- a/src/libcore/fmt/rt/v1.rs
+++ b/src/libcore/fmt/rt/v1.rs
@@ -16,7 +16,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Argument {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -25,7 +25,7 @@ pub struct Argument {
     pub format: FormatSpec,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct FormatSpec {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -41,7 +41,7 @@ pub struct FormatSpec {
 }
 
 /// Possible alignments that can be requested as part of a formatting directive.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Alignment {
     /// Indication that contents should be left-aligned.
@@ -58,7 +58,7 @@ pub enum Alignment {
     Unknown,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Count {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -71,7 +71,7 @@ pub enum Count {
     Implied,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Position {
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index d1d9c389942..619f983aee0 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -76,7 +76,7 @@ pub trait Sized : MarkerTrait {
 ///
 /// ```
 /// // we can just derive a `Copy` implementation
-/// #[derive(Debug, Copy)]
+/// #[derive(Debug, Copy, Clone)]
 /// struct Foo;
 ///
 /// let x = Foo;
@@ -125,7 +125,7 @@ pub trait Sized : MarkerTrait {
 /// There are two ways to implement `Copy` on your type:
 ///
 /// ```
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct MyStruct;
 /// ```
 ///
@@ -134,6 +134,7 @@ pub trait Sized : MarkerTrait {
 /// ```
 /// struct MyStruct;
 /// impl Copy for MyStruct {}
+/// impl Clone for MyStruct { fn clone(&self) -> MyStruct { *self } }
 /// ```
 ///
 /// There is a small difference between the two: the `derive` strategy will also place a `Copy`
@@ -155,7 +156,7 @@ pub trait Sized : MarkerTrait {
 /// change: that second example would fail to compile if we made `Foo` non-`Copy`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="copy"]
-pub trait Copy : MarkerTrait {
+pub trait Copy : Clone {
     // Empty.
 }
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 4e458e993a0..28e0bcf13dd 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -516,7 +516,7 @@ macro_rules! uint_impl {
             fn min_value() -> $T { 0 }
 
             #[inline]
-            fn max_value() -> $T { -1 }
+            fn max_value() -> $T { !0 }
 
             #[inline]
             fn count_ones(self) -> u32 {
@@ -1347,7 +1347,7 @@ macro_rules! uint_impl {
 
         /// Returns the largest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
-        pub fn max_value() -> $T { -1 }
+        pub fn max_value() -> $T { !0 }
 
         /// Convert a string slice in a given base to an integer.
         ///
@@ -2444,7 +2444,7 @@ impl_num_cast! { f32,   to_f32 }
 impl_num_cast! { f64,   to_f64 }
 
 /// Used for representing the classification of floating point numbers
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum FpCategory {
     /// "Not a Number", often obtained by dividing by zero
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index a78eed8ae5f..28276d0bf01 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -30,7 +30,7 @@ use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow};
 use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow};
 use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow};
 
-use ::{i8,i16,i32,i64,u8,u16,u32,u64};
+use ::{i8,i16,i32,i64};
 
 #[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
 #[deprecated(since = "1.0.0", reason = "moved to inherent methods")]
@@ -206,7 +206,7 @@ mod shift_max {
     pub const u64: u32 = i64;
 }
 
-macro_rules! overflowing_impl {
+macro_rules! signed_overflowing_impl {
     ($($t:ident)*) => ($(
         impl OverflowingOps for $t {
             #[inline(always)]
@@ -259,7 +259,53 @@ macro_rules! overflowing_impl {
     )*)
 }
 
-overflowing_impl! { u8 u16 u32 u64 i8 i16 i32 i64 }
+macro_rules! unsigned_overflowing_impl {
+    ($($t:ident)*) => ($(
+        impl OverflowingOps for $t {
+            #[inline(always)]
+            fn overflowing_add(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _add_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _sub_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _mul_with_overflow)(self, rhs)
+                }
+            }
+
+            #[inline(always)]
+            fn overflowing_div(self, rhs: $t) -> ($t, bool) {
+                (self/rhs, false)
+            }
+            #[inline(always)]
+            fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
+                (self % rhs, false)
+            }
+
+            #[inline(always)]
+            fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
+                (self << (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+            #[inline(always)]
+            fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
+                (self >> (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+        }
+    )*)
+}
+
+signed_overflowing_impl! { i8 i16 i32 i64 }
+unsigned_overflowing_impl! { u8 u16 u32 u64 }
 
 #[cfg(target_pointer_width = "64")]
 impl OverflowingOps for usize {
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 21af342b1bf..faf305c6a13 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -165,7 +165,7 @@ macro_rules! forward_ref_binop {
 /// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Add for Foo {
@@ -219,7 +219,7 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Sub;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Sub for Foo {
@@ -273,7 +273,7 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Mul;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Mul for Foo {
@@ -327,7 +327,7 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Div;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Div for Foo {
@@ -381,7 +381,7 @@ div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Rem;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Rem for Foo {
@@ -454,7 +454,7 @@ rem_float_impl! { f64, fmod }
 /// ```
 /// use std::ops::Neg;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Neg for Foo {
@@ -482,8 +482,10 @@ pub trait Neg {
     fn neg(self) -> Self::Output;
 }
 
-macro_rules! neg_impl {
-    ($($t:ty)*) => ($(
+
+
+macro_rules! neg_impl_core {
+    ($id:ident => $body:expr, $($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
         #[allow(unsigned_negation)]
         impl Neg for $t {
@@ -492,14 +494,28 @@ macro_rules! neg_impl {
 
             #[inline]
             #[stable(feature = "rust1", since = "1.0.0")]
-            fn neg(self) -> $t { -self }
+            fn neg(self) -> $t { let $id = self; $body }
         }
 
         forward_ref_unop! { impl Neg, neg for $t }
     )*)
 }
 
-neg_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
+macro_rules! neg_impl_numeric {
+    ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
+}
+
+macro_rules! neg_impl_unsigned {
+    ($($t:ty)*) => {
+        neg_impl_core!{ x => {
+            #[cfg(stage0)]
+            use ::num::wrapping::WrappingOps;
+            !x.wrapping_add(1)
+        }, $($t)*} }
+}
+
+// neg_impl_unsigned! { usize u8 u16 u32 u64 }
+neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Not` trait is used to specify the functionality of unary `!`.
 ///
@@ -511,7 +527,7 @@ neg_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Not;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Not for Foo {
@@ -565,7 +581,7 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitAnd;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitAnd for Foo {
@@ -619,7 +635,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitOr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitOr for Foo {
@@ -673,7 +689,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitXor;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitXor for Foo {
@@ -727,7 +743,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::Shl;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shl<Foo> for Foo {
@@ -799,7 +815,7 @@ shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// ```
 /// use std::ops::Shr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shr<Foo> for Foo {
@@ -871,7 +887,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// ```
 /// use std::ops::Index;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
@@ -912,7 +928,7 @@ pub trait Index<Idx: ?Sized> {
 /// ```
 /// use std::ops::{Index, IndexMut};
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 47d1f3a1a3c..ded52ff0778 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -18,6 +18,7 @@
 //!
 //! Their definition should always match the ABI defined in `rustc::back::abi`.
 
+use clone::Clone;
 use marker::Copy;
 use mem;
 
@@ -63,6 +64,9 @@ pub struct Slice<T> {
 }
 
 impl<T> Copy for Slice<T> {}
+impl<T> Clone for Slice<T> {
+    fn clone(&self) -> Slice<T> { *self }
+}
 
 /// The representation of a trait object like `&SomeTrait`.
 ///
@@ -136,7 +140,7 @@ impl<T> Copy for Slice<T> {}
 /// assert_eq!(synthesized.bar(), 457);
 /// ```
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct TraitObject {
     pub data: *mut (),
     pub vtable: *mut (),
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
index 21cff3021ab..7b55ba49a07 100644
--- a/src/libcore/simd.rs
+++ b/src/libcore/simd.rs
@@ -38,7 +38,7 @@
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
                  pub i8, pub i8, pub i8, pub i8,
@@ -47,26 +47,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
                  pub i16, pub i16, pub i16, pub i16);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i64x2(pub i64, pub i64);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
                  pub u8, pub u8, pub u8, pub u8,
@@ -75,31 +75,31 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
                  pub u16, pub u16, pub u16, pub u16);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u64x2(pub u64, pub u64);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct f64x2(pub f64, pub f64);
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index f07c988c2b4..dbb365c4e23 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -855,7 +855,7 @@ impl TwoWaySearcher {
     #[allow(dead_code)]
     #[allow(deprecated)]
     fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) {
-        let mut left: usize = -1; // Corresponds to i in the paper
+        let mut left: usize = !0; // Corresponds to i in the paper
         let mut right = 0; // Corresponds to j in the paper
         let mut offset = 1; // Corresponds to k in the paper
         let mut period = 1; // Corresponds to p in the paper
@@ -1105,7 +1105,7 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [
 /// Struct that contains a `char` and the index of the first byte of
 /// the next `char` in a string.  This can be used as a data structure
 /// for iterating over the UTF-8 bytes of a string.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[unstable(feature = "str_char",
            reason = "existence of this struct is uncertain as it is frequently \
                      able to be replaced with char.len_utf8() and/or \