From 3c19f1bca83be3f4abef378d0a4cd852c8615164 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 27 Jun 2013 14:20:42 +0200 Subject: [PATCH 01/11] Refactored int/uint range code in preparation for change to range_rev semantics. Also added unit tests of range code to test refactoring. The num-range-rev.rs test will need to be updated when the range_rev semantics change. --- src/libstd/num/int_macros.rs | 88 +++++++++++++++++---- src/libstd/num/uint_macros.rs | 93 +++++++++++++++++----- src/test/run-pass/num-range-rev.rs | 114 +++++++++++++++++++++++++++ src/test/run-pass/num-range.rs | 119 +++++++++++++++++++++++++++++ 4 files changed, 381 insertions(+), 33 deletions(-) create mode 100644 src/test/run-pass/num-range-rev.rs create mode 100644 src/test/run-pass/num-range.rs diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 75e0bbcb71b04..4fd30be80e66e 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -29,28 +29,38 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = (-1 as $T) << (bits - 1); pub static max_value: $T = min_value - 1 as $T; +enum Range { Closed, HalfOpen } + +#[inline] /// -/// Iterate over the range [`lo`..`hi`) +/// Iterate through a range with a given step value. /// -/// # Arguments +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. /// -/// * `lo` - lower bound, inclusive -/// * `hi` - higher bound, exclusive -/// -/// # Examples -/// ~~~ -/// let mut sum = 0; -/// for int::range(1, 5) |i| { -/// sum += i; -/// } -/// assert!(sum == 10); -/// ~~~ +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. /// -#[inline] -pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { +fn range_step_core(start: $T, stop: $T, step: $T, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); + } else if step == (1 as $T) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } @@ -66,9 +76,55 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { i += step; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// * `x_i == start + step*i`, and +/// * `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ +/// let mut sum = 0; +/// for int::range(1, 5) |i| { +/// sum += i; +/// } +/// assert!(sum == 10); +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } + #[inline] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index de1b997b14b52..09397ecfd7768 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -30,32 +30,46 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = 0 as $T; pub static max_value: $T = 0 as $T - 1 as $T; +enum Range { Closed, HalfOpen } + #[inline] -/** - * Iterate through a range with a given step value. - * - * # Examples - * ~~~ {.rust} - * let nums = [1,2,3,4,5,6,7]; - * - * for uint::range_step(0, nums.len() - 1, 2) |i| { - * println(fmt!("%d & %d", nums[i], nums[i+1])); - * } - * ~~~ - */ -pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { +/// +/// Iterate through a range with a given step value. +/// +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. +/// +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. +/// +fn range_step_core(start: $T, stop: $T, step: $T_SIGNED, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!("range_step called with step == 0"); - } - if step >= 0 { + } else if step == (1 as $T_SIGNED) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T_SIGNED) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } + } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } // avoiding overflow. break if i + step > max_value if i > max_value - (step as $T) { return true; } i += step as $T; } - } else { + } else { // descending while i > stop { if !it(i) { return false; } // avoiding underflow. break if i + step < min_value @@ -63,7 +77,52 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> i -= -step as $T; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// - `x_i == start + step*i`, and +/// - `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ {.rust} +/// let nums = [1,2,3,4,5,6,7]; +/// +/// for uint::range_step(0, nums.len() - 1, 2) |i| { +/// println(fmt!("%d & %d", nums[i], nums[i+1])); +/// } +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } #[inline] diff --git a/src/test/run-pass/num-range-rev.rs b/src/test/run-pass/num-range-rev.rs new file mode 100644 index 0000000000000..e65c793a7b452 --- /dev/null +++ b/src/test/run-pass/num-range-rev.rs @@ -0,0 +1,114 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn uint_range_rev(hi: uint, lo: uint, it: &fn(uint) -> bool) -> bool { + uint::range_rev(hi, lo, it) +} + +fn int_range_rev(hi: int, lo: int, it: &fn(int) -> bool) -> bool { + int::range_rev(hi, lo, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, step: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, step, it) +} + + +pub fn main() { + // int and uint have same result for + // Sum{100 > i >= 2} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range_rev(99, 1) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range_rev(99, 1) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7,11]; + let mut prod = 1i; + for uint_range_rev(4, 0) |i| { + println(fmt!("uint 4 downto 0: %u", i)); + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3); + let mut prod = 1i; + for int_range_rev(4, 0) |i| { + println(fmt!("int 4 downto 0: %d", i)); + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3); + + + // range and range_rev are symmetric. + let mut sum_up = 0u; + for uint_range(10, 30) |i| { + sum_up += i; + } + let mut sum_down = 0u; + for uint_range_rev(29, 9) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + let mut sum_up = 0; + for int_range(-20, 10) |i| { + sum_up += i; + } + let mut sum_down = 0; + for int_range_rev(9, -21) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + + // empty ranges + for int_range_rev(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range_rev(0, 1) |_| { + // fail!("range should be empty when start-1 underflows"); + } + + // range iterations do not wrap/underflow + let mut uflo_loop_visited = ~[]; + for int_range_step(int::min_value+15, int::min_value, -4) |x| { + uflo_loop_visited.push(x - int::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); + + let mut uflo_loop_visited = ~[]; + for uint_range_step(uint::min_value+15, uint::min_value, -4) |x| { + uflo_loop_visited.push(x - uint::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); +} diff --git a/src/test/run-pass/num-range.rs b/src/test/run-pass/num-range.rs new file mode 100644 index 0000000000000..7c1f905a049b6 --- /dev/null +++ b/src/test/run-pass/num-range.rs @@ -0,0 +1,119 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, s: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, s, it) +} + +pub fn main() { + println(fmt!("num-range start")); + // int and uint have same result for + // Sum{2 <= i < 100} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7]; + let mut prod = 1i; + for uint_range(0, 4) |i| { + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + let mut prod = 1i; + for int_range(0, 4) |i| { + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + + + // empty ranges + for int_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + + // range iterations do not wrap/overflow + let mut oflo_loop_visited = ~[]; + for uint_range_step(uint::max_value-15, uint::max_value, 4) |x| { + oflo_loop_visited.push(uint::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + let mut oflo_loop_visited = ~[]; + for int_range_step(int::max_value-15, int::max_value, 4) |x| { + oflo_loop_visited.push(int::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + + // range_step never passes nor visits the stop element + for int_range_step(0, 21, 3) |x| { + assert!(x < 21); + } + + // range_step_inclusive will never pass stop element, and may skip it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + + // range_step_inclusive will never pass stop element, but may visit it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + println(fmt!("saw: %u", x)); + if x == 21 { saw21 = true; } + } + assert!(saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(saw21); + +} From db0a13b9865510ec07f7597e11009eabc2676afc Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 1 Jul 2013 12:30:14 +0200 Subject: [PATCH 02/11] Switch over to new range_rev semantics; fix #5270. --- src/libextra/smallintmap.rs | 4 ++-- src/libstd/num/int_macros.rs | 7 ++++--- src/libstd/num/uint_macros.rs | 7 ++++--- src/libstd/run.rs | 2 +- src/libstd/trie.rs | 2 +- src/test/run-pass/num-range-rev.rs | 18 +++++++++--------- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index d952374ee5ccc..329d3a454b45a 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -159,8 +159,8 @@ impl SmallIntMap { /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { - match self.v[i - 1] { - Some(ref elt) => if !it(i - 1, elt) { return false; }, + match self.v[i] { + Some(ref elt) => if !it(i, elt) { return false; }, None => () } } diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 4fd30be80e66e..cef32b5c7e445 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -132,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T, it) } impl Num for $T {} @@ -897,7 +898,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 09397ecfd7768..54c1327fa9303 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -132,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T_SIGNED, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T_SIGNED, it) } impl Num for $T {} @@ -662,7 +663,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 17dc604a17858..883870db1e673 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -669,7 +669,7 @@ fn spawn_process_os(prog: &str, args: &[~str], fail!("failure in dup3(err_fd, 2): %s", os::last_os_error()); } // close all other fds - for int::range_rev(getdtablesize() as int - 1, 2) |fd| { + for int::range_rev(getdtablesize() as int, 3) |fd| { close(fd as c_int); } diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 8ce02d59ab15c..50552fd754788 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -261,7 +261,7 @@ impl TrieNode { fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { - match self.children[idx - 1] { + match self.children[idx] { Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () diff --git a/src/test/run-pass/num-range-rev.rs b/src/test/run-pass/num-range-rev.rs index e65c793a7b452..7262339e431d9 100644 --- a/src/test/run-pass/num-range-rev.rs +++ b/src/test/run-pass/num-range-rev.rs @@ -40,13 +40,13 @@ pub fn main() { // int and uint have same result for // Sum{100 > i >= 2} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 let mut sum = 0u; - for uint_range_rev(99, 1) |i| { + for uint_range_rev(100, 2) |i| { sum += i; } assert_eq!(sum, 4949); let mut sum = 0i; - for int_range_rev(99, 1) |i| { + for int_range_rev(100, 2) |i| { sum += i; } assert_eq!(sum, 4949); @@ -55,17 +55,17 @@ pub fn main() { // elements are visited in correct order let primes = [2,3,5,7,11]; let mut prod = 1i; - for uint_range_rev(4, 0) |i| { + for uint_range_rev(5, 0) |i| { println(fmt!("uint 4 downto 0: %u", i)); prod *= int::pow(primes[i], i); } - assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3); + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); let mut prod = 1i; - for int_range_rev(4, 0) |i| { + for int_range_rev(5, 0) |i| { println(fmt!("int 4 downto 0: %d", i)); prod *= int::pow(primes[i], i as uint); } - assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3); + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); // range and range_rev are symmetric. @@ -74,7 +74,7 @@ pub fn main() { sum_up += i; } let mut sum_down = 0u; - for uint_range_rev(29, 9) |i| { + for uint_range_rev(30, 10) |i| { sum_down += i; } assert_eq!(sum_up, sum_down); @@ -84,7 +84,7 @@ pub fn main() { sum_up += i; } let mut sum_down = 0; - for int_range_rev(9, -21) |i| { + for int_range_rev(10, -20) |i| { sum_down += i; } assert_eq!(sum_up, sum_down); @@ -96,7 +96,7 @@ pub fn main() { } for uint_range_rev(0, 1) |_| { - // fail!("range should be empty when start-1 underflows"); + fail!("range should be empty when start-1 underflows"); } // range iterations do not wrap/underflow From 3896d46c0a6b99ef166bdc29220ef6c85ad8bc8d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 11 Jul 2013 16:56:49 +0200 Subject: [PATCH 03/11] Fix #5270: another test I did not update properly. --- src/libstd/trie.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 50552fd754788..f4597f4b08e9e 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -462,7 +462,7 @@ mod tests { m.insert(x, x / 2); } - let mut n = uint::max_value - 9999; + let mut n = uint::max_value - 10000; for m.each |k, v| { if n == uint::max_value - 5000 { break } assert!(n < uint::max_value - 5000); @@ -499,7 +499,7 @@ mod tests { m.insert(x, x / 2); } - let mut n = uint::max_value; + let mut n = uint::max_value - 1; for m.each_reverse |k, v| { if n == uint::max_value - 5000 { break } assert!(n > uint::max_value - 5000); From 877bba91d54457c104ff0bf67fd46a499a451cf6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 16 Jul 2013 04:27:54 -0400 Subject: [PATCH 04/11] Permit C-style enums in vector repeat length expressions (N.B. values only, not type signatures) --- src/librustc/middle/const_eval.rs | 58 +++++++++++++++++++++-- src/librustc/middle/kind.rs | 2 +- src/librustc/middle/trans/tvec.rs | 4 +- src/librustc/middle/ty.rs | 47 +++++++++++------- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 20 ++++++-- src/test/run-pass/enum-vec-initializer.rs | 24 ++++++++++ 7 files changed, 127 insertions(+), 30 deletions(-) create mode 100644 src/test/run-pass/enum-vec-initializer.rs diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index af39dea6d79e1..2cf99e07dc9f1 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -165,10 +165,58 @@ pub fn classify(e: &expr, pub fn lookup_const(tcx: ty::ctxt, e: &expr) -> Option<@expr> { match tcx.def_map.find(&e.id) { Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id), + Some(&ast::def_variant(enum_def, variant_def)) => lookup_variant_by_id(tcx, + enum_def, + variant_def), _ => None } } +pub fn lookup_variant_by_id(tcx: ty::ctxt, + enum_def: ast::def_id, + variant_def: ast::def_id) + -> Option<@expr> { + fn variant_expr(variants: &[ast::variant], id: ast::node_id) -> Option<@expr> { + for variants.iter().advance |variant| { + if variant.node.id == id { + return variant.node.disr_expr; + } + } + None + } + + if ast_util::is_local(enum_def) { + match tcx.items.find(&enum_def.node) { + None => None, + Some(&ast_map::node_item(it, _)) => match it.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + Some(_) => None + } + } else { + let maps = astencode::Maps { + root_map: @mut HashMap::new(), + method_map: @mut HashMap::new(), + vtable_map: @mut HashMap::new(), + write_guard_map: @mut HashSet::new(), + capture_map: @mut HashMap::new() + }; + match csearch::maybe_get_item_ast(tcx, enum_def, + |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) { + csearch::found(ast::ii_item(item)) => match item.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + _ => None + } + } +} + pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::def_id) -> Option<@expr> { @@ -237,13 +285,13 @@ pub enum const_val { } pub fn eval_const_expr(tcx: middle::ty::ctxt, e: &expr) -> const_val { - match eval_const_expr_partial(tcx, e) { + match eval_const_expr_partial(&tcx, e) { Ok(r) => r, Err(s) => tcx.sess.span_fatal(e.span, s) } } -pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) +pub fn eval_const_expr_partial(tcx: &T, e: &expr) -> Result { use middle::ty; fn fromb(b: bool) -> Result { Ok(const_int(b as i64)) } @@ -360,7 +408,7 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_cast(base, _) => { - let ety = ty::expr_ty(tcx, e); + let ety = tcx.expr_ty(e); let base = eval_const_expr_partial(tcx, base); match /*bad*/copy base { Err(_) => base, @@ -390,8 +438,8 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_path(_) => { - match lookup_const(tcx, e) { - Some(actual_e) => eval_const_expr_partial(tcx, actual_e), + match lookup_const(tcx.ty_ctxt(), e) { + Some(actual_e) => eval_const_expr_partial(&tcx.ty_ctxt(), actual_e), None => Err(~"Non-constant path in constant expr") } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a9454d1b23096..ae2a27ed6ed7b 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -309,7 +309,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { "explicit copy requires a copyable argument"); } expr_repeat(element, count_expr, _) => { - let count = ty::eval_repeat_count(cx.tcx, count_expr); + let count = ty::eval_repeat_count(&cx.tcx, count_expr); if count > 1 { let element_ty = ty::expr_ty(cx.tcx, element); check_copy(cx, element_ty, element.span, diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 8fff23c649848..561c9a3399a04 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -417,7 +417,7 @@ pub fn write_content(bcx: block, return expr::trans_into(bcx, element, Ignore); } SaveIn(lldest) => { - let count = ty::eval_repeat_count(bcx.tcx(), count_expr); + let count = ty::eval_repeat_count(&bcx.tcx(), count_expr); if count == 0 { return bcx; } @@ -509,7 +509,7 @@ pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint { }, ast::expr_vec(ref es, _) => es.len(), ast::expr_repeat(_, count_expr, _) => { - ty::eval_repeat_count(bcx.tcx(), count_expr) + ty::eval_repeat_count(&bcx.tcx(), count_expr) } _ => bcx.tcx().sess.span_bug(content_expr.span, "Unexpected evec content") diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8e23f5431bcee..eb69798d0cce8 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4230,42 +4230,57 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { return t_norm; } +pub trait ExprTyProvider { + pub fn expr_ty(&self, ex: &ast::expr) -> t; + pub fn ty_ctxt(&self) -> ctxt; +} + +impl ExprTyProvider for ctxt { + pub fn expr_ty(&self, ex: &ast::expr) -> t { + expr_ty(*self, ex) + } + + pub fn ty_ctxt(&self) -> ctxt { + *self + } +} + // Returns the repeat count for a repeating vector expression. -pub fn eval_repeat_count(tcx: ctxt, count_expr: &ast::expr) -> uint { +pub fn eval_repeat_count(tcx: &T, count_expr: &ast::expr) -> uint { match const_eval::eval_const_expr_partial(tcx, count_expr) { Ok(ref const_val) => match *const_val { const_eval::const_int(count) => if count < 0 { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found negative integer"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found negative integer"); return 0; } else { return count as uint }, const_eval::const_uint(count) => return count as uint, const_eval::const_float(count) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found float"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found float"); return count as uint; } const_eval::const_str(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found string"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found string"); return 0; } const_eval::const_bool(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found boolean"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found boolean"); return 0; } }, Err(*) => { - tcx.sess.span_err(count_expr.span, - "expected constant integer for repeat count \ - but found variable"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected constant integer for repeat count \ + but found variable"); return 0; } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d8185022e416d..1186f8cecabc5 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -479,7 +479,7 @@ pub fn ast_ty_to_ty( } } ast::ty_fixed_length_vec(ref a_mt, e) => { - match const_eval::eval_const_expr_partial(tcx, e) { + match const_eval::eval_const_expr_partial(&tcx, e) { Ok(ref r) => { match *r { const_eval::const_int(i) => diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 4caf0b62a546d..396fae68f737c 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -83,7 +83,7 @@ use middle::pat_util; use middle::lint::unreachable_code; use middle::ty::{FnSig, VariantInfo_}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; -use middle::ty::{substs, param_ty}; +use middle::ty::{substs, param_ty, ExprTyProvider}; use middle::ty; use middle::typeck::astconv::AstConv; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; @@ -290,6 +290,16 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, } } +impl ExprTyProvider for FnCtxt { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { + self.expr_ty(ex) + } + + pub fn ty_ctxt(&self) -> ty::ctxt { + self.ccx.tcx + } +} + pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { let visit = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_item: |a| check_item(ccx, a), @@ -797,7 +807,7 @@ impl FnCtxt { pat.repr(self.tcx()) } - pub fn expr_ty(&self, ex: @ast::expr) -> ty::t { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { match self.inh.node_types.find(&ex.id) { Some(&t) => t, None => { @@ -2250,8 +2260,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_repeat(element, count_expr, mutbl) => { - let _ = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let _ = ty::eval_repeat_count(fcx, count_expr); let tt = ast_expr_vstore_to_vstore(fcx, ev, vst); let mutability = match vst { ast::expr_vstore_mut_box | ast::expr_vstore_mut_slice => { @@ -2730,8 +2740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } ast::expr_repeat(element, count_expr, mutbl) => { - let count = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let count = ty::eval_repeat_count(fcx, count_expr); let t: ty::t = fcx.infcx().next_ty_var(); check_expr_has_type(fcx, element, t); let element_ty = fcx.expr_ty(element); @@ -3126,7 +3136,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, // that the expression is in an form that eval_const_expr can // handle, so we may still get an internal compiler error - match const_eval::eval_const_expr_partial(ccx.tcx, e) { + match const_eval::eval_const_expr_partial(&ccx.tcx, e) { Ok(const_eval::const_int(val)) => { *disr_val = val as int; } diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs new file mode 100644 index 0000000000000..ae590ad7d1f71 --- /dev/null +++ b/src/test/run-pass/enum-vec-initializer.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Flopsy { + Bunny = 2 +} + +static BAR:uint = Bunny as uint; +static BAR2:uint = BAR; + +fn main() { + let v = [0, .. Bunny as uint]; + let v = [0, .. BAR]; + let v = [0, .. BAR2]; + static BAR3:uint = BAR2; + let v = [0, .. BAR3]; +} \ No newline at end of file From 712ac836c63c3ae98daf9fb98b7b96ed73347848 Mon Sep 17 00:00:00 2001 From: Austin King Date: Tue, 16 Jul 2013 12:47:01 -0700 Subject: [PATCH 05/11] Rename Option swap_unwrap to take_unwrap. Fixes Issue#7764 --- src/libextra/dlist.rs | 6 +++--- src/libextra/net/ip.rs | 2 +- src/libextra/sync.rs | 8 ++++---- src/libextra/treemap.rs | 12 ++++++------ src/libstd/option.rs | 14 +++++++------- src/libstd/rt/sched.rs | 10 +++++----- src/libstd/rt/task.rs | 2 +- src/libstd/rt/tube.rs | 2 +- src/libstd/rt/uv/async.rs | 2 +- src/libstd/rt/uv/idle.rs | 2 +- src/libstd/rt/uv/net.rs | 10 +++++----- src/libstd/rt/uv/timer.rs | 2 +- src/libstd/task/spawn.rs | 6 +++--- src/test/bench/msgsend-ring-mutex-arcs.rs | 4 ++-- src/test/bench/msgsend-ring-rw-arcs.rs | 4 ++-- 15 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 9eacddd90028b..35600df4f9dd0 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -173,11 +173,11 @@ impl Deque for DList { let tail_own = match tail.prev.resolve() { None => { self.list_tail = Rawlink::none(); - self.list_head.swap_unwrap() + self.list_head.take_unwrap() }, Some(tail_prev) => { self.list_tail = tail.prev; - tail_prev.next.swap_unwrap() + tail_prev.next.take_unwrap() } }; Some(tail_own.value) @@ -465,7 +465,7 @@ impl<'self, A> ListInsertion for MutDListIterator<'self, A> { Some(prev) => prev, }; let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()}; - let node_own = prev_node.next.swap_unwrap(); + let node_own = prev_node.next.take_unwrap(); ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node)); prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node)); self.list.length += 1; diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs index 6876b3510b6ca..11e3106e4b5a9 100644 --- a/src/libextra/net/ip.rs +++ b/src/libextra/net/ip.rs @@ -116,7 +116,7 @@ pub fn get_addr(node: &str, iotask: &iotask) let (output_po, output_ch) = stream(); let mut output_ch = Some(SharedChan::new(output_ch)); do str::as_buf(node) |node_ptr, len| { - let output_ch = output_ch.swap_unwrap(); + let output_ch = output_ch.take_unwrap(); debug!("slice len %?", len); let handle = create_uv_getaddrinfo_t(); let handle_ptr: *uv_getaddrinfo_t = &handle; diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index b9d25451a8a95..632f5d7827d4c 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -260,7 +260,7 @@ impl<'self> Condvar<'self> { signal_waitqueue(&state.waiters); } // Enqueue ourself to be woken up by a signaller. - let SignalEnd = SignalEnd.swap_unwrap(); + let SignalEnd = SignalEnd.take_unwrap(); state.blocked[condvar_id].tail.send(SignalEnd); } else { out_of_bounds = Some(state.blocked.len()); @@ -281,7 +281,7 @@ impl<'self> Condvar<'self> { // Unconditionally "block". (Might not actually block if a // signaller already sent -- I mean 'unconditionally' in contrast // with acquire().) - let _ = comm::recv_one(WaitEnd.swap_unwrap()); + let _ = comm::recv_one(WaitEnd.take_unwrap()); } // This is needed for a failing condition variable to reacquire the @@ -353,7 +353,7 @@ impl<'self> Condvar<'self> { } } do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { - let queue = queue.swap_unwrap(); + let queue = queue.take_unwrap(); broadcast_waitqueue(&queue) } } @@ -1436,7 +1436,7 @@ mod tests { do x.write_downgrade |xwrite| { let mut xopt = Some(xwrite); do y.write_downgrade |_ywrite| { - y.downgrade(xopt.swap_unwrap()); + y.downgrade(xopt.take_unwrap()); error!("oops, y.downgrade(x) should have failed!"); } } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f1fe7acb00f83..bd13c8619be1d 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -552,7 +552,7 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, // Remove left horizontal link by rotating right fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { - let mut save = node.left.swap_unwrap(); + let mut save = node.left.take_unwrap(); swap(&mut node.left, &mut save.right); // save.right now None swap(node, &mut save); node.right = Some(save); @@ -564,7 +564,7 @@ fn skew(node: &mut ~TreeNode) { fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { - let mut save = node.right.swap_unwrap(); + let mut save = node.right.take_unwrap(); swap(&mut node.right, &mut save.left); // save.left now None save.level += 1; swap(node, &mut save); @@ -643,7 +643,7 @@ fn remove(node: &mut Option<~TreeNode>, Equal => { if save.left.is_some() { if save.right.is_some() { - let mut left = save.left.swap_unwrap(); + let mut left = save.left.take_unwrap(); if left.right.is_some() { heir_swap(save, &mut left.right); } else { @@ -653,13 +653,13 @@ fn remove(node: &mut Option<~TreeNode>, save.left = Some(left); (remove(&mut save.left, key), true) } else { - let new = save.left.swap_unwrap(); + let new = save.left.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); - *save = save.left.swap_unwrap(); + *save = save.left.take_unwrap(); (Some(value), true) } } else if save.right.is_some() { - let new = save.right.swap_unwrap(); + let new = save.right.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); (Some(value), true) } else { diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 222952a6dc143..b0811674a7bfa 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -203,14 +203,14 @@ impl Option { /// Apply a function to the contained value or do nothing pub fn mutate(&mut self, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } } /// Apply a function to the contained value or set it to a default pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } else { *self = Some(def); } @@ -293,8 +293,8 @@ impl Option { * Fails if the value equals `None`. */ #[inline] - pub fn swap_unwrap(&mut self) -> T { - if self.is_none() { fail!("option::swap_unwrap none") } + pub fn take_unwrap(&mut self) -> T { + if self.is_none() { fail!("option::take_unwrap none") } util::replace(self, None).unwrap() } @@ -460,7 +460,7 @@ fn test_option_dance() { let mut y = Some(5); let mut y2 = 0; for x.iter().advance |_x| { - y2 = y.swap_unwrap(); + y2 = y.take_unwrap(); } assert_eq!(y2, 5); assert!(y.is_none()); @@ -468,8 +468,8 @@ fn test_option_dance() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_option_too_much_dance() { let mut y = Some(util::NonCopyable); - let _y2 = y.swap_unwrap(); - let _y3 = y.swap_unwrap(); + let _y2 = y.take_unwrap(); + let _y3 = y.take_unwrap(); } #[test] diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 6e9aef7773051..4e4145ddc161f 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -328,7 +328,7 @@ impl Scheduler { /// Given an input Coroutine sends it back to its home scheduler. fn send_task_home(task: ~Task) { let mut task = task; - let mut home = task.home.swap_unwrap(); + let mut home = task.home.take_unwrap(); match home { Sched(ref mut home_handle) => { home_handle.send(PinnedTask(task)); @@ -418,7 +418,7 @@ impl Scheduler { do self.deschedule_running_task_and_then |sched, dead_task| { let mut dead_task = dead_task; - let coroutine = dead_task.coroutine.swap_unwrap(); + let coroutine = dead_task.coroutine.take_unwrap(); coroutine.recycle(&mut sched.stack_pool); } @@ -506,7 +506,7 @@ impl Scheduler { this.metrics.context_switches_task_to_sched += 1; unsafe { - let blocked_task = this.current_task.swap_unwrap(); + let blocked_task = this.current_task.take_unwrap(); let f_fake_region = transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f); let f_opaque = ClosureConverter::from_fn(f_fake_region); @@ -538,7 +538,7 @@ impl Scheduler { rtdebug!("switching tasks"); this.metrics.context_switches_task_to_task += 1; - let old_running_task = this.current_task.swap_unwrap(); + let old_running_task = this.current_task.take_unwrap(); let f_fake_region = unsafe { transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f) @@ -576,7 +576,7 @@ impl Scheduler { assert!(self.cleanup_job.is_some()); - let cleanup_job = self.cleanup_job.swap_unwrap(); + let cleanup_job = self.cleanup_job.take_unwrap(); match cleanup_job { DoNothing => { } GiveTask(task, f) => (f.to_fn())(self, task) diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 17d0d59660f1b..449438b920551 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -127,7 +127,7 @@ impl Task { // Wait for children. Possibly report the exit status. let local_success = !self.unwinder.unwinding; - let join_latch = self.join_latch.swap_unwrap(); + let join_latch = self.join_latch.take_unwrap(); match self.on_exit { Some(ref on_exit) => { let success = join_latch.wait(local_success); diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs index 013eb438c3657..f61eee8859b1a 100644 --- a/src/libstd/rt/tube.rs +++ b/src/libstd/rt/tube.rs @@ -53,7 +53,7 @@ impl Tube { if (*state).blocked_task.is_some() { // There's a waiting task. Wake it up rtdebug!("waking blocked tube"); - let task = (*state).blocked_task.swap_unwrap(); + let task = (*state).blocked_task.take_unwrap(); let sched = Local::take::(); sched.resume_task_immediately(task); } diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs index f3d1024024ff8..81428509e33e5 100644 --- a/src/libstd/rt/uv/async.rs +++ b/src/libstd/rt/uv/async.rs @@ -62,7 +62,7 @@ impl AsyncWatcher { let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { uvll::free_handle(handle as *c_void); } diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs index a3630c9b9bf8d..28b101f686d4c 100644 --- a/src/libstd/rt/uv/idle.rs +++ b/src/libstd/rt/uv/idle.rs @@ -73,7 +73,7 @@ impl IdleWatcher { let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle); { let data = idle_watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } idle_watcher.drop_watcher_data(); uvll::idle_delete(handle); diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs index 6d096f9885a7d..09c748ec04782 100644 --- a/src/libstd/rt/uv/net.rs +++ b/src/libstd/rt/uv/net.rs @@ -209,7 +209,7 @@ impl StreamWatcher { let write_request: WriteRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = write_request.stream(); write_request.delete(); - let cb = stream_watcher.get_watcher_data().write_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -233,7 +233,7 @@ impl StreamWatcher { extern fn close_cb(handle: *uvll::uv_stream_t) { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); - stream_watcher.get_watcher_data().close_cb.swap_unwrap()(); + stream_watcher.get_watcher_data().close_cb.take_unwrap()(); stream_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } @@ -301,7 +301,7 @@ impl TcpWatcher { let connect_request: ConnectRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = connect_request.stream(); connect_request.delete(); - let cb = stream_watcher.get_watcher_data().connect_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -438,7 +438,7 @@ impl UdpWatcher { let send_request: UdpSendRequest = NativeHandle::from_native_handle(req); let mut udp_watcher = send_request.handle(); send_request.delete(); - let cb = udp_watcher.get_watcher_data().udp_send_cb.swap_unwrap(); + let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap(); let status = status_to_maybe_uv_error(udp_watcher.native_handle(), status); cb(udp_watcher, status); } @@ -456,7 +456,7 @@ impl UdpWatcher { extern fn close_cb(handle: *uvll::uv_udp_t) { let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle); - udp_watcher.get_watcher_data().close_cb.swap_unwrap()(); + udp_watcher.get_watcher_data().close_cb.take_unwrap()(); udp_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index 14465eb7dfd3a..bc5399327a032 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -70,7 +70,7 @@ impl TimerWatcher { let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 206d19e175fe9..bf09a533ebe12 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -302,7 +302,7 @@ fn each_ancestor(list: &mut AncestorList, fn with_parent_tg(parent_group: &mut Option, blk: &fn(TaskGroupInner) -> U) -> U { // If this trips, more likely the problem is 'blk' failed inside. - let tmp_arc = parent_group.swap_unwrap(); + let tmp_arc = parent_group.take_unwrap(); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; *parent_group = Some(tmp_arc); result @@ -609,7 +609,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { }; if opts.notify_chan.is_some() { - let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = opts.notify_chan.take_unwrap(); let notify_chan = Cell::new(notify_chan); let on_exit: ~fn(bool) = |success| { notify_chan.take().send( @@ -647,7 +647,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let notify_chan = if opts.notify_chan.is_none() { None } else { - Some(opts.notify_chan.swap_unwrap()) + Some(opts.notify_chan.take_unwrap()) }; let child_wrapper = make_child_wrapper(new_task, child_tg, diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 2bd53f81b0581..0bf492ae55f0c 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -60,8 +60,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index b5b5b685d87c4..a5f96b35999e2 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -56,8 +56,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); From ad3a69739f508a2d6219479bf98ac9f853ac3574 Mon Sep 17 00:00:00 2001 From: OGINO Masanori Date: Wed, 17 Jul 2013 07:18:42 +0900 Subject: [PATCH 06/11] Add project information to l10n templates. --- doc/po/rust.md.pot | 1113 +++++++++++++++------------ doc/po/rustpkg.md.pot | 10 +- doc/po/tutorial-borrowed-ptr.md.pot | 12 +- doc/po/tutorial-container.md.pot | 170 +++- doc/po/tutorial-ffi.md.pot | 12 +- doc/po/tutorial-macros.md.pot | 10 +- doc/po/tutorial-tasks.md.pot | 10 +- doc/po/tutorial.md.pot | 756 +++++++++--------- mk/docs.mk | 5 +- 9 files changed, 1202 insertions(+), 896 deletions(-) diff --git a/doc/po/rust.md.pot b/doc/po/rust.md.pot index 789b396153c0c..516ca32104adf 100644 --- a/doc/po/rust.md.pot +++ b/doc/po/rust.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:47+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,7 +24,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" @@ -456,9 +456,9 @@ msgstr "" #. type: Plain text #: doc/rust.md:223 msgid "" -"~~~~~~~~ {.keyword} as break copy do drop else enum extern false fn for if " -"impl let loop match mod mut priv pub ref return self static struct super " -"true trait type unsafe use while ~~~~~~~~" +"~~~~~~~~ {.keyword} as break copy do else enum extern false fn for if impl " +"let loop match mod mut priv pub ref return self static struct super true " +"trait type unsafe use while ~~~~~~~~" msgstr "" #. type: Plain text @@ -1637,7 +1637,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:807 -msgid "~~~~ use std::float::sin; use std::option::{Some, None};" +msgid "~~~~ use std::num::sin; use std::option::{Some, None};" msgstr "" #. type: Plain text @@ -1645,7 +1645,7 @@ msgstr "" #, no-wrap msgid "" "fn main() {\n" -" // Equivalent to 'info!(std::float::sin(1.0));'\n" +" // Equivalent to 'info!(std::num::sin(1.0));'\n" " info!(sin(1.0));\n" msgstr "" @@ -2423,7 +2423,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1231 doc/tutorial.md:2179 +#: doc/rust.md:1231 doc/tutorial.md:2177 msgid "" "In type-parameterized functions, methods of the supertrait may be called on " "values of subtrait-bound type parameters. Refering to the previous example " @@ -2431,7 +2431,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1240 doc/tutorial.md:2188 +#: doc/rust.md:1240 doc/tutorial.md:2186 #, no-wrap msgid "" "~~~\n" @@ -2445,7 +2445,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1242 doc/tutorial.md:2190 +#: doc/rust.md:1242 doc/tutorial.md:2188 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" @@ -2792,15 +2792,25 @@ msgstr "" msgid "The `test` attribute, for marking functions as unit tests." msgstr "" -#. type: Plain text +#. type: Bullet: '* ' #: doc/rust.md:1425 -#, no-wrap msgid "" -"* The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint checks. Lint checks supported\n" -"by the compiler can be found via `rustc -W help`.\n" -"* The `deriving` attribute, for automatically generating\n" -" implementations of certain traits.\n" -"* The `static_assert` attribute, for asserting that a static bool is true at compiletime\n" +"The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint " +"checks (see [Lint check attributes](#lint-check-attributes))." +msgstr "" + +#. type: Bullet: '* ' +#: doc/rust.md:1425 +msgid "" +"The `deriving` attribute, for automatically generating implementations of " +"certain traits." +msgstr "" + +#. type: Bullet: '* ' +#: doc/rust.md:1425 +msgid "" +"The `static_assert` attribute, for asserting that a static bool is true at " +"compiletime" msgstr "" #. type: Plain text @@ -2811,11 +2821,150 @@ msgstr "" #. type: Plain text #: doc/rust.md:1429 -msgid "### Language items" +msgid "### Lint check attributes" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1433 +msgid "" +"A lint check names a potentially undesirable coding pattern, such as " +"unreachable code or omitted documentation, for the static entity to which " +"the attribute applies." msgstr "" #. type: Plain text #: doc/rust.md:1435 +msgid "For any lint check `C`:" +msgstr "" + +#. type: Bullet: ' * ' +#: doc/rust.md:1442 +msgid "`warn(C)` warns about violations of `C` but continues compilation," +msgstr "" + +#. type: Bullet: ' * ' +#: doc/rust.md:1442 +msgid "`deny(C)` signals an error after encountering a violation of `C`," +msgstr "" + +#. type: Plain text +#: doc/rust.md:1442 +#, no-wrap +msgid "" +" * `allow(C)` overrides the check for `C` so that violations will go\n" +" unreported,\n" +" * `forbid(C)` is the same as `deny(C)`, but also forbids uses of\n" +" `allow(C)` within the entity.\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1445 +msgid "" +"The lint checks supported by the compiler can be found via `rustc -W help`, " +"along with their default settings." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1451 +#, no-wrap +msgid "" +"~~~{.xfail-test}\n" +"mod m1 {\n" +" // Missing documentation is ignored here\n" +" #[allow(missing_doc)]\n" +" pub fn undocumented_one() -> int { 1 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1455 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here\n" +" #[warn(missing_doc)]\n" +" pub fn undocumented_too() -> int { 2 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1461 +#, no-wrap +msgid "" +" // Missing documentation signals an error here\n" +" #[deny(missing_doc)]\n" +" pub fn undocumented_end() -> int { 3 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1464 +msgid "" +"This example shows how one can use `allow` and `warn` to toggle a particular " +"check on and off." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1472 +#, no-wrap +msgid "" +"~~~\n" +"#[warn(missing_doc)]\n" +"mod m2{\n" +" #[allow(missing_doc)]\n" +" mod nested {\n" +" // Missing documentation is ignored here\n" +" pub fn undocumented_one() -> int { 1 }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1478 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here,\n" +" // despite the allow above.\n" +" #[warn(missing_doc)]\n" +" pub fn undocumented_two() -> int { 2 }\n" +" }\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1483 +#, no-wrap +msgid "" +" // Missing documentation signals a warning here\n" +" pub fn undocumented_too() -> int { 3 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1486 +msgid "" +"This example shows how one can use `forbid` to disallow uses of `allow` for " +"that lint check." +msgstr "" + +#. type: Plain text +#: doc/rust.md:1496 +#, no-wrap +msgid "" +"~~~{.xfail-test}\n" +"#[forbid(missing_doc)]\n" +"mod m3 {\n" +" // Attempting to toggle warning signals an error here\n" +" #[allow(missing_doc)]\n" +" /// Returns 2.\n" +" pub fn undocumented_too() -> int { 2 }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1498 +msgid "### Language items" +msgstr "" + +#. type: Plain text +#: doc/rust.md:1504 msgid "" "Some primitive Rust operations are defined in Rust code, rather than being " "implemented directly in C or assembly language. The definitions of these " @@ -2825,7 +2974,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1442 +#: doc/rust.md:1511 #, no-wrap msgid "" "~~~ {.xfail-test}\n" @@ -2837,7 +2986,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1446 +#: doc/rust.md:1515 msgid "" "The name `str_eq` has a special meaning to the Rust compiler, and the " "presence of this definition means that it will use this definition when " @@ -2845,17 +2994,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1448 +#: doc/rust.md:1517 msgid "A complete list of the built-in language items follows:" msgstr "" #. type: Plain text -#: doc/rust.md:1450 +#: doc/rust.md:1519 msgid "#### Traits" msgstr "" #. type: Plain text -#: doc/rust.md:1491 +#: doc/rust.md:1560 #, no-wrap msgid "" "`const`\n" @@ -2901,12 +3050,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1493 +#: doc/rust.md:1562 msgid "#### Operations" msgstr "" #. type: Plain text -#: doc/rust.md:1522 +#: doc/rust.md:1591 #, no-wrap msgid "" "`str_eq`\n" @@ -2940,19 +3089,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1525 +#: doc/rust.md:1594 msgid "" "> **Note:** This list is likely to become out of date. We should auto-" "generate it > from `librustc/middle/lang_items.rs`." msgstr "" #. type: Plain text -#: doc/rust.md:1527 +#: doc/rust.md:1596 msgid "### Deriving" msgstr "" #. type: Plain text -#: doc/rust.md:1533 +#: doc/rust.md:1602 msgid "" "The `deriving` attribute allows certain traits to be automatically " "implemented for data structures. For example, the following will create an " @@ -2961,7 +3110,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1541 +#: doc/rust.md:1610 #, no-wrap msgid "" "~~~\n" @@ -2974,12 +3123,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1543 +#: doc/rust.md:1612 msgid "The generated `impl` for `Eq` is equivalent to" msgstr "" #. type: Plain text -#: doc/rust.md:1550 +#: doc/rust.md:1619 #, no-wrap msgid "" "~~~\n" @@ -2991,7 +3140,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1556 +#: doc/rust.md:1625 #, no-wrap msgid "" " fn ne(&self, other: &Foo) -> bool {\n" @@ -3002,42 +3151,42 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1558 +#: doc/rust.md:1627 msgid "Supported traits for `deriving` are:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "Serialization: `Encodable`, `Decodable`. These require `extra`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Clone` and `DeepClone`, to perform (deep) copies." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`IterBytes`, to iterate over the bytes in a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Rand`, to create a random instance of a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "`Zero`, to create an zero (or empty) instance of a data type." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:1569 +#: doc/rust.md:1638 msgid "" "`ToStr`, to convert to a string. For a type with this instance, `obj." "to_str()` has similar output as `fmt!(\"%?\", obj)`, but it differs in that " @@ -3046,12 +3195,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1571 +#: doc/rust.md:1640 msgid "# Statements and expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1578 +#: doc/rust.md:1647 msgid "" "Rust is _primarily_ an expression language. This means that most forms of " "value-producing or effect-causing evaluation are directed by the uniform " @@ -3062,38 +3211,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1581 +#: doc/rust.md:1650 msgid "" "In contrast, statements in Rust serve _mostly_ to contain and explicitly " "sequence expression evaluation." msgstr "" #. type: Plain text -#: doc/rust.md:1583 +#: doc/rust.md:1652 msgid "## Statements" msgstr "" #. type: Plain text -#: doc/rust.md:1586 +#: doc/rust.md:1655 msgid "" "A _statement_ is a component of a block, which is in turn a component of an " "outer [expression](#expressions) or [function](#functions)." msgstr "" #. type: Plain text -#: doc/rust.md:1590 +#: doc/rust.md:1659 msgid "" "Rust has two kinds of statement: [declaration statements](#declaration-" "statements) and [expression statements](#expression-statements)." msgstr "" #. type: Plain text -#: doc/rust.md:1592 +#: doc/rust.md:1661 msgid "### Declaration statements" msgstr "" #. type: Plain text -#: doc/rust.md:1595 +#: doc/rust.md:1664 msgid "" "A _declaration statement_ is one that introduces one or more *names* into " "the enclosing statement block. The declared names may denote new slots or " @@ -3101,12 +3250,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1597 +#: doc/rust.md:1666 msgid "#### Item declarations" msgstr "" #. type: Plain text -#: doc/rust.md:1604 +#: doc/rust.md:1673 msgid "" "An _item declaration statement_ has a syntactic form identical to an [item]" "(#items) declaration within a module. Declaring an item -- a function, " @@ -3117,26 +3266,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1607 +#: doc/rust.md:1676 msgid "" "Note: there is no implicit capture of the function's dynamic environment " "when declaring a function-local item." msgstr "" #. type: Plain text -#: doc/rust.md:1610 +#: doc/rust.md:1679 msgid "#### Slot declarations" msgstr "" #. type: Plain text -#: doc/rust.md:1615 +#: doc/rust.md:1684 msgid "" "~~~~~~~~{.ebnf .gram} let_decl : \"let\" pat [':' type ] ? [ init ] ? ';' ; " "init : [ '=' ] expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1621 +#: doc/rust.md:1690 msgid "" "A _slot declaration_ introduces a new set of slots, given by a pattern. The " "pattern may be followed by a type annotation, and/or an initializer " @@ -3147,12 +3296,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1623 +#: doc/rust.md:1692 msgid "### Expression statements" msgstr "" #. type: Plain text -#: doc/rust.md:1628 +#: doc/rust.md:1697 msgid "" "An _expression statement_ is one that evaluates an [expression]" "(#expressions) and ignores its result. The type of an expression statement " @@ -3162,12 +3311,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1630 +#: doc/rust.md:1699 msgid "## Expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1639 +#: doc/rust.md:1708 #, no-wrap msgid "" "An expression may have two roles: it always produces a *value*, and it may have *effects*\n" @@ -3181,7 +3330,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1644 +#: doc/rust.md:1713 msgid "" "In this way, the structure of expressions dictates the structure of " "execution. Blocks are just another kind of expression, so blocks, " @@ -3190,12 +3339,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1646 +#: doc/rust.md:1715 msgid "#### Lvalues, rvalues and temporaries" msgstr "" #. type: Plain text -#: doc/rust.md:1650 +#: doc/rust.md:1719 msgid "" "Expressions are divided into two main categories: _lvalues_ and _rvalues_. " "Likewise within each expression, sub-expressions may occur in _lvalue " @@ -3204,14 +3353,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1653 +#: doc/rust.md:1722 msgid "" "[Path](#path-expressions), [field](#field-expressions) and [index](#index-" "expressions) expressions are lvalues. All other expressions are rvalues." msgstr "" #. type: Plain text -#: doc/rust.md:1661 +#: doc/rust.md:1730 msgid "" "The left operand of an [assignment](#assignment-expressions), [binary move]" "(#binary-move-expressions) or [compound-assignment](#compound-assignment-" @@ -3222,7 +3371,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1664 +#: doc/rust.md:1733 msgid "" "When an lvalue is evaluated in an _lvalue context_, it denotes a memory " "location; when evaluated in an _rvalue context_, it denotes the value held " @@ -3230,7 +3379,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1667 +#: doc/rust.md:1736 msgid "" "When an rvalue is used in lvalue context, a temporary un-named lvalue is " "created and used instead. A temporary's lifetime equals the largest " @@ -3238,12 +3387,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1669 +#: doc/rust.md:1738 msgid "#### Moved and copied types" msgstr "" #. type: Plain text -#: doc/rust.md:1675 +#: doc/rust.md:1744 msgid "" "When a [local variable](#memory-slots) is used as an [rvalue](#lvalues-" "rvalues-and-temporaries) the variable will either be [moved](#move-" @@ -3253,12 +3402,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1678 +#: doc/rust.md:1747 msgid "### Literal expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1682 +#: doc/rust.md:1751 msgid "" "A _literal expression_ consists of one of the [literal](#literals) forms " "described earlier. It directly describes a number, character, string, " @@ -3266,7 +3415,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1689 +#: doc/rust.md:1758 #, no-wrap msgid "" "~~~~~~~~ {.literals}\n" @@ -3278,12 +3427,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1691 +#: doc/rust.md:1760 msgid "### Path expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1694 +#: doc/rust.md:1763 msgid "" "A [path](#paths) used as an expression context denotes either a local " "variable or an item. Path expressions are [lvalues](#lvalues-rvalues-and-" @@ -3291,29 +3440,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1696 +#: doc/rust.md:1765 msgid "### Tuple expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1700 +#: doc/rust.md:1769 msgid "" "Tuples are written by enclosing one or more comma-separated expressions in " "parentheses. They are used to create [tuple-typed](#tuple-types) values." msgstr "" #. type: Plain text -#: doc/rust.md:1706 +#: doc/rust.md:1775 msgid "~~~~~~~~ {.tuple} (0,); (0f, 4.5f); (\"a\", 4u, true); ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1708 +#: doc/rust.md:1777 msgid "### Structure expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1717 +#: doc/rust.md:1786 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -3327,7 +3476,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1724 +#: doc/rust.md:1793 msgid "" "There are several forms of structure expressions. A _structure expression_ " "consists of the [path](#paths) of a [structure item](#structures), followed " @@ -3339,7 +3488,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1729 +#: doc/rust.md:1798 msgid "" "A _tuple structure expression_ consists of the [path](#paths) of a " "[structure item](#structures), followed by a parenthesized list of one or " @@ -3349,19 +3498,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1731 +#: doc/rust.md:1800 msgid "" "A _unit-like structure expression_ consists only of the [path](#paths) of a " "[structure item](#structures)." msgstr "" #. type: Plain text -#: doc/rust.md:1733 +#: doc/rust.md:1802 msgid "The following are examples of structure expressions:" msgstr "" #. type: Plain text -#: doc/rust.md:1744 +#: doc/rust.md:1813 msgid "" "~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, " "float); # mod game { pub struct User<'self> { name: &'self str, age: uint, " @@ -3371,7 +3520,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1747 +#: doc/rust.md:1816 msgid "" "A structure expression forms a new value of the named structure type. Note " "that for a given *unit-like* structure type, this will always be the same " @@ -3379,7 +3528,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1754 +#: doc/rust.md:1823 msgid "" "A structure expression can terminate with the syntax `..` followed by an " "expression to denote a functional update. The expression following `..` " @@ -3391,19 +3540,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1760 +#: doc/rust.md:1829 msgid "" "~~~~ # struct Point3d { x: int, y: int, z: int } let base = Point3d {x: 1, " "y: 2, z: 3}; Point3d {y: 0, z: 10, .. base}; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1762 +#: doc/rust.md:1831 msgid "### Record expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1768 +#: doc/rust.md:1837 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -3414,19 +3563,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1770 +#: doc/rust.md:1839 msgid "### Method-call expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1774 +#: doc/rust.md:1843 msgid "" "~~~~~~~~{.ebnf .gram} method_call_expr : expr '.' ident paren_expr_list ; " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1779 +#: doc/rust.md:1848 msgid "" "A _method call_ consists of an expression followed by a single dot, an " "identifier, and a parenthesized expression-list. Method calls are resolved " @@ -3437,17 +3586,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1782 +#: doc/rust.md:1851 msgid "### Field expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1786 +#: doc/rust.md:1855 msgid "~~~~~~~~{.ebnf .gram} field_expr : expr '.' ident ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1790 +#: doc/rust.md:1859 msgid "" "A _field expression_ consists of an expression followed by a single dot and " "an identifier, when not immediately followed by a parenthesized expression-" @@ -3456,12 +3605,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1795 +#: doc/rust.md:1864 msgid "~~~~~~~~ {.field} myrecord.myfield; {a: 10, b: 20}.a; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1798 +#: doc/rust.md:1867 msgid "" "A field access on a record is an [lvalue](#lvalues-rvalues-and-temporaries) " "referring to the value of that field. When the field is mutable, it can be " @@ -3469,7 +3618,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1801 +#: doc/rust.md:1870 msgid "" "When the type of the expression to the left of the dot is a pointer to a " "record or structure, it is automatically derferenced to make the field " @@ -3477,29 +3626,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1804 +#: doc/rust.md:1873 msgid "### Vector expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1807 +#: doc/rust.md:1876 msgid "~~~~~~~~{.ebnf .gram} vec_expr : '[' \"mut\"? vec_elems? ']'" msgstr "" #. type: Plain text -#: doc/rust.md:1810 +#: doc/rust.md:1879 msgid "vec_elems : [expr [',' expr]*] | [expr ',' \"..\" expr] ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1813 +#: doc/rust.md:1882 msgid "" "A [_vector_](#vector-types) _expression_ is written by enclosing zero or " "more comma-separated expressions of uniform type in square brackets." msgstr "" #. type: Plain text -#: doc/rust.md:1817 +#: doc/rust.md:1886 msgid "" "In the `[expr ',' \"..\" expr]` form, the expression after the `\"..\"` must " "be a constant expression that can be evaluated at compile time, such as a " @@ -3507,7 +3656,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1824 +#: doc/rust.md:1893 #, no-wrap msgid "" "~~~~\n" @@ -3519,17 +3668,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1826 +#: doc/rust.md:1895 msgid "### Index expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1830 +#: doc/rust.md:1899 msgid "~~~~~~~~{.ebnf .gram} idx_expr : expr '[' expr ']' ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1835 +#: doc/rust.md:1904 msgid "" "[Vector](#vector-types)-typed expressions can be indexed by writing a square-" "bracket-enclosed expression (the index) after them. When the vector is " @@ -3538,7 +3687,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1839 +#: doc/rust.md:1908 msgid "" "Indices are zero-based, and may be of any integral type. Vector access is " "bounds-checked at run-time. When the check fails, it will put the task in a " @@ -3546,27 +3695,27 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1843 +#: doc/rust.md:1912 msgid "~~~~ # use std::task; # do task::spawn_unlinked {" msgstr "" #. type: Plain text -#: doc/rust.md:1846 +#: doc/rust.md:1915 msgid "([1, 2, 3, 4])[0]; ([\"a\", \"b\"])[10]; // fails" msgstr "" #. type: Plain text -#: doc/rust.md:1849 doc/tutorial-tasks.md:649 +#: doc/rust.md:1918 doc/tutorial-tasks.md:649 msgid "# } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1851 +#: doc/rust.md:1920 msgid "### Unary operator expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1855 +#: doc/rust.md:1924 msgid "" "Rust defines six symbolic unary operators, in addition to the unary [copy]" "(#unary-copy-expressions) and [move](#unary-move-expressions) operators. " @@ -3575,7 +3724,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1874 +#: doc/rust.md:1943 #, no-wrap msgid "" "`-`\n" @@ -3599,29 +3748,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1876 +#: doc/rust.md:1945 msgid "### Binary operator expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1880 +#: doc/rust.md:1949 msgid "~~~~~~~~{.ebnf .gram} binop_expr : expr binop expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:1883 +#: doc/rust.md:1952 msgid "" "Binary operators expressions are given in terms of [operator precedence]" "(#operator-precedence)." msgstr "" #. type: Plain text -#: doc/rust.md:1885 +#: doc/rust.md:1954 msgid "#### Arithmetic operators" msgstr "" #. type: Plain text -#: doc/rust.md:1890 +#: doc/rust.md:1959 msgid "" "Binary arithmetic expressions are syntactic sugar for calls to built-in " "traits, defined in the `std::ops` module of the `std` library. This means " @@ -3630,7 +3779,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1906 +#: doc/rust.md:1975 #, no-wrap msgid "" "`+`\n" @@ -3651,12 +3800,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1908 +#: doc/rust.md:1977 msgid "#### Bitwise operators" msgstr "" #. type: Plain text -#: doc/rust.md:1913 +#: doc/rust.md:1982 msgid "" "Like the [arithmetic operators](#arithmetic-operators), bitwise operators " "are syntactic sugar for calls to methods of built-in traits. This means " @@ -3665,7 +3814,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1929 +#: doc/rust.md:1998 #, no-wrap msgid "" "`&`\n" @@ -3686,12 +3835,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1931 +#: doc/rust.md:2000 msgid "#### Lazy boolean operators" msgstr "" #. type: Plain text -#: doc/rust.md:1938 +#: doc/rust.md:2007 msgid "" "The operators `||` and `&&` may be applied to operands of boolean type. The " "`||` operator denotes logical 'or', and the `&&` operator denotes logical " @@ -3703,12 +3852,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1940 +#: doc/rust.md:2009 msgid "#### Comparison operators" msgstr "" #. type: Plain text -#: doc/rust.md:1946 +#: doc/rust.md:2015 msgid "" "Comparison operators are, like the [arithmetic operators](#arithmetic-" "operators), and [bitwise operators](#bitwise-operators), syntactic sugar for " @@ -3718,7 +3867,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1965 +#: doc/rust.md:2034 #, no-wrap msgid "" "`==`\n" @@ -3742,24 +3891,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1968 +#: doc/rust.md:2037 msgid "#### Type cast expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1970 +#: doc/rust.md:2039 msgid "A type cast expression is denoted with the binary operator `as`." msgstr "" #. type: Plain text -#: doc/rust.md:1973 +#: doc/rust.md:2042 msgid "" "Executing an `as` expression casts the value on the left-hand side to the " "type on the right-hand side." msgstr "" #. type: Plain text -#: doc/rust.md:1977 +#: doc/rust.md:2046 msgid "" "A numeric value can be cast to any numeric type. A raw pointer value can be " "cast to or from any integral type or raw pointer type. Any other cast is " @@ -3767,19 +3916,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1979 +#: doc/rust.md:2048 msgid "An example of an `as` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:1983 +#: doc/rust.md:2052 msgid "" "~~~~ # fn sum(v: &[float]) -> float { 0.0 } # fn len(v: &[float]) -> int " "{ 0 }" msgstr "" #. type: Plain text -#: doc/rust.md:1990 +#: doc/rust.md:2059 #, no-wrap msgid "" "fn avg(v: &[float]) -> float {\n" @@ -3791,12 +3940,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1992 +#: doc/rust.md:2061 msgid "#### Assignment expressions" msgstr "" #. type: Plain text -#: doc/rust.md:1995 +#: doc/rust.md:2064 msgid "" "An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-" "temporaries) expression followed by an equals sign (`=`) and an [rvalue]" @@ -3804,29 +3953,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1997 +#: doc/rust.md:2066 msgid "" "Evaluating an assignment expression [either copies or moves](#moved-and-" "copied-types) its right-hand operand to its left-hand operand." msgstr "" #. type: Plain text -#: doc/rust.md:2001 +#: doc/rust.md:2070 msgid "~~~~ # let mut x = 0; # let y = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2004 +#: doc/rust.md:2073 msgid "x = y; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2006 +#: doc/rust.md:2075 msgid "#### Compound assignment expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2011 +#: doc/rust.md:2080 msgid "" "The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be " "composed with the `=` operator. The expression `lval OP= val` is equivalent " @@ -3834,24 +3983,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2013 +#: doc/rust.md:2082 msgid "Any such expression always has the [`unit`](#primitive-types) type." msgstr "" #. type: Plain text -#: doc/rust.md:2015 +#: doc/rust.md:2084 msgid "#### Operator precedence" msgstr "" #. type: Plain text -#: doc/rust.md:2018 +#: doc/rust.md:2087 msgid "" "The precedence of Rust binary operators is ordered as follows, going from " "strong to weak:" msgstr "" #. type: Plain text -#: doc/rust.md:2031 +#: doc/rust.md:2100 #, no-wrap msgid "" "~~~~ {.precedence}\n" @@ -3870,12 +4019,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2033 doc/rust.md:2174 doc/tutorial-macros.md:323 +#: doc/rust.md:2102 doc/rust.md:2243 doc/tutorial-macros.md:323 msgid "~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2036 +#: doc/rust.md:2105 msgid "" "Operators at the same precedence level are evaluated left-to-right. [Unary " "operators](#unary-operator-expressions) have the same precedence level and " @@ -3883,12 +4032,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2038 +#: doc/rust.md:2107 msgid "### Grouped expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2042 +#: doc/rust.md:2111 msgid "" "An expression enclosed in parentheses evaluates to the result of the " "enclosed expression. Parentheses can be used to explicitly specify " @@ -3896,46 +4045,46 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2046 +#: doc/rust.md:2115 msgid "~~~~~~~~{.ebnf .gram} paren_expr : '(' expr ')' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2048 +#: doc/rust.md:2117 msgid "An example of a parenthesized expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2052 +#: doc/rust.md:2121 msgid "~~~~ let x = (2 + 3) * 4; ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2054 +#: doc/rust.md:2123 msgid "### Unary copy expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2058 +#: doc/rust.md:2127 msgid "~~~~~~~~{.ebnf .gram} copy_expr : \"copy\" expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2061 +#: doc/rust.md:2130 msgid "" "> **Note:** `copy` expressions are deprecated. It's preferable to use > the " "`Clone` trait and `clone()` method." msgstr "" #. type: Plain text -#: doc/rust.md:2064 +#: doc/rust.md:2133 msgid "" "A _unary copy expression_ consists of the unary `copy` operator applied to " "some argument expression." msgstr "" #. type: Plain text -#: doc/rust.md:2068 +#: doc/rust.md:2137 msgid "" "Evaluating a copy expression first evaluates the argument expression, then " "copies the resulting value, allocating any memory necessary to hold the new " @@ -3943,7 +4092,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2072 +#: doc/rust.md:2141 msgid "" "[Managed boxes](#pointer-types) (type `@`) are, as usual, shallow-copied, as " "are raw and borrowed pointers. [Owned boxes](#pointer-types), [owned " @@ -3951,7 +4100,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2075 +#: doc/rust.md:2144 msgid "" "Since the binary [assignment operator](#assignment-expressions) `=` performs " "a copy or move implicitly, the unary copy operator is typically only used to " @@ -3959,12 +4108,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2077 +#: doc/rust.md:2146 msgid "An example of a copy expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2082 +#: doc/rust.md:2151 #, no-wrap msgid "" "~~~~\n" @@ -3974,33 +4123,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2084 +#: doc/rust.md:2153 msgid "let v = ~[1,2,3];" msgstr "" #. type: Plain text -#: doc/rust.md:2086 +#: doc/rust.md:2155 #, no-wrap msgid "mutate(copy v); // Pass a copy\n" msgstr "" #. type: Plain text -#: doc/rust.md:2089 +#: doc/rust.md:2158 msgid "assert!(v[0] == 1); // Original was not modified ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2091 +#: doc/rust.md:2160 msgid "### Unary move expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2095 +#: doc/rust.md:2164 msgid "~~~~~~~~{.ebnf .gram} move_expr : \"move\" expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2102 +#: doc/rust.md:2171 msgid "" "A _unary move expression_ is similar to a [unary copy](#unary-copy-" "expressions) expression, except that it can only be applied to a [local " @@ -4011,7 +4160,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2106 +#: doc/rust.md:2175 msgid "" "> **Note:** In future versions of Rust, `move` may be removed as a separate " "operator; > moves are now [automatically performed](#moved-and-copied-types) " @@ -4019,12 +4168,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2109 +#: doc/rust.md:2178 msgid "### Call expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2115 +#: doc/rust.md:2184 msgid "" "~~~~~~~~ {.abnf .gram} expr_list : [ expr [ ',' expr ]* ] ? ; " "paren_expr_list : '(' expr_list ')' ; call_expr : expr paren_expr_list ; " @@ -4032,7 +4181,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2120 +#: doc/rust.md:2189 msgid "" "A _call expression_ invokes a function, providing zero or more input slots " "and an optional reference slot to serve as the function's output, bound to " @@ -4041,36 +4190,36 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2122 +#: doc/rust.md:2191 msgid "Some examples of call expressions:" msgstr "" #. type: Plain text -#: doc/rust.md:2126 +#: doc/rust.md:2195 msgid "" "~~~~ # use std::from_str::FromStr; # fn add(x: int, y: int) -> int { 0 }" msgstr "" #. type: Plain text -#: doc/rust.md:2130 +#: doc/rust.md:2199 msgid "" "let x: int = add(1, 2); let pi = FromStr::from_str::(\"3.14\"); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2132 +#: doc/rust.md:2201 msgid "### Lambda expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2137 +#: doc/rust.md:2206 msgid "" "~~~~~~~~ {.abnf .gram} ident_list : [ ident [ ',' ident ]* ] ? ; " "lambda_expr : '|' ident_list '|' expr ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2141 +#: doc/rust.md:2210 msgid "" "A _lambda expression_ (sometimes called an \"anonymous function expression" "\") defines a function and denotes it as a value, in a single expression. A " @@ -4079,7 +4228,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2146 +#: doc/rust.md:2215 msgid "" "A lambda expression denotes a function that maps a list of parameters " "(`ident_list`) onto the expression that follows the `ident_list`. The " @@ -4089,7 +4238,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2149 +#: doc/rust.md:2218 msgid "" "Lambda expressions are most useful when passing functions as arguments to " "other functions, as an abbreviation for defining and capturing a separate " @@ -4097,7 +4246,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2158 +#: doc/rust.md:2227 msgid "" "Significantly, lambda expressions _capture their environment_, which regular " "[function definitions](#functions) do not. The exact type of capture " @@ -4111,14 +4260,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2161 +#: doc/rust.md:2230 msgid "" "In this example, we define a function `ten_times` that takes a higher-order " "function argument, and call it with a lambda expression as an argument." msgstr "" #. type: Plain text -#: doc/rust.md:2170 +#: doc/rust.md:2239 #, no-wrap msgid "" "~~~~\n" @@ -4132,23 +4281,23 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2172 +#: doc/rust.md:2241 msgid "ten_times(|j| println(fmt!(\"hello, %d\", j)));" msgstr "" #. type: Plain text -#: doc/rust.md:2176 +#: doc/rust.md:2245 msgid "### While loops" msgstr "" #. type: Plain text -#: doc/rust.md:2180 +#: doc/rust.md:2249 msgid "" "~~~~~~~~{.ebnf .gram} while_expr : \"while\" expr '{' block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2185 +#: doc/rust.md:2254 msgid "" "A `while` loop begins by evaluating the boolean loop conditional " "expression. If the loop conditional expression evaluates to `true`, the " @@ -4158,17 +4307,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2187 +#: doc/rust.md:2256 msgid "An example:" msgstr "" #. type: Plain text -#: doc/rust.md:2190 +#: doc/rust.md:2259 msgid "~~~~ let mut i = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2196 +#: doc/rust.md:2265 #, no-wrap msgid "" "while i < 10 {\n" @@ -4179,12 +4328,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2198 +#: doc/rust.md:2267 msgid "### Infinite loops" msgstr "" #. type: Plain text -#: doc/rust.md:2202 +#: doc/rust.md:2271 msgid "" "The keyword `loop` in Rust appears both in _loop expressions_ and in " "_continue expressions_. A loop expression denotes an infinite loop; see " @@ -4192,14 +4341,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2206 +#: doc/rust.md:2275 msgid "" "~~~~~~~~{.ebnf .gram} loop_expr : [ lifetime ':' ] \"loop\" '{' block '}'; " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2211 +#: doc/rust.md:2280 msgid "" "A `loop` expression may optionally have a _label_. If a label is present, " "then labeled `break` and `loop` expressions nested within this loop may exit " @@ -4208,17 +4357,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2213 +#: doc/rust.md:2282 msgid "### Break expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2217 +#: doc/rust.md:2286 msgid "~~~~~~~~{.ebnf .gram} break_expr : \"break\" [ lifetime ]; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2224 +#: doc/rust.md:2293 msgid "" "A `break` expression has an optional `label`. If the label is absent, then " "executing a `break` expression immediately terminates the innermost loop " @@ -4229,17 +4378,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2226 +#: doc/rust.md:2295 msgid "### Continue expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2230 +#: doc/rust.md:2299 msgid "~~~~~~~~{.ebnf .gram} continue_expr : \"loop\" [ lifetime ]; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2241 +#: doc/rust.md:2310 msgid "" "A continue expression, written `loop`, also has an optional `label`. If the " "label is absent, then executing a `loop` expression immediately terminates " @@ -4253,24 +4402,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2243 +#: doc/rust.md:2312 msgid "A `loop` expression is only permitted in the body of a loop." msgstr "" #. type: Plain text -#: doc/rust.md:2246 +#: doc/rust.md:2315 msgid "### Do expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2250 +#: doc/rust.md:2319 msgid "" "~~~~~~~~{.ebnf .gram} do_expr : \"do\" expr [ '|' ident_list '|' ] ? '{' " "block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2253 +#: doc/rust.md:2322 msgid "" "A _do expression_ provides a more-familiar block-syntax for a [lambda " "expression](#lambda-expressions), including a special translation of [return " @@ -4278,7 +4427,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2261 +#: doc/rust.md:2330 msgid "" "Any occurrence of a [return expression](#return-expressions) inside this " "`block` expression is rewritten as a reference to an (anonymous) flag set in " @@ -4290,7 +4439,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2264 +#: doc/rust.md:2333 msgid "" "The optional `ident_list` and `block` provided in a `do` expression are " "parsed as though they constitute a lambda expression; if the `ident_list` is " @@ -4298,7 +4447,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2270 +#: doc/rust.md:2339 msgid "" "The lambda expression is then provided as a _trailing argument_ to the " "outermost [call](#call-expressions) or [method call](#method-call-" @@ -4309,22 +4458,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2272 +#: doc/rust.md:2341 msgid "In this example, both calls to `f` are equivalent:" msgstr "" #. type: Plain text -#: doc/rust.md:2276 +#: doc/rust.md:2345 msgid "~~~~ # fn f(f: &fn(int)) { } # fn g(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2278 +#: doc/rust.md:2347 msgid "f(|j| g(j));" msgstr "" #. type: Plain text -#: doc/rust.md:2283 +#: doc/rust.md:2352 #, no-wrap msgid "" "do f |j| {\n" @@ -4334,23 +4483,23 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2285 +#: doc/rust.md:2354 msgid "" "In this example, both calls to the (binary) function `k` are equivalent:" msgstr "" #. type: Plain text -#: doc/rust.md:2289 +#: doc/rust.md:2358 msgid "~~~~ # fn k(x:int, f: &fn(int)) { } # fn l(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2291 +#: doc/rust.md:2360 msgid "k(3, |j| l(j));" msgstr "" #. type: Plain text -#: doc/rust.md:2296 +#: doc/rust.md:2365 #, no-wrap msgid "" "do k(3) |j| {\n" @@ -4360,19 +4509,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2299 +#: doc/rust.md:2368 msgid "### For expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2303 +#: doc/rust.md:2372 msgid "" "~~~~~~~~{.ebnf .gram} for_expr : \"for\" expr [ '|' ident_list '|' ] ? '{' " "block '}' ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2307 +#: doc/rust.md:2376 msgid "" "A _for expression_ is similar to a [`do` expression](#do-expressions), in " "that it provides a special block-form of lambda expression, suited to " @@ -4380,7 +4529,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2313 +#: doc/rust.md:2382 msgid "" "In contrast to a `do` expression, a `for` expression is designed to work " "with methods such as `each` and `times`, that require the body block to " @@ -4390,7 +4539,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2320 +#: doc/rust.md:2389 msgid "" "In addition, [`break`](#break-expressions) and [`loop`](#loop-expressions) " "expressions are rewritten inside `for` expressions in the same way that " @@ -4401,24 +4550,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2322 +#: doc/rust.md:2391 msgid "An example of a for loop over the contents of a vector:" msgstr "" #. type: Plain text -#: doc/rust.md:2329 +#: doc/rust.md:2398 msgid "" "~~~~ # type foo = int; # fn bar(f: foo) { } # let a = 0; # let b = 0; # let " "c = 0;" msgstr "" #. type: Plain text -#: doc/rust.md:2331 +#: doc/rust.md:2400 msgid "let v: &[foo] = &[a, b, c];" msgstr "" #. type: Plain text -#: doc/rust.md:2336 +#: doc/rust.md:2405 #, no-wrap msgid "" "for v.iter().advance |e| {\n" @@ -4428,12 +4577,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2338 +#: doc/rust.md:2407 msgid "An example of a for loop over a series of integers:" msgstr "" #. type: Plain text -#: doc/rust.md:2346 +#: doc/rust.md:2415 #, no-wrap msgid "" "~~~~\n" @@ -4446,12 +4595,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2348 +#: doc/rust.md:2417 msgid "### If expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2352 +#: doc/rust.md:2421 #, no-wrap msgid "" "~~~~~~~~{.ebnf .gram}\n" @@ -4460,7 +4609,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2356 +#: doc/rust.md:2425 #, no-wrap msgid "" "else_tail : \"else\" [ if_expr\n" @@ -4469,7 +4618,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2367 +#: doc/rust.md:2436 msgid "" "An `if` expression is a conditional branch in program control. The form of " "an `if` expression is a condition expression, followed by a consequent " @@ -4483,29 +4632,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2370 +#: doc/rust.md:2439 msgid "### Match expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2373 +#: doc/rust.md:2442 msgid "" "~~~~~~~~{.ebnf .gram} match_expr : \"match\" expr '{' match_arm [ '|' " "match_arm ] * '}' ;" msgstr "" #. type: Plain text -#: doc/rust.md:2375 +#: doc/rust.md:2444 msgid "match_arm : match_pat '=>' [ expr \",\" | '{' block '}' ] ;" msgstr "" #. type: Plain text -#: doc/rust.md:2378 +#: doc/rust.md:2447 msgid "match_pat : pat [ \"..\" pat ] ? [ \"if\" expr ] ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2386 +#: doc/rust.md:2455 msgid "" "A `match` expression branches on a *pattern*. The exact form of matching " "that occurs depends on the pattern. Patterns consist of some combination of " @@ -4517,7 +4666,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2390 +#: doc/rust.md:2459 msgid "" "In a pattern whose head expression has an `enum` type, a placeholder (`_`) " "stands for a *single* data field, whereas a wildcard `*` stands for *all* " @@ -4525,17 +4674,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2393 +#: doc/rust.md:2462 msgid "~~~~ enum List { Nil, Cons(X, @List) }" msgstr "" #. type: Plain text -#: doc/rust.md:2395 doc/rust.md:2424 +#: doc/rust.md:2464 doc/rust.md:2493 msgid "let x: List = Cons(10, @Cons(11, @Nil));" msgstr "" #. type: Plain text -#: doc/rust.md:2402 +#: doc/rust.md:2471 #, no-wrap msgid "" "match x {\n" @@ -4547,7 +4696,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2407 +#: doc/rust.md:2476 msgid "" "The first pattern matches lists constructed by applying `Cons` to any head " "value, and a tail value of `@Nil`. The second pattern matches _any_ list " @@ -4558,7 +4707,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2413 +#: doc/rust.md:2482 msgid "" "To execute an `match` expression, first the head expression is evaluated, " "then its value is sequentially compared to the patterns in the arms until a " @@ -4568,22 +4717,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2415 +#: doc/rust.md:2484 msgid "An example of an `match` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2420 +#: doc/rust.md:2489 msgid "~~~~ # fn process_pair(a: int, b: int) { } # fn process_ten() { }" msgstr "" #. type: Plain text -#: doc/rust.md:2422 +#: doc/rust.md:2491 msgid "enum List { Nil, Cons(X, @List) }" msgstr "" #. type: Plain text -#: doc/rust.md:2440 +#: doc/rust.md:2509 #, no-wrap msgid "" "match x {\n" @@ -4604,7 +4753,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2446 +#: doc/rust.md:2515 msgid "" "Patterns that bind variables default to binding to a copy or move of the " "matched value (depending on the matched value's type). This can be made " @@ -4614,7 +4763,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2457 +#: doc/rust.md:2526 msgid "" "A pattern that's just an identifier, like `Nil` in the previous answer, " "could either refer to an enum variant that's in scope, or bind a new " @@ -4629,19 +4778,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2461 +#: doc/rust.md:2530 msgid "" "Multiple match patterns may be joined with the `|` operator. A range of " "values may be specified with `..`. For example:" msgstr "" #. type: Plain text -#: doc/rust.md:2464 +#: doc/rust.md:2533 msgid "~~~~ # let x = 2;" msgstr "" #. type: Plain text -#: doc/rust.md:2471 +#: doc/rust.md:2540 #, no-wrap msgid "" "let message = match x {\n" @@ -4653,7 +4802,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2475 +#: doc/rust.md:2544 msgid "" "Range patterns only work on scalar types (like integers and characters; not " "like vectors and structs, which have sub-components). A range pattern may " @@ -4661,7 +4810,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2480 +#: doc/rust.md:2549 msgid "" "Finally, match patterns can accept *pattern guards* to further refine the " "criteria for matching a case. Pattern guards appear after the pattern and " @@ -4670,14 +4819,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2485 +#: doc/rust.md:2554 msgid "" "~~~~ # let maybe_digit = Some(0); # fn process_digit(i: int) { } # fn " "process_other(i: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:2492 +#: doc/rust.md:2561 #, no-wrap msgid "" "let message = match maybe_digit {\n" @@ -4689,17 +4838,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2494 +#: doc/rust.md:2563 msgid "### Return expressions" msgstr "" #. type: Plain text -#: doc/rust.md:2498 +#: doc/rust.md:2567 msgid "~~~~~~~~{.ebnf .gram} return_expr : \"return\" expr ? ; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2503 +#: doc/rust.md:2572 msgid "" "Return expressions are denoted with the keyword `return`. Evaluating a " "`return` expression moves its argument into the output slot of the current " @@ -4708,12 +4857,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2505 +#: doc/rust.md:2574 msgid "An example of a `return` expression:" msgstr "" #. type: Plain text -#: doc/rust.md:2514 +#: doc/rust.md:2583 #, no-wrap msgid "" "~~~~\n" @@ -4727,24 +4876,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2517 +#: doc/rust.md:2586 msgid "# Type system" msgstr "" #. type: Plain text -#: doc/rust.md:2519 +#: doc/rust.md:2588 msgid "## Types" msgstr "" #. type: Plain text -#: doc/rust.md:2522 +#: doc/rust.md:2591 msgid "" "Every slot, item and value in a Rust program has a type. The _type_ of a " "*value* defines the interpretation of the memory holding it." msgstr "" #. type: Plain text -#: doc/rust.md:2526 +#: doc/rust.md:2595 msgid "" "Built-in types and type-constructors are tightly integrated into the " "language, in nontrivial ways that are not possible to emulate in user-" @@ -4752,17 +4901,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2528 +#: doc/rust.md:2597 msgid "### Primitive types" msgstr "" #. type: Plain text -#: doc/rust.md:2530 +#: doc/rust.md:2599 msgid "The primitive types are the following:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "" "The \"unit\" type `()`, having the single \"unit\" value `()` (occasionally " "called \"nil\"). ^[The \"unit\" value `()` is *not* a sentinel \"null " @@ -4773,32 +4922,32 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The boolean type `bool` with values `true` and `false`." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The machine types." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2536 +#: doc/rust.md:2605 msgid "The machine-dependent integer and floating-point types." msgstr "" #. type: Plain text -#: doc/rust.md:2538 +#: doc/rust.md:2607 msgid "#### Machine types" msgstr "" #. type: Plain text -#: doc/rust.md:2540 +#: doc/rust.md:2609 msgid "The machine types are the following:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2545 +#: doc/rust.md:2614 msgid "" "The unsigned word types `u8`, `u16`, `u32` and `u64`, with values drawn from " "the integer intervals $[0, 2^8 - 1]$, $[0, 2^{16} - 1]$, $[0, 2^{32} - 1]$ " @@ -4806,7 +4955,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2550 +#: doc/rust.md:2619 msgid "" "The signed two's complement word types `i8`, `i16`, `i32` and `i64`, with " "values drawn from the integer intervals $[-(2^7), 2^7 - 1]$, $[-(2^{15}), " @@ -4815,19 +4964,19 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2553 +#: doc/rust.md:2622 msgid "" "The IEEE 754-2008 `binary32` and `binary64` floating-point types: `f32` and " "`f64`, respectively." msgstr "" #. type: Plain text -#: doc/rust.md:2555 +#: doc/rust.md:2624 msgid "#### Machine-dependent integer types" msgstr "" #. type: Plain text -#: doc/rust.md:2560 +#: doc/rust.md:2629 msgid "" "The Rust type `uint`^[A Rust `uint` is analogous to a C99 `uintptr_t`.] is " "an unsigned integer type with target-machine-dependent size. Its size, in " @@ -4836,7 +4985,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2565 +#: doc/rust.md:2634 msgid "" "The Rust type `int`^[A Rust `int` is analogous to a C99 `intptr_t`.] is a " "two's complement signed integer type with target-machine-dependent size. Its " @@ -4845,12 +4994,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2568 +#: doc/rust.md:2637 msgid "#### Machine-dependent floating point type" msgstr "" #. type: Plain text -#: doc/rust.md:2575 +#: doc/rust.md:2644 msgid "" "The Rust type `float` is a machine-specific type equal to one of the " "supported Rust floating-point machine types (`f32` or `f64`). It is the " @@ -4861,31 +5010,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2578 +#: doc/rust.md:2647 msgid "" "Note that due to the preference for hardware-supported floating-point, the " "type `float` may not be equal to the largest *supported* floating-point type." msgstr "" #. type: Plain text -#: doc/rust.md:2581 +#: doc/rust.md:2650 msgid "### Textual types" msgstr "" #. type: Plain text -#: doc/rust.md:2583 +#: doc/rust.md:2652 msgid "The types `char` and `str` hold textual data." msgstr "" #. type: Plain text -#: doc/rust.md:2586 +#: doc/rust.md:2655 msgid "" "A value of type `char` is a Unicode character, represented as a 32-bit " "unsigned word holding a UCS-4 codepoint." msgstr "" #. type: Plain text -#: doc/rust.md:2592 +#: doc/rust.md:2661 msgid "" "A value of type `str` is a Unicode string, represented as a vector of 8-bit " "unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of " @@ -4894,61 +5043,61 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2595 +#: doc/rust.md:2664 msgid "### Tuple types" msgstr "" #. type: Plain text -#: doc/rust.md:2598 +#: doc/rust.md:2667 msgid "" "The tuple type-constructor forms a new heterogeneous product of values " "similar to the record type-constructor. The differences are as follows:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2601 +#: doc/rust.md:2670 msgid "tuple elements cannot be mutable, unlike record fields" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:2601 +#: doc/rust.md:2670 msgid "" "tuple elements are not named and can be accessed only by pattern-matching" msgstr "" #. type: Plain text -#: doc/rust.md:2605 +#: doc/rust.md:2674 msgid "" "Tuple types and values are denoted by listing the types or values of their " "elements, respectively, in a parenthesized, comma-separated list." msgstr "" #. type: Plain text -#: doc/rust.md:2608 +#: doc/rust.md:2677 msgid "" "The members of a tuple are laid out in memory contiguously, like a record, " "in order specified by the tuple type." msgstr "" #. type: Plain text -#: doc/rust.md:2610 +#: doc/rust.md:2679 msgid "An example of a tuple type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2617 +#: doc/rust.md:2686 msgid "" "~~~~ type Pair<'self> = (int,&'self str); let p: Pair<'static> = (10,\"hello" "\"); let (a, b) = p; assert!(b != \"world\"); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2620 +#: doc/rust.md:2689 msgid "### Vector types" msgstr "" #. type: Plain text -#: doc/rust.md:2633 +#: doc/rust.md:2702 msgid "" "The vector type constructor represents a homogeneous array of values of a " "given type. A vector has a fixed size. (Operations like `vec.push` operate " @@ -4963,7 +5112,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2637 +#: doc/rust.md:2706 msgid "" "Expressions producing vectors of definite size cannot be evaluated in a " "context expecting a vector of indefinite size; one must copy the definite-" @@ -4971,30 +5120,30 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2639 +#: doc/rust.md:2708 msgid "An example of a vector type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2645 +#: doc/rust.md:2714 msgid "" "~~~~ let v: &[int] = &[7, 5, 3]; let i: int = v[2]; assert!(i == 3); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2648 +#: doc/rust.md:2717 msgid "" "All in-bounds elements of a vector are always initialized, and access to a " "vector is always bounds-checked." msgstr "" #. type: Plain text -#: doc/rust.md:2651 +#: doc/rust.md:2720 msgid "### Structure types" msgstr "" #. type: Plain text -#: doc/rust.md:2656 +#: doc/rust.md:2725 msgid "" "A `struct` *type* is a heterogeneous product of other types, called the " "*fields* of the type. ^[`struct` types are analogous `struct` types in C, " @@ -5003,14 +5152,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2658 +#: doc/rust.md:2727 msgid "" "New instances of a `struct` can be constructed with a [struct expression]" "(#struct-expressions)." msgstr "" #. type: Plain text -#: doc/rust.md:2662 +#: doc/rust.md:2731 msgid "" "The memory order of fields in a `struct` is given by the item defining it. " "Fields may be given in any order in a corresponding struct *expression*; the " @@ -5019,7 +5168,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2665 +#: doc/rust.md:2734 msgid "" "The fields of a `struct` may be qualified by [visibility modifiers]" "(#visibility-modifiers), to restrict access to implementation-private data " @@ -5027,14 +5176,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2667 +#: doc/rust.md:2736 msgid "" "A _tuple struct_ type is just like a structure type, except that the fields " "are anonymous." msgstr "" #. type: Plain text -#: doc/rust.md:2670 +#: doc/rust.md:2739 msgid "" "A _unit-like struct_ type is like a structure type, except that it has no " "fields. The one value constructed by the associated [structure expression]" @@ -5042,12 +5191,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2672 +#: doc/rust.md:2741 msgid "### Enumerated types" msgstr "" #. type: Plain text -#: doc/rust.md:2677 +#: doc/rust.md:2746 msgid "" "An *enumerated type* is a nominal, heterogeneous disjoint union type, " "denoted by the name of an [`enum` item](#enumerations). ^[The `enum` type " @@ -5056,7 +5205,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2680 +#: doc/rust.md:2749 msgid "" "An [`enum` item](#enumerations) declares both the type and a number of " "*variant constructors*, each of which is independently named and takes an " @@ -5064,33 +5213,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2683 +#: doc/rust.md:2752 msgid "" "New instances of an `enum` can be constructed by calling one of the variant " "constructors, in a [call expression](#call-expressions)." msgstr "" #. type: Plain text -#: doc/rust.md:2685 +#: doc/rust.md:2754 msgid "" "Any `enum` value consumes as much memory as the largest variant constructor " "for its corresponding `enum` type." msgstr "" #. type: Plain text -#: doc/rust.md:2688 +#: doc/rust.md:2757 msgid "" "Enum types cannot be denoted *structurally* as types, but must be denoted by " "named reference to an [`enum` item](#enumerations)." msgstr "" #. type: Plain text -#: doc/rust.md:2691 +#: doc/rust.md:2760 msgid "### Recursive types" msgstr "" #. type: Plain text -#: doc/rust.md:2695 +#: doc/rust.md:2764 msgid "" "Nominal types -- [enumerations](#enumerated-types) and [structures]" "(#structure-types) -- may be recursive. That is, each `enum` constructor or " @@ -5099,7 +5248,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2705 +#: doc/rust.md:2774 #, no-wrap msgid "" "* Recursive types must include a nominal type in the recursion\n" @@ -5114,12 +5263,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2707 +#: doc/rust.md:2776 msgid "An example of a *recursive* type and its use:" msgstr "" #. type: Plain text -#: doc/rust.md:2713 +#: doc/rust.md:2782 #, no-wrap msgid "" "~~~~\n" @@ -5130,17 +5279,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2716 +#: doc/rust.md:2785 msgid "let a: List = Cons(7, @Cons(13, @Nil)); ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2719 +#: doc/rust.md:2788 msgid "### Pointer types" msgstr "" #. type: Plain text -#: doc/rust.md:2723 +#: doc/rust.md:2792 msgid "" "All pointers in Rust are explicit first-class values. They can be copied, " "stored into data structures, and returned from functions. There are four " @@ -5148,7 +5297,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2733 +#: doc/rust.md:2802 #, no-wrap msgid "" "Managed pointers (`@`)\n" @@ -5163,7 +5312,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2742 +#: doc/rust.md:2811 #, no-wrap msgid "" "Owning pointers (`~`)\n" @@ -5177,7 +5326,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2755 +#: doc/rust.md:2824 #, no-wrap msgid "" "Borrowed pointers (`&`)\n" @@ -5195,7 +5344,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2765 +#: doc/rust.md:2834 #, no-wrap msgid "" "Raw pointers (`*`)\n" @@ -5210,12 +5359,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2768 +#: doc/rust.md:2837 msgid "### Function types" msgstr "" #. type: Plain text -#: doc/rust.md:2772 +#: doc/rust.md:2841 msgid "" "The function type constructor `fn` forms new function types. A function " "type consists of a possibly-empty set of function-type modifiers (such as " @@ -5223,12 +5372,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2774 +#: doc/rust.md:2843 msgid "An example of a `fn` type:" msgstr "" #. type: Plain text -#: doc/rust.md:2779 +#: doc/rust.md:2848 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5238,24 +5387,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2781 +#: doc/rust.md:2850 msgid "let mut x = add(5,7);" msgstr "" #. type: Plain text -#: doc/rust.md:2786 +#: doc/rust.md:2855 msgid "" "type Binop<'self> = &'self fn(int,int) -> int; let bo: Binop = add; x = " "bo(5,7); ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2788 +#: doc/rust.md:2857 msgid "### Object types" msgstr "" #. type: Plain text -#: doc/rust.md:2795 +#: doc/rust.md:2864 msgid "" "Every trait item (see [traits](#traits)) defines a type with the same name " "as the trait. This type is called the _object type_ of the trait. Object " @@ -5268,7 +5417,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2800 +#: doc/rust.md:2869 msgid "" "Given a pointer-typed expression `E` of type `&T`, `~T` or `@T`, where `T` " "implements trait `R`, casting `E` to the corresponding pointer type `&R`, " @@ -5278,12 +5427,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2802 +#: doc/rust.md:2871 msgid "An example of an object type:" msgstr "" #. type: Plain text -#: doc/rust.md:2808 +#: doc/rust.md:2877 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5294,7 +5443,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2812 +#: doc/rust.md:2881 #, no-wrap msgid "" "impl Printable for int {\n" @@ -5303,7 +5452,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2816 +#: doc/rust.md:2885 #, no-wrap msgid "" "fn print(a: @Printable) {\n" @@ -5312,7 +5461,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2821 +#: doc/rust.md:2890 #, no-wrap msgid "" "fn main() {\n" @@ -5322,26 +5471,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2824 +#: doc/rust.md:2893 msgid "" "In this example, the trait `Printable` occurs as an object type in both the " "type signature of `print`, and the cast expression in `main`." msgstr "" #. type: Plain text -#: doc/rust.md:2826 +#: doc/rust.md:2895 msgid "### Type parameters" msgstr "" #. type: Plain text -#: doc/rust.md:2828 +#: doc/rust.md:2897 msgid "" "Within the body of an item that has type parameter declarations, the names " "of its type parameters are types:" msgstr "" #. type: Plain text -#: doc/rust.md:2837 +#: doc/rust.md:2906 #, no-wrap msgid "" "~~~~~~~\n" @@ -5355,26 +5504,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2840 +#: doc/rust.md:2909 msgid "" "Here, `first` has type `B`, referring to `map`'s `B` type parameter; and " "`rest` has type `~[B]`, a vector type with element type `B`." msgstr "" #. type: Plain text -#: doc/rust.md:2842 +#: doc/rust.md:2911 msgid "### Self types" msgstr "" #. type: Plain text -#: doc/rust.md:2846 +#: doc/rust.md:2915 msgid "" "The special type `self` has a meaning within methods inside an impl item. It " "refers to the type of the implicit `self` argument. For example, in:" msgstr "" #. type: Plain text -#: doc/rust.md:2851 +#: doc/rust.md:2920 #, no-wrap msgid "" "~~~~~~~~\n" @@ -5384,7 +5533,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2856 +#: doc/rust.md:2925 #, no-wrap msgid "" "impl Printable for ~str {\n" @@ -5394,26 +5543,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2859 +#: doc/rust.md:2928 msgid "" "`self` refers to the value of type `~str` that is the receiver for a call to " "the method `make_string`." msgstr "" #. type: Plain text -#: doc/rust.md:2861 +#: doc/rust.md:2930 msgid "## Type kinds" msgstr "" #. type: Plain text -#: doc/rust.md:2864 +#: doc/rust.md:2933 msgid "" "Types in Rust are categorized into kinds, based on various properties of the " "components of the type. The kinds are:" msgstr "" #. type: Plain text -#: doc/rust.md:2884 +#: doc/rust.md:2953 #, no-wrap msgid "" "`Freeze`\n" @@ -5438,7 +5587,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2891 +#: doc/rust.md:2960 #, no-wrap msgid "" "_Default_\n" @@ -5450,20 +5599,20 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2894 +#: doc/rust.md:2963 msgid "" "Kinds can be supplied as _bounds_ on type parameters, like traits, in which " "case the parameter is constrained to types satisfying that kind." msgstr "" #. type: Plain text -#: doc/rust.md:2896 +#: doc/rust.md:2965 msgid "" "By default, type parameters do not carry any assumed kind-bounds at all." msgstr "" #. type: Plain text -#: doc/rust.md:2900 +#: doc/rust.md:2969 msgid "" "Any operation that causes a value to be copied requires the type of that " "value to be of copyable kind, so the `Copy` bound is frequently required on " @@ -5471,24 +5620,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2904 +#: doc/rust.md:2973 msgid "~~~~{.xfail-test} fn box(x: T) -> @T { @x } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2907 +#: doc/rust.md:2976 msgid "" "Putting `x` into a managed box involves copying, and the `T` parameter has " "the default (non-copyable) kind. To change that, a bound is declared:" msgstr "" #. type: Plain text -#: doc/rust.md:2911 +#: doc/rust.md:2980 msgid "~~~~ fn box(x: T) -> @T { @x } ~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:2916 +#: doc/rust.md:2985 msgid "" "Calling this second version of `box` on a noncopyable type is not allowed. " "When instantiating a type parameter, the kind bounds on the parameter are " @@ -5497,7 +5646,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2920 +#: doc/rust.md:2989 msgid "" "Sending operations are not part of the Rust language, but are implemented in " "the library. Generic functions that send values bound the kind of these " @@ -5505,12 +5654,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2922 +#: doc/rust.md:2991 msgid "# Memory and concurrency models" msgstr "" #. type: Plain text -#: doc/rust.md:2927 +#: doc/rust.md:2996 msgid "" "Rust has a memory model centered around concurrently-executing _tasks_. Thus " "its memory model and its concurrency model are best discussed " @@ -5519,7 +5668,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2932 +#: doc/rust.md:3001 msgid "" "When reading about the memory model, keep in mind that it is partitioned in " "order to support tasks; and when reading about tasks, keep in mind that " @@ -5528,12 +5677,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2934 +#: doc/rust.md:3003 msgid "## Memory model" msgstr "" #. type: Plain text -#: doc/rust.md:2938 +#: doc/rust.md:3007 msgid "" "A Rust program's memory consists of a static set of *items*, a set of [tasks]" "(#tasks) each with its own *stack*, and a *heap*. Immutable portions of the " @@ -5541,19 +5690,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2941 +#: doc/rust.md:3010 msgid "" "Allocations in the stack consist of *slots*, and allocations in the heap " "consist of *boxes*." msgstr "" #. type: Plain text -#: doc/rust.md:2944 +#: doc/rust.md:3013 msgid "### Memory allocation and lifetime" msgstr "" #. type: Plain text -#: doc/rust.md:2949 +#: doc/rust.md:3018 msgid "" "The _items_ of a program are those functions, modules and types that have " "their value calculated at compile-time and stored uniquely in the memory " @@ -5561,7 +5710,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2953 +#: doc/rust.md:3022 msgid "" "A task's _stack_ consists of activation frames automatically allocated on " "entry to each function as the task executes. A stack allocation is reclaimed " @@ -5569,7 +5718,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2960 +#: doc/rust.md:3029 msgid "" "The _heap_ is a general term that describes two separate sets of boxes: " "managed boxes -- which may be subject to garbage collection -- and owned " @@ -5580,19 +5729,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2962 +#: doc/rust.md:3031 msgid "### Memory ownership" msgstr "" #. type: Plain text -#: doc/rust.md:2965 +#: doc/rust.md:3034 msgid "" "A task owns all memory it can *safely* reach through local variables, as " "well as managed, owning and borrowed pointers." msgstr "" #. type: Plain text -#: doc/rust.md:2972 +#: doc/rust.md:3041 msgid "" "When a task sends a value that has the `Send` trait to another task, it " "loses ownership of the value sent and can no longer refer to it. This is " @@ -5603,14 +5752,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2975 +#: doc/rust.md:3044 msgid "" "When a stack frame is exited, its local allocations are all released, and " "its references to boxes (both managed and owned) are dropped." msgstr "" #. type: Plain text -#: doc/rust.md:2981 +#: doc/rust.md:3050 msgid "" "A managed box may (in the case of a recursive, mutable managed type) be " "cyclic; in this case the release of memory inside the managed structure may " @@ -5620,38 +5769,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:2984 +#: doc/rust.md:3053 msgid "" "When a task finishes, its stack is necessarily empty and it therefore has no " "references to any boxes; the remainder of its heap is immediately freed." msgstr "" #. type: Plain text -#: doc/rust.md:2987 +#: doc/rust.md:3056 msgid "### Memory slots" msgstr "" #. type: Plain text -#: doc/rust.md:2989 +#: doc/rust.md:3058 msgid "A task's stack contains slots." msgstr "" #. type: Plain text -#: doc/rust.md:2992 +#: doc/rust.md:3061 msgid "" "A _slot_ is a component of a stack frame, either a function parameter, a " "[temporary](#lvalues-rvalues-and-temporaries), or a local variable." msgstr "" #. type: Plain text -#: doc/rust.md:2995 +#: doc/rust.md:3064 msgid "" "A _local variable_ (or *stack-local* allocation) holds a value directly, " "allocated within the stack's memory. The value is a part of the stack frame." msgstr "" #. type: Plain text -#: doc/rust.md:3000 +#: doc/rust.md:3069 msgid "" "Local variables are immutable unless declared with `let mut`. The `mut` " "keyword applies to all local variables declared within that declaration (so " @@ -5659,7 +5808,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3005 +#: doc/rust.md:3074 msgid "" "Function parameters are immutable unless declared with `mut`. The `mut` " "keyword applies only to the following parameter (so `|mut x, y|` and `fn " @@ -5668,7 +5817,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3011 +#: doc/rust.md:3080 msgid "" "Local variables are not initialized when allocated; the entire frame worth " "of local variables are allocated at once, on frame-entry, in an " @@ -5678,31 +5827,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3014 +#: doc/rust.md:3083 msgid "### Memory boxes" msgstr "" #. type: Plain text -#: doc/rust.md:3017 +#: doc/rust.md:3086 msgid "" "A _box_ is a reference to a heap allocation holding another value. There are " "two kinds of boxes: *managed boxes* and *owned boxes*." msgstr "" #. type: Plain text -#: doc/rust.md:3019 +#: doc/rust.md:3088 msgid "" "A _managed box_ type or value is constructed by the prefix *at* sigil `@`." msgstr "" #. type: Plain text -#: doc/rust.md:3021 +#: doc/rust.md:3090 msgid "" "An _owned box_ type or value is constructed by the prefix *tilde* sigil `~`." msgstr "" #. type: Plain text -#: doc/rust.md:3026 +#: doc/rust.md:3095 msgid "" "Multiple managed box values can point to the same heap allocation; copying a " "managed box value makes a shallow copy of the pointer (optionally " @@ -5711,7 +5860,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3030 +#: doc/rust.md:3099 msgid "" "Owned box values exist in 1:1 correspondence with their heap allocation; " "copying an owned box value makes a deep copy of the heap allocation and " @@ -5719,33 +5868,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3033 +#: doc/rust.md:3102 msgid "" "An example of constructing one managed box type and value, and one owned box " "type and value:" msgstr "" #. type: Plain text -#: doc/rust.md:3038 +#: doc/rust.md:3107 msgid "~~~~~~~~ let x: @int = @10; let x: ~int = ~10; ~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:3041 +#: doc/rust.md:3110 msgid "" "Some operations (such as field selection) implicitly dereference boxes. An " "example of an _implicit dereference_ operation performed on box values:" msgstr "" #. type: Plain text -#: doc/rust.md:3047 +#: doc/rust.md:3116 msgid "" "~~~~~~~~ struct Foo { y: int } let x = @Foo{y: 10}; assert!(x.y == 10); " "~~~~~~~~" msgstr "" #. type: Plain text -#: doc/rust.md:3053 +#: doc/rust.md:3122 msgid "" "Other operations act on box values as single-word-sized address values. For " "these operations, to access the value held in the box requires an explicit " @@ -5755,33 +5904,33 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3056 +#: doc/rust.md:3125 msgid "copying box values (`x = y`)" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3056 +#: doc/rust.md:3125 msgid "passing box values to functions (`f(x,y)`)" msgstr "" #. type: Plain text -#: doc/rust.md:3059 +#: doc/rust.md:3128 msgid "" "An example of an explicit-dereference operation performed on box values:" msgstr "" #. type: Plain text -#: doc/rust.md:3063 +#: doc/rust.md:3132 msgid "~~~~~~~~ fn takes_boxed(b: @int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:3066 +#: doc/rust.md:3135 msgid "fn takes_unboxed(b: int) { }" msgstr "" #. type: Plain text -#: doc/rust.md:3073 +#: doc/rust.md:3142 #, no-wrap msgid "" "fn main() {\n" @@ -5793,12 +5942,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3075 +#: doc/rust.md:3144 msgid "## Tasks" msgstr "" #. type: Plain text -#: doc/rust.md:3083 +#: doc/rust.md:3152 msgid "" "An executing Rust program consists of a tree of tasks. A Rust _task_ " "consists of an entry function, a stack, a set of outgoing communication " @@ -5809,7 +5958,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3098 +#: doc/rust.md:3167 msgid "" "Multiple Rust tasks may coexist in a single operating-system process. The " "runtime scheduler maps tasks to a certain number of operating-system " @@ -5828,12 +5977,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3101 +#: doc/rust.md:3170 msgid "### Communication between tasks" msgstr "" #. type: Plain text -#: doc/rust.md:3106 +#: doc/rust.md:3175 msgid "" "Rust tasks are isolated and generally unable to interfere with one another's " "memory directly, except through [`unsafe` code](#unsafe-functions). All " @@ -5842,33 +5991,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3109 +#: doc/rust.md:3178 msgid "" "Inter-task communication and co-ordination facilities are provided in the " "standard library. These include:" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "" "synchronous and asynchronous communication channels with various " "communication topologies" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "" "read-only and read-write shared variables with various safe mutual exclusion " "patterns" msgstr "" #. type: Bullet: ' - ' -#: doc/rust.md:3113 +#: doc/rust.md:3182 msgid "simple locks and semaphores" msgstr "" #. type: Plain text -#: doc/rust.md:3118 +#: doc/rust.md:3187 msgid "" "When such facilities carry values, the values are restricted to the [`Send` " "type-kind](#type-kinds). Restricting communication interfaces to this kind " @@ -5879,39 +6028,39 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3121 +#: doc/rust.md:3190 msgid "### Task lifecycle" msgstr "" #. type: Plain text -#: doc/rust.md:3124 +#: doc/rust.md:3193 msgid "" "The _lifecycle_ of a task consists of a finite set of states and events that " "cause transitions between the states. The lifecycle states of a task are:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "running" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "blocked" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "failing" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3129 +#: doc/rust.md:3198 msgid "dead" msgstr "" #. type: Plain text -#: doc/rust.md:3133 +#: doc/rust.md:3202 msgid "" "A task begins its lifecycle -- once it has been spawned -- in the *running* " "state. In this state it executes the statements of its entry function, and " @@ -5919,7 +6068,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3139 +#: doc/rust.md:3208 msgid "" "A task may transition from the *running* state to the *blocked* state any " "time it makes a blocking communication call. When the call can be completed " @@ -5929,7 +6078,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3158 +#: doc/rust.md:3227 msgid "" "A task may transition to the *failing* state at any time, due being killed " "by some external event or internally, from the evaluation of a `fail!()` " @@ -5952,7 +6101,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3162 +#: doc/rust.md:3231 msgid "" "A task in the *dead* state cannot transition to other states; it exists only " "to have its termination status inspected by other tasks, and/or to await " @@ -5960,12 +6109,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3165 +#: doc/rust.md:3234 msgid "### Task scheduling" msgstr "" #. type: Plain text -#: doc/rust.md:3169 +#: doc/rust.md:3238 msgid "" "The currently scheduled task is given a finite *time slice* in which to " "execute, after which it is *descheduled* at a loop-edge or similar " @@ -5973,7 +6122,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3173 +#: doc/rust.md:3242 msgid "" "An executing task can yield control at any time, by making a library call to " "`std::task::yield`, which deschedules it immediately. Entering any other non-" @@ -5981,12 +6130,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3176 +#: doc/rust.md:3245 msgid "# Runtime services, linkage and debugging" msgstr "" #. type: Plain text -#: doc/rust.md:3183 +#: doc/rust.md:3252 msgid "" "The Rust _runtime_ is a relatively compact collection of C++ and Rust code " "that provides fundamental services and datatypes to all Rust tasks at run-" @@ -5996,19 +6145,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3185 +#: doc/rust.md:3254 msgid "" "> **Note:** The runtime library will merge with the `std` library in future " "versions of Rust." msgstr "" #. type: Plain text -#: doc/rust.md:3187 +#: doc/rust.md:3256 msgid "### Memory allocation" msgstr "" #. type: Plain text -#: doc/rust.md:3193 +#: doc/rust.md:3262 msgid "" "The runtime memory-management system is based on a _service-provider " "interface_, through which the runtime requests blocks of memory from its " @@ -6018,7 +6167,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3197 +#: doc/rust.md:3266 msgid "" "The runtime memory-management system, in turn, supplies Rust tasks with " "facilities for allocating, extending and releasing stacks, as well as " @@ -6026,12 +6175,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3199 +#: doc/rust.md:3268 msgid "### Built in types" msgstr "" #. type: Plain text -#: doc/rust.md:3203 +#: doc/rust.md:3272 msgid "" "The runtime provides C and Rust code to assist with various built-in types, " "such as vectors, strings, and the low level communication system (ports, " @@ -6039,19 +6188,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3206 +#: doc/rust.md:3275 msgid "" "Support for other built-in types such as simple types, tuples, records, and " "enums is open-coded by the Rust compiler." msgstr "" #. type: Plain text -#: doc/rust.md:3210 +#: doc/rust.md:3279 msgid "### Task scheduling and communication" msgstr "" #. type: Plain text -#: doc/rust.md:3216 +#: doc/rust.md:3285 msgid "" "The runtime provides code to manage inter-task communication. This includes " "the system of task-lifecycle state transitions depending on the contents of " @@ -6061,12 +6210,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3219 +#: doc/rust.md:3288 msgid "### Logging system" msgstr "" #. type: Plain text -#: doc/rust.md:3223 +#: doc/rust.md:3292 msgid "" "The runtime contains a system for directing [logging expressions](#log-" "expressions) to a logging console and/or internal logging buffers. Logging " @@ -6074,7 +6223,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3230 +#: doc/rust.md:3299 msgid "" "Logging output is enabled by setting the `RUST_LOG` environment variable. " "`RUST_LOG` accepts a logging specification made up of a comma-separated list " @@ -6085,7 +6234,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3238 +#: doc/rust.md:3307 msgid "" "The path to a module consists of the crate name, any parent modules, then " "the module itself, all separated by double colons (`::`). The optional log " @@ -6096,7 +6245,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3244 +#: doc/rust.md:3313 msgid "" "As an example, to see all the logs generated by the compiler, you would set " "`RUST_LOG` to `rustc`, which is the crate name (as specified in its `link` " @@ -6106,7 +6255,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3249 +#: doc/rust.md:3318 msgid "" "Note that when compiling either `.rs` or `.rc` files that don't specify a " "crate name the crate is given a default name that matches the source file, " @@ -6116,7 +6265,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3253 +#: doc/rust.md:3322 msgid "" "As a convenience, the logging spec can also be set to a special pseudo-" "crate, `::help`. In this case, when the application starts, the runtime will " @@ -6124,7 +6273,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3258 +#: doc/rust.md:3327 msgid "" "The Rust runtime itself generates logging information. The runtime's logs " "are generated for a number of artificial modules in the `::rt` pseudo-crate, " @@ -6133,84 +6282,84 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::mem` Memory management" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::comm` Messaging and task communication" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::task` Task management" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::dom` Task scheduling" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::trace` Unused" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::cache` Type descriptor cache" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::upcall` Compiler-generated runtime calls" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::timer` The scheduler timer" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::gc` Garbage collection" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::stdlib` Functions used directly by the standard library" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::kern` The runtime kernel" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::backtrace` Log a backtrace on task failure" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3272 +#: doc/rust.md:3341 msgid "`::rt::callback` Unused" msgstr "" #. type: Plain text -#: doc/rust.md:3274 +#: doc/rust.md:3343 msgid "#### Logging Expressions" msgstr "" #. type: Plain text -#: doc/rust.md:3277 +#: doc/rust.md:3346 msgid "" "Rust provides several macros to log information. Here's a simple Rust " "program that demonstrates all four of them:" msgstr "" #. type: Plain text -#: doc/rust.md:3286 +#: doc/rust.md:3355 #, no-wrap msgid "" "```rust\n" @@ -6224,13 +6373,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3288 +#: doc/rust.md:3357 msgid "" "These four log levels correspond to levels 1-4, as controlled by `RUST_LOG`:" msgstr "" #. type: Plain text -#: doc/rust.md:3295 +#: doc/rust.md:3364 msgid "" "```bash $ RUST_LOG=rust=3 ./rust rust: ~\"\\\"This is an error log\\\"\" " "rust: ~\"\\\"This is a warn log\\\"\" rust: ~\"\\\"this is an info log\\\"\" " @@ -6238,28 +6387,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3297 +#: doc/rust.md:3366 msgid "# Appendix: Rationales and design tradeoffs" msgstr "" #. type: Plain text -#: doc/rust.md:3299 +#: doc/rust.md:3368 #, no-wrap msgid "*TODO*.\n" msgstr "" #. type: Plain text -#: doc/rust.md:3301 +#: doc/rust.md:3370 msgid "# Appendix: Influences and further references" msgstr "" #. type: Plain text -#: doc/rust.md:3303 +#: doc/rust.md:3372 msgid "## Influences" msgstr "" #. type: Plain text -#: doc/rust.md:3312 +#: doc/rust.md:3381 msgid "" "> The essential problem that must be solved in making a fault-tolerant > " "software system is therefore that of fault-isolation. Different programmers " @@ -6270,7 +6419,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3324 +#: doc/rust.md:3393 msgid "" "> In our approach, all data is private to some process, and processes can > " "only communicate through communications channels. *Security*, as used > in " @@ -6282,7 +6431,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3332 +#: doc/rust.md:3401 msgid "" "> Concurrent and applicative programming complement each other. The > " "ability to send messages on channels provides I/O without side effects, > " @@ -6291,7 +6440,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3339 +#: doc/rust.md:3408 msgid "" "Rust is not a particularly original language. It may however appear unusual " "by contemporary standards, as its design elements are drawn from a number of " @@ -6301,7 +6450,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3343 +#: doc/rust.md:3412 msgid "" "The NIL (1981) and Hermes (1990) family. These languages were developed by " "Robert Strom, Shaula Yemini, David Bacon and others in their group at IBM " @@ -6309,7 +6458,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3347 +#: doc/rust.md:3416 msgid "" "The Erlang (1987) language, developed by Joe Armstrong, Robert Virding, " "Claes Wikström, Mike Williams and others in their group at the Ericsson " @@ -6317,7 +6466,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3352 +#: doc/rust.md:3421 msgid "" "The Sather (1990) language, developed by Stephen Omohundro, Chu-Cheow Lim, " "Heinz Schmidt and others in their group at The International Computer " @@ -6326,7 +6475,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3357 +#: doc/rust.md:3426 msgid "" "The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These languages " "were developed by Rob Pike, Phil Winterbottom, Sean Dorward and others in " @@ -6335,7 +6484,7 @@ msgid "" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3361 +#: doc/rust.md:3430 msgid "" "The Napier (1985) and Napier88 (1988) family. These languages were developed " "by Malcolm Atkinson, Ron Morrison and others in their group at the " @@ -6343,47 +6492,47 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:3363 +#: doc/rust.md:3432 msgid "" "Additional specific influences can be seen from the following languages:" msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The stack-growth implementation of Go." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The structural algebraic types and compilation manager of SML." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The attribute and assembly systems of C#." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The references and deterministic destructor system of C++." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The memory region systems of the ML Kit and Cyclone." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The typeclass system of Haskell." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The lexical identifier rule of Python." msgstr "" #. type: Bullet: '* ' -#: doc/rust.md:3371 +#: doc/rust.md:3440 msgid "The block syntax of Ruby." msgstr "" diff --git a/doc/po/rustpkg.md.pot b/doc/po/rustpkg.md.pot index f6b962d8565d0..134aa56b3dab4 100644 --- a/doc/po/rustpkg.md.pot +++ b/doc/po/rustpkg.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial-borrowed-ptr.md.pot b/doc/po/tutorial-borrowed-ptr.md.pot index 87900073001db..816b3eeea61e6 100644 --- a/doc/po/tutorial-borrowed-ptr.md.pot +++ b/doc/po/tutorial-borrowed-ptr.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/tutorial.md:1110 doc/tutorial-borrowed-ptr.md:72 +#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" diff --git a/doc/po/tutorial-container.md.pot b/doc/po/tutorial-container.md.pot index aa9dae62a6153..3a4e86f8c82ee 100644 --- a/doc/po/tutorial-container.md.pot +++ b/doc/po/tutorial-container.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -195,7 +195,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:89 +#: doc/tutorial-container.md:89 doc/tutorial-container.md:262 #, no-wrap msgid "" "~~~\n" @@ -217,7 +217,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:107 +#: doc/tutorial-container.md:107 doc/tutorial-container.md:284 #, no-wrap msgid "" "impl Iterator for ZeroStream {\n" @@ -440,6 +440,162 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial-container.md:207 +#: doc/tutorial-container.md:208 msgid "// the iterator is now fully consumed assert!(it.next().is_none()); ~~~" msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:210 +msgid "## Conversion" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:212 +msgid "" +"Iterators offer generic conversion to containers with the `collect` adaptor:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:218 +msgid "" +"~~~ let xs = [0, 1, 1, 2, 3, 5, 8]; let ys = xs.rev_iter().skip(1)." +"transform(|&x| x * 2).collect::<~[int]>(); assert_eq!(ys, ~[10, 6, 4, 2, 2, " +"0]); ~~~" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:221 +msgid "" +"The method requires a type hint for the container type, if the surrounding " +"code does not provide sufficient information." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:225 +msgid "" +"Containers can provide conversion from iterators through `collect` by " +"implementing the `FromIterator` trait. For example, the implementation for " +"vectors is as follows:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:238 +#, no-wrap +msgid "" +"~~~\n" +"impl> FromIterator for ~[A] {\n" +" pub fn from_iterator(iterator: &mut T) -> ~[A] {\n" +" let (lower, _) = iterator.size_hint();\n" +" let mut xs = with_capacity(lower);\n" +" for iterator.advance |x| {\n" +" xs.push(x);\n" +" }\n" +" xs\n" +" }\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:240 +msgid "### Size hints" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:243 +msgid "" +"The `Iterator` trait provides a `size_hint` default method, returning a " +"lower bound and optionally on upper bound on the length of the iterator:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:247 +msgid "~~~ fn size_hint(&self) -> (uint, Option) { (0, None) } ~~~" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:251 +msgid "" +"The vector implementation of `FromIterator` from above uses the lower bound " +"to pre-allocate enough space to hold the minimum number of elements the " +"iterator will yield." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:254 +msgid "" +"The default implementation is always correct, but it should be overridden if " +"the iterator can provide better information." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:256 +msgid "" +"The `ZeroStream` from earlier can provide an exact lower and upper bound:" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:267 +#, no-wrap +msgid "" +"impl ZeroStream {\n" +" fn new(n: uint) -> ZeroStream {\n" +" ZeroStream { remaining: n }\n" +" }\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:272 +#, no-wrap +msgid "" +" fn size_hint(&self) -> (uint, Option) {\n" +" (self.remaining, Some(self.remaining))\n" +" }\n" +"}\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:286 +msgid "## Double-ended iterators" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:290 +msgid "" +"The `DoubleEndedIterator` trait represents an iterator able to yield " +"elements from either end of a range. It inherits from the `Iterator` trait " +"and extends it with the `next_back` function." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:293 +msgid "" +"A `DoubleEndedIterator` can be flipped with the `invert` adaptor, returning " +"another `DoubleEndedIterator` with `next` and `next_back` exchanged." +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:300 +msgid "" +"~~~ let xs = [1, 2, 3, 4, 5, 6]; let mut it = xs.iter(); println(fmt!(\"%?" +"\", it.next())); // prints `Some(&1)` println(fmt!(\"%?\", it.next())); // " +"prints `Some(&2)` println(fmt!(\"%?\", it.next_back())); // prints `Some(&6)`" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:306 +#, no-wrap +msgid "" +"// prints `5`, `4` and `3`\n" +"for it.invert().advance |&x| {\n" +" println(fmt!(\"%?\", x))\n" +"}\n" +"~~~\n" +msgstr "" + +#. type: Plain text +#: doc/tutorial-container.md:308 +msgid "" +"The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted " +"version of the standard immutable and mutable vector iterators." +msgstr "" diff --git a/doc/po/tutorial-ffi.md.pot b/doc/po/tutorial-ffi.md.pot index 20641225b135d..c43b6652331ff 100644 --- a/doc/po/tutorial-ffi.md.pot +++ b/doc/po/tutorial-ffi.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/tutorial.md:875 doc/tutorial-ffi.md:143 +#: doc/tutorial.md:876 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" diff --git a/doc/po/tutorial-macros.md.pot b/doc/po/tutorial-macros.md.pot index 92a8651d2920c..5487ab5ebbd8c 100644 --- a/doc/po/tutorial-macros.md.pot +++ b/doc/po/tutorial-macros.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial-tasks.md.pot b/doc/po/tutorial-tasks.md.pot index 897d89b2a9066..43c0f4c092404 100644 --- a/doc/po/tutorial-tasks.md.pot +++ b/doc/po/tutorial-tasks.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" diff --git a/doc/po/tutorial.md.pot b/doc/po/tutorial.md.pot index cf04b7f5dc805..415d5052a0643 100644 --- a/doc/po/tutorial.md.pot +++ b/doc/po/tutorial.md.pot @@ -1,13 +1,13 @@ # SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR The Rust Project Developers +# This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-07-07 21:10+0300\n" +"Project-Id-Version: Rust 0.8-pre\n" +"POT-Creation-Date: 2013-07-17 07:18+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,12 +19,12 @@ msgstr "" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 -#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 +#: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 msgid "# Introduction" msgstr "" #. type: Plain text -#: doc/rust.md:1231 doc/tutorial.md:2179 +#: doc/rust.md:1231 doc/tutorial.md:2177 msgid "" "In type-parameterized functions, methods of the supertrait may be called on " "values of subtrait-bound type parameters. Refering to the previous example " @@ -32,7 +32,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1240 doc/tutorial.md:2188 +#: doc/rust.md:1240 doc/tutorial.md:2186 #, no-wrap msgid "" "~~~\n" @@ -46,12 +46,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/rust.md:1242 doc/tutorial.md:2190 +#: doc/rust.md:1242 doc/tutorial.md:2188 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" #. type: Plain text -#: doc/tutorial.md:2 doc/tut.md:2 +#: doc/tutorial.md:2 msgid "% The Rust Language Tutorial" msgstr "" @@ -961,24 +961,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:515 +#: doc/tutorial.md:516 #, no-wrap msgid "" "~~~~\n" "# use std::float;\n" +"# use std::num::atan;\n" "fn angle(vector: (float, float)) -> float {\n" " let pi = float::consts::pi;\n" " match vector {\n" " (0f, y) if y < 0f => 1.5 * pi,\n" " (0f, y) => 0.5 * pi,\n" -" (x, y) => float::atan(y / x)\n" +" (x, y) => atan(y / x)\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:521 +#: doc/tutorial.md:522 msgid "" "A variable name in a pattern matches any value, *and* binds that name to the " "value of the matched value inside of the arm's action. Thus, `(0f, y)` " @@ -988,7 +989,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:528 +#: doc/tutorial.md:529 msgid "" "Any `match` arm can have a guard clause (written `if EXPR`), called a " "*pattern guard*, which is an expression of type `bool` that determines, " @@ -998,7 +999,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:533 +#: doc/tutorial.md:534 msgid "" "You've already seen simple `let` bindings, but `let` is a little fancier " "than you've been led to believe. It, too, supports destructuring patterns. " @@ -1007,14 +1008,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:538 +#: doc/tutorial.md:539 msgid "" "~~~~ # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) } let (a, b) = " "get_tuple_of_two_ints(); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:542 +#: doc/tutorial.md:543 msgid "" "Let bindings only work with _irrefutable_ patterns: that is, patterns that " "can never fail to match. This excludes `let` from matching literals and most " @@ -1022,12 +1023,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:544 +#: doc/tutorial.md:545 msgid "## Loops" msgstr "" #. type: Plain text -#: doc/tutorial.md:549 +#: doc/tutorial.md:550 msgid "" "`while` denotes a loop that iterates as long as its given condition (which " "must have type `bool`) evaluates to `true`. Inside a loop, the keyword " @@ -1036,7 +1037,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:556 +#: doc/tutorial.md:557 #, no-wrap msgid "" "~~~~\n" @@ -1048,14 +1049,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:558 +#: doc/tutorial.md:559 msgid "" "`loop` denotes an infinite loop, and is the preferred way of writing `while " "true`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:568 +#: doc/tutorial.md:569 #, no-wrap msgid "" "~~~~\n" @@ -1070,14 +1071,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:571 +#: doc/tutorial.md:572 msgid "" "This code prints out a weird sequence of numbers and stops as soon as it " "finds one that can be divided by five." msgstr "" #. type: Plain text -#: doc/tutorial.md:576 +#: doc/tutorial.md:577 msgid "" "Rust also has a `for` construct. It's different from C's `for` and it works " "best when iterating over collections. See the section on [closures]" @@ -1086,17 +1087,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:578 +#: doc/tutorial.md:579 msgid "# Data structures" msgstr "" #. type: Plain text -#: doc/tutorial.md:580 +#: doc/tutorial.md:581 msgid "## Structs" msgstr "" #. type: Plain text -#: doc/tutorial.md:585 +#: doc/tutorial.md:586 msgid "" "Rust struct types must be declared before they are used using the `struct` " "syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, " @@ -1105,7 +1106,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:589 +#: doc/tutorial.md:590 msgid "" "Structs are quite similar to C structs and are even laid out the same way in " "memory (so you can read from a Rust struct in C, and vice-versa). Use the " @@ -1113,7 +1114,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:596 +#: doc/tutorial.md:597 #, no-wrap msgid "" "~~~~\n" @@ -1125,7 +1126,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:600 +#: doc/tutorial.md:601 msgid "" "Inherited mutability means that any field of a struct may be mutable, if the " "struct is in a mutable slot (or a field of a struct in a mutable slot, and " @@ -1133,7 +1134,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:604 +#: doc/tutorial.md:605 msgid "" "With a value (say, `mypoint`) of such a type in a mutable location, you can " "do `mypoint.y += 1.0`. But in an immutable location, such an assignment to a " @@ -1141,28 +1142,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:609 +#: doc/tutorial.md:610 msgid "" "~~~~ {.xfail-test} # struct Point { x: float, y: float } let mut mypoint = " "Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };" msgstr "" #. type: Plain text -#: doc/tutorial.md:613 +#: doc/tutorial.md:614 msgid "" "mypoint.y += 1.0; // mypoint is mutable, and its fields as well origin.y += " "1.0; // ERROR: assigning to immutable field ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:616 +#: doc/tutorial.md:617 msgid "" "`match` patterns destructure structs. The basic syntax is `Name { fieldname: " "pattern, ... }`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:625 +#: doc/tutorial.md:626 #, no-wrap msgid "" "~~~~\n" @@ -1176,7 +1177,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:632 +#: doc/tutorial.md:633 msgid "" "In general, the field names of a struct do not have to appear in the same " "order they appear in the type. When you are not interested in all the fields " @@ -1187,7 +1188,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:640 +#: doc/tutorial.md:641 #, no-wrap msgid "" "~~~\n" @@ -1200,19 +1201,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:642 +#: doc/tutorial.md:643 msgid "## Enums" msgstr "" #. type: Plain text -#: doc/tutorial.md:645 +#: doc/tutorial.md:646 msgid "" "Enums are datatypes that have several alternate representations. For " "example, consider the type shown earlier:" msgstr "" #. type: Plain text -#: doc/tutorial.md:653 +#: doc/tutorial.md:654 #, no-wrap msgid "" "~~~~\n" @@ -1225,7 +1226,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:659 +#: doc/tutorial.md:660 msgid "" "A value of this type is either a `Circle`, in which case it contains a " "`Point` struct and a float, or a `Rectangle`, in which case it contains two " @@ -1235,7 +1236,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:665 +#: doc/tutorial.md:666 msgid "" "The above declaration will define a type `Shape` that can refer to such " "shapes, and two functions, `Circle` and `Rectangle`, which can be used to " @@ -1244,14 +1245,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:668 +#: doc/tutorial.md:669 msgid "" "Enum variants need not have parameters. This `enum` declaration, for " "example, is equivalent to a C enum:" msgstr "" #. type: Plain text -#: doc/tutorial.md:677 +#: doc/tutorial.md:678 #, no-wrap msgid "" "~~~~\n" @@ -1265,14 +1266,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:680 +#: doc/tutorial.md:681 msgid "" "This declaration defines `North`, `East`, `South`, and `West` as constants, " "all of which have type `Direction`." msgstr "" #. type: Plain text -#: doc/tutorial.md:684 +#: doc/tutorial.md:685 msgid "" "When an enum is C-like (that is, when none of the variants have parameters), " "it is possible to explicitly set the discriminator values to a constant " @@ -1280,7 +1281,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:692 +#: doc/tutorial.md:693 #, no-wrap msgid "" "~~~~\n" @@ -1293,7 +1294,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:697 +#: doc/tutorial.md:698 msgid "" "If an explicit discriminator is not specified for a variant, the value " "defaults to the value of the previous variant plus one. If the first variant " @@ -1302,14 +1303,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:700 +#: doc/tutorial.md:701 msgid "" "When an enum is C-like, you can apply the `as` cast operator to convert it " "to its discriminator value as an `int`." msgstr "" #. type: Plain text -#: doc/tutorial.md:704 +#: doc/tutorial.md:705 msgid "" "For enum types with multiple variants, destructuring is the only way to get " "at their contents. All variant constructors can be used as patterns, as in " @@ -1317,7 +1318,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:716 +#: doc/tutorial.md:717 #, no-wrap msgid "" "~~~~\n" @@ -1334,7 +1335,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:721 +#: doc/tutorial.md:722 msgid "" "You can write a lone `_` to ignore an individual field, and can ignore all " "fields of a variant like: `Circle(*)`. As in their introduction form, " @@ -1342,7 +1343,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:734 +#: doc/tutorial.md:735 #, no-wrap msgid "" "~~~~\n" @@ -1360,12 +1361,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:736 +#: doc/tutorial.md:737 msgid "Enum variants may also be structs. For example:" msgstr "" #. type: Plain text -#: doc/tutorial.md:754 +#: doc/tutorial.md:755 #, no-wrap msgid "" "~~~~\n" @@ -1388,12 +1389,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:756 +#: doc/tutorial.md:757 msgid "## Tuples" msgstr "" #. type: Plain text -#: doc/tutorial.md:761 +#: doc/tutorial.md:762 msgid "" "Tuples in Rust behave exactly like structs, except that their fields do not " "have names. Thus, you cannot access their fields with dot notation. Tuples " @@ -1402,7 +1403,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:768 +#: doc/tutorial.md:769 #, no-wrap msgid "" "~~~~\n" @@ -1414,12 +1415,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:770 +#: doc/tutorial.md:771 msgid "## Tuple structs" msgstr "" #. type: Plain text -#: doc/tutorial.md:775 +#: doc/tutorial.md:776 msgid "" "Rust also has _tuple structs_, which behave like both structs and tuples, " "except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a " @@ -1428,7 +1429,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:784 +#: doc/tutorial.md:785 #, no-wrap msgid "" "For example:\n" @@ -1442,12 +1443,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:786 +#: doc/tutorial.md:787 msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:791 +#: doc/tutorial.md:792 msgid "" "There is a special case for tuple structs with a single field, which are " "sometimes called \"newtypes\" (after Haskell's \"newtype\" feature). These " @@ -1456,50 +1457,50 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:795 +#: doc/tutorial.md:796 msgid "~~~~ struct GizmoId(int); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:798 +#: doc/tutorial.md:799 msgid "" "For convenience, you can extract the contents of such a struct with the " "dereference (`*`) unary operator:" msgstr "" #. type: Plain text -#: doc/tutorial.md:804 +#: doc/tutorial.md:805 msgid "" "~~~~ # struct GizmoId(int); let my_gizmo_id: GizmoId = GizmoId(10); let " "id_int: int = *my_gizmo_id; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:807 +#: doc/tutorial.md:808 msgid "" "Types like this can be useful to differentiate between data that have the " "same type but must be used in different ways." msgstr "" #. type: Plain text -#: doc/tutorial.md:812 +#: doc/tutorial.md:813 msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:815 +#: doc/tutorial.md:816 msgid "" "The above definitions allow for a simple way for programs to avoid confusing " "numbers that correspond to different units." msgstr "" #. type: Plain text -#: doc/tutorial.md:817 +#: doc/tutorial.md:818 msgid "# Functions" msgstr "" #. type: Plain text -#: doc/tutorial.md:825 +#: doc/tutorial.md:826 msgid "" "We've already seen several function definitions. Like all other static " "declarations, such as `type`, functions can be declared both at the top " @@ -1511,7 +1512,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:831 +#: doc/tutorial.md:832 #, no-wrap msgid "" "~~~~\n" @@ -1522,7 +1523,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:836 +#: doc/tutorial.md:837 msgid "" "The `return` keyword immediately returns from the body of a function. It is " "optionally followed by an expression to return. A function can also return a " @@ -1530,7 +1531,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:842 +#: doc/tutorial.md:843 #, no-wrap msgid "" "~~~~\n" @@ -1541,7 +1542,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:849 +#: doc/tutorial.md:850 msgid "" "It's better Rust style to write a return value this way instead of writing " "an explicit `return`. The utility of `return` comes in when returning early " @@ -1551,35 +1552,35 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:852 +#: doc/tutorial.md:853 msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }" msgstr "" #. type: Plain text -#: doc/tutorial.md:855 +#: doc/tutorial.md:856 msgid "fn do_nothing_the_easy_way() { } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:857 +#: doc/tutorial.md:858 msgid "" "Ending the function with a semicolon like so is equivalent to returning `()`." msgstr "" #. type: Plain text -#: doc/tutorial.md:861 +#: doc/tutorial.md:862 msgid "" "~~~~ fn line(a: int, b: int, x: int) -> int { a * x + b } fn oops(a: int, b: " "int, x: int) -> () { a * x + b; }" msgstr "" #. type: Plain text -#: doc/tutorial.md:865 +#: doc/tutorial.md:866 msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:869 +#: doc/tutorial.md:870 msgid "" "As with `match` expressions and `let` bindings, function arguments support " "pattern destructuring. Like `let`, argument patterns must be irrefutable, as " @@ -1587,17 +1588,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:873 +#: doc/tutorial.md:874 msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:875 doc/tutorial-ffi.md:143 +#: doc/tutorial.md:876 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" #. type: Plain text -#: doc/tutorial.md:879 +#: doc/tutorial.md:880 msgid "" "A *destructor* is a function responsible for cleaning up the resources used " "by an object when it is no longer accessible. Destructors can be defined to " @@ -1605,7 +1606,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:883 +#: doc/tutorial.md:884 msgid "" "Objects are never accessible after their destructor has been called, so " "there are no dynamic failures from accessing freed resources. When a task " @@ -1613,13 +1614,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:885 +#: doc/tutorial.md:886 msgid "" "The `~` sigil represents a unique handle for a memory allocation on the heap:" msgstr "" #. type: Plain text -#: doc/tutorial.md:893 +#: doc/tutorial.md:894 #, no-wrap msgid "" "~~~~\n" @@ -1632,7 +1633,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:897 +#: doc/tutorial.md:898 msgid "" "Rust includes syntax for heap memory allocation in the language since it's " "commonly used, but the same semantics can be implemented by a type with a " @@ -1640,12 +1641,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:899 +#: doc/tutorial.md:900 msgid "# Ownership" msgstr "" #. type: Plain text -#: doc/tutorial.md:904 +#: doc/tutorial.md:905 msgid "" "Rust formalizes the concept of object ownership to delegate management of an " "object's lifetime to either a variable or a task-local garbage collector. An " @@ -1655,7 +1656,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:910 +#: doc/tutorial.md:911 msgid "" "Ownership is recursive, so mutability is inherited recursively and a " "destructor destroys the contained tree of owned objects. Variables are top-" @@ -1665,14 +1666,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:914 +#: doc/tutorial.md:915 msgid "" "~~~~ // the struct owns the objects contained in the `x` and `y` fields " "struct Foo { x: int, y: ~int }" msgstr "" #. type: Plain text -#: doc/tutorial.md:921 +#: doc/tutorial.md:922 #, no-wrap msgid "" "{\n" @@ -1684,14 +1685,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:926 +#: doc/tutorial.md:927 msgid "" "// `b` is mutable, and the mutability is inherited by the objects it owns " "let mut b = Foo { x: 5, y: ~10 }; b.x = 10; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:932 +#: doc/tutorial.md:933 msgid "" "If an object doesn't contain garbage-collected boxes, it consists of a " "single ownership tree and is given the `Owned` trait which allows it to be " @@ -1701,12 +1702,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:934 +#: doc/tutorial.md:935 msgid "# Boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:941 +#: doc/tutorial.md:942 msgid "" "Many modern languages represent values as pointers to heap memory by " "default. In contrast, Rust, like C and C++, represents such types directly. " @@ -1717,7 +1718,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:946 +#: doc/tutorial.md:947 msgid "" "For small structs like `Point`, this is usually more efficient than " "allocating memory and indirecting through a pointer. But for big structs, or " @@ -1726,31 +1727,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:948 +#: doc/tutorial.md:949 msgid "## Owned boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:951 +#: doc/tutorial.md:952 msgid "" "An owned box (`~`) is a uniquely owned allocation on the heap. It inherits " "the mutability and lifetime of the owner as it would if there was no box:" msgstr "" #. type: Plain text -#: doc/tutorial.md:956 +#: doc/tutorial.md:957 msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;" msgstr "" #. type: Plain text -#: doc/tutorial.md:961 +#: doc/tutorial.md:962 msgid "" "let x = ~5; // immutable let mut y = ~5; // mutable *y += 2; // the * " "operator is needed to access the contained value ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:966 +#: doc/tutorial.md:967 msgid "" "The purpose of an owned box is to add a layer of indirection in order to " "create recursive data structures or cheaply pass around an object larger " @@ -1759,14 +1760,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:969 +#: doc/tutorial.md:970 msgid "" "The following struct won't compile, because the lack of indirection would " "mean it has an infinite size:" msgstr "" #. type: Plain text -#: doc/tutorial.md:975 +#: doc/tutorial.md:976 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -1777,7 +1778,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:979 +#: doc/tutorial.md:980 msgid "" "> ***Note:*** The `Option` type is an enum that represents an *optional* " "value. > It's comparable to a nullable pointer in many other languages, but " @@ -1785,7 +1786,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:983 +#: doc/tutorial.md:984 msgid "" "Adding indirection with an owned pointer allocates the child outside of the " "struct on the heap, which makes it a finite size and won't result in a " @@ -1793,7 +1794,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:989 +#: doc/tutorial.md:990 #, no-wrap msgid "" "~~~~\n" @@ -1804,12 +1805,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:991 +#: doc/tutorial.md:992 msgid "## Managed boxes" msgstr "" #. type: Plain text -#: doc/tutorial.md:999 +#: doc/tutorial.md:1000 msgid "" "A managed box (`@`) is a heap allocation with the lifetime managed by a task-" "local garbage collector. It will be destroyed at some point after there are " @@ -1821,29 +1822,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1002 +#: doc/tutorial.md:1003 msgid "~~~~ let a = @5; // immutable" msgstr "" #. type: Plain text -#: doc/tutorial.md:1005 +#: doc/tutorial.md:1006 msgid "let mut b = @5; // mutable variable, immutable box b = @10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1008 +#: doc/tutorial.md:1009 msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1013 +#: doc/tutorial.md:1014 msgid "" "let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; " "~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1018 +#: doc/tutorial.md:1019 msgid "" "A mutable variable and an immutable variable can refer to the same box, " "given that their types are compatible. Mutability of a box is a property of " @@ -1852,7 +1853,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1022 +#: doc/tutorial.md:1023 #, no-wrap msgid "" "~~~~\n" @@ -1861,7 +1862,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1025 +#: doc/tutorial.md:1026 #, no-wrap msgid "" "let mut c : @int; // declare a variable with type managed immutable int\n" @@ -1869,7 +1870,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1029 +#: doc/tutorial.md:1030 #, no-wrap msgid "" "c = a; // box type is the same, okay\n" @@ -1878,7 +1879,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1034 +#: doc/tutorial.md:1035 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -1888,12 +1889,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1036 +#: doc/tutorial.md:1037 msgid "# Move semantics" msgstr "" #. type: Plain text -#: doc/tutorial.md:1042 +#: doc/tutorial.md:1043 msgid "" "Rust uses a shallow copy for parameter passing, assignment and returning " "values from functions. A shallow copy is considered a move of ownership if " @@ -1903,33 +1904,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1048 +#: doc/tutorial.md:1049 msgid "" "~~~~ let x = ~5; let y = x.clone(); // y is a newly allocated box let z = " "x; // no new memory allocated, x can no longer be used ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1051 +#: doc/tutorial.md:1052 msgid "" "Since in owned boxes mutability is a property of the owner, not the box, " "mutable boxes may become immutable when they are moved, and vice-versa." msgstr "" #. type: Plain text -#: doc/tutorial.md:1058 +#: doc/tutorial.md:1059 msgid "" "~~~~ let r = ~13; let mut s = r; // box becomes mutable *s += 1; let t = " "s; // box becomes immutable ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1060 +#: doc/tutorial.md:1061 msgid "# Borrowed pointers" msgstr "" #. type: Plain text -#: doc/tutorial.md:1066 +#: doc/tutorial.md:1067 msgid "" "Rust's borrowed pointers are a general purpose reference type. In contrast " "with owned boxes, where the holder of an owned box is the owner of the " @@ -1939,12 +1940,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1068 +#: doc/tutorial.md:1069 msgid "As an example, consider a simple struct type, `Point`:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1075 +#: doc/tutorial.md:1076 #, no-wrap msgid "" "~~~\n" @@ -1956,7 +1957,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1079 +#: doc/tutorial.md:1080 msgid "" "We can use this simple definition to allocate points in many different ways. " "For example, in this code, each of these three local variables contains a " @@ -1964,7 +1965,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1086 +#: doc/tutorial.md:1087 #, no-wrap msgid "" "~~~\n" @@ -1976,7 +1977,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1098 +#: doc/tutorial.md:1099 msgid "" "Suppose we want to write a procedure that computes the distance between any " "two points, no matter where they are stored. For example, we might like to " @@ -1991,7 +1992,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1108 +#: doc/tutorial.md:1109 #, no-wrap msgid "" "~~~\n" @@ -2006,12 +2007,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1110 doc/tutorial-borrowed-ptr.md:72 +#: doc/tutorial.md:1111 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1120 +#: doc/tutorial.md:1121 #, no-wrap msgid "" "~~~\n" @@ -2026,7 +2027,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1127 +#: doc/tutorial.md:1128 msgid "" "Here the `&` operator is used to take the address of the variable " "`on_the_stack`; this is because `on_the_stack` has the type `Point` (that " @@ -2036,7 +2037,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1133 +#: doc/tutorial.md:1134 msgid "" "In the case of the boxes `managed_box` and `owned_box`, however, no explicit " "action is necessary. The compiler will automatically convert a box like " @@ -2046,7 +2047,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1142 +#: doc/tutorial.md:1143 msgid "" "Whenever a value is borrowed, there are some limitations on what you can do " "with the original. For example, if the contents of a variable have been lent " @@ -2058,31 +2059,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1145 +#: doc/tutorial.md:1146 msgid "" "For a more in-depth explanation of borrowed pointers, read the [borrowed " "pointer tutorial][borrowtut]." msgstr "" #. type: Plain text -#: doc/tutorial.md:1147 +#: doc/tutorial.md:1148 msgid "[borrowtut]: tutorial-borrowed-ptr.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1149 +#: doc/tutorial.md:1150 msgid "## Freezing" msgstr "" #. type: Plain text -#: doc/tutorial.md:1152 +#: doc/tutorial.md:1153 msgid "" "Borrowing an immutable pointer to an object freezes it and prevents " "mutation. `Owned` objects have freezing enforced statically at compile-time." msgstr "" #. type: Plain text -#: doc/tutorial.md:1160 +#: doc/tutorial.md:1161 #, no-wrap msgid "" "~~~~\n" @@ -2095,7 +2096,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1164 +#: doc/tutorial.md:1165 msgid "" "Mutable managed boxes handle freezing dynamically when any of their contents " "are borrowed, and the task will fail if an attempt to modify them is made " @@ -2103,7 +2104,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1174 +#: doc/tutorial.md:1175 #, no-wrap msgid "" "~~~~\n" @@ -2118,29 +2119,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1176 +#: doc/tutorial.md:1177 msgid "# Dereferencing pointers" msgstr "" #. type: Plain text -#: doc/tutorial.md:1179 +#: doc/tutorial.md:1180 msgid "" "Rust uses the unary star operator (`*`) to access the contents of a box or " "pointer, similarly to C." msgstr "" #. type: Plain text -#: doc/tutorial.md:1184 +#: doc/tutorial.md:1185 msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1187 +#: doc/tutorial.md:1188 msgid "let sum = *managed + *owned + *borrowed; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1191 +#: doc/tutorial.md:1192 msgid "" "Dereferenced mutable pointers may appear on the left hand side of " "assignments. Such an assignment modifies the value that the pointer points " @@ -2148,17 +2149,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1195 +#: doc/tutorial.md:1196 msgid "~~~ let managed = @mut 10; let mut owned = ~20;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1198 +#: doc/tutorial.md:1199 msgid "let mut value = 30; let borrowed = &mut value;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1203 +#: doc/tutorial.md:1204 #, no-wrap msgid "" "*managed = *owned + 10;\n" @@ -2168,7 +2169,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1207 +#: doc/tutorial.md:1208 msgid "" "Pointers have high operator precedence, but lower precedence than the dot " "operator used for field and method access. This precedence order can " @@ -2176,7 +2177,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1217 +#: doc/tutorial.md:1218 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " @@ -2185,7 +2186,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1221 +#: doc/tutorial.md:1222 msgid "" "To combat this ugliness the dot operator applies _automatic pointer " "dereferencing_ to the receiver (the value on the left-hand side of the dot), " @@ -2193,7 +2194,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1231 +#: doc/tutorial.md:1232 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " @@ -2202,7 +2203,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1235 +#: doc/tutorial.md:1236 msgid "" "You can write an expression that dereferences any number of pointers " "automatically. For example, if you feel inclined, you could write something " @@ -2210,24 +2211,24 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1241 +#: doc/tutorial.md:1242 msgid "" "~~~ # struct Point { x: float, y: float } let point = &@~Point { x: 10f, y: " "20f }; println(fmt!(\"%f\", point.x)); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1243 +#: doc/tutorial.md:1244 msgid "The indexing operator (`[]`) also auto-dereferences." msgstr "" #. type: Plain text -#: doc/tutorial.md:1245 +#: doc/tutorial.md:1246 msgid "# Vectors and strings" msgstr "" #. type: Plain text -#: doc/tutorial.md:1250 +#: doc/tutorial.md:1251 msgid "" "A vector is a contiguous section of memory containing zero or more values of " "the same type. Like other types in Rust, vectors can be stored on the stack, " @@ -2236,7 +2237,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1260 +#: doc/tutorial.md:1261 #, no-wrap msgid "" "~~~\n" @@ -2251,33 +2252,33 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1263 +#: doc/tutorial.md:1264 msgid "" "// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] " "= &[Aquamarine, Asparagus, AtomicTangerine];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1266 +#: doc/tutorial.md:1267 msgid "" "// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = " "@[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1270 +#: doc/tutorial.md:1271 msgid "" "// An exchange heap (owned) vector of crayons let exchange_crayons: " "~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1272 +#: doc/tutorial.md:1273 msgid "The `+` operator means concatenation when applied to vector types." msgstr "" #. type: Plain text -#: doc/tutorial.md:1277 +#: doc/tutorial.md:1278 #, no-wrap msgid "" "~~~~\n" @@ -2287,28 +2288,28 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1280 +#: doc/tutorial.md:1281 msgid "" "let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = " "~[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1283 +#: doc/tutorial.md:1284 msgid "" "// Add two vectors to create a new one let our_crayons = my_crayons + " "your_crayons;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1288 +#: doc/tutorial.md:1289 msgid "" "// .push_all() will append to a vector, provided it lives in a mutable slot " "let mut my_crayons = my_crayons; my_crayons.push_all(your_crayons); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1293 +#: doc/tutorial.md:1294 msgid "" "> ***Note:*** The above examples of vector addition use owned > vectors. " "Some operations on slices and stack vectors are > not yet well-supported. " @@ -2316,12 +2317,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1295 +#: doc/tutorial.md:1296 msgid "Square brackets denote indexing into a vector:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1307 +#: doc/tutorial.md:1308 #, no-wrap msgid "" "~~~~\n" @@ -2338,12 +2339,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1309 +#: doc/tutorial.md:1310 msgid "A vector can be destructured using pattern matching:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1319 +#: doc/tutorial.md:1320 #, no-wrap msgid "" "~~~~\n" @@ -2358,7 +2359,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1323 +#: doc/tutorial.md:1324 msgid "" "The elements of a vector _inherit the mutability of the vector_, and as " "such, individual elements may not be reassigned when the vector lives in an " @@ -2366,7 +2367,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1329 +#: doc/tutorial.md:1330 #, no-wrap msgid "" "~~~ {.xfail-test}\n" @@ -2377,17 +2378,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1332 +#: doc/tutorial.md:1333 msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1334 +#: doc/tutorial.md:1335 msgid "Moving it into a mutable slot makes the elements assignable." msgstr "" #. type: Plain text -#: doc/tutorial.md:1340 +#: doc/tutorial.md:1341 #, no-wrap msgid "" "~~~\n" @@ -2398,25 +2399,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1343 +#: doc/tutorial.md:1344 msgid "" "// Put the vector into a mutable slot let mut mutable_crayons = crayons;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1347 +#: doc/tutorial.md:1348 msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1350 +#: doc/tutorial.md:1351 msgid "" "This is a simple example of Rust's _dual-mode data structures_, also " "referred to as _freezing and thawing_." msgstr "" #. type: Plain text -#: doc/tutorial.md:1358 +#: doc/tutorial.md:1359 msgid "" "Strings are implemented with vectors of `u8`, though they have a distinct " "type. They support most of the same allocation options as vectors, though " @@ -2427,47 +2428,47 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1362 +#: doc/tutorial.md:1363 msgid "" "~~~ // A plain string is a slice to read-only (static) memory let " "stack_crayons: &str = \"Almond, AntiqueBrass, Apricot\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1365 +#: doc/tutorial.md:1366 msgid "" "// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, " "Asparagus, AtomicTangerine\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1368 +#: doc/tutorial.md:1369 msgid "" "// A local heap (managed) string let local_crayons: @str = @\"BananaMania, " "Beaver, Bittersweet\";" msgstr "" #. type: Plain text -#: doc/tutorial.md:1372 +#: doc/tutorial.md:1373 msgid "" "// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, " "BlizzardBlue, Blue\"; ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1376 +#: doc/tutorial.md:1377 msgid "" "Both vectors and strings support a number of useful [methods](#functions-and-" "methods), defined in [`std::vec`] and [`std::str`]. Here are some examples." msgstr "" #. type: Plain text -#: doc/tutorial.md:1379 +#: doc/tutorial.md:1380 msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1390 +#: doc/tutorial.md:1391 #, no-wrap msgid "" "~~~\n" @@ -2483,19 +2484,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1392 +#: doc/tutorial.md:1393 msgid "let crayons = [Almond, AntiqueBrass, Apricot];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1396 +#: doc/tutorial.md:1397 msgid "" "// Check the length of the vector assert!(crayons.len() == 3); assert!(!" "crayons.is_empty());" msgstr "" #. type: Plain text -#: doc/tutorial.md:1403 +#: doc/tutorial.md:1404 #, no-wrap msgid "" "// Iterate over a vector, obtaining a pointer to each element\n" @@ -2507,21 +2508,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1407 +#: doc/tutorial.md:1408 msgid "" "// Map vector elements let crayon_names = crayons.map(|v| " "crayon_to_str(*v)); let favorite_crayon_name = crayon_names[0];" msgstr "" #. type: Plain text -#: doc/tutorial.md:1410 +#: doc/tutorial.md:1411 msgid "" "// Remove whitespace from before and after the string let " "new_favorite_crayon_name = favorite_crayon_name.trim();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1416 +#: doc/tutorial.md:1417 #, no-wrap msgid "" "if favorite_crayon_name.len() > 5 {\n" @@ -2532,12 +2533,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1418 +#: doc/tutorial.md:1419 msgid "# Closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1423 +#: doc/tutorial.md:1424 msgid "" "Named functions, like those we've seen so far, may not refer to local " "variables declared outside the function: they do not close over their " @@ -2546,12 +2547,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1426 +#: doc/tutorial.md:1427 msgid "~~~~ {.ignore} let foo = 10;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1431 +#: doc/tutorial.md:1432 #, no-wrap msgid "" "fn bar() -> int {\n" @@ -2561,31 +2562,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1434 +#: doc/tutorial.md:1435 msgid "" "Rust also supports _closures_, functions that can access variables in the " "enclosing scope." msgstr "" #. type: Plain text -#: doc/tutorial.md:1437 +#: doc/tutorial.md:1438 msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }" msgstr "" #. type: Plain text -#: doc/tutorial.md:1440 +#: doc/tutorial.md:1441 msgid "" "let captured_var = 20; let closure = |arg| println(fmt!(\"captured_var=%d, " "arg=%d\", captured_var, arg));" msgstr "" #. type: Plain text -#: doc/tutorial.md:1443 +#: doc/tutorial.md:1444 msgid "call_closure_with_ten(closure); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1449 +#: doc/tutorial.md:1450 msgid "" "Closures begin with the argument list between vertical bars and are followed " "by a single expression. Remember that a block, `{ ; ; ... }`, " @@ -2595,7 +2596,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1454 +#: doc/tutorial.md:1455 msgid "" "The types of the arguments are generally omitted, as is the return type, " "because the compiler can almost always infer them. In the rare case where " @@ -2604,12 +2605,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1458 +#: doc/tutorial.md:1459 msgid "~~~~ let square = |x: int| -> uint { x * x as uint }; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1462 +#: doc/tutorial.md:1463 msgid "" "There are several forms of closure, each with its own role. The most common, " "called a _stack closure_, has type `&fn` and can directly access local " @@ -2617,12 +2618,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1467 +#: doc/tutorial.md:1468 msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1476 +#: doc/tutorial.md:1477 msgid "" "Stack closures are very efficient because their environment is allocated on " "the call stack and refers by pointer to captured locals. To ensure that " @@ -2634,12 +2635,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1478 +#: doc/tutorial.md:1479 msgid "## Managed closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1484 +#: doc/tutorial.md:1485 msgid "" "When you need to store a closure in a data structure, a stack closure will " "not do, since the compiler will refuse to let you store it. For this " @@ -2649,7 +2650,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1489 +#: doc/tutorial.md:1490 msgid "" "A managed closure does not directly access its environment, but merely " "copies out the values that it closes over into a private data structure. " @@ -2658,14 +2659,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1492 +#: doc/tutorial.md:1493 msgid "" "This code creates a closure that adds a given string to its argument, " "returns it from a function, and then calls it:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1498 +#: doc/tutorial.md:1499 #, no-wrap msgid "" "~~~~\n" @@ -2676,7 +2677,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1504 +#: doc/tutorial.md:1505 #, no-wrap msgid "" "fn main() {\n" @@ -2687,12 +2688,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1506 +#: doc/tutorial.md:1507 msgid "## Owned closures" msgstr "" #. type: Plain text -#: doc/tutorial.md:1513 +#: doc/tutorial.md:1514 msgid "" "Owned closures, written `~fn` in analogy to the `~` pointer type, hold on to " "things that can safely be sent between processes. They copy the values they " @@ -2702,17 +2703,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1515 +#: doc/tutorial.md:1516 msgid "[tasks]: tutorial-tasks.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:1517 +#: doc/tutorial.md:1518 msgid "## Closure compatibility" msgstr "" #. type: Plain text -#: doc/tutorial.md:1524 +#: doc/tutorial.md:1525 msgid "" "Rust closures have a convenient subtyping property: you can pass any kind of " "closure (as long as the arguments and return types match) to functions that " @@ -2723,7 +2724,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1532 +#: doc/tutorial.md:1533 msgid "" "~~~~ fn call_twice(f: &fn()) { f(); f(); } let closure = || { \"I'm a " "closure, and it doesn't matter what type I am\"; }; fn function() { \"I'm a " @@ -2731,7 +2732,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1536 +#: doc/tutorial.md:1537 msgid "" "> ***Note:*** Both the syntax and the semantics will be changing > in small " "ways. At the moment they can be unsound in some > scenarios, particularly " @@ -2739,26 +2740,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1538 +#: doc/tutorial.md:1539 msgid "## Do syntax" msgstr "" #. type: Plain text -#: doc/tutorial.md:1541 +#: doc/tutorial.md:1542 msgid "" "The `do` expression provides a way to treat higher-order functions " "(functions that take closures as arguments) as control structures." msgstr "" #. type: Plain text -#: doc/tutorial.md:1544 +#: doc/tutorial.md:1545 msgid "" "Consider this function that iterates over a vector of integers, passing in a " "pointer to each integer in the vector:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1554 +#: doc/tutorial.md:1555 #, no-wrap msgid "" "~~~~\n" @@ -2773,14 +2774,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1558 +#: doc/tutorial.md:1559 msgid "" "As a caller, if we use a closure to provide the final operator argument, we " "can write it in a way that has a pleasant, block-like structure." msgstr "" #. type: Plain text -#: doc/tutorial.md:1566 +#: doc/tutorial.md:1567 #, no-wrap msgid "" "~~~~\n" @@ -2793,14 +2794,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1569 +#: doc/tutorial.md:1570 msgid "" "This is such a useful pattern that Rust has a special form of function call " "that can be written more like a built-in control structure:" msgstr "" #. type: Plain text -#: doc/tutorial.md:1577 +#: doc/tutorial.md:1578 #, no-wrap msgid "" "~~~~\n" @@ -2813,7 +2814,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1582 +#: doc/tutorial.md:1583 msgid "" "The call is prefixed with the keyword `do` and, instead of writing the final " "closure inside the argument list, it appears outside of the parentheses, " @@ -2821,7 +2822,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1587 +#: doc/tutorial.md:1588 msgid "" "`do` is a convenient way to create tasks with the `task::spawn` function. " "`spawn` has the signature `spawn(fn: ~fn())`. In other words, it is a " @@ -2829,12 +2830,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1590 +#: doc/tutorial.md:1591 msgid "~~~~ use std::task::spawn;" msgstr "" #. type: Plain text -#: doc/tutorial.md:1595 +#: doc/tutorial.md:1596 #, no-wrap msgid "" "do spawn() || {\n" @@ -2844,7 +2845,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1599 +#: doc/tutorial.md:1600 msgid "" "Look at all those bars and parentheses -- that's two empty argument lists " "back to back. Since that is so unsightly, empty argument lists may be " @@ -2852,7 +2853,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1606 +#: doc/tutorial.md:1607 #, no-wrap msgid "" "~~~~\n" @@ -2864,7 +2865,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1609 +#: doc/tutorial.md:1610 msgid "" "If you want to see the output of `debug!` statements, you will need to turn " "on `debug!` logging. To enable `debug!` logging, set the RUST_LOG " @@ -2873,12 +2874,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1611 +#: doc/tutorial.md:1612 msgid "# Methods" msgstr "" #. type: Plain text -#: doc/tutorial.md:1617 +#: doc/tutorial.md:1618 msgid "" "Methods are like functions except that they always begin with a special " "argument, called `self`, which has the type of the method's receiver. The " @@ -2887,7 +2888,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1621 +#: doc/tutorial.md:1622 msgid "" "_Implementations_, written with the `impl` keyword, can define methods on " "most Rust types, including structs and enums. As an example, let's define a " @@ -2895,7 +2896,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1629 +#: doc/tutorial.md:1630 #, no-wrap msgid "" "~~~\n" @@ -2908,7 +2909,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1634 +#: doc/tutorial.md:1635 #, no-wrap msgid "" "enum Shape {\n" @@ -2918,7 +2919,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1643 +#: doc/tutorial.md:1644 #, no-wrap msgid "" "impl Shape {\n" @@ -2932,12 +2933,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1647 +#: doc/tutorial.md:1648 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1651 +#: doc/tutorial.md:1652 msgid "" "This defines an _implementation_ for `Shape` containing a single method, " "`draw`. In most respects the `draw` method is defined like any other " @@ -2945,7 +2946,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1656 +#: doc/tutorial.md:1657 msgid "" "The type of `self` is the type on which the method is implemented, or a " "pointer thereof. As an argument it is written either `self`, `&self`, " @@ -2954,7 +2955,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1671 +#: doc/tutorial.md:1672 #, no-wrap msgid "" "~~~\n" @@ -2974,26 +2975,26 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1673 +#: doc/tutorial.md:1674 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);" msgstr "" #. type: Plain text -#: doc/tutorial.md:1679 +#: doc/tutorial.md:1680 msgid "" "(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s." "draw_value(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1683 +#: doc/tutorial.md:1684 msgid "" "Methods typically take a borrowed pointer self type, so the compiler will go " "to great lengths to convert a callee to a borrowed pointer." msgstr "" #. type: Plain text -#: doc/tutorial.md:1701 +#: doc/tutorial.md:1702 #, no-wrap msgid "" "~~~\n" @@ -3016,29 +3017,29 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1704 +#: doc/tutorial.md:1705 msgid "(@s).draw_borrowed(); (~s).draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1708 +#: doc/tutorial.md:1709 msgid "" "// Unlike typical function arguments, the self value will // automatically " "be referenced ... s.draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1711 +#: doc/tutorial.md:1712 msgid "// ... and dereferenced (& &s).draw_borrowed();" msgstr "" #. type: Plain text -#: doc/tutorial.md:1715 +#: doc/tutorial.md:1716 msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:1719 +#: doc/tutorial.md:1720 msgid "" "Implementations may also define standalone (sometimes called \"static\") " "methods. The absence of a `self` parameter distinguishes such methods. " @@ -3046,7 +3047,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1726 +#: doc/tutorial.md:1727 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" @@ -3058,7 +3059,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:1728 +#: doc/tutorial.md:1729 msgid "" "To call such a method, just prefix it with the type name and a double colon:" msgstr "" @@ -3069,10 +3070,9 @@ msgstr "" msgid "" "~~~~\n" "# use std::float::consts::pi;\n" -"# use std::float::sqrt;\n" "struct Circle { radius: float }\n" "impl Circle {\n" -" fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" +" fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "let c = Circle::new(42.5);\n" "~~~~\n" @@ -3525,39 +3525,38 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2004 +#: doc/tutorial.md:2003 msgid "" -"~~~~ # use std::float::consts::pi; # use std::float::sqrt; trait Shape { fn " -"new(area: float) -> Self; } struct Circle { radius: float } struct Square " -"{ length: float }" +"~~~~ # use std::float::consts::pi; trait Shape { fn new(area: float) -> " +"Self; } struct Circle { radius: float } struct Square { length: float }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2011 +#: doc/tutorial.md:2010 #, no-wrap msgid "" "impl Shape for Circle {\n" -" fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" +" fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "impl Shape for Square {\n" -" fn new(area: float) -> Square { Square { length: sqrt(area) } }\n" +" fn new(area: float) -> Square { Square { length: (area).sqrt() } }\n" "}\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2016 +#: doc/tutorial.md:2015 msgid "" "let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::" "new(area); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2018 +#: doc/tutorial.md:2017 msgid "## Bounded type parameters and static method dispatch" msgstr "" #. type: Plain text -#: doc/tutorial.md:2023 +#: doc/tutorial.md:2022 msgid "" "Traits give us a language for defining predicates on types, or abstract " "properties that types can have. We can use this language to define _bounds_ " @@ -3565,7 +3564,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2032 +#: doc/tutorial.md:2031 #, no-wrap msgid "" "~~~~\n" @@ -3579,7 +3578,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2038 +#: doc/tutorial.md:2037 msgid "" "Declaring `T` as conforming to the `Printable` trait (as we earlier did with " "`Copy`) makes it possible to call methods from that trait on values of type " @@ -3589,14 +3588,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2041 +#: doc/tutorial.md:2040 msgid "" "Type parameters can have multiple bounds by separating them with `+`, as in " "this version of `print_all` that copies elements." msgstr "" #. type: Plain text -#: doc/tutorial.md:2053 +#: doc/tutorial.md:2052 #, no-wrap msgid "" "~~~\n" @@ -3613,7 +3612,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2057 +#: doc/tutorial.md:2056 msgid "" "Method calls to bounded type parameters are _statically dispatched_, " "imposing no more overhead than normal function invocation, so are the " @@ -3621,17 +3620,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2059 +#: doc/tutorial.md:2058 msgid "This usage of traits is similar to Haskell type classes." msgstr "" #. type: Plain text -#: doc/tutorial.md:2061 +#: doc/tutorial.md:2060 msgid "## Trait objects and dynamic method dispatch" msgstr "" #. type: Plain text -#: doc/tutorial.md:2065 +#: doc/tutorial.md:2064 msgid "" "The above allows us to define functions that polymorphically act on values " "of a single unknown type that conforms to a given trait. However, consider " @@ -3639,7 +3638,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2071 +#: doc/tutorial.md:2070 msgid "" "~~~~ # type Circle = int; type Rectangle = int; # impl Drawable for int { fn " "draw(&self) {} } # fn new_circle() -> int { 1 } trait Drawable { fn " @@ -3647,7 +3646,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2078 +#: doc/tutorial.md:2077 #, no-wrap msgid "" "fn draw_all(shapes: ~[T]) {\n" @@ -3659,7 +3658,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2084 +#: doc/tutorial.md:2083 msgid "" "You can call that on an array of circles, or an array of rectangles " "(assuming those have suitable `Drawable` traits defined), but not on an " @@ -3668,7 +3667,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2091 +#: doc/tutorial.md:2090 #, no-wrap msgid "" "~~~~\n" @@ -3680,7 +3679,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2096 +#: doc/tutorial.md:2095 msgid "" "In this example, there is no type parameter. Instead, the `@Drawable` type " "denotes any managed box value that implements the `Drawable` trait. To " @@ -3689,7 +3688,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2103 +#: doc/tutorial.md:2102 msgid "" "~~~~ # type Circle = int; type Rectangle = bool; # trait Drawable { fn " "draw(&self); } # fn new_circle() -> Circle { 1 } # fn new_rectangle() -> " @@ -3697,21 +3696,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2106 +#: doc/tutorial.md:2105 msgid "" "impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for " "Rectangle { fn draw(&self) { ... } }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2111 +#: doc/tutorial.md:2110 msgid "" "let c: @Circle = @new_circle(); let r: @Rectangle = @new_rectangle(); " "draw_all([c as @Drawable, r as @Drawable]); ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2119 +#: doc/tutorial.md:2118 msgid "" "We omit the code for `new_circle` and `new_rectangle`; imagine that these " "just return `Circle`s and `Rectangle`s with a default size. Note that, like " @@ -3722,7 +3721,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2133 +#: doc/tutorial.md:2132 msgid "" "~~~ # type Circle = int; type Rectangle = int; # trait Drawable { fn " "draw(&self); } # impl Drawable for int { fn draw(&self) {} } # fn " @@ -3733,7 +3732,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2138 +#: doc/tutorial.md:2137 msgid "" "Method calls to trait types are _dynamically dispatched_. Since the compiler " "doesn't know specifically which functions to call at compile time, it uses a " @@ -3742,17 +3741,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2140 +#: doc/tutorial.md:2139 msgid "This usage of traits is similar to Java interfaces." msgstr "" #. type: Plain text -#: doc/tutorial.md:2142 +#: doc/tutorial.md:2141 msgid "## Trait inheritance" msgstr "" #. type: Plain text -#: doc/tutorial.md:2147 +#: doc/tutorial.md:2146 msgid "" "We can write a trait declaration that _inherits_ from other traits, called " "_supertraits_. Types that implement a trait must also implement its " @@ -3761,32 +3760,31 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2152 +#: doc/tutorial.md:2151 msgid "" "~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn " "radius(&self) -> float; } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2154 +#: doc/tutorial.md:2153 msgid "" "Now, we can implement `Circle` on a type only if we also implement `Shape`." msgstr "" #. type: Plain text -#: doc/tutorial.md:2170 +#: doc/tutorial.md:2168 #, no-wrap msgid "" "~~~~\n" "# use std::float::consts::pi;\n" -"# use std::float::sqrt;\n" "# trait Shape { fn area(&self) -> float; }\n" "# trait Circle : Shape { fn radius(&self) -> float; }\n" "# struct Point { x: float, y: float }\n" "# fn square(x: float) -> float { x * x }\n" "struct CircleStruct { center: Point, radius: float }\n" "impl Circle for CircleStruct {\n" -" fn radius(&self) -> float { sqrt(self.area() / pi) }\n" +" fn radius(&self) -> float { (self.area() / pi).sqrt() }\n" "}\n" "impl Shape for CircleStruct {\n" " fn area(&self) -> float { pi * square(self.radius) }\n" @@ -3795,7 +3793,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2175 +#: doc/tutorial.md:2173 msgid "" "Notice that methods of `Circle` can call methods on `Shape`, as our `radius` " "implementation calls the `area` method. This is a silly way to compute the " @@ -3804,18 +3802,18 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2200 +#: doc/tutorial.md:2197 msgid "" -"~~~ {.xfail-test} # use std::float::consts::pi; # use std::float::sqrt; # " -"trait Shape { fn area(&self) -> float; } # trait Circle : Shape { fn " -"radius(&self) -> float; } # struct Point { x: float, y: float } # struct " -"CircleStruct { center: Point, radius: float } # impl Circle for CircleStruct " -"{ fn radius(&self) -> float { sqrt(self.area() / pi) } } # impl Shape for " +"~~~ {.xfail-test} # use std::float::consts::pi; # trait Shape { fn " +"area(&self) -> float; } # trait Circle : Shape { fn radius(&self) -> " +"float; } # struct Point { x: float, y: float } # struct CircleStruct " +"{ center: Point, radius: float } # impl Circle for CircleStruct { fn " +"radius(&self) -> float { (self.area() / pi).sqrt() } } # impl Shape for " "CircleStruct { fn area(&self) -> float { pi * square(self.radius) } }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2205 +#: doc/tutorial.md:2202 msgid "" "let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; let " "mycircle: Circle = concrete as @Circle; let nonsense = mycircle.radius() * " @@ -3823,17 +3821,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2207 +#: doc/tutorial.md:2204 msgid "> ***Note:*** Trait inheritance does not actually work with objects yet" msgstr "" #. type: Plain text -#: doc/tutorial.md:2209 +#: doc/tutorial.md:2206 msgid "## Deriving implementations for traits" msgstr "" #. type: Plain text -#: doc/tutorial.md:2216 +#: doc/tutorial.md:2213 msgid "" "A small number of traits in `std` and `extra` can have implementations that " "can be automatically derived. These instances are specified by placing the " @@ -3844,17 +3842,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2220 +#: doc/tutorial.md:2217 msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }" msgstr "" #. type: Plain text -#: doc/tutorial.md:2224 +#: doc/tutorial.md:2221 msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2228 +#: doc/tutorial.md:2225 msgid "" "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, " "`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, " @@ -3862,19 +3860,19 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2230 +#: doc/tutorial.md:2227 msgid "# Modules and crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2234 +#: doc/tutorial.md:2231 msgid "" "The Rust namespace is arranged in a hierarchy of modules. Each source (.rs) " "file represents a single module and may in turn contain additional modules." msgstr "" #. type: Plain text -#: doc/tutorial.md:2240 +#: doc/tutorial.md:2237 #, no-wrap msgid "" "~~~~\n" @@ -3885,7 +3883,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2245 +#: doc/tutorial.md:2242 #, no-wrap msgid "" "fn main() {\n" @@ -3895,7 +3893,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2250 +#: doc/tutorial.md:2247 msgid "" "The contents of modules can be imported into the current scope with the " "`use` keyword, optionally giving it an alias. `use` may appear at the " @@ -3903,14 +3901,14 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2256 +#: doc/tutorial.md:2253 msgid "" "~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` " "into scope use farm::chicken;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2266 +#: doc/tutorial.md:2263 #, no-wrap msgid "" "fn chicken_farmer() {\n" @@ -3925,7 +3923,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2273 +#: doc/tutorial.md:2270 msgid "" "These farm animal functions have a new keyword, `pub`, attached to them. The " "`pub` keyword modifies an item's visibility, making it visible outside its " @@ -3935,7 +3933,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2280 +#: doc/tutorial.md:2277 msgid "" "Visibility restrictions in Rust exist only at module boundaries. This is " "quite different from most object-oriented languages that also enforce " @@ -3946,7 +3944,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2293 +#: doc/tutorial.md:2290 #, no-wrap msgid "" "~~~\n" @@ -3964,7 +3962,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2299 +#: doc/tutorial.md:2296 #, no-wrap msgid "" " impl Farm {\n" @@ -3975,7 +3973,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2305 +#: doc/tutorial.md:2302 #, no-wrap msgid "" " pub fn feed_animals(farm: &Farm) {\n" @@ -3986,7 +3984,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2315 +#: doc/tutorial.md:2312 #, no-wrap msgid "" "fn main() {\n" @@ -4001,12 +3999,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2317 +#: doc/tutorial.md:2314 msgid "## Crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2321 +#: doc/tutorial.md:2318 msgid "" "The unit of independent compilation in Rust is the crate: rustc compiles a " "single crate at a time, from which it produces either a library or an " @@ -4014,7 +4012,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2326 +#: doc/tutorial.md:2323 msgid "" "When compiling a single `.rs` source file, the file acts as the whole " "crate. You can compile it with the `--lib` compiler switch to create a " @@ -4023,7 +4021,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2331 +#: doc/tutorial.md:2328 msgid "" "Larger crates typically span multiple files and are, by convention, compiled " "from a source file with the `.rc` extension, called a *crate file*. The " @@ -4032,7 +4030,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2340 +#: doc/tutorial.md:2337 msgid "" "A typical crate file declares attributes associated with the crate that may " "affect how the compiler processes the source. Crate attributes specify " @@ -4043,34 +4041,34 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2344 +#: doc/tutorial.md:2341 msgid "" "~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers " "= \"2.5\", author = \"mjh\")];" msgstr "" #. type: Plain text -#: doc/tutorial.md:2347 +#: doc/tutorial.md:2344 msgid "// Make a library (\"bin\" is the default) #[crate_type = \"lib\"];" msgstr "" #. type: Plain text -#: doc/tutorial.md:2350 +#: doc/tutorial.md:2347 msgid "// Turn on a warning #[warn(non_camel_case_types)]" msgstr "" #. type: Plain text -#: doc/tutorial.md:2353 +#: doc/tutorial.md:2350 msgid "// Link to the standard library extern mod std;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2358 +#: doc/tutorial.md:2355 msgid "// Load some modules from other files mod cow; mod chicken; mod horse;" msgstr "" #. type: Plain text -#: doc/tutorial.md:2363 +#: doc/tutorial.md:2360 #, no-wrap msgid "" "fn main() {\n" @@ -4080,7 +4078,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2370 +#: doc/tutorial.md:2367 msgid "" "Compiling this file will cause `rustc` to look for files named `cow.rs`, " "`chicken.rs`, and `horse.rs` in the same directory as the `.rc` file, " @@ -4090,21 +4088,21 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2374 +#: doc/tutorial.md:2371 msgid "" "The `#[link(...)]` attribute provides meta information about the module, " "which other crates can use to load the right module. More about that later." msgstr "" #. type: Plain text -#: doc/tutorial.md:2377 +#: doc/tutorial.md:2374 msgid "" "To have a nested directory structure for your source files, you can nest " "mods:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2384 +#: doc/tutorial.md:2381 #, no-wrap msgid "" "~~~~ {.ignore}\n" @@ -4116,7 +4114,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2389 +#: doc/tutorial.md:2386 msgid "" "The compiler will now look for `poultry/chicken.rs` and `poultry/turkey.rs`, " "and export their content in `poultry::chicken` and `poultry::turkey`. You " @@ -4125,12 +4123,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2391 +#: doc/tutorial.md:2388 msgid "## Using other crates" msgstr "" #. type: Plain text -#: doc/tutorial.md:2399 +#: doc/tutorial.md:2396 msgid "" "The `extern mod` directive lets you use a crate (once it's been compiled " "into a library) from inside another crate. `extern mod` can appear at the " @@ -4141,17 +4139,17 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2401 +#: doc/tutorial.md:2398 msgid "For example, `extern mod std` links the [standard library]." msgstr "" #. type: Plain text -#: doc/tutorial.md:2403 +#: doc/tutorial.md:2400 msgid "[standard library]: std/index.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:2410 +#: doc/tutorial.md:2407 msgid "" "When a comma-separated list of name/value pairs appears after `extern mod`, " "the compiler front-end matches these pairs against the attributes provided " @@ -4161,22 +4159,22 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2412 +#: doc/tutorial.md:2409 msgid "Our example crate declared this set of `link` attributes:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2416 +#: doc/tutorial.md:2413 msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2418 +#: doc/tutorial.md:2415 msgid "Which you can then link with any (or all) of the following:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2424 +#: doc/tutorial.md:2421 msgid "" "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", " "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = " @@ -4184,45 +4182,45 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2427 +#: doc/tutorial.md:2424 msgid "" "If any of the requested metadata do not match, then the crate will not be " "compiled successfully." msgstr "" #. type: Plain text -#: doc/tutorial.md:2429 +#: doc/tutorial.md:2426 msgid "## A minimal example" msgstr "" #. type: Plain text -#: doc/tutorial.md:2432 +#: doc/tutorial.md:2429 msgid "" "Now for something that you can actually compile yourself, we have these two " "files:" msgstr "" #. type: Plain text -#: doc/tutorial.md:2438 +#: doc/tutorial.md:2435 msgid "" "~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() " "-> &str { \"world\" } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2444 +#: doc/tutorial.md:2441 msgid "" "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello " "\" + world::explore()); } ~~~~" msgstr "" #. type: Plain text -#: doc/tutorial.md:2446 +#: doc/tutorial.md:2443 msgid "Now compile and run like this (adjust to your platform if necessary):" msgstr "" #. type: Plain text -#: doc/tutorial.md:2453 +#: doc/tutorial.md:2450 #, no-wrap msgid "" "~~~~ {.notrust}\n" @@ -4234,7 +4232,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2458 +#: doc/tutorial.md:2455 msgid "" "Notice that the library produced contains the version in the filename as " "well as an inscrutable string of alphanumerics. These are both part of " @@ -4243,12 +4241,12 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2460 +#: doc/tutorial.md:2457 msgid "## The standard library" msgstr "" #. type: Plain text -#: doc/tutorial.md:2465 +#: doc/tutorial.md:2462 msgid "" "The Rust standard library provides runtime features required by the " "language, including the task scheduler and memory allocators, as well as " @@ -4257,7 +4255,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2476 +#: doc/tutorial.md:2473 msgid "" "[`std`] includes modules corresponding to each of the integer types, each of " "the floating point types, the [`bool`] type, [tuples], [characters], " @@ -4271,25 +4269,25 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2478 +#: doc/tutorial.md:2475 msgid "### Standard Library injection and the Rust prelude" msgstr "" #. type: Plain text -#: doc/tutorial.md:2481 +#: doc/tutorial.md:2478 msgid "" "`std` is imported at the topmost level of every crate by default, as if the " "first line of each crate was" msgstr "" #. type: Plain text -#: doc/tutorial.md:2483 +#: doc/tutorial.md:2480 #, no-wrap msgid " extern mod std;\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2487 +#: doc/tutorial.md:2484 msgid "" "This means that the contents of std can be accessed from from any context " "with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, " @@ -4297,7 +4295,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2492 +#: doc/tutorial.md:2489 msgid "" "Additionally, `std` contains a `prelude` module that reexports many of the " "most common standard modules, types and traits. The contents of the prelude " @@ -4306,13 +4304,13 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2494 +#: doc/tutorial.md:2491 #, no-wrap msgid " use std::prelude::*;\n" msgstr "" #. type: Plain text -#: doc/tutorial.md:2520 +#: doc/tutorial.md:2517 msgid "" "[`std`]: std/index.html [`bool`]: std/bool.html [tuples]: std/tuple.html " "[characters]: std/char.html [strings]: std/str.html [vectors]: std/vec.html " @@ -4326,56 +4324,56 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2522 +#: doc/tutorial.md:2519 msgid "# What next?" msgstr "" #. type: Plain text -#: doc/tutorial.md:2525 +#: doc/tutorial.md:2522 msgid "" "Now that you know the essentials, check out any of the additional tutorials " "on individual topics." msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Borrowed pointers][borrow]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Tasks and communication][tasks]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Macros][macros]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[The foreign function interface][ffi]" msgstr "" #. type: Bullet: '* ' -#: doc/tutorial.md:2531 +#: doc/tutorial.md:2528 msgid "[Containers and iterators](tutorial-container.html)" msgstr "" #. type: Plain text -#: doc/tutorial.md:2533 +#: doc/tutorial.md:2530 msgid "There is further documentation on the [wiki]." msgstr "" #. type: Plain text -#: doc/tutorial.md:2538 +#: doc/tutorial.md:2535 msgid "" "[borrow]: tutorial-borrowed-ptr.html [tasks]: tutorial-tasks.html [macros]: " "tutorial-macros.html [ffi]: tutorial-ffi.html" msgstr "" #. type: Plain text -#: doc/tutorial.md:2544 +#: doc/tutorial.md:2541 msgid "" "[wiki]: https://github.com/mozilla/rust/wiki/Docs [unit testing]: https://" "github.com/mozilla/rust/wiki/Doc-unit-testing [rustdoc]: https://github.com/" @@ -4385,7 +4383,7 @@ msgid "" msgstr "" #. type: Plain text -#: doc/tutorial.md:2545 +#: doc/tutorial.md:2542 msgid "" "[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust" msgstr "" diff --git a/mk/docs.mk b/mk/docs.mk index 14480dfed00f9..cc86111b728d4 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -236,6 +236,9 @@ GENERATED += doc/version.md doc/version_info.html docs: $(DOCS) docs-l10n: - po4a doc/po4a.conf + po4a --copyright-holder="The Rust Project Developers" \ + --package-name="Rust" \ + --package-version="$(CFG_RELEASE)" \ + doc/po4a.conf .PHONY: docs-l10n From 40f74341f3ba2cee2afedb31014ee14432d700cd Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 16 Jul 2013 17:42:28 -0700 Subject: [PATCH 07/11] test: new codegen tests, rename hello. --- src/test/codegen/iterate-over-array.cc | 17 +++++++++++++++++ src/test/codegen/iterate-over-array.rs | 10 ++++++++++ src/test/codegen/scalar-function-call.cc | 10 ++++++++++ src/test/codegen/scalar-function-call.rs | 8 ++++++++ src/test/codegen/small-dense-int-switch.cc | 11 +++++++++++ src/test/codegen/small-dense-int-switch.rs | 9 +++++++++ .../{hello.cc => stack-alloc-string-slice.cc} | 0 .../{hello.rs => stack-alloc-string-slice.rs} | 0 8 files changed, 65 insertions(+) create mode 100644 src/test/codegen/iterate-over-array.cc create mode 100644 src/test/codegen/iterate-over-array.rs create mode 100644 src/test/codegen/scalar-function-call.cc create mode 100644 src/test/codegen/scalar-function-call.rs create mode 100644 src/test/codegen/small-dense-int-switch.cc create mode 100644 src/test/codegen/small-dense-int-switch.rs rename src/test/codegen/{hello.cc => stack-alloc-string-slice.cc} (100%) rename src/test/codegen/{hello.rs => stack-alloc-string-slice.rs} (100%) diff --git a/src/test/codegen/iterate-over-array.cc b/src/test/codegen/iterate-over-array.cc new file mode 100644 index 0000000000000..7eca21b13d70b --- /dev/null +++ b/src/test/codegen/iterate-over-array.cc @@ -0,0 +1,17 @@ +#include +#include + +struct slice { + int const *p; + size_t len; +}; + +extern "C" +size_t test(slice s) { + size_t y = 0; + for (int i = 0; i < s.len; ++i) { + assert(i < s.len); + y += s.p[i]; + } + return y; +} diff --git a/src/test/codegen/iterate-over-array.rs b/src/test/codegen/iterate-over-array.rs new file mode 100644 index 0000000000000..cf54e6eafbaf1 --- /dev/null +++ b/src/test/codegen/iterate-over-array.rs @@ -0,0 +1,10 @@ +#[no_mangle] +fn test(x: &[int]) -> int { + let mut y = 0; + let mut i = 0; + while (i < x.len()) { + y += x[i]; + i += 1; + } + y +} diff --git a/src/test/codegen/scalar-function-call.cc b/src/test/codegen/scalar-function-call.cc new file mode 100644 index 0000000000000..91ed882f68a9f --- /dev/null +++ b/src/test/codegen/scalar-function-call.cc @@ -0,0 +1,10 @@ +#include + +size_t foo(size_t x) { + return x * x; +} + +extern "C" +void test() { + size_t x = foo(10); +} diff --git a/src/test/codegen/scalar-function-call.rs b/src/test/codegen/scalar-function-call.rs new file mode 100644 index 0000000000000..7e4a566749ba6 --- /dev/null +++ b/src/test/codegen/scalar-function-call.rs @@ -0,0 +1,8 @@ +fn foo(x: int) -> int { + x * x +} + +#[no_mangle] +fn test() { + let x = foo(10); +} diff --git a/src/test/codegen/small-dense-int-switch.cc b/src/test/codegen/small-dense-int-switch.cc new file mode 100644 index 0000000000000..87bc5bf852eb4 --- /dev/null +++ b/src/test/codegen/small-dense-int-switch.cc @@ -0,0 +1,11 @@ +#include + +extern "C" +size_t test(size_t x, size_t y) { + switch (x) { + case 1: return y; + case 2: return y*2; + case 4: return y*3; + default: return 11; + } +} diff --git a/src/test/codegen/small-dense-int-switch.rs b/src/test/codegen/small-dense-int-switch.rs new file mode 100644 index 0000000000000..6840dc7411b34 --- /dev/null +++ b/src/test/codegen/small-dense-int-switch.rs @@ -0,0 +1,9 @@ +#[no_mangle] +fn test(x: int, y: int) -> int { + match x { + 1 => y, + 2 => y*2, + 4 => y*3, + _ => 11 + } +} diff --git a/src/test/codegen/hello.cc b/src/test/codegen/stack-alloc-string-slice.cc similarity index 100% rename from src/test/codegen/hello.cc rename to src/test/codegen/stack-alloc-string-slice.cc diff --git a/src/test/codegen/hello.rs b/src/test/codegen/stack-alloc-string-slice.rs similarity index 100% rename from src/test/codegen/hello.rs rename to src/test/codegen/stack-alloc-string-slice.rs From 948a62401ef717eb484c2215713291749f0f35ed Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Jul 2013 17:20:43 -0700 Subject: [PATCH 08/11] Add a `get_mut` method for TLS Simulates borrow checks for '@mut' boxes, or at least it's the same idea. --- src/libstd/local_data.rs | 77 ++++++++++++++++++++++++++- src/libstd/task/local_data_priv.rs | 84 ++++++++++++++++++++++++------ 2 files changed, 145 insertions(+), 16 deletions(-) diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index be170cce07e54..6c1640e683e59 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -41,7 +41,7 @@ magic. use prelude::*; -use task::local_data_priv::{local_get, local_pop, local_set, Handle}; +use task::local_data_priv::*; #[cfg(test)] use task; @@ -95,6 +95,13 @@ pub fn get(key: Key<@T>, f: &fn(Option<&@T>) -> U) -> U { pub fn get(key: Key, f: &fn(Option<&T>) -> U) -> U { unsafe { local_get(Handle::new(), key, f) } } +/** + * Retrieve a mutable borrowed pointer to a task-local data value. + */ +#[cfg(not(stage0))] +pub fn get_mut(key: Key, f: &fn(Option<&mut T>) -> U) -> U { + unsafe { local_get_mut(Handle::new(), key, f) } +} /** * Store a value in task-local data. If this key already has a value, * that value is overwritten (and its destructor is run). @@ -262,6 +269,34 @@ fn test_static_pointer() { fn test_owned() { static key: Key<~int> = &Key; set(key, ~1); + + do get(key) |v| { + do get(key) |v| { + do get(key) |v| { + assert_eq!(**v.unwrap(), 1); + } + assert_eq!(**v.unwrap(), 1); + } + assert_eq!(**v.unwrap(), 1); + } + set(key, ~2); + do get(key) |v| { + assert_eq!(**v.unwrap(), 2); + } +} + +#[test] +fn test_get_mut() { + static key: Key = &Key; + set(key, 1); + + do get_mut(key) |v| { + *v.unwrap() = 2; + } + + do get(key) |v| { + assert_eq!(*v.unwrap(), 2); + } } #[test] @@ -283,3 +318,43 @@ fn test_same_key_type() { get(key4, |x| assert_eq!(*x.unwrap(), 4)); get(key5, |x| assert_eq!(*x.unwrap(), 5)); } + +#[test] +#[should_fail] +fn test_nested_get_set1() { + static key: Key = &Key; + set(key, 4); + do get(key) |_| { + set(key, 4); + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut2() { + static key: Key = &Key; + set(key, 4); + do get(key) |_| { + get_mut(key, |_| {}) + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut3() { + static key: Key = &Key; + set(key, 4); + do get_mut(key) |_| { + get(key, |_| {}) + } +} + +#[test] +#[should_fail] +fn test_nested_get_mut4() { + static key: Key = &Key; + set(key, 4); + do get_mut(key) |_| { + get_mut(key, |_| {}) + } +} diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index d46e5707f14a9..75fd6eacc1b3a 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -44,6 +44,21 @@ impl Handle { } } +#[deriving(Eq)] +enum LoanState { + NoLoan, ImmLoan, MutLoan +} + +impl LoanState { + fn describe(&self) -> &'static str { + match *self { + NoLoan => "no loan", + ImmLoan => "immutable", + MutLoan => "mutable" + } + } +} + trait LocalData {} impl LocalData for T {} @@ -77,7 +92,7 @@ impl LocalData for T {} // // n.b. If TLS is used heavily in future, this could be made more efficient with // a proper map. -type TaskLocalMap = ~[Option<(*libc::c_void, TLSValue, uint)>]; +type TaskLocalMap = ~[Option<(*libc::c_void, TLSValue, LoanState)>]; type TLSValue = ~LocalData:; fn cleanup_task_local_map(map_ptr: *libc::c_void) { @@ -152,9 +167,10 @@ pub unsafe fn local_pop(handle: Handle, for map.mut_iter().advance |entry| { match *entry { - Some((k, _, loans)) if k == key_value => { - if loans != 0 { - fail!("TLS value has been loaned via get already"); + Some((k, _, loan)) if k == key_value => { + if loan != NoLoan { + fail!("TLS value cannot be removed because it is already \ + borrowed as %s", loan.describe()); } // Move the data out of the `entry` slot via util::replace. This // is guaranteed to succeed because we already matched on `Some` @@ -192,6 +208,29 @@ pub unsafe fn local_pop(handle: Handle, pub unsafe fn local_get(handle: Handle, key: local_data::Key, f: &fn(Option<&T>) -> U) -> U { + local_get_with(handle, key, ImmLoan, f) +} + +pub unsafe fn local_get_mut(handle: Handle, + key: local_data::Key, + f: &fn(Option<&mut T>) -> U) -> U { + do local_get_with(handle, key, MutLoan) |x| { + match x { + None => f(None), + // We're violating a lot of compiler guarantees with this + // invocation of `transmute_mut`, but we're doing runtime checks to + // ensure that it's always valid (only one at a time). + // + // there is no need to be upset! + Some(x) => { f(Some(cast::transmute_mut(x))) } + } + } +} + +unsafe fn local_get_with(handle: Handle, + key: local_data::Key, + state: LoanState, + f: &fn(Option<&T>) -> U) -> U { // This function must be extremely careful. Because TLS can store owned // values, and we must have some form of `get` function other than `pop`, // this function has to give a `&` reference back to the caller. @@ -218,12 +257,24 @@ pub unsafe fn local_get(handle: Handle, None => { return f(None); } Some(i) => { let ret; + let mut return_loan = false; match map[i] { - Some((_, ref data, ref mut loans)) => { - *loans = *loans + 1; + Some((_, ref data, ref mut loan)) => { + match (state, *loan) { + (_, NoLoan) => { + *loan = state; + return_loan = true; + } + (ImmLoan, ImmLoan) => {} + (want, cur) => { + fail!("TLS slot cannot be borrowed as %s because \ + it is already borrowed as %s", + want.describe(), cur.describe()); + } + } // data was created with `~~T as ~LocalData`, so we extract // pointer part of the trait, (as ~~T), and then use - // compiler coercions to achieve a '&' pointer + // compiler coercions to achieve a '&' pointer. match *cast::transmute::<&TLSValue, &(uint, ~~T)>(data) { (_vtable, ref box) => { let value: &T = **box; @@ -238,9 +289,11 @@ pub unsafe fn local_get(handle: Handle, // 'f' returned because `f` could have appended more TLS items which // in turn relocated the vector. Hence we do another lookup here to // fixup the loans. - match map[i] { - Some((_, _, ref mut loans)) => { *loans = *loans - 1; } - None => { libc::abort(); } + if return_loan { + match map[i] { + Some((_, _, ref mut loan)) => { *loan = NoLoan; } + None => { libc::abort(); } + } } return ret; } @@ -269,9 +322,10 @@ pub unsafe fn local_set(handle: Handle, // First see if the map contains this key already let curspot = map.iter().position(|entry| { match *entry { - Some((ekey, _, loans)) if key == ekey => { - if loans != 0 { - fail!("TLS value has been loaned via get already"); + Some((ekey, _, loan)) if key == ekey => { + if loan != NoLoan { + fail!("TLS value cannot be overwritten because it is + already borrowed as %s", loan.describe()) } true } @@ -286,7 +340,7 @@ pub unsafe fn local_set(handle: Handle, } match insertion_position(map, keyval) { - Some(i) => { map[i] = Some((keyval, data, 0)); } - None => { map.push(Some((keyval, data, 0))); } + Some(i) => { map[i] = Some((keyval, data, NoLoan)); } + None => { map.push(Some((keyval, data, NoLoan))); } } } From 0fd4d5d7783ffa709bcf089f5167a1871ec278fa Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Jul 2013 21:12:16 -0700 Subject: [PATCH 09/11] Sort lint attributes to print them in a more sane way Closes #7818 --- src/librustc/middle/lint.rs | 9 +++++++-- src/librustc/rustc.rs | 25 ++++++++++++++----------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index b679da714a174..d18fbada009a1 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -108,17 +108,22 @@ pub fn level_to_str(lv: level) -> &'static str { } } -#[deriving(Eq)] +#[deriving(Eq, Ord)] pub enum level { allow, warn, deny, forbid } -struct LintSpec { +#[deriving(Eq)] +pub struct LintSpec { lint: lint, desc: &'static str, default: level } +impl Ord for LintSpec { + fn lt(&self, other: &LintSpec) -> bool { self.default < other.default } +} + pub type LintDict = HashMap<&'static str, LintSpec>; enum AttributedNode<'self> { diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 787d8d5685a34..6f638959bc830 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -144,6 +144,7 @@ Additional help: } pub fn describe_warnings() { + use extra::sort::Sort; io::println(fmt!(" Available lint options: -W Warn about @@ -153,8 +154,15 @@ Available lint options: ")); let lint_dict = lint::get_lint_dict(); + let mut lint_dict = lint_dict.consume_iter() + .transform(|(k, v)| (v, k)) + .collect::<~[(lint::LintSpec, &'static str)]>(); + lint_dict.qsort(); + let mut max_key = 0; - for lint_dict.each_key |k| { max_key = num::max(k.len(), max_key); } + for lint_dict.iter().advance |&(_, name)| { + max_key = num::max(name.len(), max_key); + } fn padded(max: uint, s: &str) -> ~str { str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s } @@ -163,17 +171,12 @@ Available lint options: padded(max_key, "name"), "default", "meaning")); io::println(fmt!(" %s %7.7s %s\n", padded(max_key, "----"), "-------", "-------")); - for lint_dict.iter().advance |(k, v)| { - let k = k.replace("_", "-"); + for lint_dict.consume_iter().advance |(spec, name)| { + let name = name.replace("_", "-"); io::println(fmt!(" %s %7.7s %s", - padded(max_key, k), - match v.default { - lint::allow => ~"allow", - lint::warn => ~"warn", - lint::deny => ~"deny", - lint::forbid => ~"forbid" - }, - v.desc)); + padded(max_key, name), + lint::level_to_str(spec.default), + spec.desc)); } io::println(""); } From 3e572511af26f5b469cbfded83069ca215c74740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 11 Jul 2013 19:31:38 +0200 Subject: [PATCH 10/11] Remove duplicated code from trans_intrinsics Most arms of the huge match contain the same code, differing only in small details like the name of the llvm intrinsic that is to be called. Thus the duplicated code can be factored out into a few functions that take some parameters to handle the differences. --- src/librustc/middle/trans/foreign.rs | 428 +++++++-------------------- 1 file changed, 109 insertions(+), 319 deletions(-) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index edf003e3e529e..6a38c41da0d62 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -550,6 +550,64 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ref_id: Option) { debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); + fn simple_llvm_intrinsic(bcx: block, name: &'static str, num_args: uint) { + assert!(num_args <= 4); + let mut args = [0 as ValueRef, ..4]; + let first_real_arg = bcx.fcx.arg_pos(0u); + for uint::range(0, num_args) |i| { + args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); + } + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Store(bcx, Call(bcx, llfn, args.slice(0, num_args)), bcx.fcx.llretptr.get()); + } + + fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); + } + + fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + } + + fn count_zeros_intrinsic(bcx: block, name: &'static str) { + let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); + let y = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Store(bcx, Call(bcx, llfn, [x, y]), bcx.fcx.llretptr.get()) + } + let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); let fcx = new_fn_ctxt_w_id(ccx, @@ -800,325 +858,57 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); Store(bcx, morestack_addr, fcx.llretptr.get()); } - "memcpy32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memcpy64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memset32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "memset64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "sqrtf32" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f32"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "sqrtf64" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f64"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "powif32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f32"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "powif64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f64"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "sinf32" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f32"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "sinf64" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f64"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "cosf32" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f32"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "cosf64" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f64"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "powf32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f32"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "powf64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f64"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "expf32" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f32"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "expf64" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f64"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "exp2f32" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f32"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "exp2f64" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f64"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "logf32" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f32"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "logf64" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f64"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "log10f32" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f32"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log10f64" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f64"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log2f32" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f32"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "log2f64" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f64"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "fmaf32" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f32"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fmaf64" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f64"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fabsf32" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f32"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "fabsf64" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f64"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "floorf32" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f32"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "floorf64" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f64"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "ceilf32" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f32"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "ceilf64" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f64"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "truncf32" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f32"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "truncf64" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f64"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "ctpop8" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i8"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop16" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i16"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop32" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i32"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop64" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i64"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctlz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i8"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i16"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i32"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i64"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "cttz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i8"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i16"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i32"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i64"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "bswap16" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i16"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap32" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i32"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap64" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i64"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } + "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), + "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), + "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), + "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64), + "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32), + "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64), + "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1), + "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1), + "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2), + "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2), + "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1), + "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1), + "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1), + "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1), + "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2), + "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2), + "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1), + "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1), + "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1), + "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1), + "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1), + "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1), + "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1), + "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1), + "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1), + "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1), + "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3), + "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3), + "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1), + "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1), + "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1), + "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1), + "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1), + "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1), + "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1), + "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1), + "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1), + "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1), + "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1), + "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1), + "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"), + "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"), + "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"), + "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"), + "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"), + "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"), + "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"), + "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"), + "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1), + "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1), + "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1), _ => { // Could we make this an enum rather than a string? does it get // checked earlier? From 15ea4a8dd8242a0ee01169872bc538c974e748c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 16 Jul 2013 19:25:06 +0200 Subject: [PATCH 11/11] Generate better code for intrinsics Currently, our intrinsics are generated as functions that have the usual setup, which means an alloca, and therefore also a jump, for those intrinsics that return an immediate value. This is especially bad for unoptimized builds because it means that an intrinsic like "contains_managed" that should be just "ret 0" or "ret 1" actually ends up allocating stack space, doing a jump and a store/load sequence before it finally returns the value. To fix that, we need a way to stop the generic function declaration mechanism from allocating stack space for the return value. This implicitly also kills the jump, because the block for static allocas isn't required anymore. Additionally, trans_intrinsic needs to build the return itself instead of calling finish_fn, because the latter relies on the availability of the return value pointer. With these changes, we get the bare minimum code required for our intrinsics, which makes them small enough that inlining them makes the resulting code smaller, so we can mark them as "always inline" to get better performing unoptimized builds. Optimized builds also benefit slightly from this change as there's less code for LLVM to translate and the smaller intrinsics help it to make better inlining decisions for a few code paths. Building stage2 librustc gets ~1% faster for the optimized version and 5% for the unoptimized version. --- src/librustc/middle/trans/base.rs | 7 ++- src/librustc/middle/trans/foreign.rs | 86 ++++++++++++++++++---------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d7c0490751332..b2d14dce4d854 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1610,6 +1610,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, llfndecl: ValueRef, id: ast::node_id, output_type: ty::t, + skip_retptr: bool, param_substs: Option<@param_substs>, sp: Option) -> fn_ctxt { @@ -1653,7 +1654,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, fcx.llenv = unsafe { llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) }; - if !ty::type_is_nil(substd_output_type) { + if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) { fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type)); } fcx @@ -1665,7 +1666,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext, output_type: ty::t, sp: Option) -> fn_ctxt { - new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp) + new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp) } // NB: must keep 4 fns in sync: @@ -1859,6 +1860,7 @@ pub fn trans_closure(ccx: @mut CrateContext, llfndecl, id, output_type, + false, param_substs, Some(body.span)); let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); @@ -2068,6 +2070,7 @@ pub fn trans_enum_variant_or_tuple_like_struct( llfndecl, ctor_id, result_ty, + false, param_substs, None); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 6a38c41da0d62..d9de1657da273 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -10,7 +10,7 @@ use back::{link, abi}; -use lib::llvm::{ValueRef}; +use lib::llvm::{Pointer, ValueRef}; use lib; use middle::trans::base::*; use middle::trans::cabi; @@ -558,7 +558,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); } let llfn = bcx.ccx().intrinsics.get_copy(&name); - Store(bcx, Call(bcx, llfn, args.slice(0, num_args)), bcx.fcx.llretptr.get()); + Ret(bcx, Call(bcx, llfn, args.slice(0, num_args))); } fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { @@ -579,6 +579,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(&name); Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); } fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { @@ -599,13 +600,14 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(&name); Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); } fn count_zeros_intrinsic(bcx: block, name: &'static str) { let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); let y = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(&name); - Store(bcx, Call(bcx, llfn, [x, y]), bcx.fcx.llretptr.get()) + Ret(bcx, Call(bcx, llfn, [x, y])); } let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); @@ -615,16 +617,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, decl, item.id, output_type, + true, Some(substs), Some(item.span)); + set_always_inline(fcx.llfn); + // Set the fixed stack segment flag if necessary. if attr::attrs_contains_name(attributes, "fixed_stack_segment") { set_fixed_stack_segment(fcx.llfn); } let mut bcx = top_scope_block(fcx, None); - let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); let nm = ccx.sess.str_of(item.ident); @@ -653,17 +657,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg + 2u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "load" => { let old = AtomicLoad(bcx, get_param(decl, first_real_arg), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "store" => { AtomicStore(bcx, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg), order); + RetVoid(bcx); } op => { // These are all AtomicRMW ops @@ -685,12 +690,10 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } } - finish_fn(fcx, lltop, bcx); - return; } @@ -698,8 +701,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty))); } "move_val" => { // Create a datum reflecting the value being moved. @@ -713,6 +715,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, get_param(decl, first_real_arg)); + RetVoid(bcx); } "move_val_init" => { // See comments for `"move_val"`. @@ -721,18 +724,17 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); + RetVoid(bcx); } "min_align_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty))); } "pref_align_of"=> { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))); } "get_tydesc" => { let tp_ty = substs.tys[0]; @@ -745,19 +747,31 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // the llvm type of intrinsic::TyDesc struct. let userland_tydesc_ty = type_of::type_of(ccx, output_type); let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty); - Store(bcx, td, fcx.llretptr.get()); + Ret(bcx, td); } "init" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - if !ty::type_is_nil(tp_ty) { - Store(bcx, C_null(lltp_ty), fcx.llretptr.get()); + match bcx.fcx.llretptr { + Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); } + None if ty::type_is_nil(tp_ty) => RetVoid(bcx), + None => Ret(bcx, C_null(lltp_ty)), } } "uninit" => { // Do nothing, this is effectively a no-op + let retty = substs.tys[0]; + if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) { + unsafe { + Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref())); + } + } else { + RetVoid(bcx) + } + } + "forget" => { + RetVoid(bcx); } - "forget" => {} "transmute" => { let (in_type, out_type) = (substs.tys[0], substs.tys[1]); let llintype = type_of::type_of(ccx, in_type); @@ -784,34 +798,45 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } if !ty::type_is_nil(out_type) { - let lldestptr = fcx.llretptr.get(); let llsrcval = get_param(decl, first_real_arg); if ty::type_is_immediate(ccx.tcx, in_type) { - let lldestptr = PointerCast(bcx, lldestptr, llintype.ptr_to()); - Store(bcx, llsrcval, lldestptr); + match fcx.llretptr { + Some(llretptr) => { + Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to())); + RetVoid(bcx); + } + None => match (llintype.kind(), llouttype.kind()) { + (Pointer, other) | (other, Pointer) if other != Pointer => { + let tmp = Alloca(bcx, llouttype, ""); + Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to())); + Ret(bcx, Load(bcx, tmp)); + } + _ => Ret(bcx, BitCast(bcx, llsrcval, llouttype)) + } + } } else { // NB: Do not use a Load and Store here. This causes massive // code bloat when `transmute` is used on large structural // types. + let lldestptr = fcx.llretptr.get(); let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p()); let llsize = llsize_of(ccx, llintype); call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); + RetVoid(bcx); }; + } else { + RetVoid(bcx); } } "needs_drop" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty))); } "contains_managed" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed())); } "visit_tydesc" => { let td = get_param(decl, first_real_arg); @@ -821,6 +846,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to()); glue::call_tydesc_glue_full(bcx, visitor, td, abi::tydesc_field_visit_glue, None); + RetVoid(bcx); } "frame_address" => { let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress"); @@ -847,6 +873,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, bcx, None, fty, ty::mk_nil(), |bcx| Callee {bcx: bcx, data: Closure(datum)}, ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx; + RetVoid(bcx); } "morestack_addr" => { // XXX This is a hack to grab the address of this particular @@ -856,7 +883,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); - Store(bcx, morestack_addr, fcx.llretptr.get()); + Ret(bcx, morestack_addr); } "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), @@ -915,7 +942,6 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ccx.sess.span_bug(item.span, "unknown intrinsic"); } } - finish_fn(fcx, lltop, bcx); } /**