use core::kinds::Sized;
use core::mem::size_of;
use core::mem;
-use core::ops::FnMut;
+use core::ops::{FnMut,SliceMut};
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
-use core::prelude::{Ord, Ordering, RawPtr, Some, range};
+use core::prelude::{Ord, Ordering, PtrExt, Some, range};
use core::ptr;
use core::slice as core_slice;
use self::Direction::*;
#[inline]
fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
- for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) {
+ for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) {
mem::swap(a, b);
}
cmp::min(self.len(), end-start)
#[unstable = "trait is unstable"]
impl<T> BorrowFromMut<Vec<T>> for [T] {
- fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned[mut] }
+ fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned.as_mut_slice_() }
}
#[unstable = "trait is unstable"]
#[cfg(test)]
mod tests {
use std::boxed::Box;
- use prelude::*;
+ use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal};
+ use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt};
+ use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice};
+ use prelude::{RandomAccessIterator, Ord, VectorVector};
use core::cell::Cell;
use core::default::Default;
use core::mem;
- use std::rand::{Rng, task_rng};
+ use std::rand::{Rng, thread_rng};
use std::rc::Rc;
use super::ElementSwaps;
fn test_sort() {
for len in range(4u, 25) {
for _ in range(0i, 100) {
- let mut v = task_rng().gen_iter::<uint>().take(len)
+ let mut v = thread_rng().gen_iter::<uint>().take(len)
.collect::<Vec<uint>>();
let mut v1 = v.clone();
// number this element is, i.e. the second elements
// will occur in sorted order.
let mut v = range(0, len).map(|_| {
- let n = task_rng().gen::<uint>() % 10;
+ let n = thread_rng().gen::<uint>() % 10;
counts[n] += 1;
(n, counts[n])
}).collect::<Vec<(uint, int)>>();
assert!(a == [7i,2,3,4]);
let mut a = [1i,2,3,4,5];
let b = vec![5i,6,7,8,9,0];
- assert_eq!(a[mut 2..4].move_from(b,1,6), 2);
+ assert_eq!(a.slice_mut(2, 4).move_from(b,1,6), 2);
assert!(a == [1i,2,6,7,5]);
}
#[test]
fn test_reverse_part() {
let mut values = [1i,2,3,4,5];
- values[mut 1..4].reverse();
+ values.slice_mut(1, 4).reverse();
assert!(values == [1,4,3,2,5]);
}
fn test_bytes_set_memory() {
use slice::bytes::MutableByteVector;
let mut values = [1u8,2,3,4,5];
- values[mut 0..5].set_memory(0xAB);
+ values.slice_mut(0, 5).set_memory(0xAB);
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
- values[mut 2..4].set_memory(0xFF);
+ values.slice_mut(2, 4).set_memory(0xFF);
assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
}
pub use core::str::{from_utf8, CharEq, Chars, CharIndices};
pub use core::str::{Bytes, CharSplits, is_utf8};
-pub use core::str::{CharSplitsN, Lines, LinesAny, MatchIndices, StrSplits};
+pub use core::str::{CharSplitsN, Lines, LinesAny, MatchIndices, StrSplits, SplitStr};
pub use core::str::{CharRange};
pub use core::str::{FromStr, from_str, Utf8Error};
pub use core::str::Str;
pub use core::str::{from_utf8_unchecked, from_c_str};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
+pub use core::str::{Split, SplitTerminator};
+pub use core::str::{SplitN, RSplitN};
// FIXME(conventions): ensure bit/char conventions are followed by str's API
/// // not found, so no change.
/// assert_eq!(s.replace("cookie monster", "little lamb"), s);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
+ #[stable]
fn replace(&self, from: &str, to: &str) -> String {
let mut result = String::new();
let mut last_end = 0;
}
}
- /// Returns true if one string contains another
+ /// Returns true if a string contains a string pattern.
///
/// # Arguments
///
- /// - needle - The string to look for
+ /// - pat - The string pattern to look for
///
/// # Example
///
/// ```rust
/// assert!("bananas".contains("nana"));
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn contains(&self, needle: &str) -> bool {
- core_str::StrExt::contains(self[], needle)
+ #[stable]
+ fn contains(&self, pat: &str) -> bool {
+ core_str::StrExt::contains(self[], pat)
}
- /// Returns true if a string contains a char.
+ /// Returns true if a string contains a char pattern.
///
/// # Arguments
///
- /// - needle - The char to look for
+ /// - pat - The char pattern to look for
///
/// # Example
///
/// ```rust
/// assert!("hello".contains_char('e'));
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn contains_char(&self, needle: char) -> bool {
- core_str::StrExt::contains_char(self[], needle)
+ #[unstable = "might get removed in favour of a more generic contains()"]
+ fn contains_char<P: CharEq>(&self, pat: P) -> bool {
+ core_str::StrExt::contains_char(self[], pat)
}
/// An iterator over the characters of `self`. Note, this iterates
}
/// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`.
+ /// matched by the pattern `pat`.
///
/// # Example
///
/// let v: Vec<&str> = "".split('X').collect();
/// assert_eq!(v, vec![""]);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> {
- core_str::StrExt::split(self[], sep)
+ #[stable]
+ fn split<P: CharEq>(&self, pat: P) -> Split<P> {
+ core_str::StrExt::split(self[], pat)
}
/// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`, restricted to splitting at most `count`
+ /// matched by the pattern `pat`, restricted to splitting at most `count`
/// times.
///
/// # Example
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
/// assert_eq!(v, vec![""]);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<Sep> {
- core_str::StrExt::splitn(self[], count, sep)
+ #[stable]
+ fn splitn<P: CharEq>(&self, count: uint, pat: P) -> SplitN<P> {
+ core_str::StrExt::splitn(self[], count, pat)
}
/// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`.
+ /// matched by the pattern `pat`.
///
/// Equivalent to `split`, except that the trailing substring
/// is skipped if empty (terminator semantics).
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
/// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> {
- core_str::StrExt::split_terminator(self[], sep)
+ #[unstable = "might get removed"]
+ fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
+ core_str::StrExt::split_terminator(self[], pat)
}
/// An iterator over substrings of `self`, separated by characters
- /// matched by `sep`, starting from the end of the string.
+ /// matched by the pattern `pat`, starting from the end of the string.
/// Restricted to splitting at most `count` times.
///
/// # Example
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
/// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<Sep> {
- core_str::StrExt::rsplitn(self[], count, sep)
+ #[stable]
+ fn rsplitn<P: CharEq>(&self, count: uint, pat: P) -> RSplitN<P> {
+ core_str::StrExt::rsplitn(self[], count, pat)
}
/// An iterator over the start and end indices of the disjoint
- /// matches of `sep` within `self`.
+ /// matches of the pattern `pat` within `self`.
///
/// That is, each returned value `(start, end)` satisfies
/// `self.slice(start, end) == sep`. For matches of `sep` within
/// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect();
/// assert_eq!(v, vec![(0, 3)]); // only the first `aba`
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> {
- core_str::StrExt::match_indices(self[], sep)
+ #[unstable = "might have its iterator type changed"]
+ fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> {
+ core_str::StrExt::match_indices(self[], pat)
}
- /// An iterator over the substrings of `self` separated by `sep`.
+ /// An iterator over the substrings of `self` separated by the pattern `sep`.
///
/// # Example
///
/// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
/// assert_eq!(v, vec!["1", "", "2"]);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn split_str<'a>(&'a self, s: &'a str) -> StrSplits<'a> {
- core_str::StrExt::split_str(self[], s)
+ #[unstable = "might get removed in the future in favor of a more generic split()"]
+ fn split_str<'a>(&'a self, pat: &'a str) -> StrSplits<'a> {
+ core_str::StrExt::split_str(self[], pat)
}
/// An iterator over the lines of a string (subsequences separated
core_str::StrExt::slice_unchecked(self[], begin, end)
}
- /// Returns true if `needle` is a prefix of the string.
+ /// Returns true if the pattern `pat` is a prefix of the string.
///
/// # Example
///
/// ```rust
/// assert!("banana".starts_with("ba"));
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn starts_with(&self, needle: &str) -> bool {
- core_str::StrExt::starts_with(self[], needle)
+ #[stable]
+ fn starts_with(&self, pat: &str) -> bool {
+ core_str::StrExt::starts_with(self[], pat)
}
- /// Returns true if `needle` is a suffix of the string.
+ /// Returns true if the pattern `pat` is a suffix of the string.
///
/// # Example
///
/// ```rust
/// assert!("banana".ends_with("nana"));
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn ends_with(&self, needle: &str) -> bool {
- core_str::StrExt::ends_with(self[], needle)
+ #[stable]
+ fn ends_with(&self, pat: &str) -> bool {
+ core_str::StrExt::ends_with(self[], pat)
}
- /// Returns a string with characters that match `to_trim` removed from the left and the right.
+ /// Returns a string with all pre- and suffixes that match
+ /// the pattern `pat` repeatedly removed.
///
/// # Arguments
///
- /// * to_trim - a character matcher
+ /// * pat - a string pattern
///
/// # Example
///
/// ```rust
- /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
+ /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
/// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar");
- /// assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar");
+ /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
+ /// assert_eq!("123foo1bar123".trim_matches(|&: c: char| c.is_numeric()), "foo1bar");
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn trim_chars<C: CharEq>(&self, to_trim: C) -> &str {
- core_str::StrExt::trim_chars(self[], to_trim)
+ #[stable]
+ fn trim_matches<P: CharEq>(&self, pat: P) -> &str {
+ core_str::StrExt::trim_matches(self[], pat)
+ }
+
+ /// Deprecated
+ #[deprecated = "Replaced by `trim_matches`"]
+ fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
+ self.trim_matches(to_trim)
}
- /// Returns a string with leading `chars_to_trim` removed.
+ /// Returns a string with all prefixes that match
+ /// the pattern `pat` repeatedly removed.
///
/// # Arguments
///
- /// * to_trim - a character matcher
+ /// * pat - a string pattern
///
/// # Example
///
/// ```rust
- /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
+ /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
/// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12");
- /// assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123");
+ /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
+ /// assert_eq!("123foo1bar123".trim_left_matches(|&: c: char| c.is_numeric()), "foo1bar123");
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &str {
- core_str::StrExt::trim_left_chars(self[], to_trim)
+ #[stable]
+ fn trim_left_matches<P: CharEq>(&self, pat: P) -> &str {
+ core_str::StrExt::trim_left_matches(self[], pat)
+ }
+
+ /// Deprecated
+ #[deprecated = "Replaced by `trim_left_matches`"]
+ fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
+ self.trim_left_matches(to_trim)
}
- /// Returns a string with trailing `chars_to_trim` removed.
+ /// Returns a string with all suffixes that match
+ /// the pattern `pat` repeatedly removed.
///
/// # Arguments
///
- /// * to_trim - a character matcher
+ /// * pat - a string pattern
///
/// # Example
///
/// ```rust
- /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
+ /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
/// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar");
- /// assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar");
+ /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
+ /// assert_eq!("123foo1bar123".trim_right_matches(|&: c: char| c.is_numeric()), "123foo1bar");
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &str {
- core_str::StrExt::trim_right_chars(self[], to_trim)
+ #[stable]
+ fn trim_right_matches<P: CharEq>(&self, pat: P) -> &str {
+ core_str::StrExt::trim_right_matches(self[], pat)
+ }
+
+ /// Deprecated
+ #[deprecated = "Replaced by `trim_right_matches`"]
+ fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
+ self.trim_right_matches(to_trim)
}
/// Check that `index`-th byte lies at the start and/or end of a
}
/// Returns the byte index of the first character of `self` that
- /// matches `search`.
+ /// matches the pattern `pat`.
///
/// # Return value
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!(s.find(x), None);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn find<C: CharEq>(&self, search: C) -> Option<uint> {
- core_str::StrExt::find(self[], search)
+ #[stable]
+ fn find<P: CharEq>(&self, pat: P) -> Option<uint> {
+ core_str::StrExt::find(self[], pat)
}
/// Returns the byte index of the last character of `self` that
- /// matches `search`.
+ /// matches the pattern `pat`.
///
/// # Return value
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!(s.rfind(x), None);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
- fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
- core_str::StrExt::rfind(self[], search)
+ #[stable]
+ fn rfind<P: CharEq>(&self, pat: P) -> Option<uint> {
+ core_str::StrExt::rfind(self[], pat)
}
/// Returns the byte index of the first matching substring
/// assert_eq!(s.find_str("老虎 L"), Some(6));
/// assert_eq!(s.find_str("muffin man"), None);
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
+ #[unstable = "might get removed in favor of a more generic find in the future"]
fn find_str(&self, needle: &str) -> Option<uint> {
core_str::StrExt::find_str(self[], needle)
}
/// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
/// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
/// ```
- #[unstable = "awaiting pattern/matcher stabilization"]
+ #[unstable = "awaiting convention about comparability of arbitrary slices"]
fn subslice_offset(&self, inner: &str) -> uint {
core_str::StrExt::subslice_offset(self[], inner)
}
#[cfg(test)]
mod tests {
- use std::iter::AdditiveIterator;
- use std::iter::range;
- use std::default::Default;
- use std::char::Char;
- use std::clone::Clone;
- use std::cmp::{Ord, PartialOrd, Equiv};
- use std::cmp::Ordering::{Equal, Greater, Less};
- use std::option::Option::{mod, Some, None};
- use std::result::Result::{Ok, Err};
- use std::ptr::RawPtr;
- use std::iter::{Iterator, IteratorExt, DoubleEndedIteratorExt};
-
- use super::*;
+ use prelude::*;
+
+ use core::default::Default;
+ use core::iter::AdditiveIterator;
+ use super::{eq_slice, from_utf8, is_utf8, is_utf16, raw};
+ use super::truncate_utf16_at_nul;
use super::MaybeOwned::{Owned, Slice};
use std::slice::{AsSlice, SliceExt};
use string::{String, ToString};
#[cfg(test)]
mod bench {
use super::*;
- use prelude::*;
+ use prelude::{SliceExt, IteratorExt, DoubleEndedIteratorExt};
use test::Bencher;
use test::black_box;
#[deriving(Show,PartialEq,Clone,Copy)]
enum Shadowable {
Always,
- /// Means that the recorded import obeys the glob shadowing rules, i.e., can
- /// only be shadowed by another glob import.
- Glob,
Never
}
target.unwrap().shadowable
}
+
+ fn set_target_and_id(&mut self,
+ namespace: Namespace,
+ target: Option<Target>,
+ id: NodeId) {
+ match namespace {
+ TypeNS => {
+ self.type_target = target;
+ self.type_id = id;
+ }
+ ValueNS => {
+ self.value_target = target;
+ self.value_id = id;
+ }
+ }
+ }
}
/// The link from a module up to its nearest parent node.
ItemImpl(_, _, Some(_), _, _) => parent,
- ItemTrait(_, _, _, _, ref items) => {
+ ItemTrait(_, _, _, ref items) => {
let name_bindings =
self.add_child(name,
parent.clone(),
view_path.span,
id,
is_public,
- if shadowable == Shadowable::Never {
- Shadowable::Glob
- } else {
- shadowable
- });
+ shadowable);
}
}
}
// We've successfully resolved the import. Write the results in.
let mut import_resolutions = module_.import_resolutions.borrow_mut();
let import_resolution = &mut (*import_resolutions)[target];
+ {
+ let check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
+ let namespace_name = match namespace {
+ TypeNS => "type",
+ ValueNS => "value",
+ };
- match value_result {
- BoundResult(ref target_module, ref name_bindings) => {
- debug!("(resolving single import) found value target: {}",
- { name_bindings.value_def.borrow().clone().unwrap().def });
- self.check_for_conflicting_import(
- &import_resolution.value_target,
- directive.span,
- target,
- ValueNS);
-
- self.check_that_import_is_importable(
- &**name_bindings,
- directive.span,
- target,
- ValueNS);
-
- import_resolution.value_target =
- Some(Target::new(target_module.clone(),
- name_bindings.clone(),
- directive.shadowable));
- import_resolution.value_id = directive.id;
- import_resolution.is_public = directive.is_public;
- value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
- }
- UnboundResult => { /* Continue. */ }
- UnknownResult => {
- panic!("value result should be known at this point");
- }
- }
- match type_result {
- BoundResult(ref target_module, ref name_bindings) => {
- debug!("(resolving single import) found type target: {}",
- { name_bindings.type_def.borrow().clone().unwrap().type_def });
- self.check_for_conflicting_import(
- &import_resolution.type_target,
- directive.span,
- target,
- TypeNS);
-
- self.check_that_import_is_importable(
- &**name_bindings,
- directive.span,
- target,
- TypeNS);
-
- import_resolution.type_target =
- Some(Target::new(target_module.clone(),
- name_bindings.clone(),
- directive.shadowable));
- import_resolution.type_id = directive.id;
- import_resolution.is_public = directive.is_public;
- type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
- }
- UnboundResult => { /* Continue. */ }
- UnknownResult => {
- panic!("type result should be known at this point");
- }
+ match *result {
+ BoundResult(ref target_module, ref name_bindings) => {
+ debug!("(resolving single import) found {} target: {}",
+ namespace_name,
+ name_bindings.def_for_namespace(namespace));
+ self.check_for_conflicting_import(
+ &import_resolution.target_for_namespace(namespace),
+ directive.span,
+ target,
+ namespace);
+
+ self.check_that_import_is_importable(
+ &**name_bindings,
+ directive.span,
+ target,
+ namespace);
+
+ let target = Some(Target::new(target_module.clone(),
+ name_bindings.clone(),
+ directive.shadowable));
+ import_resolution.set_target_and_id(namespace, target, directive.id);
+ import_resolution.is_public = directive.is_public;
+ *used_public = name_bindings.defined_in_public_namespace(namespace);
+ }
+ UnboundResult => { /* Continue. */ }
+ UnknownResult => {
+ panic!("{} result should be known at this point", namespace_name);
+ }
+ }
+ };
+ check_and_write_import(ValueNS, &value_result, &mut value_used_public);
+ check_and_write_import(TypeNS, &type_result, &mut type_used_public);
}
self.check_for_conflicts_between_imports_and_items(
// Resolves a glob import. Note that this function cannot fail; it either
// succeeds or bails out (as importing * from an empty module or a module
- // that exports nothing is valid).
+ // that exports nothing is valid). containing_module is the module we are
+ // actually importing, i.e., `foo` in `use foo::*`.
fn resolve_glob_import(&mut self,
module_: &Module,
containing_module: Rc<Module>,
assert_eq!(containing_module.glob_count.get(), 0);
// Add all resolved imports from the containing module.
- let import_resolutions = containing_module.import_resolutions
- .borrow();
+ let import_resolutions = containing_module.import_resolutions.borrow();
for (ident, target_import_resolution) in import_resolutions.iter() {
debug!("(resolving glob import) writing module resolution \
{} into `{}`",
- target_import_resolution.type_target.is_none(),
+ token::get_name(*ident),
self.module_to_string(module_));
if !target_import_resolution.is_public {
// Continue.
}
Some(ref value_target) => {
- dest_import_resolution.value_target =
- Some(value_target.clone());
+ self.check_for_conflicting_import(&dest_import_resolution.value_target,
+ import_directive.span,
+ *ident,
+ ValueNS);
+ dest_import_resolution.value_target = Some(value_target.clone());
}
}
match target_import_resolution.type_target {
// Continue.
}
Some(ref type_target) => {
- dest_import_resolution.type_target =
- Some(type_target.clone());
+ self.check_for_conflicting_import(&dest_import_resolution.type_target,
+ import_directive.span,
+ *ident,
+ TypeNS);
+ dest_import_resolution.type_target = Some(type_target.clone());
}
}
dest_import_resolution.is_public = is_public;
// Add all children from the containing module.
self.populate_module_if_necessary(&containing_module);
- for (&name, name_bindings) in containing_module.children
- .borrow().iter() {
+ for (&name, name_bindings) in containing_module.children.borrow().iter() {
self.merge_import_resolution(module_,
containing_module.clone(),
import_directive,
}
// Add external module children from the containing module.
- for (&name, module) in containing_module.external_module_children
- .borrow().iter() {
+ for (&name, module) in containing_module.external_module_children.borrow().iter() {
let name_bindings =
Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
self.merge_import_resolution(module_,
debug!("(resolving glob import) writing resolution `{}` in `{}` \
to `{}`",
- token::get_name(name).get().to_string(),
+ token::get_name(name).get(),
self.module_to_string(&*containing_module),
self.module_to_string(module_));
// Merge the child item into the import resolution.
- if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
- debug!("(resolving glob import) ... for value target");
- if dest_import_resolution.shadowable(ValueNS) == Shadowable::Never {
- let msg = format!("a value named `{}` has already been imported \
- in this module",
- token::get_name(name).get());
- self.session.span_err(import_directive.span, msg.as_slice());
- } else {
- dest_import_resolution.value_target =
- Some(Target::new(containing_module.clone(),
- name_bindings.clone(),
- import_directive.shadowable));
- dest_import_resolution.value_id = id;
- }
- }
- if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
- debug!("(resolving glob import) ... for type target");
- if dest_import_resolution.shadowable(TypeNS) == Shadowable::Never {
- let msg = format!("a type named `{}` has already been imported \
- in this module",
- token::get_name(name).get());
- self.session.span_err(import_directive.span, msg.as_slice());
- } else {
- dest_import_resolution.type_target =
- Some(Target::new(containing_module,
- name_bindings.clone(),
- import_directive.shadowable));
- dest_import_resolution.type_id = id;
- }
+ {
+ let merge_child_item = |namespace| {
+ if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
+ let namespace_name = match namespace {
+ TypeNS => "type",
+ ValueNS => "value",
+ };
+ debug!("(resolving glob import) ... for {} target", namespace_name);
+ if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
+ let msg = format!("a {} named `{}` has already been imported \
+ in this module",
+ namespace_name,
+ token::get_name(name).get());
+ self.session.span_err(import_directive.span, msg.as_slice());
+ } else {
+ let target = Target::new(containing_module.clone(),
+ name_bindings.clone(),
+ import_directive.shadowable);
+ dest_import_resolution.set_target_and_id(namespace,
+ Some(target),
+ id);
+ }
+ }
+ };
+ merge_child_item(ValueNS);
+ merge_child_item(TypeNS);
}
+
dest_import_resolution.is_public = is_public;
self.check_for_conflicts_between_imports_and_items(
return
}
+ debug!("check_for_conflicting_import: {}; target exists: {}",
+ token::get_name(name).get(),
+ target.is_some());
+
match *target {
Some(ref target) if target.shadowable != Shadowable::Always => {
let msg = format!("a {} named `{}` has already been imported \
}
}
+ /// Searches the current set of local scopes and
+ /// applies translations for closures.
fn search_ribs(&self,
ribs: &[Rib],
name: Name,
None
}
+ /// Searches the current set of local scopes for labels.
+ /// Stops after meeting a closure.
+ fn search_label(&self, name: Name) -> Option<DefLike> {
+ for rib in self.label_ribs.iter().rev() {
+ match rib.kind {
+ NormalRibKind => {
+ // Continue
+ }
+ _ => {
+ // Do not resolve labels across function boundary
+ return None
+ }
+ }
+ let result = rib.bindings.get(&name).cloned();
+ if result.is_some() {
+ return result
+ }
+ }
+ None
+ }
+
fn resolve_crate(&mut self, krate: &ast::Crate) {
debug!("(resolving crate) starting");
impl_items[]);
}
- ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
+ ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
// Create a new rib for the self type.
let mut self_type_rib = Rib::new(ItemRibKind);
this.resolve_type_parameter_bounds(item.id, bounds,
TraitDerivation);
- match *unbound {
- Some(ref tpb) => {
- this.resolve_trait_reference(item.id, tpb, TraitDerivation);
- }
- None => {}
- }
-
for trait_item in (*trait_items).iter() {
// Create a new rib for the trait_item-specific type
// parameters.
let def_like = DlDef(DefTyParam(space,
local_def(type_parameter.id),
- index));
+ index as u32));
// Associate this type parameter with
// the item that bound it
self.record_def(type_parameter.id,
self.resolve_type_parameter_bound(type_parameter.id, bound,
TraitBoundingTypeParameter);
}
- match &type_parameter.unbound {
- &Some(ref unbound) =>
- self.resolve_trait_reference(
- type_parameter.id, unbound, TraitBoundingTypeParameter),
- &None => {}
- }
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
None => {}
type_parameter_bound: &TyParamBound,
reference_type: TraitReferenceType) {
match *type_parameter_bound {
- TraitTyParamBound(ref tref) => {
+ TraitTyParamBound(ref tref, _) => {
self.resolve_poly_trait_reference(id, tref, reference_type)
}
RegionTyParamBound(..) => {}
ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
let renamed = mtwt::resolve(label);
- match self.search_ribs(self.label_ribs[],
- renamed, expr.span) {
+ match self.search_label(renamed) {
None => {
self.resolve_error(
expr.span,
let unboxed_closure = &(*unboxed_closures)[closure_id];
match unboxed_closure.kind {
ty::FnUnboxedClosureKind => {
- ty::mk_imm_rptr(ccx.tcx(), ty::ReStatic, fn_ty)
+ ty::mk_imm_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
}
ty::FnMutUnboxedClosureKind => {
- ty::mk_mut_rptr(ccx.tcx(), ty::ReStatic, fn_ty)
+ ty::mk_mut_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
}
ty::FnOnceUnboxedClosureKind => fn_ty
}
ty::ty_closure(ref f) => {
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, Some(Type::i8p(ccx)))
}
- ty::ty_unboxed_closure(closure_did, _, ref substs) => {
+ ty::ty_unboxed_closure(closure_did, _, substs) => {
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
let unboxed_closure = &(*unboxed_closures)[closure_did];
let function_type = unboxed_closure.closure_type.clone();
assert_eq!(did.krate, ast::LOCAL_CRATE);
// Since we're in trans we don't care for any region parameters
- let ref substs = subst::Substs::erased(substs.types.clone());
+ let substs = subst::Substs::erased(substs.types.clone());
- let (val, _) = monomorphize::monomorphic_fn(ccx, did, substs, None);
+ let (val, _) = monomorphize::monomorphic_fn(ccx, did, &substs, None);
val
} else if did.krate == ast::LOCAL_CRATE {
}
})
}
- ty::ty_unboxed_closure(def_id, _, ref substs) => {
+ ty::ty_unboxed_closure(def_id, _, substs) => {
let repr = adt::represent_type(cx.ccx(), t);
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs);
for (i, upvar) in upvars.iter().enumerate() {
cx = f(cx, llfld_a, *arg);
}
}
- ty::ty_enum(tid, ref substs) => {
+ ty::ty_enum(tid, substs) => {
let fcx = cx.fcx;
let ccx = fcx.ccx;
llfn: ValueRef,
llargs: &[ValueRef],
fn_ty: Ty<'tcx>,
- call_info: Option<NodeInfo>,
- // FIXME(15064) is_lang_item is a horrible hack, please remove it
- // at the soonest opportunity.
- is_lang_item: bool)
+ call_info: Option<NodeInfo>)
-> (ValueRef, Block<'blk, 'tcx>) {
let _icx = push_ctxt("invoke_");
if bcx.unreachable.get() {
return (C_null(Type::i8(bcx.ccx())), bcx);
}
- // FIXME(15064) Lang item methods may (in the reflect case) not have proper
- // types, so doing an attribute lookup will fail.
- let attributes = if is_lang_item {
- llvm::AttrBuilder::new()
- } else {
- get_fn_llvm_attributes(bcx.ccx(), fn_ty)
- };
+ let attributes = get_fn_llvm_attributes(bcx.ccx(), fn_ty);
match bcx.opt_node_id {
None => {
}
// work around bizarre resolve errors
- pub type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
- pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
+ type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
// create_datums_for_fn_args: creates rvalue datums for each of the
// incoming function arguments. These will later be stored into
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
let mut sizes = Vec::new(); // does no allocation if no pushes, thankfully
+ let print_info = ccx.sess().print_enum_sizes();
+
let levels = ccx.tcx().node_lint_levels.borrow();
let lint_id = lint::LintId::of(lint::builtin::VARIANT_SIZE_DIFFERENCES);
- let lvlsrc = match levels.get(&(id, lint_id)) {
- None | Some(&(lint::Allow, _)) => return,
- Some(&lvlsrc) => lvlsrc,
- };
+ let lvlsrc = levels.get(&(id, lint_id));
+ let is_allow = lvlsrc.map_or(true, |&(lvl, _)| lvl == lint::Allow);
- let avar = adt::represent_type(ccx, ty::node_id_to_type(ccx.tcx(), id));
+ if is_allow && !print_info {
+ // we're not interested in anything here
+ return
+ }
+
+ let ty = ty::node_id_to_type(ccx.tcx(), id);
+ let avar = adt::represent_type(ccx, ty);
match *avar {
adt::General(_, ref variants, _) => {
for var in variants.iter() {
}
);
+ if print_info {
+ let llty = type_of::sizing_type_of(ccx, ty);
+
+ let sess = &ccx.tcx().sess;
+ sess.span_note(sp, &*format!("total size: {} bytes", llsize_of_real(ccx, llty)));
+ match *avar {
+ adt::General(..) => {
+ for (i, var) in enum_def.variants.iter().enumerate() {
+ ccx.tcx().sess.span_note(var.span,
+ &*format!("variant data: {} bytes", sizes[i]));
+ }
+ }
+ _ => {}
+ }
+ }
+
// we only warn if the largest variant is at least thrice as large as
// the second-largest.
- if largest > slargest * 3 && slargest > 0 {
+ if !is_allow && largest > slargest * 3 && slargest > 0 {
// Use lint::raw_emit_lint rather than sess.add_lint because the lint-printing
// pass for the latter already ran.
lint::raw_emit_lint(&ccx.tcx().sess, lint::builtin::VARIANT_SIZE_DIFFERENCES,
- lvlsrc, Some(sp),
+ *lvlsrc.unwrap(), Some(sp),
format!("enum variant is more than three times larger \
({} bytes) than the next largest (ignoring padding)",
largest)[]);
ast::ItemMod(ref m) => {
trans_mod(&ccx.rotate(), m);
}
- ast::ItemEnum(ref enum_definition, _) => {
- enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
+ ast::ItemEnum(ref enum_definition, ref gens) => {
+ if gens.ty_params.is_empty() {
+ // sizes only make sense for non-generic types
+
+ enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
+ }
}
ast::ItemConst(_, ref expr) => {
// Recurse on the expression to catch items in blocks
let (fn_sig, abi, has_env) = match fn_ty.sty {
ty::ty_closure(ref f) => (f.sig.clone(), f.abi, true),
ty::ty_bare_fn(_, ref f) => (f.sig.clone(), f.abi, false),
- ty::ty_unboxed_closure(closure_did, _, ref substs) => {
+ ty::ty_unboxed_closure(closure_did, _, substs) => {
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
let ref function_type = (*unboxed_closures)[closure_did]
.closure_type;
attrs.arg(idx, llvm::ReadOnlyAttribute);
}
- if let ReLateBound(_, BrAnon(_)) = b {
+ if let ReLateBound(_, BrAnon(_)) = *b {
attrs.arg(idx, llvm::NoCaptureAttribute);
}
}
// When a reference in an argument has no named lifetime, it's impossible for that
// reference to escape this function (returned or stored beyond the call by a closure).
- ty::ty_rptr(ReLateBound(_, BrAnon(_)), mt) => {
+ ty::ty_rptr(&ReLateBound(_, BrAnon(_)), mt) => {
let llsz = llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
attrs.arg(idx, llvm::NoCaptureAttribute)
.arg(idx, llvm::DereferenceableAttribute(llsz));
fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ty: Ty<'tcx>) -> bool {
match ty.sty {
- ty::ty_struct(def_id, ref substs) => {
+ ty::ty_struct(def_id, substs) => {
let fields = ty::struct_fields(ccx.tcx(), def_id, substs);
fields.len() == 1 &&
fields[0].name ==
}
// work around bizarre resolve errors
- pub type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
- pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
+ type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
+ type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
// Function context. Every LLVM function we create will have one of
// these.
}
}
+#[allow(dead_code)] // potentially useful
pub fn is_null(val: ValueRef) -> bool {
unsafe {
llvm::LLVMIsNull(val) != False
let write_len = min(buf.len(), self.buf.len() - self.pos);
{
let input = self.buf[self.pos.. self.pos + write_len];
- let output = buf[mut ..write_len];
+ let output = buf.slice_to_mut(write_len);
assert_eq!(input.len(), output.len());
slice::bytes::copy_memory(output, input);
}
let write_len = min(buf.len(), self.len());
{
let input = self[..write_len];
- let output = buf[mut ..write_len];
+ let output = buf.slice_to_mut(write_len);
slice::bytes::copy_memory(output, input);
}
impl<'a> Writer for BufWriter<'a> {
#[inline]
fn write(&mut self, src: &[u8]) -> IoResult<()> {
- let dst = self.buf[mut self.pos..];
+ let dst = self.buf.slice_from_mut(self.pos);
let dst_len = dst.len();
if dst_len == 0 {
let write_len = min(buf.len(), self.buf.len() - self.pos);
{
let input = self.buf[self.pos.. self.pos + write_len];
- let output = buf[mut ..write_len];
+ let output = buf.slice_to_mut(write_len);
assert_eq!(input.len(), output.len());
slice::bytes::copy_memory(output, input);
}
mod test {
extern crate "test" as test_crate;
use super::*;
- use io::*;
- use prelude::*;
+ use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek};
+ use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt, CloneSliceExt};
use io;
use self::test_crate::Bencher;
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
let b: &[_] = &[1, 2, 3];
assert_eq!(buf, b);
- assert!(r.read_at_least(0, buf[mut ..0]).is_ok());
+ assert!(r.read_at_least(0, buf.slice_to_mut(0)).is_ok());
assert_eq!(buf, b);
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
let b: &[_] = &[4, 5, 6];
while read < min {
let mut zeroes = 0;
loop {
- match self.read(buf[mut read..]) {
+ match self.read(buf.slice_from_mut(read)) {
Ok(0) => {
zeroes += 1;
if zeroes >= NO_PROGRESS_LIMIT {
// API yet. If so, it should be a method on Vec.
unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -> &'a mut [T] {
use raw::Slice;
- use ptr::RawPtr;
+ use ptr::PtrExt;
assert!(start <= end);
assert!(end <= v.capacity());
#[inline]
fn write_char(&mut self, c: char) -> IoResult<()> {
let mut buf = [0u8, ..4];
- let n = c.encode_utf8(buf[mut]).unwrap_or(0);
+ let n = c.encode_utf8(buf.as_mut_slice()).unwrap_or(0);
self.write(buf[..n])
}
{
let mut start = 1;
while start < width {
- match try!(self.read(buf[mut start..width])) {
+ match try!(self.read(buf.slice_mut(start, width))) {
n if n == width - start => break,
n if n < width - start => { start += n; }
_ => return Err(standard_error(InvalidInput)),
/// A mode specifies how a file should be opened or created. These modes are
/// passed to `File::open_mode` and are used to control where the file is
/// positioned when it is initially opened.
-#[deriving(Copy)]
+#[deriving(Copy, Clone, PartialEq, Eq)]
pub enum FileMode {
/// Opens a file positioned at the beginning.
Open,
/// Access permissions with which the file should be opened. `File`s
/// opened with `Read` will return an error if written to.
-#[deriving(Copy)]
+#[deriving(Copy, Clone, PartialEq, Eq)]
pub enum FileAccess {
/// Read-only access, requests to write will result in an error
Read,
#[cfg(test)]
mod tests {
use self::BadReaderBehavior::*;
- use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput};
- use prelude::*;
+ use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer};
+ use prelude::{Ok, Vec, Buffer, CloneSliceExt};
use uint;
#[deriving(Clone, PartialEq, Show)]
/// match socket.recv_from(&mut buf) {
/// Ok((amt, src)) => {
/// // Send a reply to the socket we received data from
-/// let buf = buf[mut ..amt];
+/// let buf = buf.slice_to_mut(amt);
/// buf.reverse();
/// socket.send_to(buf, src);
/// }
mod test {
use super::*;
use io::net::ip::*;
- use io::*;
+ use io::{ShortWrite, IoError, TimedOut, PermissionDenied};
use io::test::*;
- use prelude::*;
+ use prelude::{Ok, Err, spawn, range, drop, Some, None, channel, Clone, Reader, Writer};
// FIXME #11530 this fails on android because tests are run as root
#[cfg_attr(any(windows, target_os = "android"), ignore)]
}
let len = cmp::min(self.limit, buf.len());
- let res = self.inner.read(buf[mut ..len]);
+ let res = self.inner.read(buf.slice_to_mut(len));
match res {
Ok(len) => self.limit -= len,
_ => {}
use io;
use boxed::Box;
use super::*;
- use prelude::*;
+ use prelude::{Ok, range, Vec, Buffer, Writer, Reader, ToString, AsSlice};
#[test]
fn test_limit_reader_unlimited() {