diff options
Diffstat (limited to 'src')
120 files changed, 1029 insertions, 843 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md index 5d1401e27ba..28cb2de2923 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -133,7 +133,7 @@ Some productions are defined by exclusion of particular Unicode characters: ```{.ebnf .gram} comment : block_comment | line_comment ; -block_comment : "/*" block_comment_body * '*' + '/' ; +block_comment : "/*" block_comment_body * "*/" ; block_comment_body : [block_comment | character] * ; line_comment : "//" non_eol * ; ``` @@ -458,10 +458,9 @@ Examples of floating-point literals of various forms: 12E+99_f64; // type f64 ``` -##### Unit and boolean literals +##### Boolean literals -The _unit value_, the only value of the type that has the same name, is written -as `()`. The two values of the boolean type are written `true` and `false`. +The two values of the boolean type are written `true` and `false`. ### Symbols @@ -2717,7 +2716,7 @@ or an item. Path expressions are [lvalues](#lvalues,-rvalues-and-temporaries). ### Tuple expressions -Tuples are written by enclosing one or more comma-separated expressions in +Tuples are written by enclosing zero or more comma-separated expressions in parentheses. They are used to create [tuple-typed](#tuple-types) values. ```{.tuple} @@ -2726,6 +2725,11 @@ parentheses. They are used to create [tuple-typed](#tuple-types) values. ("a", 4u, true); ``` +### Unit expressions + +The expression `()` denotes the _unit value_, the only value of the type with +the same name. + ### Structure expressions ```{.ebnf .gram} diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py index 94b3fb6b93a..1e5d5ccf339 100755 --- a/src/etc/generate-deriving-span-tests.py +++ b/src/etc/generate-deriving-span-tests.py @@ -37,7 +37,6 @@ TEMPLATE = """// Copyright {year} The Rust Project Developers. See the COPYRIGHT // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; {error_deriving} diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 46fd86df987..e95660b546e 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -15,14 +15,19 @@ use core::prelude::*; -use core::cmp; use core::default::Default; use core::fmt; use core::iter; -use core::slice; +use core::raw::Slice as RawSlice; +use core::ptr; +use core::kinds::marker; +use core::mem; +use core::num::{Int, UnsignedInt}; + use std::hash::{Writer, Hash}; +use std::cmp; -use vec::Vec; +use alloc::heap; static INITIAL_CAPACITY: uint = 8u; // 2^3 static MINIMUM_CAPACITY: uint = 2u; @@ -33,11 +38,37 @@ static MINIMUM_CAPACITY: uint = 2u; /// `RingBuf` is a circular buffer that implements `Deque`. -#[deriving(Clone)] pub struct RingBuf<T> { - nelts: uint, - lo: uint, - elts: Vec<Option<T>> + // tail and head are pointers into the buffer. Tail always points + // to the first element that could be read, Head always points + // to where data should be written. + // If tail == head the buffer is empty. The length of the ringbuf + // is defined as the distance between the two. + + tail: uint, + head: uint, + cap: uint, + ptr: *mut T +} + +impl<T: Clone> Clone for RingBuf<T> { + fn clone(&self) -> RingBuf<T> { + self.iter().map(|t| t.clone()).collect() + } +} + +#[unsafe_destructor] +impl<T> Drop for RingBuf<T> { + fn drop(&mut self) { + self.clear(); + unsafe { + if mem::size_of::<T>() != 0 { + heap::deallocate(self.ptr as *mut u8, + self.cap * mem::size_of::<T>(), + mem::min_align_of::<T>()) + } + } + } } impl<T> Default for RingBuf<T> { @@ -46,6 +77,34 @@ impl<T> Default for RingBuf<T> { } impl<T> RingBuf<T> { + /// Turn ptr into a slice + #[inline] + unsafe fn buffer_as_slice(&self) -> &[T] { + mem::transmute(RawSlice { data: self.ptr as *const T, len: self.cap }) + } + + /// Moves an element out of the buffer + #[inline] + unsafe fn buffer_read(&mut self, off: uint) -> T { + ptr::read(self.ptr.offset(off as int) as *const T) + } + + /// Writes an element into the buffer, moving it. + #[inline] + unsafe fn buffer_write(&mut self, off: uint, t: T) { + ptr::write(self.ptr.offset(off as int), t); + } + + /// Returns true iff the buffer is at capacity + #[inline] + fn is_full(&self) -> bool { self.cap - self.len() == 1 } + + /// Returns the index in the underlying buffer for a given logical element index. + #[inline] + fn wrap_index(&self, idx: uint) -> uint { wrap_index(idx, self.cap) } +} + +impl<T> RingBuf<T> { /// Creates an empty `RingBuf`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> RingBuf<T> { @@ -55,8 +114,27 @@ impl<T> RingBuf<T> { /// Creates an empty `RingBuf` with space for at least `n` elements. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(n: uint) -> RingBuf<T> { - RingBuf{nelts: 0, lo: 0, - elts: Vec::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)} + // +1 since the ringbuffer always leaves one space empty + let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two(); + let size = cap.checked_mul(mem::size_of::<T>()) + .expect("capacity overflow"); + + let ptr = if mem::size_of::<T>() != 0 { + unsafe { + let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;; + if ptr.is_null() { ::alloc::oom() } + ptr + } + } else { + heap::EMPTY as *mut T + }; + + RingBuf { + tail: 0, + head: 0, + cap: cap, + ptr: ptr + } } /// Retrieves an element in the `RingBuf` by index. @@ -74,9 +152,11 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn get(&self, i: uint) -> Option<&T> { - match self.elts.get(i) { - None => None, - Some(opt) => opt.as_ref(), + if i < self.len() { + let idx = self.wrap_index(self.tail + i); + unsafe { Some(&*self.ptr.offset(idx as int)) } + } else { + None } } @@ -102,9 +182,11 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn get_mut(&mut self, i: uint) -> Option<&mut T> { - match self.elts.get_mut(i) { - None => None, - Some(opt) => opt.as_mut(), + if i < self.len() { + let idx = self.wrap_index(self.tail + i); + unsafe { Some(&mut *self.ptr.offset(idx as int)) } + } else { + None } } @@ -130,15 +212,11 @@ impl<T> RingBuf<T> { pub fn swap(&mut self, i: uint, j: uint) { assert!(i < self.len()); assert!(j < self.len()); - let ri = self.raw_index(i); - let rj = self.raw_index(j); - self.elts.as_mut_slice().swap(ri, rj); - } - - /// Returns the index in the underlying `Vec` for a given logical element - /// index. - fn raw_index(&self, idx: uint) -> uint { - raw_index(self.lo, self.elts.len(), idx) + let ri = self.wrap_index(self.tail + i); + let rj = self.wrap_index(self.tail + j); + unsafe { + ptr::swap(self.ptr.offset(ri as int), self.ptr.offset(rj as int)) + } } /// Returns the number of elements the `RingBuf` can hold without @@ -150,14 +228,11 @@ impl<T> RingBuf<T> { /// use std::collections::RingBuf; /// /// let buf: RingBuf<int> = RingBuf::with_capacity(10); - /// assert_eq!(buf.capacity(), 10); + /// assert!(buf.capacity() >= 10); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn capacity(&self) -> uint { - // FXIME(Gankro): not the actual usable capacity if you use reserve/reserve_exact - self.elts.capacity() - } + pub fn capacity(&self) -> uint { self.cap - 1 } /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the /// given `RingBuf`. Does nothing if the capacity is already sufficient. @@ -181,8 +256,7 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { - // FIXME(Gankro): this is just wrong. The ringbuf won't actually use this space - self.elts.reserve_exact(additional); + self.reserve(additional); } /// Reserves capacity for at least `additional` more elements to be inserted in the given @@ -203,8 +277,69 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { - // FIXME(Gankro): this is just wrong. The ringbuf won't actually use this space - self.elts.reserve(additional); + let new_len = self.len() + additional; + assert!(new_len + 1 > self.len(), "capacity overflow"); + if new_len > self.capacity() { + let count = (new_len + 1).next_power_of_two(); + assert!(count >= new_len + 1); + + if mem::size_of::<T>() != 0 { + let old = self.cap * mem::size_of::<T>(); + let new = count.checked_mul(mem::size_of::<T>()) + .expect("capacity overflow"); + unsafe { + self.ptr = heap::reallocate(self.ptr as *mut u8, + old, + new, + mem::min_align_of::<T>()) as *mut T; + if self.ptr.is_null() { ::alloc::oom() } + } + } + + // Move the shortest contiguous section of the ring buffer + // T H + // [o o o o o o o . ] + // T H + // A [o o o o o o o . . . . . . . . . ] + // H T + // [o o . o o o o o ] + // T H + // B [. . . o o o o o o o . . . . . . ] + // H T + // [o o o o o . o o ] + // H T + // C [o o o o o . . . . . . . . . o o ] + + let oldcap = self.cap; + self.cap = count; + + if self.tail <= self.head { // A + // Nop + } else if self.head < oldcap - self.tail { // B + unsafe { + ptr::copy_nonoverlapping_memory( + self.ptr.offset(oldcap as int), + self.ptr as *const T, + self.head + ); + } + self.head += oldcap; + debug_assert!(self.head > self.tail); + } else { // C + unsafe { + ptr::copy_nonoverlapping_memory( + self.ptr.offset((count - (oldcap - self.tail)) as int), + self.ptr.offset(self.tail as int) as *const T, + oldcap - self.tail + ); + } + self.tail = count - (oldcap - self.tail); + debug_assert!(self.head < self.tail); + } + debug_assert!(self.head < self.cap); + debug_assert!(self.tail < self.cap); + debug_assert!(self.cap.count_ones() == 1); + } } /// Returns a front-to-back iterator. @@ -223,7 +358,11 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter(&self) -> Items<T> { - Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()} + Items { + tail: self.tail, + head: self.head, + ring: unsafe { self.buffer_as_slice() } + } } /// Returns a front-to-back iterator which returns mutable references. @@ -244,32 +383,14 @@ impl<T> RingBuf<T> { /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter_mut(&mut self) -> MutItems<T> { - let start_index = raw_index(self.lo, self.elts.len(), 0); - let end_index = raw_index(self.lo, self.elts.len(), self.nelts); - - // Divide up the array - if end_index <= start_index { - // Items to iterate goes from: - // start_index to self.elts.len() - // and then - // 0 to end_index - let (temp, remaining1) = self.elts.split_at_mut(start_index); - let (remaining2, _) = temp.split_at_mut(end_index); - MutItems { - remaining1: remaining1.iter_mut(), - remaining2: remaining2.iter_mut(), - nelts: self.nelts, - } - } else { - // Items to iterate goes from start_index to end_index: - let (empty, elts) = self.elts.split_at_mut(0); - let remaining1 = elts[mut start_index..end_index]; - MutItems { - remaining1: remaining1.iter_mut(), - remaining2: empty.iter_mut(), - nelts: self.nelts, - } + pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> { + MutItems { + tail: self.tail, + head: self.head, + cap: self.cap, + ptr: self.ptr, + marker: marker::ContravariantLifetime::<'a>, + marker2: marker::NoCopy } } @@ -286,7 +407,7 @@ impl<T> RingBuf<T> { /// assert_eq!(v.len(), 1); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.nelts } + pub fn len(&self) -> uint { count(self.tail, self.head, self.cap) } /// Returns true if the buffer contains no elements /// @@ -317,9 +438,9 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { - for x in self.elts.iter_mut() { *x = None } - self.nelts = 0; - self.lo = 0; + while self.pop_front().is_some() {} + self.head = 0; + self.tail = 0; } /// Provides a reference to the front element, or `None` if the sequence is @@ -339,7 +460,7 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn front(&self) -> Option<&T> { - if self.nelts > 0 { Some(&self[0]) } else { None } + if !self.is_empty() { Some(&self[0]) } else { None } } /// Provides a mutable reference to the front element, or `None` if the @@ -363,7 +484,7 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn front_mut(&mut self) -> Option<&mut T> { - if self.nelts > 0 { Some(&mut self[0]) } else { None } + if !self.is_empty() { Some(&mut self[0]) } else { None } } /// Provides a reference to the back element, or `None` if the sequence is @@ -383,7 +504,7 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn back(&self) -> Option<&T> { - if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None } + if !self.is_empty() { Some(&self[self.len() - 1]) } else { None } } /// Provides a mutable reference to the back element, or `None` if the @@ -407,8 +528,8 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn back_mut(&mut self) -> Option<&mut T> { - let nelts = self.nelts; - if nelts > 0 { Some(&mut self[nelts - 1]) } else { None } + let len = self.len(); + if !self.is_empty() { Some(&mut self[len - 1]) } else { None } } /// Removes the first element and returns it, or `None` if the sequence is @@ -429,12 +550,13 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn pop_front(&mut self) -> Option<T> { - let result = self.elts[self.lo].take(); - if result.is_some() { - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; + if self.is_empty() { + None + } else { + let tail = self.tail; + self.tail = self.wrap_index(self.tail + 1); + unsafe { Some(self.buffer_read(tail)) } } - result } /// Inserts an element first in the sequence. @@ -451,14 +573,14 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push_front(&mut self, t: T) { - if self.nelts == self.elts.len() { - grow(self.nelts, &mut self.lo, &mut self.elts); + if self.is_full() { + self.reserve(1); + debug_assert!(!self.is_full()); } - if self.lo == 0u { - self.lo = self.elts.len() - 1u; - } else { self.lo -= 1u; } - self.elts[self.lo] = Some(t); - self.nelts += 1u; + + self.tail = self.wrap_index(self.tail - 1); + let tail = self.tail; + unsafe { self.buffer_write(tail, t); } } /// Deprecated: Renamed to `push_back`. @@ -481,12 +603,14 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push_back(&mut self, t: T) { - if self.nelts == self.elts.len() { - grow(self.nelts, &mut self.lo, &mut self.elts); + if self.is_full() { + self.reserve(1); + debug_assert!(!self.is_full()); } - let hi = self.raw_index(self.nelts); - self.elts[hi] = Some(t); - self.nelts += 1u; + + let head = self.head; + self.head = self.wrap_index(self.head + 1); + unsafe { self.buffer_write(head, t) } } /// Deprecated: Renamed to `pop_back`. @@ -511,38 +635,51 @@ impl<T> RingBuf<T> { /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn pop_back(&mut self) -> Option<T> { - if self.nelts > 0 { - self.nelts -= 1; - let hi = self.raw_index(self.nelts); - self.elts[hi].take() - } else { + if self.is_empty() { None + } else { + self.head = self.wrap_index(self.head - 1); + let head = self.head; + unsafe { Some(self.buffer_read(head)) } } } } +/// Returns the index in the underlying buffer for a given logical element index. +#[inline] +fn wrap_index(index: uint, size: uint) -> uint { + // size is always a power of 2 + index & (size - 1) +} + +/// Calculate the number of elements left to be read in the buffer +#[inline] +fn count(tail: uint, head: uint, size: uint) -> uint { + // size is always a power of 2 + (head - tail) & (size - 1) +} + /// `RingBuf` iterator. pub struct Items<'a, T:'a> { - lo: uint, - index: uint, - rindex: uint, - elts: &'a [Option<T>], + ring: &'a [T], + tail: uint, + head: uint } impl<'a, T> Iterator<&'a T> for Items<'a, T> { #[inline] fn next(&mut self) -> Option<&'a T> { - if self.index == self.rindex { + if self.tail == self.head { return None; } - let raw_index = raw_index(self.lo, self.elts.len(), self.index); - self.index += 1; - Some(self.elts[raw_index].as_ref().unwrap()) + let tail = self.tail; + self.tail = wrap_index(self.tail + 1, self.ring.len()); + unsafe { Some(self.ring.unsafe_get(tail)) } } #[inline] fn size_hint(&self) -> (uint, Option<uint>) { - let len = self.rindex - self.index; + let len = count(self.tail, self.head, self.ring.len()); (len, Some(len)) } } @@ -550,129 +687,87 @@ impl<'a, T> Iterator<&'a T> for Items<'a, T> { impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a T> { - if self.index == self.rindex { + if self.tail == self.head { return None; } - self.rindex -= 1; - let raw_index = raw_index(self.lo, self.elts.len(), self.rindex); - Some(self.elts[raw_index].as_ref().unwrap()) + self.head = wrap_index(self.head - 1, self.ring.len()); + unsafe { Some(self.ring.unsafe_get(self.head)) } } } + impl<'a, T> ExactSize<&'a T> for Items<'a, T> {} impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> { #[inline] - fn indexable(&self) -> uint { self.rindex - self.index } + fn indexable(&self) -> uint { + let (len, _) = self.size_hint(); + len + } #[inline] fn idx(&mut self, j: uint) -> Option<&'a T> { if j >= self.indexable() { None } else { - let raw_index = raw_index(self.lo, self.elts.len(), self.index + j); - Some(self.elts[raw_index].as_ref().unwrap()) + let idx = wrap_index(self.tail + j, self.ring.len()); + unsafe { Some(self.ring.unsafe_get(idx)) } } } } +// FIXME This was implemented differently from Items because of a problem +// with returning the mutable reference. I couldn't find a way to +// make the lifetime checker happy so, but there should be a way. /// `RingBuf` mutable iterator. pub struct MutItems<'a, T:'a> { - remaining1: slice::MutItems<'a, Option<T>>, - remaining2: slice::MutItems<'a, Option<T>>, - nelts: uint, + ptr: *mut T, + tail: uint, + head: uint, + cap: uint, + marker: marker::ContravariantLifetime<'a>, + marker2: marker::NoCopy } impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut T> { - if self.nelts == 0 { + if self.tail == self.head { return None; } - self.nelts -= 1; - match self.remaining1.next() { - Some(ptr) => return Some(ptr.as_mut().unwrap()), - None => {} - } - match self.remaining2.next() { - Some(ptr) => return Some(ptr.as_mut().unwrap()), - None => unreachable!(), + let tail = self.tail; + self.tail = wrap_index(self.tail + 1, self.cap); + if mem::size_of::<T>() != 0 { + unsafe { Some(&mut *self.ptr.offset(tail as int)) } + } else { + // use a non-zero pointer + Some(unsafe { mem::transmute(1u) }) } } #[inline] fn size_hint(&self) -> (uint, Option<uint>) { - (self.nelts, Some(self.nelts)) + let len = count(self.tail, self.head, self.cap); + (len, Some(len)) } } impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut T> { - if self.nelts == 0 { + if self.tail == self.head { return None; } - self.nelts -= 1; - match self.remaining2.next_back() { - Some(ptr) => return Some(ptr.as_mut().unwrap()), - None => {} - } - match self.remaining1.next_back() { - Some(ptr) => return Some(ptr.as_mut().unwrap()), - None => unreachable!(), - } + self.head = wrap_index(self.head - 1, self.cap); + unsafe { Some(&mut *self.ptr.offset(self.head as int)) } } } impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {} -/// Grow is only called on full elts, so nelts is also len(elts), unlike -/// elsewhere. -fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut Vec<Option<T>>) { - assert_eq!(nelts, elts.len()); - let lo = *loptr; - elts.reserve_exact(nelts); - let newlen = elts.capacity(); - - /* fill with None */ - for _ in range(elts.len(), newlen) { - elts.push(None); - } - - /* - Move the shortest half into the newly reserved area. - lo ---->| - nelts ----------->| - [o o o|o o o o o] - A [. . .|o o o o o o o o|. . . . .] - B [o o o|. . . . . . . .|o o o o o] - */ - - assert!(newlen - nelts/2 >= nelts); - if lo <= (nelts - lo) { // A - for i in range(0u, lo) { - elts.as_mut_slice().swap(i, nelts + i); - } - } else { // B - for i in range(lo, nelts) { - elts.as_mut_slice().swap(i, newlen - nelts + i); - } - *loptr += newlen - nelts; - } -} - -/// Returns the index in the underlying `Vec` for a given logical element index. -fn raw_index(lo: uint, len: uint, index: uint) -> uint { - if lo >= len - index { - lo + index - len - } else { - lo + index - } -} - impl<A: PartialEq> PartialEq for RingBuf<A> { fn eq(&self, other: &RingBuf<A>) -> bool { - self.nelts == other.nelts && + self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) } fn ne(&self, other: &RingBuf<A>) -> bool { @@ -707,22 +802,14 @@ impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> { impl<A> Index<uint, A> for RingBuf<A> { #[inline] fn index<'a>(&'a self, i: &uint) -> &'a A { - let idx = self.raw_index(*i); - match self.elts[idx] { - None => panic!(), - Some(ref v) => v, - } + self.get(*i).expect("Out of bounds access") } } impl<A> IndexMut<uint, A> for RingBuf<A> { #[inline] fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A { - let idx = self.raw_index(*i); - match *(&mut self.elts[idx]) { - None => panic!(), - Some(ref mut v) => v - } + self.get_mut(*i).expect("Out of bounds access") } } @@ -888,36 +975,99 @@ mod tests { #[bench] fn bench_new(b: &mut test::Bencher) { b.iter(|| { - let _: RingBuf<u64> = RingBuf::new(); + let ring: RingBuf<u64> = RingBuf::new(); + test::black_box(ring); }) } #[bench] - fn bench_push_back(b: &mut test::Bencher) { - let mut deq = RingBuf::new(); + fn bench_push_back_100(b: &mut test::Bencher) { + let mut deq = RingBuf::with_capacity(101); b.iter(|| { - deq.push_back(0i); + for i in range(0i, 100) { + deq.push_back(i); + } + deq.head = 0; + deq.tail = 0; }) } #[bench] - fn bench_push_front(b: &mut test::Bencher) { - let mut deq = RingBuf::new(); + fn bench_push_front_100(b: &mut test::Bencher) { + let mut deq = RingBuf::with_capacity(101); b.iter(|| { - deq.push_front(0i); + for i in range(0i, 100) { + deq.push_front(i); + } + deq.head = 0; + deq.tail = 0; }) } #[bench] - fn bench_grow(b: &mut test::Bencher) { - let mut deq = RingBuf::new(); + fn bench_pop_back_100(b: &mut test::Bencher) { + let mut deq: RingBuf<int> = RingBuf::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_back()); + } + }) + } + + #[bench] + fn bench_pop_front_100(b: &mut test::Bencher) { + let mut deq: RingBuf<int> = RingBuf::with_capacity(101); + + b.iter(|| { + deq.head = 100; + deq.tail = 0; + while !deq.is_empty() { + test::black_box(deq.pop_front()); + } + }) + } + + #[bench] + fn bench_grow_1025(b: &mut test::Bencher) { + b.iter(|| { + let mut deq = RingBuf::new(); + for i in range(0i, 1025) { + deq.push_front(i); + } + test::black_box(deq); + }) + } + + #[bench] + fn bench_iter_1000(b: &mut test::Bencher) { + let ring: RingBuf<int> = range(0i, 1000).collect(); + b.iter(|| { - for _ in range(0i, 65) { - deq.push_front(1i); + let mut sum = 0; + for &i in ring.iter() { + sum += i; } + test::black_box(sum); }) } + #[bench] + fn bench_mut_iter_1000(b: &mut test::Bencher) { + let mut ring: RingBuf<int> = range(0i, 1000).collect(); + + b.iter(|| { + let mut sum = 0; + for i in ring.iter_mut() { + sum += *i; + } + test::black_box(sum); + }) + } + + #[deriving(Clone, PartialEq, Show)] enum Taggy { One(int), @@ -1034,11 +1184,11 @@ mod tests { let mut d = RingBuf::new(); d.push_back(0u64); d.reserve(50); - assert!(d.capacity() >= 64); + assert!(d.capacity() >= 51); let mut d = RingBuf::new(); d.push_back(0u32); d.reserve(50); - assert!(d.capacity() >= 64); + assert!(d.capacity() >= 51); } #[test] @@ -1257,4 +1407,169 @@ mod tests { .collect(); assert!(format!("{}", ringbuf).as_slice() == "[just, one, test, more]"); } + + #[test] + fn test_drop() { + static mut drops: uint = 0; + struct Elem; + impl Drop for Elem { + fn drop(&mut self) { + unsafe { drops += 1; } + } + } + + let mut ring = RingBuf::new(); + ring.push_back(Elem); + ring.push_front(Elem); + ring.push_back(Elem); + ring.push_front(Elem); + drop(ring); + + assert_eq!(unsafe {drops}, 4); + } + + #[test] + fn test_drop_with_pop() { + static mut drops: uint = 0; + struct Elem; + impl Drop for Elem { + fn drop(&mut self) { + unsafe { drops += 1; } + } + } + + let mut ring = RingBuf::new(); + ring.push_back(Elem); + ring.push_front(Elem); + ring.push_back(Elem); + ring.push_front(Elem); + + drop(ring.pop_back()); + drop(ring.pop_front()); + assert_eq!(unsafe {drops}, 2); + + drop(ring); + assert_eq!(unsafe {drops}, 4); + } + + #[test] + fn test_drop_clear() { + static mut drops: uint = 0; + struct Elem; + impl Drop for Elem { + fn drop(&mut self) { + unsafe { drops += 1; } + } + } + + let mut ring = RingBuf::new(); + ring.push_back(Elem); + ring.push_front(Elem); + ring.push_back(Elem); + ring.push_front(Elem); + ring.clear(); + assert_eq!(unsafe {drops}, 4); + + drop(ring); + assert_eq!(unsafe {drops}, 4); + } + + #[test] + fn test_reserve_grow() { + // test growth path A + // [T o o H] -> [T o o H . . . . ] + let mut ring = RingBuf::with_capacity(4); + for i in range(0i, 3) { + ring.push_back(i); + } + ring.reserve(7); + for i in range(0i, 3) { + assert_eq!(ring.pop_front(), Some(i)); + } + + // test growth path B + // [H T o o] -> [. T o o H . . . ] + let mut ring = RingBuf::with_capacity(4); + for i in range(0i, 1) { + ring.push_back(i); + assert_eq!(ring.pop_front(), Some(i)); + } + for i in range(0i, 3) { + ring.push_back(i); + } + ring.reserve(7); + for i in range(0i, 3) { + assert_eq!(ring.pop_front(), Some(i)); + } + + // test growth path C + // [o o H T] -> [o o H . . . . T ] + let mut ring = RingBuf::with_capacity(4); + for i in range(0i, 3) { + ring.push_back(i); + assert_eq!(ring.pop_front(), Some(i)); + } + for i in range(0i, 3) { + ring.push_back(i); + } + ring.reserve(7); + for i in range(0i, 3) { + assert_eq!(ring.pop_front(), Some(i)); + } + } + + #[test] + fn test_get() { + let mut ring = RingBuf::new(); + ring.push_back(0i); + assert_eq!(ring.get(0), Some(&0)); + assert_eq!(ring.get(1), None); + + ring.push_back(1); + assert_eq!(ring.get(0), Some(&0)); + assert_eq!(ring.get(1), Some(&1)); + assert_eq!(ring.get(2), None); + + ring.push_back(2); + assert_eq!(ring.get(0), Some(&0)); + assert_eq!(ring.get(1), Some(&1)); + assert_eq!(ring.get(2), Some(&2)); + assert_eq!(ring.get(3), None); + + assert_eq!(ring.pop_front(), Some(0)); + assert_eq!(ring.get(0), Some(&1)); + assert_eq!(ring.get(1), Some(&2)); + assert_eq!(ring.get(2), None); + + assert_eq!(ring.pop_front(), Some(1)); + assert_eq!(ring.get(0), Some(&2)); + assert_eq!(ring.get(1), None); + + assert_eq!(ring.pop_front(), Some(2)); + assert_eq!(ring.get(0), None); + assert_eq!(ring.get(1), None); + } + + #[test] + fn test_get_mut() { + let mut ring = RingBuf::new(); + for i in range(0i, 3) { + ring.push_back(i); + } + + match ring.get_mut(1) { + Some(x) => *x = -1, + None => () + }; + + assert_eq!(ring.get_mut(0), Some(&mut 0)); + assert_eq!(ring.get_mut(1), Some(&mut -1)); + assert_eq!(ring.get_mut(2), Some(&mut 2)); + assert_eq!(ring.get_mut(3), None); + + assert_eq!(ring.pop_front(), Some(0)); + assert_eq!(ring.get_mut(0), Some(&mut -1)); + assert_eq!(ring.get_mut(1), Some(&mut 2)); + assert_eq!(ring.get_mut(2), None); + } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 5ae1060dd29..f05a681a526 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -236,7 +236,10 @@ impl<T> Option<T> { #[inline] #[stable] pub fn as_ref<'r>(&'r self) -> Option<&'r T> { - match *self { Some(ref x) => Some(x), None => None } + match *self { + Some(ref x) => Some(x), + None => None + } } /// Convert from `Option<T>` to `Option<&mut T>` @@ -254,7 +257,10 @@ impl<T> Option<T> { #[inline] #[unstable = "waiting for mut conventions"] pub fn as_mut<'r>(&'r mut self) -> Option<&'r mut T> { - match *self { Some(ref mut x) => Some(x), None => None } + match *self { + Some(ref mut x) => Some(x), + None => None + } } /// Convert from `Option<T>` to `&mut [T]` (without copying) @@ -402,7 +408,10 @@ impl<T> Option<T> { #[inline] #[unstable = "waiting for unboxed closures"] pub fn map<U>(self, f: |T| -> U) -> Option<U> { - match self { Some(x) => Some(f(x)), None => None } + match self { + Some(x) => Some(f(x)), + None => None + } } /// Applies a function to the contained value or returns a default. @@ -419,7 +428,10 @@ impl<T> Option<T> { #[inline] #[unstable = "waiting for unboxed closures"] pub fn map_or<U>(self, def: U, f: |T| -> U) -> U { - match self { None => def, Some(t) => f(t) } + match self { + Some(t) => f(t), + None => def + } } /// Applies a function to the contained value or computes a default. @@ -438,7 +450,10 @@ impl<T> Option<T> { #[inline] #[unstable = "waiting for unboxed closures"] pub fn map_or_else<U>(self, def: || -> U, f: |T| -> U) -> U { - match self { None => def(), Some(t) => f(t) } + match self { + Some(t) => f(t), + None => def() + } } /// Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index d5e9c1ef99f..1792599783b 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -66,7 +66,6 @@ register_diagnostics!( E0055, E0056, E0057, - E0058, E0059, E0060, E0061, diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c2bb702d5c0..ac2f6dd9d37 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -447,7 +447,9 @@ impl LintPass for ImproperCTypes { for input in decl.inputs.iter() { check_ty(cx, &*input.ty); } - check_ty(cx, &*decl.output) + if let ast::Return(ref ret_ty) = decl.output { + check_ty(cx, &**ret_ty); + } } match it.node { @@ -735,7 +737,8 @@ impl LintPass for UnusedResults { let t = ty::expr_ty(cx.tcx, expr); let mut warned = false; match ty::get(t).sty { - ty::ty_nil | ty::ty_bool => return, + ty::ty_tup(ref tys) if tys.is_empty() => return, + ty::ty_bool => return, ty::ty_struct(did, _) | ty::ty_enum(did, _) => { if ast_util::is_local(did) { @@ -1399,6 +1402,9 @@ pub struct MissingDoc { /// Stack of IDs of struct definitions. struct_def_stack: Vec<ast::NodeId>, + /// True if inside variant definition + in_variant: bool, + /// Stack of whether #[doc(hidden)] is set /// at each level which has lint attributes. doc_hidden_stack: Vec<bool>, @@ -1408,6 +1414,7 @@ impl MissingDoc { pub fn new() -> MissingDoc { MissingDoc { struct_def_stack: vec!(), + in_variant: false, doc_hidden_stack: vec!(false), } } @@ -1522,7 +1529,7 @@ impl LintPass for MissingDoc { fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) { match sf.node.kind { - ast::NamedField(_, vis) if vis == ast::Public => { + ast::NamedField(_, vis) if vis == ast::Public || self.in_variant => { let cur_struct_def = *self.struct_def_stack.last() .expect("empty struct_def_stack"); self.check_missing_docs_attrs(cx, Some(cur_struct_def), @@ -1536,6 +1543,13 @@ impl LintPass for MissingDoc { fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) { self.check_missing_docs_attrs(cx, Some(v.node.id), v.node.attrs.as_slice(), v.span, "a variant"); + assert!(!self.in_variant); + self.in_variant = true; + } + + fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) { + assert!(self.in_variant); + self.in_variant = false; } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 7f8b779dac1..917f05365ec 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -665,6 +665,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { self.with_lint_attrs(v.node.attrs.as_slice(), |cx| { run_lints!(cx, check_variant, v, g); visit::walk_variant(cx, v, g); + run_lints!(cx, check_variant_post, v, g); }) } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 0202aa18558..3ea4c9c720c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -149,6 +149,7 @@ pub trait LintPass { _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } fn check_struct_field(&mut self, _: &Context, _: &ast::StructField) { } fn check_variant(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) { } + fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) { } fn check_opt_lifetime_ref(&mut self, _: &Context, _: Span, _: &Option<ast::Lifetime>) { } fn check_lifetime_ref(&mut self, _: &Context, _: &ast::Lifetime) { } fn check_lifetime_decl(&mut self, _: &Context, _: &ast::LifetimeDef) { } diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 364cc298e8c..d660cc970e7 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -360,7 +360,6 @@ fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef { fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { match next(st) { - 'n' => return ty::mk_nil(), 'b' => return ty::mk_bool(), 'i' => return ty::mk_int(), 'u' => return ty::mk_uint(), diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 56e44b69a5f..3242d396146 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -199,7 +199,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore) fn enc_sty(w: &mut SeekableMemWriter, cx: &ctxt, st: &ty::sty) { match *st { - ty::ty_nil => mywrite!(w, "n"), ty::ty_bool => mywrite!(w, "b"), ty::ty_char => mywrite!(w, "c"), ty::ty_int(t) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 74a438190fa..9e1e4552ee2 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::const_eval::{compare_const_vals, const_bool, const_float, const_nil, const_val}; +use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val}; use middle::const_eval::{const_expr_to_pat, eval_const_expr, lookup_const_by_id}; use middle::def::*; use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init}; @@ -332,7 +332,6 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) { fn const_val_to_expr(value: &const_val) -> P<Expr> { let node = match value { &const_bool(b) => LitBool(b), - &const_nil => LitNil, _ => unreachable!() }; P(Expr { @@ -497,9 +496,6 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: ty::t, ty::ty_bool => [true, false].iter().map(|b| ConstantValue(const_bool(*b))).collect(), - ty::ty_nil => - vec!(ConstantValue(const_nil)), - ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty { ty::ty_vec(_, None) => range_inclusive(0, max_slice_length).map(|length| Slice(length)).collect(), @@ -552,7 +548,7 @@ fn is_useful(cx: &MatchCheckCtxt, None => v[0] }; let left_ty = if real_pat.id == DUMMY_NODE_ID { - ty::mk_nil() + ty::mk_nil(cx.tcx) } else { ty::pat_ty(cx.tcx, &*real_pat) }; diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 1a3267492d2..a626a028e2e 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -311,8 +311,7 @@ pub enum const_val { const_uint(u64), const_str(InternedString), const_binary(Rc<Vec<u8> >), - const_bool(bool), - const_nil + const_bool(bool) } pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<Pat> { @@ -589,7 +588,6 @@ pub fn lit_to_const(lit: &Lit) -> const_val { LitFloatUnsuffixed(ref n) => { const_float(from_str::<f64>(n.get()).unwrap() as f64) } - LitNil => const_nil, LitBool(b) => const_bool(b) } } @@ -605,7 +603,6 @@ pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> { (&const_str(ref a), &const_str(ref b)) => compare_vals(a, b), (&const_bool(a), &const_bool(b)) => compare_vals(a, b), (&const_binary(ref a), &const_binary(ref b)) => compare_vals(a, b), - (&const_nil, &const_nil) => compare_vals((), ()), _ => None } } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index e9884d0376d..d3b70afe39b 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -1239,6 +1239,7 @@ struct VisiblePrivateTypesVisitor<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, exported_items: &'a ExportedItems, public_items: &'a PublicItems, + in_variant: bool, } struct CheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> { @@ -1514,13 +1515,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) { if self.exported_items.contains(&v.node.id) { + self.in_variant = true; visit::walk_variant(self, v, g); + self.in_variant = false; } } fn visit_struct_field(&mut self, s: &ast::StructField) { match s.node.kind { - ast::NamedField(_, ast::Public) => { + ast::NamedField(_, vis) if vis == ast::Public || self.in_variant => { visit::walk_struct_field(self, s); } _ => {} @@ -1598,7 +1601,8 @@ pub fn check_crate(tcx: &ty::ctxt, let mut visitor = VisiblePrivateTypesVisitor { tcx: tcx, exported_items: &exported_items, - public_items: &public_items + public_items: &public_items, + in_variant: false, }; visit::walk_crate(&mut visitor, krate); } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index e4a6b14767f..fd62d0cdc11 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -102,10 +102,10 @@ pub enum LastPrivate { // and whether the import is in fact used for each. // If the Option<PrivateDep> fields are None, it means there is no definition // in that namespace. - LastImport{pub value_priv: Option<PrivateDep>, - pub value_used: ImportUse, - pub type_priv: Option<PrivateDep>, - pub type_used: ImportUse}, + LastImport{value_priv: Option<PrivateDep>, + value_used: ImportUse, + type_priv: Option<PrivateDep>, + type_used: ImportUse}, } #[deriving(Show)] @@ -4285,7 +4285,9 @@ impl<'a> Resolver<'a> { _ => {} } - this.resolve_type(&*ty_m.decl.output); + if let ast::Return(ref ret_ty) = ty_m.decl.output { + this.resolve_type(&**ret_ty); + } }); } ast::ProvidedMethod(ref m) => { @@ -4467,7 +4469,9 @@ impl<'a> Resolver<'a> { debug!("(resolving function) recorded argument"); } - this.resolve_type(&*declaration.output); + if let ast::Return(ref ret_ty) = declaration.output { + this.resolve_type(&**ret_ty); + } } } diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index 59fbcde85e8..367fe2845dd 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -383,7 +383,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { for arg in method.pe_fn_decl().inputs.iter() { self.visit_ty(&*arg.ty); } - self.visit_ty(&*method.pe_fn_decl().output); + + if let ast::Return(ref ret_ty) = method.pe_fn_decl().output { + self.visit_ty(&**ret_ty); + } + // walk the fn body self.nest(method.id, |v| v.visit_block(&*method.pe_body())); @@ -491,7 +495,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { for arg in decl.inputs.iter() { self.visit_ty(&*arg.ty); } - self.visit_ty(&*decl.output); + + if let ast::Return(ref ret_ty) = decl.output { + self.visit_ty(&**ret_ty); + } // walk the body self.nest(item.id, |v| v.visit_block(&*body)); @@ -1136,7 +1143,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { for arg in method_type.decl.inputs.iter() { self.visit_ty(&*arg.ty); } - self.visit_ty(&*method_type.decl.output); + + if let ast::Return(ref ret_ty) = method_type.decl.output { + self.visit_ty(&**ret_ty); + } self.process_generic_params(&method_type.generics, method_type.span, @@ -1352,7 +1362,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { for arg in decl.inputs.iter() { self.visit_ty(&*arg.ty); } - self.visit_ty(&*decl.output); + + if let ast::Return(ref ret_ty) = decl.output { + self.visit_ty(&**ret_ty); + } // walk the body self.nest(ex.id, |v| v.visit_block(&**body)); diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 9900620b229..be5a007c1eb 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -79,7 +79,6 @@ pub fn ty_is_local(tcx: &ty::ctxt, debug!("ty_is_local({})", ty.repr(tcx)); match ty::get(ty).sty { - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_int(..) | diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ce8ba7c14d3..b50956ec9db 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1227,7 +1227,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ty_infer(ty::FloatVar(_)) | ty::ty_uint(_) | ty::ty_int(_) | - ty::ty_nil | ty::ty_bool | ty::ty_float(_) | ty::ty_bare_fn(_) | diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 46a72ae8dc0..7035df542c0 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1012,7 +1012,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, .unwrap_or(DUMMY_NODE_ID); let left_ty = if pat_id == DUMMY_NODE_ID { - ty::mk_nil() + ty::mk_nil(tcx) } else { node_id_type(bcx, pat_id) }; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 0d3a84eb8bc..19209a3b8e6 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -101,9 +101,9 @@ pub enum Repr { * otherwise it indicates the other case. */ RawNullablePointer { - pub nndiscr: Disr, - pub nnty: ty::t, - pub nullfields: Vec<ty::t> + nndiscr: Disr, + nnty: ty::t, + nullfields: Vec<ty::t> }, /** * Two cases distinguished by a nullable pointer: the case with discriminant @@ -117,10 +117,10 @@ pub enum Repr { * identity function. */ StructWrappedNullablePointer { - pub nonnull: Struct, - pub nndiscr: Disr, - pub ptrfield: PointerField, - pub nullfields: Vec<ty::t>, + nonnull: Struct, + nndiscr: Disr, + ptrfield: PointerField, + nullfields: Vec<ty::t>, } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d79d703336f..86fe3e7a641 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -47,7 +47,7 @@ use middle::trans::builder::{Builder, noname}; use middle::trans::callee; use middle::trans::cleanup::{CleanupMethods, ScopeId}; use middle::trans::cleanup; -use middle::trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral, C_nil}; +use middle::trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral}; use middle::trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_uint, C_undef}; use middle::trans::common::{CrateContext, ExternMap, FunctionContext}; use middle::trans::common::{NodeInfo, Result, SubstP}; @@ -517,7 +517,7 @@ pub fn get_res_dtor(ccx: &CrateContext, let class_ty = ty::lookup_item_type(tcx, parent_id).ty.subst(tcx, substs); let llty = type_of_dtor(ccx, class_ty); let dtor_ty = ty::mk_ctor_fn(ccx.tcx(), ast::DUMMY_NODE_ID, - [glue::get_drop_glue_type(ccx, t)], ty::mk_nil()); + [glue::get_drop_glue_type(ccx, t)], ty::mk_nil(ccx.tcx())); get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), name.as_slice(), @@ -551,7 +551,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>, let f = |a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op)); match ty::get(t).sty { - ty::ty_nil => f(nil_type), + ty::ty_tup(ref tys) if tys.is_empty() => f(nil_type), ty::ty_bool | ty::ty_uint(_) | ty::ty_char => f(unsigned_int), ty::ty_ptr(mt) if ty::type_is_sized(cx.tcx(), mt.ty) => f(unsigned_int), ty::ty_int(_) => f(signed_int), @@ -1578,12 +1578,6 @@ fn create_datums_for_fn_args_under_call_abi( "argtuple")); result.push(tuple); } - ty::ty_nil => { - let mode = datum::Rvalue::new(datum::ByValue); - result.push(datum::Datum::new(C_nil(bcx.ccx()), - ty::mk_nil(), - mode)) - } _ => { bcx.tcx().sess.bug("last argument of a function with \ `rust-call` ABI isn't a tuple?!") @@ -1647,10 +1641,8 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>( arg_datum.to_lvalue_datum_in_scope(bcx, "argtuple", arg_scope_id)); - let empty = Vec::new(); let untupled_arg_types = match ty::get(monomorphized_arg_types[0]).sty { ty::ty_tup(ref types) => types.as_slice(), - ty::ty_nil => empty.as_slice(), _ => { bcx.tcx().sess.span_bug(args[0].pat.span, "first arg to `rust-call` ABI function \ @@ -1824,7 +1816,7 @@ pub fn trans_closure(ccx: &CrateContext, NotUnboxedClosure => monomorphized_arg_types, // Tuple up closure argument types for the "rust-call" ABI. - IsUnboxedClosure => vec![ty::mk_tup_or_nil(ccx.tcx(), monomorphized_arg_types)] + IsUnboxedClosure => vec![ty::mk_tup(ccx.tcx(), monomorphized_arg_types)] }; for monomorphized_arg_type in monomorphized_arg_types.iter() { debug!("trans_closure: monomorphized_arg_type: {}", @@ -2380,7 +2372,6 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) assert!(abi == RustCall); match ty::get(fn_sig.inputs[0]).sty { - ty::ty_nil => Vec::new(), ty::ty_tup(ref inputs) => inputs.clone(), _ => ccx.sess().bug("expected tuple'd inputs") } @@ -2389,7 +2380,6 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t) let mut inputs = vec![fn_sig.inputs[0]]; match ty::get(fn_sig.inputs[1]).sty { - ty::ty_nil => inputs, ty::ty_tup(ref t_in) => { inputs.push_all(t_in.as_slice()); inputs @@ -2532,7 +2522,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, llfty: Type) -> ValueRef { debug!("register_fn_llvmty id={} sym={}", node_id, sym); - let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::FnConverging(ty::mk_nil())); + let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::FnConverging(ty::mk_nil(ccx.tcx()))); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -2564,7 +2554,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, let llfty = Type::func([ccx.int_type(), Type::i8p(ccx).ptr_to()], &ccx.int_type()); - let llfn = decl_cdecl_fn(ccx, "main", llfty, ty::mk_nil()); + let llfn = decl_cdecl_fn(ccx, "main", llfty, ty::mk_nil(ccx.tcx())); // FIXME: #16581: Marking a symbol in the executable with `dllexport` // linkage forces MinGW's linker to output a `.reloc` section for ASLR diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 7a040196ea8..f62159cd490 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -764,7 +764,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr::Ignore => { let ret_ty = match ret_ty { ty::FnConverging(ret_ty) => ret_ty, - ty::FnDiverging => ty::mk_nil() + ty::FnDiverging => ty::mk_nil(ccx.tcx()) }; if !is_rust_fn || type_of::return_uses_outptr(ccx, ret_ty) || @@ -957,7 +957,6 @@ fn trans_args_under_call_abi<'blk, 'tcx>( llargs.push(arg_datum.add_clean(bcx.fcx, arg_cleanup_scope)); } } - ty::ty_nil => {} _ => { bcx.sess().span_bug(tuple_expr.span, "argument to `.call()` wasn't a tuple?!") @@ -1004,7 +1003,6 @@ fn trans_overloaded_call_args<'blk, 'tcx>( })) } } - ty::ty_nil => {} _ => { bcx.sess().span_bug(arg_exprs[0].span, "argument to `.call()` wasn't a tuple?!") diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 6c8ae8b45ff..1cdd681c8bc 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -81,7 +81,6 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) } } ast::LitBool(b) => C_bool(cx, b), - ast::LitNil => C_nil(cx), ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()), ast::LitBinary(ref data) => C_binary_slice(cx, data.as_slice()), } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index aa3d9ae83fa..85700efec71 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -718,7 +718,9 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef macro_rules! ifn ( ($name:expr fn() -> $ret:expr) => ( if *key == $name { - let f = base::decl_cdecl_fn(ccx, $name, Type::func([], &$ret), ty::mk_nil()); + let f = base::decl_cdecl_fn( + ccx, $name, Type::func([], &$ret), + ty::mk_nil(ccx.tcx())); ccx.intrinsics().borrow_mut().insert($name, f.clone()); return Some(f); } @@ -726,7 +728,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef ($name:expr fn($($arg:expr),*) -> $ret:expr) => ( if *key == $name { let f = base::decl_cdecl_fn(ccx, $name, - Type::func([$($arg),*], &$ret), ty::mk_nil()); + Type::func([$($arg),*], &$ret), ty::mk_nil(ccx.tcx())); ccx.intrinsics().borrow_mut().insert($name, f.clone()); return Some(f); } @@ -863,7 +865,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef } else if *key == $name { let f = base::decl_cdecl_fn(ccx, stringify!($cname), Type::func([$($arg),*], &$ret), - ty::mk_nil()); + ty::mk_nil(ccx.tcx())); ccx.intrinsics().borrow_mut().insert($name, f.clone()); return Some(f); } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ebf05f51e73..6e909e6532e 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -350,7 +350,6 @@ impl TypeMap { unique_type_id.push('{'); match ty::get(type_).sty { - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_str | @@ -367,6 +366,9 @@ impl TypeMap { unique_type_id.push_str("struct "); from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id); }, + ty::ty_tup(ref component_types) if component_types.is_empty() => { + push_debuginfo_type_name(cx, type_, false, &mut unique_type_id); + }, ty::ty_tup(ref component_types) => { unique_type_id.push_str("tuple "); for &component_type in component_types.iter() { @@ -1372,10 +1374,9 @@ pub fn create_function_debug_context(cx: &CrateContext, let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1); // Return type -- llvm::DIBuilder wants this at index 0 - match fn_decl.output.node { - ast::TyNil => { - signature.push(ptr::null_mut()); - } + match fn_decl.output { + ast::Return(ref ret_ty) if ret_ty.node == ast::TyTup(vec![]) => + signature.push(ptr::null_mut()), _ => { assert_type_for_node_id(cx, fn_ast_id, error_reporting_span); @@ -1736,7 +1737,8 @@ fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType { debug!("basic_type_metadata: {}", ty::get(t)); let (name, encoding) = match ty::get(t).sty { - ty::ty_nil => ("()".to_string(), DW_ATE_unsigned), + ty::ty_tup(ref elements) if elements.is_empty() => + ("()".to_string(), DW_ATE_unsigned), ty::ty_bool => ("bool".to_string(), DW_ATE_boolean), ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char), ty::ty_int(int_ty) => match int_ty { @@ -2773,7 +2775,7 @@ fn subroutine_type_metadata(cx: &CrateContext, // return type signature_metadata.push(match signature.output { ty::FnConverging(ret_ty) => match ty::get(ret_ty).sty { - ty::ty_nil => ptr::null_mut(), + ty::ty_tup(ref tys) if tys.is_empty() => ptr::null_mut(), _ => type_metadata(cx, ret_ty, span) }, ty::FnDiverging => diverging_type_metadata(cx) @@ -2880,7 +2882,6 @@ fn type_metadata(cx: &CrateContext, let sty = &ty::get(t).sty; let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty { - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_int(_) | @@ -2888,6 +2889,9 @@ fn type_metadata(cx: &CrateContext, ty::ty_float(_) => { MetadataCreationResult::new(basic_type_metadata(cx, t), false) } + ty::ty_tup(ref elements) if elements.is_empty() => { + MetadataCreationResult::new(basic_type_metadata(cx, t), false) + } ty::ty_enum(def_id, _) => { prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx) } @@ -3669,9 +3673,8 @@ fn compute_debuginfo_type_name(cx: &CrateContext, fn push_debuginfo_type_name(cx: &CrateContext, t: ty::t, qualified: bool, - output:&mut String) { + output: &mut String) { match ty::get(t).sty { - ty::ty_nil => output.push_str("()"), ty::ty_bool => output.push_str("bool"), ty::ty_char => output.push_str("char"), ty::ty_str => output.push_str("str"), @@ -3698,8 +3701,10 @@ fn push_debuginfo_type_name(cx: &CrateContext, push_debuginfo_type_name(cx, component_type, true, output); output.push_str(", "); } - output.pop(); - output.pop(); + if !component_types.is_empty() { + output.pop(); + output.pop(); + } output.push(')'); }, ty::ty_uniq(inner_type) => { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index bed45a28691..0b03163a02b 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -520,7 +520,7 @@ pub fn decl_rust_fn_with_foreign_abi(ccx: &CrateContext, } _ => panic!("expected bare fn in decl_rust_fn_with_foreign_abi") }; - let llfn = base::decl_fn(ccx, name, cconv, llfn_ty, ty::FnConverging(ty::mk_nil())); + let llfn = base::decl_fn(ccx, name, cconv, llfn_ty, ty::FnConverging(ty::mk_nil(ccx.tcx()))); add_argument_attributes(&tys, llfn); debug!("decl_rust_fn_with_foreign_abi(llfn_ty={}, llfn={})", ccx.tn().type_to_string(llfn_ty), ccx.tn().val_to_string(llfn)); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0a44abb6780..f5db3d41812 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -159,7 +159,7 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef { let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) { Some(old_sym) => { - let glue = decl_cdecl_fn(ccx, old_sym.as_slice(), llfnty, ty::mk_nil()); + let glue = decl_cdecl_fn(ccx, old_sym.as_slice(), llfnty, ty::mk_nil(ccx.tcx())); (glue, None) }, None => { @@ -288,7 +288,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } let dtor_ty = ty::mk_ctor_fn(variant_cx.tcx(), ast::DUMMY_NODE_ID, - [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil()); + [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil(bcx.tcx())); let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None, false); variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope); @@ -520,7 +520,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, ccx, t, format!("glue_{}", name).as_slice()); - let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil()); + let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil(ccx.tcx())); note_unique_llvm_symbol(ccx, fn_nm.clone()); return (fn_nm, llfn); } @@ -538,10 +538,11 @@ fn make_generic_glue(ccx: &CrateContext, let arena = TypedArena::new(); let empty_param_substs = param_substs::empty(); - let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, ty::FnConverging(ty::mk_nil()), + let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, + ty::FnConverging(ty::mk_nil(ccx.tcx())), &empty_param_substs, None, &arena); - let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil())); + let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx()))); update_linkage(ccx, llfn, None, OriginalTranslation); @@ -556,7 +557,7 @@ fn make_generic_glue(ccx: &CrateContext, let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint); let bcx = helper(bcx, llrawptr0, t); - finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil())); + finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx()))); llfn } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 553e0b22d5c..4af4b397a6e 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -594,7 +594,6 @@ pub fn get_vtable(bcx: Block, new_inputs.push(element.subst(bcx.tcx(), substs)); } } - ty::ty_nil => {} _ => { bcx.tcx().sess.bug("get_vtable(): closure \ type wasn't a tuple") diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 092fe2d1fa9..c185a1ba539 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -83,7 +83,6 @@ pub fn untuple_arguments_if_necessary(ccx: &CrateContext, result.push(tupled_argument); } } - ty::ty_nil => {} _ => { ccx.tcx().sess.bug("argument to function with \"rust-call\" ABI \ is neither a tuple nor unit") @@ -186,7 +185,6 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { ppaux::ty_to_string(cx.tcx(), t)).as_slice()) } - ty::ty_nil => Type::nil(cx), ty::ty_bool => Type::bool(cx), ty::ty_char => Type::char(cx), ty::ty_int(t) => Type::int_from_ty(cx, t), @@ -211,6 +209,10 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type { Type::array(&llty, size) } + ty::ty_tup(ref tys) if tys.is_empty() => { + Type::nil(cx) + } + ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_unboxed_closure(..) => { let repr = adt::represent_type(cx, t); adt::sizing_type_of(cx, &*repr, false) @@ -298,7 +300,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { } let mut llty = match ty::get(t).sty { - ty::ty_nil => Type::nil(cx), ty::ty_bool => Type::bool(cx), ty::ty_char => Type::char(cx), ty::ty_int(t) => Type::int_from_ty(cx, t), @@ -365,6 +366,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { let fn_ty = type_of_fn_from_ty(cx, t).ptr_to(); Type::struct_(cx, [fn_ty, Type::i8p(cx)], false) } + ty::ty_tup(ref tys) if tys.is_empty() => Type::nil(cx), ty::ty_tup(..) => { let repr = adt::represent_type(cx, t); adt::type_of(cx, &*repr) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8ec5e381b92..059394dc832 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -906,7 +906,6 @@ mod primitives { ) ) - def_prim_ty!(TY_NIL, super::ty_nil) def_prim_ty!(TY_BOOL, super::ty_bool) def_prim_ty!(TY_CHAR, super::ty_char) def_prim_ty!(TY_INT, super::ty_int(ast::TyI)) @@ -932,7 +931,6 @@ mod primitives { // AST structure in libsyntax/ast.rs as well. #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum sty { - ty_nil, ty_bool, ty_char, ty_int(ast::IntTy), @@ -1557,7 +1555,6 @@ pub fn mk_ctxt<'tcx>(s: Session, pub fn mk_t(cx: &ctxt, st: sty) -> t { // Check for primitive types. match st { - ty_nil => return mk_nil(), ty_err => return mk_err(), ty_bool => return mk_bool(), ty_int(i) => return mk_mach_int(i), @@ -1603,7 +1600,7 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { rflags(bounds.region_bound) } match &st { - &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) | + &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) | &ty_str => {} // You might think that we could just return ty_err for // any type containing ty_err as a component, and get @@ -1690,9 +1687,6 @@ pub fn mk_prim_t(primitive: &'static t_box_) -> t { } #[inline] -pub fn mk_nil() -> t { mk_prim_t(&primitives::TY_NIL) } - -#[inline] pub fn mk_err() -> t { mk_prim_t(&primitives::TY_ERR) } #[inline] @@ -1803,7 +1797,7 @@ pub fn mk_imm_ptr(cx: &ctxt, ty: t) -> t { } pub fn mk_nil_ptr(cx: &ctxt) -> t { - mk_ptr(cx, mt {ty: mk_nil(), mutbl: ast::MutImmutable}) + mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable}) } pub fn mk_vec(cx: &ctxt, t: t, sz: Option<uint>) -> t { @@ -1818,14 +1812,12 @@ pub fn mk_slice(cx: &ctxt, r: Region, tm: mt) -> t { }) } -pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) } +pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { + mk_t(cx, ty_tup(ts)) +} -pub fn mk_tup_or_nil(cx: &ctxt, ts: Vec<t>) -> t { - if ts.len() == 0 { - ty::mk_nil() - } else { - mk_t(cx, ty_tup(ts)) - } +pub fn mk_nil(cx: &ctxt) -> t { + mk_tup(cx, Vec::new()) } pub fn mk_closure(cx: &ctxt, fty: ClosureTy) -> t { @@ -1908,7 +1900,7 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) { return; } match get(ty).sty { - ty_nil | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | + ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | ty_str | ty_infer(_) | ty_param(_) | ty_err => {} ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f), ty_ptr(ref tm) | ty_rptr(_, ref tm) => { @@ -1996,7 +1988,10 @@ impl ParamBounds { // Type utilities pub fn type_is_nil(ty: t) -> bool { - get(ty).sty == ty_nil + match get(ty).sty { + ty_tup(ref tys) => tys.is_empty(), + _ => false + } } pub fn type_is_error(ty: t) -> bool { @@ -2133,9 +2128,10 @@ pub fn type_is_fat_ptr(cx: &ctxt, ty: t) -> bool { */ pub fn type_is_scalar(ty: t) -> bool { match get(ty).sty { - ty_nil | ty_bool | ty_char | ty_int(_) | ty_float(_) | ty_uint(_) | + ty_bool | ty_char | ty_int(_) | ty_float(_) | ty_uint(_) | ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_bare_fn(..) | ty_ptr(_) => true, + ty_tup(ref tys) if tys.is_empty() => true, _ => false } } @@ -2170,7 +2166,7 @@ pub fn type_needs_unwind_cleanup(cx: &ctxt, ty: t) -> bool { let mut needs_unwind_cleanup = false; maybe_walk_ty(ty, |ty| { needs_unwind_cleanup |= match get(ty).sty { - ty_nil | ty_bool | ty_int(_) | ty_uint(_) | + ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_tup(_) | ty_ptr(_) => false, ty_enum(did, ref substs) => @@ -2429,7 +2425,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { // Scalar and unique types are sendable, and durable ty_infer(ty::SkolemizedIntTy(_)) | - ty_nil | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | + ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_bare_fn(_) | ty::ty_char => { TC::None } @@ -2740,7 +2736,6 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool { ty_vec(_, Some(0)) => false, // don't need no contents ty_vec(ty, Some(_)) => type_requires(cx, seen, r_ty, ty), - ty_nil | ty_bool | ty_char | ty_int(_) | @@ -3779,10 +3774,11 @@ pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem]) pub fn ty_sort_string(cx: &ctxt, t: t) -> String { match get(t).sty { - ty_nil | ty_bool | ty_char | ty_int(_) | + ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | ty_str => { ::util::ppaux::ty_to_string(cx, t) } + ty_tup(ref tys) if tys.is_empty() => ::util::ppaux::ty_to_string(cx, t), ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)), ty_uniq(_) => "box".to_string(), @@ -4777,54 +4773,42 @@ pub fn normalize_ty(cx: &ctxt, t: t) -> t { // Returns the repeat count for a repeating vector expression. pub fn eval_repeat_count(tcx: &ctxt, 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, found negative integer"); - 0 - } else { - count as uint - }, - const_eval::const_uint(count) => count as uint, - const_eval::const_float(count) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found float"); - count as uint - } - const_eval::const_str(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found string"); - 0 - } - const_eval::const_bool(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found boolean"); - 0 - } - const_eval::const_binary(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found binary array"); - 0 - } - const_eval::const_nil => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count, found ()"); - 0 - } - }, - Err(..) => { - tcx.sess.span_err(count_expr.span, - "expected constant integer for repeat count, \ - found variable"); - 0 - } + Ok(val) => { + let found = match val { + const_eval::const_uint(count) => return count as uint, + const_eval::const_int(count) if count >= 0 => return count as uint, + const_eval::const_int(_) => + "negative integer", + const_eval::const_float(_) => + "float", + const_eval::const_str(_) => + "string", + const_eval::const_bool(_) => + "boolean", + const_eval::const_binary(_) => + "binary array" + }; + tcx.sess.span_err(count_expr.span, format!( + "expected positive integer for repeat count, found {}", + found).as_slice()); + } + Err(_) => { + let found = match count_expr.node { + ast::ExprPath(ast::Path { + global: false, + ref segments, + .. + }) if segments.len() == 1 => + "variable", + _ => + "non-constant expression" + }; + tcx.sess.span_err(count_expr.span, format!( + "expected constant integer for repeat count, found {}", + found).as_slice()); + } } + 0 } // Iterate over a type parameter's bounded traits and any supertraits @@ -5141,7 +5125,6 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 { }; ty::walk_ty(t, |t| { match ty::get(t).sty { - ty_nil => byte!(0), ty_bool => byte!(2), ty_char => byte!(3), ty_int(i) => { @@ -5512,7 +5495,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>, accumulator.push(*region); accum_substs(accumulator, substs); } - ty_nil | ty_bool | ty_char | ty_int(_) | diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 031c7b2aed6..6d8d03aa0ab 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -554,7 +554,7 @@ pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, ty::ty_unboxed_closure(did, ref region, ref substs) => { ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this)) } - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_str | + ty::ty_bool | ty::ty_char | ty::ty_str | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | ty::ty_err | ty::ty_infer(_) | ty::ty_param(..) => { diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index ec289a2d806..8df4d59a292 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -385,11 +385,11 @@ fn ast_path_substs<'tcx,AC,RS>( let inputs = data.inputs.iter() .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t)) .collect(); - let input_ty = ty::mk_tup_or_nil(this.tcx(), inputs); + let input_ty = ty::mk_tup(this.tcx(), inputs); let output = match data.output { Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty), - None => ty::mk_nil() + None => ty::mk_nil(this.tcx()) }; (Vec::new(), vec![input_ty, output]) @@ -652,12 +652,6 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } } -#[deriving(Show)] -enum PointerTy { - RPtr(ty::Region), - Uniq -} - // Handle `~`, `Box`, and `&` being able to mean strs and vecs. // If a_seq_ty is a str or a vec, make it a str/vec. // Also handle first-class trait types. @@ -666,14 +660,14 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( rscope: &RS, a_seq_mutbl: ast::Mutability, a_seq_ty: &ast::Ty, - ptr_ty: PointerTy, + region: ty::Region, constr: |ty::t| -> ty::t) -> ty::t { let tcx = this.tcx(); - debug!("mk_pointer(ptr_ty={}, a_seq_ty={})", - ptr_ty, + debug!("mk_pointer(region={}, a_seq_ty={})", + region, a_seq_ty.repr(tcx)); match a_seq_ty.node { @@ -688,14 +682,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( match tcx.def_map.borrow().get(&id) { Some(&def::DefPrimTy(ast::TyStr)) => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); - match ptr_ty { - Uniq => { - return constr(ty::mk_str(tcx)); - } - RPtr(r) => { - return ty::mk_str_slice(tcx, r, a_seq_mutbl); - } - } + return ty::mk_str_slice(tcx, region, a_seq_mutbl); } Some(&def::DefTrait(trait_def_id)) => { let result = ast_path_to_trait_ref(this, @@ -716,14 +703,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( let tr = ty::mk_trait(tcx, result, existential_bounds); - return match ptr_ty { - Uniq => { - return ty::mk_uniq(tcx, tr); - } - RPtr(r) => { - return ty::mk_rptr(tcx, r, ty::mt{mutbl: a_seq_mutbl, ty: tr}); - } - }; + return ty::mk_rptr(tcx, region, ty::mt{mutbl: a_seq_mutbl, ty: tr}); } _ => {} } @@ -824,12 +804,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( let typ = ast_ty_to_builtin_ty(this, rscope, ast_ty).unwrap_or_else(|| { match ast_ty.node { - ast::TyNil => ty::mk_nil(), - ast::TyBot => unreachable!(), - ast::TyUniq(ref ty) => { - mk_pointer(this, rscope, ast::MutImmutable, &**ty, Uniq, - |ty| ty::mk_uniq(tcx, ty)) - } ast::TyVec(ref ty) => { ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None) } @@ -842,7 +816,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( ast::TyRptr(ref region, ref mt) => { let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region); debug!("ty_rptr r={}", r.repr(this.tcx())); - mk_pointer(this, rscope, mt.mutbl, &*mt.ty, RPtr(r), + mk_pointer(this, rscope, mt.mutbl, &*mt.ty, r, |ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl})) } ast::TyTup(ref fields) => { @@ -1208,22 +1182,24 @@ fn ty_of_method_or_bare_fn<'tcx, AC: AstConv<'tcx>>( .filter(|&(_, l)| l != 0) .collect(); - let output_ty = match decl.output.node { - ast::TyBot => ty::FnDiverging, - ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)), - _ => ty::FnConverging(match implied_output_region { - Some(implied_output_region) => { - let rb = SpecificRscope::new(implied_output_region); - ast_ty_to_ty(this, &rb, &*decl.output) - } - None => { - // All regions must be explicitly specified in the output - // if the lifetime elision rules do not apply. This saves - // the user from potentially-confusing errors. - let rb = UnelidableRscope::new(param_lifetimes); - ast_ty_to_ty(this, &rb, &*decl.output) - } - }) + let output_ty = match decl.output { + ast::Return(ref output) if output.node == ast::TyInfer => + ty::FnConverging(this.ty_infer(output.span)), + ast::Return(ref output) => + ty::FnConverging(match implied_output_region { + Some(implied_output_region) => { + let rb = SpecificRscope::new(implied_output_region); + ast_ty_to_ty(this, &rb, &**output) + } + None => { + // All regions must be explicitly specified in the output + // if the lifetime elision rules do not apply. This saves + // the user from potentially-confusing errors. + let rb = UnelidableRscope::new(param_lifetimes); + ast_ty_to_ty(this, &rb, &**output) + } + }), + ast::NoReturn(_) => ty::FnDiverging }; (ty::BareFnTy { @@ -1346,11 +1322,14 @@ pub fn ty_of_closure<'tcx, AC: AstConv<'tcx>>( let expected_ret_ty = expected_sig.map(|e| e.output); - let output_ty = match decl.output.node { - ast::TyBot => ty::FnDiverging, - ast::TyInfer if expected_ret_ty.is_some() => expected_ret_ty.unwrap(), - ast::TyInfer => ty::FnConverging(this.ty_infer(decl.output.span)), - _ => ty::FnConverging(ast_ty_to_ty(this, &rb, &*decl.output)) + let output_ty = match decl.output { + ast::Return(ref output) if output.node == ast::TyInfer && expected_ret_ty.is_some() => + expected_ret_ty.unwrap(), + ast::Return(ref output) if output.node == ast::TyInfer => + ty::FnConverging(this.ty_infer(output.span)), + ast::Return(ref output) => + ty::FnConverging(ast_ty_to_ty(this, &rb, &**output)), + ast::NoReturn(_) => ty::FnDiverging }; ty::ClosureTy { diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 6280fce035a..a35bc502813 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1214,7 +1214,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { ty_bare_fn(..) | ty_uniq(..) | ty_rptr(..) | ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | - ty_param(..) | ty_nil | ty_bool | + ty_param(..) | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | ty_enum(..) | ty_ptr(..) | ty_struct(..) | ty_unboxed_closure(..) | ty_tup(..) | ty_open(..) | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 0cf5069218e..d783286272c 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -556,7 +556,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, .collect(); if let ty::FnConverging(ret_ty) = ret_ty { - fcx.require_type_is_sized(ret_ty, decl.output.span, traits::ReturnType); + fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType); fn_sig_tys.push(ret_ty); } @@ -1569,7 +1569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn default_diverging_type_variables_to_nil(&self) { for (_, &ref ty) in self.inh.node_types.borrow_mut().iter_mut() { if self.infcx().type_var_diverges(self.infcx().resolve_type_vars_if_possible(*ty)) { - demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil()); + demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil(self.tcx())); } } } @@ -1741,7 +1741,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn write_nil(&self, node_id: ast::NodeId) { - self.write_ty(node_id, ty::mk_nil()); + self.write_ty(node_id, ty::mk_nil(self.tcx())); } pub fn write_error(&self, node_id: ast::NodeId) { self.write_ty(node_id, ty::mk_err()); @@ -2664,17 +2664,6 @@ fn check_argument_types<'a>(fcx: &FnCtxt, (*arg_types).clone() } } - ty::ty_nil => { - if args.len() != 0 { - span_err!(tcx.sess, sp, E0058, - "this function takes 0 parameters but {} parameter{} supplied", - args.len(), - if args.len() == 1 {" was"} else {"s were"}); - err_args(args.len()) - } else { - vec![] - } - } _ => { span_err!(tcx.sess, sp, E0059, "cannot use call notation; the first type parameter \ @@ -2865,7 +2854,6 @@ fn check_lit(fcx: &FnCtxt, opt_ty.unwrap_or_else( || ty::mk_float_var(tcx, fcx.infcx().next_float_var_id())) } - ast::LitNil => ty::mk_nil(), ast::LitBool(_) => ty::mk_bool() } } @@ -3179,7 +3167,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, infer::IfExpressionWithNoElse(sp), false, then_ty, - ty::mk_nil()) + ty::mk_nil(fcx.tcx())) } }; @@ -3480,7 +3468,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, // Tuple up the arguments and insert the resulting function type into // the `unboxed_closures` table. - fn_ty.sig.inputs = vec![ty::mk_tup_or_nil(fcx.tcx(), fn_ty.sig.inputs)]; + fn_ty.sig.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.inputs)]; let kind = match kind { ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind, @@ -4148,7 +4136,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, match *expr_opt { None => if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span), - result_type, ty::mk_nil()) { + result_type, ty::mk_nil(fcx.tcx())) { span_err!(tcx.sess, expr.span, E0069, "`return;` in function returning non-nil"); }, @@ -4743,7 +4731,7 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt) { ast::StmtExpr(ref expr, id) => { node_id = id; // Check with expected type of () - check_expr_has_type(fcx, &**expr, ty::mk_nil()); + check_expr_has_type(fcx, &**expr, ty::mk_nil(fcx.tcx())); let expr_ty = fcx.expr_ty(&**expr); saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty); saw_err = saw_err || ty::type_is_error(expr_ty); @@ -4769,12 +4757,12 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt) { } pub fn check_block_no_value(fcx: &FnCtxt, blk: &ast::Block) { - check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil())); + check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil(fcx.tcx()))); let blkty = fcx.node_ty(blk.id); if ty::type_is_error(blkty) { fcx.write_error(blk.id); } else { - let nilty = ty::mk_nil(); + let nilty = ty::mk_nil(fcx.tcx()); demand::suptype(fcx, blk.span, nilty, blkty); } } @@ -5497,7 +5485,7 @@ pub fn instantiate_path(fcx: &FnCtxt, data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect(); let tuple_ty = - ty::mk_tup_or_nil(fcx.tcx(), input_tys); + ty::mk_tup(fcx.tcx(), input_tys); if type_count >= 1 { substs.types.push(space, tuple_ty); @@ -5507,7 +5495,7 @@ pub fn instantiate_path(fcx: &FnCtxt, data.output.as_ref().map(|ty| fcx.to_ty(&**ty)); let output_ty = - output_ty.unwrap_or(ty::mk_nil()); + output_ty.unwrap_or(ty::mk_nil(fcx.tcx())); if type_count >= 2 { substs.types.push(space, output_ty); @@ -5727,7 +5715,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "load" => (1, vec!(ty::mk_imm_ptr(tcx, param(ccx, 0))), param(ccx, 0)), "store" => (1, vec!(ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0)), - ty::mk_nil()), + ty::mk_nil(tcx)), "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" | "umin" => { @@ -5735,7 +5723,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { param(ccx, 0)) } "fence" => { - (0, Vec::new(), ty::mk_nil()) + (0, Vec::new(), ty::mk_nil(tcx)) } op => { span_err!(tcx.sess, it.span, E0092, @@ -5748,12 +5736,12 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { (0, Vec::new(), ty::FnDiverging) } else { let (n_tps, inputs, output) = match name.get() { - "breakpoint" => (0, Vec::new(), ty::mk_nil()), + "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)), "size_of" | "pref_align_of" | "min_align_of" => (1u, Vec::new(), ty::mk_uint()), "init" => (1u, Vec::new(), param(ccx, 0u)), "uninit" => (1u, Vec::new(), param(ccx, 0u)), - "forget" => (1u, vec!( param(ccx, 0) ), ty::mk_nil()), + "forget" => (1u, vec!( param(ccx, 0) ), ty::mk_nil(tcx)), "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)), "move_val_init" => { (1u, @@ -5761,7 +5749,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { ty::mk_mut_rptr(tcx, ty::ReLateBound(it.id, ty::BrAnon(0)), param(ccx, 0)), param(ccx, 0u) ), - ty::mk_nil()) + ty::mk_nil(tcx)) } "needs_drop" => (1u, Vec::new(), ty::mk_bool()), "owns_managed" => (1u, Vec::new(), ty::mk_bool()), @@ -5817,7 +5805,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { }), ty::mk_uint() ), - ty::mk_nil()) + ty::mk_nil(tcx)) } "set_memory" | "volatile_set_memory" => { (1, @@ -5829,7 +5817,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { ty::mk_u8(), ty::mk_uint() ), - ty::mk_nil()) + ty::mk_nil(tcx)) } "sqrtf32" => (0, vec!( ty::mk_f32() ), ty::mk_f32()), "sqrtf64" => (0, vec!( ty::mk_f64() ), ty::mk_f64()), @@ -5912,7 +5900,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "volatile_load" => (1, vec!( ty::mk_imm_ptr(tcx, param(ccx, 0)) ), param(ccx, 0)), "volatile_store" => - (1, vec!( ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0) ), ty::mk_nil()), + (1, vec!( ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0) ), ty::mk_nil(tcx)), "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" => (0, vec!(ty::mk_i8(), ty::mk_i8()), @@ -5948,7 +5936,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "return_address" => (0, vec![], ty::mk_imm_ptr(tcx, ty::mk_u8())), - "assume" => (0, vec![ty::mk_bool()], ty::mk_nil()), + "assume" => (0, vec![ty::mk_bool()], ty::mk_nil(tcx)), ref other => { span_err!(tcx.sess, it.span, E0093, diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 0856c86946b..032b31b1f38 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -91,7 +91,6 @@ impl<'a, 'tcx> Wf<'a, 'tcx> { ty.repr(self.tcx)); match ty::get(ty).sty { - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_int(..) | diff --git a/src/librustc/middle/typeck/coherence/mod.rs b/src/librustc/middle/typeck/coherence/mod.rs index 9e4728195b6..574b04c9e99 100644 --- a/src/librustc/middle/typeck/coherence/mod.rs +++ b/src/librustc/middle/typeck/coherence/mod.rs @@ -24,7 +24,7 @@ use middle::ty::get; use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId}; use middle::ty::{TypeTraitItemId, lookup_item_type}; use middle::ty::{t, ty_bool, ty_char, ty_enum, ty_err}; -use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil, ty_open}; +use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open}; use middle::ty::{ty_param, Polytype, ty_ptr}; use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup}; use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn}; @@ -82,7 +82,7 @@ fn get_base_type(inference_context: &InferCtxt, Some(resolved_type) } - ty_nil | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | + ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) | ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) | ty_infer(..) | ty_param(..) | ty_err | ty_open(..) | ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 6685bb9be77..eed574a1a1d 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -2096,9 +2096,11 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt, .map(|a| ty_of_arg(ccx, &rb, a, None)) .collect(); - let output = match decl.output.node { - ast::TyBot => ty::FnDiverging, - _ => ty::FnConverging(ast_ty_to_ty(ccx, &rb, &*decl.output)) + let output = match decl.output { + ast::Return(ref ty) => + ty::FnConverging(ast_ty_to_ty(ccx, &rb, &**ty)), + ast::NoReturn(_) => + ty::FnDiverging }; let t_fn = ty::mk_bare_fn( diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index 83d90274fd3..078a2c10bcb 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -433,7 +433,6 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t } (&ty::ty_char, _) | - (&ty::ty_nil, _) | (&ty::ty_bool, _) | (&ty::ty_int(_), _) | (&ty::ty_uint(_), _) | @@ -540,9 +539,11 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, a: ty::t, b: ty::t) -> cres<t .map(|(a, b)| this.tys(*a, *b)) .collect::<Result<_, _>>() .map(|ts| ty::mk_tup(tcx, ts)) - } else { + } else if as_.len() != 0 && bs.len() != 0 { Err(ty::terr_tuple_size( expected_found(this, as_.len(), bs.len()))) + } else { + Err(ty::terr_sorts(expected_found(this, a, b))) } } diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 80b4948f6fb..e12019a1530 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -973,8 +973,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { &anon_nums, ®ion_names); inputs = self.rebuild_args_ty(inputs.as_slice(), lifetime, &anon_nums, ®ion_names); - output = self.rebuild_arg_ty_or_output(&*output, lifetime, - &anon_nums, ®ion_names); + output = self.rebuild_output(&output, lifetime, &anon_nums, ®ion_names); ty_params = self.rebuild_ty_params(ty_params, lifetime, ®ion_names); } @@ -989,7 +988,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { let new_fn_decl = ast::FnDecl { inputs: inputs, output: output, - cf: self.fn_decl.cf, variadic: self.fn_decl.variadic }; (new_fn_decl, expl_self_opt, generics) @@ -1206,6 +1204,18 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { new_inputs } + fn rebuild_output(&self, ty: &ast::FunctionRetTy, + lifetime: ast::Lifetime, + anon_nums: &HashSet<uint>, + region_names: &HashSet<ast::Name>) -> ast::FunctionRetTy { + match *ty { + ast::Return(ref ret_ty) => ast::Return( + self.rebuild_arg_ty_or_output(&**ret_ty, lifetime, anon_nums, region_names) + ), + ast::NoReturn(span) => ast::NoReturn(span) + } + } + fn rebuild_arg_ty_or_output(&self, ty: &ast::Ty, lifetime: ast::Lifetime, @@ -1301,7 +1311,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { ty_queue.push(&*mut_ty.ty); } ast::TyVec(ref ty) | - ast::TyUniq(ref ty) | ast::TyFixedLengthVec(ref ty, _) => { ty_queue.push(&**ty); } @@ -1338,7 +1347,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { }) } ast::TyVec(ty) => ast::TyVec(build_to(ty, to)), - ast::TyUniq(ty) => ast::TyUniq(build_to(ty, to)), ast::TyFixedLengthVec(ty, e) => { ast::TyFixedLengthVec(build_to(ty, to), e) } diff --git a/src/librustc/middle/typeck/infer/skolemize.rs b/src/librustc/middle/typeck/infer/skolemize.rs index 6e5e8d72839..9458960156e 100644 --- a/src/librustc/middle/typeck/infer/skolemize.rs +++ b/src/librustc/middle/typeck/infer/skolemize.rs @@ -148,7 +148,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeSkolemizer<'a, 'tcx> { self.tcx().sess.bug("Cannot skolemize an open existential type"); } - ty::ty_nil | ty::ty_bool | ty::ty_char | ty::ty_int(..) | diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index f348e6155a2..2c8d1ce3f4f 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -382,7 +382,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, sig: ty::FnSig { binder_id: main_id, inputs: Vec::new(), - output: ty::FnConverging(ty::mk_nil()), + output: ty::FnConverging(ty::mk_nil(tcx)), variadic: false } }); diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 3a2dc1d5ff0..97d7f9f1863 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -728,7 +728,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx())); match ty::get(ty).sty { - ty::ty_nil | ty::ty_bool | + ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | ty::ty_str => { /* leaf type -- noop */ diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 60a7436dbaa..bcd70510edd 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -19,7 +19,7 @@ use middle::ty::{ReSkolemized, ReVar, BrEnv}; use middle::ty::{mt, t, ParamTy}; use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum}; use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure}; -use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_tup, ty_open}; +use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open}; use middle::ty::{ty_unboxed_closure}; use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer}; use middle::ty; @@ -384,7 +384,6 @@ pub fn ty_to_string(cx: &ctxt, typ: t) -> String { // pretty print the structural type representation: match ty::get(typ).sty { - ty_nil => "()".to_string(), ty_bool => "bool".to_string(), ty_char => "char".to_string(), ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 38e0c4fe040..24cad1b6d05 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -710,8 +710,7 @@ impl Clean<Item> for ast::Method { inputs: Arguments { values: inputs.iter().map(|x| x.clean(cx)).collect(), }, - output: (self.pe_fn_decl().output.clean(cx)), - cf: self.pe_fn_decl().cf.clean(cx), + output: self.pe_fn_decl().output.clean(cx), attrs: Vec::new() }; Item { @@ -749,8 +748,7 @@ impl Clean<Item> for ast::TypeMethod { inputs: Arguments { values: inputs.iter().map(|x| x.clean(cx)).collect(), }, - output: (self.decl.output.clean(cx)), - cf: self.decl.cf.clean(cx), + output: self.decl.output.clean(cx), attrs: Vec::new() }; Item { @@ -840,8 +838,7 @@ impl Clean<ClosureDecl> for ast::ClosureTy { #[deriving(Clone, Encodable, Decodable, PartialEq)] pub struct FnDecl { pub inputs: Arguments, - pub output: Type, - pub cf: RetStyle, + pub output: FunctionRetTy, pub attrs: Vec<Attribute>, } @@ -857,7 +854,6 @@ impl Clean<FnDecl> for ast::FnDecl { values: self.inputs.clean(cx), }, output: self.output.clean(cx), - cf: self.cf.clean(cx), attrs: Vec::new() } } @@ -884,8 +880,7 @@ impl<'a> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig) { let _ = names.next(); } FnDecl { - output: sig.output.clean(cx), - cf: Return, + output: Return(sig.output.clean(cx)), attrs: Vec::new(), inputs: Arguments { values: sig.inputs.iter().map(|t| { @@ -918,16 +913,16 @@ impl Clean<Argument> for ast::Arg { } #[deriving(Clone, Encodable, Decodable, PartialEq)] -pub enum RetStyle { - NoReturn, - Return +pub enum FunctionRetTy { + Return(Type), + NoReturn } -impl Clean<RetStyle> for ast::RetStyle { - fn clean(&self, _: &DocContext) -> RetStyle { +impl Clean<FunctionRetTy> for ast::FunctionRetTy { + fn clean(&self, cx: &DocContext) -> FunctionRetTy { match *self { - ast::Return => Return, - ast::NoReturn => NoReturn + ast::Return(ref typ) => Return(typ.clean(cx)), + ast::NoReturn(_) => NoReturn } } } @@ -1085,9 +1080,9 @@ impl Clean<Item> for ty::ImplOrTraitItem { pub enum Type { /// structs/enums/traits (anything that'd be an ast::TyPath) ResolvedPath { - pub path: Path, - pub typarams: Option<Vec<TyParamBound>>, - pub did: ast::DefId, + path: Path, + typarams: Option<Vec<TyParamBound>>, + did: ast::DefId, }, // I have no idea how to usefully use this. TyParamBinder(ast::NodeId), @@ -1110,9 +1105,9 @@ pub enum Type { Unique(Box<Type>), RawPointer(Mutability, Box<Type>), BorrowedRef { - pub lifetime: Option<Lifetime>, - pub mutability: Mutability, - pub type_: Box<Type>, + lifetime: Option<Lifetime>, + mutability: Mutability, + type_: Box<Type>, }, // region, raw, other boxes, mutable } @@ -1124,7 +1119,6 @@ pub enum PrimitiveType { F32, F64, Char, Bool, - Unit, Str, Slice, PrimitiveTuple, @@ -1156,7 +1150,6 @@ impl PrimitiveType { "u32" => Some(U32), "u64" => Some(U64), "bool" => Some(Bool), - "unit" => Some(Unit), "char" => Some(Char), "str" => Some(Str), "f32" => Some(F32), @@ -1205,17 +1198,13 @@ impl PrimitiveType { Str => "str", Bool => "bool", Char => "char", - Unit => "()", Slice => "slice", PrimitiveTuple => "tuple", } } pub fn to_url_str(&self) -> &'static str { - match *self { - Unit => "unit", - other => other.to_string(), - } + self.to_string() } /// Creates a rustdoc-specific node id for primitive types. @@ -1230,12 +1219,10 @@ impl Clean<Type> for ast::Ty { fn clean(&self, cx: &DocContext) -> Type { use syntax::ast::*; match self.node { - TyNil => Primitive(Unit), TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), TyRptr(ref l, ref m) => BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx), type_: box m.ty.clean(cx)}, - TyUniq(ref ty) => Unique(box ty.clean(cx)), TyVec(ref ty) => Vector(box ty.clean(cx)), TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx), e.span.to_src(cx)), @@ -1247,7 +1234,6 @@ impl Clean<Type> for ast::Ty { TyProc(ref c) => Proc(box c.clean(cx)), TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)), TyParen(ref ty) => ty.clean(cx), - TyBot => Bottom, ref x => panic!("Unimplemented type {}", x), } } @@ -1256,7 +1242,6 @@ impl Clean<Type> for ast::Ty { impl Clean<Type> for ty::t { fn clean(&self, cx: &DocContext) -> Type { match ty::get(*self).sty { - ty::ty_nil => Primitive(Unit), ty::ty_bool => Primitive(Bool), ty::ty_char => Primitive(Char), ty::ty_int(ast::TyI) => Primitive(Int), @@ -1342,7 +1327,7 @@ impl Clean<Type> for ty::t { } } - ty::ty_unboxed_closure(..) => Primitive(Unit), // FIXME(pcwalton) + ty::ty_unboxed_closure(..) => Tuple(vec![]), // FIXME(pcwalton) ty::ty_infer(..) => panic!("ty_infer"), ty::ty_open(..) => panic!("ty_open"), @@ -2041,7 +2026,6 @@ fn lit_to_string(lit: &ast::Lit) -> String { ast::LitFloat(ref f, _t) => f.get().to_string(), ast::LitFloatUnsuffixed(ref f) => f.get().to_string(), ast::LitBool(b) => b.to_string(), - ast::LitNil => "".to_string(), } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fe96c9b3a9f..a7f33151547 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -393,10 +393,7 @@ impl fmt::Show for clean::Type { format!("<{:#}>", decl.lifetimes) }, args = decl.decl.inputs, - arrow = match decl.decl.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", decl.decl.output), - }, + arrow = decl.decl.output, bounds = { let mut ret = String::new(); for bound in decl.bounds.iter() { @@ -435,10 +432,7 @@ impl fmt::Show for clean::Type { ": {}", m.collect::<Vec<String>>().connect(" + ")) }, - arrow = match decl.decl.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", decl.decl.output) - }) + arrow = decl.decl.output) } clean::BareFunction(ref decl) => { write!(f, "{}{}fn{}{}", @@ -514,14 +508,19 @@ impl fmt::Show for clean::Arguments { } } +impl fmt::Show for clean::FunctionRetTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + clean::Return(clean::Tuple(ref tys)) if tys.is_empty() => Ok(()), + clean::Return(ref ty) => write!(f, " -> {}", ty), + clean::NoReturn => write!(f, " -> !") + } + } +} + impl fmt::Show for clean::FnDecl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "({args}){arrow}", - args = self.inputs, - arrow = match self.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", self.output), - }) + write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output) } } @@ -551,12 +550,7 @@ impl<'a> fmt::Show for Method<'a> { } args.push_str(format!("{}", input.type_).as_slice()); } - write!(f, "({args}){arrow}", - args = args, - arrow = match d.output { - clean::Primitive(clean::Unit) => "".to_string(), - _ => format!(" -> {}", d.output), - }) + write!(f, "({args}){arrow}", args = args, arrow = d.output) } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7c5de627d08..593d5811553 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -893,7 +893,6 @@ pub enum Lit_ { LitInt(u64, LitIntType), LitFloat(InternedString, FloatTy), LitFloatUnsuffixed(InternedString), - LitNil, LitBool(bool), } @@ -1086,12 +1085,6 @@ pub struct BareFnTy { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] /// The different kinds of types recognized by the compiler pub enum Ty_ { - /// The unit type (`()`) - TyNil, - /// The bottom type (`!`) - TyBot, - TyUniq(P<Ty>), - /// An array (`[T]`) TyVec(P<Ty>), /// A fixed length array (`[T, ..n]`) TyFixedLengthVec(P<Ty>, P<Expr>), @@ -1175,8 +1168,7 @@ impl Arg { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct FnDecl { pub inputs: Vec<Arg>, - pub output: P<Ty>, - pub cf: RetStyle, + pub output: FunctionRetTy, pub variadic: bool } @@ -1198,12 +1190,21 @@ impl fmt::Show for FnStyle { } #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub enum RetStyle { +pub enum FunctionRetTy { /// Functions with return type ! that always /// raise an error or exit (i.e. never return to the caller) - NoReturn, + NoReturn(Span), /// Everything else - Return, + Return(P<Ty>), +} + +impl FunctionRetTy { + pub fn span(&self) -> Span { + match *self { + NoReturn(span) => span, + Return(ref ty) => ty.span + } + } } /// Represents the kind of 'self' associated with a method @@ -1292,8 +1293,8 @@ pub type Variant = Spanned<Variant_>; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum PathListItem_ { - PathListIdent { pub name: Ident, pub id: NodeId }, - PathListMod { pub id: NodeId } + PathListIdent { name: Ident, id: NodeId }, + PathListMod { id: NodeId } } impl PathListItem_ { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 1e2d935af00..0c7a3cf4a6c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -248,7 +248,7 @@ impl DummyResult { pub fn raw_expr(sp: Span) -> P<ast::Expr> { P(ast::Expr { id: ast::DUMMY_NODE_ID, - node: ast::ExprLit(P(codemap::respan(sp, ast::LitNil))), + node: ast::ExprLit(P(codemap::respan(sp, ast::LitBool(false)))), span: sp, }) } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 862cbf3d7ca..ffc42b67033 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -54,11 +54,9 @@ pub trait AstBuilder { fn ty_ptr(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty>; - fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>; fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>; fn ty_infer(&self, sp: Span) -> P<ast::Ty>; - fn ty_nil(&self) -> P<ast::Ty>; fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ; fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ; @@ -377,9 +375,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty(span, ast::TyPtr(self.ty_mt(ty, mutbl))) } - fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> { - self.ty(span, ast::TyUniq(ty)) - } fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> { self.ty_path( @@ -406,14 +401,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.ty(span, ast::TyInfer) } - fn ty_nil(&self) -> P<ast::Ty> { - P(ast::Ty { - id: ast::DUMMY_NODE_ID, - node: ast::TyNil, - span: DUMMY_SP, - }) - } - fn typaram(&self, span: Span, id: ast::Ident, @@ -809,8 +796,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.pat(span, pat) } fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { - let pat = ast::PatTup(pats); - self.pat(span, pat) + self.pat(span, ast::PatTup(pats)) } fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { @@ -931,11 +917,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // FIXME unused self - fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl> { + fn fn_decl(&self, inputs: Vec<ast::Arg>, output: P<ast::Ty>) -> P<ast::FnDecl> { P(ast::FnDecl { inputs: inputs, - output: output, - cf: ast::Return, + output: ast::Return(output), variadic: false }) } diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index af7cd4157ec..e2867c2fbab 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -46,7 +46,6 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => { accumulator.push_str(format!("-{}", i).as_slice()); } - ast::LitNil => {} ast::LitBool(b) => { accumulator.push_str(format!("{}", b).as_slice()); } diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 69eb260b8c4..62f3b5d01b4 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -88,7 +88,7 @@ //! } //! ``` -use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil}; +use ast::{MetaItem, Item, Expr, ExprRet, MutMutable}; use codemap::Span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -186,7 +186,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, if stmts.is_empty() { let ret_ok = cx.expr(trait_span, ExprRet(Some(cx.expr_ok(trait_span, - cx.expr_lit(trait_span, LitNil))))); + cx.expr_tuple(trait_span, vec![]))))); stmts.push(cx.stmt_expr(ret_ok)); } @@ -231,7 +231,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, if stmts.len() == 0 { let ret_ok = cx.expr(trait_span, ExprRet(Some(cx.expr_ok(trait_span, - cx.expr_lit(trait_span, LitNil))))); + cx.expr_tuple(trait_span, vec![]))))); stmts.push(cx.stmt_expr(ret_ok)); } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 7c32b845508..4be299994fd 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -922,7 +922,7 @@ impl<'a> MethodDef<'a> { } // Here is the pat = `(&VariantK, &VariantK, ...)` - let single_pat = cx.pat(sp, ast::PatTup(subpats)); + let single_pat = cx.pat_tuple(sp, subpats); // For the BodyK, we need to delegate to our caller, // passing it an EnumMatching to indicate which case diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index 1ec1e3b1224..8b46769d633 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -152,14 +152,9 @@ impl<'a> Ty<'a> { cx.ty_path(self.to_path(cx, span, self_ty, self_generics), None) } Tuple(ref fields) => { - let ty = if fields.is_empty() { - ast::TyNil - } else { - ast::TyTup(fields.iter() - .map(|f| f.to_ty(cx, span, self_ty, self_generics)) - .collect()) - }; - + let ty = ast::TyTup(fields.iter() + .map(|f| f.to_ty(cx, span, self_ty, self_generics)) + .collect()); cx.ty(span, ty) } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 87406081aae..fa69495fa42 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -159,7 +159,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { // `_ => [<elseopt> | ()]` let else_arm = { let pat_under = fld.cx.pat_wild(span); - let else_expr = elseopt.unwrap_or_else(|| fld.cx.expr_lit(span, ast::LitNil)); + let else_expr = elseopt.unwrap_or_else(|| fld.cx.expr_tuple(span, vec![])); fld.cx.arm(span, vec![pat_under], else_expr) }; diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index a28f24e7663..a816b479630 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -654,7 +654,7 @@ impl<'a, 'b> Context<'a, 'b> { // // But the nested match expression is proved to perform not as well // as series of let's; the first approach does. - let pat = self.ecx.pat(self.fmtsp, ast::PatTup(pats)); + let pat = self.ecx.pat_tuple(self.fmtsp, pats); let arm = self.ecx.arm(self.fmtsp, vec!(pat), body); let head = self.ecx.expr(self.fmtsp, ast::ExprTup(heads)); self.ecx.expr_match(self.fmtsp, head, vec!(arm)) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c38fea9b3d5..019d2315c1a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -37,7 +37,7 @@ use std::slice; static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("globs", Active), ("macro_rules", Active), - ("struct_variant", Active), + ("struct_variant", Accepted), ("asm", Active), ("managed_boxes", Removed), ("non_ascii_idents", Active), @@ -184,19 +184,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { } } match i.node { - ast::ItemEnum(ref def, _) => { - for variant in def.variants.iter() { - match variant.node.kind { - ast::StructVariantKind(..) => { - self.gate_feature("struct_variant", variant.span, - "enum struct variants are \ - experimental and possibly buggy"); - } - _ => {} - } - } - } - ast::ItemForeignMod(ref foreign_module) => { if attr::contains_name(i.attrs.as_slice(), "link_args") { self.gate_feature("link_args", i.span, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d7c3ca8efc4..56d91282437 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -391,8 +391,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { t.map(|Ty {id, node, span}| Ty { id: fld.new_id(id), node: match node { - TyNil | TyBot | TyInfer => node, - TyUniq(ty) => TyUniq(fld.fold_ty(ty)), + TyInfer => node, TyVec(ty) => TyVec(fld.fold_ty(ty)), TyPtr(mt) => TyPtr(fld.fold_mt(mt)), TyRptr(region, mt) => { @@ -706,10 +705,12 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T) } pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> { - decl.map(|FnDecl {inputs, output, cf, variadic}| FnDecl { + decl.map(|FnDecl {inputs, output, variadic}| FnDecl { inputs: inputs.move_map(|x| fld.fold_arg(x)), - output: fld.fold_ty(output), - cf: cf, + output: match output { + Return(ty) => Return(fld.fold_ty(ty)), + NoReturn(span) => NoReturn(span) + }, variadic: variadic }) } @@ -1146,10 +1147,12 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) -> attrs: attrs.move_map(|x| folder.fold_attribute(x)), node: match node { ForeignItemFn(fdec, generics) => { - ForeignItemFn(fdec.map(|FnDecl {inputs, output, cf, variadic}| FnDecl { + ForeignItemFn(fdec.map(|FnDecl {inputs, output, variadic}| FnDecl { inputs: inputs.move_map(|a| folder.fold_arg(a)), - output: folder.fold_ty(output), - cf: cf, + output: match output { + Return(ty) => Return(folder.fold_ty(ty)), + NoReturn(span) => NoReturn(span) + }, variadic: variadic }), folder.fold_generics(generics)) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 4881be8996a..fa10cb90f83 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -24,7 +24,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/")] #![allow(unknown_features)] -#![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)] +#![feature(if_let, macro_rules, globs, default_type_params, phase, slicing_syntax)] #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)] extern crate arena; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 51738ece80f..2810db4eadd 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1037,10 +1037,9 @@ mod test { }), id: ast::DUMMY_NODE_ID }), - output: P(ast::Ty{id: ast::DUMMY_NODE_ID, - node: ast::TyNil, - span:sp(15,15)}), // not sure - cf: ast::Return, + output: ast::Return(P(ast::Ty{id: ast::DUMMY_NODE_ID, + node: ast::TyTup(vec![]), + span:sp(15,15)})), // not sure variadic: false }), ast::NormalFn, diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 73787763c8b..1b2ab3c235d 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -17,8 +17,8 @@ Obsolete syntax that becomes too hard to parse can be removed. */ -use ast::{Expr, ExprLit, LitNil}; -use codemap::{Span, respan}; +use ast::{Expr, ExprTup}; +use codemap::Span; use parse::parser; use parse::token; use ptr::P; @@ -96,7 +96,7 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { /// a placeholder expression fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> { self.obsolete(sp, kind); - self.mk_expr(sp.lo, sp.hi, ExprLit(P(respan(sp, LitNil)))) + self.mk_expr(sp.lo, sp.hi, ExprTup(vec![])) } fn report(&mut self, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index db10dc1bc90..50e3483fb15 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -30,13 +30,13 @@ use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; use ast::{Once, Many}; use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; -use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod}; +use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy}; use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic}; use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst}; use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy}; use ast::{LifetimeDef, Lit, Lit_}; use ast::{LitBool, LitChar, LitByte, LitBinary}; -use ast::{LitNil, LitStr, LitInt, Local, LocalLet}; +use ast::{LitStr, LitInt, Local, LocalLet}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchNormal}; use ast::{Method, MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot}; @@ -44,18 +44,18 @@ use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; use ast::{PolyTraitRef}; use ast::{QPath, RequiredMethod}; -use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl}; +use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub}; use ast::StrStyle; use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; -use ast::{TupleVariantKind, Ty, Ty_, TyBot}; +use ast::{TupleVariantKind, Ty, Ty_}; use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; -use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath}; -use ast::{TyRptr, TyTup, TyU32, TyUniq, TyVec, UnUniq}; +use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath}; +use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; @@ -1066,11 +1066,10 @@ impl<'a> Parser<'a> { self.expect_keyword(keywords::Fn); let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs); let (inputs, variadic) = self.parse_fn_args(false, true); - let (ret_style, ret_ty) = self.parse_ret_ty(); + let ret_ty = self.parse_ret_ty(); let decl = P(FnDecl { inputs: inputs, output: ret_ty, - cf: ret_style, variadic: variadic }); TyBareFn(P(BareFnTy { @@ -1100,11 +1099,10 @@ impl<'a> Parser<'a> { let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs); let (inputs, variadic) = self.parse_fn_args(false, false); let bounds = self.parse_colon_then_ty_param_bounds(); - let (ret_style, ret_ty) = self.parse_ret_ty(); + let ret_ty = self.parse_ret_ty(); let decl = P(FnDecl { inputs: inputs, output: ret_ty, - cf: ret_style, variadic: variadic }); TyProc(P(ClosureTy { @@ -1200,11 +1198,10 @@ impl<'a> Parser<'a> { let bounds = self.parse_colon_then_ty_param_bounds(); - let (return_style, output) = self.parse_ret_ty(); + let output = self.parse_ret_ty(); let decl = P(FnDecl { inputs: inputs, output: output, - cf: return_style, variadic: false }); @@ -1384,31 +1381,20 @@ impl<'a> Parser<'a> { } /// Parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) { - return if self.eat(&token::RArrow) { - let lo = self.span.lo; + pub fn parse_ret_ty(&mut self) -> FunctionRetTy { + if self.eat(&token::RArrow) { if self.eat(&token::Not) { - ( - NoReturn, - P(Ty { - id: ast::DUMMY_NODE_ID, - node: TyBot, - span: mk_sp(lo, self.last_span.hi) - }) - ) + NoReturn(self.span) } else { - (Return, self.parse_ty(true)) + Return(self.parse_ty(true)) } } else { let pos = self.span.lo; - ( - Return, - P(Ty { - id: ast::DUMMY_NODE_ID, - node: TyNil, - span: mk_sp(pos, pos), - }) - ) + Return(P(Ty { + id: ast::DUMMY_NODE_ID, + node: TyTup(vec![]), + span: mk_sp(pos, pos), + })) } } @@ -1423,34 +1409,29 @@ impl<'a> Parser<'a> { let t = if self.token == token::OpenDelim(token::Paren) { self.bump(); - if self.token == token::CloseDelim(token::Paren) { - self.bump(); - TyNil - } else { - // (t) is a parenthesized ty - // (t,) is the type of a tuple with only one field, - // of type t - let mut ts = vec!(self.parse_ty(true)); - let mut one_tuple = false; - while self.token == token::Comma { - self.bump(); - if self.token != token::CloseDelim(token::Paren) { - ts.push(self.parse_ty(true)); - } - else { - one_tuple = true; - } - } - if ts.len() == 1 && !one_tuple { - self.expect(&token::CloseDelim(token::Paren)); - TyParen(ts.into_iter().nth(0).unwrap()) + // (t) is a parenthesized ty + // (t,) is the type of a tuple with only one field, + // of type t + let mut ts = vec![]; + let mut last_comma = false; + while self.token != token::CloseDelim(token::Paren) { + ts.push(self.parse_ty(true)); + if self.token == token::Comma { + last_comma = true; + self.bump(); } else { - let t = TyTup(ts); - self.expect(&token::CloseDelim(token::Paren)); - t + last_comma = false; + break; } } + + self.expect(&token::CloseDelim(token::Paren)); + if ts.len() == 1 && !last_comma { + TyParen(ts.into_iter().nth(0).unwrap()) + } else { + TyTup(ts) + } } else if self.token == token::Tilde { // OWNED POINTER self.bump(); @@ -1459,7 +1440,7 @@ impl<'a> Parser<'a> { token::OpenDelim(token::Bracket) => self.obsolete(last_span, ObsoleteOwnedVector), _ => self.obsolete(last_span, ObsoleteOwnedType) } - TyUniq(self.parse_ty(false)) + TyTup(vec![self.parse_ty(false)]) } else if self.token == token::BinOp(token::Star) { // STAR POINTER (bare pointer?) self.bump(); @@ -1662,10 +1643,6 @@ impl<'a> Parser<'a> { LitBinary(parse::binary_lit(i.as_str())), token::LitBinaryRaw(i, _) => LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())), - token::OpenDelim(token::Paren) => { - self.expect(&token::CloseDelim(token::Paren)); - LitNil - }, _ => { self.unexpected_last(tok); } } } @@ -2126,33 +2103,29 @@ impl<'a> Parser<'a> { match self.token { token::OpenDelim(token::Paren) => { self.bump(); + // (e) is parenthesized e // (e,) is a tuple with only one field, e + let mut es = vec![]; let mut trailing_comma = false; - if self.token == token::CloseDelim(token::Paren) { - hi = self.span.hi; - self.bump(); - let lit = P(spanned(lo, hi, LitNil)); - return self.mk_expr(lo, hi, ExprLit(lit)); - } - let mut es = vec!(self.parse_expr()); - self.commit_expr(&**es.last().unwrap(), &[], - &[token::Comma, token::CloseDelim(token::Paren)]); - while self.token == token::Comma { - self.bump(); - if self.token != token::CloseDelim(token::Paren) { - es.push(self.parse_expr()); - self.commit_expr(&**es.last().unwrap(), &[], - &[token::Comma, token::CloseDelim(token::Paren)]); - } else { + while self.token != token::CloseDelim(token::Paren) { + es.push(self.parse_expr()); + self.commit_expr(&**es.last().unwrap(), &[], + &[token::Comma, token::CloseDelim(token::Paren)]); + if self.token == token::Comma { trailing_comma = true; + + self.bump(); + } else { + trailing_comma = false; + break; } } - hi = self.span.hi; - self.commit_expr_expecting(&**es.last().unwrap(), token::CloseDelim(token::Paren)); + self.bump(); + hi = self.span.hi; return if es.len() == 1 && !trailing_comma { - self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap())) + self.mk_expr(lo, hi, ExprParen(es.into_iter().nth(0).unwrap())) } else { self.mk_expr(lo, hi, ExprTup(es)) } @@ -3293,13 +3266,8 @@ impl<'a> Parser<'a> { // parse (pat,pat,pat,...) as tuple self.bump(); if self.token == token::CloseDelim(token::Paren) { - hi = self.span.hi; self.bump(); - let lit = P(codemap::Spanned { - node: LitNil, - span: mk_sp(lo, hi)}); - let expr = self.mk_expr(lo, hi, ExprLit(lit)); - pat = PatLit(expr); + pat = PatTup(vec![]); } else { let mut fields = vec!(self.parse_pat()); if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) { @@ -4137,12 +4105,11 @@ impl<'a> Parser<'a> { pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> { let (args, variadic) = self.parse_fn_args(true, allow_variadic); - let (ret_style, ret_ty) = self.parse_ret_ty(); + let ret_ty = self.parse_ret_ty(); P(FnDecl { inputs: args, output: ret_ty, - cf: ret_style, variadic: variadic }) } @@ -4337,12 +4304,11 @@ impl<'a> Parser<'a> { let hi = self.span.hi; - let (ret_style, ret_ty) = self.parse_ret_ty(); + let ret_ty = self.parse_ret_ty(); let fn_decl = P(FnDecl { inputs: fn_inputs, output: ret_ty, - cf: ret_style, variadic: false }); @@ -4368,10 +4334,10 @@ impl<'a> Parser<'a> { (optional_unboxed_closure_kind, args) } }; - let (style, output) = if self.token == token::RArrow { + let output = if self.token == token::RArrow { self.parse_ret_ty() } else { - (Return, P(Ty { + Return(P(Ty { id: ast::DUMMY_NODE_ID, node: TyInfer, span: self.span, @@ -4381,7 +4347,6 @@ impl<'a> Parser<'a> { (P(FnDecl { inputs: inputs_captures, output: output, - cf: style, variadic: false }), optional_unboxed_closure_kind) } @@ -4394,10 +4359,10 @@ impl<'a> Parser<'a> { seq_sep_trailing_allowed(token::Comma), |p| p.parse_fn_block_arg()); - let (style, output) = if self.token == token::RArrow { + let output = if self.token == token::RArrow { self.parse_ret_ty() } else { - (Return, P(Ty { + Return(P(Ty { id: ast::DUMMY_NODE_ID, node: TyInfer, span: self.span, @@ -4407,7 +4372,6 @@ impl<'a> Parser<'a> { P(FnDecl { inputs: inputs, output: output, - cf: style, variadic: false }) } @@ -4648,7 +4612,7 @@ impl<'a> Parser<'a> { is_tuple_like = false; fields = Vec::new(); while self.token != token::CloseDelim(token::Brace) { - fields.push(self.parse_struct_decl_field()); + fields.push(self.parse_struct_decl_field(true)); } if fields.len() == 0 { self.fatal(format!("unit-like struct definition should be \ @@ -4725,12 +4689,16 @@ impl<'a> Parser<'a> { } /// Parse an element of a struct definition - fn parse_struct_decl_field(&mut self) -> StructField { + fn parse_struct_decl_field(&mut self, allow_pub: bool) -> StructField { let attrs = self.parse_outer_attributes(); if self.eat_keyword(keywords::Pub) { - return self.parse_single_struct_field(Public, attrs); + if !allow_pub { + let span = self.last_span; + self.span_err(span, "`pub` is not allowed here"); + } + return self.parse_single_struct_field(Public, attrs); } return self.parse_single_struct_field(Inherited, attrs); @@ -5178,7 +5146,7 @@ impl<'a> Parser<'a> { fn parse_struct_def(&mut self) -> P<StructDef> { let mut fields: Vec<StructField> = Vec::new(); while self.token != token::CloseDelim(token::Brace) { - fields.push(self.parse_struct_decl_field()); + fields.push(self.parse_struct_decl_field(false)); } self.bump(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c1515a36bec..7025555ab40 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -645,12 +645,6 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ty.span.lo)); try!(self.ibox(0u)); match ty.node { - ast::TyNil => try!(word(&mut self.s, "()")), - ast::TyBot => try!(word(&mut self.s, "!")), - ast::TyUniq(ref ty) => { - try!(word(&mut self.s, "~")); - try!(self.print_type(&**ty)); - } ast::TyVec(ref ty) => { try!(word(&mut self.s, "[")); try!(self.print_type(&**ty)); @@ -2307,15 +2301,7 @@ impl<'a> State<'a> { } try!(self.pclose()); - try!(self.maybe_print_comment(decl.output.span.lo)); - match decl.output.node { - ast::TyNil => Ok(()), - _ => { - try!(self.space_if_not_bol()); - try!(self.word_space("->")); - self.print_type(&*decl.output) - } - } + self.print_fn_output(decl) } pub fn print_fn_block_args( @@ -2333,16 +2319,24 @@ impl<'a> State<'a> { try!(self.print_fn_args(decl, None)); try!(word(&mut self.s, "|")); - match decl.output.node { - ast::TyInfer => {} - _ => { - try!(self.space_if_not_bol()); - try!(self.word_space("->")); - try!(self.print_type(&*decl.output)); + if let ast::Return(ref ty) = decl.output { + if ty.node == ast::TyInfer { + return self.maybe_print_comment(ty.span.lo); } } - self.maybe_print_comment(decl.output.span.lo) + try!(self.space_if_not_bol()); + try!(self.word_space("->")); + match decl.output { + ast::Return(ref ty) => { + try!(self.print_type(&**ty)); + self.maybe_print_comment(ty.span.lo) + } + ast::NoReturn(span) => { + try!(self.word_nbsp("!")); + self.maybe_print_comment(span.lo) + } + } } pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause) @@ -2359,16 +2353,24 @@ impl<'a> State<'a> { try!(self.print_fn_args(decl, None)); try!(word(&mut self.s, ")")); - match decl.output.node { - ast::TyInfer => {} - _ => { - try!(self.space_if_not_bol()); - try!(self.word_space("->")); - try!(self.print_type(&*decl.output)); + if let ast::Return(ref ty) = decl.output { + if ty.node == ast::TyInfer { + return self.maybe_print_comment(ty.span.lo); } } - self.maybe_print_comment(decl.output.span.lo) + try!(self.space_if_not_bol()); + try!(self.word_space("->")); + match decl.output { + ast::Return(ref ty) => { + try!(self.print_type(&**ty)); + self.maybe_print_comment(ty.span.lo) + } + ast::NoReturn(span) => { + try!(self.word_nbsp("!")); + self.maybe_print_comment(span.lo) + } + } } pub fn print_bounds(&mut self, @@ -2627,20 +2629,30 @@ impl<'a> State<'a> { } pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> { - match decl.output.node { - ast::TyNil => Ok(()), - _ => { - try!(self.space_if_not_bol()); - try!(self.ibox(indent_unit)); - try!(self.word_space("->")); - if decl.cf == ast::NoReturn { - try!(self.word_nbsp("!")); - } else { - try!(self.print_type(&*decl.output)); + if let ast::Return(ref ty) = decl.output { + match ty.node { + ast::TyTup(ref tys) if tys.is_empty() => { + return self.maybe_print_comment(ty.span.lo); } - self.end() + _ => () } } + + try!(self.space_if_not_bol()); + try!(self.ibox(indent_unit)); + try!(self.word_space("->")); + match decl.output { + ast::NoReturn(_) => + try!(self.word_nbsp("!")), + ast::Return(ref ty) => + try!(self.print_type(&**ty)) + } + try!(self.end()); + + match decl.output { + ast::Return(ref output) => self.maybe_print_comment(output.span.lo), + _ => Ok(()) + } } pub fn print_ty_fn(&mut self, @@ -2700,8 +2712,6 @@ impl<'a> State<'a> { try!(self.print_bounds(":", bounds)); - try!(self.maybe_print_comment(decl.output.span.lo)); - try!(self.print_fn_output(decl)); match generics { @@ -2807,7 +2817,6 @@ impl<'a> State<'a> { ast_util::float_ty_to_string(t).as_slice()).as_slice()) } ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()), - ast::LitNil => word(&mut self.s, "()"), ast::LitBool(val) => { if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") } } @@ -3003,10 +3012,9 @@ mod test { let decl = ast::FnDecl { inputs: Vec::new(), - output: P(ast::Ty {id: 0, - node: ast::TyNil, - span: codemap::DUMMY_SP}), - cf: ast::Return, + output: ast::Return(P(ast::Ty {id: 0, + node: ast::TyTup(vec![]), + span: codemap::DUMMY_SP})), variadic: false }; let generics = ast_util::empty_generics(); diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 29637e88dd5..8b6d752d484 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -289,9 +289,12 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { fn has_test_signature(i: &ast::Item) -> HasTestSignature { match &i.node { &ast::ItemFn(ref decl, _, _, ref generics, _) => { - let no_output = match decl.output.node { - ast::TyNil => true, - _ => false, + let no_output = match decl.output { + ast::Return(ref ret_ty) => match ret_ty.node { + ast::TyTup(ref tys) if tys.is_empty() => true, + _ => false, + }, + ast::NoReturn(_) => false }; if decl.inputs.is_empty() && no_output @@ -325,9 +328,12 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { match i.node { ast::ItemFn(ref decl, _, _, ref generics, _) => { let input_cnt = decl.inputs.len(); - let no_output = match decl.output.node { - ast::TyNil => true, - _ => false + let no_output = match decl.output { + ast::Return(ref ret_ty) => match ret_ty.node { + ast::TyTup(ref tys) if tys.is_empty() => true, + _ => false, + }, + ast::NoReturn(_) => false }; let tparm_cnt = generics.ty_params.len(); // NB: inadequate check, but we're running diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1b1d1e9cace..f30a4325eb8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -341,7 +341,7 @@ pub fn skip_ty<'v, V: Visitor<'v>>(_: &mut V, _: &'v Ty) { pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { match typ.node { - TyUniq(ref ty) | TyVec(ref ty) | TyParen(ref ty) => { + TyVec(ref ty) | TyParen(ref ty) => { visitor.visit_ty(&**ty) } TyPtr(ref mutable_type) => { @@ -360,7 +360,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty) } - visitor.visit_ty(&*function_declaration.decl.output); + walk_fn_ret_ty(visitor, &function_declaration.decl.output); walk_ty_param_bounds(visitor, &function_declaration.bounds); walk_lifetime_decls(visitor, &function_declaration.lifetimes); } @@ -368,7 +368,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty) } - visitor.visit_ty(&*function_declaration.decl.output); + walk_fn_ret_ty(visitor, &function_declaration.decl.output); walk_ty_param_bounds(visitor, &function_declaration.bounds); walk_lifetime_decls(visitor, &function_declaration.lifetimes); } @@ -376,7 +376,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty) } - visitor.visit_ty(&*function_declaration.decl.output); + walk_fn_ret_ty(visitor, &function_declaration.decl.output); walk_lifetime_decls(visitor, &function_declaration.lifetimes); } TyPath(ref path, ref opt_bounds, id) => { @@ -403,7 +403,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyTypeof(ref expression) => { visitor.visit_expr(&**expression) } - TyNil | TyBot | TyInfer => {} + TyInfer => {} } } @@ -538,12 +538,18 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics } } +pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) { + if let Return(ref output_ty) = *ret_ty { + visitor.visit_ty(&**output_ty) + } +} + pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { for argument in function_declaration.inputs.iter() { visitor.visit_pat(&*argument.pat); visitor.visit_ty(&*argument.ty) } - visitor.visit_ty(&*function_declaration.output) + walk_fn_ret_ty(visitor, &function_declaration.output) } // Note: there is no visit_method() method in the visitor, instead override @@ -601,7 +607,7 @@ pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v Type visitor.visit_ty(&*argument_type.ty) } visitor.visit_generics(&method_type.generics); - visitor.visit_ty(&*method_type.decl.output); + walk_fn_ret_ty(visitor, &method_type.decl.output); for attr in method_type.attrs.iter() { visitor.visit_attribute(attr); } diff --git a/src/test/compile-fail/deriving-primitive.rs b/src/test/compile-fail/deriving-primitive.rs index 7d8741c98e2..1af0193ca47 100644 --- a/src/test/compile-fail/deriving-primitive.rs +++ b/src/test/compile-fail/deriving-primitive.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - use std::num::FromPrimitive; use std::int; diff --git a/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs index 58a9c72b8b1..1abafb84dd2 100644 --- a/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-Clone-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Clone-enum.rs b/src/test/compile-fail/deriving-span-Clone-enum.rs index cf8345dbe7b..50badaeea00 100644 --- a/src/test/compile-fail/deriving-span-Clone-enum.rs +++ b/src/test/compile-fail/deriving-span-Clone-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Clone-struct.rs b/src/test/compile-fail/deriving-span-Clone-struct.rs index cd53f5a1e8f..49530afec05 100644 --- a/src/test/compile-fail/deriving-span-Clone-struct.rs +++ b/src/test/compile-fail/deriving-span-Clone-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs b/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs index 95798af49b2..27e281bb220 100644 --- a/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Clone-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Default-struct.rs b/src/test/compile-fail/deriving-span-Default-struct.rs index 1da88f2e257..a75d909c06d 100644 --- a/src/test/compile-fail/deriving-span-Default-struct.rs +++ b/src/test/compile-fail/deriving-span-Default-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Default-tuple-struct.rs b/src/test/compile-fail/deriving-span-Default-tuple-struct.rs index cf0d9fb7443..8df6acd2704 100644 --- a/src/test/compile-fail/deriving-span-Default-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Default-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Hash-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Hash-enum-struct-variant.rs index 49b4840ff8e..fb94799caba 100644 --- a/src/test/compile-fail/deriving-span-Hash-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-Hash-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Hash-enum.rs b/src/test/compile-fail/deriving-span-Hash-enum.rs index 653dabfbc13..d4100badcdb 100644 --- a/src/test/compile-fail/deriving-span-Hash-enum.rs +++ b/src/test/compile-fail/deriving-span-Hash-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Hash-struct.rs b/src/test/compile-fail/deriving-span-Hash-struct.rs index 46234f6e724..8b0ec01283c 100644 --- a/src/test/compile-fail/deriving-span-Hash-struct.rs +++ b/src/test/compile-fail/deriving-span-Hash-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Hash-tuple-struct.rs b/src/test/compile-fail/deriving-span-Hash-tuple-struct.rs index 5dbf4a0376a..8ed8350e557 100644 --- a/src/test/compile-fail/deriving-span-Hash-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Hash-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-PartialEq-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-PartialEq-enum-struct-variant.rs index 566585aa065..f9ce978a057 100644 --- a/src/test/compile-fail/deriving-span-PartialEq-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-PartialEq-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-PartialEq-enum.rs b/src/test/compile-fail/deriving-span-PartialEq-enum.rs index 8a9771a0509..7756e9bfbb6 100644 --- a/src/test/compile-fail/deriving-span-PartialEq-enum.rs +++ b/src/test/compile-fail/deriving-span-PartialEq-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-PartialEq-struct.rs b/src/test/compile-fail/deriving-span-PartialEq-struct.rs index de39e9bacd5..43685a5b0ef 100644 --- a/src/test/compile-fail/deriving-span-PartialEq-struct.rs +++ b/src/test/compile-fail/deriving-span-PartialEq-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-PartialEq-tuple-struct.rs b/src/test/compile-fail/deriving-span-PartialEq-tuple-struct.rs index 101461e39b7..b84b8b4a658 100644 --- a/src/test/compile-fail/deriving-span-PartialEq-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-PartialEq-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-PartialOrd-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-PartialOrd-enum-struct-variant.rs index dd6c11d2b39..810f0f350f3 100644 --- a/src/test/compile-fail/deriving-span-PartialOrd-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-PartialOrd-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-PartialOrd-enum.rs b/src/test/compile-fail/deriving-span-PartialOrd-enum.rs index 1b3d73a6f8b..7ae2bbf8eb5 100644 --- a/src/test/compile-fail/deriving-span-PartialOrd-enum.rs +++ b/src/test/compile-fail/deriving-span-PartialOrd-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-PartialOrd-struct.rs b/src/test/compile-fail/deriving-span-PartialOrd-struct.rs index 2ef3b4dfe8a..c5b008da884 100644 --- a/src/test/compile-fail/deriving-span-PartialOrd-struct.rs +++ b/src/test/compile-fail/deriving-span-PartialOrd-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-PartialOrd-tuple-struct.rs b/src/test/compile-fail/deriving-span-PartialOrd-tuple-struct.rs index 303896737dc..f282943bba3 100644 --- a/src/test/compile-fail/deriving-span-PartialOrd-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-PartialOrd-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs index 79c38dcb4cc..c44abc2313a 100644 --- a/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-Rand-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Rand-enum.rs b/src/test/compile-fail/deriving-span-Rand-enum.rs index 1e153a772c7..fc03b99983d 100644 --- a/src/test/compile-fail/deriving-span-Rand-enum.rs +++ b/src/test/compile-fail/deriving-span-Rand-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Rand-struct.rs b/src/test/compile-fail/deriving-span-Rand-struct.rs index 2c223918773..36e1e521393 100644 --- a/src/test/compile-fail/deriving-span-Rand-struct.rs +++ b/src/test/compile-fail/deriving-span-Rand-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs b/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs index 5d5a1372c13..ffa26061833 100644 --- a/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Rand-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs index 93f53dc73f7..fa1cfc3de5b 100644 --- a/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-Show-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Show-enum.rs b/src/test/compile-fail/deriving-span-Show-enum.rs index e61a62c2f6d..9b1dccf7df5 100644 --- a/src/test/compile-fail/deriving-span-Show-enum.rs +++ b/src/test/compile-fail/deriving-span-Show-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Show-struct.rs b/src/test/compile-fail/deriving-span-Show-struct.rs index 3a48b3334b7..8acb6875d53 100644 --- a/src/test/compile-fail/deriving-span-Show-struct.rs +++ b/src/test/compile-fail/deriving-span-Show-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Show-tuple-struct.rs b/src/test/compile-fail/deriving-span-Show-tuple-struct.rs index 54806f322b3..bcbced125ef 100644 --- a/src/test/compile-fail/deriving-span-Show-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Show-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs index 964e7d8c811..25add55ae4b 100644 --- a/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-TotalEq-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalEq-enum.rs b/src/test/compile-fail/deriving-span-TotalEq-enum.rs index 96e87ca2006..e58121f2cb0 100644 --- a/src/test/compile-fail/deriving-span-TotalEq-enum.rs +++ b/src/test/compile-fail/deriving-span-TotalEq-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalEq-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-struct.rs index 784c766c057..0637c6e305c 100644 --- a/src/test/compile-fail/deriving-span-TotalEq-struct.rs +++ b/src/test/compile-fail/deriving-span-TotalEq-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs index 3dcff5f80ce..3a2cbb11f53 100644 --- a/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-TotalEq-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs index c16e64829dd..3b4f4e1080d 100644 --- a/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs +++ b/src/test/compile-fail/deriving-span-TotalOrd-enum-struct-variant.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(Eq,PartialOrd,PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalOrd-enum.rs b/src/test/compile-fail/deriving-span-TotalOrd-enum.rs index 4b3f0ce52c7..02a55fdfbb2 100644 --- a/src/test/compile-fail/deriving-span-TotalOrd-enum.rs +++ b/src/test/compile-fail/deriving-span-TotalOrd-enum.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(Eq,PartialOrd,PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalOrd-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-struct.rs index 56d62742378..7cf3ad57f47 100644 --- a/src/test/compile-fail/deriving-span-TotalOrd-struct.rs +++ b/src/test/compile-fail/deriving-span-TotalOrd-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(Eq,PartialOrd,PartialEq)] diff --git a/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs b/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs index 2330fdd8b89..7b8d1d3ecd0 100644 --- a/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-TotalOrd-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; #[deriving(Eq,PartialOrd,PartialEq)] diff --git a/src/test/compile-fail/deriving-span-Zero-struct.rs b/src/test/compile-fail/deriving-span-Zero-struct.rs index fb7759c6032..302fecd518b 100644 --- a/src/test/compile-fail/deriving-span-Zero-struct.rs +++ b/src/test/compile-fail/deriving-span-Zero-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs b/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs index 193e4b5c6b2..05b81ce3251 100644 --- a/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs +++ b/src/test/compile-fail/deriving-span-Zero-tuple-struct.rs @@ -10,7 +10,6 @@ // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' -#![feature(struct_variant)] extern crate rand; diff --git a/src/test/compile-fail/dup-struct-enum-struct-variant.rs b/src/test/compile-fail/dup-struct-enum-struct-variant.rs index 47b576b2b85..7ea114605ce 100644 --- a/src/test/compile-fail/dup-struct-enum-struct-variant.rs +++ b/src/test/compile-fail/dup-struct-enum-struct-variant.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - enum Foo { C { a: int, b: int } } struct C { a: int, b: int } //~ ERROR error: duplicate definition of type or module `C` diff --git a/src/test/compile-fail/gated-non-ascii-idents.rs b/src/test/compile-fail/gated-non-ascii-idents.rs index 0634ba183a8..4cbb61d9853 100644 --- a/src/test/compile-fail/gated-non-ascii-idents.rs +++ b/src/test/compile-fail/gated-non-ascii-idents.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(struct_variant)] - extern crate bäz; //~ ERROR non-ascii idents use föö::bar; //~ ERROR non-ascii idents diff --git a/src/test/compile-fail/issue-13624.rs b/src/test/compile-fail/issue-13624.rs index 0c103515981..5b9ff06e9c9 100644 --- a/src/test/compile-fail/issue-13624.rs +++ b/src/test/compile-fail/issue-13624.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - mod a { pub enum Enum { EnumStructVariant { x: u8, y: u8, z: u8 } diff --git a/src/test/compile-fail/issue-16939.rs b/src/test/compile-fail/issue-16939.rs index 8e7a2a9db3d..e7d3d15e5a9 100644 --- a/src/test/compile-fail/issue-16939.rs +++ b/src/test/compile-fail/issue-16939.rs @@ -14,7 +14,7 @@ // wrong arity. fn _foo<F: Fn()> (f: F) { - |t| f(t); //~ ERROR E0058 + |t| f(t); //~ ERROR E0057 } fn main() {} diff --git a/src/test/compile-fail/issue-18252.rs b/src/test/compile-fail/issue-18252.rs index c884f02892f..930e96f170e 100644 --- a/src/test/compile-fail/issue-18252.rs +++ b/src/test/compile-fail/issue-18252.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - enum Foo { Variant { x: uint } } diff --git a/src/test/compile-fail/lint-dead-code-4.rs b/src/test/compile-fail/lint-dead-code-4.rs index a698bf61f58..7c3242a6a25 100644 --- a/src/test/compile-fail/lint-dead-code-4.rs +++ b/src/test/compile-fail/lint-dead-code-4.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] #![allow(unused_variables)] #![allow(non_camel_case_types)] #![deny(dead_code)] diff --git a/src/test/compile-fail/lint-dead-code-5.rs b/src/test/compile-fail/lint-dead-code-5.rs index 1f0d91dcb3c..1a3bd82a981 100644 --- a/src/test/compile-fail/lint-dead-code-5.rs +++ b/src/test/compile-fail/lint-dead-code-5.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] #![allow(unused_variables)] #![deny(dead_code)] diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index f0b6abe28d3..365081aee1a 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -10,7 +10,6 @@ // When denying at the crate level, be sure to not get random warnings from the // injected intrinsics by the compiler. -#![feature(struct_variant)] #![feature(globs)] #![deny(missing_docs)] #![allow(dead_code)] @@ -106,8 +105,7 @@ enum Baz { pub enum PubBaz { //~ ERROR: missing documentation PubBazA { //~ ERROR: missing documentation - pub a: int, //~ ERROR: missing documentation - b: int + a: int, //~ ERROR: missing documentation }, } @@ -116,15 +114,13 @@ pub enum PubBaz2 { /// dox PubBaz2A { /// dox - pub a: int, - b: int + a: int, }, } #[allow(missing_docs)] pub enum PubBaz3 { PubBaz3A { - pub a: int, b: int }, } diff --git a/src/test/compile-fail/lint-raw-ptr-deriving.rs b/src/test/compile-fail/lint-raw-ptr-deriving.rs index da43324d494..72632b56706 100644 --- a/src/test/compile-fail/lint-raw-ptr-deriving.rs +++ b/src/test/compile-fail/lint-raw-ptr-deriving.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] #![allow(dead_code)] #![deny(raw_pointer_deriving)] diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs index 55ffdcd7f9f..373bcb1f859 100644 --- a/src/test/compile-fail/lint-visible-private-types.rs +++ b/src/test/compile-fail/lint-visible-private-types.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] #![deny(visible_private_types)] #![allow(dead_code)] #![crate_type="lib"] @@ -57,8 +56,7 @@ struct Bar { pub enum Baz { Baz1(Private<int>), //~ ERROR private type in exported type signature Baz2 { - pub x: Private<int>, //~ ERROR private type in exported type signature - y: Private<int> + y: Private<int> //~ ERROR private type in exported type signature }, } diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs index 09916a11f72..120f092d732 100644 --- a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:namespaced_enums.rs -#![feature(struct_variant, globs)] +#![feature(globs)] extern crate namespaced_enums; diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs index 1554d410070..a8f4e6ba090 100644 --- a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs @@ -7,7 +7,7 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant, globs)] +#![feature(globs)] mod m2 { pub enum Foo { diff --git a/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs b/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs index c4d5d734a71..87fe50c8666 100644 --- a/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs +++ b/src/test/compile-fail/non-constant-enum-for-vec-repeat.rs @@ -12,5 +12,5 @@ enum State { ST_NULL, ST_WHITESPACE } fn main() { [ST_NULL, ..(ST_WHITESPACE as uint)]; - //~^ ERROR expected constant integer for repeat count, found variable + //~^ ERROR expected constant integer for repeat count, found non-constant expression } diff --git a/src/test/compile-fail/non-exhaustive-pattern-witness.rs b/src/test/compile-fail/non-exhaustive-pattern-witness.rs index b7ff3a18fcf..7f1204ceee8 100644 --- a/src/test/compile-fail/non-exhaustive-pattern-witness.rs +++ b/src/test/compile-fail/non-exhaustive-pattern-witness.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns, struct_variant)] +#![feature(advanced_slice_patterns)] struct Foo { first: bool, diff --git a/src/test/compile-fail/repeat_count.rs b/src/test/compile-fail/repeat_count.rs index be79a7a915b..38fbb426fb1 100644 --- a/src/test/compile-fail/repeat_count.rs +++ b/src/test/compile-fail/repeat_count.rs @@ -13,8 +13,9 @@ fn main() { let n = 1; let a = [0, ..n]; //~ ERROR expected constant integer for repeat count, found variable - let b = [0, ..()]; //~ ERROR expected positive integer for repeat count, found () - //~^ ERROR: expected `uint`, found `()` + let b = [0, ..()]; +//~^ ERROR expected constant integer for repeat count, found non-constant expression +//~^^ ERROR: expected `uint`, found `()` let c = [0, ..true]; //~ ERROR expected positive integer for repeat count, found boolean //~^ ERROR: expected `uint`, found `bool` let d = [0, ..0.5]; //~ ERROR expected positive integer for repeat count, found float diff --git a/src/test/compile-fail/struct-like-enum-nonexhaustive.rs b/src/test/compile-fail/struct-like-enum-nonexhaustive.rs index 8d1e5b46279..91709e2ea7d 100644 --- a/src/test/compile-fail/struct-like-enum-nonexhaustive.rs +++ b/src/test/compile-fail/struct-like-enum-nonexhaustive.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - enum A { B { x: Option<int> }, C diff --git a/src/test/compile-fail/gated-struct-enums.rs b/src/test/compile-fail/struct-variant-no-pub.rs index f1bd9362bb7..15ed69083e0 100644 --- a/src/test/compile-fail/gated-struct-enums.rs +++ b/src/test/compile-fail/struct-variant-no-pub.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum A { B { foo: int } } -//~^ ERROR: enum struct variants are experimental +enum Foo { + Bar { + pub a: int //~ ERROR: `pub` is not allowed here + } +} fn main() {} - diff --git a/src/test/compile-fail/struct-variant-privacy-xc.rs b/src/test/compile-fail/struct-variant-privacy-xc.rs index 2d289c7f6cd..c58273361ad 100644 --- a/src/test/compile-fail/struct-variant-privacy-xc.rs +++ b/src/test/compile-fail/struct-variant-privacy-xc.rs @@ -9,8 +9,6 @@ // except according to those terms. // aux-build:struct_variant_privacy.rs -#![feature(struct_variant)] - extern crate struct_variant_privacy; fn f(b: struct_variant_privacy::Bar) { //~ ERROR enum `Bar` is private diff --git a/src/test/compile-fail/struct-variant-privacy.rs b/src/test/compile-fail/struct-variant-privacy.rs index 53b8fdf71b7..bf404c27648 100644 --- a/src/test/compile-fail/struct-variant-privacy.rs +++ b/src/test/compile-fail/struct-variant-privacy.rs @@ -7,8 +7,6 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] - mod foo { enum Bar { Baz { a: int } diff --git a/src/test/compile-fail/unsized5.rs b/src/test/compile-fail/unsized5.rs index 41196b60c8e..2f1eb35a426 100644 --- a/src/test/compile-fail/unsized5.rs +++ b/src/test/compile-fail/unsized5.rs @@ -7,7 +7,6 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(struct_variant)] // Test `Sized?` types not allowed in fields (except the last one). diff --git a/src/test/run-pass/concat.rs b/src/test/run-pass/concat.rs index 21c247cc69e..d78f948edc5 100644 --- a/src/test/run-pass/concat.rs +++ b/src/test/run-pass/concat.rs @@ -15,12 +15,12 @@ pub fn main() { assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string()); assert_eq!( - concat!(1, 2i, 3u, 4f32, 4.0, 'a', true, ()), + concat!(1, 2i, 3u, 4f32, 4.0, 'a', true), "12344.0atrue" ); assert!(match "12344.0atrue" { - concat!(1, 2i, 3u, 4f32, 4.0, 'a', true, ()) => true, + concat!(1, 2i, 3u, 4f32, 4.0, 'a', true) => true, _ => false }) } |
