From 5825c72e730a12efdc0e2d60fb9d40f6f5ea771c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 28 Mar 2015 15:57:49 +0300 Subject: [PATCH 01/32] Change the type of constants BYTES/BITS to usize --- src/libcore/num/int_macros.rs | 4 ++-- src/libcore/num/uint_macros.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index fe0d6d13c4c06..3113521e0afff 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -15,11 +15,11 @@ macro_rules! int_module { ($T:ty, $bits:expr) => ( // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of // calling the `mem::size_of` function. #[unstable(feature = "core")] -pub const BITS : u32 = $bits; +pub const BITS : usize = $bits; // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of // calling the `mem::size_of` function. #[unstable(feature = "core")] -pub const BYTES : u32 = ($bits / 8); +pub const BYTES : usize = ($bits / 8); // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of // calling the `Bounded::min_value` function. diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index d0c4885ad00b7..8678295074550 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -13,9 +13,9 @@ macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => ( #[unstable(feature = "core")] -pub const BITS : u32 = $bits; +pub const BITS : usize = $bits; #[unstable(feature = "core")] -pub const BYTES : u32 = ($bits / 8); +pub const BYTES : usize = ($bits / 8); #[stable(feature = "rust1", since = "1.0.0")] pub const MIN: $T = 0 as $T; From ee76be54861189275be483c3f4a72531dc7f7698 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 28 Mar 2015 16:07:25 +0300 Subject: [PATCH 02/32] Remove unnecessary `as usize` --- src/libcollections/bit.rs | 34 ++++----- src/libcollections/enum_set.rs | 2 +- src/libcollectionstest/bit/set.rs | 2 +- src/libcollectionstest/bit/vec.rs | 80 ++++++++++----------- src/libcore/hash/mod.rs | 2 +- src/librustc/middle/dataflow.rs | 8 +-- src/libstd/old_io/mod.rs | 16 ++--- src/libstd/sys/unix/c.rs | 4 +- src/test/run-pass/issue-13763.rs | 2 +- src/test/run-pass/vector-sort-panic-safe.rs | 2 +- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index fcf8c8156944c..99577b0d7e775 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -191,17 +191,17 @@ fn blocks_for_bits(bits: usize) -> usize { // // Note that we can technically avoid this branch with the expression // `(nbits + u32::BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow. - if bits % u32::BITS as usize == 0 { - bits / u32::BITS as usize + if bits % u32::BITS == 0 { + bits / u32::BITS } else { - bits / u32::BITS as usize + 1 + bits / u32::BITS + 1 } } /// Computes the bitmask for the final word of the vector fn mask_for_bits(bits: usize) -> u32 { // Note especially that a perfect multiple of u32::BITS should mask all 1s. - !0 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize + !0 >> (u32::BITS - bits % u32::BITS) % u32::BITS } impl BitVec { @@ -239,7 +239,7 @@ impl BitVec { /// An operation might screw up the unused bits in the last block of the /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up. fn fix_last_block(&mut self) { - let extra_bits = self.len() % u32::BITS as usize; + let extra_bits = self.len() % u32::BITS; if extra_bits > 0 { let mask = (1 << extra_bits) - 1; let storage_len = self.storage.len(); @@ -318,7 +318,7 @@ impl BitVec { /// false, false, true, false])); /// ``` pub fn from_bytes(bytes: &[u8]) -> BitVec { - let len = bytes.len().checked_mul(u8::BITS as usize).expect("capacity overflow"); + let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow"); let mut bit_vec = BitVec::with_capacity(len); let complete_words = bytes.len() / 4; let extra_bytes = bytes.len() % 4; @@ -387,8 +387,8 @@ impl BitVec { if i >= self.nbits { return None; } - let w = i / u32::BITS as usize; - let b = i % u32::BITS as usize; + let w = i / u32::BITS; + let b = i % u32::BITS; self.storage.get(w).map(|&block| (block & (1 << b)) != 0 ) @@ -415,8 +415,8 @@ impl BitVec { reason = "panic semantics are likely to change in the future")] pub fn set(&mut self, i: usize, x: bool) { assert!(i < self.nbits); - let w = i / u32::BITS as usize; - let b = i % u32::BITS as usize; + let w = i / u32::BITS; + let b = i % u32::BITS; let flag = 1 << b; let val = if x { self.storage[w] | flag } else { self.storage[w] & !flag }; @@ -812,7 +812,7 @@ impl BitVec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { - self.storage.capacity().checked_mul(u32::BITS as usize).unwrap_or(usize::MAX) + self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX) } /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`. @@ -843,7 +843,7 @@ impl BitVec { // Correct the old tail word, setting or clearing formerly unused bits let num_cur_blocks = blocks_for_bits(self.nbits); - if self.nbits % u32::BITS as usize > 0 { + if self.nbits % u32::BITS > 0 { let mask = mask_for_bits(self.nbits); if value { self.storage[num_cur_blocks - 1] |= !mask; @@ -893,7 +893,7 @@ impl BitVec { // (3) self.set(i, false); self.nbits = i; - if self.nbits % u32::BITS as usize == 0 { + if self.nbits % u32::BITS == 0 { // (2) self.storage.pop(); } @@ -916,7 +916,7 @@ impl BitVec { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn push(&mut self, elem: bool) { - if self.nbits % u32::BITS as usize == 0 { + if self.nbits % u32::BITS == 0 { self.storage.push(0); } let insert_pos = self.nbits; @@ -1442,7 +1442,7 @@ impl BitSet { // Truncate let trunc_len = cmp::max(old_len - n, 1); bit_vec.storage.truncate(trunc_len); - bit_vec.nbits = trunc_len * u32::BITS as usize; + bit_vec.nbits = trunc_len * u32::BITS; } /// Iterator over each u32 stored in the `BitSet`. @@ -1880,13 +1880,13 @@ impl<'a> Iterator for TwoBitPositions<'a> { fn next(&mut self) -> Option { while self.next_idx < self.set.bit_vec.len() || self.next_idx < self.other.bit_vec.len() { - let bit_idx = self.next_idx % u32::BITS as usize; + let bit_idx = self.next_idx % u32::BITS; if bit_idx == 0 { let s_bit_vec = &self.set.bit_vec; let o_bit_vec = &self.other.bit_vec; // Merging the two words is a bit of an awkward dance since // one BitVec might be longer than the other - let word_idx = self.next_idx / u32::BITS as usize; + let word_idx = self.next_idx / u32::BITS; let w1 = if word_idx < s_bit_vec.storage.len() { s_bit_vec.storage[word_idx] } else { 0 }; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index fe2efc7164d0c..ecf341a5ea6b8 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -83,7 +83,7 @@ pub trait CLike { fn bit(e: &E) -> usize { use core::usize; let value = e.to_usize(); - assert!(value < usize::BITS as usize, + assert!(value < usize::BITS, "EnumSet only supports up to {} variants.", usize::BITS - 1); 1 << value } diff --git a/src/libcollectionstest/bit/set.rs b/src/libcollectionstest/bit/set.rs index 4b4995d5fa7d9..ef2f4969d0cd6 100644 --- a/src/libcollectionstest/bit/set.rs +++ b/src/libcollectionstest/bit/set.rs @@ -408,7 +408,7 @@ mod bench { let mut bit_vec = BitSet::new(); b.iter(|| { for _ in 0..100 { - bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize); + bit_vec.insert((r.next_u32() as usize) % u32::BITS); } black_box(&bit_vec); }); diff --git a/src/libcollectionstest/bit/vec.rs b/src/libcollectionstest/bit/vec.rs index 3826974d1ad6b..de3c0586ab728 100644 --- a/src/libcollectionstest/bit/vec.rs +++ b/src/libcollectionstest/bit/vec.rs @@ -541,43 +541,43 @@ fn test_big_bit_vec_tests() { #[test] fn test_bit_vec_push_pop() { - let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false); - assert_eq!(s.len(), 5 * u32::BITS as usize - 2); - assert_eq!(s[5 * u32::BITS as usize - 3], false); + let mut s = BitVec::from_elem(5 * u32::BITS - 2, false); + assert_eq!(s.len(), 5 * u32::BITS - 2); + assert_eq!(s[5 * u32::BITS - 3], false); s.push(true); s.push(true); - assert_eq!(s[5 * u32::BITS as usize - 2], true); - assert_eq!(s[5 * u32::BITS as usize - 1], true); + assert_eq!(s[5 * u32::BITS - 2], true); + assert_eq!(s[5 * u32::BITS - 1], true); // Here the internal vector will need to be extended s.push(false); - assert_eq!(s[5 * u32::BITS as usize], false); + assert_eq!(s[5 * u32::BITS], false); s.push(false); - assert_eq!(s[5 * u32::BITS as usize + 1], false); - assert_eq!(s.len(), 5 * u32::BITS as usize + 2); + assert_eq!(s[5 * u32::BITS + 1], false); + assert_eq!(s.len(), 5 * u32::BITS + 2); // Pop it all off assert_eq!(s.pop(), Some(false)); assert_eq!(s.pop(), Some(false)); assert_eq!(s.pop(), Some(true)); assert_eq!(s.pop(), Some(true)); - assert_eq!(s.len(), 5 * u32::BITS as usize - 2); + assert_eq!(s.len(), 5 * u32::BITS - 2); } #[test] fn test_bit_vec_truncate() { - let mut s = BitVec::from_elem(5 * u32::BITS as usize, true); + let mut s = BitVec::from_elem(5 * u32::BITS, true); - assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true)); - assert_eq!(s.len(), 5 * u32::BITS as usize); - s.truncate(4 * u32::BITS as usize); - assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true)); - assert_eq!(s.len(), 4 * u32::BITS as usize); + assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true)); + assert_eq!(s.len(), 5 * u32::BITS); + s.truncate(4 * u32::BITS); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); + assert_eq!(s.len(), 4 * u32::BITS); // Truncating to a size > s.len() should be a noop - s.truncate(5 * u32::BITS as usize); - assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true)); - assert_eq!(s.len(), 4 * u32::BITS as usize); - s.truncate(3 * u32::BITS as usize - 10); - assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true)); - assert_eq!(s.len(), 3 * u32::BITS as usize - 10); + s.truncate(5 * u32::BITS); + assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true)); + assert_eq!(s.len(), 4 * u32::BITS); + s.truncate(3 * u32::BITS - 10); + assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true)); + assert_eq!(s.len(), 3 * u32::BITS - 10); s.truncate(0); assert_eq!(s, BitVec::from_elem(0, true)); assert_eq!(s.len(), 0); @@ -585,26 +585,26 @@ fn test_bit_vec_truncate() { #[test] fn test_bit_vec_reserve() { - let mut s = BitVec::from_elem(5 * u32::BITS as usize, true); + let mut s = BitVec::from_elem(5 * u32::BITS, true); // Check capacity - assert!(s.capacity() >= 5 * u32::BITS as usize); - s.reserve(2 * u32::BITS as usize); - assert!(s.capacity() >= 7 * u32::BITS as usize); - s.reserve(7 * u32::BITS as usize); - assert!(s.capacity() >= 12 * u32::BITS as usize); - s.reserve_exact(7 * u32::BITS as usize); - assert!(s.capacity() >= 12 * u32::BITS as usize); - s.reserve(7 * u32::BITS as usize + 1); - assert!(s.capacity() >= 12 * u32::BITS as usize + 1); + assert!(s.capacity() >= 5 * u32::BITS); + s.reserve(2 * u32::BITS); + assert!(s.capacity() >= 7 * u32::BITS); + s.reserve(7 * u32::BITS); + assert!(s.capacity() >= 12 * u32::BITS); + s.reserve_exact(7 * u32::BITS); + assert!(s.capacity() >= 12 * u32::BITS); + s.reserve(7 * u32::BITS + 1); + assert!(s.capacity() >= 12 * u32::BITS + 1); // Check that length hasn't changed - assert_eq!(s.len(), 5 * u32::BITS as usize); + assert_eq!(s.len(), 5 * u32::BITS); s.push(true); s.push(false); s.push(true); - assert_eq!(s[5 * u32::BITS as usize - 1], true); - assert_eq!(s[5 * u32::BITS as usize - 0], true); - assert_eq!(s[5 * u32::BITS as usize + 1], false); - assert_eq!(s[5 * u32::BITS as usize + 2], true); + assert_eq!(s[5 * u32::BITS - 1], true); + assert_eq!(s[5 * u32::BITS - 0], true); + assert_eq!(s[5 * u32::BITS + 1], false); + assert_eq!(s[5 * u32::BITS + 2], true); } #[test] @@ -650,7 +650,7 @@ mod bench { let mut bit_vec = 0 as usize; b.iter(|| { for _ in 0..100 { - bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize); + bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS); } black_box(&bit_vec); }); @@ -683,10 +683,10 @@ mod bench { #[bench] fn bench_bit_set_small(b: &mut Bencher) { let mut r = rng(); - let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false); + let mut bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { for _ in 0..100 { - bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true); + bit_vec.set((r.next_u32() as usize) % u32::BITS, true); } black_box(&bit_vec); }); @@ -703,7 +703,7 @@ mod bench { #[bench] fn bench_bit_vec_small_iter(b: &mut Bencher) { - let bit_vec = BitVec::from_elem(u32::BITS as usize, false); + let bit_vec = BitVec::from_elem(u32::BITS, false); b.iter(|| { let mut sum = 0; for _ in 0..10 { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 2375ae8965005..553e0c0dfe6e4 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -194,7 +194,7 @@ mod impls { fn hash_slice(data: &[$ty], state: &mut H) { // FIXME(#23542) Replace with type ascription. #![allow(trivial_casts)] - let newlen = data.len() * ::$ty::BYTES as usize; + let newlen = data.len() * ::$ty::BYTES; let ptr = data.as_ptr() as *const u8; state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index a112ce6bd287c..4cd56999cb3d5 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -195,7 +195,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { oper: O, id_range: IdRange, bits_per_id: usize) -> DataFlowContext<'a, 'tcx, O> { - let words_per_id = (bits_per_id + usize::BITS as usize - 1) / usize::BITS as usize; + let words_per_id = (bits_per_id + usize::BITS - 1) / usize::BITS; let num_nodes = cfg.graph.all_nodes().len(); debug!("DataFlowContext::new(analysis_name: {}, id_range={:?}, \ @@ -367,7 +367,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { for (word_index, &word) in words.iter().enumerate() { if word != 0 { - let base_index = word_index * usize::BITS as usize; + let base_index = word_index * usize::BITS; for offset in 0..usize::BITS { let bit = 1 << offset; if (word & bit) != 0 { @@ -601,8 +601,8 @@ fn bitwise(out_vec: &mut [usize], fn set_bit(words: &mut [usize], bit: usize) -> bool { debug!("set_bit: words={} bit={}", mut_bits_to_string(words), bit_str(bit)); - let word = bit / usize::BITS as usize; - let bit_in_word = bit % usize::BITS as usize; + let word = bit / usize::BITS; + let bit_in_word = bit % usize::BITS; let bit_mask = 1 << bit_in_word; debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, word); let oldv = words[word]; diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs index df8ac78f7e581..e14a934d8dd1d 100644 --- a/src/libstd/old_io/mod.rs +++ b/src/libstd/old_io/mod.rs @@ -726,28 +726,28 @@ pub trait Reader { /// /// The number of bytes returned is system-dependent. fn read_le_uint(&mut self) -> IoResult { - self.read_le_uint_n(usize::BYTES as usize).map(|i| i as usize) + self.read_le_uint_n(usize::BYTES).map(|i| i as usize) } /// Reads a little-endian integer. /// /// The number of bytes returned is system-dependent. fn read_le_int(&mut self) -> IoResult { - self.read_le_int_n(isize::BYTES as usize).map(|i| i as isize) + self.read_le_int_n(isize::BYTES).map(|i| i as isize) } /// Reads a big-endian unsigned integer. /// /// The number of bytes returned is system-dependent. fn read_be_uint(&mut self) -> IoResult { - self.read_be_uint_n(usize::BYTES as usize).map(|i| i as usize) + self.read_be_uint_n(usize::BYTES).map(|i| i as usize) } /// Reads a big-endian integer. /// /// The number of bytes returned is system-dependent. fn read_be_int(&mut self) -> IoResult { - self.read_be_int_n(isize::BYTES as usize).map(|i| i as isize) + self.read_be_int_n(isize::BYTES).map(|i| i as isize) } /// Reads a big-endian `u64`. @@ -1110,25 +1110,25 @@ pub trait Writer { /// Write a little-endian usize (number of bytes depends on system). #[inline] fn write_le_uint(&mut self, n: usize) -> IoResult<()> { - extensions::u64_to_le_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v)) + extensions::u64_to_le_bytes(n as u64, usize::BYTES, |v| self.write_all(v)) } /// Write a little-endian isize (number of bytes depends on system). #[inline] fn write_le_int(&mut self, n: isize) -> IoResult<()> { - extensions::u64_to_le_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v)) + extensions::u64_to_le_bytes(n as u64, isize::BYTES, |v| self.write_all(v)) } /// Write a big-endian usize (number of bytes depends on system). #[inline] fn write_be_uint(&mut self, n: usize) -> IoResult<()> { - extensions::u64_to_be_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v)) + extensions::u64_to_be_bytes(n as u64, usize::BYTES, |v| self.write_all(v)) } /// Write a big-endian isize (number of bytes depends on system). #[inline] fn write_be_int(&mut self, n: isize) -> IoResult<()> { - extensions::u64_to_be_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v)) + extensions::u64_to_be_bytes(n as u64, isize::BYTES, |v| self.write_all(v)) } /// Write a big-endian u64 (8 bytes). diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index 2514d4bf4a396..5ae508e46106a 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -194,12 +194,12 @@ mod select { #[repr(C)] pub struct fd_set { // FIXME: shouldn't this be a c_ulong? - fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS as usize)] + fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS)] } pub fn fd_set(set: &mut fd_set, fd: i32) { let fd = fd as usize; - set.fds_bits[fd / usize::BITS as usize] |= 1 << (fd % usize::BITS as usize); + set.fds_bits[fd / usize::BITS] |= 1 << (fd % usize::BITS); } } diff --git a/src/test/run-pass/issue-13763.rs b/src/test/run-pass/issue-13763.rs index fb82cccc871e7..e11270c94ca54 100644 --- a/src/test/run-pass/issue-13763.rs +++ b/src/test/run-pass/issue-13763.rs @@ -14,7 +14,7 @@ use std::u8; -const NUM: usize = u8::BITS as usize; +const NUM: usize = u8::BITS; struct MyStruct { nums: [usize; 8] } diff --git a/src/test/run-pass/vector-sort-panic-safe.rs b/src/test/run-pass/vector-sort-panic-safe.rs index 09ecdf45b939e..eca7e62d67cbf 100644 --- a/src/test/run-pass/vector-sort-panic-safe.rs +++ b/src/test/run-pass/vector-sort-panic-safe.rs @@ -57,7 +57,7 @@ impl Drop for DropCounter { } pub fn main() { - assert!(MAX_LEN <= std::usize::BITS as usize); + assert!(MAX_LEN <= std::usize::BITS); // len can't go above 64. for len in 2..MAX_LEN { for _ in 0..REPEATS { From 883adc6763c3dd06b282368698b28a07cdd65fd6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 28 Mar 2015 20:22:48 +0300 Subject: [PATCH 03/32] Fix the fallout --- src/libcoretest/num/int_macros.rs | 6 +++--- src/libcoretest/num/uint_macros.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs index fa41167cae8a6..cb2359873e9dc 100644 --- a/src/libcoretest/num/int_macros.rs +++ b/src/libcoretest/num/int_macros.rs @@ -86,9 +86,9 @@ mod tests { #[test] fn test_count_zeros() { - assert!(A.count_zeros() == BITS - 3); - assert!(B.count_zeros() == BITS - 2); - assert!(C.count_zeros() == BITS - 5); + assert!(A.count_zeros() == BITS as u32 - 3); + assert!(B.count_zeros() == BITS as u32 - 2); + assert!(C.count_zeros() == BITS as u32 - 5); } #[test] diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs index 39e41a4fad3b7..57a44f5082006 100644 --- a/src/libcoretest/num/uint_macros.rs +++ b/src/libcoretest/num/uint_macros.rs @@ -54,9 +54,9 @@ mod tests { #[test] fn test_count_zeros() { - assert!(A.count_zeros() == BITS - 3); - assert!(B.count_zeros() == BITS - 2); - assert!(C.count_zeros() == BITS - 5); + assert!(A.count_zeros() == BITS as u32 - 3); + assert!(B.count_zeros() == BITS as u32 - 2); + assert!(C.count_zeros() == BITS as u32 - 5); } #[test] From 7c3efcc5bb260234fc163340c9fd7aad3d8d780e Mon Sep 17 00:00:00 2001 From: Chris Wong Date: Wed, 1 Apr 2015 19:48:49 +1300 Subject: [PATCH 04/32] Don't reborrow the target of a `write!()` This means passing in e.g. a `Vec` or `String` will work as intended, rather than deref-ing to `&mut [u8]` or `&mut str`. [breaking-change] Closes #23768 --- src/libcore/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d5a7c1d6b2647..e867ed3efd908 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -184,7 +184,7 @@ macro_rules! try { /// ``` #[macro_export] macro_rules! write { - ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*))) + ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) } /// Equivalent to the `write!` macro, except that a newline is appended after From 48aea41adbae76759c1b56e145ce4b46675586a1 Mon Sep 17 00:00:00 2001 From: Carlos Galarza Date: Wed, 1 Apr 2015 10:16:36 -0500 Subject: [PATCH 05/32] Fix sidebar bug Validate if the description is available in the rawSearchIndex --- src/librustdoc/html/static/main.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ca6d944195777..4f8488cca682b 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -713,10 +713,12 @@ if (crates[i] == window.currentCrate) { klass += ' current'; } - var desc = rawSearchIndex[crates[i]].items[0][3]; - div.append($('', {'href': '../' + crates[i] + '/index.html', - 'title': plainSummaryLine(desc), - 'class': klass}).text(crates[i])); + if (rawSearchIndex[crates[i]].items[0]) { + var desc = rawSearchIndex[crates[i]].items[0][3]; + div.append($('', {'href': '../' + crates[i] + '/index.html', + 'title': plainSummaryLine(desc), + 'class': klass}).text(crates[i])); + } } sidebar.append(div); } From 35c1bdb2b44afd11603ec7bff6f31e6b4990699b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 31 Mar 2015 09:10:11 +0300 Subject: [PATCH 06/32] syntax: Rewrite parsing of patterns --- src/libsyntax/parse/parser.rs | 352 +++++++----------- src/test/compile-fail/issue-22426-1.rs | 2 +- src/test/compile-fail/issue-22426-2.rs | 2 +- src/test/compile-fail/issue-22426-3.rs | 2 +- src/test/parse-fail/issue-22647.rs | 2 +- src/test/parse-fail/issue-22712.rs | 2 +- src/test/parse-fail/match-vec-invalid.rs | 2 +- src/test/parse-fail/omitted-arg-in-item-fn.rs | 2 +- .../parse-fail/removed-syntax-larrow-init.rs | 2 +- .../struct-literal-in-match-discriminant.rs | 2 +- 10 files changed, 136 insertions(+), 234 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c721624323923..cb7b93d2ef24b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -40,8 +40,8 @@ use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource}; use ast::{MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot}; -use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; -use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; +use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatMac, PatRange, PatRegion}; +use ast::{PatStruct, PatTup, PatVec, PatWild, PatWildMulti, PatWildSingle}; use ast::{PolyTraitRef, QSelf}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; @@ -86,12 +86,10 @@ bitflags! { flags Restrictions: u8 { const UNRESTRICTED = 0b0000, const RESTRICTION_STMT_EXPR = 0b0001, - const RESTRICTION_NO_BAR_OP = 0b0010, - const RESTRICTION_NO_STRUCT_LITERAL = 0b0100, + const RESTRICTION_NO_STRUCT_LITERAL = 0b0010, } } - type ItemInfo = (Ident, Item_, Option >); /// How to parse a path. There are four different kinds of paths, all of which @@ -2603,13 +2601,6 @@ impl<'a> Parser<'a> { pub fn parse_more_binops(&mut self, lhs: P, min_prec: usize) -> P { if self.expr_is_complete(&*lhs) { return lhs; } - // Prevent dynamic borrow errors later on by limiting the - // scope of the borrows. - if self.token == token::BinOp(token::Or) && - self.restrictions.contains(RESTRICTION_NO_BAR_OP) { - return lhs; - } - self.expected_tokens.push(TokenType::Operator); let cur_op_span = self.span; @@ -2956,6 +2947,22 @@ impl<'a> Parser<'a> { }; } + fn parse_pat_tuple_elements(&mut self) -> Vec> { + let mut fields = vec![]; + if !self.check(&token::CloseDelim(token::Paren)) { + fields.push(self.parse_pat()); + if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) { + while self.eat(&token::Comma) && !self.check(&token::CloseDelim(token::Paren)) { + fields.push(self.parse_pat()); + } + } + if fields.len() == 1 { + self.expect(&token::Comma); + } + } + fields + } + fn parse_pat_vec_elements( &mut self, ) -> (Vec>, Option>, Vec>) { @@ -3087,250 +3094,145 @@ impl<'a> Parser<'a> { return (fields, etc); } + fn parse_pat_range_end(&mut self) -> P { + if self.is_path_start() { + let lo = self.span.lo; + let path = self.parse_path(LifetimeAndTypesWithColons); + let hi = self.last_span.hi; + self.mk_expr(lo, hi, ExprPath(None, path)) + } else { + self.parse_literal_maybe_minus() + } + } + + fn is_path_start(&self) -> bool { + (self.token == token::ModSep || self.token.is_ident() || self.token.is_path()) + && !self.token.is_keyword(keywords::True) && !self.token.is_keyword(keywords::False) + } + /// Parse a pattern. pub fn parse_pat(&mut self) -> P { maybe_whole!(self, NtPat); let lo = self.span.lo; - let mut hi; let pat; match self.token { - // parse _ token::Underscore => { + // Parse _ self.bump(); pat = PatWild(PatWildSingle); - hi = self.last_span.hi; - return P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: pat, - span: mk_sp(lo, hi) - }) } token::BinOp(token::And) | token::AndAnd => { - // parse &pat and &mut pat - let lo = self.span.lo; + // Parse &pat / &mut pat self.expect_and(); - let mutability = if self.eat_keyword(keywords::Mut) { - ast::MutMutable - } else { - ast::MutImmutable - }; - let sub = self.parse_pat(); - pat = PatRegion(sub, mutability); - hi = self.last_span.hi; - return P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: pat, - span: mk_sp(lo, hi) - }) + let mutbl = self.parse_mutability(); + let subpat = self.parse_pat(); + pat = PatRegion(subpat, mutbl); } token::OpenDelim(token::Paren) => { - // parse (pat,pat,pat,...) as tuple + // Parse (pat,pat,pat,...) as tuple pattern self.bump(); - if self.check(&token::CloseDelim(token::Paren)) { - self.bump(); - pat = PatTup(vec![]); - } else { - let mut fields = vec!(self.parse_pat()); - if self.look_ahead(1, |t| *t != token::CloseDelim(token::Paren)) { - while self.check(&token::Comma) { - self.bump(); - if self.check(&token::CloseDelim(token::Paren)) { break; } - fields.push(self.parse_pat()); - } - } - if fields.len() == 1 { self.expect(&token::Comma); } - self.expect(&token::CloseDelim(token::Paren)); - pat = PatTup(fields); - } - hi = self.last_span.hi; - return P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: pat, - span: mk_sp(lo, hi) - }) + let fields = self.parse_pat_tuple_elements(); + self.expect(&token::CloseDelim(token::Paren)); + pat = PatTup(fields); } token::OpenDelim(token::Bracket) => { - // parse [pat,pat,...] as vector pattern + // Parse [pat,pat,...] as vector pattern self.bump(); - let (before, slice, after) = - self.parse_pat_vec_elements(); - + let (before, slice, after) = self.parse_pat_vec_elements(); self.expect(&token::CloseDelim(token::Bracket)); - pat = ast::PatVec(before, slice, after); - hi = self.last_span.hi; - return P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: pat, - span: mk_sp(lo, hi) - }) + pat = PatVec(before, slice, after); } - _ => {} - } - // at this point, token != _, ~, &, &&, (, [ - - if (!(self.token.is_ident() || self.token.is_path()) - && self.token != token::ModSep) - || self.token.is_keyword(keywords::True) - || self.token.is_keyword(keywords::False) { - // Parse an expression pattern or exp ... exp. - // - // These expressions are limited to literals (possibly - // preceded by unary-minus) or identifiers. - let val = self.parse_literal_maybe_minus(); - if (self.check(&token::DotDotDot)) && - self.look_ahead(1, |t| { - *t != token::Comma && *t != token::CloseDelim(token::Bracket) - }) { - self.bump(); - let end = if self.token.is_ident() || self.token.is_path() { - let path = self.parse_path(LifetimeAndTypesWithColons); - let hi = self.span.hi; - self.mk_expr(lo, hi, ExprPath(None, path)) - } else { - self.parse_literal_maybe_minus() - }; - pat = PatRange(val, end); - } else { - pat = PatLit(val); - } - } else if self.eat_keyword(keywords::Mut) { - pat = self.parse_pat_ident(BindByValue(MutMutable)); - } else if self.eat_keyword(keywords::Ref) { - // parse ref pat - let mutbl = self.parse_mutability(); - pat = self.parse_pat_ident(BindByRef(mutbl)); - } else if self.eat_keyword(keywords::Box) { - // `box PAT` - // - // FIXME(#13910): Rename to `PatBox` and extend to full DST - // support. - let sub = self.parse_pat(); - pat = PatBox(sub); - hi = self.last_span.hi; - return P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: pat, - span: mk_sp(lo, hi) - }) - } else { - let can_be_enum_or_struct = self.look_ahead(1, |t| { - match *t { - token::OpenDelim(_) | token::Lt | token::ModSep => true, - _ => false, - } - }); - - if self.look_ahead(1, |t| *t == token::DotDotDot) && - self.look_ahead(2, |t| { - *t != token::Comma && *t != token::CloseDelim(token::Bracket) - }) { - let start = self.parse_expr_res(RESTRICTION_NO_BAR_OP); - self.eat(&token::DotDotDot); - let end = self.parse_expr_res(RESTRICTION_NO_BAR_OP); - pat = PatRange(start, end); - } else if self.token.is_plain_ident() && !can_be_enum_or_struct { - let id = self.parse_ident(); - let id_span = self.last_span; - let pth1 = codemap::Spanned{span:id_span, node: id}; - if self.eat(&token::Not) { - // macro invocation - let delim = self.expect_open_delim(); - let tts = self.parse_seq_to_end(&token::CloseDelim(delim), - seq_sep_none(), - |p| p.parse_token_tree()); - - let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT); - pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span}); - } else { - let sub = if self.eat(&token::At) { - // parse foo @ pat - Some(self.parse_pat()) - } else { - // or just foo - None - }; - pat = PatIdent(BindByValue(MutImmutable), pth1, sub); - } - } else if self.look_ahead(1, |t| *t == token::Lt) { - self.bump(); - self.unexpected() - } else { - // parse an enum pat - let enum_path = self.parse_path(LifetimeAndTypesWithColons); - match self.token { - token::OpenDelim(token::Brace) => { - self.bump(); - let (fields, etc) = - self.parse_pat_fields(); + _ => { + // At this point, token != _, &, &&, (, [ + if self.eat_keyword(keywords::Mut) { + // Parse mut ident @ pat + pat = self.parse_pat_ident(BindByValue(MutMutable)); + } else if self.eat_keyword(keywords::Ref) { + // Parse ref ident @ pat / ref mut ident @ pat + let mutbl = self.parse_mutability(); + pat = self.parse_pat_ident(BindByRef(mutbl)); + } else if self.eat_keyword(keywords::Box) { + // Parse box pat + let subpat = self.parse_pat(); + pat = PatBox(subpat); + } else if self.is_path_start() { + // Parse pattern starting with a path + if self.token.is_plain_ident() && self.look_ahead(1, |t| *t != token::DotDotDot && + *t != token::OpenDelim(token::Brace) && + *t != token::OpenDelim(token::Paren)) { + // Plain idents have some extra abilities here compared to general paths + if self.look_ahead(1, |t| *t == token::Not) { + // Parse macro invocation + let ident = self.parse_ident(); + let ident_span = self.last_span; + let path = ident_to_path(ident_span, ident); self.bump(); - pat = PatStruct(enum_path, fields, etc); + let delim = self.expect_open_delim(); + let tts = self.parse_seq_to_end(&token::CloseDelim(delim), + seq_sep_none(), |p| p.parse_token_tree()); + let mac = MacInvocTT(path, tts, EMPTY_CTXT); + pat = PatMac(codemap::Spanned {node: mac, span: self.span}); + } else { + // Parse ident @ pat + // This can give false positives and parse nullary enums, + // they are dealt with later in resolve + pat = self.parse_pat_ident(BindByValue(MutImmutable)); } - token::DotDotDot => { + } else { + // Parse as a general path + let path = self.parse_path(LifetimeAndTypesWithColons); + match self.token { + token::DotDotDot => { + // Parse range let hi = self.last_span.hi; - let start = self.mk_expr(lo, hi, ExprPath(None, enum_path)); - self.eat(&token::DotDotDot); - let end = if self.token.is_ident() || self.token.is_path() { - let path = self.parse_path(LifetimeAndTypesWithColons); - let hi = self.span.hi; - self.mk_expr(lo, hi, ExprPath(None, path)) + let begin = self.mk_expr(lo, hi, ExprPath(None, path)); + self.bump(); + let end = self.parse_pat_range_end(); + pat = PatRange(begin, end); + } + token::OpenDelim(token::Brace) => { + // Parse struct pattern + self.bump(); + let (fields, etc) = self.parse_pat_fields(); + self.bump(); + pat = PatStruct(path, fields, etc); + } + token::OpenDelim(token::Paren) => { + // Parse tuple struct or enum pattern + if self.look_ahead(1, |t| *t == token::DotDot) { + // This is a "top constructor only" pat + self.bump(); + self.bump(); + self.expect(&token::CloseDelim(token::Paren)); + pat = PatEnum(path, None); } else { - self.parse_literal_maybe_minus() - }; - pat = PatRange(start, end); - } - _ => { - let mut args: Vec> = Vec::new(); - match self.token { - token::OpenDelim(token::Paren) => { - let is_dotdot = self.look_ahead(1, |t| { - match *t { - token::DotDot => true, - _ => false, - } - }); - if is_dotdot { - // This is a "top constructor only" pat - self.bump(); - self.bump(); - self.expect(&token::CloseDelim(token::Paren)); - pat = PatEnum(enum_path, None); - } else { - args = self.parse_enum_variant_seq( - &token::OpenDelim(token::Paren), + let args = self.parse_enum_variant_seq(&token::OpenDelim(token::Paren), &token::CloseDelim(token::Paren), - seq_sep_trailing_allowed(token::Comma), - |p| p.parse_pat() - ); - pat = PatEnum(enum_path, Some(args)); - } - }, - _ => { - if !enum_path.global && - enum_path.segments.len() == 1 && - enum_path.segments[0].parameters.is_empty() - { - // NB: If enum_path is a single identifier, - // this should not be reachable due to special - // handling further above. - // - // However, previously a PatIdent got emitted - // here, so we preserve the branch just in case. - // - // A rewrite of the logic in this function - // would probably make this obvious. - self.span_bug(enum_path.span, - "ident only path should have been covered already"); - } else { - pat = PatEnum(enum_path, Some(args)); - } - } + seq_sep_trailing_allowed(token::Comma), |p| p.parse_pat()); + pat = PatEnum(path, Some(args)); } + } + _ => { + // Parse nullary enum + pat = PatEnum(path, Some(vec![])); + } } } + } else { + // Try to parse everything else as literal with optional minus + let begin = self.parse_literal_maybe_minus(); + if self.eat(&token::DotDotDot) { + let end = self.parse_pat_range_end(); + pat = PatRange(begin, end); + } else { + pat = PatLit(begin); + } } + } } - hi = self.last_span.hi; + + let hi = self.last_span.hi; P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, diff --git a/src/test/compile-fail/issue-22426-1.rs b/src/test/compile-fail/issue-22426-1.rs index f026a5db551e4..6d3d120778830 100644 --- a/src/test/compile-fail/issue-22426-1.rs +++ b/src/test/compile-fail/issue-22426-1.rs @@ -11,7 +11,7 @@ fn main() { match 42 { x < 7 => (), - //~^ error: unexpected token: `<` + //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<` _ => () } } diff --git a/src/test/compile-fail/issue-22426-2.rs b/src/test/compile-fail/issue-22426-2.rs index ea5180e3eec61..6a0653041d45b 100644 --- a/src/test/compile-fail/issue-22426-2.rs +++ b/src/test/compile-fail/issue-22426-2.rs @@ -9,4 +9,4 @@ // except according to those terms. fn a(B<) {} - //~^ error: unexpected token: `<` + //~^ error: expected one of `:` or `@`, found `<` diff --git a/src/test/compile-fail/issue-22426-3.rs b/src/test/compile-fail/issue-22426-3.rs index 2e0b5d6b80fa7..8ea2bcf900c97 100644 --- a/src/test/compile-fail/issue-22426-3.rs +++ b/src/test/compile-fail/issue-22426-3.rs @@ -14,7 +14,7 @@ impl Foo { fn foo(&self) { match *self { Foo(x, y) => { - //~^ error: unexpected token: `<` + //~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<` println!("Goodbye, World!") } } diff --git a/src/test/parse-fail/issue-22647.rs b/src/test/parse-fail/issue-22647.rs index 5de8627001087..1ace57edba3d8 100644 --- a/src/test/parse-fail/issue-22647.rs +++ b/src/test/parse-fail/issue-22647.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - let caller = |f: F| //~ ERROR unexpected token: `<` + let caller = |f: F| //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `<` where F: Fn() -> i32 { let x = f(); diff --git a/src/test/parse-fail/issue-22712.rs b/src/test/parse-fail/issue-22712.rs index abc9e599467e9..ed936cdd9a934 100644 --- a/src/test/parse-fail/issue-22712.rs +++ b/src/test/parse-fail/issue-22712.rs @@ -13,7 +13,7 @@ struct Foo { } fn bar() { - let Foo> //~ ERROR unexpected token: `<` + let Foo> //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `<` } fn main() {} diff --git a/src/test/parse-fail/match-vec-invalid.rs b/src/test/parse-fail/match-vec-invalid.rs index 3e073d34f3261..0fc00c350748a 100644 --- a/src/test/parse-fail/match-vec-invalid.rs +++ b/src/test/parse-fail/match-vec-invalid.rs @@ -11,7 +11,7 @@ fn main() { let a = Vec::new(); match a { - [1, tail.., tail..] => {}, //~ ERROR: expected one of `!`, `,`, or `@`, found `..` + [1, tail.., tail..] => {}, //~ ERROR: expected one of `,` or `@`, found `..` _ => () } } diff --git a/src/test/parse-fail/omitted-arg-in-item-fn.rs b/src/test/parse-fail/omitted-arg-in-item-fn.rs index 729b45df8b430..2826d3b4af942 100644 --- a/src/test/parse-fail/omitted-arg-in-item-fn.rs +++ b/src/test/parse-fail/omitted-arg-in-item-fn.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(x) { //~ ERROR expected one of `!`, `:`, or `@`, found `)` +fn foo(x) { //~ ERROR expected one of `:` or `@`, found `)` } diff --git a/src/test/parse-fail/removed-syntax-larrow-init.rs b/src/test/parse-fail/removed-syntax-larrow-init.rs index 1474cc9dd396d..116848c42c28e 100644 --- a/src/test/parse-fail/removed-syntax-larrow-init.rs +++ b/src/test/parse-fail/removed-syntax-larrow-init.rs @@ -11,5 +11,5 @@ fn removed_moves() { let mut x = 0; let y <- x; - //~^ ERROR expected one of `!`, `:`, `;`, `=`, or `@`, found `<-` + //~^ ERROR expected one of `:`, `;`, `=`, or `@`, found `<-` } diff --git a/src/test/parse-fail/struct-literal-in-match-discriminant.rs b/src/test/parse-fail/struct-literal-in-match-discriminant.rs index cdcf98a42f94b..85addc822939d 100644 --- a/src/test/parse-fail/struct-literal-in-match-discriminant.rs +++ b/src/test/parse-fail/struct-literal-in-match-discriminant.rs @@ -14,7 +14,7 @@ struct Foo { fn main() { match Foo { - x: 3 //~ ERROR expected one of `!`, `=>`, `@`, `if`, or `|`, found `:` + x: 3 //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `:` } { Foo { x: x From 76567a64c1df7881ccd46d790108d9ec768b4c0c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 2 Apr 2015 15:09:43 +0300 Subject: [PATCH 07/32] Fix parsing of patterns in macros --- src/libsyntax/parse/parser.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb7b93d2ef24b..62c03f0e12e3b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3160,7 +3160,9 @@ impl<'a> Parser<'a> { // Parse pattern starting with a path if self.token.is_plain_ident() && self.look_ahead(1, |t| *t != token::DotDotDot && *t != token::OpenDelim(token::Brace) && - *t != token::OpenDelim(token::Paren)) { + *t != token::OpenDelim(token::Paren) && + // Contrary to its definition, a plain ident can be followed by :: in macros + *t != token::ModSep) { // Plain idents have some extra abilities here compared to general paths if self.look_ahead(1, |t| *t == token::Not) { // Parse macro invocation From 63c01cea2d1fa1125bbe2c9bb54d89e0dbb0c196 Mon Sep 17 00:00:00 2001 From: Gleb Kozyrev Date: Thu, 2 Apr 2015 18:50:09 +0300 Subject: [PATCH 08/32] Change PartialEq impls in collections::string to slice notation --- src/libcollections/string.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 7a7725320914f..bce314b6e04a9 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -796,9 +796,9 @@ impl<'a, 'b> Pattern<'a> for &'b String { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for String { #[inline] - fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &String) -> bool { PartialEq::eq(&self[..], &other[..]) } #[inline] - fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &String) -> bool { PartialEq::ne(&self[..], &other[..]) } } macro_rules! impl_eq { @@ -806,17 +806,17 @@ macro_rules! impl_eq { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> PartialEq<$rhs> for $lhs { #[inline] - fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) } #[inline] - fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&self[..], &other[..]) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a> PartialEq<$lhs> for $rhs { #[inline] - fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) } #[inline] - fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&self[..], &other[..]) } } } @@ -828,17 +828,17 @@ impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> { #[inline] - fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&self[..], &other[..]) } #[inline] - fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&self[..], &other[..]) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, 'b> PartialEq> for &'b str { #[inline] - fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) } + fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&self[..], &other[..]) } #[inline] - fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) } + fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&self[..], &other[..]) } } #[unstable(feature = "collections", reason = "waiting on Str stabilization")] From 52340630a6f76eae4e9b605d17c650d57114951e Mon Sep 17 00:00:00 2001 From: Gleb Kozyrev Date: Thu, 2 Apr 2015 18:51:14 +0300 Subject: [PATCH 09/32] Implement PartialEq for String and Cow --- src/libcollections/string.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index bce314b6e04a9..8da8cad98a705 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -822,7 +822,9 @@ macro_rules! impl_eq { } } +impl_eq! { String, str } impl_eq! { String, &'a str } +impl_eq! { Cow<'a, str>, str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] From dd31bb24e8c23f27e19da535e762361b2d8e773a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 31 Mar 2015 19:57:16 -0400 Subject: [PATCH 10/32] Modify variance inference to always infer all trait parameters as invariant. --- src/librustc_typeck/variance.rs | 99 +-------------------------------- 1 file changed, 3 insertions(+), 96 deletions(-) diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index b83d8fc6af7fa..a95919c20f31f 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -644,39 +644,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { ast::ItemTrait(..) => { let trait_def = ty::lookup_trait_def(tcx, did); - let predicates = ty::lookup_super_predicates(tcx, did); - self.add_constraints_from_predicates(&trait_def.generics, - predicates.predicates.as_slice(), - self.covariant); - - let trait_items = ty::trait_items(tcx, did); - for trait_item in &*trait_items { - match *trait_item { - ty::MethodTraitItem(ref method) => { - self.add_constraints_from_predicates( - &method.generics, - method.predicates.predicates.get_slice(FnSpace), - self.contravariant); - - self.add_constraints_from_sig( - &method.generics, - &method.fty.sig, - self.covariant); - } - ty::TypeTraitItem(ref data) => { - // Any trait with an associated type is - // invariant with respect to all of its - // inputs. See length discussion in the comment - // on this module. - let projection_ty = ty::mk_projection(tcx, - trait_def.trait_ref.clone(), - data.name); - self.add_constraints_from_ty(&trait_def.generics, - projection_ty, - self.invariant); - } - } - } + self.add_constraints_from_trait_ref(&trait_def.generics, + &trait_def.trait_ref, + self.invariant); } ast::ItemExternCrate(_) | @@ -1045,69 +1015,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } } - fn add_constraints_from_predicates(&mut self, - generics: &ty::Generics<'tcx>, - predicates: &[ty::Predicate<'tcx>], - variance: VarianceTermPtr<'a>) { - debug!("add_constraints_from_generics({})", - generics.repr(self.tcx())); - - for predicate in predicates.iter() { - match *predicate { - ty::Predicate::Trait(ty::Binder(ref data)) => { - self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance); - } - - ty::Predicate::Equate(ty::Binder(ref data)) => { - // A == B is only true if A and B are the same - // types, not subtypes of one another, so this is - // an invariant position: - self.add_constraints_from_ty(generics, data.0, self.invariant); - self.add_constraints_from_ty(generics, data.1, self.invariant); - } - - ty::Predicate::TypeOutlives(ty::Binder(ref data)) => { - // Why contravariant on both? Let's consider: - // - // Under what conditions is `(T:'t) <: (U:'u)`, - // meaning that `(T:'t) => (U:'u)`. The answer is - // if `U <: T` or `'u <= 't`. Let's see some examples: - // - // (T: 'big) => (T: 'small) - // where 'small <= 'big - // - // (&'small Foo: 't) => (&'big Foo: 't) - // where 'small <= 'big - // note that &'big Foo <: &'small Foo - - let variance_r = self.xform(variance, self.contravariant); - self.add_constraints_from_ty(generics, data.0, variance_r); - self.add_constraints_from_region(generics, data.1, variance_r); - } - - ty::Predicate::RegionOutlives(ty::Binder(ref data)) => { - // `'a : 'b` is still true if 'a gets bigger - self.add_constraints_from_region(generics, data.0, variance); - - // `'a : 'b` is still true if 'b gets smaller - let variance_r = self.xform(variance, self.contravariant); - self.add_constraints_from_region(generics, data.1, variance_r); - } - - ty::Predicate::Projection(ty::Binder(ref data)) => { - self.add_constraints_from_trait_ref(generics, - &*data.projection_ty.trait_ref, - variance); - - // as the equality predicate above, a binder is a - // type equality relation, not a subtyping - // relation - self.add_constraints_from_ty(generics, data.ty, self.invariant); - } - } - } - } - /// Adds constraints appropriate for a function with signature /// `sig` appearing in a context with ambient variance `variance` fn add_constraints_from_sig(&mut self, From 9b5accade787beb0c82fe1f6937c43bfb6abd054 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 31 Mar 2015 19:58:01 -0400 Subject: [PATCH 11/32] Fallout in tests --- src/test/auxiliary/coherence_orphan_lib.rs | 2 +- src/test/auxiliary/lang-item-public.rs | 8 +-- ...ed-types-ICE-when-projecting-out-of-err.rs | 6 +-- src/test/compile-fail/issue-13853-2.rs | 4 +- src/test/compile-fail/issue-19660.rs | 6 +-- .../compile-fail/kindck-impl-type-params.rs | 2 +- src/test/compile-fail/lint-unsafe-code.rs | 7 +-- .../compile-fail/object-safety-phantom-fn.rs | 6 +-- .../compile-fail/on-unimplemented-bad-anno.rs | 6 --- src/test/compile-fail/on-unimplemented.rs | 3 -- src/test/compile-fail/privacy1.rs | 8 +-- src/test/compile-fail/privacy4.rs | 8 +-- ...c-type-in-supertrait-outlives-container.rs | 4 +- ...ions-assoc-type-outlives-container-hrtb.rs | 4 +- ...egions-assoc-type-outlives-container-wc.rs | 4 +- .../regions-assoc-type-outlives-container.rs | 4 +- .../regions-close-object-into-object-1.rs | 6 +-- .../regions-close-object-into-object-2.rs | 6 +-- .../regions-close-object-into-object-3.rs | 8 ++- .../regions-close-object-into-object-4.rs | 6 +-- src/test/compile-fail/required-lang-item.rs | 6 +-- .../trait-bounds-impl-comparison-1.rs | 3 +- .../trait-bounds-impl-comparison-2.rs | 1 - .../unboxed-closure-sugar-equiv.rs | 4 +- .../unboxed-closure-sugar-lifetime-elision.rs | 2 +- .../variance-contravariant-arg-object.rs | 6 ++- .../variance-contravariant-arg-trait-match.rs | 4 +- ...variance-contravariant-self-trait-match.rs | 5 +- .../variance-covariant-arg-object.rs | 3 +- .../variance-covariant-arg-trait-match.rs | 3 +- .../variance-covariant-self-trait-match.rs | 3 +- .../compile-fail/variance-region-bounds.rs | 4 +- .../variance-regions-unused-direct.rs | 2 +- .../compile-fail/variance-trait-bounds.rs | 10 ++-- .../compile-fail/variance-trait-matching.rs | 45 ++++++++++++----- .../compile-fail/variance-types-bounds.rs | 10 ++-- .../variance-unused-region-param.rs | 2 +- .../variance-unused-type-param.rs | 4 -- src/test/run-make/simd-ffi/simd.rs | 8 +-- src/test/run-make/target-specs/foo.rs | 8 +-- .../coherence-subtyping.rs | 4 +- src/test/run-pass/cycle-generic-bound.rs | 4 +- src/test/run-pass/issue-22356.rs | 4 +- ...egions-early-bound-lifetime-in-assoc-fn.rs | 4 +- src/test/run-pass/unsized.rs | 20 ++++---- src/test/run-pass/variance-trait-matching.rs | 49 ------------------- src/test/run-pass/where-for-self.rs | 7 +-- 47 files changed, 117 insertions(+), 216 deletions(-) rename src/test/{compile-fail => run-pass}/coherence-subtyping.rs (94%) delete mode 100644 src/test/run-pass/variance-trait-matching.rs diff --git a/src/test/auxiliary/coherence_orphan_lib.rs b/src/test/auxiliary/coherence_orphan_lib.rs index 93d8fd3da88fb..b22d12300c7d1 100644 --- a/src/test/auxiliary/coherence_orphan_lib.rs +++ b/src/test/auxiliary/coherence_orphan_lib.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait TheTrait : ::std::marker::PhantomFn { +pub trait TheTrait { fn the_fn(&self); } diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 72dfc75f41b96..d195bd7e77bd8 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -12,12 +12,8 @@ #![no_std] #![feature(lang_items)] -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } - #[lang="sized"] -pub trait Sized : PhantomFn {} +pub trait Sized { } #[lang="panic"] fn panic(_: &(&'static str, &'static str, usize)) -> ! { loop {} } @@ -29,7 +25,7 @@ extern fn stack_exhausted() {} extern fn eh_personality() {} #[lang="copy"] -pub trait Copy : PhantomFn { +pub trait Copy { // Empty. } diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs index 04170779ed2f6..0e083e4723634 100644 --- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -16,12 +16,8 @@ #![feature(no_std)] #![no_std] -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } - #[lang="sized"] -pub trait Sized : PhantomFn { +pub trait Sized { // Empty. } diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs index dc697e4784f85..ea0d880f4a1cc 100644 --- a/src/test/compile-fail/issue-13853-2.rs +++ b/src/test/compile-fail/issue-13853-2.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::marker::PhantomFn; - -trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { } +trait FromStructReader<'a> { } trait ResponseHook { fn get<'a, T: FromStructReader<'a>>(&'a self); } diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs index 4435ee0cb225d..a4a8eac682dc3 100644 --- a/src/test/compile-fail/issue-19660.rs +++ b/src/test/compile-fail/issue-19660.rs @@ -13,12 +13,8 @@ #![feature(lang_items, start, no_std)] #![no_std] -#[lang="phantom_fn"] -trait PhantomFn { } -impl PhantomFn for U { } - #[lang = "sized"] -trait Sized : PhantomFn {} +trait Sized { } #[start] fn main(_: isize, _: *const *const u8) -> isize { diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs index 71494fd5f38dc..d4ee93e9ca5d6 100644 --- a/src/test/compile-fail/kindck-impl-type-params.rs +++ b/src/test/compile-fail/kindck-impl-type-params.rs @@ -41,7 +41,7 @@ fn g(val: T) { fn foo<'a>() { let t: S<&'a isize> = S(marker::PhantomData); let a = &t as &Gettable<&'a isize>; - //~^ ERROR cannot infer + //~^ ERROR does not fulfill } fn foo2<'a>() { diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs index 8440cf3a88e10..10f245aaaf9d7 100644 --- a/src/test/compile-fail/lint-unsafe-code.rs +++ b/src/test/compile-fail/lint-unsafe-code.rs @@ -12,18 +12,15 @@ #![allow(dead_code)] #![deny(unsafe_code)] -use std::marker::PhantomFn; - struct Bar; struct Bar2; struct Bar3; #[allow(unsafe_code)] mod allowed_unsafe { - use std::marker::PhantomFn; fn allowed() { unsafe {} } unsafe fn also_allowed() {} - unsafe trait AllowedUnsafe : PhantomFn {} + unsafe trait AllowedUnsafe { } unsafe impl AllowedUnsafe for super::Bar {} } @@ -34,7 +31,7 @@ macro_rules! unsafe_in_macro { } unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function -unsafe trait Foo : PhantomFn {} //~ ERROR: declaration of an `unsafe` trait +unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait trait Baz { diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs index 1c95ee43d27af..518c45ac9dff6 100644 --- a/src/test/compile-fail/object-safety-phantom-fn.rs +++ b/src/test/compile-fail/object-safety-phantom-fn.rs @@ -13,12 +13,10 @@ #![feature(rustc_attrs)] #![allow(dead_code)] -use std::marker::PhantomFn; - -trait Baz : PhantomFn { +trait Baz { } -trait Bar : PhantomFn<(Self, T)> { +trait Bar { } fn make_bar>(t: &T) -> &Bar { diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs index 7538b1c85e533..8580749084d22 100644 --- a/src/test/compile-fail/on-unimplemented-bad-anno.rs +++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs @@ -13,11 +13,8 @@ #![allow(unused)] -use std::marker; - #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] trait Foo - : marker::PhantomFn<(Self,Bar,Baz,Quux)> {} #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] @@ -28,19 +25,16 @@ trait MyFromIterator { #[rustc_on_unimplemented] //~ ERROR this attribute must have a value trait BadAnnotation1 - : marker::MarkerTrait {} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] //~^ ERROR there is no type parameter C on trait BadAnnotation2 trait BadAnnotation2 - : marker::PhantomFn<(Self,A,B)> {} #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] //~^ only named substitution parameters are allowed trait BadAnnotation3 - : marker::PhantomFn<(Self,A,B)> {} pub fn main() { diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs index 2447d0864226a..c4eb467c4f961 100644 --- a/src/test/compile-fail/on-unimplemented.rs +++ b/src/test/compile-fail/on-unimplemented.rs @@ -11,11 +11,8 @@ #![feature(on_unimplemented)] -use std::marker; - #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] trait Foo - : marker::PhantomFn<(Self,Bar,Baz,Quux)> {} fn foobar>() -> T { diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs index 67dccb4c93e1a..f728fdfaf9a80 100644 --- a/src/test/compile-fail/privacy1.rs +++ b/src/test/compile-fail/privacy1.rs @@ -11,15 +11,11 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } - #[lang="sized"] -pub trait Sized : PhantomFn {} +pub trait Sized {} #[lang="copy"] -pub trait Copy : PhantomFn {} +pub trait Copy {} mod bar { // shouldn't bring in too much diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs index adce93af0794f..bcb46663aa849 100644 --- a/src/test/compile-fail/privacy4.rs +++ b/src/test/compile-fail/privacy4.rs @@ -11,12 +11,8 @@ #![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } - -#[lang = "sized"] pub trait Sized : PhantomFn {} -#[lang="copy"] pub trait Copy : PhantomFn {} +#[lang = "sized"] pub trait Sized {} +#[lang="copy"] pub trait Copy {} // Test to make sure that private items imported through globs remain private // when they're used. diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs index 6aa0cc003ce64..9a13541bd0b17 100644 --- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs @@ -15,11 +15,9 @@ #![allow(dead_code)] -use std::marker::PhantomFn; - /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait: PhantomFn { +pub trait TheTrait { type TheAssocType; } diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs index 9736910d7b5fe..0d3d2e296bec6 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs @@ -14,11 +14,9 @@ #![allow(dead_code)] #![feature(rustc_attrs)] -use std::marker::PhantomFn; - /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> { +pub trait TheTrait<'b> { type TheAssocType; } diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs index da7546ce21c60..2ceaea98d2797 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -15,11 +15,9 @@ #![allow(dead_code)] -use std::marker::PhantomFn; - /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait: PhantomFn { +pub trait TheTrait { type TheAssocType; } diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs index e1e72e6f56e93..e3e57ff17115c 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -15,11 +15,9 @@ #![allow(dead_code)] #![feature(rustc_attrs)] -use std::marker::PhantomFn; - /////////////////////////////////////////////////////////////////////////// -pub trait TheTrait: PhantomFn { +pub trait TheTrait { type TheAssocType; } diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs index 4c831a2b65953..5472e09ba4be4 100644 --- a/src/test/compile-fail/regions-close-object-into-object-1.rs +++ b/src/test/compile-fail/regions-close-object-into-object-1.rs @@ -11,12 +11,10 @@ #![feature(box_syntax)] #![allow(warnings)] -use std::marker::PhantomFn; - -trait A : PhantomFn<(Self,T)> { } +trait A { } struct B<'a, T>(&'a (A+'a)); -trait X : ::std::marker::MarkerTrait {} +trait X { } impl<'a, T> X for B<'a, T> {} diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs index 6de49020a6fbb..1ef000852d561 100644 --- a/src/test/compile-fail/regions-close-object-into-object-2.rs +++ b/src/test/compile-fail/regions-close-object-into-object-2.rs @@ -10,12 +10,10 @@ #![feature(box_syntax)] -use std::marker::PhantomFn; - -trait A : PhantomFn<(Self,T)> { } +trait A { } struct B<'a, T>(&'a (A+'a)); -trait X : PhantomFn {} +trait X { } impl<'a, T> X for B<'a, T> {} fn g<'a, T: 'static>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs index b723efff3c902..b7dc759b2717f 100644 --- a/src/test/compile-fail/regions-close-object-into-object-3.rs +++ b/src/test/compile-fail/regions-close-object-into-object-3.rs @@ -11,15 +11,13 @@ #![feature(box_syntax)] #![allow(warnings)] -use std::marker::PhantomFn; - -trait A : PhantomFn<(Self,T)> {} +trait A { } struct B<'a, T>(&'a (A+'a)); -trait X : PhantomFn {} +trait X { } impl<'a, T> X for B<'a, T> {} -fn h<'a, T, U>(v: Box+'static>) -> Box { +fn h<'a, T, U:'static>(v: Box+'static>) -> Box { box B(&*v) as Box //~ ERROR `*v` does not live long enough } diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs index 9b311588bb1ea..247578d253ea0 100644 --- a/src/test/compile-fail/regions-close-object-into-object-4.rs +++ b/src/test/compile-fail/regions-close-object-into-object-4.rs @@ -10,12 +10,10 @@ #![feature(box_syntax)] -use std::marker::PhantomFn; - -trait A : PhantomFn<(Self,T)> {} +trait A { } struct B<'a, T>(&'a (A+'a)); -trait X : PhantomFn {} +trait X { } impl<'a, T> X for B<'a, T> {} fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs index 1b749faf1b8b9..bb80c763a8b39 100644 --- a/src/test/compile-fail/required-lang-item.rs +++ b/src/test/compile-fail/required-lang-item.rs @@ -11,11 +11,7 @@ #![feature(lang_items, no_std)] #![no_std] -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } - -#[lang="sized"] pub trait Sized : PhantomFn {} +#[lang="sized"] pub trait Sized { } // error-pattern:requires `start` lang_item diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs index 34e06cc93658a..a2369f8ffb4f2 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs @@ -13,8 +13,7 @@ use std::marker; -trait A : marker::PhantomFn { -} +trait A { } trait B: A {} diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs index 217540415a7dd..beabdcea2bbe9 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs @@ -15,7 +15,6 @@ trait Iterator { } trait IteratorUtil - : ::std::marker::PhantomFn<(),A> { fn zip>(self, other: U) -> ZipIterator; } diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs index 6d315c1b7a996..dc5576aee650a 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs @@ -16,14 +16,12 @@ #![feature(unboxed_closures)] #![allow(dead_code)] -use std::marker::PhantomFn; - trait Foo { type Output; fn dummy(&self, t: T, u: Self::Output); } -trait Eq : PhantomFn<(Self,X)> { } +trait Eq { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs index bd3530e6e3026..a6f59b7882344 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs @@ -23,7 +23,7 @@ trait Foo { fn dummy(&self, t: T); } -trait Eq : marker::PhantomFn<(Self, X)> { } +trait Eq { } impl Eq for X { } fn eq>() { } diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs index 3330e1d0d51b0..e47d0c33d8f3b 100644 --- a/src/test/compile-fail/variance-contravariant-arg-object.rs +++ b/src/test/compile-fail/variance-contravariant-arg-object.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// This test was previously testing variance on traits. +// But now that it is removed, both cases error. + trait Get : 'static { fn get(&self, t: T); } @@ -25,7 +28,8 @@ fn get_max_from_min<'min, 'max, G>(v: Box>) -> Box> where 'max : 'min { - v + // Previously OK: + v //~ ERROR mismatched types } fn main() { } diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs index caaad4014adfa..b96e19220d04b 100644 --- a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs +++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs @@ -23,7 +23,9 @@ fn get_min_from_max<'min, 'max, G>() fn get_max_from_min<'min, 'max, G>() where 'max : 'min, G : Get<&'min i32> { - impls_get::() + // Previously OK, but now an error because traits are invariant: + + impls_get::() //~ ERROR mismatched types } fn impls_get() where G : Get { } diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs index 013511ed517a8..9d2766d878b34 100644 --- a/src/test/compile-fail/variance-contravariant-self-trait-match.rs +++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs @@ -23,7 +23,10 @@ fn get_min_from_max<'min, 'max, G>() fn get_max_from_min<'min, 'max, G>() where 'max : 'min, G : 'max, &'min G : Get { - impls_get::<&'max G>(); + // Previously OK, but now error because traits are invariant with + // respect to all inputs. + + impls_get::<&'max G>(); //~ ERROR mismatched types } fn impls_get() where G : Get { } diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs index 828c987c08212..757c1c9a8a268 100644 --- a/src/test/compile-fail/variance-covariant-arg-object.rs +++ b/src/test/compile-fail/variance-covariant-arg-object.rs @@ -18,7 +18,8 @@ fn get_min_from_max<'min, 'max>(v: Box>) -> Box> where 'max : 'min { - v + // Previously OK, now an error as traits are invariant. + v //~ ERROR mismatched types } fn get_max_from_min<'min, 'max, G>(v: Box>) diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs index 17761b9c0b19e..097f8eb9864e2 100644 --- a/src/test/compile-fail/variance-covariant-arg-trait-match.rs +++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs @@ -17,7 +17,8 @@ trait Get { fn get_min_from_max<'min, 'max, G>() where 'max : 'min, G : Get<&'max i32> { - impls_get::() + // Previously OK, now an error as traits are invariant. + impls_get::() //~ ERROR mismatched types } fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs index 4e94a3eeb46e6..57ea367b49c30 100644 --- a/src/test/compile-fail/variance-covariant-self-trait-match.rs +++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs @@ -17,7 +17,8 @@ trait Get { fn get_min_from_max<'min, 'max, G>() where 'max : 'min, G : 'max, &'max G : Get { - impls_get::<&'min G>(); + // Previously OK, now an error as traits are invariant. + impls_get::<&'min G>(); //~ ERROR mismatched types } fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/compile-fail/variance-region-bounds.rs b/src/test/compile-fail/variance-region-bounds.rs index 96ae201f6ae94..dfa5dc1444151 100644 --- a/src/test/compile-fail/variance-region-bounds.rs +++ b/src/test/compile-fail/variance-region-bounds.rs @@ -13,11 +13,11 @@ #![feature(rustc_attrs)] #[rustc_variance] -trait Foo: 'static { //~ ERROR types=[[];[-];[]] +trait Foo: 'static { //~ ERROR types=[[];[o];[]] } #[rustc_variance] -trait Bar { //~ ERROR types=[[+];[-];[]] +trait Bar { //~ ERROR types=[[o];[o];[]] fn do_it(&self) where T: 'static; } diff --git a/src/test/compile-fail/variance-regions-unused-direct.rs b/src/test/compile-fail/variance-regions-unused-direct.rs index 396e77652067d..037fff72c8022 100644 --- a/src/test/compile-fail/variance-regions-unused-direct.rs +++ b/src/test/compile-fail/variance-regions-unused-direct.rs @@ -18,7 +18,7 @@ struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used field: &'a [i32] } -trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used +trait Trait<'a, 'd> { // OK on traits fn method(&'a self); } diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs index 88b50058b6580..222d8338aa2c4 100644 --- a/src/test/compile-fail/variance-trait-bounds.rs +++ b/src/test/compile-fail/variance-trait-bounds.rs @@ -16,12 +16,12 @@ // influence variance. #[rustc_variance] -trait Getter { //~ ERROR types=[[+];[-];[]] +trait Getter { //~ ERROR types=[[o];[o];[]] fn get(&self) -> T; } #[rustc_variance] -trait Setter { //~ ERROR types=[[-];[-];[]] +trait Setter { //~ ERROR types=[[o];[o];[]] fn get(&self, T); } @@ -37,16 +37,16 @@ enum TestEnum> {//~ ERROR types=[[*, +];[];[]] } #[rustc_variance] -trait TestTrait> { //~ ERROR types=[[-, +];[-];[]] +trait TestTrait> { //~ ERROR types=[[o, o];[o];[]] fn getter(&self, u: U) -> T; } #[rustc_variance] -trait TestTrait2 : Getter { //~ ERROR types=[[+];[-];[]] +trait TestTrait2 : Getter { //~ ERROR types=[[o];[o];[]] } #[rustc_variance] -trait TestTrait3 { //~ ERROR types=[[-];[-];[]] +trait TestTrait3 { //~ ERROR types=[[o];[o];[]] fn getter>(&self); } diff --git a/src/test/compile-fail/variance-trait-matching.rs b/src/test/compile-fail/variance-trait-matching.rs index ec020f1881893..49dc1e68c221f 100644 --- a/src/test/compile-fail/variance-trait-matching.rs +++ b/src/test/compile-fail/variance-trait-matching.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,22 +8,43 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Issue #5781. Tests that subtyping is handled properly in trait matching. +// pretty-expanded FIXME #23616 -trait Make<'a> { - fn make(x: &'a mut isize) -> Self; +#![allow(dead_code)] + +// Get is covariant in T +trait Get { + fn get(&self) -> T; +} + +struct Cloner { + t: T } -impl<'a> Make<'a> for &'a mut isize { - fn make(x: &'a mut isize) -> &'a mut isize { - x +impl Get for Cloner { + fn get(&self) -> T { + self.t.clone() } } -fn f() -> &'static mut isize { - let mut x = 1; - let y: &'static mut isize = Make::make(&mut x); //~ ERROR `x` does not live long enough - y +fn get<'a, G>(get: &G) -> i32 + where G : Get<&'a i32> +{ + // This fails to type-check because, without variance, we can't + // use `G : Get<&'a i32>` as evidence that `G : Get<&'b i32>`, + // even if `'a : 'b`. + pick(get, &22) //~ ERROR cannot infer } -fn main() {} +fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 + where G : Get<&'b i32> +{ + let v = *get.get(); + if v % 2 != 0 { v } else { *if_odd } +} + +fn main() { + let x = Cloner { t: &23 }; + let y = get(&x); + assert_eq!(y, 23); +} diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs index d53e4cd76105b..a02f20656e7b5 100644 --- a/src/test/compile-fail/variance-types-bounds.rs +++ b/src/test/compile-fail/variance-types-bounds.rs @@ -37,12 +37,12 @@ struct TestIndirect2 { //~ ERROR types=[[o, o];[];[]] } #[rustc_variance] -trait Getter { //~ ERROR types=[[+];[-];[]] +trait Getter { //~ ERROR types=[[o];[o];[]] fn get(&self) -> A; } #[rustc_variance] -trait Setter { //~ ERROR types=[[-];[o];[]] +trait Setter { //~ ERROR types=[[o];[o];[]] fn set(&mut self, a: A); } @@ -53,7 +53,7 @@ trait GetterSetter { //~ ERROR types=[[o];[o];[]] } #[rustc_variance] -trait GetterInTypeBound { //~ ERROR types=[[-];[-];[]] +trait GetterInTypeBound { //~ ERROR types=[[o];[o];[]] // Here, the use of `A` in the method bound *does* affect // variance. Think of it as if the method requested a dictionary // for `T:Getter`. Since this dictionary is an input, it is @@ -63,12 +63,12 @@ trait GetterInTypeBound { //~ ERROR types=[[-];[-];[]] } #[rustc_variance] -trait SetterInTypeBound { //~ ERROR types=[[+];[-];[]] +trait SetterInTypeBound { //~ ERROR types=[[o];[o];[]] fn do_it>(&self); } #[rustc_variance] -struct TestObject { //~ ERROR types=[[-, +];[];[]] +struct TestObject { //~ ERROR types=[[o, o];[];[]] n: Box+Send>, m: Box+Send>, } diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs index 5f504226370a4..407282e5ce0d4 100644 --- a/src/test/compile-fail/variance-unused-region-param.rs +++ b/src/test/compile-fail/variance-unused-region-param.rs @@ -12,6 +12,6 @@ struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used -trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used +trait SomeTrait<'a> { fn foo(&self); } // OK on traits. fn main() {} diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs index 2e867ec3c9384..862d842d62c23 100644 --- a/src/test/compile-fail/variance-unused-type-param.rs +++ b/src/test/compile-fail/variance-unused-type-param.rs @@ -21,10 +21,6 @@ enum SomeEnum { Nothing } //~^ ERROR parameter `A` is never used //~| HELP PhantomData -trait SomeTrait { fn foo(&self); } -//~^ ERROR parameter `A` is never used -//~| HELP PhantomFn - // Here T might *appear* used, but in fact it isn't. enum ListCell { //~^ ERROR parameter `T` is never used diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index f418d5d1fb74f..563fe79e53732 100644 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs @@ -70,14 +70,10 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { } #[lang = "sized"] -pub trait Sized : PhantomFn {} +pub trait Sized { } #[lang = "copy"] -pub trait Copy : PhantomFn {} - -#[lang="phantom_fn"] -pub trait PhantomFn { } -impl PhantomFn for U { } +pub trait Copy { } mod core { pub mod marker { diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index b13c41be55971..9dbae19338809 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -11,15 +11,11 @@ #![feature(lang_items, no_std)] #![no_std] -#[lang="phantom_fn"] -trait PhantomFn { } -impl PhantomFn for U { } - #[lang="copy"] -trait Copy : PhantomFn { } +trait Copy { } #[lang="sized"] -trait Sized : PhantomFn { } +trait Sized { } #[lang="start"] fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 } diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/run-pass/coherence-subtyping.rs similarity index 94% rename from src/test/compile-fail/coherence-subtyping.rs rename to src/test/run-pass/coherence-subtyping.rs index 897cb083f849d..082a39f56312e 100644 --- a/src/test/compile-fail/coherence-subtyping.rs +++ b/src/test/run-pass/coherence-subtyping.rs @@ -16,7 +16,6 @@ trait Contravariant { } impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) { - //~^ ERROR E0119 } impl Contravariant for for<'a> fn(&'a u8, &'a u8) { @@ -29,7 +28,6 @@ trait Covariant { } impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) { - //~^ ERROR E0119 } impl Covariant for for<'a> fn(&'a u8, &'a u8) { @@ -38,7 +36,7 @@ impl Covariant for for<'a> fn(&'a u8, &'a u8) { /////////////////////////////////////////////////////////////////////////// trait Invariant { - fn foo(&self) -> Self { } + fn foo(&self) { } } impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) { diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/run-pass/cycle-generic-bound.rs index 94e4665bb86ab..86b41284cdf35 100644 --- a/src/test/run-pass/cycle-generic-bound.rs +++ b/src/test/run-pass/cycle-generic-bound.rs @@ -12,9 +12,7 @@ // pretty-expanded FIXME #23616 -use std::marker::PhantomFn; - -trait Chromosome> : PhantomFn<(Self,X)> { +trait Chromosome> { } fn main() { } diff --git a/src/test/run-pass/issue-22356.rs b/src/test/run-pass/issue-22356.rs index a54490386d0e7..51a871d59b361 100644 --- a/src/test/run-pass/issue-22356.rs +++ b/src/test/run-pass/issue-22356.rs @@ -10,7 +10,7 @@ // pretty-expanded FIXME #23616 -use std::marker::{PhantomData, PhantomFn}; +use std::marker::PhantomData; pub struct Handle(T, I); @@ -34,7 +34,7 @@ impl BufferHandle { pub type RawBufferHandle = Handle<::Buffer, String>; -pub trait Device: PhantomFn { +pub trait Device { type Buffer; } diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs index 9aed915512434..0ffbc432aaeb5 100644 --- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs +++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs @@ -27,9 +27,7 @@ pub trait Decoder<'v> { fn read(&mut self) -> Value<'v>; } -pub trait Decodable<'v, D: Decoder<'v>> - : marker::PhantomFn<(), &'v isize> -{ +pub trait Decodable<'v, D: Decoder<'v>> { fn decode(d: &mut D) -> Self; } diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs index 8ff8169ef497c..449d6b37e9f89 100644 --- a/src/test/run-pass/unsized.rs +++ b/src/test/run-pass/unsized.rs @@ -12,17 +12,17 @@ // pretty-expanded FIXME #23616 -use std::marker::{PhantomData, PhantomFn}; +use std::marker::PhantomData; -trait T1 : PhantomFn { } -pub trait T2 : PhantomFn { } -trait T3 : T2 + PhantomFn { } -trait T4 : PhantomFn<(Self,X)> {} -trait T5 : PhantomFn<(Self,X,Y)> {} -trait T6 : PhantomFn<(Self,X,Y)> {} -trait T7 : PhantomFn<(Self,X,Y)> {} -trait T8 : PhantomFn<(Self,X)> {} -trait T9 : PhantomFn<(Self,X)> {} +trait T1 { } +pub trait T2 { } +trait T3 : T2 { } +trait T4 { } +trait T5 { } +trait T6 { } +trait T7 { } +trait T8 { } +trait T9 { } struct S1(PhantomData); enum E { E1(PhantomData) } impl T1 for S1 {} diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs deleted file mode 100644 index 5a179bfc7d47f..0000000000000 --- a/src/test/run-pass/variance-trait-matching.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// pretty-expanded FIXME #23616 - -#![allow(dead_code)] - -// Get is covariant in T -trait Get { - fn get(&self) -> T; -} - -struct Cloner { - t: T -} - -impl Get for Cloner { - fn get(&self) -> T { - self.t.clone() - } -} - -fn get<'a, G>(get: &G) -> i32 - where G : Get<&'a i32> -{ - // This call only type checks if we can use `G : Get<&'a i32>` as - // evidence that `G : Get<&'b i32>` where `'a : 'b`. - pick(get, &22) -} - -fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 - where G : Get<&'b i32> -{ - let v = *get.get(); - if v % 2 != 0 { v } else { *if_odd } -} - -fn main() { - let x = Cloner { t: &23 }; - let y = get(&x); - assert_eq!(y, 23); -} diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs index 8535d76d4714c..eb95b13d3fa5b 100644 --- a/src/test/run-pass/where-for-self.rs +++ b/src/test/run-pass/where-for-self.rs @@ -13,18 +13,13 @@ // pretty-expanded FIXME #23616 -use std::marker::PhantomFn; - static mut COUNT: u32 = 1; -trait Bar<'a> - : PhantomFn<&'a ()> -{ +trait Bar<'a> { fn bar(&self); } trait Baz<'a> - : PhantomFn<&'a ()> { fn baz(&self); } From 628d715ff42c83ab74bef3a5a5c5ac3c2f915c11 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 31 Mar 2015 19:58:15 -0400 Subject: [PATCH 12/32] Deprecate MarkerTrait and PhantomFn. --- src/libarena/lib.rs | 5 ++- src/libcore/marker.rs | 79 +++++++----------------------------------- src/libcore/nonzero.rs | 1 + 3 files changed, 17 insertions(+), 68 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 7843be0b483eb..3f85af9719778 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -192,13 +192,16 @@ struct TyDesc { align: usize } +trait AllTypes { fn dummy(&self) { } } +impl AllTypes for T { } + unsafe fn get_tydesc() -> *const TyDesc { use std::raw::TraitObject; let ptr = &*(1 as *const T); // Can use any trait that is implemented for all types. - let obj = mem::transmute::<&marker::MarkerTrait, TraitObject>(ptr); + let obj = mem::transmute::<&AllTypes, TraitObject>(ptr); obj.vtable as *const TyDesc } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 619f983aee071..e867ba0285439 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -35,6 +35,7 @@ use hash::Hasher; #[stable(feature = "rust1", since = "1.0.0")] #[lang="send"] #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] +#[allow(deprecated)] pub unsafe trait Send : MarkerTrait { // empty. } @@ -50,6 +51,7 @@ impl !Send for Managed { } #[lang="sized"] #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable +#[allow(deprecated)] pub trait Sized : MarkerTrait { // Empty. } @@ -203,6 +205,7 @@ pub trait Copy : Clone { #[stable(feature = "rust1", since = "1.0.0")] #[lang="sync"] #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] +#[allow(deprecated)] pub unsafe trait Sync : MarkerTrait { // Empty } @@ -269,14 +272,10 @@ macro_rules! impls{ ) } -/// `MarkerTrait` is intended to be used as the supertrait for traits -/// that don't have any methods but instead serve just to designate -/// categories of types. An example would be the `Send` trait, which -/// indicates types that are sendable: `Send` does not itself offer -/// any methods, but instead is used to gate access to data. -/// -/// FIXME. Better documentation needed here! -#[stable(feature = "rust1", since = "1.0.0")] +/// `MarkerTrait` is deprecated and no longer needed. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "No longer needed")] +#[allow(deprecated)] pub trait MarkerTrait : PhantomFn { } // ~~~~~ <-- FIXME(#22806)? // @@ -284,68 +283,13 @@ pub trait MarkerTrait : PhantomFn { } // but we should ideally solve the underlying problem. That's a bit // complicated. +#[allow(deprecated)] impl MarkerTrait for T { } -/// `PhantomFn` is a marker trait for use with traits that contain -/// type or lifetime parameters that do not appear in any of their -/// methods. In that case, you can either remove those parameters, or -/// add a `PhantomFn` supertrait that reflects the signature of -/// methods that compiler should "pretend" exists. This most commonly -/// occurs for traits with no methods: in that particular case, you -/// can extend `MarkerTrait`, which is equivalent to -/// `PhantomFn`. -/// -/// # Examples -/// -/// As an example, consider a trait with no methods like `Even`, meant -/// to represent types that are "even": -/// -/// ```rust,ignore -/// trait Even { } -/// ``` -/// -/// In this case, because the implicit parameter `Self` is unused, the -/// compiler will issue an error. The only purpose of this trait is to -/// categorize types (and hence instances of those types) as "even" or -/// not, so if we *were* going to have a method, it might look like: -/// -/// ```rust,ignore -/// trait Even { -/// fn is_even(self) -> bool { true } -/// } -/// ``` -/// -/// Therefore, we can model a method like this as follows: -/// -/// ``` -/// use std::marker::PhantomFn; -/// trait Even : PhantomFn { } -/// ``` -/// -/// Another equivalent, but clearer, option would be to use -/// `MarkerTrait`: -/// -/// ``` -/// # #![feature(core)] -/// use std::marker::MarkerTrait; -/// trait Even : MarkerTrait { } -/// ``` -/// -/// # Parameters -/// -/// - `A` represents the type of the method's argument. You can use a -/// tuple to represent "multiple" arguments. Any types appearing here -/// will be considered "contravariant". -/// - `R`, if supplied, represents the method's return type. This defaults -/// to `()` as it is rarely needed. -/// -/// # Additional reading -/// -/// More details and background can be found in [RFC 738][738]. -/// -/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md +/// `PhantomFn` is a deprecated marker trait that is no longer needed. #[lang="phantom_fn"] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "No longer needed")] pub trait PhantomFn { } /// `PhantomData` allows you to describe that a type acts as if it stores a value of type `T`, @@ -444,6 +388,7 @@ mod impls { /// [1]: http://en.wikipedia.org/wiki/Parametricity #[rustc_reflect_like] #[unstable(feature = "core", reason = "requires RFC and more experience")] +#[allow(deprecated)] pub trait Reflect : MarkerTrait { } diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 230587b726fd1..3df4d00f60cc4 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -14,6 +14,7 @@ use marker::{Sized, MarkerTrait}; use ops::Deref; /// Unsafe trait to indicate what types are usable with the NonZero struct +#[allow(deprecated)] pub unsafe trait Zeroable : MarkerTrait {} unsafe impl Zeroable for *const T {} From 38fdd50e0b16e947c5a3879f593f51fd769deae2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 1 Apr 2015 04:41:45 -0400 Subject: [PATCH 13/32] Remove *most* mentions of phantom fns and variance on traits. Leave some comments and also leave the entries in the variance tables for now. --- src/libcore/marker.rs | 28 +- src/librustc/middle/lang_items.rs | 1 - src/librustc/middle/traits/object_safety.rs | 9 +- src/librustc/middle/traits/select.rs | 8 - src/librustc_typeck/check/wf.rs | 42 +-- src/librustc_typeck/variance.rs | 239 +++++++++--------- .../variance-contravariant-arg-object.rs | 4 +- .../variance-contravariant-arg-trait-match.rs | 3 + ...variance-contravariant-self-trait-match.rs | 3 + .../variance-covariant-arg-object.rs | 3 + .../variance-covariant-arg-trait-match.rs | 3 + .../variance-covariant-self-trait-match.rs | 3 + 12 files changed, 174 insertions(+), 172 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index e867ba0285439..352f7d869774c 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -276,12 +276,15 @@ macro_rules! impls{ #[unstable(feature = "core", reason = "deprecated")] #[deprecated(since = "1.0.0", reason = "No longer needed")] #[allow(deprecated)] +#[cfg(stage0)] pub trait MarkerTrait : PhantomFn { } -// ~~~~~ <-- FIXME(#22806)? -// -// Marker trait has been made invariant so as to avoid inf recursion, -// but we should ideally solve the underlying problem. That's a bit -// complicated. + +/// `MarkerTrait` is deprecated and no longer needed. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "No longer needed")] +#[allow(deprecated)] +#[cfg(not(stage0))] +pub trait MarkerTrait { } #[allow(deprecated)] impl MarkerTrait for T { } @@ -290,7 +293,20 @@ impl MarkerTrait for T { } #[lang="phantom_fn"] #[unstable(feature = "core", reason = "deprecated")] #[deprecated(since = "1.0.0", reason = "No longer needed")] -pub trait PhantomFn { } +#[cfg(stage0)] +pub trait PhantomFn { +} + +/// `PhantomFn` is a deprecated marker trait that is no longer needed. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "No longer needed")] +#[cfg(not(stage0))] +pub trait PhantomFn { +} + +#[allow(deprecated)] +#[cfg(not(stage0))] +impl PhantomFn for T { } /// `PhantomData` allows you to describe that a type acts as if it stores a value of type `T`, /// even though it does not. This allows you to inform the compiler about certain safety properties diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index a08de58f909d3..89a8625856c2c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -321,7 +321,6 @@ lets_do_this! { ExchangeHeapLangItem, "exchange_heap", exchange_heap; OwnedBoxLangItem, "owned_box", owned_box; - PhantomFnItem, "phantom_fn", phantom_fn; PhantomDataItem, "phantom_data", phantom_data; // Deprecated: diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index af6bb4ccccd80..a2ff86cd06590 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -138,11 +138,10 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, match predicate { ty::Predicate::Trait(ref data) => { // In the case of a trait predicate, we can skip the "self" type. - Some(data.def_id()) != tcx.lang_items.phantom_fn() && - data.0.trait_ref.substs.types.get_slice(TypeSpace) - .iter() - .cloned() - .any(is_self) + data.0.trait_ref.substs.types.get_slice(TypeSpace) + .iter() + .cloned() + .any(is_self) } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) | diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index f7e7d071f8ca4..ad7d96c652d9b 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -836,14 +836,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ambiguous: false }; - // Check for the `PhantomFn` trait. This is really just a - // special annotation that is *always* considered to match, no - // matter what the type parameters are etc. - if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) { - candidates.vec.push(PhantomFnCandidate); - return Ok(candidates); - } - // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index a86e2b17c93b8..eb06caf7d5a63 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -117,15 +117,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_variances_for_type_defn(item, ast_generics); } - ast::ItemTrait(_, ref ast_generics, _, ref items) => { + ast::ItemTrait(_, _, _, ref items) => { let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(item.id)); - reject_non_type_param_bounds( - ccx.tcx, - item.span, - &trait_predicates); - self.check_variances(item, ast_generics, &trait_predicates, - self.tcx().lang_items.phantom_fn()); + reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates); if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { if !items.is_empty() { ccx.tcx.sess.span_err( @@ -287,30 +282,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { ast_generics: &ast::Generics) { let item_def_id = local_def(item.id); - let predicates = ty::lookup_predicates(self.tcx(), item_def_id); - self.check_variances(item, - ast_generics, - &predicates, - self.tcx().lang_items.phantom_data()); - } - - fn check_variances(&self, - item: &ast::Item, - ast_generics: &ast::Generics, - ty_predicates: &ty::GenericPredicates<'tcx>, - suggested_marker_id: Option) - { - let variance_lang_items = &[ - self.tcx().lang_items.phantom_fn(), - self.tcx().lang_items.phantom_data(), - ]; - - let item_def_id = local_def(item.id); - let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id)); - if is_lang_item { - return; - } - + let ty_predicates = ty::lookup_predicates(self.tcx(), item_def_id); let variances = ty::item_variances(self.tcx(), item_def_id); let mut constrained_parameters: HashSet<_> = @@ -331,7 +303,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { continue; } let span = self.ty_param_span(ast_generics, item, space, index); - self.report_bivariance(span, param_ty.name, suggested_marker_id); + self.report_bivariance(span, param_ty.name); } for (space, index, &variance) in variances.regions.iter_enumerated() { @@ -342,7 +314,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { assert_eq!(space, TypeSpace); let span = ast_generics.lifetimes[index].lifetime.span; let name = ast_generics.lifetimes[index].lifetime.name; - self.report_bivariance(span, name, suggested_marker_id); + self.report_bivariance(span, name); } } @@ -377,14 +349,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { fn report_bivariance(&self, span: Span, - param_name: ast::Name, - suggested_marker_id: Option) + param_name: ast::Name) { self.tcx().sess.span_err( span, &format!("parameter `{}` is never used", param_name.user_string(self.tcx()))); + let suggested_marker_id = self.tcx().lang_items.phantom_data(); match suggested_marker_id { Some(def_id) => { self.tcx().sess.fileline_help( diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index a95919c20f31f..da2de731d648a 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -18,34 +18,121 @@ //! defined on type `X`, we only consider the definition of the type `X` //! and the definitions of any types it references. //! -//! We only infer variance for type parameters found on *types*: structs, -//! enums, and traits. We do not infer variance for type parameters found -//! on fns or impls. This is because those things are not type definitions -//! and variance doesn't really make sense in that context. -//! -//! It is worth covering what variance means in each case. For structs and -//! enums, I think it is fairly straightforward. The variance of the type +//! We only infer variance for type parameters found on *data types* +//! like structs and enums. In these cases, there is fairly straightforward +//! explanation for what variance means. The variance of the type //! or lifetime parameters defines whether `T` is a subtype of `T` //! (resp. `T<'a>` and `T<'b>`) based on the relationship of `A` and `B` -//! (resp. `'a` and `'b`). (FIXME #3598 -- we do not currently make use of -//! the variances we compute for type parameters.) +//! (resp. `'a` and `'b`). +//! +//! We do not infer variance for type parameters found on traits, fns, +//! or impls. Variance on trait parameters can make indeed make sense +//! (and we used to compute it) but it is actually rather subtle in +//! meaning and not that useful in practice, so we removed it. See the +//! addendum for some details. Variances on fn/impl parameters, otoh, +//! doesn't make sense because these parameters are instantiated and +//! then forgotten, they don't persist in types or compiled +//! byproducts. +//! +//! ### The algorithm +//! +//! The basic idea is quite straightforward. We iterate over the types +//! defined and, for each use of a type parameter X, accumulate a +//! constraint indicating that the variance of X must be valid for the +//! variance of that use site. We then iteratively refine the variance of +//! X until all constraints are met. There is *always* a sol'n, because at +//! the limit we can declare all type parameters to be invariant and all +//! constraints will be satisfied. +//! +//! As a simple example, consider: +//! +//! enum Option { Some(A), None } +//! enum OptionalFn { Some(|B|), None } +//! enum OptionalMap { Some(|C| -> C), None } +//! +//! Here, we will generate the constraints: +//! +//! 1. V(A) <= + +//! 2. V(B) <= - +//! 3. V(C) <= + +//! 4. V(C) <= - +//! +//! These indicate that (1) the variance of A must be at most covariant; +//! (2) the variance of B must be at most contravariant; and (3, 4) the +//! variance of C must be at most covariant *and* contravariant. All of these +//! results are based on a variance lattice defined as follows: +//! +//! * Top (bivariant) +//! - + +//! o Bottom (invariant) +//! +//! Based on this lattice, the solution V(A)=+, V(B)=-, V(C)=o is the +//! optimal solution. Note that there is always a naive solution which +//! just declares all variables to be invariant. +//! +//! You may be wondering why fixed-point iteration is required. The reason +//! is that the variance of a use site may itself be a function of the +//! variance of other type parameters. In full generality, our constraints +//! take the form: +//! +//! V(X) <= Term +//! Term := + | - | * | o | V(X) | Term x Term +//! +//! Here the notation V(X) indicates the variance of a type/region +//! parameter `X` with respect to its defining class. `Term x Term` +//! represents the "variance transform" as defined in the paper: +//! +//! If the variance of a type variable `X` in type expression `E` is `V2` +//! and the definition-site variance of the [corresponding] type parameter +//! of a class `C` is `V1`, then the variance of `X` in the type expression +//! `C` is `V3 = V1.xform(V2)`. +//! +//! ### Constraints +//! +//! If I have a struct or enum with where clauses: +//! +//! struct Foo { ... } +//! +//! you might wonder whether the variance of `T` with respect to `Bar` +//! affects the variance `T` with respect to `Foo`. I claim no. The +//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t +//! `Foo`. And then we have a `Foo` that is upcast to `Foo`, where +//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold. In that +//! case, the upcast will be illegal, but not because of a variance +//! failure, but rather because the target type `Foo` is itself just +//! not well-formed. Basically we get to assume well-formedness of all +//! types involved before considering variance. //! -//! ### Variance on traits +//! ### Addendum: Variance on traits //! -//! The meaning of variance for trait parameters is more subtle and worth -//! expanding upon. There are in fact two uses of the variance values we -//! compute. +//! As mentioned above, we used to permit variance on traits. This was +//! computed based on the appearance of trait type parameters in +//! method signatures and was used to represent the compatibility of +//! vtables in trait objects (and also "virtual" vtables or dictionary +//! in trait bounds). One complication was that variance for +//! associated types is less obvious, since they can be projected out +//! and put to myriad uses, so it's not clear when it is safe to allow +//! `X::Bar` to vary (or indeed just what that means). Moreover (as +//! covered below) all inputs on any trait with an associated type had +//! to be invariant, limiting the applicability. Finally, the +//! annotations (`MarkerTrait`, `PhantomFn`) needed to ensure that all +//! trait type parameters had a variance were confusing and annoying +//! for little benefit. //! -//! #### Trait variance and object types +//! Just for historical reference,I am going to preserve some text indicating +//! how one could interpret variance and trait matching. //! -//! The first is for object types. Just as with structs and enums, we can -//! decide the subtyping relationship between two object types `&Trait` -//! and `&Trait` based on the relationship of `A` and `B`. Note that -//! for object types we ignore the `Self` type parameter -- it is unknown, -//! and the nature of dynamic dispatch ensures that we will always call a +//! #### Variance and object types +//! +//! Just as with structs and enums, we can decide the subtyping +//! relationship between two object types `&Trait` and `&Trait` +//! based on the relationship of `A` and `B`. Note that for object +//! types we ignore the `Self` type parameter -- it is unknown, and +//! the nature of dynamic dispatch ensures that we will always call a //! function that is expected the appropriate `Self` type. However, we -//! must be careful with the other type parameters, or else we could end -//! up calling a function that is expecting one type but provided another. +//! must be careful with the other type parameters, or else we could +//! end up calling a function that is expecting one type but provided +//! another. //! //! To see what I mean, consider a trait like so: //! @@ -135,104 +222,24 @@ //! //! These conditions are satisfied and so we are happy. //! -//! ### The algorithm -//! -//! The basic idea is quite straightforward. We iterate over the types -//! defined and, for each use of a type parameter X, accumulate a -//! constraint indicating that the variance of X must be valid for the -//! variance of that use site. We then iteratively refine the variance of -//! X until all constraints are met. There is *always* a sol'n, because at -//! the limit we can declare all type parameters to be invariant and all -//! constraints will be satisfied. -//! -//! As a simple example, consider: -//! -//! enum Option { Some(A), None } -//! enum OptionalFn { Some(|B|), None } -//! enum OptionalMap { Some(|C| -> C), None } -//! -//! Here, we will generate the constraints: -//! -//! 1. V(A) <= + -//! 2. V(B) <= - -//! 3. V(C) <= + -//! 4. V(C) <= - -//! -//! These indicate that (1) the variance of A must be at most covariant; -//! (2) the variance of B must be at most contravariant; and (3, 4) the -//! variance of C must be at most covariant *and* contravariant. All of these -//! results are based on a variance lattice defined as follows: -//! -//! * Top (bivariant) -//! - + -//! o Bottom (invariant) +//! #### Variance and associated types //! -//! Based on this lattice, the solution V(A)=+, V(B)=-, V(C)=o is the -//! optimal solution. Note that there is always a naive solution which -//! just declares all variables to be invariant. -//! -//! You may be wondering why fixed-point iteration is required. The reason -//! is that the variance of a use site may itself be a function of the -//! variance of other type parameters. In full generality, our constraints -//! take the form: -//! -//! V(X) <= Term -//! Term := + | - | * | o | V(X) | Term x Term -//! -//! Here the notation V(X) indicates the variance of a type/region -//! parameter `X` with respect to its defining class. `Term x Term` -//! represents the "variance transform" as defined in the paper: -//! -//! If the variance of a type variable `X` in type expression `E` is `V2` -//! and the definition-site variance of the [corresponding] type parameter -//! of a class `C` is `V1`, then the variance of `X` in the type expression -//! `C` is `V3 = V1.xform(V2)`. -//! -//! ### Constraints -//! -//! If I have a struct or enum with where clauses: -//! -//! struct Foo { ... } -//! -//! you might wonder whether the variance of `T` with respect to `Bar` -//! affects the variance `T` with respect to `Foo`. I claim no. The -//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t -//! `Foo`. And then we have a `Foo` that is upcast to `Foo`, where -//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold. In that -//! case, the upcast will be illegal, but not because of a variance -//! failure, but rather because the target type `Foo` is itself just -//! not well-formed. Basically we get to assume well-formedness of all -//! types involved before considering variance. -//! -//! ### Associated types -//! -//! Any trait with an associated type is invariant with respect to all -//! of its inputs. To see why this makes sense, consider what -//! subtyping for a trait reference means: +//! Traits with associated types -- or at minimum projection +//! expressions -- must be invariant with respect to all of their +//! inputs. To see why this makes sense, consider what subtyping for a +//! trait reference means: //! //! <: //! -//! means that if I know that `T as Trait`, -//! I also know that `U as -//! Trait`. Moreover, if you think of it as -//! dictionary passing style, it means that -//! a dictionary for `` is safe -//! to use where a dictionary for `` is expected. -//! -//! The problem is that when you can -//! project types out from ``, -//! the relationship to types projected out -//! of `` is completely unknown -//! unless `T==U` (see #21726 for more -//! details). Making `Trait` invariant -//! ensures that this is true. +//! means that if I know that `T as Trait`, I also know that `U as +//! Trait`. Moreover, if you think of it as dictionary passing style, +//! it means that a dictionary for `` is safe to use where +//! a dictionary for `` is expected. //! -//! *Historical note: we used to preserve this invariant another way, -//! by tweaking the subtyping rules and requiring that when a type `T` -//! appeared as part of a projection, that was considered an invariant -//! location, but this version does away with the need for those -//! somewhat "special-case-feeling" rules.* +//! The problem is that when you can project types out from ``, the relationship to types projected out of `` +//! is completely unknown unless `T==U` (see #21726 for more +//! details). Making `Trait` invariant ensures that this is true. //! //! Another related reason is that if we didn't make traits with //! associated types invariant, then projection is no longer a @@ -383,7 +390,6 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec)> { let all = vec![ - (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]), (tcx.lang_items.phantom_data(), vec![ty::Covariant]), (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]), @@ -520,6 +526,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { self.add_inferreds_for_item(item.id, false, generics); } ast::ItemTrait(_, ref generics, _, _) => { + // Note: all inputs for traits are ultimately + // constrained to be invariant. See `visit_item` in + // the impl for `ConstraintContext` below. self.add_inferreds_for_item(item.id, true, generics); visit::walk_item(self, item); } diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs index e47d0c33d8f3b..1795ac95358d7 100644 --- a/src/test/compile-fail/variance-contravariant-arg-object.rs +++ b/src/test/compile-fail/variance-contravariant-arg-object.rs @@ -10,8 +10,8 @@ #![allow(dead_code)] -// This test was previously testing variance on traits. -// But now that it is removed, both cases error. +// Test that even when `T` is only used in contravariant position, it +// is treated as invariant. trait Get : 'static { fn get(&self, t: T); diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs index b96e19220d04b..9b6e3c9de3bbd 100644 --- a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs +++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// Test that even when `T` is only used in contravariant position, it +// is treated as invariant. + trait Get { fn get(&self, t: T); } diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs index 9d2766d878b34..6d9d1e61fed61 100644 --- a/src/test/compile-fail/variance-contravariant-self-trait-match.rs +++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// Test that even when `Self` is only used in contravariant position, it +// is treated as invariant. + trait Get { fn get(&self); } diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs index 757c1c9a8a268..ad059a467f570 100644 --- a/src/test/compile-fail/variance-covariant-arg-object.rs +++ b/src/test/compile-fail/variance-covariant-arg-object.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// Test that even when `T` is only used in covariant position, it +// is treated as invariant. + trait Get : 'static { fn get(&self) -> T; } diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs index 097f8eb9864e2..c42a845b3b504 100644 --- a/src/test/compile-fail/variance-covariant-arg-trait-match.rs +++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// Test that even when `T` is only used in covariant position, it +// is treated as invariant. + trait Get { fn get(&self) -> T; } diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs index 57ea367b49c30..25148dfc0208a 100644 --- a/src/test/compile-fail/variance-covariant-self-trait-match.rs +++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs @@ -10,6 +10,9 @@ #![allow(dead_code)] +// Test that even when `Self` is only used in covariant position, it +// is treated as invariant. + trait Get { fn get() -> Self; } From c2dba8580a5e472cc3344792030306130b1e5636 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 2 Apr 2015 13:24:44 -0400 Subject: [PATCH 14/32] Merge conflicts --- src/librustc/middle/ty_relate/mod.rs | 36 +++++++++---------- src/test/auxiliary/coherence_copy_like_lib.rs | 4 +-- ...erence_copy_like_err_fundamental_struct.rs | 4 +-- ...ce_copy_like_err_fundamental_struct_ref.rs | 4 +-- src/test/run-pass/coherence_copy_like.rs | 4 +-- .../run-pass/traits-conditional-dispatch.rs | 4 +-- 6 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs index 1205b7d957930..3a55a64314ed9 100644 --- a/src/librustc/middle/ty_relate/mod.rs +++ b/src/librustc/middle/ty_relate/mod.rs @@ -122,11 +122,11 @@ fn relate_item_substs<'a,'tcx:'a,R>(relation: &mut R, relate_substs(relation, opt_variances, a_subst, b_subst) } -fn relate_substs<'a,'tcx,R>(relation: &mut R, - variances: Option<&ty::ItemVariances>, - a_subst: &Substs<'tcx>, - b_subst: &Substs<'tcx>) - -> RelateResult<'tcx, Substs<'tcx>> +fn relate_substs<'a,'tcx:'a,R>(relation: &mut R, + variances: Option<&ty::ItemVariances>, + a_subst: &Substs<'tcx>, + b_subst: &Substs<'tcx>) + -> RelateResult<'tcx, Substs<'tcx>> where R: TypeRelation<'a,'tcx> { let mut substs = Substs::empty(); @@ -161,11 +161,11 @@ fn relate_substs<'a,'tcx,R>(relation: &mut R, Ok(substs) } -fn relate_type_params<'a,'tcx,R>(relation: &mut R, - variances: Option<&[ty::Variance]>, - a_tys: &[Ty<'tcx>], - b_tys: &[Ty<'tcx>]) - -> RelateResult<'tcx, Vec>> +fn relate_type_params<'a,'tcx:'a,R>(relation: &mut R, + variances: Option<&[ty::Variance]>, + a_tys: &[Ty<'tcx>], + b_tys: &[Ty<'tcx>]) + -> RelateResult<'tcx, Vec>> where R: TypeRelation<'a,'tcx> { if a_tys.len() != b_tys.len() { @@ -264,10 +264,10 @@ impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::FnSig<'tcx> { } } -fn relate_arg_vecs<'a,'tcx,R>(relation: &mut R, - a_args: &[Ty<'tcx>], - b_args: &[Ty<'tcx>]) - -> RelateResult<'tcx, Vec>> +fn relate_arg_vecs<'a,'tcx:'a,R>(relation: &mut R, + a_args: &[Ty<'tcx>], + b_args: &[Ty<'tcx>]) + -> RelateResult<'tcx, Vec>> where R: TypeRelation<'a,'tcx> { if a_args.len() != b_args.len() { @@ -629,10 +629,10 @@ impl<'a,'tcx:'a,T> Relate<'a,'tcx> for Box /////////////////////////////////////////////////////////////////////////// // Error handling -pub fn expected_found<'a,'tcx,R,T>(relation: &mut R, - a: &T, - b: &T) - -> ty::expected_found +pub fn expected_found<'a,'tcx:'a,R,T>(relation: &mut R, + a: &T, + b: &T) + -> ty::expected_found where R: TypeRelation<'a,'tcx>, T: Clone { expected_found_bool(relation.a_is_expected(), a, b) diff --git a/src/test/auxiliary/coherence_copy_like_lib.rs b/src/test/auxiliary/coherence_copy_like_lib.rs index a1e1b48c2c4e9..d3d389c6a8bd5 100644 --- a/src/test/auxiliary/coherence_copy_like_lib.rs +++ b/src/test/auxiliary/coherence_copy_like_lib.rs @@ -11,9 +11,7 @@ #![crate_type = "rlib"] #![feature(fundamental)] -use std::marker::MarkerTrait; - -pub trait MyCopy : MarkerTrait { } +pub trait MyCopy { } impl MyCopy for i32 { } pub struct MyStruct(T); diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs index f13175ce8e2a4..fcd6e5c495207 100644 --- a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs +++ b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs @@ -18,11 +18,9 @@ extern crate coherence_copy_like_lib as lib; -use std::marker::MarkerTrait; - struct MyType { x: i32 } -trait MyTrait : MarkerTrait { } +trait MyTrait { } impl MyTrait for T { } // `MyFundamentalStruct` is declared fundamental, so we can test that diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs index ae3d242af705e..b5c0a7fb5f564 100644 --- a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs +++ b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs @@ -18,11 +18,9 @@ extern crate coherence_copy_like_lib as lib; -use std::marker::MarkerTrait; - struct MyType { x: i32 } -trait MyTrait : MarkerTrait { } +trait MyTrait { } impl MyTrait for T { } // `MyFundamentalStruct` is declared fundamental, so we can test that diff --git a/src/test/run-pass/coherence_copy_like.rs b/src/test/run-pass/coherence_copy_like.rs index db9893613ad11..71db5225ecc08 100644 --- a/src/test/run-pass/coherence_copy_like.rs +++ b/src/test/run-pass/coherence_copy_like.rs @@ -15,11 +15,9 @@ extern crate coherence_copy_like_lib as lib; -use std::marker::MarkerTrait; - struct MyType { x: i32 } -trait MyTrait : MarkerTrait { } +trait MyTrait { } impl MyTrait for T { } impl MyTrait for MyType { } impl<'a> MyTrait for &'a MyType { } diff --git a/src/test/run-pass/traits-conditional-dispatch.rs b/src/test/run-pass/traits-conditional-dispatch.rs index 0190b7b7b9628..0a6b9da74f218 100644 --- a/src/test/run-pass/traits-conditional-dispatch.rs +++ b/src/test/run-pass/traits-conditional-dispatch.rs @@ -17,13 +17,11 @@ #![allow(unknown_features)] #![feature(box_syntax)] -use std::marker::MarkerTrait; - trait Get { fn get(&self) -> Self; } -trait MyCopy : MarkerTrait { fn copy(&self) -> Self; } +trait MyCopy { fn copy(&self) -> Self; } impl MyCopy for u16 { fn copy(&self) -> Self { *self } } impl MyCopy for u32 { fn copy(&self) -> Self { *self } } impl MyCopy for i32 { fn copy(&self) -> Self { *self } } From 1cbaf9fd18a4e99345f3ae6d7ba23309e214e32a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 2 Apr 2015 11:31:31 -0700 Subject: [PATCH 15/32] Upgrade rust-installer --- src/rust-installer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust-installer b/src/rust-installer index 49cc7f6fef12b..ebc6b04c29591 160000 --- a/src/rust-installer +++ b/src/rust-installer @@ -1 +1 @@ -Subproject commit 49cc7f6fef12bdd77a0f8b182d9a64c371cb17c8 +Subproject commit ebc6b04c29591108d3f28e724b4b9b74cd1232e6 From 8b719eefc0a772986dc33d6d9193c2cfd04b82f7 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Thu, 2 Apr 2015 21:10:25 +0100 Subject: [PATCH 16/32] std: impl From for Box --- src/libstd/error.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 150ffcdd77a9f..c9babeb32301a 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -88,8 +88,8 @@ impl<'a, E: Error + Send + 'a> From for Box { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> From<&'b str> for Box { - fn from(err: &'b str) -> Box { +impl From for Box { + fn from(err: String) -> Box { #[derive(Debug)] struct StringError(String); @@ -103,7 +103,14 @@ impl<'a, 'b> From<&'b str> for Box { } } - Box::new(StringError(String::from_str(err))) + Box::new(StringError(err)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, 'b> From<&'b str> for Box { + fn from(err: &'b str) -> Box { + From::from(String::from_str(err)) } } From 5a700b26e8cffee1d1ffbebf6d58a25a0cda1a41 Mon Sep 17 00:00:00 2001 From: Richo Healey Date: Thu, 2 Apr 2015 15:08:10 -0700 Subject: [PATCH 17/32] liballoc: fix typo --- src/liballoc/arc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index f87c450eda5ed..c07a6063d1475 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -446,7 +446,7 @@ impl Weak { /// ``` pub fn upgrade(&self) -> Option> { // We use a CAS loop to increment the strong count instead of a - // fetch_add because once the count hits 0 is must never be above 0. + // fetch_add because once the count hits 0 it must never be above 0. let inner = self.inner(); loop { let n = inner.strong.load(SeqCst); From e1be69b8a97d48d579b5474907aab9199d1b8ab7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 3 Apr 2015 05:56:27 +0300 Subject: [PATCH 18/32] Add tests for parsing of patterns --- .../pat-lt-bracket-1.rs} | 0 .../pat-lt-bracket-2.rs} | 0 .../pat-lt-bracket-3.rs} | 0 src/test/parse-fail/pat-lt-bracket-4.rs | 21 ++++++++ src/test/parse-fail/pat-lt-bracket-5.rs | 13 +++++ src/test/parse-fail/pat-lt-bracket-6.rs | 13 +++++ src/test/parse-fail/pat-lt-bracket-7.rs | 13 +++++ src/test/parse-fail/pat-ranges-1.rs | 15 ++++++ src/test/parse-fail/pat-ranges-2.rs | 15 ++++++ src/test/parse-fail/pat-ranges-3.rs | 15 ++++++ src/test/parse-fail/pat-ranges-4.rs | 15 ++++++ src/test/run-pass/issue-22546.rs | 54 +++++++++++++++++++ src/test/run-pass/pat-ranges.rs | 23 ++++++++ 13 files changed, 197 insertions(+) rename src/test/{compile-fail/issue-22426-1.rs => parse-fail/pat-lt-bracket-1.rs} (100%) rename src/test/{compile-fail/issue-22426-2.rs => parse-fail/pat-lt-bracket-2.rs} (100%) rename src/test/{compile-fail/issue-22426-3.rs => parse-fail/pat-lt-bracket-3.rs} (100%) create mode 100644 src/test/parse-fail/pat-lt-bracket-4.rs create mode 100644 src/test/parse-fail/pat-lt-bracket-5.rs create mode 100644 src/test/parse-fail/pat-lt-bracket-6.rs create mode 100644 src/test/parse-fail/pat-lt-bracket-7.rs create mode 100644 src/test/parse-fail/pat-ranges-1.rs create mode 100644 src/test/parse-fail/pat-ranges-2.rs create mode 100644 src/test/parse-fail/pat-ranges-3.rs create mode 100644 src/test/parse-fail/pat-ranges-4.rs create mode 100644 src/test/run-pass/issue-22546.rs create mode 100644 src/test/run-pass/pat-ranges.rs diff --git a/src/test/compile-fail/issue-22426-1.rs b/src/test/parse-fail/pat-lt-bracket-1.rs similarity index 100% rename from src/test/compile-fail/issue-22426-1.rs rename to src/test/parse-fail/pat-lt-bracket-1.rs diff --git a/src/test/compile-fail/issue-22426-2.rs b/src/test/parse-fail/pat-lt-bracket-2.rs similarity index 100% rename from src/test/compile-fail/issue-22426-2.rs rename to src/test/parse-fail/pat-lt-bracket-2.rs diff --git a/src/test/compile-fail/issue-22426-3.rs b/src/test/parse-fail/pat-lt-bracket-3.rs similarity index 100% rename from src/test/compile-fail/issue-22426-3.rs rename to src/test/parse-fail/pat-lt-bracket-3.rs diff --git a/src/test/parse-fail/pat-lt-bracket-4.rs b/src/test/parse-fail/pat-lt-bracket-4.rs new file mode 100644 index 0000000000000..3d9b492307a7c --- /dev/null +++ b/src/test/parse-fail/pat-lt-bracket-4.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum BtNode { + Node(u32,Box,Box), + Leaf(u32), +} + +fn main() { + let y = match x { + Foo::A(value) => value, //~ error: expected one of `=>`, `@`, `if`, or `|`, found `<` + Foo::B => 7, + }; +} diff --git a/src/test/parse-fail/pat-lt-bracket-5.rs b/src/test/parse-fail/pat-lt-bracket-5.rs new file mode 100644 index 0000000000000..3345845eee9ae --- /dev/null +++ b/src/test/parse-fail/pat-lt-bracket-5.rs @@ -0,0 +1,13 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let v[0] = v[1]; //~ error: expected one of `:`, `;`, `=`, or `@`, found `[` +} diff --git a/src/test/parse-fail/pat-lt-bracket-6.rs b/src/test/parse-fail/pat-lt-bracket-6.rs new file mode 100644 index 0000000000000..72fdae82260ea --- /dev/null +++ b/src/test/parse-fail/pat-lt-bracket-6.rs @@ -0,0 +1,13 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let Test(&desc[..]) = x; //~ error: expected one of `,` or `@`, found `[` +} diff --git a/src/test/parse-fail/pat-lt-bracket-7.rs b/src/test/parse-fail/pat-lt-bracket-7.rs new file mode 100644 index 0000000000000..c7731d156ad62 --- /dev/null +++ b/src/test/parse-fail/pat-lt-bracket-7.rs @@ -0,0 +1,13 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + for thing(x[]) {} //~ error: expected one of `,` or `@`, found `[` +} diff --git a/src/test/parse-fail/pat-ranges-1.rs b/src/test/parse-fail/pat-ranges-1.rs new file mode 100644 index 0000000000000..e1cbb961b1bcc --- /dev/null +++ b/src/test/parse-fail/pat-ranges-1.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing of range patterns + +fn main() { + let macropus!() ... 11 = 12; //~ error: expected one of `:`, `;`, or `=`, found `...` +} diff --git a/src/test/parse-fail/pat-ranges-2.rs b/src/test/parse-fail/pat-ranges-2.rs new file mode 100644 index 0000000000000..04ad5ff083bc8 --- /dev/null +++ b/src/test/parse-fail/pat-ranges-2.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing of range patterns + +fn main() { + let 10 ... makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, or `=`, found `!` +} diff --git a/src/test/parse-fail/pat-ranges-3.rs b/src/test/parse-fail/pat-ranges-3.rs new file mode 100644 index 0000000000000..5f7aac71d29b2 --- /dev/null +++ b/src/test/parse-fail/pat-ranges-3.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing of range patterns + +fn main() { + let 10 ... 10 + 3 = 12; //~ expected one of `:`, `;`, or `=`, found `+` +} diff --git a/src/test/parse-fail/pat-ranges-4.rs b/src/test/parse-fail/pat-ranges-4.rs new file mode 100644 index 0000000000000..50dcb8995279c --- /dev/null +++ b/src/test/parse-fail/pat-ranges-4.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing of range patterns + +fn main() { + let 10 - 3 ... 10 = 8; //~ error: expected one of `...`, `:`, `;`, or `=`, found `-` +} diff --git a/src/test/run-pass/issue-22546.rs b/src/test/run-pass/issue-22546.rs new file mode 100644 index 0000000000000..b3cb8a78213b8 --- /dev/null +++ b/src/test/run-pass/issue-22546.rs @@ -0,0 +1,54 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing patterns with paths with type parameters (issue #22544) + +use std::default::Default; + +#[derive(Default)] +pub struct Foo(T, T); + +impl Foo { + fn foo(&self) { + match *self { + Foo::(ref x, ref y) => println!("Goodbye, World! {} {}", x, y) + } + } +} + +trait Tr { + type U; +} + +impl Tr for Foo { + type U = T; +} + +struct Wrapper { + value: T +} + +fn main() { + let Foo::(a, b) = Default::default(); + + let f = Foo(2,3); + f.foo(); + + let w = Wrapper { value: Foo(10u8, 11u8) }; + match w { + Wrapper::> { value: Foo(10, 11) } => {}, + ::Wrapper::< as Tr>::U> { value: Foo::(11, 16) } => { panic!() }, + _ => { panic!() } + } + + if let None:: = Some(8) { + panic!(); + } +} diff --git a/src/test/run-pass/pat-ranges.rs b/src/test/run-pass/pat-ranges.rs new file mode 100644 index 0000000000000..964989508ccf2 --- /dev/null +++ b/src/test/run-pass/pat-ranges.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Parsing of range patterns + +const NUM1: i32 = 10; + +mod m { + pub const NUM2: i32 = 16; +} + +fn main() { + if let NUM1 ... m::NUM2 = 10 {} else { panic!() } + if let ::NUM1 ... ::m::NUM2 = 11 {} else { panic!() } + if let -13 ... -10 = 12 { panic!() } else {} +} From ad3daa89f2b77aeba508188dd96bf0ffbe633806 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Thu, 2 Apr 2015 19:13:26 -0700 Subject: [PATCH 19/32] Update AUTHORS.txt as of 1.0.0-beta --- AUTHORS.txt | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 4109797a55ee7..7a800b70e4a38 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -9,17 +9,19 @@ Aaron Todd Aaron Turon Aaron Weiss Adam Bozanich +Adam Jacob Adam Roben Adam Szkoda +Adenilson Cavalcanti Adolfo Ochagavía Adrien Brault Adrien Tétar -Ahmed Charles Ahmed Charles Aidan Cully Aidan Hobson Sayers Akos Kiss Alan Andrade +Alan Cutter Alan Williams Aleksander Balicki Aleksandr Koshlo @@ -29,6 +31,8 @@ Alex Lyon Alex Rønne Petersen Alex Whitney Alexander Bliskovsky +Alexander Campbell +Alexander Chernyakhovsky Alexander Korolkov Alexander Light Alexander Stavonin @@ -41,6 +45,7 @@ Alfie John Ali Smesseim Alisdair Owens Aljaž "g5pw" Srebrnič +Amol Mundayoor Amy Unger Anders Kaseorg Andre Arko @@ -56,6 +61,7 @@ Andrew Cann Andrew Chin Andrew Dunham Andrew Gallant +Andrew Hobden Andrew Paseltiner Andrew Poelstra Andrew Wagner @@ -110,6 +116,8 @@ Brendan McLoughlin Brendan Zabarauskas Brett Cannon Brian Anderson +Brian Brooks +Brian Campbell Brian Dawn Brian J Brennan Brian J. Burg @@ -122,6 +130,8 @@ Cadence Marseille Caitlin Potter Cam Jackson Cameron Zwarich +Camille Roussel +Camille TJHOA CarVac Carl Lerche Carl-Anton Ingmarsson @@ -132,6 +142,8 @@ Carter Hinsley Carter Tazio Schonwald Caspar Krieger Chase Southwood +Ches Martin +Chloe <5paceToast@users.noreply.github.com> Chris Double Chris Morgan Chris Nixon @@ -158,7 +170,9 @@ Corey Farwell Corey Ford Corey Richardson Cristi Burcă +Cristian Kubis DJUrsus +Dabo Ross Damian Gryski Damien Grassart Damien Radtke @@ -167,6 +181,8 @@ Dan Albert Dan Burkert Dan Connolly Dan Luu +Dan Schatzberg +Dan W. <1danwade@gmail.com> Dan Yang Daniel Brooks Daniel Fagnan @@ -174,6 +190,7 @@ Daniel Farina Daniel Griffen Daniel Grunwald Daniel Hofstetter +Daniel Lobato García Daniel Luz Daniel MacDougall Daniel Micay @@ -183,17 +200,23 @@ Daniel Ralston Daniel Rosenwasser Daniel Ursache Dogariu Daniil Smirnov +Darin Morrison +Darrell Hamilton Dave Herman Dave Hodder +Dave Huseby David Creswick David Forsythe David Halperin +David King David Klein +David Mally David Manescu David Rajchenbach-Teller David Renshaw David Vazgenovich Shakaryan Davis Silverman +Denis Defreyne Derecho Derek Chiang Derek Guenther @@ -214,10 +237,12 @@ Do Nhat Minh Dominik Inführ Donovan Preston Douglas Young +Drew Crawford Drew Willcoxon Duane Edwards Duncan Regan Dylan Braithwaite +Dylan Ede Dzmitry Malyshau Earl St Sauver Eduard Bopp @@ -230,12 +255,14 @@ Elantsev Serj Elliott Slaughter Elly Fong-Jones Emanuel Rylke +Emeliov Dmitrii Eric Allen Eric Biggers Eric Holk Eric Holmes Eric Kidd Eric Martin +Eric Platon Eric Reed Erick Rivas Erick Tryzelaar @@ -268,6 +295,7 @@ Florian Wilkens Florian Zeitz Francisco Souza Franklin Chen +FuGangqiang Gabriel Gareth Daniel Smith Garrett Heel @@ -279,8 +307,10 @@ Geoffrey Thomas Geoffroy Couprie George Papanikolaou Georges Dubus +Germano Gabbianelli Gil Cottle Gioele Barabucci +GlacJAY Gleb Kozyrev Glenn Willen Gonçalo Cabrita <_@gmcabrita.com> @@ -303,9 +333,11 @@ Herman J. Radtke III HeroesGrave Hong Chulju Honza Strnad +Huachao Huang Hugo Jobling Hugo van der Wijst Huon Wilson +Hyeon Kim Ian Connolly Ian D. Bollinger Ian Daniher @@ -318,12 +350,14 @@ Isaac Aggrey Isaac Dupree Ivan Enderlin Ivan Petkov +Ivan Radanov Ivanov Ivan Ukhov Ivano Coppola J. J. Weber J.C. Moyer JONNALAGADDA Srinivas JP Sugarbroad +JP-Ellis Jack Heizer Jack Moffitt Jacob Edelman @@ -338,6 +372,7 @@ Jake Kerr Jake Scott Jakub Bukaj Jakub Wieczorek +Jakub Vrána James Deng James Hurst James Lal @@ -359,6 +394,7 @@ Jason Toffaletti Jauhien Piatlicki Jay Anderson Jay True +Jeaye Jed Davis Jed Estep Jeff Balogh @@ -375,29 +411,36 @@ Jesse Jones Jesse Luehrs Jesse Ray Jesse Ruderman -Jihyun Yu +Jessy Diamond Exum +Jihyeok Seo +Jihyun Yu Jim Apple Jim Blandy Jim Radford Jimmie Elvenmark Jimmy Lu Jimmy Zelinskie +Jiří Stránský Joe Pletcher Joe Schafer Johannes Hoff Johannes Löthberg Johannes Muenzel +Johannes Oertel John Albietz John Barker John Clements +John Ericson John Fresco John Gallagher John Hodge John Kåre Alsaker John Kleint +John Kåre Alsaker John Louis Walker John Schmidt John Simon +John Zhang Jon Haddad Jon Morton Jonas Hietala @@ -407,6 +450,7 @@ Jonathan Reem Jonathan S Jonathan Sternberg Joonas Javanainen +Jordan Woehr Jordi Boggiano Jorge Aparicio Jorge Israel Peña @@ -423,16 +467,17 @@ Joshua Wise Joshua Yanovski Julia Evans Julian Orth +Julian Viereck Junseok Lee Junyoung Cho JustAPerson Justin Noah Jyun-Yan You Kang Seonghoon -Kang Seonghoon Kasey Carrothers Keegan McAllister Kelly Wilson +Kelvin Ly Ken Tossell KernelJ Keshav Kini @@ -442,6 +487,7 @@ Kevin Butler Kevin Cantu Kevin Mehall Kevin Murphy +Kevin Rauwolf Kevin Walter Kevin Yap Kiet Tran @@ -459,6 +505,8 @@ Lee Wondong LemmingAvalanche Lennart Kudling Leo Testard +Leonids Maslovs +Liam Monahan Liigo Zhuang Lindsey Kuper Lionel Flandrin @@ -495,6 +543,7 @@ Mathijs van de Nes Matt Brubeck Matt Carberry Matt Coffin +Matt Cox Matt McPherrin Matt Murphy Matt Roche @@ -532,6 +581,7 @@ Michael Sullivan Michael Williams Michael Woerister Michael Zhou +Michał Krasnoborski Mick Koch Mickaël Delahaye Mihnea Dobrescu-Balaur @@ -559,7 +609,9 @@ Nathaniel Theis Neil Pankey Nelson Chen NiccosSystem +Nicholas Nicholas Bishop +Nicholas Mazzuca Nick Cameron Nick Desaulniers Nick Howell @@ -579,8 +631,10 @@ Oliver Schneider Olivier Saut Olle Jonsson Or Brostovski +Or Neeman Oren Hazi Orpheus Lummis +Orphée Lafond-Lummis P1start Pablo Brasero Palmer Cox @@ -590,8 +644,11 @@ Patrick Reisert Patrick Walton Patrick Yevsukov Patrik Kårlin +Paul ADENOT Paul Collier +Paul Collins Paul Crowley +Paul Osborne Paul Stansifer Paul Woolcock Pavel Panchekha @@ -602,6 +659,7 @@ Peter Atashian Peter Elmers Peter Hull Peter Marheine +Peter Minten Peter Schuller Peter Williams Peter Zotov @@ -620,14 +678,17 @@ Potpourri Pradeep Kumar Prudhvi Krishna Surapaneni Pyfisch +Pyry Kontio Pythoner6 Q.P.Liu Rafael Ávila de Espíndola +Rahul Horé Ralph Bodenner Ralph Giles Ramkumar Ramachandra Randati Raphael Catolino +Raphael Nestler Raphael Speyer Raul Gutierrez S Ray Clanan @@ -637,6 +698,7 @@ Renato Riccieri Santos Zannon Renato Zannon Reuben Morais Ricardo M. Correia +Ricardo Martins Rich Lane Richard Diamond Richo Healey @@ -663,10 +725,13 @@ Russell Ruud van Asseldonk Ryan Levick Ryan Mulligan +Ryan Prichard +Ryan Riginding Ryan Scheel Ryman Rüdiger Sonderfeld S Pradeep Kumar +Sae-bom Kim Salem Talha Samuel Chase Samuel Neves @@ -678,6 +743,7 @@ Santiago Rodriguez Saurabh Anand Scott Jenkins Scott Lawrence +Scott Olson Sean Chalmers Sean Collins Sean Gillespie @@ -730,10 +796,13 @@ Tamir Duberstein Taras Shpot Taylor Hutchison Ted Horst +Tero Hänninen Thad Guidry Thiago Carvalho +Thiago Pontes Thomas Backman Thomas Daede +Tiago Nobrega Till Hoeppner Tim Brooks Tim Chevalier @@ -760,6 +829,7 @@ Toni Cárdenas Tony Young Torsten Weber Travis Watkins +Trent Nadeau Trent Ogren Trinick Tristan Storch @@ -769,9 +839,9 @@ TyOverby Tycho Sci Tyler Bindon Tyler Thrailkill -U-NOV2010\eugals Ulrik Sverdrup Ulysse Carion +User Jyyou Utkarsh Kukreti Uwe Dauernheim Vadim Chugunov @@ -797,6 +867,7 @@ Wade Mealing Wangshan Lu WebeWizard Wendell Smith +Wesley Wiser Will William Ting Willson Mock @@ -817,12 +888,16 @@ Zack Slayton Zbigniew Siciarz Ziad Hatahet Zooko Wilcox-O'Hearn +adridu59 aochagavia areski arturo auREAX +awlnx +aydin.kim b1nd bachm +bcoopers blackbeam blake2-ppc bluss @@ -835,6 +910,7 @@ comex crhino dan@daramos.com darkf +defuz dgoon donkopotamus eliovir @@ -845,6 +921,7 @@ fort free-Runner g3xzh gamazeps +gareth gentlefolk gifnksm hansjorg @@ -860,6 +937,8 @@ joaoxsouls jrincayc juxiliary jxv +kgv +kjpgit klutzy korenchkin kud1ing @@ -868,6 +947,7 @@ kvark kwantam lpy lucy +lummax lyuts m-r-r madmalik @@ -882,20 +962,26 @@ mrec musitdev nathan dotz nham +niftynif noam novalis +nsf +nwin oli-obk olivren osa1 posixphreak qwitwa +ray glover reedlepee +reus rjz sevrak sheroze1123 smenardpw sp3d startling +tav th0114nd theptrk thiagopnts @@ -911,3 +997,5 @@ xales zofrex zslayton zzmp +Łukasz Niemier +克雷 From 6529872afcd4934cd16202a67c747df6674f76c6 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Thu, 2 Apr 2015 22:22:44 -0700 Subject: [PATCH 20/32] Adjust `AsRef` impl for `Cow` The existing impl had the too-strong requirement of `Clone`, when only `ToOwned` was needed. --- src/libcollections/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs index 2fe769b73f5cc..4503ad14e92b4 100644 --- a/src/libcollections/borrow.rs +++ b/src/libcollections/borrow.rs @@ -342,7 +342,7 @@ impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: Clone> AsRef for Cow<'a, T> { +impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { fn as_ref(&self) -> &T { self } From b406782e29cef9615dcc14b70404b872de25d771 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 2 Apr 2015 22:47:50 -0700 Subject: [PATCH 21/32] Indicate associated type in comment is code-like --- src/libcore/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 42e90ec34db7c..b5f16b6ccf260 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -1065,7 +1065,7 @@ pub trait IntoIterator { #[stable(feature = "rust1", since = "1.0.0")] type Item; - /// A container for iterating over elements of type Item + /// A container for iterating over elements of type `Item` #[stable(feature = "rust1", since = "1.0.0")] type IntoIter: Iterator; From 0621a83ba56943eb080fc523ae713cd4bdb9b882 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Fri, 3 Apr 2015 15:05:54 +0200 Subject: [PATCH 22/32] Workaround `javac` popup on MacOS X MacOS X does not ship with Java installed by default. Instead it includes binary stubs that upon execution pop up a message suggesting the installation of the JDK. Since `javac` is only used when `antlr4` is available, it is possible to work around the popup by only probing for `javac` if `antlr4` has been successfully detected (in which case the JDK is probably already installed on the system). Fixes #23138. --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index ca73c1cf8b1c3..5de6f3c7e1f82 100755 --- a/configure +++ b/configure @@ -669,7 +669,6 @@ probe CFG_LD ld probe CFG_VALGRIND valgrind probe CFG_PERF perf probe CFG_ISCC iscc -probe CFG_JAVAC javac probe CFG_ANTLR4 antlr4 probe CFG_GRUN grun probe CFG_FLEX flex @@ -679,6 +678,14 @@ probe CFG_XELATEX xelatex probe CFG_GDB gdb probe CFG_LLDB lldb +# On MacOS X, invoking `javac` pops up a dialog if the JDK is not +# installed. Since `javac` is only used if `antlr4` is available, +# probe for it only in this case. +if [ ! -z "$CFG_ANTLR4" ] +then + probe CFG_JAVAC javac +fi + if [ ! -z "$CFG_GDB" ] then # Store GDB's version From 787c6cda00f45de8634052b743b384f1fdaee7e0 Mon Sep 17 00:00:00 2001 From: Dave Huseby Date: Thu, 2 Apr 2015 17:27:19 -0700 Subject: [PATCH 23/32] this correctly disables jemalloc on Bitrig --- configure | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/configure b/configure index ca73c1cf8b1c3..1c0911314b2fb 100755 --- a/configure +++ b/configure @@ -545,7 +545,6 @@ opt verify-install 1 "verify installed binaries work" # This is used by the automation to produce single-target nightlies opt dist-host-only 0 "only install bins for the host architecture" opt inject-std-version 1 "inject the current compiler version of libstd into programs" -opt jemalloc 1 "build liballoc with jemalloc" opt llvm-version-check 1 "don't check if the LLVM version is supported, build anyway" valopt localstatedir "/var/lib" "local state directory" @@ -562,6 +561,7 @@ valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path" # (others are conditionally saved). opt_nosave manage-submodules 1 "let the build manage the git submodules" opt_nosave clang 0 "prefer clang to gcc for building the runtime" +opt_nosave jemalloc 1 "build liballoc with jemalloc" valopt_nosave prefix "/usr/local" "set installation prefix" valopt_nosave local-rust-root "/usr/local" "set prefix for local rust binary" @@ -775,7 +775,7 @@ if [ $CFG_OSTYPE = unknown-bitrig ] then step_msg "on Bitrig, forcing use of clang, disabling jemalloc" CFG_ENABLE_CLANG=1 - CFG_ENABLE_JEMALLOC=0 + CFG_DISABLE_JEMALLOC=1 fi if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ] @@ -828,6 +828,12 @@ then putvar CFG_ENABLE_CLANG fi +# Same with jemalloc. save the setting here. +if [ ! -z "$CFG_DISABLE_JEMALLOC" ] +then + putvar CFG_DISABLE_JEMALLOC +fi + if [ ! -z "$CFG_LLVM_ROOT" -a -z "$CFG_DISABLE_LLVM_VERSION_CHECK" -a -e "$CFG_LLVM_ROOT/bin/llvm-config" ] then step_msg "using custom LLVM at $CFG_LLVM_ROOT" From 2f63e9c127ceff853f560a8a74f6d37c8ebad400 Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Fri, 3 Apr 2015 13:23:58 -0400 Subject: [PATCH 24/32] Remove unnecessary `Vec<_>` annotation from docs This was brought up in IRC by a confused reader. --- src/libcollections/vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 087b065031f2b..b767a1ea054c1 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -185,7 +185,7 @@ impl Vec { /// # Examples /// /// ``` - /// let mut vec: Vec<_> = Vec::with_capacity(10); + /// let mut vec = Vec::with_capacity(10); /// /// // The vector contains no items, even though it has capacity for more /// assert_eq!(vec.len(), 0); From 62b30605071698ca38baf103c4666c52b0b30fac Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 3 Apr 2015 14:30:13 -0400 Subject: [PATCH 25/32] Revert accidental change from stable -> unstable; just meant to deprecate (though these will likely be purged for 1.0). --- src/libcore/marker.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 352f7d869774c..ad640c862855e 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -273,14 +273,14 @@ macro_rules! impls{ } /// `MarkerTrait` is deprecated and no longer needed. -#[unstable(feature = "core", reason = "deprecated")] +#[stable(feature = "rust1", since = "1.0.0")] #[deprecated(since = "1.0.0", reason = "No longer needed")] #[allow(deprecated)] #[cfg(stage0)] pub trait MarkerTrait : PhantomFn { } /// `MarkerTrait` is deprecated and no longer needed. -#[unstable(feature = "core", reason = "deprecated")] +#[stable(feature = "rust1", since = "1.0.0")] #[deprecated(since = "1.0.0", reason = "No longer needed")] #[allow(deprecated)] #[cfg(not(stage0))] @@ -291,14 +291,14 @@ impl MarkerTrait for T { } /// `PhantomFn` is a deprecated marker trait that is no longer needed. #[lang="phantom_fn"] -#[unstable(feature = "core", reason = "deprecated")] +#[stable(feature = "rust1", since = "1.0.0")] #[deprecated(since = "1.0.0", reason = "No longer needed")] #[cfg(stage0)] pub trait PhantomFn { } /// `PhantomFn` is a deprecated marker trait that is no longer needed. -#[unstable(feature = "core", reason = "deprecated")] +#[stable(feature = "rust1", since = "1.0.0")] #[deprecated(since = "1.0.0", reason = "No longer needed")] #[cfg(not(stage0))] pub trait PhantomFn { From 862e16025af182a603f350cddb5de9e2f4f1cfb6 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 3 Apr 2015 15:24:47 -0400 Subject: [PATCH 26/32] Don't speak of old_io from https://news.ycombinator.com/item?id=9317822 --- src/libstd/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 5c9ff544fa3e8..df81981c3f445 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -77,9 +77,8 @@ //! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpsc/index.html), //! which contains the channel types for message passing. //! -//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, -//! timers, and process spawning, are defined in the -//! [`old_io`](old_io/index.html) module. +//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, and +//! process spawning, are defined in the [`io`](io/index.html) module. //! //! Rust's I/O and concurrency depends on a small runtime interface //! that lives, along with its support code, in mod [`rt`](rt/index.html). From 3b73a6e3cee96e6065fa9cc65dc89475f87d1653 Mon Sep 17 00:00:00 2001 From: Dan Callahan Date: Fri, 3 Apr 2015 14:29:33 -0500 Subject: [PATCH 27/32] Remove old_io from trpl/concurrency.md Also: the std_misc feature flag is removed; it's not needed in Beta. Hat tip to @tshepang in #23871 Fixes #24023 --- src/doc/trpl/concurrency.md | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index 6b814a685424e..bc0a76bc2b6e7 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -88,17 +88,14 @@ When `guard` goes out of scope, it will block execution until the thread is finished. If we didn't want this behaviour, we could use `thread::spawn()`: ``` -# #![feature(old_io, std_misc)] use std::thread; -use std::old_io::timer; -use std::time::Duration; fn main() { thread::spawn(|| { println!("Hello from a thread!"); }); - timer::sleep(Duration::milliseconds(50)); + thread::sleep_ms(50); } ``` @@ -147,10 +144,7 @@ As an example, here is a Rust program that would have a data race in many languages. It will not compile: ```ignore -# #![feature(old_io, std_misc)] use std::thread; -use std::old_io::timer; -use std::time::Duration; fn main() { let mut data = vec![1u32, 2, 3]; @@ -161,14 +155,14 @@ fn main() { }); } - timer::sleep(Duration::milliseconds(50)); + thread::sleep_ms(50); } ``` This gives us an error: ```text -12:17 error: capture of moved value: `data` +8:17 error: capture of moved value: `data` data[i] += 1; ^~~~ ``` @@ -187,10 +181,7 @@ only one person at a time can mutate what's inside. For that, we can use the but for a different reason: ```ignore -# #![feature(old_io, std_misc)] use std::thread; -use std::old_io::timer; -use std::time::Duration; use std::sync::Mutex; fn main() { @@ -203,17 +194,17 @@ fn main() { }); } - timer::sleep(Duration::milliseconds(50)); + thread::sleep_ms(50); } ``` Here's the error: ```text -:11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` [E0277] +:9:9: 9:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` [E0277] :11 thread::spawn(move || { ^~~~~~~~~~~~~ -:11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` cannot be sent between threads safely +:9:9: 9:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` cannot be sent between threads safely :11 thread::spawn(move || { ^~~~~~~~~~~~~ ``` @@ -232,11 +223,8 @@ guard across thread boundaries, which gives us our error. We can use `Arc` to fix this. Here's the working version: ``` -# #![feature(old_io, std_misc)] use std::sync::{Arc, Mutex}; use std::thread; -use std::old_io::timer; -use std::time::Duration; fn main() { let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); @@ -249,7 +237,7 @@ fn main() { }); } - timer::sleep(Duration::milliseconds(50)); + thread::sleep_ms(50); } ``` @@ -258,11 +246,9 @@ handle is then moved into the new thread. Let's examine the body of the thread more closely: ``` -# #![feature(old_io, std_misc)] # use std::sync::{Arc, Mutex}; # use std::thread; -# use std::old_io::timer; -# use std::time::Duration; +# # fn main() { # let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); # for i in 0..2 { @@ -272,6 +258,8 @@ thread::spawn(move || { data[i] += 1; }); # } +# +# thread::sleep_ms(50); # } ``` From 925a52cb9324e6fdf5c97d5c0e852e39c6969b4a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 3 Apr 2015 19:09:41 -0400 Subject: [PATCH 28/32] Update Rust install instructions in TRPL Default is now beta, add nightly in the unstable section --- src/doc/trpl/installing-rust.md | 4 +-- src/doc/trpl/unstable.md | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/installing-rust.md b/src/doc/trpl/installing-rust.md index 288a4a158fb80..c839688047aa6 100644 --- a/src/doc/trpl/installing-rust.md +++ b/src/doc/trpl/installing-rust.md @@ -18,9 +18,9 @@ $ sudo sh rustup.sh ``` If you're on Windows, please download either the [32-bit -installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe) +installer](https://static.rust-lang.org/dist/rust-1.0.0-beta-i686-pc-windows-gnu.exe) or the [64-bit -installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe) +installer](https://static.rust-lang.org/dist/rust-1.0.0-beta-x86_64-pc-windows-gnu.exe) and run it. If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay. diff --git a/src/doc/trpl/unstable.md b/src/doc/trpl/unstable.md index e8e02cc9d092c..d69831c237838 100644 --- a/src/doc/trpl/unstable.md +++ b/src/doc/trpl/unstable.md @@ -1 +1,51 @@ % Unstable Rust + +Rust provides three distribution channels for Rust: nightly, beta, and stable. +Unstable features are only available on nightly Rust. For more details on this +process, see [this post](http://blog.rust-lang.org/2014/10/30/Stability.html). + +To install nightly Rust, you can use `rustup.sh`: + +```bash +$ curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly +``` + +If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`, +please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script: + +```bash +$ curl -f -L https://static.rust-lang.org/rustup.sh -O +$ sudo sh rustup.sh --channel=nightly +``` + +If you're on Windows, please download either the [32-bit +installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe) +or the [64-bit +installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe) +and run it. + +If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay. +Not every programming language is great for everyone. Just run the uninstall +script: + +```bash +$ sudo /usr/local/lib/rustlib/uninstall.sh +``` + +If you used the Windows installer, just re-run the `.exe` and it will give you +an uninstall option. + +You can re-run this script any time you want to update Rust. Which, at this +point, is often. Rust is still pre-1.0, and so people assume that you're using +a very recent Rust. + +This brings me to one other point: some people, and somewhat rightfully so, get +very upset when we tell you to `curl | sudo sh`. And they should be! Basically, +when you do this, you are trusting that the good people who maintain Rust +aren't going to hack your computer and do bad things. That's a good instinct! +If you're one of those people, please check out the documentation on [building +Rust from Source](https://github.com/rust-lang/rust#building-from-source), or +[the official binary downloads](http://www.rust-lang.org/install.html). And we +promise that this method will not be the way to install Rust forever: it's just +the easiest way to keep people updated while Rust is in its alpha state. + From 692c88c9bc5e0f8d8fc1b732874a48dcf2c47b0a Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 3 Apr 2015 18:09:11 -0700 Subject: [PATCH 29/32] Simplify `match` branches in documentation comment --- src/libcore/result.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index eff04dd590393..42d0b2a2c62ff 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -46,12 +46,8 @@ //! //! let version = parse_version(&[1, 2, 3, 4]); //! match version { -//! Ok(v) => { -//! println!("working with version: {:?}", v); -//! } -//! Err(e) => { -//! println!("error parsing header: {:?}", e); -//! } +//! Ok(v) => println!("working with version: {:?}", v), +//! Err(e) => println!("error parsing header: {:?}", e), //! } //! ``` //! From 6ff085c9a9ae5ac5da186ca85e1bd642d6154bec Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 3 Apr 2015 18:32:29 -0700 Subject: [PATCH 30/32] Make example function in comment more idiomatic --- src/libcore/result.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index eff04dd590393..5be46a09a95d2 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -34,13 +34,11 @@ //! enum Version { Version1, Version2 } //! //! fn parse_version(header: &[u8]) -> Result { -//! if header.len() < 1 { -//! return Err("invalid header length"); -//! } -//! match header[0] { -//! 1 => Ok(Version::Version1), -//! 2 => Ok(Version::Version2), -//! _ => Err("invalid version") +//! match header.get(0) { +//! None => Err("invalid header length"), +//! Some(&1) => Ok(Version::Version1), +//! Some(&2) => Ok(Version::Version2), +//! Some(_) => Err("invalid version") //! } //! } //! From eb2a6d9866c4bb662d7ca5d735a6b25801c2f2f9 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Fri, 3 Apr 2015 22:56:34 -0300 Subject: [PATCH 31/32] Removed repeated sentence. --- src/doc/trpl/closures.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index 01b8163ffd372..52d07ae465f44 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.md @@ -175,9 +175,6 @@ we called `add_num`, it mutated the underlying value, as we'd expect. We also needed to declare `add_num` as `mut` too, because we’re mutating its environment. -We also had to declare `add_num` as mut, since we will be modifying its -environment. - If we change to a `move` closure, it's different: ```rust From b62c11023c4fdbb1e6ef9f074310a8e95db7827e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 4 Apr 2015 12:50:43 +0530 Subject: [PATCH 32/32] Fix doc (fixup #24031) --- src/doc/trpl/concurrency.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index bc0a76bc2b6e7..f9358f28b0194 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -245,10 +245,9 @@ We now call `clone()` on our `Arc`, which increases the internal count. This handle is then moved into the new thread. Let's examine the body of the thread more closely: -``` +```rust # use std::sync::{Arc, Mutex}; # use std::thread; -# # fn main() { # let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); # for i in 0..2 { @@ -258,7 +257,6 @@ thread::spawn(move || { data[i] += 1; }); # } -# # thread::sleep_ms(50); # } ```