Skip to content

Commit 5a8ba07

Browse files
committed
Make to_str pure and fix const parameters for str-mutating functions
Two separate changes that got intertwined (sorry): Make to_str pure. Closes #3691 In str, change functions like push_char to take an &mut str instead of an &str. Closes #3710
1 parent 41bce91 commit 5a8ba07

File tree

14 files changed

+87
-75
lines changed

14 files changed

+87
-75
lines changed

src/libcore/float.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub mod consts {
9191
* * digits - The number of significant digits
9292
* * exact - Whether to enforce the exact number of significant digits
9393
*/
94-
pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
94+
pub pure fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
9595
if is_NaN(num) { return ~"NaN"; }
9696
if num == infinity { return ~"inf"; }
9797
if num == neg_infinity { return ~"-inf"; }
@@ -125,7 +125,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
125125
// store the next digit
126126
frac *= 10.0;
127127
let digit = frac as uint;
128-
fractionalParts.push(digit);
128+
// Bleh: not really unsafe.
129+
unsafe { fractionalParts.push(digit); }
129130

130131
// calculate the next frac
131132
frac -= digit as float;
@@ -140,7 +141,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
140141
// turn digits into string
141142
// using stack of digits
142143
while fractionalParts.is_not_empty() {
143-
let mut adjusted_digit = carry + fractionalParts.pop();
144+
// Bleh; shouldn't need to be unsafe
145+
let mut adjusted_digit = carry + unsafe { fractionalParts.pop() };
144146

145147
if adjusted_digit == 10 {
146148
carry = 1;
@@ -196,7 +198,7 @@ pub fn test_to_str_exact_do_decimal() {
196198
* * num - The float value
197199
* * digits - The number of significant digits
198200
*/
199-
pub fn to_str(num: float, digits: uint) -> ~str {
201+
pub pure fn to_str(num: float, digits: uint) -> ~str {
200202
to_str_common(num, digits, false)
201203
}
202204

@@ -361,7 +363,7 @@ pub fn from_str(num: &str) -> Option<float> {
361363
*
362364
* `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
363365
*/
364-
pub fn pow_with_uint(base: uint, pow: uint) -> float {
366+
pub pure fn pow_with_uint(base: uint, pow: uint) -> float {
365367
if base == 0u {
366368
if pow == 0u {
367369
return NaN as float;

src/libcore/int-template.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ impl T : FromStr {
154154
}
155155

156156
/// Convert to a string in a given base
157-
pub fn to_str(n: T, radix: uint) -> ~str {
157+
pub pure fn to_str(n: T, radix: uint) -> ~str {
158158
do to_str_bytes(n, radix) |slice| {
159159
do vec::as_imm_buf(slice) |p, len| {
160160
unsafe { str::raw::from_buf_len(p, len) }
161161
}
162162
}
163163
}
164164

165-
pub fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
165+
pub pure fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
166166
if n < 0 as T {
167167
uint::to_str_bytes(true, -n as uint, radix, f)
168168
} else {
@@ -171,7 +171,7 @@ pub fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
171171
}
172172

173173
/// Convert to a string
174-
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
174+
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
175175

176176
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
177177
#[test]

src/libcore/path.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub pure fn Path(s: &str) -> Path {
6161
}
6262

6363
impl PosixPath : ToStr {
64-
fn to_str() -> ~str {
64+
pure fn to_str() -> ~str {
6565
let mut s = ~"";
6666
if self.is_absolute {
6767
s += "/";
@@ -236,7 +236,7 @@ impl PosixPath : GenericPath {
236236

237237

238238
impl WindowsPath : ToStr {
239-
fn to_str() -> ~str {
239+
pure fn to_str() -> ~str {
240240
let mut s = ~"";
241241
match self.host {
242242
Some(ref h) => { s += "\\\\"; s += *h; }

src/libcore/str.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub pure fn from_byte(b: u8) -> ~str {
4949
}
5050

5151
/// Appends a character at the end of a string
52-
pub fn push_char(s: &const ~str, ch: char) {
52+
pub fn push_char(s: &mut ~str, ch: char) {
5353
unsafe {
5454
let code = ch as uint;
5555
let nb = if code < max_one_b { 1u }
@@ -140,7 +140,7 @@ pub pure fn from_chars(chs: &[char]) -> ~str {
140140

141141
/// Appends a string slice to the back of a string, without overallocating
142142
#[inline(always)]
143-
pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) {
143+
pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) {
144144
unsafe {
145145
let llen = lhs.len();
146146
let rlen = rhs.len();
@@ -157,7 +157,7 @@ pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) {
157157
}
158158
/// Appends a string slice to the back of a string
159159
#[inline(always)]
160-
pub fn push_str(lhs: &const ~str, rhs: &str) {
160+
pub fn push_str(lhs: &mut ~str, rhs: &str) {
161161
unsafe {
162162
let llen = lhs.len();
163163
let rlen = rhs.len();
@@ -214,7 +214,7 @@ Section: Adding to and removing from a string
214214
*
215215
* If the string does not contain any characters
216216
*/
217-
pub fn pop_char(s: &const ~str) -> char {
217+
pub fn pop_char(s: &mut ~str) -> char {
218218
let end = len(*s);
219219
assert end > 0u;
220220
let {ch, prev} = char_range_at_reverse(*s, end);
@@ -1802,9 +1802,9 @@ pub pure fn as_buf<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
18021802
* * s - A string
18031803
* * n - The number of bytes to reserve space for
18041804
*/
1805-
pub fn reserve(s: &const ~str, n: uint) {
1805+
pub fn reserve(s: &mut ~str, n: uint) {
18061806
unsafe {
1807-
let v: *mut ~[u8] = cast::transmute(copy s);
1807+
let v: *mut ~[u8] = cast::transmute(s);
18081808
vec::reserve(&mut *v, n + 1);
18091809
}
18101810
}
@@ -1829,7 +1829,7 @@ pub fn reserve(s: &const ~str, n: uint) {
18291829
* * s - A string
18301830
* * n - The number of bytes to reserve space for
18311831
*/
1832-
pub fn reserve_at_least(s: &const ~str, n: uint) {
1832+
pub fn reserve_at_least(s: &mut ~str, n: uint) {
18331833
reserve(s, uint::next_power_of_two(n + 1u) - 1u)
18341834
}
18351835

@@ -1974,7 +1974,7 @@ pub mod raw {
19741974
}
19751975

19761976
/// Appends a byte to a string. (Not UTF-8 safe).
1977-
pub unsafe fn push_byte(s: &const ~str, b: u8) {
1977+
pub unsafe fn push_byte(s: &mut ~str, b: u8) {
19781978
reserve_at_least(s, s.len() + 1);
19791979
do as_buf(*s) |buf, len| {
19801980
let buf: *mut u8 = ::cast::reinterpret_cast(&buf);
@@ -1984,13 +1984,13 @@ pub mod raw {
19841984
}
19851985

19861986
/// Appends a vector of bytes to a string. (Not UTF-8 safe).
1987-
unsafe fn push_bytes(s: &const ~str, bytes: &[u8]) {
1987+
unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
19881988
reserve_at_least(s, s.len() + bytes.len());
19891989
for vec::each(bytes) |byte| { push_byte(s, *byte); }
19901990
}
19911991

19921992
/// Removes the last byte from a string and returns it. (Not UTF-8 safe).
1993-
pub unsafe fn pop_byte(s: &const ~str) -> u8 {
1993+
pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
19941994
let len = len(*s);
19951995
assert (len > 0u);
19961996
let b = s[len - 1u];
@@ -2008,7 +2008,7 @@ pub mod raw {
20082008
}
20092009

20102010
/// Sets the length of the string and adds the null terminator
2011-
pub unsafe fn set_len(v: &const ~str, new_len: uint) {
2011+
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
20122012
let v: **vec::raw::VecRepr = cast::transmute(copy v);
20132013
let repr: *vec::raw::VecRepr = *v;
20142014
(*repr).unboxed.fill = new_len + 1u;

src/libcore/to_str.rs

+27-25
Original file line numberDiff line numberDiff line change
@@ -8,80 +8,82 @@ The `ToStr` trait for converting to strings
88
#[forbid(deprecated_mode)];
99
#[forbid(deprecated_pattern)];
1010

11-
pub trait ToStr { fn to_str() -> ~str; }
11+
pub trait ToStr { pure fn to_str() -> ~str; }
1212

1313
impl int: ToStr {
14-
fn to_str() -> ~str { int::str(self) }
14+
pure fn to_str() -> ~str { int::str(self) }
1515
}
1616
impl i8: ToStr {
17-
fn to_str() -> ~str { i8::str(self) }
17+
pure fn to_str() -> ~str { i8::str(self) }
1818
}
1919
impl i16: ToStr {
20-
fn to_str() -> ~str { i16::str(self) }
20+
pure fn to_str() -> ~str { i16::str(self) }
2121
}
2222
impl i32: ToStr {
23-
fn to_str() -> ~str { i32::str(self) }
23+
pure fn to_str() -> ~str { i32::str(self) }
2424
}
2525
impl i64: ToStr {
26-
fn to_str() -> ~str { i64::str(self) }
26+
pure fn to_str() -> ~str { i64::str(self) }
2727
}
2828
impl uint: ToStr {
29-
fn to_str() -> ~str { uint::str(self) }
29+
pure fn to_str() -> ~str { uint::str(self) }
3030
}
3131
impl u8: ToStr {
32-
fn to_str() -> ~str { u8::str(self) }
32+
pure fn to_str() -> ~str { u8::str(self) }
3333
}
3434
impl u16: ToStr {
35-
fn to_str() -> ~str { u16::str(self) }
35+
pure fn to_str() -> ~str { u16::str(self) }
3636
}
3737
impl u32: ToStr {
38-
fn to_str() -> ~str { u32::str(self) }
38+
pure fn to_str() -> ~str { u32::str(self) }
3939
}
4040
impl u64: ToStr {
41-
fn to_str() -> ~str { u64::str(self) }
41+
pure fn to_str() -> ~str { u64::str(self) }
4242
}
4343
impl float: ToStr {
44-
fn to_str() -> ~str { float::to_str(self, 4u) }
44+
pure fn to_str() -> ~str { float::to_str(self, 4u) }
4545
}
4646
impl f32: ToStr {
47-
fn to_str() -> ~str { float::to_str(self as float, 4u) }
47+
pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
4848
}
4949
impl f64: ToStr {
50-
fn to_str() -> ~str { float::to_str(self as float, 4u) }
50+
pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
5151
}
5252
impl bool: ToStr {
53-
fn to_str() -> ~str { bool::to_str(self) }
53+
pure fn to_str() -> ~str { bool::to_str(self) }
5454
}
5555
impl (): ToStr {
56-
fn to_str() -> ~str { ~"()" }
56+
pure fn to_str() -> ~str { ~"()" }
5757
}
5858
impl ~str: ToStr {
59-
fn to_str() -> ~str { copy self }
59+
pure fn to_str() -> ~str { copy self }
6060
}
6161
impl &str: ToStr {
62-
fn to_str() -> ~str { str::from_slice(self) }
62+
pure fn to_str() -> ~str { str::from_slice(self) }
6363
}
6464
impl @str: ToStr {
65-
fn to_str() -> ~str { str::from_slice(self) }
65+
pure fn to_str() -> ~str { str::from_slice(self) }
6666
}
6767

6868
impl<A: ToStr Copy, B: ToStr Copy> (A, B): ToStr {
69-
fn to_str() -> ~str {
69+
pure fn to_str() -> ~str {
7070
let (a, b) = self;
7171
~"(" + a.to_str() + ~", " + b.to_str() + ~")"
7272
}
7373
}
7474
impl<A: ToStr Copy, B: ToStr Copy, C: ToStr Copy> (A, B, C): ToStr {
75-
fn to_str() -> ~str {
75+
pure fn to_str() -> ~str {
7676
let (a, b, c) = self;
7777
~"(" + a.to_str() + ~", " + b.to_str() + ~", " + c.to_str() + ~")"
7878
}
7979
}
8080

8181
impl<A: ToStr> ~[A]: ToStr {
82-
fn to_str() -> ~str {
82+
pure fn to_str() -> ~str unsafe {
83+
// Bleh -- not really unsafe
84+
// push_str and push_char
8385
let mut acc = ~"[", first = true;
84-
for vec::each(self) |elt| {
86+
for vec::each(self) |elt| unsafe {
8587
if first { first = false; }
8688
else { str::push_str(&mut acc, ~", "); }
8789
str::push_str(&mut acc, elt.to_str());
@@ -92,10 +94,10 @@ impl<A: ToStr> ~[A]: ToStr {
9294
}
9395
9496
impl<A: ToStr> @A: ToStr {
95-
fn to_str() -> ~str { ~"@" + (*self).to_str() }
97+
pure fn to_str() -> ~str { ~"@" + (*self).to_str() }
9698
}
9799
impl<A: ToStr> ~A: ToStr {
98-
fn to_str() -> ~str { ~"~" + (*self).to_str() }
100+
pure fn to_str() -> ~str { ~"~" + (*self).to_str() }
99101
}
100102

101103
#[cfg(test)]

src/libcore/uint-template.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
232232
}
233233

234234
/// Convert to a string
235-
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
235+
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
236236

237237
#[test]
238238
pub fn test_to_str() {

src/libstd/json.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn escape_str(s: &str) -> ~str {
5151

5252
fn spaces(n: uint) -> ~str {
5353
let mut ss = ~"";
54-
for n.times { str::push_str(&ss, " "); }
54+
for n.times { str::push_str(&mut ss, " "); }
5555
return ss;
5656
}
5757

@@ -302,7 +302,8 @@ pub fn to_writer(wr: io::Writer, json: &Json) {
302302
}
303303

304304
/// Serializes a json value into a string
305-
pub fn to_str(json: &Json) -> ~str {
305+
pub pure fn to_str(json: &Json) -> ~str unsafe {
306+
// ugh, should be safe
306307
io::with_str_writer(|wr| to_writer(wr, json))
307308
}
308309

@@ -546,14 +547,14 @@ priv impl Parser {
546547

547548
if (escape) {
548549
match self.ch {
549-
'"' => str::push_char(&res, '"'),
550-
'\\' => str::push_char(&res, '\\'),
551-
'/' => str::push_char(&res, '/'),
552-
'b' => str::push_char(&res, '\x08'),
553-
'f' => str::push_char(&res, '\x0c'),
554-
'n' => str::push_char(&res, '\n'),
555-
'r' => str::push_char(&res, '\r'),
556-
't' => str::push_char(&res, '\t'),
550+
'"' => str::push_char(&mut res, '"'),
551+
'\\' => str::push_char(&mut res, '\\'),
552+
'/' => str::push_char(&mut res, '/'),
553+
'b' => str::push_char(&mut res, '\x08'),
554+
'f' => str::push_char(&mut res, '\x0c'),
555+
'n' => str::push_char(&mut res, '\n'),
556+
'r' => str::push_char(&mut res, '\r'),
557+
't' => str::push_char(&mut res, '\t'),
557558
'u' => {
558559
// Parse \u1234.
559560
let mut i = 0u;
@@ -582,7 +583,7 @@ priv impl Parser {
582583
~"invalid \\u escape (not four digits)");
583584
}
584585

585-
str::push_char(&res, n as char);
586+
str::push_char(&mut res, n as char);
586587
}
587588
_ => return self.error(~"invalid escape")
588589
}
@@ -594,7 +595,7 @@ priv impl Parser {
594595
self.bump();
595596
return Ok(res);
596597
}
597-
str::push_char(&res, self.ch);
598+
str::push_char(&mut res, self.ch);
598599
}
599600
}
600601

@@ -1166,11 +1167,11 @@ impl <A: ToJson> Option<A>: ToJson {
11661167
}
11671168

11681169
impl Json: to_str::ToStr {
1169-
fn to_str() -> ~str { to_str(&self) }
1170+
pure fn to_str() -> ~str { to_str(&self) }
11701171
}
11711172

11721173
impl Error: to_str::ToStr {
1173-
fn to_str() -> ~str {
1174+
pure fn to_str() -> ~str {
11741175
fmt!("%u:%u: %s", self.line, self.col, *self.msg)
11751176
}
11761177
}

src/libstd/map.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ pub mod chained {
341341
wr.write_str(~" }");
342342
}
343343

344-
fn to_str() -> ~str {
344+
pure fn to_str() -> ~str unsafe {
345+
// Meh -- this should be safe
345346
do io::with_str_writer |wr| { self.to_writer(wr) }
346347
}
347348
}

0 commit comments

Comments
 (0)