diff --git a/.gitmodules b/.gitmodules index 52ece628c573f..c84426161796d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,8 @@ [submodule "src/llvm"] path = src/llvm url = https://github.com/brson/llvm.git + branch = master [submodule "src/libuv"] path = src/libuv url = https://github.com/brson/libuv.git + branch = master diff --git a/RELEASES.txt b/RELEASES.txt index 60169b347ad84..dbee53f8e3058 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -4,6 +4,8 @@ Version 0.7 (July 2013) * ??? changes, numerous bugfixes * Syntax changes + * `impl`s no longer accept a visibility qualifier. Put them on methods + instead. * `use mod` is no longer valid. * `fail!` and `assert!` accept `~str`, `&'static str` or `fmt!`-style argument list. @@ -25,6 +27,10 @@ Version 0.7 (July 2013) no padding between fields. * The `for` loop protocol now requires `for`-iterators to return `bool` so they compose better. + * Trait default methods work more often. + * Type parameters bound by `Copy` must now be copied explicitly with + the `copy` keyword. + * It is now illegal to move out of a dereferenced unsafe pointer. * `Option<~T>` is now represented as a nullable pointer. * `@mut` does dynamic borrow checks correctly. * Macros TODO @@ -43,26 +49,30 @@ Version 0.7 (July 2013) * Libraries * The `core` crate was renamed to `std`. * The `std` crate was renamed to `extra`. - * `std::mut` removed. - * std: The prelude no longer reexports any modules, only types and traits. - * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, - `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. * std: `iterator` module for external iterator objects. + * Many old-style (internal, higher-order function) iterators replaced by + implementations of `Iterator`. * std: Many old internal vector and string iterators, incl. `any`, `all`. removed. - * std: new numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, + * std: The `finalize` method of `Drop` renamed to `drop`. + * std: The prelude no longer reexports any modules, only types and traits. + * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, + `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. + * std: New numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, `Algebraic`, `Trigonometric`, `Exponential`, `Primitive`. * std: Tuple traits and accessors defined for up to 12-tuples, e.g. `(0, 1, 2).n2()` or `(0, 1, 2).n2_ref()`. - * std: many types implement `Clone`. + * std: Many types implement `Clone`. * std: `path` type renamed to `Path`. + * std: `mut` module and `Mut` type removed. * std: Many standalone functions removed in favor of methods and iterators in `vec`, `str`. In the future methods will also work as functions. - * std: `reinterpret_cast` removed. Used `transmute`. + * std: `reinterpret_cast` removed. Use `transmute`. * std: ascii string handling in `std::ascii`. * std: `Rand` is implemented for ~/@. * std: `run` module for spawning processes overhauled. * std: Various atomic types added to `unstable::atomic`. + * std: Various types implement `Zero`. * std: `LinearMap` and `LinearSet` renamed to `HashMap` and `HashSet`. * std: Borrowed pointer functions moved from `ptr` to `borrow`. * std: Added `os::mkdir_recursive`. @@ -96,7 +106,6 @@ Version 0.7 (July 2013) * More and improved library documentation. * Various improvements on ARM and Android. * Various improvements to MIPS backend. - * jemalloc is the Rust allocator. Version 0.6 (April 2013) ------------------------ diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index 8e9caf189c220..36031d31149a9 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -60,7 +60,7 @@ def scrub(b): for t in stage2_tests: p = os.path.join("test", "run-pass", t) p = p.replace("\\", "\\\\") - d.write(" out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p) + d.write(" out.write_str(\"run-pass [stage2]: %s\\n\");\n" % p) d.write(" t_%d::main();\n" % i) i += 1 d.write("}\n") diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs index c8bb984736a11..e6a7dd6483730 100644 --- a/src/libextra/deque.rs +++ b/src/libextra/deque.rs @@ -9,12 +9,12 @@ // except according to those terms. //! A double-ended queue implemented as a circular buffer - use core::prelude::*; use core::uint; use core::util::replace; use core::vec; +use core::cast::transmute; static initial_capacity: uint = 32u; // 2^5 @@ -153,7 +153,86 @@ impl Deque { pub fn reserve_at_least(&mut self, n: uint) { vec::reserve_at_least(&mut self.elts, n); } + + /// Front-to-back iterator. + pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> { + DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } + } + + /// Front-to-back iterator which returns mutable values. + pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> { + DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts } + } + + /// Back-to-front iterator. + pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> { + DequeRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } + } + + /// Back-to-front iterator which returns mutable values. + pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> { + DequeMutRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts } + } +} + +macro_rules! iterator { + (impl $name:ident -> $elem:ty, $step:expr) => { + impl<'self, T> Iterator<$elem> for $name<'self, T> { + #[inline] + fn next(&mut self) -> Option<$elem> { + if self.used >= self.nelts { + return None; + } + let ret = unsafe { + match self.vec[self.idx % self.vec.len()] { + Some(ref e) => Some(transmute(e)), + None => None + } + }; + self.idx += $step; + self.used += 1; + ret + } + } + } +} + +/// Deque iterator +pub struct DequeIterator<'self, T> { + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self [Option] } +iterator!{impl DequeIterator -> &'self T, 1} + +/// Deque reverse iterator +pub struct DequeRevIterator<'self, T> { + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self [Option] +} +iterator!{impl DequeRevIterator -> &'self T, -1} + +/// Deque mutable iterator +pub struct DequeMutIterator<'self, T> { + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self mut [Option] + +} +iterator!{impl DequeMutIterator -> &'self mut T, 1} + +/// Deque mutable reverse iterator +pub struct DequeMutRevIterator<'self, T> { + priv idx: uint, + priv nelts: uint, + priv used: uint, + priv vec: &'self mut [Option] +} +iterator!{impl DequeMutRevIterator -> &'self mut T, -1} /// Grow is only called on full elts, so nelts is also len(elts), unlike /// elsewhere. @@ -178,6 +257,7 @@ mod tests { use core::cmp::Eq; use core::kinds::Copy; use core::vec::capacity; + use core; #[test] fn test_simple() { @@ -318,8 +398,7 @@ mod tests { #[test] fn test_param_taggy() { - test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), - Two(17, 42)); + test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42)); } #[test] @@ -382,4 +461,31 @@ mod tests { assert_eq!(capacity(&mut d.elts), 64); } + #[test] + fn test_iter() { + let mut d = Deque::new(); + for core::int::range(0,5) |i| { + d.add_back(i); + } + assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]); + + for core::int::range(6,9) |i| { + d.add_front(i); + } + assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]); + } + + #[test] + fn test_rev_iter() { + let mut d = Deque::new(); + for core::int::range(0,5) |i| { + d.add_back(i); + } + assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]); + + for core::int::range(6,9) |i| { + d.add_front(i); + } + assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]); + } } diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 4e201a6538ba4..af891edf9e5fd 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -37,10 +37,11 @@ impl Mutable for PriorityQueue { } impl PriorityQueue { - /// Visit all values in the underlying vector. - /// - /// The values are **not** visited in order. - pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.iter().advance(f) } + /// An iterator visiting all values in underlying vector, in + /// arbitrary order. + pub fn iter<'a>(&'a self) -> PriorityQueueIterator<'a, T> { + PriorityQueueIterator { iter: self.data.iter() } + } /// Returns the greatest item in the queue - fails if empty pub fn top<'a>(&'a self) -> &'a T { &self.data[0] } @@ -178,11 +179,33 @@ impl PriorityQueue { } } +/// PriorityQueue iterator +pub struct PriorityQueueIterator <'self, T> { + priv iter: vec::VecIterator<'self, T>, +} + +impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> { + #[inline] + fn next(&mut self) -> Option<(&'self T)> { self.iter.next() } +} + #[cfg(test)] mod tests { use sort::merge_sort; use priority_queue::PriorityQueue; + #[test] + fn test_iterator() { + let data = ~[5, 9, 3]; + let iterout = ~[9, 5, 3]; + let pq = PriorityQueue::from_vec(data); + let mut i = 0; + for pq.iter().advance |el| { + assert_eq!(*el, iterout[i]); + i += 1; + } + } + #[test] fn test_top_and_pop() { let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]; diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 345b217871cc5..3d35d1332b2f0 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -832,7 +832,7 @@ impl< fn encode(&self, e: &mut E) { do e.emit_map(self.len()) |e| { let mut i = 0; - for self.each |key, val| { + for self.iter().advance |(key, val)| { e.emit_map_elt_key(i, |e| key.encode(e)); e.emit_map_elt_val(i, |e| val.encode(e)); i += 1; @@ -866,7 +866,7 @@ impl< fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { let mut i = 0; - for self.each |e| { + for self.iter().advance |e| { s.emit_seq_elt(i, |s| e.encode(s)); i += 1; } diff --git a/src/libextra/term.rs b/src/libextra/term.rs index 782a73deadf9a..9a4469cb5265a 100644 --- a/src/libextra/term.rs +++ b/src/libextra/term.rs @@ -24,35 +24,38 @@ use core::io; // FIXME (#2807): Windows support. -pub static color_black: u8 = 0u8; -pub static color_red: u8 = 1u8; -pub static color_green: u8 = 2u8; -pub static color_yellow: u8 = 3u8; -pub static color_blue: u8 = 4u8; -pub static color_magenta: u8 = 5u8; -pub static color_cyan: u8 = 6u8; -pub static color_light_gray: u8 = 7u8; -pub static color_light_grey: u8 = 7u8; -pub static color_dark_gray: u8 = 8u8; -pub static color_dark_grey: u8 = 8u8; -pub static color_bright_red: u8 = 9u8; -pub static color_bright_green: u8 = 10u8; -pub static color_bright_yellow: u8 = 11u8; -pub static color_bright_blue: u8 = 12u8; -pub static color_bright_magenta: u8 = 13u8; -pub static color_bright_cyan: u8 = 14u8; -pub static color_bright_white: u8 = 15u8; +pub mod color { + pub type Color = u16; + + pub static black: Color = 0u16; + pub static red: Color = 1u16; + pub static green: Color = 2u16; + pub static yellow: Color = 3u16; + pub static blue: Color = 4u16; + pub static magenta: Color = 5u16; + pub static cyan: Color = 6u16; + pub static white: Color = 7u16; + + pub static bright_black: Color = 8u16; + pub static bright_red: Color = 9u16; + pub static bright_green: Color = 10u16; + pub static bright_yellow: Color = 11u16; + pub static bright_blue: Color = 12u16; + pub static bright_magenta: Color = 13u16; + pub static bright_cyan: Color = 14u16; + pub static bright_white: Color = 15u16; +} #[cfg(not(target_os = "win32"))] pub struct Terminal { - color_supported: bool, + num_colors: u16, priv out: @io::Writer, priv ti: ~TermInfo } #[cfg(target_os = "win32")] pub struct Terminal { - color_supported: bool, + num_colors: u16, priv out: @io::Writer, } @@ -66,66 +69,81 @@ impl Terminal { let entry = open(term.unwrap()); if entry.is_err() { - return Err(entry.get_err()); + return Err(entry.unwrap_err()); } - let ti = parse(entry.get(), false); + let ti = parse(entry.unwrap(), false); if ti.is_err() { - return Err(entry.get_err()); + return Err(ti.unwrap_err()); } - let mut inf = ti.get(); - let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16 - && inf.strings.find(&~"setaf").is_some() - && inf.strings.find_equiv(&("setab")).is_some(); + let inf = ti.unwrap(); + let nc = if inf.strings.find_equiv(&("setaf")).is_some() + && inf.strings.find_equiv(&("setab")).is_some() { + inf.numbers.find_equiv(&("colors")).map_consume_default(0, |&n| n) + } else { 0 }; - return Ok(Terminal {out: out, ti: inf, color_supported: cs}); + return Ok(Terminal {out: out, ti: inf, num_colors: nc}); } - pub fn fg(&self, color: u8) { - if self.color_supported { + /// Sets the foreground color to the given color. + /// + /// If the color is a bright color, but the terminal only supports 8 colors, + /// the corresponding normal color will be used instead. + pub fn fg(&self, color: color::Color) { + let color = self.dim_if_necessary(color); + if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.get()); + self.out.write(s.unwrap()); } else { - warn!(s.get_err()); + warn!(s.unwrap_err()); } } } - pub fn bg(&self, color: u8) { - if self.color_supported { + /// Sets the background color to the given color. + /// + /// If the color is a bright color, but the terminal only supports 8 colors, + /// the corresponding normal color will be used instead. + pub fn bg(&self, color: color::Color) { + let color = self.dim_if_necessary(color); + if self.num_colors > color { let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(), [Number(color as int)], &mut Variables::new()); if s.is_ok() { - self.out.write(s.get()); + self.out.write(s.unwrap()); } else { - warn!(s.get_err()); + warn!(s.unwrap_err()); } } } pub fn reset(&self) { - if self.color_supported { - let mut vars = Variables::new(); - let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars); - if s.is_ok() { - self.out.write(s.get()); - } else { - warn!(s.get_err()); - } + let mut vars = Variables::new(); + let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars); + if s.is_ok() { + self.out.write(s.unwrap()); + } else { + warn!(s.unwrap_err()); } } + + priv fn dim_if_necessary(&self, color: color::Color) -> color::Color { + if color >= self.num_colors && color >= 8 && color < 16 { + color-8 + } else { color } + } } #[cfg(target_os = "win32")] impl Terminal { pub fn new(out: @io::Writer) -> Result { - return Ok(Terminal {out: out, color_supported: false}); + return Ok(Terminal {out: out, num_colors: 0}); } - pub fn fg(&self, _color: u8) { + pub fn fg(&self, _color: color::Color) { } - pub fn bg(&self, _color: u8) { + pub fn bg(&self, _color: color::Color) { } pub fn reset(&self) { diff --git a/src/libextra/test.rs b/src/libextra/test.rs index ee0d3649467bf..72e70943ce1cc 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -326,33 +326,33 @@ pub fn run_tests_console(opts: &TestOpts, } fn write_ok(out: @io::Writer, use_color: bool) { - write_pretty(out, "ok", term::color_green, use_color); + write_pretty(out, "ok", term::color::green, use_color); } fn write_failed(out: @io::Writer, use_color: bool) { - write_pretty(out, "FAILED", term::color_red, use_color); + write_pretty(out, "FAILED", term::color::red, use_color); } fn write_ignored(out: @io::Writer, use_color: bool) { - write_pretty(out, "ignored", term::color_yellow, use_color); + write_pretty(out, "ignored", term::color::yellow, use_color); } fn write_bench(out: @io::Writer, use_color: bool) { - write_pretty(out, "bench", term::color_cyan, use_color); + write_pretty(out, "bench", term::color::cyan, use_color); } fn write_pretty(out: @io::Writer, word: &str, - color: u8, + color: term::color::Color, use_color: bool) { let t = term::Terminal::new(out); match t { Ok(term) => { - if use_color && term.color_supported { + if use_color { term.fg(color); } out.write_str(word); - if use_color && term.color_supported { + if use_color { term.reset(); } }, diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index fd83fd1991674..33ec4ae94ba52 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -164,19 +164,14 @@ impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } - /// Visit all key-value pairs in order - pub fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { - each(&self.root, f) - } - /// Visit all keys in order pub fn each_key(&self, f: &fn(&K) -> bool) -> bool { - self.each(|k, _| f(k)) + self.iter().advance(|(k, _)| f(k)) } /// Visit all values in order pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { - self.each(|_, v| f(v)) + self.iter().advance(|(_, v)| f(v)) } /// Iterate over the map and mutate the contained values @@ -484,10 +479,6 @@ impl TreeSet { TreeSetIterator{iter: self.map.iter()} } - /// Visit all values in order - #[inline] - pub fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) } - /// Visit all values in reverse order #[inline] pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool { @@ -779,7 +770,7 @@ mod test_treemap { let &(k, v) = x; assert!(map.find(&k).unwrap() == &v) } - for map.each |map_k, map_v| { + for map.iter().advance |(map_k, map_v)| { let mut found = false; for ctrl.iter().advance |x| { let &(ctrl_k, ctrl_v) = x; @@ -885,7 +876,7 @@ mod test_treemap { } #[test] - fn test_each() { + fn test_iterator() { let mut m = TreeMap::new(); assert!(m.insert(3, 6)); @@ -895,7 +886,7 @@ mod test_treemap { assert!(m.insert(1, 2)); let mut n = 0; - for m.each |k, v| { + for m.iter().advance |(k, v)| { assert_eq!(*k, n); assert_eq!(*v, n * 2); n += 1; @@ -1090,7 +1081,7 @@ mod test_set { } #[test] - fn test_each() { + fn test_iterator() { let mut m = TreeSet::new(); assert!(m.insert(3)); @@ -1100,7 +1091,7 @@ mod test_set { assert!(m.insert(1)); let mut n = 0; - for m.each |x| { + for m.iter().advance |x| { println(fmt!("%?", x)); assert_eq!(*x, n); n += 1 diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index f6ad676546dd9..9e0d6fb8e3a6e 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -89,70 +89,68 @@ fn find_library_crate_aux( filesearch: @filesearch::FileSearch ) -> Option<(~str, @~[u8])> { let crate_name = crate_name_from_metas(cx.metas); - let prefix: ~str = prefix + crate_name + "-"; - let suffix: ~str = /*bad*/copy suffix; + let prefix = prefix + crate_name + "-"; let mut matches = ~[]; - filesearch::search(filesearch, |path| { + filesearch::search(filesearch, |path| -> Option<()> { debug!("inspecting file %s", path.to_str()); - let f: ~str = path.filename().get(); - if !(f.starts_with(prefix) && f.ends_with(suffix)) { - debug!("skipping %s, doesn't look like %s*%s", path.to_str(), - prefix, suffix); - option::None::<()> - } else { - debug!("%s is a candidate", path.to_str()); - match get_metadata_section(cx.os, path) { - option::Some(cvec) => { - if !crate_matches(cvec, cx.metas, cx.hash) { - debug!("skipping %s, metadata doesn't match", - path.to_str()); - option::None::<()> - } else { - debug!("found %s with matching metadata", path.to_str()); - matches.push((path.to_str(), cvec)); - option::None::<()> + match path.filename() { + Some(ref f) if f.starts_with(prefix) && f.ends_with(suffix) => { + debug!("%s is a candidate", path.to_str()); + match get_metadata_section(cx.os, path) { + Some(cvec) => + if !crate_matches(cvec, cx.metas, cx.hash) { + debug!("skipping %s, metadata doesn't match", + path.to_str()); + None + } else { + debug!("found %s with matching metadata", path.to_str()); + matches.push((path.to_str(), cvec)); + None + }, + _ => { + debug!("could not load metadata for %s", path.to_str()); + None + } } - } - _ => { - debug!("could not load metadata for %s", path.to_str()); - option::None::<()> - } } - } - }); + _ => { + debug!("skipping %s, doesn't look like %s*%s", path.to_str(), + prefix, suffix); + None + } + }}); - if matches.is_empty() { - None - } else if matches.len() == 1u { - Some(/*bad*/copy matches[0]) - } else { - cx.diag.span_err( - cx.span, fmt!("multiple matching crates for `%s`", crate_name)); - cx.diag.handler().note("candidates:"); - for matches.iter().advance |&(ident, data)| { - cx.diag.handler().note(fmt!("path: %s", ident)); - let attrs = decoder::get_crate_attributes(data); - note_linkage_attrs(cx.intr, cx.diag, attrs); + match matches.len() { + 0 => None, + 1 => Some(matches[0]), + _ => { + cx.diag.span_err( + cx.span, fmt!("multiple matching crates for `%s`", crate_name)); + cx.diag.handler().note("candidates:"); + for matches.iter().advance |&(ident, data)| { + cx.diag.handler().note(fmt!("path: %s", ident)); + let attrs = decoder::get_crate_attributes(data); + note_linkage_attrs(cx.intr, cx.diag, attrs); + } + cx.diag.handler().abort_if_errors(); + None + } } - cx.diag.handler().abort_if_errors(); - None - } } pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { - let name_items = attr::find_meta_items_by_name(metas, "name"); - match name_items.last_opt() { - Some(i) => { - match attr::get_meta_item_value_str(*i) { - Some(n) => n, - // FIXME (#2406): Probably want a warning here since the user - // is using the wrong type of meta item. - _ => fail!() - } + for metas.iter().advance |m| { + match m.node { + ast::meta_name_value(s, ref l) if s == @"name" => + match l.node { + ast::lit_str(s) => return s, + _ => () + }, + _ => () } - None => fail!("expected to find the crate name") } + fail!("expected to find the crate name") } pub fn note_linkage_attrs(intr: @ident_interner, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 3e55934198f55..b4e6245f629d7 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -55,7 +55,6 @@ use middle::trans::machine::{llalign_of_min, llsize_of}; use middle::trans::meth; use middle::trans::monomorphize; use middle::trans::reachable; -use middle::trans::shape::*; use middle::trans::tvec; use middle::trans::type_of; use middle::trans::type_of::*; @@ -2869,6 +2868,26 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { } } +fn mk_global(ccx: &CrateContext, + name: &str, + llval: ValueRef, + internal: bool) + -> ValueRef { + unsafe { + let llglobal = do str::as_c_str(name) |buf| { + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) + }; + llvm::LLVMSetInitializer(llglobal, llval); + llvm::LLVMSetGlobalConstant(llglobal, True); + + if internal { + lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); + } + + return llglobal; + } +} + // Writes the current ABI version into the crate. pub fn write_abi_version(ccx: &mut CrateContext) { mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 6cff996d0d45f..227e22131636b 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -210,7 +210,7 @@ pub fn store_environment(bcx: block, let ccx = bcx.ccx(); let tcx = ccx.tcx; - // compute the shape of the closure + // compute the type of the closure let cdata_ty = mk_closure_tys(tcx, bound_values); // allocate closure in the heap diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 442ab475046fd..272d7b234aa57 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -658,7 +658,7 @@ impl block_ { pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { let ptr = ty::mk_ptr( tcx, - ty::mt {ty: ty::mk_nil(), mutbl: ast::m_imm} + ty::mt {ty: ty::mk_i8(), mutbl: ast::m_imm} ); return ty::mk_tup(tcx, ~[ty::mk_uint(), ty::mk_type(tcx), ptr, ptr, @@ -826,20 +826,6 @@ pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { } } -pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { - unsafe { - let llshape = C_bytes_plus_null(bytes); - let name = fmt!("shape%u", token::gensym("shape")); - let llglobal = do name.as_c_str |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) - }; - llvm::LLVMSetInitializer(llglobal, llshape); - llvm::LLVMSetGlobalConstant(llglobal, True); - lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); - } -} - pub fn get_param(fndecl: ValueRef, param: uint) -> ValueRef { unsafe { llvm::LLVMGetParam(fndecl, param as c_uint) diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 57cfb1474dfeb..a0ae579c86554 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -22,7 +22,6 @@ use middle::trans::adt; use middle::trans::base; use middle::trans::debuginfo; use middle::trans::reachable; -use middle::trans::shape; use middle::trans::type_use; use middle::ty; @@ -40,8 +39,6 @@ use middle::trans::common::{mono_id,new_namegen}; use middle::trans::base::{decl_crate_map}; -use middle::trans::shape::{mk_ctxt}; - pub struct CrateContext { sess: session::Session, llmod: ModuleRef, @@ -110,7 +107,6 @@ pub struct CrateContext { float_type: Type, opaque_vec_type: Type, builder: BuilderRef_res, - shape_cx: shape::Ctxt, crate_map: ValueRef, // Set when at least one function uses GC. Needed so that // decl_gc_metadata knows whether to link to the module metadata, which @@ -223,7 +219,6 @@ impl CrateContext { float_type: float_type, opaque_vec_type: opaque_vec_type, builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), - shape_cx: mk_ctxt(llmod), crate_map: crate_map, uses_gc: false, dbg_cx: dbg_cx, diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index 1345b92418e3d..c2a25d80998a5 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -35,7 +35,6 @@ pub mod cabi_arm; pub mod cabi_mips; pub mod foreign; pub mod reflect; -pub mod shape; pub mod debuginfo; pub mod type_use; pub mod reachable; diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs deleted file mode 100644 index 4118291dca0d6..0000000000000 --- a/src/librustc/middle/trans/shape.rs +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -// A "shape" is a compact encoding of a type that is used by interpreted glue. -// This substitutes for the runtime tags used by e.g. MLs. - - -use lib::llvm::llvm; -use lib::llvm::{True, ModuleRef, ValueRef}; -use middle::trans::common::*; - -use middle::trans::type_::Type; - -use core::str; - -pub struct Ctxt { - next_tag_id: u16, - pad: u16, - pad2: u32 -} - -pub fn mk_global(ccx: &CrateContext, - name: &str, - llval: ValueRef, - internal: bool) - -> ValueRef { - unsafe { - let llglobal = do str::as_c_str(name) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) - }; - llvm::LLVMSetInitializer(llglobal, llval); - llvm::LLVMSetGlobalConstant(llglobal, True); - - if internal { - ::lib::llvm::SetLinkage(llglobal, - ::lib::llvm::InternalLinkage); - } - - return llglobal; - } -} - -pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { - unsafe { - let llshapetablesty = Type::named_struct("shapes"); - do "shapes".as_c_str |buf| { - llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf) - }; - - Ctxt { - next_tag_id: 0u16, - pad: 0u16, - pad2: 0u32 - } - } -} diff --git a/src/librusti/program.rs b/src/librusti/program.rs index f17777559deb5..869b3472422bc 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -107,7 +107,7 @@ impl Program { match *to_print { Some(ref s) => { code.push_str(*s); - code.push_char('\n'); + code.push_str(";\n"); } None => {} } diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 57a2a48a0f634..54a404d971eec 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -648,6 +648,11 @@ mod tests { fn f() {} f() "); + + debug!("simultaneous definitions + expressions are allowed"); + run_program(" + let a = 3; a as u8 + "); } #[test] diff --git a/src/librustpkg/messages.rs b/src/librustpkg/messages.rs index d3962470e7c84..bde7aaeab8e4a 100644 --- a/src/librustpkg/messages.rs +++ b/src/librustpkg/messages.rs @@ -13,18 +13,18 @@ use core::io; use core::result::*; pub fn note(msg: &str) { - pretty_message(msg, "note: ", term::color_green, io::stdout()) + pretty_message(msg, "note: ", term::color::green, io::stdout()) } pub fn warn(msg: &str) { - pretty_message(msg, "warning: ", term::color_yellow, io::stdout()) + pretty_message(msg, "warning: ", term::color::yellow, io::stdout()) } pub fn error(msg: &str) { - pretty_message(msg, "error: ", term::color_red, io::stdout()) + pretty_message(msg, "error: ", term::color::red, io::stdout()) } -fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: u8, out: @io::Writer) { +fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: term::color::Color, out: @io::Writer) { let term = term::Terminal::new(out); match term { Ok(ref t) => { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 2e18a588fae31..56e6bacf93e30 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -15,6 +15,7 @@ use cast::transmute; use cast; use container::{Container, Mutable}; +use cmp; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; use iterator::{FromIterator, Iterator, IteratorUtil}; @@ -1299,44 +1300,6 @@ pub fn reverse(v: &mut [T]) { } } -/** - * Reverse part of a vector in place. - * - * Reverse the elements in the vector between `start` and `end - 1`. - * - * If either start or end do not represent valid positions in the vector, the - * vector is returned unchanged. - * - * # Arguments - * - * * `v` - The mutable vector to be modified - * - * * `start` - Index of the first element of the slice - * - * * `end` - Index one past the final element to be reversed. - * - * # Example - * - * Assume a mutable vector `v` contains `[1,2,3,4,5]`. After the call: - * - * ~~~ {.rust} - * reverse_part(v, 1, 4); - * ~~~ - * - * `v` now contains `[1,4,3,2,5]`. - */ -pub fn reverse_part(v: &mut [T], start: uint, end : uint) { - let sz = v.len(); - if start >= sz || end > sz { return; } - let mut i = start; - let mut j = end - 1; - while i < j { - vec::swap(v, i, j); - i += 1; - j -= 1; - } -} - /// Returns a vector with the order of elements reversed pub fn reversed(v: &const [T]) -> ~[T] { let mut rs: ~[T] = ~[]; @@ -1393,7 +1356,7 @@ pub fn each_permutation(values: &[T], fun: &fn(perm : &[T]) -> bool) -> // swap indices[k] and indices[l]; sort indices[k+1..] // (they're just reversed) vec::swap(indices, k, l); - reverse_part(indices, k+1, length); + reverse(indices.mut_slice(k+1, length)); // fixup permutation based on indices for uint::range(k, length) |i| { permutation[i] = copy values[indices[i]]; @@ -2059,6 +2022,21 @@ pub trait MutableVector<'self, T> { fn mut_iter(self) -> VecMutIterator<'self, T>; fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>; + /** + * Consumes `src` and moves as many elements as it can into `self` + * from the range [start,end). + * + * Returns the number of elements copied (the shorter of self.len() + * and end - start). + * + * # Arguments + * + * * src - A mutable vector of `T` + * * start - The index into `src` to start copying from + * * end - The index into `str` to stop copying from + */ + fn move_from(self, src: ~[T], start: uint, end: uint) -> uint; + unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T; unsafe fn unsafe_set(&self, index: uint, val: T); } @@ -2087,6 +2065,14 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } + #[inline] + fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint { + for self.mut_iter().zip(src.mut_slice(start, end).mut_iter()).advance |(a, b)| { + util::swap(a, b); + } + cmp::min(self.len(), end-start) + } + #[inline] unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T { let pair_ptr: &(*mut T, uint) = transmute(self); @@ -2100,6 +2086,23 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } } +/// Trait for ~[T] where T is Cloneable +pub trait MutableCloneableVector { + /// Copies as many elements from `src` as it can into `self` + /// (the shorter of self.len() and src.len()). Returns the number of elements copied. + fn copy_from(self, &[T]) -> uint; +} + +impl<'self, T:Clone> MutableCloneableVector for &'self mut [T] { + #[inline] + fn copy_from(self, src: &[T]) -> uint { + for self.mut_iter().zip(src.iter()).advance |(a, b)| { + *a = b.clone(); + } + cmp::min(self.len(), src.len()) + } +} + /** * Constructs a vector from an unsafe pointer to a buffer * @@ -2288,6 +2291,22 @@ pub mod bytes { use uint; use vec::raw; use vec; + use ptr; + + /// A trait for operations on mutable operations on `[u8]` + pub trait MutableByteVector { + /// Sets all bytes of the receiver to the given value. + pub fn set_memory(self, value: u8); + } + + impl<'self> MutableByteVector for &'self mut [u8] { + #[inline] + fn set_memory(self, value: u8) { + do vec::as_mut_buf(self) |p, len| { + unsafe { ptr::set_memory(p, value, len) }; + } + } + } /// Bytewise string comparison pub fn memcmp(a: &~[u8], b: &~[u8]) -> int { @@ -3879,10 +3898,42 @@ mod tests { assert_eq!(xs, [5, 5, 5, 5, 5]) } + #[test] + fn test_move_from() { + let mut a = [1,2,3,4,5]; + let b = ~[6,7,8]; + assert_eq!(a.move_from(b, 0, 3), 3); + assert_eq!(a, [6,7,8,4,5]); + let mut a = [7,2,8,1]; + let b = ~[3,1,4,1,5,9]; + assert_eq!(a.move_from(b, 0, 6), 4); + assert_eq!(a, [3,1,4,1]); + let mut a = [1,2,3,4]; + let b = ~[5,6,7,8,9,0]; + assert_eq!(a.move_from(b, 2, 3), 1); + assert_eq!(a, [7,2,3,4]); + let mut a = [1,2,3,4,5]; + let b = ~[5,6,7,8,9,0]; + assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2); + assert_eq!(a, [1,2,6,7,5]); + } + + #[test] + fn test_copy_from() { + let mut a = [1,2,3,4,5]; + let b = [6,7,8]; + assert_eq!(a.copy_from(b), 3); + assert_eq!(a, [6,7,8,4,5]); + let mut c = [7,2,8,1]; + let d = [3,1,4,1,5,9]; + assert_eq!(c.copy_from(d), 4); + assert_eq!(c, [3,1,4,1]); + } + #[test] fn test_reverse_part() { let mut values = [1,2,3,4,5]; - reverse_part(values,1,4); + reverse(values.mut_slice(1, 4)); assert_eq!(values, [1,4,3,2,5]); } @@ -3941,4 +3992,14 @@ mod tests { t!(@[int]); t!(~[int]); } + + #[test] + fn test_bytes_set_memory() { + use vec::bytes::MutableByteVector; + let mut values = [1u8,2,3,4,5]; + values.mut_slice(0,5).set_memory(0xAB); + assert_eq!(values, [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]); + values.mut_slice(2,4).set_memory(0xFF); + assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]); + } } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 13fa01c96e120..89867922b25bd 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -178,16 +178,16 @@ fn diagnosticstr(lvl: level) -> ~str { } } -fn diagnosticcolor(lvl: level) -> u8 { +fn diagnosticcolor(lvl: level) -> term::color::Color { match lvl { - fatal => term::color_bright_red, - error => term::color_bright_red, - warning => term::color_bright_yellow, - note => term::color_bright_green + fatal => term::color::bright_red, + error => term::color::bright_red, + warning => term::color::bright_yellow, + note => term::color::bright_green } } -fn print_maybe_colored(msg: &str, color: u8) { +fn print_maybe_colored(msg: &str, color: term::color::Color) { let stderr = io::stderr(); let t = term::Terminal::new(stderr); @@ -231,7 +231,7 @@ pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) { let ss = cm.span_to_str(sp); let lines = cm.span_to_lines(sp); print_diagnostic(ss, lvl, msg); - highlight_lines(cm, sp, lines); + highlight_lines(cm, sp, lvl, lines); print_macro_backtrace(cm, sp); } None => { @@ -241,7 +241,7 @@ pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) { } fn highlight_lines(cm: @codemap::CodeMap, - sp: span, + sp: span, lvl: level, lines: @codemap::FileLines) { let fm = lines.file; @@ -293,18 +293,18 @@ fn highlight_lines(cm: @codemap::CodeMap, let curChar = (orig[pos] as char); s += match curChar { // Whenever a tab occurs on the previous '\t' => "\t", // line, we insert one on the error-point- - _ => " " // -squigly-line as well (instead of a - }; // space). This way the squigly-line will + _ => " " // -squiggly-line as well (instead of a + }; // space). This way the squiggly-line will } // usually appear in the correct position. io::stderr().write_str(s); let mut s = ~"^"; let hi = cm.lookup_char_pos(sp.hi); if hi.col != lo.col { // the ^ already takes up one space - let num_squiglies = hi.col.to_uint()-lo.col.to_uint()-1u; - for num_squiglies.times() { s += "~"; } + let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u; + for num_squigglies.times() { s += "~"; } } - print_maybe_colored(s + "\n", term::color_bright_green); + print_maybe_colored(s + "\n", diagnosticcolor(lvl)); } } diff --git a/src/test/run-pass/match-borrowed_str.rs b/src/test/run-pass/match-borrowed_str.rs index 99e1ae6ec56e3..7a30f5152d01d 100644 --- a/src/test/run-pass/match-borrowed_str.rs +++ b/src/test/run-pass/match-borrowed_str.rs @@ -1,55 +1,60 @@ -// FIXME #7306 -// xfail-fast +// 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::io; - -fn f1(ref_string: &str) { +fn f1(ref_string: &str) -> ~str { match ref_string { - "a" => io::println("found a"), - "b" => io::println("found b"), - _ => io::println("not found") + "a" => ~"found a", + "b" => ~"found b", + _ => ~"not found" } } -fn f2(ref_string: &str) { +fn f2(ref_string: &str) -> ~str { match ref_string { - "a" => io::println("found a"), - "b" => io::println("found b"), - s => io::println(fmt!("not found (%s)", s)) + "a" => ~"found a", + "b" => ~"found b", + s => fmt!("not found (%s)", s) } } -fn g1(ref_1: &str, ref_2: &str) { +fn g1(ref_1: &str, ref_2: &str) -> ~str { match (ref_1, ref_2) { - ("a", "b") => io::println("found a,b"), - ("b", "c") => io::println("found b,c"), - _ => io::println("not found") + ("a", "b") => ~"found a,b", + ("b", "c") => ~"found b,c", + _ => ~"not found" } } -fn g2(ref_1: &str, ref_2: &str) { +fn g2(ref_1: &str, ref_2: &str) -> ~str { match (ref_1, ref_2) { - ("a", "b") => io::println("found a,b"), - ("b", "c") => io::println("found b,c"), - (s1, s2) => io::println(fmt!("not found (%s, %s)", s1, s2)) + ("a", "b") => ~"found a,b", + ("b", "c") => ~"found b,c", + (s1, s2) => fmt!("not found (%s, %s)", s1, s2) } } pub fn main() { - f1(@"a"); - f1(~"b"); - f1(&"c"); - f1("d"); - f2(@"a"); - f2(~"b"); - f2(&"c"); - f2("d"); - g1(@"a", @"b"); - g1(~"b", ~"c"); - g1(&"c", &"d"); - g1("d", "e"); - g2(@"a", @"b"); - g2(~"b", ~"c"); - g2(&"c", &"d"); - g2("d", "e"); + assert_eq!(f1(@"a"), ~"found a"); + assert_eq!(f1(~"b"), ~"found b"); + assert_eq!(f1(&"c"), ~"not found"); + assert_eq!(f1("d"), ~"not found"); + assert_eq!(f2(@"a"), ~"found a"); + assert_eq!(f2(~"b"), ~"found b"); + assert_eq!(f2(&"c"), ~"not found (c)"); + assert_eq!(f2("d"), ~"not found (d)"); + assert_eq!(g1(@"a", @"b"), ~"found a,b"); + assert_eq!(g1(~"b", ~"c"), ~"found b,c"); + assert_eq!(g1(&"c", &"d"), ~"not found"); + assert_eq!(g1("d", "e"), ~"not found"); + assert_eq!(g2(@"a", @"b"), ~"found a,b"); + assert_eq!(g2(~"b", ~"c"), ~"found b,c"); + assert_eq!(g2(&"c", &"d"), ~"not found (c, d)"); + assert_eq!(g2("d", "e"), ~"not found (d, e)"); } diff --git a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs index f29d0c6f108c6..34afc12f02e4f 100644 --- a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs +++ b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs @@ -1,5 +1,3 @@ -// xfail-fast - // 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. @@ -14,9 +12,6 @@ // on x86_64: when there is a enum embedded in an // interior record which is then itself interior to // something else, shape calculations were off. -extern mod extra; -use extra::list; -use extra::list::list; enum opt_span {