diff --git a/src/libcore/float.rs b/src/libcore/float.rs index 098e82f5fad..dd46d30d6ba 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -91,7 +91,7 @@ pub mod consts { * * digits - The number of significant digits * * exact - Whether to enforce the exact number of significant digits */ -pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { +pub pure fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { if is_NaN(num) { return ~"NaN"; } if num == infinity { return ~"inf"; } if num == neg_infinity { return ~"-inf"; } @@ -125,7 +125,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { // store the next digit frac *= 10.0; let digit = frac as uint; - fractionalParts.push(digit); + // Bleh: not really unsafe. + unsafe { fractionalParts.push(digit); } // calculate the next frac frac -= digit as float; @@ -140,7 +141,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { // turn digits into string // using stack of digits while fractionalParts.is_not_empty() { - let mut adjusted_digit = carry + fractionalParts.pop(); + // Bleh; shouldn't need to be unsafe + let mut adjusted_digit = carry + unsafe { fractionalParts.pop() }; if adjusted_digit == 10 { carry = 1; @@ -196,7 +198,7 @@ pub fn test_to_str_exact_do_decimal() { * * num - The float value * * digits - The number of significant digits */ -pub fn to_str(num: float, digits: uint) -> ~str { +pub pure fn to_str(num: float, digits: uint) -> ~str { to_str_common(num, digits, false) } @@ -361,7 +363,7 @@ pub fn from_str(num: &str) -> Option { * * `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow` */ -pub fn pow_with_uint(base: uint, pow: uint) -> float { +pub pure fn pow_with_uint(base: uint, pow: uint) -> float { if base == 0u { if pow == 0u { return NaN as float; diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index 8cb689fd286..0ea7e1d2944 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -154,7 +154,7 @@ impl T : FromStr { } /// Convert to a string in a given base -pub fn to_str(n: T, radix: uint) -> ~str { +pub pure fn to_str(n: T, radix: uint) -> ~str { do to_str_bytes(n, radix) |slice| { do vec::as_imm_buf(slice) |p, len| { unsafe { str::raw::from_buf_len(p, len) } @@ -162,7 +162,7 @@ pub fn to_str(n: T, radix: uint) -> ~str { } } -pub fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { if n < 0 as T { uint::to_str_bytes(true, -n as uint, radix, f) } else { @@ -171,7 +171,7 @@ pub fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { } /// Convert to a string -pub fn str(i: T) -> ~str { return to_str(i, 10u); } +pub pure fn str(i: T) -> ~str { return to_str(i, 10u); } // FIXME: Has alignment issues on windows and 32-bit linux (#2609) #[test] diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 6d023ed1bfb..e5d2397da0d 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -61,7 +61,7 @@ pub pure fn Path(s: &str) -> Path { } impl PosixPath : ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { let mut s = ~""; if self.is_absolute { s += "/"; @@ -236,7 +236,7 @@ impl PosixPath : GenericPath { impl WindowsPath : ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { let mut s = ~""; match self.host { Some(ref h) => { s += "\\\\"; s += *h; } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 1256e5b5617..aff4c50cfd2 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -49,7 +49,7 @@ pub pure fn from_byte(b: u8) -> ~str { } /// Appends a character at the end of a string -pub fn push_char(s: &const ~str, ch: char) { +pub fn push_char(s: &mut ~str, ch: char) { unsafe { let code = ch as uint; let nb = if code < max_one_b { 1u } @@ -140,7 +140,7 @@ pub pure fn from_chars(chs: &[char]) -> ~str { /// Appends a string slice to the back of a string, without overallocating #[inline(always)] -pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) { +pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) { unsafe { let llen = lhs.len(); let rlen = rhs.len(); @@ -157,7 +157,7 @@ pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) { } /// Appends a string slice to the back of a string #[inline(always)] -pub fn push_str(lhs: &const ~str, rhs: &str) { +pub fn push_str(lhs: &mut ~str, rhs: &str) { unsafe { let llen = lhs.len(); let rlen = rhs.len(); @@ -214,7 +214,7 @@ Section: Adding to and removing from a string * * If the string does not contain any characters */ -pub fn pop_char(s: &const ~str) -> char { +pub fn pop_char(s: &mut ~str) -> char { let end = len(*s); assert end > 0u; let {ch, prev} = char_range_at_reverse(*s, end); @@ -1802,9 +1802,9 @@ pub pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { * * s - A string * * n - The number of bytes to reserve space for */ -pub fn reserve(s: &const ~str, n: uint) { +pub fn reserve(s: &mut ~str, n: uint) { unsafe { - let v: *mut ~[u8] = cast::transmute(copy s); + let v: *mut ~[u8] = cast::transmute(s); vec::reserve(&mut *v, n + 1); } } @@ -1829,7 +1829,7 @@ pub fn reserve(s: &const ~str, n: uint) { * * s - A string * * n - The number of bytes to reserve space for */ -pub fn reserve_at_least(s: &const ~str, n: uint) { +pub fn reserve_at_least(s: &mut ~str, n: uint) { reserve(s, uint::next_power_of_two(n + 1u) - 1u) } @@ -1974,7 +1974,7 @@ pub mod raw { } /// Appends a byte to a string. (Not UTF-8 safe). - pub unsafe fn push_byte(s: &const ~str, b: u8) { + pub unsafe fn push_byte(s: &mut ~str, b: u8) { reserve_at_least(s, s.len() + 1); do as_buf(*s) |buf, len| { let buf: *mut u8 = ::cast::reinterpret_cast(&buf); @@ -1984,13 +1984,13 @@ pub mod raw { } /// Appends a vector of bytes to a string. (Not UTF-8 safe). - unsafe fn push_bytes(s: &const ~str, bytes: &[u8]) { + unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) { reserve_at_least(s, s.len() + bytes.len()); for vec::each(bytes) |byte| { push_byte(s, *byte); } } /// Removes the last byte from a string and returns it. (Not UTF-8 safe). - pub unsafe fn pop_byte(s: &const ~str) -> u8 { + pub unsafe fn pop_byte(s: &mut ~str) -> u8 { let len = len(*s); assert (len > 0u); let b = s[len - 1u]; @@ -2008,7 +2008,7 @@ pub mod raw { } /// Sets the length of the string and adds the null terminator - pub unsafe fn set_len(v: &const ~str, new_len: uint) { + pub unsafe fn set_len(v: &mut ~str, new_len: uint) { let v: **vec::raw::VecRepr = cast::transmute(copy v); let repr: *vec::raw::VecRepr = *v; (*repr).unboxed.fill = new_len + 1u; diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index a3659937ad4..fb0608906a1 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -8,80 +8,82 @@ The `ToStr` trait for converting to strings #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -pub trait ToStr { fn to_str() -> ~str; } +pub trait ToStr { pure fn to_str() -> ~str; } impl int: ToStr { - fn to_str() -> ~str { int::str(self) } + pure fn to_str() -> ~str { int::str(self) } } impl i8: ToStr { - fn to_str() -> ~str { i8::str(self) } + pure fn to_str() -> ~str { i8::str(self) } } impl i16: ToStr { - fn to_str() -> ~str { i16::str(self) } + pure fn to_str() -> ~str { i16::str(self) } } impl i32: ToStr { - fn to_str() -> ~str { i32::str(self) } + pure fn to_str() -> ~str { i32::str(self) } } impl i64: ToStr { - fn to_str() -> ~str { i64::str(self) } + pure fn to_str() -> ~str { i64::str(self) } } impl uint: ToStr { - fn to_str() -> ~str { uint::str(self) } + pure fn to_str() -> ~str { uint::str(self) } } impl u8: ToStr { - fn to_str() -> ~str { u8::str(self) } + pure fn to_str() -> ~str { u8::str(self) } } impl u16: ToStr { - fn to_str() -> ~str { u16::str(self) } + pure fn to_str() -> ~str { u16::str(self) } } impl u32: ToStr { - fn to_str() -> ~str { u32::str(self) } + pure fn to_str() -> ~str { u32::str(self) } } impl u64: ToStr { - fn to_str() -> ~str { u64::str(self) } + pure fn to_str() -> ~str { u64::str(self) } } impl float: ToStr { - fn to_str() -> ~str { float::to_str(self, 4u) } + pure fn to_str() -> ~str { float::to_str(self, 4u) } } impl f32: ToStr { - fn to_str() -> ~str { float::to_str(self as float, 4u) } + pure fn to_str() -> ~str { float::to_str(self as float, 4u) } } impl f64: ToStr { - fn to_str() -> ~str { float::to_str(self as float, 4u) } + pure fn to_str() -> ~str { float::to_str(self as float, 4u) } } impl bool: ToStr { - fn to_str() -> ~str { bool::to_str(self) } + pure fn to_str() -> ~str { bool::to_str(self) } } impl (): ToStr { - fn to_str() -> ~str { ~"()" } + pure fn to_str() -> ~str { ~"()" } } impl ~str: ToStr { - fn to_str() -> ~str { copy self } + pure fn to_str() -> ~str { copy self } } impl &str: ToStr { - fn to_str() -> ~str { str::from_slice(self) } + pure fn to_str() -> ~str { str::from_slice(self) } } impl @str: ToStr { - fn to_str() -> ~str { str::from_slice(self) } + pure fn to_str() -> ~str { str::from_slice(self) } } impl (A, B): ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { let (a, b) = self; ~"(" + a.to_str() + ~", " + b.to_str() + ~")" } } impl (A, B, C): ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { let (a, b, c) = self; ~"(" + a.to_str() + ~", " + b.to_str() + ~", " + c.to_str() + ~")" } } impl ~[A]: ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str unsafe { + // Bleh -- not really unsafe + // push_str and push_char let mut acc = ~"[", first = true; - for vec::each(self) |elt| { + for vec::each(self) |elt| unsafe { if first { first = false; } else { str::push_str(&mut acc, ~", "); } str::push_str(&mut acc, elt.to_str()); @@ -92,10 +94,10 @@ impl ~[A]: ToStr { } impl @A: ToStr { - fn to_str() -> ~str { ~"@" + (*self).to_str() } + pure fn to_str() -> ~str { ~"@" + (*self).to_str() } } impl ~A: ToStr { - fn to_str() -> ~str { ~"~" + (*self).to_str() } + pure fn to_str() -> ~str { ~"~" + (*self).to_str() } } #[cfg(test)] diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index 7d0421c0730..00dd9be76db 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -232,7 +232,7 @@ pub pure fn to_str_bytes(neg: bool, num: T, radix: uint, } /// Convert to a string -pub fn str(i: T) -> ~str { return to_str(i, 10u); } +pub pure fn str(i: T) -> ~str { return to_str(i, 10u); } #[test] pub fn test_to_str() { diff --git a/src/libstd/json.rs b/src/libstd/json.rs index fa7c0286dc1..bb331240b76 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -51,7 +51,7 @@ fn escape_str(s: &str) -> ~str { fn spaces(n: uint) -> ~str { let mut ss = ~""; - for n.times { str::push_str(&ss, " "); } + for n.times { str::push_str(&mut ss, " "); } return ss; } @@ -302,7 +302,8 @@ pub fn to_writer(wr: io::Writer, json: &Json) { } /// Serializes a json value into a string -pub fn to_str(json: &Json) -> ~str { +pub pure fn to_str(json: &Json) -> ~str unsafe { + // ugh, should be safe io::with_str_writer(|wr| to_writer(wr, json)) } @@ -546,14 +547,14 @@ priv impl Parser { if (escape) { match self.ch { - '"' => str::push_char(&res, '"'), - '\\' => str::push_char(&res, '\\'), - '/' => str::push_char(&res, '/'), - 'b' => str::push_char(&res, '\x08'), - 'f' => str::push_char(&res, '\x0c'), - 'n' => str::push_char(&res, '\n'), - 'r' => str::push_char(&res, '\r'), - 't' => str::push_char(&res, '\t'), + '"' => str::push_char(&mut res, '"'), + '\\' => str::push_char(&mut res, '\\'), + '/' => str::push_char(&mut res, '/'), + 'b' => str::push_char(&mut res, '\x08'), + 'f' => str::push_char(&mut res, '\x0c'), + 'n' => str::push_char(&mut res, '\n'), + 'r' => str::push_char(&mut res, '\r'), + 't' => str::push_char(&mut res, '\t'), 'u' => { // Parse \u1234. let mut i = 0u; @@ -582,7 +583,7 @@ priv impl Parser { ~"invalid \\u escape (not four digits)"); } - str::push_char(&res, n as char); + str::push_char(&mut res, n as char); } _ => return self.error(~"invalid escape") } @@ -594,7 +595,7 @@ priv impl Parser { self.bump(); return Ok(res); } - str::push_char(&res, self.ch); + str::push_char(&mut res, self.ch); } } @@ -1166,11 +1167,11 @@ impl Option: ToJson { } impl Json: to_str::ToStr { - fn to_str() -> ~str { to_str(&self) } + pure fn to_str() -> ~str { to_str(&self) } } impl Error: to_str::ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { fmt!("%u:%u: %s", self.line, self.col, *self.msg) } } diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 765d40339d3..9f78f98fa31 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -341,7 +341,8 @@ pub mod chained { wr.write_str(~" }"); } - fn to_str() -> ~str { + pure fn to_str() -> ~str unsafe { + // Meh -- this should be safe do io::with_str_writer |wr| { self.to_writer(wr) } } } diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 0ab4d89f363..c3fd3383979 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -94,7 +94,8 @@ pub fn encode(s: &str) -> ~str { * * This function is compliant with RFC 3986. */ -pub fn encode_component(s: &str) -> ~str { + +fn encode_component(s: &str) -> ~str { encode_inner(s, false) } @@ -297,7 +298,7 @@ fn userinfo_from_str(uinfo: &str) -> UserInfo { return UserInfo(user, pass); } -fn userinfo_to_str(userinfo: UserInfo) -> ~str { +pure fn userinfo_to_str(userinfo: UserInfo) -> ~str { if option::is_some(&userinfo.pass) { return str::concat(~[copy userinfo.user, ~":", option::unwrap(copy userinfo.pass), @@ -325,11 +326,15 @@ fn query_from_str(rawquery: &str) -> Query { return query; } -pub fn query_to_str(query: Query) -> ~str { +pub pure fn query_to_str(query: Query) -> ~str { let mut strvec = ~[]; for query.each |kv| { let (k, v) = copy *kv; - strvec += ~[#fmt("%s=%s", encode_component(k), encode_component(v))]; + // This is really safe... + unsafe { + strvec += ~[#fmt("%s=%s", + encode_component(k), encode_component(v))]; + } }; return str::connect(strvec, ~"&"); } @@ -672,7 +677,7 @@ impl Url : FromStr { * result in just "http://somehost.com". * */ -pub fn to_str(url: Url) -> ~str { +pub pure fn to_str(url: Url) -> ~str { let user = if url.user.is_some() { userinfo_to_str(option::unwrap(copy url.user)) } else { @@ -688,7 +693,8 @@ pub fn to_str(url: Url) -> ~str { } else { str::concat(~[~"?", query_to_str(url.query)]) }; - let fragment = if url.fragment.is_some() { + // ugh, this really is safe + let fragment = if url.fragment.is_some() unsafe { str::concat(~[~"#", encode_component( option::unwrap(copy url.fragment))]) } else { @@ -704,7 +710,7 @@ pub fn to_str(url: Url) -> ~str { } impl Url: to_str::ToStr { - pub fn to_str() -> ~str { + pub pure fn to_str() -> ~str { to_str(self) } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 6d58d209fcf..a501df4c32d 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -18,7 +18,7 @@ impl direction : cmp::Eq { } impl direction: ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { match self { send => ~"Send", recv => ~"Recv" diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index 12d63cdacbf..3ae0727de60 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -195,11 +195,11 @@ fn check_crate(tcx: ty::ctxt, } impl LiveNode: to_str::ToStr { - fn to_str() -> ~str { fmt!("ln(%u)", *self) } + pure fn to_str() -> ~str { fmt!("ln(%u)", *self) } } impl Variable: to_str::ToStr { - fn to_str() -> ~str { fmt!("v(%u)", *self) } + pure fn to_str() -> ~str { fmt!("v(%u)", *self) } } // ______________________________________________________________________ diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/auxiliary/cci_class_cast.rs index 288fe66dd20..ca2af387587 100644 --- a/src/test/auxiliary/cci_class_cast.rs +++ b/src/test/auxiliary/cci_class_cast.rs @@ -13,7 +13,7 @@ struct cat { } impl cat : ToStr { - fn to_str() -> ~str { self.name } + pure fn to_str() -> ~str { self.name } } priv impl cat { diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index c7517ab1b3d..8a51eb33857 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -45,7 +45,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { } impl cat: ToStr { - fn to_str() -> ~str { self.name } + pure fn to_str() -> ~str { self.name } } fn print_out(thing: T, expected: ~str) { diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 6d771dc7386..4bb2c561422 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -16,7 +16,7 @@ enum square { } impl square: to_str::ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { match self { bot => { ~"R" } wall => { ~"#" }