diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-09-06 14:36:26 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-09-06 14:36:26 +0200 |
| commit | 76ceeddb2b6fd4589cf8292d8dafa65a91ace019 (patch) | |
| tree | 11106836a5a37fc73a209a905786431ea0f10117 /src/test/ui | |
| parent | 20ca02569ae3e1dc29962e92739fbab632abf241 (diff) | |
| download | rust-76ceeddb2b6fd4589cf8292d8dafa65a91ace019.tar.gz rust-76ceeddb2b6fd4589cf8292d8dafa65a91ace019.zip | |
Migrated remaining `src/test/run-pass/` subdirectories to `src/test/ui/run-pass/`.
Diffstat (limited to 'src/test/ui')
171 files changed, 7266 insertions, 0 deletions
diff --git a/src/test/ui/run-pass/allocator/auxiliary/custom-as-global.rs b/src/test/ui/run-pass/allocator/auxiliary/custom-as-global.rs new file mode 100644 index 00000000000..a3f05a01c5a --- /dev/null +++ b/src/test/ui/run-pass/allocator/auxiliary/custom-as-global.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +extern crate custom; + +use std::sync::atomic::{ATOMIC_USIZE_INIT, Ordering}; + +use custom::A; + +#[global_allocator] +static ALLOCATOR: A = A(ATOMIC_USIZE_INIT); + +pub fn get() -> usize { + ALLOCATOR.0.load(Ordering::SeqCst) +} diff --git a/src/test/ui/run-pass/allocator/auxiliary/custom.rs b/src/test/ui/run-pass/allocator/auxiliary/custom.rs new file mode 100644 index 00000000000..b17464e0419 --- /dev/null +++ b/src/test/ui/run-pass/allocator/auxiliary/custom.rs @@ -0,0 +1,31 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![feature(allocator_api)] +#![crate_type = "rlib"] + +use std::alloc::{GlobalAlloc, System, Layout}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +pub struct A(pub AtomicUsize); + +unsafe impl GlobalAlloc for A { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + self.0.fetch_add(1, Ordering::SeqCst); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + self.0.fetch_add(1, Ordering::SeqCst); + System.dealloc(ptr, layout) + } +} diff --git a/src/test/ui/run-pass/allocator/auxiliary/helper.rs b/src/test/ui/run-pass/allocator/auxiliary/helper.rs new file mode 100644 index 00000000000..e75a432710d --- /dev/null +++ b/src/test/ui/run-pass/allocator/auxiliary/helper.rs @@ -0,0 +1,19 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +use std::fmt; + +pub fn work_with(p: &fmt::Debug) { + drop(p); +} diff --git a/src/test/ui/run-pass/allocator/custom.rs b/src/test/ui/run-pass/allocator/custom.rs new file mode 100644 index 00000000000..3a7f8fa8620 --- /dev/null +++ b/src/test/ui/run-pass/allocator/custom.rs @@ -0,0 +1,66 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate helper; + +use std::alloc::{self, Global, Alloc, System, Layout}; +use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; + +static HITS: AtomicUsize = ATOMIC_USIZE_INIT; + +struct A; + +unsafe impl alloc::GlobalAlloc for A { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + HITS.fetch_add(1, Ordering::SeqCst); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + HITS.fetch_add(1, Ordering::SeqCst); + System.dealloc(ptr, layout) + } +} + +#[global_allocator] +static GLOBAL: A = A; + +fn main() { + println!("hello!"); + + let n = HITS.load(Ordering::SeqCst); + assert!(n > 0); + unsafe { + let layout = Layout::from_size_align(4, 2).unwrap(); + + let ptr = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&ptr); + assert_eq!(HITS.load(Ordering::SeqCst), n + 1); + Global.dealloc(ptr, layout.clone()); + assert_eq!(HITS.load(Ordering::SeqCst), n + 2); + + let s = String::with_capacity(10); + helper::work_with(&s); + assert_eq!(HITS.load(Ordering::SeqCst), n + 3); + drop(s); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + + let ptr = System.alloc(layout.clone()).unwrap(); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + helper::work_with(&ptr); + System.dealloc(ptr, layout); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + } +} diff --git a/src/test/ui/run-pass/allocator/xcrate-use.rs b/src/test/ui/run-pass/allocator/xcrate-use.rs new file mode 100644 index 00000000000..482e3b04aae --- /dev/null +++ b/src/test/ui/run-pass/allocator/xcrate-use.rs @@ -0,0 +1,43 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:custom.rs +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate custom; +extern crate helper; + +use std::alloc::{Global, Alloc, System, Layout}; +use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT}; + +#[global_allocator] +static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT); + +fn main() { + unsafe { + let n = GLOBAL.0.load(Ordering::SeqCst); + let layout = Layout::from_size_align(4, 2).unwrap(); + + let ptr = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&ptr); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); + Global.dealloc(ptr, layout.clone()); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + + let ptr = System.alloc(layout.clone()).unwrap(); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + helper::work_with(&ptr); + System.dealloc(ptr, layout); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + } +} diff --git a/src/test/ui/run-pass/allocator/xcrate-use2.rs b/src/test/ui/run-pass/allocator/xcrate-use2.rs new file mode 100644 index 00000000000..7a45fd28bdb --- /dev/null +++ b/src/test/ui/run-pass/allocator/xcrate-use2.rs @@ -0,0 +1,56 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:custom.rs +// aux-build:custom-as-global.rs +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate custom; +extern crate custom_as_global; +extern crate helper; + +use std::alloc::{alloc, dealloc, GlobalAlloc, System, Layout}; +use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT}; + +static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT); + +fn main() { + unsafe { + let n = custom_as_global::get(); + let layout = Layout::from_size_align(4, 2).unwrap(); + + // Global allocator routes to the `custom_as_global` global + let ptr = alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 1); + dealloc(ptr, layout.clone()); + assert_eq!(custom_as_global::get(), n + 2); + + // Usage of the system allocator avoids all globals + let ptr = System.alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 2); + System.dealloc(ptr, layout.clone()); + assert_eq!(custom_as_global::get(), n + 2); + + // Usage of our personal allocator doesn't affect other instances + let ptr = GLOBAL.alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 2); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1); + GLOBAL.dealloc(ptr, layout); + assert_eq!(custom_as_global::get(), n + 2); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2); + } +} + diff --git a/src/test/ui/run-pass/bench/issue-32062.rs b/src/test/ui/run-pass/bench/issue-32062.rs new file mode 100644 index 00000000000..8f6457d820a --- /dev/null +++ b/src/test/ui/run-pass/bench/issue-32062.rs @@ -0,0 +1,58 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// pretty-expanded FIXME #23616 + +fn main() { + let _ = test(Some(0).into_iter()); +} + +trait Parser { + type Input: Iterator; + type Output; + fn parse(self, input: Self::Input) -> Result<(Self::Output, Self::Input), ()>; + fn chain<P>(self, p: P) -> Chain<Self, P> where Self: Sized { + Chain(self, p) + } +} + +struct Token<T>(T::Item) where T: Iterator; + +impl<T> Parser for Token<T> where T: Iterator { + type Input = T; + type Output = T::Item; + fn parse(self, _input: Self::Input) -> Result<(Self::Output, Self::Input), ()> { + Err(()) + } +} + +struct Chain<L, R>(L, R); + +impl<L, R> Parser for Chain<L, R> where L: Parser, R: Parser<Input = L::Input> { + type Input = L::Input; + type Output = (L::Output, R::Output); + fn parse(self, _input: Self::Input) -> Result<(Self::Output, Self::Input), ()> { + Err(()) + } +} + +fn test<I>(i: I) -> Result<((), I), ()> where I: Iterator<Item = i32> { + Chain(Token(0), Token(1)) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .parse(i) + .map(|(_, i)| ((), i)) +} diff --git a/src/test/ui/run-pass/ctfe/assoc-const.rs b/src/test/ui/run-pass/ctfe/assoc-const.rs new file mode 100644 index 00000000000..6a740dc1dd3 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/assoc-const.rs @@ -0,0 +1,28 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Nat { + const VALUE: usize; +} + +struct Zero; +struct Succ<N>(N); + +impl Nat for Zero { + const VALUE: usize = 0; +} + +impl<N: Nat> Nat for Succ<N> { + const VALUE: usize = N::VALUE + 1; +} + +fn main() { + let x: [i32; <Succ<Succ<Succ<Succ<Zero>>>>>::VALUE] = [1, 2, 3, 4]; +} diff --git a/src/test/ui/run-pass/ctfe/bswap-const.rs b/src/test/ui/run-pass/ctfe/bswap-const.rs new file mode 100644 index 00000000000..b951a9b72b1 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/bswap-const.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(core_intrinsics)] + +use std::intrinsics; + +const SWAPPED_U8: u8 = unsafe { intrinsics::bswap(0x12_u8) }; +const SWAPPED_U16: u16 = unsafe { intrinsics::bswap(0x12_34_u16) }; +const SWAPPED_I32: i32 = unsafe { intrinsics::bswap(0x12_34_56_78_i32) }; + +fn main() { + assert_eq!(SWAPPED_U8, 0x12); + assert_eq!(SWAPPED_U16, 0x34_12); + assert_eq!(SWAPPED_I32, 0x78_56_34_12); +} diff --git a/src/test/ui/run-pass/ctfe/chained-constants-stackoverflow.rs b/src/test/ui/run-pass/ctfe/chained-constants-stackoverflow.rs new file mode 100644 index 00000000000..813dd5fbb99 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/chained-constants-stackoverflow.rs @@ -0,0 +1,364 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/34997 + +pub const CST_1: u32 = 0; +pub const CST_2: u32 = CST_1+1; +pub const CST_3: u32 = CST_2+1; +pub const CST_4: u32 = CST_3+1; +pub const CST_5: u32 = CST_4+1; +pub const CST_6: u32 = CST_5+1; +pub const CST_7: u32 = CST_6+1; +pub const CST_8: u32 = CST_7+1; +pub const CST_9: u32 = CST_8+1; +pub const CST_10: u32 = CST_9+1; +pub const CST_11: u32 = CST_10+1; +pub const CST_12: u32 = CST_11+1; +pub const CST_13: u32 = CST_12+1; +pub const CST_14: u32 = CST_13+1; +pub const CST_15: u32 = CST_14+1; +pub const CST_16: u32 = CST_15+1; +pub const CST_17: u32 = CST_16+1; +pub const CST_18: u32 = CST_17+1; +pub const CST_19: u32 = CST_18+1; +pub const CST_20: u32 = CST_19+1; +pub const CST_21: u32 = CST_20+1; +pub const CST_22: u32 = CST_21+1; +pub const CST_23: u32 = CST_22+1; +pub const CST_24: u32 = CST_23+1; +pub const CST_25: u32 = CST_24+1; +pub const CST_26: u32 = CST_25+1; +pub const CST_27: u32 = CST_26+1; +pub const CST_28: u32 = CST_27+1; +pub const CST_29: u32 = CST_28+1; +pub const CST_30: u32 = CST_29+1; +pub const CST_31: u32 = CST_30+1; +pub const CST_32: u32 = CST_31+1; +pub const CST_33: u32 = CST_32+1; +pub const CST_34: u32 = CST_33+1; +pub const CST_35: u32 = CST_34+1; +pub const CST_36: u32 = CST_35+1; +pub const CST_37: u32 = CST_36+1; +pub const CST_38: u32 = CST_37+1; +pub const CST_39: u32 = CST_38+1; +pub const CST_40: u32 = CST_39+1; +pub const CST_41: u32 = CST_40+1; +pub const CST_42: u32 = CST_41+1; +pub const CST_43: u32 = CST_42+1; +pub const CST_44: u32 = CST_43+1; +pub const CST_45: u32 = CST_44+1; +pub const CST_46: u32 = CST_45+1; +pub const CST_47: u32 = CST_46+1; +pub const CST_48: u32 = CST_47+1; +pub const CST_49: u32 = CST_48+1; +pub const CST_50: u32 = CST_49+1; +pub const CST_51: u32 = CST_50+1; +pub const CST_52: u32 = CST_51+1; +pub const CST_53: u32 = CST_52+1; +pub const CST_54: u32 = CST_53+1; +pub const CST_55: u32 = CST_54+1; +pub const CST_56: u32 = CST_55+1; +pub const CST_57: u32 = CST_56+1; +pub const CST_58: u32 = CST_57+1; +pub const CST_59: u32 = CST_58+1; +pub const CST_60: u32 = CST_59+1; +pub const CST_61: u32 = CST_60+1; +pub const CST_62: u32 = CST_61+1; +pub const CST_63: u32 = CST_62+1; +pub const CST_64: u32 = CST_63+1; +pub const CST_65: u32 = CST_64+1; +pub const CST_66: u32 = CST_65+1; +pub const CST_67: u32 = CST_66+1; +pub const CST_68: u32 = CST_67+1; +pub const CST_69: u32 = CST_68+1; +pub const CST_70: u32 = CST_69+1; +pub const CST_71: u32 = CST_70+1; +pub const CST_72: u32 = CST_71+1; +pub const CST_73: u32 = CST_72+1; +pub const CST_74: u32 = CST_73+1; +pub const CST_75: u32 = CST_74+1; +pub const CST_76: u32 = CST_75+1; +pub const CST_77: u32 = CST_76+1; +pub const CST_78: u32 = CST_77+1; +pub const CST_79: u32 = CST_78+1; +pub const CST_80: u32 = CST_79+1; +pub const CST_81: u32 = CST_80+1; +pub const CST_82: u32 = CST_81+1; +pub const CST_83: u32 = CST_82+1; +pub const CST_84: u32 = CST_83+1; +pub const CST_85: u32 = CST_84+1; +pub const CST_86: u32 = CST_85+1; +pub const CST_87: u32 = CST_86+1; +pub const CST_88: u32 = CST_87+1; +pub const CST_89: u32 = CST_88+1; +pub const CST_90: u32 = CST_89+1; +pub const CST_91: u32 = CST_90+1; +pub const CST_92: u32 = CST_91+1; +pub const CST_93: u32 = CST_92+1; +pub const CST_94: u32 = CST_93+1; +pub const CST_95: u32 = CST_94+1; +pub const CST_96: u32 = CST_95+1; +pub const CST_97: u32 = CST_96+1; +pub const CST_98: u32 = CST_97+1; +pub const CST_99: u32 = CST_98+1; +pub const CST_100: u32 = CST_99+1; +pub const CST_101: u32 = CST_100+1; +pub const CST_102: u32 = CST_101+1; +pub const CST_103: u32 = CST_102+1; +pub const CST_104: u32 = CST_103+1; +pub const CST_105: u32 = CST_104+1; +pub const CST_106: u32 = CST_105+1; +pub const CST_107: u32 = CST_106+1; +pub const CST_108: u32 = CST_107+1; +pub const CST_109: u32 = CST_108+1; +pub const CST_110: u32 = CST_109+1; +pub const CST_111: u32 = CST_110+1; +pub const CST_112: u32 = CST_111+1; +pub const CST_113: u32 = CST_112+1; +pub const CST_114: u32 = CST_113+1; +pub const CST_115: u32 = CST_114+1; +pub const CST_116: u32 = CST_115+1; +pub const CST_117: u32 = CST_116+1; +pub const CST_118: u32 = CST_117+1; +pub const CST_119: u32 = CST_118+1; +pub const CST_120: u32 = CST_119+1; +pub const CST_121: u32 = CST_120+1; +pub const CST_122: u32 = CST_121+1; +pub const CST_123: u32 = CST_122+1; +pub const CST_124: u32 = CST_123+1; +pub const CST_125: u32 = CST_124+1; +pub const CST_126: u32 = CST_125+1; +pub const CST_127: u32 = CST_126+1; +pub const CST_128: u32 = CST_127+1; +pub const CST_129: u32 = CST_128+1; +pub const CST_130: u32 = CST_129+1; +pub const CST_131: u32 = CST_130+1; +pub const CST_132: u32 = CST_131+1; +pub const CST_133: u32 = CST_132+1; +pub const CST_134: u32 = CST_133+1; +pub const CST_135: u32 = CST_134+1; +pub const CST_136: u32 = CST_135+1; +pub const CST_137: u32 = CST_136+1; +pub const CST_138: u32 = CST_137+1; +pub const CST_139: u32 = CST_138+1; +pub const CST_140: u32 = CST_139+1; +pub const CST_141: u32 = CST_140+1; +pub const CST_142: u32 = CST_141+1; +pub const CST_143: u32 = CST_142+1; +pub const CST_144: u32 = CST_143+1; +pub const CST_145: u32 = CST_144+1; +pub const CST_146: u32 = CST_145+1; +pub const CST_147: u32 = CST_146+1; +pub const CST_148: u32 = CST_147+1; +pub const CST_149: u32 = CST_148+1; +pub const CST_150: u32 = CST_149+1; +pub const CST_151: u32 = CST_150+1; +pub const CST_152: u32 = CST_151+1; +pub const CST_153: u32 = CST_152+1; +pub const CST_154: u32 = CST_153+1; +pub const CST_155: u32 = CST_154+1; +pub const CST_156: u32 = CST_155+1; +pub const CST_157: u32 = CST_156+1; +pub const CST_158: u32 = CST_157+1; +pub const CST_159: u32 = CST_158+1; +pub const CST_160: u32 = CST_159+1; +pub const CST_161: u32 = CST_160+1; +pub const CST_162: u32 = CST_161+1; +pub const CST_163: u32 = CST_162+1; +pub const CST_164: u32 = CST_163+1; +pub const CST_165: u32 = CST_164+1; +pub const CST_166: u32 = CST_165+1; +pub const CST_167: u32 = CST_166+1; +pub const CST_168: u32 = CST_167+1; +pub const CST_169: u32 = CST_168+1; +pub const CST_170: u32 = CST_169+1; +pub const CST_171: u32 = CST_170+1; +pub const CST_172: u32 = CST_171+1; +pub const CST_173: u32 = CST_172+1; +pub const CST_174: u32 = CST_173+1; +pub const CST_175: u32 = CST_174+1; +pub const CST_176: u32 = CST_175+1; +pub const CST_177: u32 = CST_176+1; +pub const CST_178: u32 = CST_177+1; +pub const CST_179: u32 = CST_178+1; +pub const CST_180: u32 = CST_179+1; +pub const CST_181: u32 = CST_180+1; +pub const CST_182: u32 = CST_181+1; +pub const CST_183: u32 = CST_182+1; +pub const CST_184: u32 = CST_183+1; +pub const CST_185: u32 = CST_184+1; +pub const CST_186: u32 = CST_185+1; +pub const CST_187: u32 = CST_186+1; +pub const CST_188: u32 = CST_187+1; +pub const CST_189: u32 = CST_188+1; +pub const CST_190: u32 = CST_189+1; +pub const CST_191: u32 = CST_190+1; +pub const CST_192: u32 = CST_191+1; +pub const CST_193: u32 = CST_192+1; +pub const CST_194: u32 = CST_193+1; +pub const CST_195: u32 = CST_194+1; +pub const CST_196: u32 = CST_195+1; +pub const CST_197: u32 = CST_196+1; +pub const CST_198: u32 = CST_197+1; +pub const CST_199: u32 = CST_198+1; +pub const CST_200: u32 = CST_199+1; +pub const CST_201: u32 = CST_200+1; +pub const CST_202: u32 = CST_201+1; +pub const CST_203: u32 = CST_202+1; +pub const CST_204: u32 = CST_203+1; +pub const CST_205: u32 = CST_204+1; +pub const CST_206: u32 = CST_205+1; +pub const CST_207: u32 = CST_206+1; +pub const CST_208: u32 = CST_207+1; +pub const CST_209: u32 = CST_208+1; +pub const CST_210: u32 = CST_209+1; +pub const CST_211: u32 = CST_210+1; +pub const CST_212: u32 = CST_211+1; +pub const CST_213: u32 = CST_212+1; +pub const CST_214: u32 = CST_213+1; +pub const CST_215: u32 = CST_214+1; +pub const CST_216: u32 = CST_215+1; +pub const CST_217: u32 = CST_216+1; +pub const CST_218: u32 = CST_217+1; +pub const CST_219: u32 = CST_218+1; +pub const CST_220: u32 = CST_219+1; +pub const CST_221: u32 = CST_220+1; +pub const CST_222: u32 = CST_221+1; +pub const CST_223: u32 = CST_222+1; +pub const CST_224: u32 = CST_223+1; +pub const CST_225: u32 = CST_224+1; +pub const CST_226: u32 = CST_225+1; +pub const CST_227: u32 = CST_226+1; +pub const CST_228: u32 = CST_227+1; +pub const CST_229: u32 = CST_228+1; +pub const CST_230: u32 = CST_229+1; +pub const CST_231: u32 = CST_230+1; +pub const CST_232: u32 = CST_231+1; +pub const CST_233: u32 = CST_232+1; +pub const CST_234: u32 = CST_233+1; +pub const CST_235: u32 = CST_234+1; +pub const CST_236: u32 = CST_235+1; +pub const CST_237: u32 = CST_236+1; +pub const CST_238: u32 = CST_237+1; +pub const CST_239: u32 = CST_238+1; +pub const CST_240: u32 = CST_239+1; +pub const CST_241: u32 = CST_240+1; +pub const CST_242: u32 = CST_241+1; +pub const CST_243: u32 = CST_242+1; +pub const CST_244: u32 = CST_243+1; +pub const CST_245: u32 = CST_244+1; +pub const CST_246: u32 = CST_245+1; +pub const CST_247: u32 = CST_246+1; +pub const CST_248: u32 = CST_247+1; +pub const CST_249: u32 = CST_248+1; +pub const CST_250: u32 = CST_249+1; +pub const CST_251: u32 = CST_250+1; +pub const CST_252: u32 = CST_251+1; +pub const CST_253: u32 = CST_252+1; +pub const CST_254: u32 = CST_253+1; +pub const CST_255: u32 = CST_254+1; +pub const CST_256: u32 = CST_255+1; +pub const CST_257: u32 = CST_256+1; +pub const CST_258: u32 = CST_257+1; +pub const CST_259: u32 = CST_258+1; +pub const CST_260: u32 = CST_259+1; +pub const CST_261: u32 = CST_260+1; +pub const CST_262: u32 = CST_261+1; +pub const CST_263: u32 = CST_262+1; +pub const CST_264: u32 = CST_263+1; +pub const CST_265: u32 = CST_264+1; +pub const CST_266: u32 = CST_265+1; +pub const CST_267: u32 = CST_266+1; +pub const CST_268: u32 = CST_267+1; +pub const CST_269: u32 = CST_268+1; +pub const CST_270: u32 = CST_269+1; +pub const CST_271: u32 = CST_270+1; +pub const CST_272: u32 = CST_271+1; +pub const CST_273: u32 = CST_272+1; +pub const CST_274: u32 = CST_273+1; +pub const CST_275: u32 = CST_274+1; +pub const CST_276: u32 = CST_275+1; +pub const CST_277: u32 = CST_276+1; +pub const CST_278: u32 = CST_277+1; +pub const CST_279: u32 = CST_278+1; +pub const CST_280: u32 = CST_279+1; +pub const CST_281: u32 = CST_280+1; +pub const CST_282: u32 = CST_281+1; +pub const CST_283: u32 = CST_282+1; +pub const CST_284: u32 = CST_283+1; +pub const CST_285: u32 = CST_284+1; +pub const CST_286: u32 = CST_285+1; +pub const CST_287: u32 = CST_286+1; +pub const CST_288: u32 = CST_287+1; +pub const CST_289: u32 = CST_288+1; +pub const CST_290: u32 = CST_289+1; +pub const CST_291: u32 = CST_290+1; +pub const CST_292: u32 = CST_291+1; +pub const CST_293: u32 = CST_292+1; +pub const CST_294: u32 = CST_293+1; +pub const CST_295: u32 = CST_294+1; +pub const CST_296: u32 = CST_295+1; +pub const CST_297: u32 = CST_296+1; +pub const CST_298: u32 = CST_297+1; +pub const CST_299: u32 = CST_298+1; +pub const CST_300: u32 = CST_299+1; +pub const CST_301: u32 = CST_300+1; +pub const CST_302: u32 = CST_301+1; +pub const CST_303: u32 = CST_302+1; +pub const CST_304: u32 = CST_303+1; +pub const CST_305: u32 = CST_304+1; +pub const CST_306: u32 = CST_305+1; +pub const CST_307: u32 = CST_306+1; +pub const CST_308: u32 = CST_307+1; +pub const CST_309: u32 = CST_308+1; +pub const CST_310: u32 = CST_309+1; +pub const CST_311: u32 = CST_310+1; +pub const CST_312: u32 = CST_311+1; +pub const CST_313: u32 = CST_312+1; +pub const CST_314: u32 = CST_313+1; +pub const CST_315: u32 = CST_314+1; +pub const CST_316: u32 = CST_315+1; +pub const CST_317: u32 = CST_316+1; +pub const CST_318: u32 = CST_317+1; +pub const CST_319: u32 = CST_318+1; +pub const CST_320: u32 = CST_319+1; +pub const CST_321: u32 = CST_320+1; +pub const CST_322: u32 = CST_321+1; +pub const CST_323: u32 = CST_322+1; +pub const CST_324: u32 = CST_323+1; +pub const CST_325: u32 = CST_324+1; +pub const CST_326: u32 = CST_325+1; +pub const CST_327: u32 = CST_326+1; +pub const CST_328: u32 = CST_327+1; +pub const CST_329: u32 = CST_328+1; +pub const CST_330: u32 = CST_329+1; +pub const CST_331: u32 = CST_330+1; +pub const CST_332: u32 = CST_331+1; +pub const CST_333: u32 = CST_332+1; +pub const CST_334: u32 = CST_333+1; +pub const CST_335: u32 = CST_334+1; +pub const CST_336: u32 = CST_335+1; +pub const CST_337: u32 = CST_336+1; +pub const CST_338: u32 = CST_337+1; +pub const CST_339: u32 = CST_338+1; +pub const CST_340: u32 = CST_339+1; +pub const CST_341: u32 = CST_340+1; +pub const CST_342: u32 = CST_341+1; +pub const CST_343: u32 = CST_342+1; +pub const CST_344: u32 = CST_343+1; +pub const CST_345: u32 = CST_344+1; +pub const CST_346: u32 = CST_345+1; +pub const CST_347: u32 = CST_346+1; +pub const CST_348: u32 = CST_347+1; +pub const CST_349: u32 = CST_348+1; +pub const CST_350: u32 = CST_349+1; + +fn main() {} diff --git a/src/test/ui/run-pass/ctfe/const-block-non-item-statement-3.rs b/src/test/ui/run-pass/ctfe/const-block-non-item-statement-3.rs new file mode 100644 index 00000000000..e233107169c --- /dev/null +++ b/src/test/ui/run-pass/ctfe/const-block-non-item-statement-3.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_let)] + +type Array = [u32; { let x = 2; 5 }]; + +pub fn main() {} diff --git a/src/test/ui/run-pass/ctfe/const-block-non-item-statement.rs b/src/test/ui/run-pass/ctfe/const-block-non-item-statement.rs new file mode 100644 index 00000000000..b5a9bfb45a1 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/const-block-non-item-statement.rs @@ -0,0 +1,17 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_let)] + +enum Foo { + Bar = { let x = 1; 3 } +} + +pub fn main() {} diff --git a/src/test/ui/run-pass/ctfe/const-fn-destructuring-arg.rs b/src/test/ui/run-pass/ctfe/const-fn-destructuring-arg.rs new file mode 100644 index 00000000000..8b832976aab --- /dev/null +++ b/src/test/ui/run-pass/ctfe/const-fn-destructuring-arg.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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// test that certain things are disallowed in constant functions + +#![feature(const_fn, const_let)] + +// no destructuring +const fn i(( + a, + b + ): (u32, u32)) -> u32 { + a + b +} + +fn main() {} diff --git a/src/test/ui/run-pass/ctfe/deref_in_pattern.rs b/src/test/ui/run-pass/ctfe/deref_in_pattern.rs new file mode 100644 index 00000000000..4ccfa0338f3 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/deref_in_pattern.rs @@ -0,0 +1,20 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/25574 + +const A: [u8; 4] = *b"fooo"; + +fn main() { + match *b"xxxx" { + A => {}, + _ => {} + } +} diff --git a/src/test/ui/run-pass/ctfe/ice-48279.rs b/src/test/ui/run-pass/ctfe/ice-48279.rs new file mode 100644 index 00000000000..f59a6810e3a --- /dev/null +++ b/src/test/ui/run-pass/ctfe/ice-48279.rs @@ -0,0 +1,34 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/48279 + +#![feature(min_const_fn)] + +#[derive(PartialEq, Eq)] +pub struct NonZeroU32 { + value: u32 +} + +impl NonZeroU32 { + const unsafe fn new_unchecked(value: u32) -> Self { + NonZeroU32 { value } + } +} + +//pub const FOO_ATOM: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(7) }; +pub const FOO_ATOM: NonZeroU32 = unsafe { NonZeroU32 { value: 7 } }; + +fn main() { + match None { + Some(FOO_ATOM) => {} + _ => {} + } +} diff --git a/src/test/ui/run-pass/ctfe/issue-37550.rs b/src/test/ui/run-pass/ctfe/issue-37550.rs new file mode 100644 index 00000000000..27796a5feea --- /dev/null +++ b/src/test/ui/run-pass/ctfe/issue-37550.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_fn, const_let)] + +const fn x() { + let t = true; + let x = || t; +} + +fn main() {} diff --git a/src/test/ui/run-pass/ctfe/issue-broken-mir.rs b/src/test/ui/run-pass/ctfe/issue-broken-mir.rs new file mode 100644 index 00000000000..6ed0c7c0d5d --- /dev/null +++ b/src/test/ui/run-pass/ctfe/issue-broken-mir.rs @@ -0,0 +1,18 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/27918 + +fn main() { + match b" " { + b"1234" => {}, + _ => {}, + } +} diff --git a/src/test/ui/run-pass/ctfe/locals-in-const-fn.rs b/src/test/ui/run-pass/ctfe/locals-in-const-fn.rs new file mode 100644 index 00000000000..8c153315c25 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/locals-in-const-fn.rs @@ -0,0 +1,45 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/48821 + +#![feature(const_fn, const_let)] + +const fn foo(i: usize) -> usize { + let x = i; + x +} + +static FOO: usize = foo(42); + +const fn bar(mut i: usize) -> usize { + i += 8; + let x = &i; + *x +} + +static BAR: usize = bar(42); + +const fn boo(mut i: usize) -> usize { + { + let mut x = i; + x += 10; + i = x; + } + i +} + +static BOO: usize = boo(42); + +fn main() { + assert!(FOO == 42); + assert!(BAR == 50); + assert!(BOO == 52); +} diff --git a/src/test/ui/run-pass/ctfe/match-const-fn-structs.rs b/src/test/ui/run-pass/ctfe/match-const-fn-structs.rs new file mode 100644 index 00000000000..352958f4c6a --- /dev/null +++ b/src/test/ui/run-pass/ctfe/match-const-fn-structs.rs @@ -0,0 +1,31 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/46114 + +#![feature(min_const_fn)] + +#[derive(Eq, PartialEq)] +struct A { value: u32 } + +const fn new(value: u32) -> A { + A { value } +} + +const A_1: A = new(1); +const A_2: A = new(2); + +fn main() { + let a_str = match new(42) { + A_1 => "A 1", + A_2 => "A 2", + _ => "Unknown A", + }; +} diff --git a/src/test/ui/run-pass/ctfe/mozjs-error.rs b/src/test/ui/run-pass/ctfe/mozjs-error.rs new file mode 100644 index 00000000000..9c8a4b5ae6a --- /dev/null +++ b/src/test/ui/run-pass/ctfe/mozjs-error.rs @@ -0,0 +1,37 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct CustomAutoRooterVFTable { + trace: unsafe extern "C" fn(this: *mut i32, trc: *mut u32), +} + +unsafe trait CustomAutoTraceable: Sized { + const vftable: CustomAutoRooterVFTable = CustomAutoRooterVFTable { + trace: Self::trace, + }; + + unsafe extern "C" fn trace(this: *mut i32, trc: *mut u32) { + let this = this as *const Self; + let this = this.as_ref().unwrap(); + Self::do_trace(this, trc); + } + + fn do_trace(&self, trc: *mut u32); +} + +unsafe impl CustomAutoTraceable for () { + fn do_trace(&self, _: *mut u32) { + // nop + } +} + +fn main() { + let _ = <()>::vftable; +} diff --git a/src/test/ui/run-pass/ctfe/non-scalar-cast.rs b/src/test/ui/run-pass/ctfe/non-scalar-cast.rs new file mode 100644 index 00000000000..ff4474f47c9 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/non-scalar-cast.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/37448 + +fn main() { + struct A; + const FOO: &A = &(A as A); + let _x = FOO; +} diff --git a/src/test/ui/run-pass/ctfe/promotion.rs b/src/test/ui/run-pass/ctfe/promotion.rs new file mode 100644 index 00000000000..28b876c308b --- /dev/null +++ b/src/test/ui/run-pass/ctfe/promotion.rs @@ -0,0 +1,25 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -O + +fn foo(_: &'static [&'static str]) {} +fn bar(_: &'static [&'static str; 3]) {} +fn baz_i32(_: &'static i32) {} +fn baz_u32(_: &'static u32) {} + +fn main() { + foo(&["a", "b", "c"]); + bar(&["d", "e", "f"]); + + // make sure that these do not cause trouble despite overflowing + baz_u32(&(0-1)); + baz_i32(&-std::i32::MIN); +} diff --git a/src/test/ui/run-pass/ctfe/references.rs b/src/test/ui/run-pass/ctfe/references.rs new file mode 100644 index 00000000000..ad7dbeb79c7 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/references.rs @@ -0,0 +1,34 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const FOO: &[u8] = b"foo"; +const BAR: &[u8] = &[1, 2, 3]; + +const BOO: &i32 = &42; + +fn main() { + match &[1u8, 2, 3] as &[u8] { + FOO => panic!("a"), + BAR => println!("b"), + _ => panic!("c"), + } + + match b"foo" as &[u8] { + FOO => println!("a"), + BAR => panic!("b"), + _ => panic!("c"), + } + + match &43 { + &42 => panic!(), + BOO => panic!(), + _ => println!("d"), + } +} diff --git a/src/test/ui/run-pass/ctfe/repeat_match.rs b/src/test/ui/run-pass/ctfe/repeat_match.rs new file mode 100644 index 00000000000..dedf5defebb --- /dev/null +++ b/src/test/ui/run-pass/ctfe/repeat_match.rs @@ -0,0 +1,20 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/45044 + +const X: [u8; 1] = [0; 1]; + +fn main() { + match &X { + &X => println!("a"), + _ => println!("b"), + }; +} diff --git a/src/test/ui/run-pass/ctfe/return-in-const-fn.rs b/src/test/ui/run-pass/ctfe/return-in-const-fn.rs new file mode 100644 index 00000000000..87fdac4bfb4 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/return-in-const-fn.rs @@ -0,0 +1,19 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/43754 + +#![feature(min_const_fn)] +const fn foo(x: usize) -> usize { + return x; +} +fn main() { + [0; foo(2)]; +} diff --git a/src/test/ui/run-pass/ctfe/signed_enum_discr.rs b/src/test/ui/run-pass/ctfe/signed_enum_discr.rs new file mode 100644 index 00000000000..7049d28a870 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/signed_enum_discr.rs @@ -0,0 +1,27 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49181 + +#[derive(Eq, PartialEq)] +#[repr(i8)] +pub enum A { + B = -1, + C = 1, +} + +pub const D: A = A::B; + +fn main() { + match A::C { + D => {}, + _ => {} + } +} diff --git a/src/test/ui/run-pass/ctfe/transmute-const.rs b/src/test/ui/run-pass/ctfe/transmute-const.rs new file mode 100644 index 00000000000..bf9459a67c4 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/transmute-const.rs @@ -0,0 +1,22 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_transmute)] + +use std::mem; + +#[repr(transparent)] +struct Foo(u32); + +const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) }; + +fn main() { + assert_eq!(TRANSMUTED_U32, 3); +} diff --git a/src/test/ui/run-pass/ctfe/tuple-struct-constructors.rs b/src/test/ui/run-pass/ctfe/tuple-struct-constructors.rs new file mode 100644 index 00000000000..d5f3e88fd52 --- /dev/null +++ b/src/test/ui/run-pass/ctfe/tuple-struct-constructors.rs @@ -0,0 +1,18 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/41898 + +use std::num::NonZeroU64; + +fn main() { + const FOO: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(2) }; + if let FOO = FOO {} +} diff --git a/src/test/ui/run-pass/generator/auxiliary/xcrate-reachable.rs b/src/test/ui/run-pass/generator/auxiliary/xcrate-reachable.rs new file mode 100644 index 00000000000..91e43537cc2 --- /dev/null +++ b/src/test/ui/run-pass/generator/auxiliary/xcrate-reachable.rs @@ -0,0 +1,24 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn msg() -> u32 { + 0 +} + +pub fn foo() -> impl Generator<Yield=(), Return=u32> { + || { + yield; + return msg(); + } +} diff --git a/src/test/ui/run-pass/generator/auxiliary/xcrate.rs b/src/test/ui/run-pass/generator/auxiliary/xcrate.rs new file mode 100644 index 00000000000..fcfe0b754b6 --- /dev/null +++ b/src/test/ui/run-pass/generator/auxiliary/xcrate.rs @@ -0,0 +1,27 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +pub fn foo() -> impl Generator<Yield = (), Return = ()> { + || { + if false { + yield; + } + } +} + +pub fn bar<T: 'static>(t: T) -> Box<Generator<Yield = T, Return = ()>> { + Box::new(|| { + yield t; + }) +} diff --git a/src/test/ui/run-pass/generator/borrow-in-tail-expr.rs b/src/test/ui/run-pass/generator/borrow-in-tail-expr.rs new file mode 100644 index 00000000000..486fe3c900d --- /dev/null +++ b/src/test/ui/run-pass/generator/borrow-in-tail-expr.rs @@ -0,0 +1,19 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn main() { + let _a = || { + yield; + let a = String::new(); + a.len() + }; +} diff --git a/src/test/ui/run-pass/generator/conditional-drop.rs b/src/test/ui/run-pass/generator/conditional-drop.rs new file mode 100644 index 00000000000..3d39c46186b --- /dev/null +++ b/src/test/ui/run-pass/generator/conditional-drop.rs @@ -0,0 +1,65 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static A: AtomicUsize = ATOMIC_USIZE_INIT; + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + + +fn test() -> bool { true } +fn test2() -> bool { false } + +fn main() { + t1(); + t2(); +} + +fn t1() { + let mut a = || { + let b = B; + if test() { + drop(b); + } + yield; + }; + + let n = A.load(Ordering::SeqCst); + unsafe { a.resume() }; + assert_eq!(A.load(Ordering::SeqCst), n + 1); + unsafe { a.resume() }; + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t2() { + let mut a = || { + let b = B; + if test2() { + drop(b); + } + yield; + }; + + let n = A.load(Ordering::SeqCst); + unsafe { a.resume() }; + assert_eq!(A.load(Ordering::SeqCst), n); + unsafe { a.resume() }; + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} diff --git a/src/test/ui/run-pass/generator/control-flow.rs b/src/test/ui/run-pass/generator/control-flow.rs new file mode 100644 index 00000000000..09971410e55 --- /dev/null +++ b/src/test/ui/run-pass/generator/control-flow.rs @@ -0,0 +1,56 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; + +fn finish<T>(mut amt: usize, mut t: T) -> T::Return + where T: Generator<Yield = ()> +{ + loop { + match unsafe { t.resume() } { + GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), + GeneratorState::Complete(ret) => { + assert_eq!(amt, 0); + return ret + } + } + } + +} + +fn main() { + finish(1, || yield); + finish(8, || { + for _ in 0..8 { + yield; + } + }); + finish(1, || { + if true { + yield; + } else { + } + }); + finish(1, || { + if false { + } else { + yield; + } + }); + finish(2, || { + if { yield; false } { + yield; + panic!() + } + yield + }); +} diff --git a/src/test/ui/run-pass/generator/drop-env.rs b/src/test/ui/run-pass/generator/drop-env.rs new file mode 100644 index 00000000000..ef4dc24472e --- /dev/null +++ b/src/test/ui/run-pass/generator/drop-env.rs @@ -0,0 +1,70 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static A: AtomicUsize = ATOMIC_USIZE_INIT; + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + t1(); + t2(); + t3(); +} + +fn t1() { + let b = B; + let mut foo = || { + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + drop(unsafe { foo.resume() }); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t2() { + let b = B; + let mut foo = || { + yield b; + }; + + let n = A.load(Ordering::SeqCst); + drop(unsafe { foo.resume() }); + assert_eq!(A.load(Ordering::SeqCst), n + 1); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t3() { + let b = B; + let foo = || { + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} diff --git a/src/test/ui/run-pass/generator/issue-44197.rs b/src/test/ui/run-pass/generator/issue-44197.rs new file mode 100644 index 00000000000..272b7eb7bfd --- /dev/null +++ b/src/test/ui/run-pass/generator/issue-44197.rs @@ -0,0 +1,42 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{ Generator, GeneratorState }; + +fn foo(_: &str) -> String { + String::new() +} + +fn bar(baz: String) -> impl Generator<Yield = String, Return = ()> { + move || { + yield foo(&baz); + } +} + +fn foo2(_: &str) -> Result<String, ()> { + Err(()) +} + +fn bar2(baz: String) -> impl Generator<Yield = String, Return = ()> { + move || { + if let Ok(quux) = foo2(&baz) { + yield quux; + } + } +} + +fn main() { + unsafe { + assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); + assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); + } +} diff --git a/src/test/ui/run-pass/generator/issue-52398.rs b/src/test/ui/run-pass/generator/issue-52398.rs new file mode 100644 index 00000000000..0fb8f277ea9 --- /dev/null +++ b/src/test/ui/run-pass/generator/issue-52398.rs @@ -0,0 +1,35 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +use std::cell::RefCell; + +struct A; + +impl A { + fn test(&self, a: ()) {} +} + +fn main() { + // Test that the MIR local with type &A created for the auto-borrow adjustment + // is caught by typeck + move || { + A.test(yield); + }; + + // Test that the std::cell::Ref temporary returned from the `borrow` call + // is caught by typeck + let y = RefCell::new(true); + static move || { + yield *y.borrow(); + return "Done"; + }; +} diff --git a/src/test/ui/run-pass/generator/iterator-count.rs b/src/test/ui/run-pass/generator/iterator-count.rs new file mode 100644 index 00000000000..3564ddaa806 --- /dev/null +++ b/src/test/ui/run-pass/generator/iterator-count.rs @@ -0,0 +1,50 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; + +struct W<T>(T); + +// This impl isn't safe in general, but the generator used in this test is movable +// so it won't cause problems. +impl<T: Generator<Return = ()>> Iterator for W<T> { + type Item = T::Yield; + + fn next(&mut self) -> Option<Self::Item> { + match unsafe { self.0.resume() } { + GeneratorState::Complete(..) => None, + GeneratorState::Yielded(v) => Some(v), + } + } +} + +fn test() -> impl Generator<Return=(), Yield=u8> { + || { + for i in 1..6 { + yield i + } + } +} + +fn main() { + let end = 11; + + let closure_test = |start| { + move || { + for i in start..end { + yield i + } + } + }; + + assert!(W(test()).chain(W(closure_test(6))).eq(1..11)); +} diff --git a/src/test/ui/run-pass/generator/live-upvar-across-yield.rs b/src/test/ui/run-pass/generator/live-upvar-across-yield.rs new file mode 100644 index 00000000000..28e7da232ce --- /dev/null +++ b/src/test/ui/run-pass/generator/live-upvar-across-yield.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn main() { + let b = |_| 3; + let mut a = || { + b(yield); + }; + unsafe { a.resume() }; +} diff --git a/src/test/ui/run-pass/generator/match-bindings.rs b/src/test/ui/run-pass/generator/match-bindings.rs new file mode 100644 index 00000000000..231aa1b42f0 --- /dev/null +++ b/src/test/ui/run-pass/generator/match-bindings.rs @@ -0,0 +1,30 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +enum Enum { + A(String), + B +} + +fn main() { + || { + loop { + if let true = true { + match Enum::A(String::new()) { + Enum::A(_var) => {} + Enum::B => {} + } + } + yield; + } + }; +} diff --git a/src/test/ui/run-pass/generator/nested_generators.rs b/src/test/ui/run-pass/generator/nested_generators.rs new file mode 100644 index 00000000000..29808da85a7 --- /dev/null +++ b/src/test/ui/run-pass/generator/nested_generators.rs @@ -0,0 +1,30 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] +#![feature(generator_trait)] + +use std::ops::Generator; +use std::ops::GeneratorState; + +fn main() { + let _generator = || { + let mut sub_generator = || { + yield 2; + }; + + match unsafe { sub_generator.resume() } { + GeneratorState::Yielded(x) => { + yield x; + } + _ => panic!(), + }; + }; +} diff --git a/src/test/ui/run-pass/generator/panic-drops.rs b/src/test/ui/run-pass/generator/panic-drops.rs new file mode 100644 index 00000000000..3d7b60ab6b9 --- /dev/null +++ b/src/test/ui/run-pass/generator/panic-drops.rs @@ -0,0 +1,64 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-wasm32-bare compiled as panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +static A: AtomicUsize = ATOMIC_USIZE_INIT; + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn bool_true() -> bool { + true +} + +fn main() { + let b = B; + let mut foo = || { + if bool_true() { + panic!(); + } + drop(b); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 0); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + unsafe { foo.resume() } + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); + + let mut foo = || { + if bool_true() { + panic!(); + } + drop(B); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 1); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + unsafe { foo.resume() } + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); +} diff --git a/src/test/ui/run-pass/generator/panic-safe.rs b/src/test/ui/run-pass/generator/panic-safe.rs new file mode 100644 index 00000000000..ace5cdde51d --- /dev/null +++ b/src/test/ui/run-pass/generator/panic-safe.rs @@ -0,0 +1,37 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic; + +fn main() { + let mut foo = || { + if true { + panic!(); + } + yield; + }; + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + unsafe { foo.resume() } + })); + assert!(res.is_err()); + + for _ in 0..10 { + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + unsafe { foo.resume() } + })); + assert!(res.is_err()); + } +} diff --git a/src/test/ui/run-pass/generator/reborrow-mut-upvar.rs b/src/test/ui/run-pass/generator/reborrow-mut-upvar.rs new file mode 100644 index 00000000000..8353066bfbe --- /dev/null +++ b/src/test/ui/run-pass/generator/reborrow-mut-upvar.rs @@ -0,0 +1,24 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn _run(bar: &mut i32) { + || { + { + let _baz = &*bar; + yield; + } + + *bar = 2; + }; +} + +fn main() {} diff --git a/src/test/ui/run-pass/generator/resume-after-return.rs b/src/test/ui/run-pass/generator/resume-after-return.rs new file mode 100644 index 00000000000..06e7615d261 --- /dev/null +++ b/src/test/ui/run-pass/generator/resume-after-return.rs @@ -0,0 +1,35 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::panic; + +fn main() { + let mut foo = || { + if true { + return + } + yield; + }; + + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + + match panic::catch_unwind(move || unsafe { foo.resume() }) { + Ok(_) => panic!("generator successfully resumed"), + Err(_) => {} + } +} diff --git a/src/test/ui/run-pass/generator/smoke.rs b/src/test/ui/run-pass/generator/smoke.rs new file mode 100644 index 00000000000..7395c8484c1 --- /dev/null +++ b/src/test/ui/run-pass/generator/smoke.rs @@ -0,0 +1,181 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-emscripten no threads support +// compile-flags: --test + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::thread; + +#[test] +fn simple() { + let mut foo = || { + if false { + yield; + } + }; + + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_capture() { + let a = String::from("foo"); + let mut foo = || { + if false { + yield; + } + a + }; + + match unsafe { foo.resume() } { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield() { + let mut foo = || { + yield; + }; + + match unsafe { foo.resume() } { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn yield_capture() { + let b = String::from("foo"); + let mut foo = || { + yield b; + }; + + match unsafe { foo.resume() } { + GeneratorState::Yielded(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield_value() { + let mut foo = || { + yield String::from("bar"); + return String::from("foo") + }; + + match unsafe { foo.resume() } { + GeneratorState::Yielded(ref s) if *s == "bar" => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_after_yield() { + let a = String::from("foo"); + let mut foo = || { + yield; + return a + }; + + match unsafe { foo.resume() } { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn send_and_sync() { + assert_send_sync(|| { + yield + }); + assert_send_sync(|| { + yield String::from("foo"); + }); + assert_send_sync(|| { + yield; + return String::from("foo"); + }); + let a = 3; + assert_send_sync(|| { + yield a; + return + }); + let a = 3; + assert_send_sync(move || { + yield a; + return + }); + let a = String::from("a"); + assert_send_sync(|| { + yield ; + drop(a); + return + }); + let a = String::from("a"); + assert_send_sync(move || { + yield ; + drop(a); + return + }); + + fn assert_send_sync<T: Send + Sync>(_: T) {} +} + +#[test] +fn send_over_threads() { + let mut foo = || { yield }; + thread::spawn(move || { + match unsafe { foo.resume() } { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); + + let a = String::from("a"); + let mut foo = || { yield a }; + thread::spawn(move || { + match unsafe { foo.resume() } { + GeneratorState::Yielded(ref s) if *s == "a" => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); +} diff --git a/src/test/ui/run-pass/generator/static-generators.rs b/src/test/ui/run-pass/generator/static-generators.rs new file mode 100644 index 00000000000..ebc070eee09 --- /dev/null +++ b/src/test/ui/run-pass/generator/static-generators.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; + +fn main() { + let mut generator = static || { + let a = true; + let b = &a; + yield; + assert_eq!(b as *const _, &a as *const _); + }; + unsafe { + assert_eq!(generator.resume(), GeneratorState::Yielded(())); + assert_eq!(generator.resume(), GeneratorState::Complete(())); + } +} diff --git a/src/test/ui/run-pass/generator/too-live-local-in-immovable-gen.rs b/src/test/ui/run-pass/generator/too-live-local-in-immovable-gen.rs new file mode 100644 index 00000000000..2314533a681 --- /dev/null +++ b/src/test/ui/run-pass/generator/too-live-local-in-immovable-gen.rs @@ -0,0 +1,28 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn main() { + unsafe { + static move || { + // Tests that the generator transformation finds out that `a` is not live + // during the yield expression. Type checking will also compute liveness + // and it should also find out that `a` is not live. + // The compiler will panic if the generator transformation finds that + // `a` is live and type checking finds it dead. + let a = { + yield (); + 4i32 + }; + &a; + }; + } +} diff --git a/src/test/ui/run-pass/generator/xcrate-reachable.rs b/src/test/ui/run-pass/generator/xcrate-reachable.rs new file mode 100644 index 00000000000..2fc39ba1869 --- /dev/null +++ b/src/test/ui/run-pass/generator/xcrate-reachable.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:xcrate-reachable.rs + +#![feature(generator_trait)] + +extern crate xcrate_reachable as foo; + +use std::ops::Generator; + +fn main() { + unsafe { foo::foo().resume(); } +} diff --git a/src/test/ui/run-pass/generator/xcrate.rs b/src/test/ui/run-pass/generator/xcrate.rs new file mode 100644 index 00000000000..04791d51356 --- /dev/null +++ b/src/test/ui/run-pass/generator/xcrate.rs @@ -0,0 +1,37 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:xcrate.rs + +#![feature(generators, generator_trait)] + +extern crate xcrate; + +use std::ops::{GeneratorState, Generator}; + +fn main() { + let mut foo = xcrate::foo(); + + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + + let mut foo = xcrate::bar(3); + + match unsafe { foo.resume() } { + GeneratorState::Yielded(3) => {} + s => panic!("bad state: {:?}", s), + } + match unsafe { foo.resume() } { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} diff --git a/src/test/ui/run-pass/generator/yield-in-args-rev.rs b/src/test/ui/run-pass/generator/yield-in-args-rev.rs new file mode 100644 index 00000000000..df00329799e --- /dev/null +++ b/src/test/ui/run-pass/generator/yield-in-args-rev.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that a borrow that occurs after a yield in the same +// argument list is not treated as live across the yield by +// type-checking. + +#![feature(generators)] + +fn foo(_a: (), _b: &bool) {} + +fn bar() { + || { + let b = true; + foo(yield, &b); + }; +} + +fn main() { } diff --git a/src/test/ui/run-pass/generator/yield-in-box.rs b/src/test/ui/run-pass/generator/yield-in-box.rs new file mode 100644 index 00000000000..d68007be05c --- /dev/null +++ b/src/test/ui/run-pass/generator/yield-in-box.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that box-statements with yields in them work. + +#![feature(generators, box_syntax)] + +fn main() { + let x = 0i32; + || { + let y = 2u32; + { + let _t = box (&x, yield 0, &y); + } + match box (&x, yield 0, &y) { + _t => {} + } + }; +} diff --git a/src/test/ui/run-pass/generator/yield-in-initializer.rs b/src/test/ui/run-pass/generator/yield-in-initializer.rs new file mode 100644 index 00000000000..3042061226b --- /dev/null +++ b/src/test/ui/run-pass/generator/yield-in-initializer.rs @@ -0,0 +1,25 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn main() { + static || { + loop { + // Test that `opt` is not live across the yield, even when borrowed in a loop + // See https://github.com/rust-lang/rust/issues/52792 + let opt = { + yield; + true + }; + &opt; + } + }; +} diff --git a/src/test/ui/run-pass/generator/yield-subtype.rs b/src/test/ui/run-pass/generator/yield-subtype.rs new file mode 100644 index 00000000000..c4134169044 --- /dev/null +++ b/src/test/ui/run-pass/generator/yield-subtype.rs @@ -0,0 +1,27 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// revisions:lexical nll +//[nll]compile-flags: -Z disable-nll-user-type-assert +#![cfg_attr(nll, feature(nll))] + +#![feature(generators)] + +fn bar<'a>() { + let a: &'static str = "hi"; + let b: &'a str = a; + + || { + yield a; + yield b; + }; +} + +fn main() {} diff --git a/src/test/ui/run-pass/impl-trait/auto-trait-leak.rs b/src/test/ui/run-pass/impl-trait/auto-trait-leak.rs new file mode 100644 index 00000000000..62fbae7b40c --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/auto-trait-leak.rs @@ -0,0 +1,29 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Fast path, main can see the concrete type returned. +fn before() -> impl FnMut(i32) { + let mut p = Box::new(0); + move |x| *p = x +} + +fn send<T: Send>(_: T) {} + +fn main() { + send(before()); + send(after()); +} + +// Deferred path, main has to wait until typeck finishes, +// to check if the return type of after is Send. +fn after() -> impl FnMut(i32) { + let mut p = Box::new(0); + move |x| *p = x +} diff --git a/src/test/ui/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/ui/run-pass/impl-trait/auxiliary/xcrate.rs new file mode 100644 index 00000000000..c57c1cfe74f --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/auxiliary/xcrate.rs @@ -0,0 +1,33 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// NOTE commented out due to issue #45994 +//pub fn fourway_add(a: i32) -> impl Fn(i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 { +// move |b| move |c| move |d| a + b + c + d +//} + +fn some_internal_fn() -> u32 { + 1 +} + +fn other_internal_fn() -> u32 { + 1 +} + +// See #40839 +pub fn return_closure_accessing_internal_fn() -> impl Fn() -> u32 { + || { + some_internal_fn() + 1 + } +} + +pub fn return_internal_fn() -> impl Fn() -> u32 { + other_internal_fn +} diff --git a/src/test/ui/run-pass/impl-trait/bounds_regression.rs b/src/test/ui/run-pass/impl-trait/bounds_regression.rs new file mode 100644 index 00000000000..cc931a68edd --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/bounds_regression.rs @@ -0,0 +1,32 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait FakeGenerator { + type Yield; + type Return; +} + +pub trait FakeFuture { + type Output; +} + +pub fn future_from_generator< + T: FakeGenerator<Yield = ()> +>(x: T) -> impl FakeFuture<Output = T::Return> { + GenFuture(x) +} + +struct GenFuture<T: FakeGenerator<Yield = ()>>(T); + +impl<T: FakeGenerator<Yield = ()>> FakeFuture for GenFuture<T> { + type Output = T::Return; +} + +fn main() {} diff --git a/src/test/ui/run-pass/impl-trait/equality.rs b/src/test/ui/run-pass/impl-trait/equality.rs new file mode 100644 index 00000000000..034d3d7c80f --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/equality.rs @@ -0,0 +1,56 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +trait Foo: std::fmt::Debug + Eq {} + +impl<T: std::fmt::Debug + Eq> Foo for T {} + +fn hide<T: Foo>(x: T) -> impl Foo { + x +} + +trait Leak<T>: Sized { + fn leak(self) -> T; +} +impl<T, U> Leak<T> for U { + default fn leak(self) -> T { panic!("type mismatch") } +} +impl<T> Leak<T> for T { + fn leak(self) -> T { self } +} + +trait CheckIfSend: Sized { + type T: Default; + fn check(self) -> Self::T { Default::default() } +} +impl<T> CheckIfSend for T { + default type T = (); +} +impl<T: Send> CheckIfSend for T { + type T = bool; +} + +fn lucky_seven() -> impl Fn(usize) -> u8 { + let a = [1, 2, 3, 4, 5, 6, 7]; + move |i| a[i] +} + +fn main() { + assert_eq!(hide(42), hide(42)); + + assert_eq!(std::mem::size_of_val(&hide([0_u8; 5])), 5); + assert_eq!(std::mem::size_of_val(&lucky_seven()), 7); + + assert_eq!(Leak::<i32>::leak(hide(5_i32)), 5_i32); + + assert_eq!(CheckIfSend::check(hide(0_i32)), false); +} diff --git a/src/test/ui/run-pass/impl-trait/example-calendar.rs b/src/test/ui/run-pass/impl-trait/example-calendar.rs new file mode 100644 index 00000000000..fce31256db4 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/example-calendar.rs @@ -0,0 +1,892 @@ +// Copyright 2016-2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// revisions: normal nll +//[nll] compile-flags:-Zborrowck=mir + +#![feature(fn_traits, + step_trait, + unboxed_closures, +)] + +//! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>. +//! +//! Originally converted to Rust by [Daniel Keep](https://github.com/DanielKeep). + +use std::fmt::Write; +use std::mem; + +/// Date representation. +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct NaiveDate(i32, u32, u32); + +impl NaiveDate { + pub fn from_ymd(y: i32, m: u32, d: u32) -> NaiveDate { + assert!(1 <= m && m <= 12, "m = {:?}", m); + assert!(1 <= d && d <= NaiveDate(y, m, 1).days_in_month(), "d = {:?}", d); + NaiveDate(y, m, d) + } + + pub fn year(&self) -> i32 { + self.0 + } + + pub fn month(&self) -> u32 { + self.1 + } + + pub fn day(&self) -> u32 { + self.2 + } + + pub fn succ(&self) -> NaiveDate { + let (mut y, mut m, mut d, n) = ( + self.year(), self.month(), self.day()+1, self.days_in_month()); + if d > n { + d = 1; + m += 1; + } + if m > 12 { + m = 1; + y += 1; + } + NaiveDate::from_ymd(y, m, d) + } + + pub fn weekday(&self) -> Weekday { + use Weekday::*; + + // 0 = Sunday + let year = self.year(); + let dow_jan_1 = (year*365 + ((year-1) / 4) - ((year-1) / 100) + ((year-1) / 400)) % 7; + let dow = (dow_jan_1 + (self.day_of_year() as i32 - 1)) % 7; + [Sun, Mon, Tue, Wed, Thu, Fri, Sat][dow as usize] + } + + pub fn isoweekdate(&self) -> (i32, u32, Weekday) { + let first_dow_mon_0 = self.year_first_day_of_week().num_days_from_monday(); + + // Work out this date's DOtY and week number, not including year adjustment. + let doy_0 = self.day_of_year() - 1; + let mut week_mon_0: i32 = ((first_dow_mon_0 + doy_0) / 7) as i32; + + if self.first_week_in_prev_year() { + week_mon_0 -= 1; + } + + let weeks_in_year = self.last_week_number(); + + // Work out the final result. + // If the week is -1 or >= weeks_in_year, we will need to adjust the year. + let year = self.year(); + let wd = self.weekday(); + + if week_mon_0 < 0 { + (year - 1, NaiveDate::from_ymd(year - 1, 1, 1).last_week_number(), wd) + } else if week_mon_0 >= weeks_in_year as i32 { + (year + 1, (week_mon_0 + 1 - weeks_in_year as i32) as u32, wd) + } else { + (year, (week_mon_0 + 1) as u32, wd) + } + } + + fn first_week_in_prev_year(&self) -> bool { + let first_dow_mon_0 = self.year_first_day_of_week().num_days_from_monday(); + + // Any day in the year *before* the first Monday of that year + // is considered to be in the last week of the previous year, + // assuming the first week has *less* than four days in it. + // Adjust the week appropriately. + ((7 - first_dow_mon_0) % 7) < 4 + } + + fn year_first_day_of_week(&self) -> Weekday { + NaiveDate::from_ymd(self.year(), 1, 1).weekday() + } + + fn weeks_in_year(&self) -> u32 { + let days_in_last_week = self.year_first_day_of_week().num_days_from_monday() + 1; + if days_in_last_week >= 4 { 53 } else { 52 } + } + + fn last_week_number(&self) -> u32 { + let wiy = self.weeks_in_year(); + if self.first_week_in_prev_year() { wiy - 1 } else { wiy } + } + + fn day_of_year(&self) -> u32 { + (1..self.1).map(|m| NaiveDate::from_ymd(self.year(), m, 1).days_in_month()) + .fold(0, |a,b| a+b) + self.day() + } + + fn is_leap_year(&self) -> bool { + let year = self.year(); + if year % 4 != 0 { + return false + } else if year % 100 != 0 { + return true + } else if year % 400 != 0 { + return false + } else { + return true + } + } + + fn days_in_month(&self) -> u32 { + match self.month() { + /* Jan */ 1 => 31, + /* Feb */ 2 => if self.is_leap_year() { 29 } else { 28 }, + /* Mar */ 3 => 31, + /* Apr */ 4 => 30, + /* May */ 5 => 31, + /* Jun */ 6 => 30, + /* Jul */ 7 => 31, + /* Aug */ 8 => 31, + /* Sep */ 9 => 30, + /* Oct */ 10 => 31, + /* Nov */ 11 => 30, + /* Dec */ 12 => 31, + _ => unreachable!() + } + } +} + +impl<'a, 'b> std::ops::Add<&'b NaiveDate> for &'a NaiveDate { + type Output = NaiveDate; + + fn add(self, other: &'b NaiveDate) -> NaiveDate { + assert_eq!(*other, NaiveDate(0, 0, 1)); + self.succ() + } +} + +impl std::iter::Step for NaiveDate { + fn steps_between(_: &Self, _: &Self) -> Option<usize> { + unimplemented!() + } + + fn replace_one(&mut self) -> Self { + mem::replace(self, NaiveDate(0, 0, 1)) + } + + fn replace_zero(&mut self) -> Self { + mem::replace(self, NaiveDate(0, 0, 0)) + } + + fn add_one(&self) -> Self { + self.succ() + } + + fn sub_one(&self) -> Self { + unimplemented!() + } + + fn add_usize(&self, _: usize) -> Option<Self> { + unimplemented!() + } +} + +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum Weekday { + Mon, + Tue, + Wed, + Thu, + Fri, + Sat, + Sun, +} + +impl Weekday { + pub fn num_days_from_monday(&self) -> u32 { + use Weekday::*; + match *self { + Mon => 0, + Tue => 1, + Wed => 2, + Thu => 3, + Fri => 4, + Sat => 5, + Sun => 6, + } + } + + pub fn num_days_from_sunday(&self) -> u32 { + use Weekday::*; + match *self { + Sun => 0, + Mon => 1, + Tue => 2, + Wed => 3, + Thu => 4, + Fri => 5, + Sat => 6, + } + } +} + +/// GroupBy implementation. +struct GroupBy<It: Iterator, F> { + it: std::iter::Peekable<It>, + f: F, +} + +impl<It, F> Clone for GroupBy<It, F> +where + It: Iterator + Clone, + It::Item: Clone, + F: Clone, +{ + fn clone(&self) -> Self { + GroupBy { + it: self.it.clone(), + f: self.f.clone(), + } + } +} + +impl<'a, G, It: 'a, F: 'a> Iterator for GroupBy<It, F> +where It: Iterator + Clone, + It::Item: Clone, + F: Clone + FnMut(&It::Item) -> G, + G: Eq + Clone +{ + type Item = (G, InGroup<std::iter::Peekable<It>, F, G>); + + fn next(&mut self) -> Option<Self::Item> { + self.it.peek().map(&mut self.f).map(|key| { + let start = self.it.clone(); + while let Some(k) = self.it.peek().map(&mut self.f) { + if key != k { + break; + } + self.it.next(); + } + + (key.clone(), InGroup { + it: start, + f: self.f.clone(), + g: key + }) + }) + } +} + +#[derive(Copy, Clone)] +struct InGroup<It, F, G> { + it: It, + f: F, + g: G +} + +impl<It: Iterator, F: FnMut(&It::Item) -> G, G: Eq> Iterator for InGroup<It, F, G> { + type Item = It::Item; + + fn next(&mut self) -> Option<It::Item> { + self.it.next().and_then(|x| { + if (self.f)(&x) == self.g { Some(x) } else { None } + }) + } +} + +trait IteratorExt: Iterator + Sized { + fn group_by<G, F>(self, f: F) -> GroupBy<Self, F> + where F: Clone + FnMut(&Self::Item) -> G, + G: Eq + { + GroupBy { it: self.peekable(), f } + } + + fn join(mut self, sep: &str) -> String + where Self::Item: std::fmt::Display { + let mut s = String::new(); + if let Some(e) = self.next() { + write!(s, "{}", e); + for e in self { + s.push_str(sep); + write!(s, "{}", e); + } + } + s + } + + // HACK(eddyb) Only needed because `impl Trait` can't be + // used with trait methods: `.foo()` becomes `.__(foo)`. + fn __<F, R>(self, f: F) -> R + where F: FnOnce(Self) -> R { + f(self) + } +} + +impl<It> IteratorExt for It where It: Iterator {} + +/// +/// Generates an iterator that yields exactly n spaces. +/// +fn spaces(n: usize) -> std::iter::Take<std::iter::Repeat<char>> { + std::iter::repeat(' ').take(n) +} + +fn test_spaces() { + assert_eq!(spaces(0).collect::<String>(), ""); + assert_eq!(spaces(10).collect::<String>(), " ") +} + +/// +/// Returns an iterator of dates in a given year. +/// +fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone { + InGroup { + it: NaiveDate::from_ymd(year, 1, 1).., + f: |d: &NaiveDate| d.year(), + g: year + } +} + +fn test_dates_in_year() { + { + let mut dates = dates_in_year(2013); + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 1))); + + // Check increment + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 2))); + + // Check monthly rollover + for _ in 3..31 { + assert!(dates.next() != None); + } + + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 31))); + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 2, 1))); + } + + { + // Check length of year + let mut dates = dates_in_year(2013); + for _ in 0..365 { + assert!(dates.next() != None); + } + assert_eq!(dates.next(), None); + } + + { + // Check length of leap year + let mut dates = dates_in_year(1984); + for _ in 0..366 { + assert!(dates.next() != None); + } + assert_eq!(dates.next(), None); + } +} + +/// +/// Convenience trait for verifying that a given type iterates over +/// `NaiveDate`s. +/// +trait DateIterator: Iterator<Item=NaiveDate> + Clone {} +impl<It> DateIterator for It where It: Iterator<Item=NaiveDate> + Clone {} + +fn test_group_by() { + let input = [ + [1, 1], + [1, 1], + [1, 2], + [2, 2], + [2, 3], + [2, 3], + [3, 3] + ]; + + let by_x = input.iter().cloned().group_by(|a| a[0]); + let expected_1: &[&[[i32; 2]]] = &[ + &[[1, 1], [1, 1], [1, 2]], + &[[2, 2], [2, 3], [2, 3]], + &[[3, 3]] + ]; + for ((_, a), b) in by_x.zip(expected_1.iter().cloned()) { + assert_eq!(&a.collect::<Vec<_>>()[..], b); + } + + let by_y = input.iter().cloned().group_by(|a| a[1]); + let expected_2: &[&[[i32; 2]]] = &[ + &[[1, 1], [1, 1]], + &[[1, 2], [2, 2]], + &[[2, 3], [2, 3], [3, 3]] + ]; + for ((_, a), b) in by_y.zip(expected_2.iter().cloned()) { + assert_eq!(&a.collect::<Vec<_>>()[..], b); + } +} + +/// +/// Groups an iterator of dates by month. +/// +fn by_month(it: impl Iterator<Item=NaiveDate> + Clone) + -> impl Iterator<Item=(u32, impl Iterator<Item=NaiveDate> + Clone)> + Clone +{ + it.group_by(|d| d.month()) +} + +fn test_by_month() { + let mut months = dates_in_year(2013).__(by_month); + for (month, (_, mut date)) in (1..13).zip(&mut months) { + assert_eq!(date.nth(0).unwrap(), NaiveDate::from_ymd(2013, month, 1)); + } + assert!(months.next().is_none()); +} + +/// +/// Groups an iterator of dates by week. +/// +fn by_week(it: impl DateIterator) + -> impl Iterator<Item=(u32, impl DateIterator)> + Clone +{ + // We go forward one day because `isoweekdate` considers the week to start on a Monday. + it.group_by(|d| d.succ().isoweekdate().1) +} + +fn test_isoweekdate() { + fn weeks_uniq(year: i32) -> Vec<((i32, u32), u32)> { + let mut weeks = dates_in_year(year).map(|d| d.isoweekdate()) + .map(|(y,w,_)| (y,w)); + let mut result = vec![]; + let mut accum = (weeks.next().unwrap(), 1); + for yw in weeks { + if accum.0 == yw { + accum.1 += 1; + } else { + result.push(accum); + accum = (yw, 1); + } + } + result.push(accum); + result + } + + let wu_1984 = weeks_uniq(1984); + assert_eq!(&wu_1984[..2], &[((1983, 52), 1), ((1984, 1), 7)]); + assert_eq!(&wu_1984[wu_1984.len()-2..], &[((1984, 52), 7), ((1985, 1), 1)]); + + let wu_2013 = weeks_uniq(2013); + assert_eq!(&wu_2013[..2], &[((2013, 1), 6), ((2013, 2), 7)]); + assert_eq!(&wu_2013[wu_2013.len()-2..], &[((2013, 52), 7), ((2014, 1), 2)]); + + let wu_2015 = weeks_uniq(2015); + assert_eq!(&wu_2015[..2], &[((2015, 1), 4), ((2015, 2), 7)]); + assert_eq!(&wu_2015[wu_2015.len()-2..], &[((2015, 52), 7), ((2015, 53), 4)]); +} + +fn test_by_week() { + let mut weeks = dates_in_year(2013).__(by_week); + assert_eq!( + &*weeks.next().unwrap().1.collect::<Vec<_>>(), + &[ + NaiveDate::from_ymd(2013, 1, 1), + NaiveDate::from_ymd(2013, 1, 2), + NaiveDate::from_ymd(2013, 1, 3), + NaiveDate::from_ymd(2013, 1, 4), + NaiveDate::from_ymd(2013, 1, 5), + ] + ); + assert_eq!( + &*weeks.next().unwrap().1.collect::<Vec<_>>(), + &[ + NaiveDate::from_ymd(2013, 1, 6), + NaiveDate::from_ymd(2013, 1, 7), + NaiveDate::from_ymd(2013, 1, 8), + NaiveDate::from_ymd(2013, 1, 9), + NaiveDate::from_ymd(2013, 1, 10), + NaiveDate::from_ymd(2013, 1, 11), + NaiveDate::from_ymd(2013, 1, 12), + ] + ); + assert_eq!(weeks.next().unwrap().1.nth(0).unwrap(), NaiveDate::from_ymd(2013, 1, 13)); +} + +/// The number of columns per day in the formatted output. +const COLS_PER_DAY: u32 = 3; + +/// The number of columns per week in the formatted output. +const COLS_PER_WEEK: u32 = 7 * COLS_PER_DAY; + +/// +/// Formats an iterator of weeks into an iterator of strings. +/// +fn format_weeks(it: impl Iterator<Item = impl DateIterator>) -> impl Iterator<Item=String> { + it.map(|week| { + let mut buf = String::with_capacity((COLS_PER_DAY * COLS_PER_WEEK + 2) as usize); + + // Format each day into its own cell and append to target string. + let mut last_day = 0; + let mut first = true; + for d in week { + last_day = d.weekday().num_days_from_sunday(); + + // Insert enough filler to align the first day with its respective day-of-week. + if first { + buf.extend(spaces((COLS_PER_DAY * last_day) as usize)); + first = false; + } + + write!(buf, " {:>2}", d.day()); + } + + // Insert more filler at the end to fill up the remainder of the week, + // if its a short week (e.g. at the end of the month). + buf.extend(spaces((COLS_PER_DAY * (6 - last_day)) as usize)); + buf + }) +} + +fn test_format_weeks() { + let jan_2013 = dates_in_year(2013) + .__(by_month).next() // pick January 2013 for testing purposes + // NOTE: This `map` is because `next` returns an `Option<_>`. + .map(|(_, month)| + month.__(by_week) + .map(|(_, weeks)| weeks) + .__(format_weeks) + .join("\n")); + + assert_eq!( + jan_2013.as_ref().map(|s| &**s), + Some(" 1 2 3 4 5\n\ + \x20 6 7 8 9 10 11 12\n\ + \x2013 14 15 16 17 18 19\n\ + \x2020 21 22 23 24 25 26\n\ + \x2027 28 29 30 31 ") + ); +} + +/// +/// Formats the name of a month, centered on COLS_PER_WEEK. +/// +fn month_title(month: u32) -> String { + const MONTH_NAMES: &'static [&'static str] = &[ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + ]; + assert_eq!(MONTH_NAMES.len(), 12); + + // Determine how many spaces before and after the month name + // we need to center it over the formatted weeks in the month. + let name = MONTH_NAMES[(month - 1) as usize]; + assert!(name.len() < COLS_PER_WEEK as usize); + let before = (COLS_PER_WEEK as usize - name.len()) / 2; + let after = COLS_PER_WEEK as usize - name.len() - before; + + // NOTE: Being slightly more verbose to avoid extra allocations. + let mut result = String::with_capacity(COLS_PER_WEEK as usize); + result.extend(spaces(before)); + result.push_str(name); + result.extend(spaces(after)); + result +} + +fn test_month_title() { + assert_eq!(month_title(1).len(), COLS_PER_WEEK as usize); +} + +/// +/// Formats a month. +/// +fn format_month(it: impl DateIterator) -> impl Iterator<Item=String> { + let mut month_days = it.peekable(); + let title = month_title(month_days.peek().unwrap().month()); + + Some(title).into_iter() + .chain(month_days.__(by_week) + .map(|(_, week)| week) + .__(format_weeks)) +} + +fn test_format_month() { + let month_fmt = dates_in_year(2013) + .__(by_month).next() // Pick January as a test case + .map(|(_, days)| days.into_iter() + .__(format_month) + .join("\n")); + + assert_eq!( + month_fmt.as_ref().map(|s| &**s), + Some(" January \n\ + \x20 1 2 3 4 5\n\ + \x20 6 7 8 9 10 11 12\n\ + \x2013 14 15 16 17 18 19\n\ + \x2020 21 22 23 24 25 26\n\ + \x2027 28 29 30 31 ") + ); +} + + +/// +/// Formats an iterator of months. +/// +fn format_months(it: impl Iterator<Item = impl DateIterator>) + -> impl Iterator<Item=impl Iterator<Item=String>> +{ + it.map(format_month) +} + +/// +/// Takes an iterator of iterators of strings; the sub-iterators are consumed +/// in lock-step, with their elements joined together. +/// +trait PasteBlocks: Iterator + Sized +where Self::Item: Iterator<Item=String> { + fn paste_blocks(self, sep_width: usize) -> PasteBlocksIter<Self::Item> { + PasteBlocksIter { + iters: self.collect(), + cache: vec![], + col_widths: None, + sep_width: sep_width, + } + } +} + +impl<It> PasteBlocks for It where It: Iterator, It::Item: Iterator<Item=String> {} + +struct PasteBlocksIter<StrIt> +where StrIt: Iterator<Item=String> { + iters: Vec<StrIt>, + cache: Vec<Option<String>>, + col_widths: Option<Vec<usize>>, + sep_width: usize, +} + +impl<StrIt> Iterator for PasteBlocksIter<StrIt> +where StrIt: Iterator<Item=String> { + type Item = String; + + fn next(&mut self) -> Option<String> { + self.cache.clear(); + + // `cache` is now the next line from each iterator. + self.cache.extend(self.iters.iter_mut().map(|it| it.next())); + + // If every line in `cache` is `None`, we have nothing further to do. + if self.cache.iter().all(|e| e.is_none()) { return None } + + // Get the column widths if we haven't already. + let col_widths = match self.col_widths { + Some(ref v) => &**v, + None => { + self.col_widths = Some(self.cache.iter() + .map(|ms| ms.as_ref().map(|s| s.len()).unwrap_or(0)) + .collect()); + &**self.col_widths.as_ref().unwrap() + } + }; + + // Fill in any `None`s with spaces. + let mut parts = col_widths.iter().cloned().zip(self.cache.iter_mut()) + .map(|(w,ms)| ms.take().unwrap_or_else(|| spaces(w).collect())); + + // Join them all together. + let first = parts.next().unwrap_or(String::new()); + let sep_width = self.sep_width; + Some(parts.fold(first, |mut accum, next| { + accum.extend(spaces(sep_width)); + accum.push_str(&next); + accum + })) + } +} + +fn test_paste_blocks() { + let row = dates_in_year(2013) + .__(by_month).map(|(_, days)| days) + .take(3) + .__(format_months) + .paste_blocks(1) + .join("\n"); + assert_eq!( + &*row, + " January February March \n\ + \x20 1 2 3 4 5 1 2 1 2\n\ + \x20 6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9\n\ + \x2013 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16\n\ + \x2020 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23\n\ + \x2027 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30\n\ + \x20 31 " + ); +} + +/// +/// Produces an iterator that yields `n` elements at a time. +/// +trait Chunks: Iterator + Sized { + fn chunks(self, n: usize) -> ChunksIter<Self> { + assert!(n > 0); + ChunksIter { + it: self, + n: n, + } + } +} + +impl<It> Chunks for It where It: Iterator {} + +struct ChunksIter<It> +where It: Iterator { + it: It, + n: usize, +} + +// NOTE: `chunks` in Rust is more-or-less impossible without overhead of some kind. +// Aliasing rules mean you need to add dynamic borrow checking, and the design of +// `Iterator` means that you need to have the iterator's state kept in an allocation +// that is jointly owned by the iterator itself and the sub-iterator. +// As such, I've chosen to cop-out and just heap-allocate each chunk. + +impl<It> Iterator for ChunksIter<It> +where It: Iterator { + type Item = Vec<It::Item>; + + fn next(&mut self) -> Option<Vec<It::Item>> { + let first = match self.it.next() { + Some(e) => e, + None => return None + }; + + let mut result = Vec::with_capacity(self.n); + result.push(first); + + Some((&mut self.it).take(self.n-1) + .fold(result, |mut acc, next| { acc.push(next); acc })) + } +} + +fn test_chunks() { + let r = &[1, 2, 3, 4, 5, 6, 7]; + let c = r.iter().cloned().chunks(3).collect::<Vec<_>>(); + assert_eq!(&*c, &[vec![1, 2, 3], vec![4, 5, 6], vec![7]]); +} + +/// +/// Formats a year. +/// +fn format_year(year: i32, months_per_row: usize) -> String { + const COL_SPACING: usize = 1; + + // Start by generating all dates for the given year. + dates_in_year(year) + + // Group them by month and throw away month number. + .__(by_month).map(|(_, days)| days) + + // Group the months into horizontal rows. + .chunks(months_per_row) + + // Format each row + .map(|r| r.into_iter() + // By formatting each month + .__(format_months) + + // Horizontally pasting each respective month's lines together. + .paste_blocks(COL_SPACING) + .join("\n") + ) + + // Insert a blank line between each row + .join("\n\n") +} + +fn test_format_year() { + const MONTHS_PER_ROW: usize = 3; + + macro_rules! assert_eq_cal { + ($lhs:expr, $rhs:expr) => { + if $lhs != $rhs { + println!("got:\n```\n{}\n```\n", $lhs.replace(" ", ".")); + println!("expected:\n```\n{}\n```", $rhs.replace(" ", ".")); + panic!("calendars didn't match!"); + } + } + } + + assert_eq_cal!(&format_year(1984, MONTHS_PER_ROW), "\ +\x20 January February March \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 1 2 3\n\ +\x20 8 9 10 11 12 13 14 5 6 7 8 9 10 11 4 5 6 7 8 9 10\n\ +\x2015 16 17 18 19 20 21 12 13 14 15 16 17 18 11 12 13 14 15 16 17\n\ +\x2022 23 24 25 26 27 28 19 20 21 22 23 24 25 18 19 20 21 22 23 24\n\ +\x2029 30 31 26 27 28 29 25 26 27 28 29 30 31\n\ +\n\ +\x20 April May June \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 5 1 2\n\ +\x20 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9\n\ +\x2015 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16\n\ +\x2022 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23\n\ +\x2029 30 27 28 29 30 31 24 25 26 27 28 29 30\n\ +\n\ +\x20 July August September \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 1\n\ +\x20 8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8\n\ +\x2015 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15\n\ +\x2022 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22\n\ +\x2029 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29\n\ +\x20 30 \n\ +\n\ +\x20 October November December \n\ +\x20 1 2 3 4 5 6 1 2 3 1\n\ +\x20 7 8 9 10 11 12 13 4 5 6 7 8 9 10 2 3 4 5 6 7 8\n\ +\x2014 15 16 17 18 19 20 11 12 13 14 15 16 17 9 10 11 12 13 14 15\n\ +\x2021 22 23 24 25 26 27 18 19 20 21 22 23 24 16 17 18 19 20 21 22\n\ +\x2028 29 30 31 25 26 27 28 29 30 23 24 25 26 27 28 29\n\ +\x20 30 31 "); + + assert_eq_cal!(&format_year(2015, MONTHS_PER_ROW), "\ +\x20 January February March \n\ +\x20 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7\n\ +\x20 4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14\n\ +\x2011 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21\n\ +\x2018 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28\n\ +\x2025 26 27 28 29 30 31 29 30 31 \n\ +\n\ +\x20 April May June \n\ +\x20 1 2 3 4 1 2 1 2 3 4 5 6\n\ +\x20 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13\n\ +\x2012 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20\n\ +\x2019 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27\n\ +\x2026 27 28 29 30 24 25 26 27 28 29 30 28 29 30 \n\ +\x20 31 \n\ +\n\ +\x20 July August September \n\ +\x20 1 2 3 4 1 1 2 3 4 5\n\ +\x20 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12\n\ +\x2012 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19\n\ +\x2019 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26\n\ +\x2026 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30 \n\ +\x20 30 31 \n\ +\n\ +\x20 October November December \n\ +\x20 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5\n\ +\x20 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12\n\ +\x2011 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19\n\ +\x2018 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26\n\ +\x2025 26 27 28 29 30 31 29 30 27 28 29 30 31 "); +} + +fn main() { + // Run tests. + test_spaces(); + test_dates_in_year(); + test_group_by(); + test_by_month(); + test_isoweekdate(); + test_by_week(); + test_format_weeks(); + test_month_title(); + test_format_month(); + test_paste_blocks(); + test_chunks(); + test_format_year(); +} diff --git a/src/test/ui/run-pass/impl-trait/example-st.rs b/src/test/ui/run-pass/impl-trait/example-st.rs new file mode 100644 index 00000000000..a06bde7f532 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/example-st.rs @@ -0,0 +1,38 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct State; +type Error = (); + +trait Bind<F> { + type Output; + fn bind(self, f: F) -> Self::Output; +} + +fn bind<T, U, A, B, F>(mut a: A, mut f: F) + -> impl FnMut(&mut State) -> Result<U, Error> +where F: FnMut(T) -> B, + A: FnMut(&mut State) -> Result<T, Error>, + B: FnMut(&mut State) -> Result<U, Error> +{ + move |state | { + let r = a(state)?; + f(r)(state) + } +} + +fn atom<T>(x: T) -> impl FnMut(&mut State) -> Result<T, Error> { + let mut x = Some(x); + move |_| x.take().map_or(Err(()), Ok) +} + +fn main() { + assert_eq!(bind(atom(5), |x| atom(x > 4))(&mut State), Ok(true)); +} diff --git a/src/test/ui/run-pass/impl-trait/existential-minimal.rs b/src/test/ui/run-pass/impl-trait/existential-minimal.rs new file mode 100644 index 00000000000..4e9d786dda0 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/existential-minimal.rs @@ -0,0 +1,13 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} + +fn foo() -> impl std::fmt::Debug { "cake" } diff --git a/src/test/ui/run-pass/impl-trait/issue-42479.rs b/src/test/ui/run-pass/impl-trait/issue-42479.rs new file mode 100644 index 00000000000..df7a6c13092 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/issue-42479.rs @@ -0,0 +1,25 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iter::once; + +struct Foo { + x: i32, +} + +impl Foo { + fn inside(&self) -> impl Iterator<Item = &i32> { + once(&self.x) + } +} + +fn main() { + println!("hi"); +} diff --git a/src/test/ui/run-pass/impl-trait/issue-49376.rs b/src/test/ui/run-pass/impl-trait/issue-49376.rs new file mode 100644 index 00000000000..b687b485fce --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/issue-49376.rs @@ -0,0 +1,29 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests for nested self-reference which caused a stack overflow. + +use std::fmt::Debug; +use std::ops::*; + +fn gen() -> impl PartialOrd + PartialEq + Debug { } + +struct Bar {} +trait Foo<T = Self> {} +impl Foo for Bar {} + +fn foo() -> impl Foo { + Bar {} +} + +fn test_impl_ops() -> impl Add + Sub + Mul + Div { 1 } +fn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign { 1 } + +fn main() {} diff --git a/src/test/ui/run-pass/impl-trait/lifetimes.rs b/src/test/ui/run-pass/impl-trait/lifetimes.rs new file mode 100644 index 00000000000..d126d795d90 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/lifetimes.rs @@ -0,0 +1,126 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(warnings)] + +use std::fmt::Debug; + +fn any_lifetime<'a>() -> &'a u32 { &5 } + +fn static_lifetime() -> &'static u32 { &5 } + +fn any_lifetime_as_static_impl_trait() -> impl Debug { + any_lifetime() +} + +fn lifetimes_as_static_impl_trait() -> impl Debug { + static_lifetime() +} + +fn no_params_or_lifetimes_is_static() -> impl Debug + 'static { + lifetimes_as_static_impl_trait() +} + +fn static_input_type_is_static<T: Debug + 'static>(x: T) -> impl Debug + 'static { x } + +fn type_outlives_reference_lifetime<'a, T: Debug>(x: &'a T) -> impl Debug + 'a { x } +fn type_outlives_reference_lifetime_elided<T: Debug>(x: &T) -> impl Debug + '_ { x } + +trait SingleRegionTrait<'a> {} +impl<'a> SingleRegionTrait<'a> for u32 {} +impl<'a> SingleRegionTrait<'a> for &'a u32 {} +struct SingleRegionStruct<'a>(&'a u32); + +fn simple_type_hrtb<'b>() -> impl for<'a> SingleRegionTrait<'a> { 5 } +// FIXME(cramertj) add test after #45992 lands to ensure lint is triggered +fn elision_single_region_trait(x: &u32) -> impl SingleRegionTrait { x } +fn elision_single_region_struct(x: SingleRegionStruct) -> impl Into<SingleRegionStruct> { x } + +fn closure_hrtb() -> impl for<'a> Fn(&'a u32) { |_| () } +fn closure_hr_elided() -> impl Fn(&u32) { |_| () } +fn closure_hr_elided_return() -> impl Fn(&u32) -> &u32 { |x| x } +fn closure_pass_through_elided_return(x: impl Fn(&u32) -> &u32) -> impl Fn(&u32) -> &u32 { x } +fn closure_pass_through_reference_elided(x: &impl Fn(&u32) -> &u32) -> &impl Fn(&u32) -> &u32 { x } + +fn nested_lifetime<'a>(input: &'a str) + -> impl Iterator<Item = impl Iterator<Item = i32> + 'a> + 'a +{ + input.lines().map(|line| { + line.split_whitespace().map(|cell| cell.parse().unwrap()) + }) +} + +fn pass_through_elision(x: &u32) -> impl Into<&u32> { x } +fn pass_through_elision_with_fn_ptr(x: &fn(&u32) -> &u32) -> impl Into<&fn(&u32) -> &u32> { x } + +fn pass_through_elision_with_fn_path<T: Fn(&u32) -> &u32>( + x: &T +) -> &impl Fn(&u32) -> &u32 { x } + +fn foo(x: &impl Debug) -> &impl Debug { x } +fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x } +fn foo_explicit_arg<T: Debug>(x: &T) -> &impl Debug { x } + +fn mixed_lifetimes<'a>() -> impl for<'b> Fn(&'b &'a u32) { |_| () } +fn mixed_as_static() -> impl Fn(&'static &'static u32) { mixed_lifetimes() } + +trait MultiRegionTrait<'a, 'b>: Debug {} + +#[derive(Debug)] +struct MultiRegionStruct<'a, 'b>(&'a u32, &'b u32); +impl<'a, 'b> MultiRegionTrait<'a, 'b> for MultiRegionStruct<'a, 'b> {} + +#[derive(Debug)] +struct NoRegionStruct; +impl<'a, 'b> MultiRegionTrait<'a, 'b> for NoRegionStruct {} + +fn finds_least_region<'a: 'b, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound<'a: 'b, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound_even_without_least_region<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + NoRegionStruct +} + +/* FIXME: `impl Trait<'a> + 'b` should live as long as 'b, even if 'b outlives 'a +fn outlives_bounds_even_with_contained_regions<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug + 'b +{ + finds_explicit_bound_even_without_least_region(x, y) +} +*/ + +fn unnamed_lifetimes_arent_contained_in_impl_trait_and_will_unify<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug +{ + fn deref<'lt>(x: &'lt u32) -> impl Debug { *x } + + if true { deref(x) } else { deref(y) } +} + +fn can_add_region_bound_to_static_type<'a, 'b>(_: &'a u32) -> impl Debug + 'a { 5 } + +struct MyVec(Vec<Vec<u8>>); + +impl<'unnecessary_lifetime> MyVec { + fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator<Item = &'s u8> { + self.0.iter().flat_map(|inner_vec| inner_vec.iter()) + } +} + +fn main() {} diff --git a/src/test/ui/run-pass/impl-trait/nesting.rs b/src/test/ui/run-pass/impl-trait/nesting.rs new file mode 100644 index 00000000000..73e6c1c0d1d --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/nesting.rs @@ -0,0 +1,22 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo<T>(t: T) -> impl Into<[T; { const FOO: usize = 1; FOO }]> { + [t] +} + +fn bar() -> impl Into<[u8; { const FOO: usize = 1; FOO }]> { + [99] +} + +fn main() { + println!("{:?}", foo(42).into()); + println!("{:?}", bar().into()); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_hrtb_anon.rs b/src/test/ui/run-pass/impl-trait/universal_hrtb_anon.rs new file mode 100644 index 00000000000..9fc74757da0 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_hrtb_anon.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn hrtb(f: impl Fn(&u32) -> u32) -> u32 { + f(&22) + f(&44) +} + +fn main() { + let sum = hrtb(|x| x * 2); + assert_eq!(sum, 22*2 + 44*2); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_hrtb_named.rs b/src/test/ui/run-pass/impl-trait/universal_hrtb_named.rs new file mode 100644 index 00000000000..3aefc79ebf7 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_hrtb_named.rs @@ -0,0 +1,18 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn hrtb(f: impl for<'a> Fn(&'a u32) -> &'a u32) -> u32 { + f(&22) + f(&44) +} + +fn main() { + let sum = hrtb(|x| x); + assert_eq!(sum, 22 + 44); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_in_adt_in_parameters.rs b/src/test/ui/run-pass/impl-trait/universal_in_adt_in_parameters.rs new file mode 100644 index 00000000000..57452a2e475 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_in_adt_in_parameters.rs @@ -0,0 +1,30 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt::Display; + +fn check_display_eq(iter: &Vec<impl Display>) { + let mut collected = String::new(); + for it in iter { + let disp = format!("{} ", it); + collected.push_str(&disp); + } + assert_eq!("0 3 27 823 4891 1 0", collected.trim()); +} + +fn main() { + let i32_list_vec = vec![0i32, 3, 27, 823, 4891, 1, 0]; + let u32_list_vec = vec![0u32, 3, 27, 823, 4891, 1, 0]; + let str_list_vec = vec!["0", "3", "27", "823", "4891", "1", "0"]; + + check_display_eq(&i32_list_vec); + check_display_eq(&u32_list_vec); + check_display_eq(&str_list_vec); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/ui/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs new file mode 100644 index 00000000000..fea946f1258 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs @@ -0,0 +1,38 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt::Display; + +fn check_display_eq(iter: impl IntoIterator<Item = impl Display>) { + let mut collected = String::new(); + for it in iter { + let disp = format!("{} ", it); + collected.push_str(&disp); + } + assert_eq!("0 3 27 823 4891 1 0", collected.trim()); +} + +fn main() { + let i32_list = [0i32, 3, 27, 823, 4891, 1, 0]; + let i32_list_vec = vec![0i32, 3, 27, 823, 4891, 1, 0]; + let u32_list = [0u32, 3, 27, 823, 4891, 1, 0]; + let u32_list_vec = vec![0u32, 3, 27, 823, 4891, 1, 0]; + let u16_list = [0u16, 3, 27, 823, 4891, 1, 0]; + let str_list = ["0", "3", "27", "823", "4891", "1", "0"]; + let str_list_vec = vec!["0", "3", "27", "823", "4891", "1", "0"]; + + check_display_eq(&i32_list); + check_display_eq(i32_list_vec); + check_display_eq(&u32_list); + check_display_eq(u32_list_vec); + check_display_eq(&u16_list); + check_display_eq(&str_list); + check_display_eq(str_list_vec); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/ui/run-pass/impl-trait/universal_in_trait_defn_parameters.rs new file mode 100644 index 00000000000..d3611e02e02 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_in_trait_defn_parameters.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt::Debug; + +trait InTraitDefnParameters { + fn in_parameters(_: impl Debug) -> String; +} + +impl InTraitDefnParameters for () { + fn in_parameters(v: impl Debug) -> String { + format!("() + {:?}", v) + } +} + +fn main() { + let s = <() as InTraitDefnParameters>::in_parameters(22); + assert_eq!(s, "() + 22"); +} diff --git a/src/test/ui/run-pass/impl-trait/universal_multiple_bounds.rs b/src/test/ui/run-pass/impl-trait/universal_multiple_bounds.rs new file mode 100644 index 00000000000..594207feb09 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/universal_multiple_bounds.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt::Display; + +fn foo(f: impl Display + Clone) -> String { + let g = f.clone(); + format!("{} + {}", f, g) +} + +fn main() { + let sum = foo(format!("22")); + assert_eq!(sum, r"22 + 22"); +} diff --git a/src/test/ui/run-pass/impl-trait/xcrate.rs b/src/test/ui/run-pass/impl-trait/xcrate.rs new file mode 100644 index 00000000000..35ae185b3e1 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/xcrate.rs @@ -0,0 +1,19 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:xcrate.rs + +extern crate xcrate; + +fn main() { +// NOTE line below commeted out due to issue #45994 +// assert_eq!(xcrate::fourway_add(1)(2)(3)(4), 10); + xcrate::return_closure_accessing_internal_fn()(); +} diff --git a/src/test/ui/run-pass/impl-trait/xcrate_simple.rs b/src/test/ui/run-pass/impl-trait/xcrate_simple.rs new file mode 100644 index 00000000000..8d4086cc880 --- /dev/null +++ b/src/test/ui/run-pass/impl-trait/xcrate_simple.rs @@ -0,0 +1,17 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:xcrate.rs + +extern crate xcrate; + +fn main() { + xcrate::return_internal_fn()(); +} diff --git a/src/test/ui/run-pass/nll/issue-47153-generic-const.rs b/src/test/ui/run-pass/nll/issue-47153-generic-const.rs new file mode 100644 index 00000000000..9708ca1c142 --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-47153-generic-const.rs @@ -0,0 +1,27 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #47153: constants in a generic context (such as +// a trait) used to ICE. + +#![feature(nll)] +#![allow(warnings)] + +trait Foo { + const B: bool = true; +} + +struct Bar<T> { x: T } + +impl<T> Bar<T> { + const B: bool = true; +} + +fn main() { } diff --git a/src/test/ui/run-pass/nll/issue-47589.rs b/src/test/ui/run-pass/nll/issue-47589.rs new file mode 100644 index 00000000000..393c18efad0 --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-47589.rs @@ -0,0 +1,33 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +pub struct DescriptorSet<'a> { + pub slots: Vec<AttachInfo<'a, Resources>> +} + +pub trait ResourcesTrait<'r>: Sized { + type DescriptorSet: 'r; +} + +pub struct Resources; + +impl<'a> ResourcesTrait<'a> for Resources { + type DescriptorSet = DescriptorSet<'a>; +} + +pub enum AttachInfo<'a, R: ResourcesTrait<'a>> { + NextDescriptorSet(Box<R::DescriptorSet>) +} + +fn main() { + let _x = DescriptorSet {slots: Vec::new()}; +} diff --git a/src/test/ui/run-pass/nll/issue-48623-closure.rs b/src/test/ui/run-pass/nll/issue-48623-closure.rs new file mode 100644 index 00000000000..08ff54a428e --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-48623-closure.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +fn reborrow_from_closure(r: &mut ()) -> &mut () { + let d = WithDrop; + (move || { d; &mut *r })() +} + +fn main() {} diff --git a/src/test/ui/run-pass/nll/issue-48623-generator.rs b/src/test/ui/run-pass/nll/issue-48623-generator.rs new file mode 100644 index 00000000000..524837c4ba9 --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-48623-generator.rs @@ -0,0 +1,25 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] +#![feature(generators, generator_trait)] + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +fn reborrow_from_generator(r: &mut ()) { + let d = WithDrop; + move || { d; yield; &mut *r }; +} + +fn main() {} diff --git a/src/test/ui/run-pass/nll/issue-50343.rs b/src/test/ui/run-pass/nll/issue-50343.rs new file mode 100644 index 00000000000..f01d99c68cc --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-50343.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] +#![deny(unused_mut)] + +fn main() { + vec![42].iter().map(|_| ()).count(); + vec![(42, 22)].iter().map(|(_x, _y)| ()).count(); +} diff --git a/src/test/ui/run-pass/nll/issue-50461-used-mut-from-moves.rs b/src/test/ui/run-pass/nll/issue-50461-used-mut-from-moves.rs new file mode 100644 index 00000000000..d5cf122bf3b --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-50461-used-mut-from-moves.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] +#![deny(unused_mut)] + +struct Foo { + pub value: i32 +} + +fn use_foo_mut(mut foo: Foo) { + foo = foo; + println!("{}", foo.value); +} + +fn main() { + use_foo_mut(Foo { value: 413 }); +} diff --git a/src/test/ui/run-pass/nll/issue-53123-raw-pointer-cast.rs b/src/test/ui/run-pass/nll/issue-53123-raw-pointer-cast.rs new file mode 100644 index 00000000000..7959f1737b9 --- /dev/null +++ b/src/test/ui/run-pass/nll/issue-53123-raw-pointer-cast.rs @@ -0,0 +1,35 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] +#![allow(unused_variables)] + +pub trait TryTransform { + fn try_transform<F>(self, f: F) + where + Self: Sized, + F: FnOnce(Self); +} + +impl<'a, T> TryTransform for &'a mut T { + fn try_transform<F>(self, f: F) + where + // The bug was that `Self: Sized` caused the lifetime of `this` to "extend" for all + // of 'a instead of only lasting as long as the binding is used (for just that line). + Self: Sized, + F: FnOnce(Self), + { + let this: *mut T = self as *mut T; + f(self); + } +} + +fn main() { +} diff --git a/src/test/ui/run-pass/nll/mutating_references.rs b/src/test/ui/run-pass/nll/mutating_references.rs new file mode 100644 index 00000000000..96b7362e4d9 --- /dev/null +++ b/src/test/ui/run-pass/nll/mutating_references.rs @@ -0,0 +1,34 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +struct List<T> { + value: T, + next: Option<Box<List<T>>>, +} + +fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +fn main() { + let mut list = List { value: 1, next: None }; + let vec = to_refs(&mut list); + assert_eq!(vec![&mut 1], vec); +} diff --git a/src/test/ui/run-pass/nll/process_or_insert_default.rs b/src/test/ui/run-pass/nll/process_or_insert_default.rs new file mode 100644 index 00000000000..a3a484402cc --- /dev/null +++ b/src/test/ui/run-pass/nll/process_or_insert_default.rs @@ -0,0 +1,37 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +use std::collections::HashMap; + +fn process_or_insert_default(map: &mut HashMap<usize, String>, key: usize) { + match map.get_mut(&key) { + Some(value) => { + process(value); + } + None => { + map.insert(key, "".to_string()); + } + } +} + +fn process(x: &str) { + assert_eq!(x, "Hello, world"); +} + +fn main() { + let map = &mut HashMap::new(); + map.insert(22, format!("Hello, world")); + map.insert(44, format!("Goodbye, world")); + process_or_insert_default(map, 22); + process_or_insert_default(map, 66); + assert_eq!(map[&66], ""); +} diff --git a/src/test/ui/run-pass/nll/rc-loop.rs b/src/test/ui/run-pass/nll/rc-loop.rs new file mode 100644 index 00000000000..2114dbebe93 --- /dev/null +++ b/src/test/ui/run-pass/nll/rc-loop.rs @@ -0,0 +1,39 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// A test for something that NLL enables. It sometimes happens that +// the `while let` pattern makes some borrows from a variable (in this +// case, `x`) that you need in order to compute the next value for +// `x`. The lexical checker makes this very painful. The NLL checker +// does not. + +#![feature(nll)] + +use std::rc::Rc; + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Base(usize), + Next(Rc<Foo>), +} + +fn find_base(mut x: Rc<Foo>) -> Rc<Foo> { + while let Foo::Next(n) = &*x { + x = n.clone(); + } + x +} + +fn main() { + let chain = Rc::new(Foo::Next(Rc::new(Foo::Base(44)))); + let base = find_base(chain); + assert_eq!(&*base, &Foo::Base(44)); +} + diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod.rs b/src/test/ui/run-pass/non_modrs_mods/foors_mod.rs new file mode 100644 index 00000000000..7d37c6d9399 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod.rs @@ -0,0 +1,14 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-test: not a test, used by non_modrs_mods.rs + +pub mod inner_modrs_mod; +pub mod inner_foors_mod; diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir b/src/test/ui/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod/compiletest-ignore-dir diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs new file mode 100644 index 00000000000..77cab972352 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod innest; diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs new file mode 100644 index 00000000000..b61667cfd88 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() {} diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..b61667cfd88 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() {} diff --git a/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..77cab972352 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod innest; diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/compiletest-ignore-dir diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs new file mode 100644 index 00000000000..77cab972352 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod innest; diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs new file mode 100644 index 00000000000..b61667cfd88 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() {} diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..b61667cfd88 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() {} diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..77cab972352 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod innest; diff --git a/src/test/ui/run-pass/non_modrs_mods/modrs_mod/mod.rs b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/mod.rs new file mode 100644 index 00000000000..9e3f10f12ed --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/modrs_mod/mod.rs @@ -0,0 +1,12 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod inner_modrs_mod; +pub mod inner_foors_mod; diff --git a/src/test/ui/run-pass/non_modrs_mods/non_modrs_mods.rs b/src/test/ui/run-pass/non_modrs_mods/non_modrs_mods.rs new file mode 100644 index 00000000000..eab8112b855 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/non_modrs_mods.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-pretty issue #37195 +#![feature(non_modrs_mods)] + +pub mod modrs_mod; +pub mod foors_mod; + +#[path = "some_crazy_attr_mod_dir/arbitrary_name.rs"] +pub mod attr_mod; + +pub fn main() { + modrs_mod::inner_modrs_mod::innest::foo(); + modrs_mod::inner_foors_mod::innest::foo(); + foors_mod::inner_modrs_mod::innest::foo(); + foors_mod::inner_foors_mod::innest::foo(); + attr_mod::inner_modrs_mod::innest::foo(); +} diff --git a/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs new file mode 100644 index 00000000000..226e6fda0a4 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod inner_modrs_mod; diff --git a/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/compiletest-ignore-dir diff --git a/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs new file mode 100644 index 00000000000..b61667cfd88 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() {} diff --git a/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs new file mode 100644 index 00000000000..77cab972352 --- /dev/null +++ b/src/test/ui/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs @@ -0,0 +1,11 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod innest; diff --git a/src/test/ui/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs b/src/test/ui/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs new file mode 100644 index 00000000000..731603606e4 --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/abort-link-to-unwinding-crates.rs @@ -0,0 +1,48 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-C panic=abort +// aux-build:exit-success-if-unwind.rs +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-macos + +extern crate exit_success_if_unwind; + +use std::process::Command; +use std::env; + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + exit_success_if_unwind::bar(do_panic); + } + } + + let mut cmd = Command::new(env::args_os().next().unwrap()); + cmd.arg("foo"); + + + // ARMv6 hanges while printing the backtrace, see #41004 + if cfg!(target_arch = "arm") && cfg!(target_env = "gnu") { + cmd.env("RUST_BACKTRACE", "0"); + } + + let s = cmd.status(); + assert!(s.unwrap().code() != Some(0)); +} + +fn do_panic() { + panic!("try to catch me"); +} diff --git a/src/test/ui/run-pass/panic-runtime/abort.rs b/src/test/ui/run-pass/panic-runtime/abort.rs new file mode 100644 index 00000000000..4692ad3ca2f --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/abort.rs @@ -0,0 +1,51 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-C panic=abort +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-macos + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + + let mut cmd = Command::new(env::args_os().next().unwrap()); + cmd.arg("foo"); + + // ARMv6 hanges while printing the backtrace, see #41004 + if cfg!(target_arch = "arm") && cfg!(target_env = "gnu") { + cmd.env("RUST_BACKTRACE", "0"); + } + + let s = cmd.status(); + assert!(s.unwrap().code() != Some(0)); +} diff --git a/src/test/ui/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs b/src/test/ui/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs new file mode 100644 index 00000000000..9e5fc592b1a --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/auxiliary/exit-success-if-unwind.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +pub fn bar(f: fn()) { + let _bomb = Bomb; + f(); +} diff --git a/src/test/ui/run-pass/panic-runtime/link-to-abort.rs b/src/test/ui/run-pass/panic-runtime/link-to-abort.rs new file mode 100644 index 00000000000..9f5407e4526 --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/link-to-abort.rs @@ -0,0 +1,19 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-C panic=abort +// no-prefer-dynamic +// ignore-macos + +#![feature(panic_abort)] + +extern crate panic_abort; + +fn main() {} diff --git a/src/test/ui/run-pass/panic-runtime/link-to-unwind.rs b/src/test/ui/run-pass/panic-runtime/link-to-unwind.rs new file mode 100644 index 00000000000..dec8f738d32 --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/link-to-unwind.rs @@ -0,0 +1,18 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![feature(panic_unwind)] + +extern crate panic_unwind; + +fn main() { +} diff --git a/src/test/ui/run-pass/panic-runtime/lto-abort.rs b/src/test/ui/run-pass/panic-runtime/lto-abort.rs new file mode 100644 index 00000000000..54e02fb6975 --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/lto-abort.rs @@ -0,0 +1,41 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-C lto -C panic=abort +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + let s = Command::new(env::args_os().next().unwrap()).arg("foo").status(); + assert!(s.unwrap().code() != Some(0)); +} diff --git a/src/test/ui/run-pass/panic-runtime/lto-unwind.rs b/src/test/ui/run-pass/panic-runtime/lto-unwind.rs new file mode 100644 index 00000000000..52f10688f14 --- /dev/null +++ b/src/test/ui/run-pass/panic-runtime/lto-unwind.rs @@ -0,0 +1,43 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:-C lto -C panic=unwind +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + println!("hurray you ran me"); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + let s = Command::new(env::args_os().next().unwrap()).arg("foo").output(); + let s = s.unwrap(); + assert!(!s.status.success()); + assert!(String::from_utf8_lossy(&s.stdout).contains("hurray you ran me")); +} diff --git a/src/test/ui/run-pass/specialization/README.md b/src/test/ui/run-pass/specialization/README.md new file mode 100644 index 00000000000..1373a2cf81b --- /dev/null +++ b/src/test/ui/run-pass/specialization/README.md @@ -0,0 +1,37 @@ +Tests that specialization is working correctly: + +- Dispatch + - [On methods](specialization-basics.rs), includes: + - Specialization via adding a trait bound + - Including both remote and local traits + - Specialization via pure structure (e.g. `(T, U)` vs `(T, T)`) + - Specialization via concrete types vs unknown types + - In top level of the trait reference + - Embedded within another type (`Vec<T>` vs `Vec<i32>`) + - [Specialization based on super trait relationships](specialization-super-traits.rs) + - [On assoc fns](specialization-assoc-fns.rs) + - [Ensure that impl order doesn't matter](specialization-out-of-order.rs) + +- Item inheritance + - [Correct default cascading for methods](specialization-default-methods.rs) + - Inheritance works across impls with varying generics + - [With projections](specialization-translate-projections.rs) + - [With projections that involve input types](specialization-translate-projections-with-params.rs) + +- Normalization issues + - [Non-default assoc types can be projected](specialization-projection.rs) + - Including non-specialized cases + - Including specialized cases + - [Specialized Impls can happen on projections](specialization-on-projection.rs) + - [Projections and aliases play well together](specialization-projection-alias.rs) + - [Projections involving specialization allowed in the trait ref for impls, and overlap can still be determined](specialization-overlap-projection.rs) + - Only works for the simple case where the most specialized impl directly + provides a non-`default` associated type + +- Across crates + - [For traits defined in upstream crate](specialization-allowed-cross-crate.rs) + - [Full method dispatch tests, drawing from upstream crate](specialization-cross-crate.rs) + - Including *additional* local specializations + - [Full method dispatch tests, *without* turning on specialization in local crate](specialization-cross-crate-no-gate.rs) + - [Test that defaults cascade correctly from upstream crates](specialization-cross-crate-defaults.rs) + - Including *additional* local use of defaults diff --git a/src/test/ui/run-pass/specialization/assoc-ty-graph-cycle.rs b/src/test/ui/run-pass/specialization/assoc-ty-graph-cycle.rs new file mode 100644 index 00000000000..a65dcf33d85 --- /dev/null +++ b/src/test/ui/run-pass/specialization/assoc-ty-graph-cycle.rs @@ -0,0 +1,33 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure we don't crash with a cycle error during coherence. + +#![feature(specialization)] + +trait Trait<T> { + type Assoc; +} + +impl<T> Trait<T> for Vec<T> { + default type Assoc = (); +} + +impl Trait<u8> for Vec<u8> { + type Assoc = u8; +} + +impl<T> Trait<T> for String { + type Assoc = (); +} + +impl Trait<<Vec<u8> as Trait<u8>>::Assoc> for String {} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/auxiliary/cross_crates_defaults.rs b/src/test/ui/run-pass/specialization/auxiliary/cross_crates_defaults.rs new file mode 100644 index 00000000000..b62d80b589f --- /dev/null +++ b/src/test/ui/run-pass/specialization/auxiliary/cross_crates_defaults.rs @@ -0,0 +1,49 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +#![feature(specialization)] + +// First, test only use of explicit `default` items: + +pub trait Foo { + fn foo(&self) -> bool; +} + +impl<T> Foo for T { + default fn foo(&self) -> bool { false } +} + +impl Foo for i32 {} + +impl Foo for i64 { + fn foo(&self) -> bool { true } +} + +// Next, test mixture of explicit `default` and provided methods: + +pub trait Bar { + fn bar(&self) -> i32 { 0 } +} + +impl<T> Bar for T {} // use the provided method + +impl Bar for i32 { + fn bar(&self) -> i32 { 1 } +} +impl<'a> Bar for &'a str {} + +impl<T> Bar for Vec<T> { + default fn bar(&self) -> i32 { 2 } +} +impl Bar for Vec<i32> {} +impl Bar for Vec<i64> { + fn bar(&self) -> i32 { 3 } +} diff --git a/src/test/ui/run-pass/specialization/auxiliary/go_trait.rs b/src/test/ui/run-pass/specialization/auxiliary/go_trait.rs new file mode 100644 index 00000000000..044bb606b40 --- /dev/null +++ b/src/test/ui/run-pass/specialization/auxiliary/go_trait.rs @@ -0,0 +1,53 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go<G:Go>(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once<G:GoOnce>(this: G, arg: isize) { + this.go_once(arg) +} + +impl<G> GoMut for G + where G : Go +{ + default fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +impl<G> GoOnce for G + where G : GoMut +{ + default fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} diff --git a/src/test/ui/run-pass/specialization/auxiliary/specialization_cross_crate.rs b/src/test/ui/run-pass/specialization/auxiliary/specialization_cross_crate.rs new file mode 100644 index 00000000000..1d235336de8 --- /dev/null +++ b/src/test/ui/run-pass/specialization/auxiliary/specialization_cross_crate.rs @@ -0,0 +1,82 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +pub trait Foo { + fn foo(&self) -> &'static str; +} + +impl<T> Foo for T { + default fn foo(&self) -> &'static str { + "generic" + } +} + +impl<T: Clone> Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone" + } +} + +impl<T, U> Foo for (T, U) where T: Clone, U: Clone { + default fn foo(&self) -> &'static str { + "generic pair" + } +} + +impl<T: Clone> Foo for (T, T) { + default fn foo(&self) -> &'static str { + "generic uniform pair" + } +} + +impl Foo for (u8, u32) { + default fn foo(&self) -> &'static str { + "(u8, u32)" + } +} + +impl Foo for (u8, u8) { + default fn foo(&self) -> &'static str { + "(u8, u8)" + } +} + +impl<T: Clone> Foo for Vec<T> { + default fn foo(&self) -> &'static str { + "generic Vec" + } +} + +impl Foo for Vec<i32> { + fn foo(&self) -> &'static str { + "Vec<i32>" + } +} + +impl Foo for String { + fn foo(&self) -> &'static str { + "String" + } +} + +impl Foo for i32 { + fn foo(&self) -> &'static str { + "i32" + } +} + +pub trait MyMarker {} +impl<T: Clone + MyMarker> Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone + MyMarker" + } +} diff --git a/src/test/ui/run-pass/specialization/cross-crate-defaults.rs b/src/test/ui/run-pass/specialization/cross-crate-defaults.rs new file mode 100644 index 00000000000..132520dcb73 --- /dev/null +++ b/src/test/ui/run-pass/specialization/cross-crate-defaults.rs @@ -0,0 +1,49 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:cross_crates_defaults.rs + +#![feature(specialization)] + +extern crate cross_crates_defaults; + +use cross_crates_defaults::*; + +struct LocalDefault; +struct LocalOverride; + +impl Foo for LocalDefault {} + +impl Foo for LocalOverride { + fn foo(&self) -> bool { true } +} + +fn test_foo() { + assert!(!0i8.foo()); + assert!(!0i32.foo()); + assert!(0i64.foo()); + + assert!(!LocalDefault.foo()); + assert!(LocalOverride.foo()); +} + +fn test_bar() { + assert!(0u8.bar() == 0); + assert!(0i32.bar() == 1); + assert!("hello".bar() == 0); + assert!(vec![()].bar() == 2); + assert!(vec![0i32].bar() == 2); + assert!(vec![0i64].bar() == 3); +} + +fn main() { + test_foo(); + test_bar(); +} diff --git a/src/test/ui/run-pass/specialization/defaultimpl/allowed-cross-crate.rs b/src/test/ui/run-pass/specialization/defaultimpl/allowed-cross-crate.rs new file mode 100644 index 00000000000..6b999f38358 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/allowed-cross-crate.rs @@ -0,0 +1,31 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:go_trait.rs + +#![feature(specialization)] + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } diff --git a/src/test/ui/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs b/src/test/ui/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs new file mode 100644 index 00000000000..dd060f8ef40 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/auxiliary/go_trait.rs @@ -0,0 +1,53 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go<G:Go>(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once<G:GoOnce>(this: G, arg: isize) { + this.go_once(arg) +} + +default impl<G> GoMut for G + where G : Go +{ + fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +default impl<G> GoOnce for G + where G : GoMut +{ + fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} diff --git a/src/test/ui/run-pass/specialization/defaultimpl/out-of-order.rs b/src/test/ui/run-pass/specialization/defaultimpl/out-of-order.rs new file mode 100644 index 00000000000..f77b88e2f85 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/out-of-order.rs @@ -0,0 +1,27 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +default impl<T> Foo for T { + type Out = bool; +} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/defaultimpl/overlap-projection.rs b/src/test/ui/run-pass/specialization/defaultimpl/overlap-projection.rs new file mode 100644 index 00000000000..500cded38c1 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/overlap-projection.rs @@ -0,0 +1,33 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that impls on projected self types can resolve overlap, even when the +// projections involve specialization, so long as the associated type is +// provided by the most specialized impl. + +#![feature(specialization)] + +trait Assoc { + type Output; +} + +default impl<T> Assoc for T { + type Output = bool; +} + +impl Assoc for u8 { type Output = u8; } +impl Assoc for u16 { type Output = u16; } + +trait Foo {} +impl Foo for u32 {} +impl Foo for <u8 as Assoc>::Output {} +impl Foo for <u16 as Assoc>::Output {} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/defaultimpl/projection.rs b/src/test/ui/run-pass/specialization/defaultimpl/projection.rs new file mode 100644 index 00000000000..6a833ba6760 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/projection.rs @@ -0,0 +1,49 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Make sure we *can* project non-defaulted associated types +// cf compile-fail/specialization-default-projection.rs + +// First, do so without any use of specialization + +trait Foo { + type Assoc; +} + +impl<T> Foo for T { + type Assoc = (); +} + +fn generic_foo<T>() -> <T as Foo>::Assoc { + () +} + +// Next, allow for one layer of specialization + +trait Bar { + type Assoc; +} + +default impl<T> Bar for T { + type Assoc = (); +} + +impl<T: Clone> Bar for T { + type Assoc = u8; +} + +fn generic_bar_clone<T: Clone>() -> <T as Bar>::Assoc { + 0u8 +} + +fn main() { +} diff --git a/src/test/ui/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs b/src/test/ui/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs new file mode 100644 index 00000000000..fc731202005 --- /dev/null +++ b/src/test/ui/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs @@ -0,0 +1,42 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests that we can combine a default impl that supplies one method with a +// full impl that supplies the other, and they can invoke one another. + +#![feature(specialization)] + +trait Foo { + fn foo_one(&self) -> &'static str; + fn foo_two(&self) -> &'static str; + fn foo_three(&self) -> &'static str; +} + +struct MyStruct; + +default impl<T> Foo for T { + fn foo_one(&self) -> &'static str { + self.foo_three() + } +} + +impl Foo for MyStruct { + fn foo_two(&self) -> &'static str { + self.foo_one() + } + + fn foo_three(&self) -> &'static str { + "generic" + } +} + +fn main() { + assert!(MyStruct.foo_two() == "generic"); +} diff --git a/src/test/ui/run-pass/specialization/specialization-allowed-cross-crate.rs b/src/test/ui/run-pass/specialization/specialization-allowed-cross-crate.rs new file mode 100644 index 00000000000..6b999f38358 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-allowed-cross-crate.rs @@ -0,0 +1,31 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:go_trait.rs + +#![feature(specialization)] + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } diff --git a/src/test/ui/run-pass/specialization/specialization-assoc-fns.rs b/src/test/ui/run-pass/specialization/specialization-assoc-fns.rs new file mode 100644 index 00000000000..577f217862d --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-assoc-fns.rs @@ -0,0 +1,37 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that non-method associated functions can be specialized + +#![feature(specialization)] + +trait Foo { + fn mk() -> Self; +} + +impl<T: Default> Foo for T { + default fn mk() -> T { + T::default() + } +} + +impl Foo for Vec<u8> { + fn mk() -> Vec<u8> { + vec![0] + } +} + +fn main() { + let v1: Vec<i32> = Foo::mk(); + let v2: Vec<u8> = Foo::mk(); + + assert!(v1.len() == 0); + assert!(v2.len() == 1); +} diff --git a/src/test/ui/run-pass/specialization/specialization-basics.rs b/src/test/ui/run-pass/specialization/specialization-basics.rs new file mode 100644 index 00000000000..b11495e9edf --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-basics.rs @@ -0,0 +1,106 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Tests a variety of basic specialization scenarios and method +// dispatch for them. + +trait Foo { + fn foo(&self) -> &'static str; +} + +impl<T> Foo for T { + default fn foo(&self) -> &'static str { + "generic" + } +} + +impl<T: Clone> Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone" + } +} + +impl<T, U> Foo for (T, U) where T: Clone, U: Clone { + default fn foo(&self) -> &'static str { + "generic pair" + } +} + +impl<T: Clone> Foo for (T, T) { + default fn foo(&self) -> &'static str { + "generic uniform pair" + } +} + +impl Foo for (u8, u32) { + default fn foo(&self) -> &'static str { + "(u8, u32)" + } +} + +impl Foo for (u8, u8) { + default fn foo(&self) -> &'static str { + "(u8, u8)" + } +} + +impl<T: Clone> Foo for Vec<T> { + default fn foo(&self) -> &'static str { + "generic Vec" + } +} + +impl Foo for Vec<i32> { + fn foo(&self) -> &'static str { + "Vec<i32>" + } +} + +impl Foo for String { + fn foo(&self) -> &'static str { + "String" + } +} + +impl Foo for i32 { + fn foo(&self) -> &'static str { + "i32" + } +} + +struct NotClone; + +trait MyMarker {} +impl<T: Clone + MyMarker> Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone + MyMarker" + } +} + +#[derive(Clone)] +struct MarkedAndClone; +impl MyMarker for MarkedAndClone {} + +fn main() { + assert!(NotClone.foo() == "generic"); + assert!(0u8.foo() == "generic Clone"); + assert!(vec![NotClone].foo() == "generic"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec<i32>"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); + assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); +} diff --git a/src/test/ui/run-pass/specialization/specialization-cross-crate-no-gate.rs b/src/test/ui/run-pass/specialization/specialization-cross-crate-no-gate.rs new file mode 100644 index 00000000000..b9548539e16 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-cross-crate-no-gate.rs @@ -0,0 +1,29 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that specialization works even if only the upstream crate enables it + +// aux-build:specialization_cross_crate.rs + +extern crate specialization_cross_crate; + +use specialization_cross_crate::*; + +fn main() { + assert!(0u8.foo() == "generic Clone"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec<i32>"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); +} diff --git a/src/test/ui/run-pass/specialization/specialization-cross-crate.rs b/src/test/ui/run-pass/specialization/specialization-cross-crate.rs new file mode 100644 index 00000000000..7593ac4fb1d --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-cross-crate.rs @@ -0,0 +1,58 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:specialization_cross_crate.rs + +#![feature(specialization)] + +extern crate specialization_cross_crate; + +use specialization_cross_crate::*; + +struct NotClone; + +#[derive(Clone)] +struct MarkedAndClone; +impl MyMarker for MarkedAndClone {} + +struct MyType<T>(T); +impl<T> Foo for MyType<T> { + default fn foo(&self) -> &'static str { + "generic MyType" + } +} + +impl Foo for MyType<u8> { + fn foo(&self) -> &'static str { + "MyType<u8>" + } +} + +struct MyOtherType; +impl Foo for MyOtherType {} + +fn main() { + assert!(NotClone.foo() == "generic"); + assert!(0u8.foo() == "generic Clone"); + assert!(vec![NotClone].foo() == "generic"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec<i32>"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); + assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); + + assert!(MyType(()).foo() == "generic MyType"); + assert!(MyType(0u8).foo() == "MyType<u8>"); + assert!(MyOtherType.foo() == "generic"); +} diff --git a/src/test/ui/run-pass/specialization/specialization-default-methods.rs b/src/test/ui/run-pass/specialization/specialization-default-methods.rs new file mode 100644 index 00000000000..9cfc6aabbb4 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-default-methods.rs @@ -0,0 +1,94 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Test that default methods are cascaded correctly + +// First, test only use of explicit `default` items: + +trait Foo { + fn foo(&self) -> bool; +} + +// Specialization tree for Foo: +// +// T +// / \ +// i32 i64 + +impl<T> Foo for T { + default fn foo(&self) -> bool { false } +} + +impl Foo for i32 {} + +impl Foo for i64 { + fn foo(&self) -> bool { true } +} + +fn test_foo() { + assert!(!0i8.foo()); + assert!(!0i32.foo()); + assert!(0i64.foo()); +} + +// Next, test mixture of explicit `default` and provided methods: + +trait Bar { + fn bar(&self) -> i32 { 0 } +} + +// Specialization tree for Bar. +// Uses of $ designate that method is provided +// +// $Bar (the trait) +// | +// T +// /|\ +// / | \ +// / | \ +// / | \ +// / | \ +// / | \ +// $i32 &str $Vec<T> +// /\ +// / \ +// Vec<i32> $Vec<i64> + +// use the provided method +impl<T> Bar for T {} + +impl Bar for i32 { + fn bar(&self) -> i32 { 1 } +} +impl<'a> Bar for &'a str {} + +impl<T> Bar for Vec<T> { + default fn bar(&self) -> i32 { 2 } +} +impl Bar for Vec<i32> {} +impl Bar for Vec<i64> { + fn bar(&self) -> i32 { 3 } +} + +fn test_bar() { + assert!(0u8.bar() == 0); + assert!(0i32.bar() == 1); + assert!("hello".bar() == 0); + assert!(vec![()].bar() == 2); + assert!(vec![0i32].bar() == 2); + assert!(vec![0i64].bar() == 3); +} + +fn main() { + test_foo(); + test_bar(); +} diff --git a/src/test/ui/run-pass/specialization/specialization-on-projection.rs b/src/test/ui/run-pass/specialization/specialization-on-projection.rs new file mode 100644 index 00000000000..acf78def1b9 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-on-projection.rs @@ -0,0 +1,31 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Ensure that specialization works for impls defined directly on a projection + +trait Foo<T> {} + +trait Assoc { + type Item; +} + +impl<T: Assoc> Foo<T::Item> for T {} + +struct Struct; + +impl Assoc for Struct { + type Item = u8; +} + +impl Foo<u8> for Struct {} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/specialization-out-of-order.rs b/src/test/ui/run-pass/specialization/specialization-out-of-order.rs new file mode 100644 index 00000000000..2d293f494a3 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-out-of-order.rs @@ -0,0 +1,27 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +impl<T> Foo for T { + default type Out = bool; +} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/specialization-overlap-projection.rs b/src/test/ui/run-pass/specialization/specialization-overlap-projection.rs new file mode 100644 index 00000000000..20046ee66b0 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-overlap-projection.rs @@ -0,0 +1,33 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that impls on projected self types can resolve overlap, even when the +// projections involve specialization, so long as the associated type is +// provided by the most specialized impl. + +#![feature(specialization)] + +trait Assoc { + type Output; +} + +impl<T> Assoc for T { + default type Output = bool; +} + +impl Assoc for u8 { type Output = u8; } +impl Assoc for u16 { type Output = u16; } + +trait Foo {} +impl Foo for u32 {} +impl Foo for <u8 as Assoc>::Output {} +impl Foo for <u16 as Assoc>::Output {} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/specialization-projection-alias.rs b/src/test/ui/run-pass/specialization/specialization-projection-alias.rs new file mode 100644 index 00000000000..7fce1cca582 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-projection-alias.rs @@ -0,0 +1,32 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Regression test for ICE when combining specialized associated types and type +// aliases + +trait Id_ { + type Out; +} + +type Id<T> = <T as Id_>::Out; + +impl<T> Id_ for T { + default type Out = T; +} + +fn test_proection() { + let x: Id<bool> = panic!(); +} + +fn main() { + +} diff --git a/src/test/ui/run-pass/specialization/specialization-projection.rs b/src/test/ui/run-pass/specialization/specialization-projection.rs new file mode 100644 index 00000000000..4e0bdec297f --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-projection.rs @@ -0,0 +1,49 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Make sure we *can* project non-defaulted associated types +// cf compile-fail/specialization-default-projection.rs + +// First, do so without any use of specialization + +trait Foo { + type Assoc; +} + +impl<T> Foo for T { + type Assoc = (); +} + +fn generic_foo<T>() -> <T as Foo>::Assoc { + () +} + +// Next, allow for one layer of specialization + +trait Bar { + type Assoc; +} + +impl<T> Bar for T { + default type Assoc = (); +} + +impl<T: Clone> Bar for T { + type Assoc = u8; +} + +fn generic_bar_clone<T: Clone>() -> <T as Bar>::Assoc { + 0u8 +} + +fn main() { +} diff --git a/src/test/ui/run-pass/specialization/specialization-super-traits.rs b/src/test/ui/run-pass/specialization/specialization-super-traits.rs new file mode 100644 index 00000000000..a9b3bfca53d --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-super-traits.rs @@ -0,0 +1,25 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Test that you can specialize via an explicit trait hierarchy + +// FIXME: this doesn't work yet... + +trait Parent {} +trait Child: Parent {} + +trait Foo {} + +impl<T: Parent> Foo for T {} +impl<T: Child> Foo for T {} + +fn main() {} diff --git a/src/test/ui/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs b/src/test/ui/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs new file mode 100644 index 00000000000..9702f632413 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-translate-projections-with-lifetimes.rs @@ -0,0 +1,41 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +trait Iterator { + fn next(&self); +} + +trait WithAssoc { + type Item; +} + +impl<'a> WithAssoc for &'a () { + type Item = &'a u32; +} + +struct Cloned<I>(I); + +impl<'a, I, T: 'a> Iterator for Cloned<I> + where I: WithAssoc<Item=&'a T>, T: Clone +{ + fn next(&self) {} +} + +impl<'a, I, T: 'a> Iterator for Cloned<I> + where I: WithAssoc<Item=&'a T>, T: Copy +{ + +} + +fn main() { + Cloned(&()).next(); +} diff --git a/src/test/ui/run-pass/specialization/specialization-translate-projections-with-params.rs b/src/test/ui/run-pass/specialization/specialization-translate-projections-with-params.rs new file mode 100644 index 00000000000..647d5523c37 --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-translate-projections-with-params.rs @@ -0,0 +1,40 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that provided items are inherited properly even when impls vary in +// type parameters *and* rely on projections, and the type parameters are input +// types on the trait. + +#![feature(specialization)] + +trait Trait<T> { + fn convert(&self) -> T; +} +trait WithAssoc { + type Item; + fn as_item(&self) -> &Self::Item; +} + +impl<T, U> Trait<U> for T where T: WithAssoc<Item=U>, U: Clone { + fn convert(&self) -> U { + self.as_item().clone() + } +} + +impl WithAssoc for u8 { + type Item = u8; + fn as_item(&self) -> &u8 { self } +} + +impl Trait<u8> for u8 {} + +fn main() { + assert!(3u8.convert() == 3u8); +} diff --git a/src/test/ui/run-pass/specialization/specialization-translate-projections.rs b/src/test/ui/run-pass/specialization/specialization-translate-projections.rs new file mode 100644 index 00000000000..11e1d997fdd --- /dev/null +++ b/src/test/ui/run-pass/specialization/specialization-translate-projections.rs @@ -0,0 +1,41 @@ +// 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that provided items are inherited properly even when impls vary in +// type parameters *and* rely on projections. + +#![feature(specialization)] + +use std::convert::Into; + +trait Trait { + fn to_u8(&self) -> u8; +} +trait WithAssoc { + type Item; + fn to_item(&self) -> Self::Item; +} + +impl<T, U> Trait for T where T: WithAssoc<Item=U>, U: Into<u8> { + fn to_u8(&self) -> u8 { + self.to_item().into() + } +} + +impl WithAssoc for u8 { + type Item = u8; + fn to_item(&self) -> u8 { *self } +} + +impl Trait for u8 {} + +fn main() { + assert!(3u8.to_u8() == 3u8); +} diff --git a/src/test/ui/run-pass/thinlto/all-crates.rs b/src/test/ui/run-pass/thinlto/all-crates.rs new file mode 100644 index 00000000000..8d68202d711 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/all-crates.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Clto=thin +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} diff --git a/src/test/ui/run-pass/thinlto/auxiliary/dylib.rs b/src/test/ui/run-pass/thinlto/auxiliary/dylib.rs new file mode 100644 index 00000000000..cdb3f49cae8 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/auxiliary/dylib.rs @@ -0,0 +1,16 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z thinlto -C codegen-units=8 + +#[inline] +pub fn foo(b: u8) { + b.to_string(); +} diff --git a/src/test/ui/run-pass/thinlto/auxiliary/msvc-imp-present.rs b/src/test/ui/run-pass/thinlto/auxiliary/msvc-imp-present.rs new file mode 100644 index 00000000000..eff7802a245 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/auxiliary/msvc-imp-present.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +// compile-flags: -Z thinlto -C codegen-units=8 -C prefer-dynamic + +#![crate_type = "rlib"] +#![crate_type = "dylib"] + +pub static A: u32 = 43; + +pub mod a { + pub static A: u32 = 43; +} diff --git a/src/test/ui/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs b/src/test/ui/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs new file mode 100644 index 00000000000..ccbb0e7a718 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/auxiliary/thin-lto-inlines-aux.rs @@ -0,0 +1,17 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn bar() -> u32 { + 3 +} diff --git a/src/test/ui/run-pass/thinlto/dylib-works.rs b/src/test/ui/run-pass/thinlto/dylib-works.rs new file mode 100644 index 00000000000..06df40f6142 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/dylib-works.rs @@ -0,0 +1,17 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:dylib.rs + +extern crate dylib; + +fn main() { + dylib::foo(1); +} diff --git a/src/test/ui/run-pass/thinlto/msvc-imp-present.rs b/src/test/ui/run-pass/thinlto/msvc-imp-present.rs new file mode 100644 index 00000000000..95cff2a2862 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/msvc-imp-present.rs @@ -0,0 +1,30 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:msvc-imp-present.rs +// compile-flags: -Z thinlto -C codegen-units=8 +// no-prefer-dynamic + +// On MSVC we have a "hack" where we emit symbols that look like `_imp_$name` +// for all exported statics. This is done because we apply `dllimport` to all +// imported constants and this allows everything to actually link correctly. +// +// The ThinLTO passes aggressively remove symbols if they can, and this test +// asserts that the ThinLTO passes don't remove these compiler-generated +// `_imp_*` symbols. The external library that we link in here is compiled with +// ThinLTO and multiple codegen units and has a few exported constants. Note +// that we also namely compile the library as both a dylib and an rlib, but we +// link the rlib to ensure that we assert those generated symbols exist. + +extern crate msvc_imp_present as bar; + +fn main() { + println!("{}", bar::A); +} diff --git a/src/test/ui/run-pass/thinlto/thin-lto-inlines.rs b/src/test/ui/run-pass/thinlto/thin-lto-inlines.rs new file mode 100644 index 00000000000..41ca983af51 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/thin-lto-inlines.rs @@ -0,0 +1,38 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z thinlto -C codegen-units=8 -O +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +pub fn foo() -> u32 { + bar::bar() +} + +mod bar { + pub fn bar() -> u32 { + 3 + } +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} diff --git a/src/test/ui/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/ui/run-pass/thinlto/thin-lto-inlines2.rs new file mode 100644 index 00000000000..3c0e904662a --- /dev/null +++ b/src/test/ui/run-pass/thinlto/thin-lto-inlines2.rs @@ -0,0 +1,37 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C codegen-units=8 -O -C lto=thin +// aux-build:thin-lto-inlines-aux.rs +// no-prefer-dynamic +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +extern crate thin_lto_inlines_aux as bar; + +pub fn foo() -> u32 { + bar::bar() +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} + diff --git a/src/test/ui/run-pass/thinlto/weak-works.rs b/src/test/ui/run-pass/thinlto/weak-works.rs new file mode 100644 index 00000000000..0a1b7307a46 --- /dev/null +++ b/src/test/ui/run-pass/thinlto/weak-works.rs @@ -0,0 +1,36 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C codegen-units=8 -Z thinlto +// ignore-windows + +#![feature(linkage)] + +pub mod foo { + #[linkage = "weak"] + #[no_mangle] + pub extern "C" fn FOO() -> i32 { + 0 + } +} + +mod bar { + extern "C" { + fn FOO() -> i32; + } + + pub fn bar() -> i32 { + unsafe { FOO() } + } +} + +fn main() { + bar::bar(); +} diff --git a/src/test/ui/run-pass/uniform-paths/basic-nested.rs b/src/test/ui/run-pass/uniform-paths/basic-nested.rs new file mode 100644 index 00000000000..954736dfd90 --- /dev/null +++ b/src/test/ui/run-pass/uniform-paths/basic-nested.rs @@ -0,0 +1,59 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(decl_macro, uniform_paths)] + +// This test is similar to `basic.rs`, but nested in modules. + +mod foo { + // Test that ambiguity errors are not emitted between `self::test` and + // `::test`, assuming the latter (crate) is not in `extern_prelude`. + mod test { + pub struct Foo(pub ()); + } + pub use test::Foo; + + // Test that qualified paths can refer to both the external crate and local item. + mod std { + pub struct io(pub ()); + } + pub use ::std::io as std_io; + pub use self::std::io as local_io; +} + +// Test that we can refer to the external crate unqualified +// (when there isn't a local item with the same name). +use std::io; + +mod bar { + // Also test the unqualified external crate import in a nested module, + // to show that the above import doesn't resolve through a local `std` + // item, e.g. the automatically injected `extern crate std;`, which in + // the Rust 2018 should no longer be visible through `crate::std`. + pub use std::io; + + // Also test that items named `std` in other namespaces don't + // cause ambiguity errors for the import from `std` above. + pub fn std() {} + pub macro std() {} +} + + +fn main() { + foo::Foo(()); + foo::std_io::stdout(); + foo::local_io(()); + io::stdout(); + bar::io::stdout(); + bar::std(); + bar::std!(); +} diff --git a/src/test/ui/run-pass/uniform-paths/basic.rs b/src/test/ui/run-pass/uniform-paths/basic.rs new file mode 100644 index 00000000000..59a0404e4c3 --- /dev/null +++ b/src/test/ui/run-pass/uniform-paths/basic.rs @@ -0,0 +1,33 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +// Test that ambiguity errors are not emitted between `self::test` and +// `::test`, assuming the latter (crate) is not in `extern_prelude`. +mod test { + pub struct Foo(pub ()); +} +use test::Foo; + +// Test that qualified paths can refer to both the external crate and local item. +mod std { + pub struct io(pub ()); +} +use ::std::io as std_io; +use self::std::io as local_io; + +fn main() { + Foo(()); + std_io::stdout(); + local_io(()); +} diff --git a/src/test/ui/run-pass/uniform-paths/macros-nested.rs b/src/test/ui/run-pass/uniform-paths/macros-nested.rs new file mode 100644 index 00000000000..9cf05cd9560 --- /dev/null +++ b/src/test/ui/run-pass/uniform-paths/macros-nested.rs @@ -0,0 +1,62 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +// This test is similar to `macros.rs`, but nested in modules. + +mod foo { + // Test that ambiguity errors are not emitted between `self::test` and + // `::test`, assuming the latter (crate) is not in `extern_prelude`. + macro_rules! m1 { + () => { + mod test { + pub struct Foo(pub ()); + } + } + } + pub use test::Foo; + m1!(); + + // Test that qualified paths can refer to both the external crate and local item. + macro_rules! m2 { + () => { + mod std { + pub struct io(pub ()); + } + } + } + pub use ::std::io as std_io; + pub use self::std::io as local_io; + m2!(); +} + +// Test that we can refer to the external crate unqualified +// (when there isn't a local item with the same name). +use std::io; + +mod bar { + // Also test the unqualified external crate import in a nested module, + // to show that the above import doesn't resolve through a local `std` + // item, e.g. the automatically injected `extern crate std;`, which in + // the Rust 2018 should no longer be visible through `crate::std`. + pub use std::io; +} + + +fn main() { + foo::Foo(()); + foo::std_io::stdout(); + foo::local_io(()); + io::stdout(); + bar::io::stdout(); +} diff --git a/src/test/ui/run-pass/uniform-paths/macros.rs b/src/test/ui/run-pass/uniform-paths/macros.rs new file mode 100644 index 00000000000..ad74f5d0876 --- /dev/null +++ b/src/test/ui/run-pass/uniform-paths/macros.rs @@ -0,0 +1,45 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +// This test is similar to `basic.rs`, but with macros defining local items. + +// Test that ambiguity errors are not emitted between `self::test` and +// `::test`, assuming the latter (crate) is not in `extern_prelude`. +macro_rules! m1 { + () => { + mod test { + pub struct Foo(pub ()); + } + } +} +use test::Foo; +m1!(); + +// Test that qualified paths can refer to both the external crate and local item. +macro_rules! m2 { + () => { + mod std { + pub struct io(pub ()); + } + } +} +use ::std::io as std_io; +use self::std::io as local_io; +m2!(); + +fn main() { + Foo(()); + std_io::stdout(); + local_io(()); +} diff --git a/src/test/ui/run-pass/uniform-paths/same-crate.rs b/src/test/ui/run-pass/uniform-paths/same-crate.rs new file mode 100644 index 00000000000..a3eefa7134c --- /dev/null +++ b/src/test/ui/run-pass/uniform-paths/same-crate.rs @@ -0,0 +1,109 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +pub const A: usize = 0; + +pub mod foo { + pub const B: usize = 1; + + pub mod bar { + pub const C: usize = 2; + + pub enum E { + V1(usize), + V2(String), + } + + pub fn test() -> String { + format!("{} {} {}", crate::A, crate::foo::B, C) + } + + pub fn test_use() -> String { + use crate::A; + use crate::foo::B; + + format!("{} {} {}", A, B, C) + } + + pub fn test_enum() -> String { + use E::*; + match E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } + } + } + + pub fn test() -> String { + format!("{} {} {}", crate::A, B, bar::C) + } + + pub fn test_use() -> String { + use crate::A; + use bar::C; + + format!("{} {} {}", A, B, C) + } + + pub fn test_enum() -> String { + use bar::E::*; + match bar::E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } + } +} + +pub fn test() -> String { + format!("{} {} {}", A, foo::B, foo::bar::C) +} + +pub fn test_use() -> String { + use foo::B; + use foo::bar::C; + + format!("{} {} {}", A, B, C) +} + +pub fn test_enum() -> String { + use foo::bar::E::*; + match foo::bar::E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } +} + +fn main() { + let output = [ + test(), + foo::test(), + foo::bar::test(), + test_use(), + foo::test_use(), + foo::bar::test_use(), + test_enum(), + foo::test_enum(), + foo::bar::test_enum(), + ].join("\n"); + assert_eq!(output, "\ +0 1 2 +0 1 2 +0 1 2 +0 1 2 +0 1 2 +0 1 2 +V1: 10 +V1: 10 +V1: 10"); +} diff --git a/src/test/ui/run-pass/union/auxiliary/union.rs b/src/test/ui/run-pass/union/auxiliary/union.rs new file mode 100644 index 00000000000..2c4945622ab --- /dev/null +++ b/src/test/ui/run-pass/union/auxiliary/union.rs @@ -0,0 +1,14 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub union U { + pub a: u8, + pub b: u16, +} diff --git a/src/test/ui/run-pass/union/union-align.rs b/src/test/ui/run-pass/union/union-align.rs new file mode 100644 index 00000000000..54e4e12d24f --- /dev/null +++ b/src/test/ui/run-pass/union/union-align.rs @@ -0,0 +1,70 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(untagged_unions)] + +use std::mem::{size_of, size_of_val, align_of, align_of_val}; + +#[repr(align(16))] +pub union U16 { + a: u8, + b: u32 +} + +fn main() { + assert_eq!(align_of::<U16>(), 16); + assert_eq!(size_of::<U16>(), 16); + let u = U16 { a: 10 }; + unsafe { + assert_eq!(align_of_val(&u.a), 1); + assert_eq!(size_of_val(&u.a), 1); + assert_eq!(u.a, 10); + } + + let u = U16 { b: 11 }; + unsafe { + assert_eq!(align_of_val(&u.b), 4); + assert_eq!(size_of_val(&u.b), 4); + assert_eq!(u.b, 11); + } + + hybrid::check_hybrid(); +} + +mod hybrid { + use std::mem::{size_of, align_of}; + + #[repr(align(16))] + struct S1 { + a: u16, + b: u8, + } + + #[repr(align(32))] + union U { + s: S1, + c: u16, + } + + #[repr(align(64))] + struct S2 { + d: u8, + u: U, + } + + pub fn check_hybrid() { + assert_eq!(align_of::<S1>(), 16); + assert_eq!(size_of::<S1>(), 16); + assert_eq!(align_of::<U>(), 32); + assert_eq!(size_of::<U>(), 32); + assert_eq!(align_of::<S2>(), 64); + assert_eq!(size_of::<S2>(), 64); + } +} diff --git a/src/test/ui/run-pass/union/union-backcomp.rs b/src/test/ui/run-pass/union/union-backcomp.rs new file mode 100644 index 00000000000..b706a81850c --- /dev/null +++ b/src/test/ui/run-pass/union/union-backcomp.rs @@ -0,0 +1,31 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! union { + () => (struct S;) +} + +union!(); + +fn union() {} + +fn main() { + union(); + + let union = 10; + + union; + + union as u8; + + union U { + a: u8, + } +} diff --git a/src/test/ui/run-pass/union/union-basic.rs b/src/test/ui/run-pass/union/union-basic.rs new file mode 100644 index 00000000000..079f6a6b641 --- /dev/null +++ b/src/test/ui/run-pass/union/union-basic.rs @@ -0,0 +1,66 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:union.rs + +extern crate union; +use std::mem::{size_of, align_of, zeroed}; + +union U { + a: u8, + b: u16 +} + +fn local() { + assert_eq!(size_of::<U>(), 2); + assert_eq!(align_of::<U>(), 2); + + let u = U { a: 10 }; + unsafe { + assert_eq!(u.a, 10); + let U { a } = u; + assert_eq!(a, 10); + } + + let mut w = U { b: 0 }; + unsafe { + assert_eq!(w.a, 0); + assert_eq!(w.b, 0); + w.a = 1; + assert_eq!(w.a, 1); + assert_eq!(w.b.to_le(), 1); + } +} + +fn xcrate() { + assert_eq!(size_of::<union::U>(), 2); + assert_eq!(align_of::<union::U>(), 2); + + let u = union::U { a: 10 }; + unsafe { + assert_eq!(u.a, 10); + let union::U { a } = u; + assert_eq!(a, 10); + } + + let mut w = union::U { b: 0 }; + unsafe { + assert_eq!(w.a, 0); + assert_eq!(w.b, 0); + w.a = 1; + assert_eq!(w.a, 1); + assert_eq!(w.b.to_le(), 1); + } +} + +fn main() { + local(); + xcrate(); +} diff --git a/src/test/ui/run-pass/union/union-c-interop.rs b/src/test/ui/run-pass/union/union-c-interop.rs new file mode 100644 index 00000000000..dd16bf2e4a3 --- /dev/null +++ b/src/test/ui/run-pass/union/union-c-interop.rs @@ -0,0 +1,44 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Clone, Copy)] +#[repr(C)] +struct LARGE_INTEGER_U { + LowPart: u32, + HighPart: u32, +} + +#[derive(Clone, Copy)] +#[repr(C)] +union LARGE_INTEGER { + __unnamed__: LARGE_INTEGER_U, + u: LARGE_INTEGER_U, + QuadPart: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER; +} + +fn main() { + unsafe { + let mut li = LARGE_INTEGER { QuadPart: 0 }; + let li_c = increment_all_parts(li); + li.__unnamed__.LowPart += 1; + li.__unnamed__.HighPart += 1; + li.u.LowPart += 1; + li.u.HighPart += 1; + li.QuadPart += 1; + assert_eq!(li.QuadPart, li_c.QuadPart); + } +} diff --git a/src/test/ui/run-pass/union/union-const-codegen.rs b/src/test/ui/run-pass/union/union-const-codegen.rs new file mode 100644 index 00000000000..77270364bb5 --- /dev/null +++ b/src/test/ui/run-pass/union/union-const-codegen.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +union U { + a: u64, + b: u64, +} + +const C: U = U { b: 10 }; + +fn main() { + unsafe { + let a = C.a; + let b = C.b; + assert_eq!(a, 10); + assert_eq!(b, 10); + } +} diff --git a/src/test/ui/run-pass/union/union-const-eval-field.rs b/src/test/ui/run-pass/union/union-const-eval-field.rs new file mode 100644 index 00000000000..a380b01dcc1 --- /dev/null +++ b/src/test/ui/run-pass/union/union-const-eval-field.rs @@ -0,0 +1,53 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_fn)] + +type Field1 = (i32, u32); +type Field2 = f32; +type Field3 = i64; + +union DummyUnion { + field1: Field1, + field2: Field2, + field3: Field3, +} + +const FLOAT1_AS_I32: i32 = 1065353216; +const UNION: DummyUnion = DummyUnion { field1: (FLOAT1_AS_I32, 0) }; + +const fn read_field1() -> Field1 { + const FIELD1: Field1 = unsafe { UNION.field1 }; + FIELD1 +} + +const fn read_field2() -> Field2 { + const FIELD2: Field2 = unsafe { UNION.field2 }; + FIELD2 +} + +const fn read_field3() -> Field3 { + const FIELD3: Field3 = unsafe { UNION.field3 }; + FIELD3 +} + +fn main() { + let foo = FLOAT1_AS_I32; + assert_eq!(read_field1().0, foo); + assert_eq!(read_field1().0, FLOAT1_AS_I32); + + let foo = 1.0; + assert_eq!(read_field2(), foo); + assert_eq!(read_field2(), 1.0); + + assert_eq!(read_field3(), unsafe { UNION.field3 }); + let foo = unsafe { UNION.field3 }; + assert_eq!(read_field3(), foo); +} diff --git a/src/test/ui/run-pass/union/union-derive.rs b/src/test/ui/run-pass/union/union-derive.rs new file mode 100644 index 00000000000..8ff6f17394f --- /dev/null +++ b/src/test/ui/run-pass/union/union-derive.rs @@ -0,0 +1,47 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Some traits can be derived for unions. + +#![feature(untagged_unions)] + +#[derive( + Copy, + Clone, + Eq, +)] +union U { + a: u8, + b: u16, +} + +impl PartialEq for U { fn eq(&self, rhs: &Self) -> bool { true } } + +#[derive( + Clone, + Copy, + Eq +)] +union W<T> { + a: T, +} + +impl<T> PartialEq for W<T> { fn eq(&self, rhs: &Self) -> bool { true } } + +fn main() { + let u = U { b: 0 }; + let u1 = u; + let u2 = u.clone(); + assert!(u1 == u2); + + let w = W { a: 0 }; + let w1 = w.clone(); + assert!(w == w1); +} diff --git a/src/test/ui/run-pass/union/union-drop-assign.rs b/src/test/ui/run-pass/union/union-drop-assign.rs new file mode 100644 index 00000000000..0da68e43f32 --- /dev/null +++ b/src/test/ui/run-pass/union/union-drop-assign.rs @@ -0,0 +1,44 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Drop works for union itself. + +#![feature(untagged_unions)] + +struct S; + +union U { + a: S +} + +impl Drop for S { + fn drop(&mut self) { + unsafe { CHECK += 10; } + } +} + +impl Drop for U { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +static mut CHECK: u8 = 0; + +fn main() { + unsafe { + let mut u = U { a: S }; + assert_eq!(CHECK, 0); + u = U { a: S }; + assert_eq!(CHECK, 1); // union itself is assigned, union is dropped, field is not dropped + u.a = S; + assert_eq!(CHECK, 11); // union field is assigned, field is dropped + } +} diff --git a/src/test/ui/run-pass/union/union-drop.rs b/src/test/ui/run-pass/union/union-drop.rs new file mode 100644 index 00000000000..2ca68dc3b6e --- /dev/null +++ b/src/test/ui/run-pass/union/union-drop.rs @@ -0,0 +1,65 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Drop works for union itself. + +#![feature(untagged_unions)] + +struct S; + +union U { + a: u8 +} + +union W { + a: S, +} + +union Y { + a: S, +} + +impl Drop for S { + fn drop(&mut self) { + unsafe { CHECK += 10; } + } +} + +impl Drop for U { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +impl Drop for W { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +static mut CHECK: u8 = 0; + +fn main() { + unsafe { + assert_eq!(CHECK, 0); + { + let u = U { a: 1 }; + } + assert_eq!(CHECK, 1); // 1, dtor of U is called + { + let w = W { a: S }; + } + assert_eq!(CHECK, 2); // 2, not 11, dtor of S is not called + { + let y = Y { a: S }; + } + assert_eq!(CHECK, 2); // 2, not 12, dtor of S is not called + } +} diff --git a/src/test/ui/run-pass/union/union-generic.rs b/src/test/ui/run-pass/union/union-generic.rs new file mode 100644 index 00000000000..9293805edbf --- /dev/null +++ b/src/test/ui/run-pass/union/union-generic.rs @@ -0,0 +1,43 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(untagged_unions)] + +union MaybeItem<T: Iterator> { + elem: T::Item, + none: (), +} + +union U<A, B> { + a: A, + b: B, +} + +unsafe fn union_transmute<A, B>(a: A) -> B { + U { a: a }.b +} + +fn main() { + unsafe { + let u = U::<String, Vec<u8>> { a: String::from("abcd") }; + + assert_eq!(u.b.len(), 4); + assert_eq!(u.b[0], b'a'); + + let b = union_transmute::<(u8, u8), u16>((1, 1)); + assert_eq!(b, (1 << 8) + 1); + + let v: Vec<u8> = vec![1, 2, 3]; + let mut i = v.iter(); + i.next(); + let mi = MaybeItem::<std::slice::Iter<_>> { elem: i.next().unwrap() }; + assert_eq!(*mi.elem, 2); + } +} diff --git a/src/test/ui/run-pass/union/union-inherent-method.rs b/src/test/ui/run-pass/union/union-inherent-method.rs new file mode 100644 index 00000000000..a88fdc57a3e --- /dev/null +++ b/src/test/ui/run-pass/union/union-inherent-method.rs @@ -0,0 +1,22 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +union U { + a: u8, +} + +impl U { + fn method(&self) -> u8 { unsafe { self.a } } +} + +fn main() { + let u = U { a: 10 }; + assert_eq!(u.method(), 10); +} diff --git a/src/test/ui/run-pass/union/union-macro.rs b/src/test/ui/run-pass/union/union-macro.rs new file mode 100644 index 00000000000..b6141ae82c3 --- /dev/null +++ b/src/test/ui/run-pass/union/union-macro.rs @@ -0,0 +1,31 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! duplicate { + ($i: item) => { + mod m1 { + $i + } + mod m2 { + $i + } + } +} + +duplicate! { + pub union U { + pub a: u8 + } +} + +fn main() { + let u1 = m1::U { a: 0 }; + let u2 = m2::U { a: 0 }; +} diff --git a/src/test/ui/run-pass/union/union-nodrop.rs b/src/test/ui/run-pass/union/union-nodrop.rs new file mode 100644 index 00000000000..6295c6120c5 --- /dev/null +++ b/src/test/ui/run-pass/union/union-nodrop.rs @@ -0,0 +1,69 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(core_intrinsics)] +#![feature(untagged_unions)] + +#![allow(unions_with_drop_fields)] +#![allow(dead_code)] + +use std::intrinsics::needs_drop; + +struct NeedDrop; + +impl Drop for NeedDrop { + fn drop(&mut self) {} +} + +// Constant expressios allow `NoDrop` to go out of scope, +// unlike a value of the interior type implementing `Drop`. +static X: () = (NoDrop { inner: NeedDrop }, ()).1; + +// A union that scrubs the drop glue from its inner type +union NoDrop<T> {inner: T} + +// Copy currently can't be implemented on drop-containing unions, +// this may change later +// https://github.com/rust-lang/rust/pull/38934#issuecomment-271219289 + +// // We should be able to implement Copy for NoDrop +// impl<T> Copy for NoDrop<T> {} +// impl<T> Clone for NoDrop<T> {fn clone(&self) -> Self { *self }} + +// // We should be able to implement Copy for things using NoDrop +// #[derive(Copy, Clone)] +struct Foo { + x: NoDrop<Box<u8>> +} + +struct Baz { + x: NoDrop<Box<u8>>, + y: Box<u8>, +} + +union ActuallyDrop<T> {inner: T} + +impl<T> Drop for ActuallyDrop<T> { + fn drop(&mut self) {} +} + +fn main() { + unsafe { + // NoDrop should not make needs_drop true + assert!(!needs_drop::<Foo>()); + assert!(!needs_drop::<NoDrop<u8>>()); + assert!(!needs_drop::<NoDrop<Box<u8>>>()); + // presence of other drop types should still work + assert!(needs_drop::<Baz>()); + // drop impl on union itself should work + assert!(needs_drop::<ActuallyDrop<u8>>()); + assert!(needs_drop::<ActuallyDrop<Box<u8>>>()); + } +} diff --git a/src/test/ui/run-pass/union/union-overwrite.rs b/src/test/ui/run-pass/union/union-overwrite.rs new file mode 100644 index 00000000000..9389a6237bc --- /dev/null +++ b/src/test/ui/run-pass/union/union-overwrite.rs @@ -0,0 +1,80 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(untagged_unions)] + +#[repr(C)] +struct Pair<T, U>(T, U); +#[repr(C)] +struct Triple<T>(T, T, T); + +#[repr(C)] +union U<A, B> { + a: Pair<A, A>, + b: B, +} + +#[repr(C)] +union W<A, B> { + a: A, + b: B, +} + +#[cfg(target_endian = "little")] +unsafe fn check() { + let mut u = U::<u8, u16> { b: 0xDE_DE }; + u.a.0 = 0xBE; + assert_eq!(u.b, 0xDE_BE); + + let mut u = U::<u16, u32> { b: 0xDEAD_DEAD }; + u.a.0 = 0xBEEF; + assert_eq!(u.b, 0xDEAD_BEEF); + + let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF }; + u.a.0 = 0xBAADF00D; + assert_eq!(u.b, 0xDEADBEEF_BAADF00D); + + let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD }; + w.a.0 = Triple(0, 0, 0); + assert_eq!(w.b, 0xDE00_0000); + + let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD }; + w.a.1 = Triple(0, 0, 0); + assert_eq!(w.b, 0x0000_00AD); +} + +#[cfg(target_endian = "big")] +unsafe fn check() { + let mut u = U::<u8, u16> { b: 0xDE_DE }; + u.a.0 = 0xBE; + assert_eq!(u.b, 0xBE_DE); + + let mut u = U::<u16, u32> { b: 0xDEAD_DEAD }; + u.a.0 = 0xBEEF; + assert_eq!(u.b, 0xBEEF_DEAD); + + let mut u = U::<u32, u64> { b: 0xDEADBEEF_DEADBEEF }; + u.a.0 = 0xBAADF00D; + assert_eq!(u.b, 0xBAADF00D_DEADBEEF); + + let mut w = W::<Pair<Triple<u8>, u8>, u32> { b: 0xDEAD_DEAD }; + w.a.0 = Triple(0, 0, 0); + assert_eq!(w.b, 0x0000_00AD); + + let mut w = W::<Pair<u8, Triple<u8>>, u32> { b: 0xDEAD_DEAD }; + w.a.1 = Triple(0, 0, 0); + assert_eq!(w.b, 0xDE00_0000); +} + +fn main() { + unsafe { + check(); + } +} diff --git a/src/test/ui/run-pass/union/union-packed.rs b/src/test/ui/run-pass/union/union-packed.rs new file mode 100644 index 00000000000..61bb04fece0 --- /dev/null +++ b/src/test/ui/run-pass/union/union-packed.rs @@ -0,0 +1,178 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(untagged_unions)] +#![feature(repr_packed)] + +use std::mem::{size_of, size_of_val, align_of, align_of_val}; + +struct S { + a: u16, + b: [u8; 3], +} + +#[repr(packed)] +struct Sp1 { + a: u16, + b: [u8; 3], +} + +#[repr(packed(2))] +struct Sp2 { + a: u16, + b: [u8; 3], +} + +union U { + a: u16, + b: [u8; 3], +} + +#[repr(packed)] +union Up1 { + a: u16, + b: [u8; 3], +} + +#[repr(packed(2))] +union Up2 { + a: u16, + b: [u8; 3], +} + +#[repr(C, packed(4))] +union Up4c { + a: u16, + b: [u8; 3], +} + +const CS: S = S { a: 0, b: [0, 0, 0] }; +const CSP1: Sp1 = Sp1 { a: 0, b: [0, 0, 0] }; +const CSP2: Sp2 = Sp2 { a: 0, b: [0, 0, 0] }; +const CU: U = U { b: [0, 0, 0] }; +const CUP1: Up1 = Up1 { b: [0, 0, 0] }; +const CUP2: Up2 = Up2 { b: [0, 0, 0] }; +const CUP4C: Up4c = Up4c { b: [0, 0, 0] }; + +fn main() { + let s = S { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::<S>(), 6); + assert_eq!(size_of_val(&s), 6); + assert_eq!(size_of_val(&CS), 6); + assert_eq!(align_of::<S>(), 2); + assert_eq!(align_of_val(&s), 2); + assert_eq!(align_of_val(&CS), 2); + + let sp1 = Sp1 { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::<Sp1>(), 5); + assert_eq!(size_of_val(&sp1), 5); + assert_eq!(size_of_val(&CSP1), 5); + assert_eq!(align_of::<Sp1>(), 1); + assert_eq!(align_of_val(&sp1), 1); + assert_eq!(align_of_val(&CSP1), 1); + + let sp2 = Sp2 { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::<Sp2>(), 6); + assert_eq!(size_of_val(&sp2), 6); + assert_eq!(size_of_val(&CSP2), 6); + assert_eq!(align_of::<Sp2>(), 2); + assert_eq!(align_of_val(&sp2), 2); + assert_eq!(align_of_val(&CSP2), 2); + + let u = U { b: [0, 0, 0] }; + assert_eq!(size_of::<U>(), 4); + assert_eq!(size_of_val(&u), 4); + assert_eq!(size_of_val(&CU), 4); + assert_eq!(align_of::<U>(), 2); + assert_eq!(align_of_val(&u), 2); + assert_eq!(align_of_val(&CU), 2); + + let Up1 = Up1 { b: [0, 0, 0] }; + assert_eq!(size_of::<Up1>(), 3); + assert_eq!(size_of_val(&Up1), 3); + assert_eq!(size_of_val(&CUP1), 3); + assert_eq!(align_of::<Up1>(), 1); + assert_eq!(align_of_val(&Up1), 1); + assert_eq!(align_of_val(&CUP1), 1); + + let up2 = Up2 { b: [0, 0, 0] }; + assert_eq!(size_of::<Up2>(), 4); + assert_eq!(size_of_val(&up2), 4); + assert_eq!(size_of_val(&CUP2), 4); + assert_eq!(align_of::<Up2>(), 2); + assert_eq!(align_of_val(&up2), 2); + assert_eq!(align_of_val(&CUP2), 2); + + let up4c = Up4c { b: [0, 0, 0] }; + assert_eq!(size_of::<Up4c>(), 4); + assert_eq!(size_of_val(&up4c), 4); + assert_eq!(size_of_val(&CUP4C), 4); + assert_eq!(align_of::<Up4c>(), 2); + assert_eq!(align_of_val(&up4c), 2); + assert_eq!(align_of_val(&CUP4C), 2); + + hybrid::check_hybrid(); +} + +mod hybrid { + use std::mem::{size_of, align_of}; + + #[repr(packed)] + struct S1 { + a: u16, + b: u8, + } + + #[repr(packed)] + union U { + s: S1, + c: u16, + } + + #[repr(packed)] + struct S2 { + d: u8, + u: U, + } + + #[repr(C, packed(2))] + struct S1C { + a: u16, + b: u8, + } + + #[repr(C, packed(2))] + union UC { + s: S1, + c: u16, + } + + #[repr(C, packed(2))] + struct S2C { + d: u8, + u: UC, + } + + pub fn check_hybrid() { + assert_eq!(align_of::<S1>(), 1); + assert_eq!(size_of::<S1>(), 3); + assert_eq!(align_of::<U>(), 1); + assert_eq!(size_of::<U>(), 3); + assert_eq!(align_of::<S2>(), 1); + assert_eq!(size_of::<S2>(), 4); + + assert_eq!(align_of::<S1C>(), 2); + assert_eq!(size_of::<S1C>(), 4); + assert_eq!(align_of::<UC>(), 2); + assert_eq!(size_of::<UC>(), 4); + assert_eq!(align_of::<S2C>(), 2); + assert_eq!(size_of::<S2C>(), 6); + } +} diff --git a/src/test/ui/run-pass/union/union-pat-refutability.rs b/src/test/ui/run-pass/union/union-pat-refutability.rs new file mode 100644 index 00000000000..81607236c9e --- /dev/null +++ b/src/test/ui/run-pass/union/union-pat-refutability.rs @@ -0,0 +1,60 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[repr(u32)] +enum Tag { I, F } + +#[repr(C)] +union U { + i: i32, + f: f32, +} + +#[repr(C)] +struct Value { + tag: Tag, + u: U, +} + +fn is_zero(v: Value) -> bool { + unsafe { + match v { + Value { tag: Tag::I, u: U { i: 0 } } => true, + Value { tag: Tag::F, u: U { f: 0.0 } } => true, + _ => false, + } + } +} + +union W { + a: u8, + b: u8, +} + +fn refut(w: W) { + unsafe { + match w { + W { a: 10 } => { + panic!(); + } + W { b } => { + assert_eq!(b, 11); + } + } + } +} + +fn main() { + let v = Value { tag: Tag::I, u: U { i: 1 } }; + assert_eq!(is_zero(v), false); + + let w = W { a: 11 }; + refut(w); +} diff --git a/src/test/ui/run-pass/union/union-trait-impl.rs b/src/test/ui/run-pass/union/union-trait-impl.rs new file mode 100644 index 00000000000..c1e408cc02a --- /dev/null +++ b/src/test/ui/run-pass/union/union-trait-impl.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; + +union U { + a: u8 +} + +impl fmt::Display for U { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + unsafe { write!(f, "Oh hai {}", self.a) } + } +} + +fn main() { + assert_eq!(U { a: 2 }.to_string(), "Oh hai 2"); +} diff --git a/src/test/ui/run-pass/union/union-transmute.rs b/src/test/ui/run-pass/union/union-transmute.rs new file mode 100644 index 00000000000..7233687aaab --- /dev/null +++ b/src/test/ui/run-pass/union/union-transmute.rs @@ -0,0 +1,36 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate core; +use core::f32; + +union U { + a: (u8, u8), + b: u16, +} + +union W { + a: u32, + b: f32, +} + +fn main() { + unsafe { + let mut u = U { a: (1, 1) }; + assert_eq!(u.b, (1 << 8) + 1); + u.b = (2 << 8) + 2; + assert_eq!(u.a, (2, 2)); + + let mut w = W { a: 0b0_11111111_00000000000000000000000 }; + assert_eq!(w.b, f32::INFINITY); + w.b = f32::NEG_INFINITY; + assert_eq!(w.a, 0b1_11111111_00000000000000000000000); + } +} diff --git a/src/test/ui/run-pass/union/union-with-drop-fields-lint.rs b/src/test/ui/run-pass/union/union-with-drop-fields-lint.rs new file mode 100644 index 00000000000..6cb7e82d6b7 --- /dev/null +++ b/src/test/ui/run-pass/union/union-with-drop-fields-lint.rs @@ -0,0 +1,40 @@ +// Copyright 2016 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(untagged_unions)] +#![allow(dead_code)] +#![allow(unions_with_drop_fields)] + +union U { + a: u8, // OK +} + +union W { + a: String, // OK + b: String, // OK +} + +struct S(String); + +// `S` doesn't implement `Drop` trait, but still has non-trivial destructor +union Y { + a: S, // OK +} + +// We don't know if `T` is trivially-destructable or not until trans +union J<T> { + a: T, // OK +} + +union H<T: Copy> { + a: T, // OK +} + +fn main() {} diff --git a/src/test/ui/run-pass/unsized-locals/reference-unsized-locals.rs b/src/test/ui/run-pass/unsized-locals/reference-unsized-locals.rs new file mode 100644 index 00000000000..6ed39a78648 --- /dev/null +++ b/src/test/ui/run-pass/unsized-locals/reference-unsized-locals.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(unsized_locals)] + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let foo: [u8] = *foo; + assert_eq!(&foo, b"foo" as &[u8]); +} diff --git a/src/test/ui/run-pass/unsized-locals/simple-unsized-locals.rs b/src/test/ui/run-pass/unsized-locals/simple-unsized-locals.rs new file mode 100644 index 00000000000..0b1aa6225eb --- /dev/null +++ b/src/test/ui/run-pass/unsized-locals/simple-unsized-locals.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(unsized_locals)] + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let _foo: [u8] = *foo; +} diff --git a/src/test/ui/run-pass/unsized-locals/unsized-exprs.rs b/src/test/ui/run-pass/unsized-locals/unsized-exprs.rs new file mode 100644 index 00000000000..9a5e534db25 --- /dev/null +++ b/src/test/ui/run-pass/unsized-locals/unsized-exprs.rs @@ -0,0 +1,45 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(unsized_tuple_coercion, unsized_locals)] + +struct A<X: ?Sized>(X); + +fn udrop<T: ?Sized>(_x: T) {} +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} +fn tfoo() -> Box<(i32, [u8])> { + Box::new((42, *b"foo")) +} +fn afoo() -> Box<A<[u8]>> { + Box::new(A(*b"foo")) +} + +impl std::ops::Add<i32> for A<[u8]> { + type Output = (); + fn add(self, _rhs: i32) -> Self::Output {} +} + +fn main() { + udrop::<[u8]>(loop { + break *foo(); + }); + udrop::<[u8]>(if true { + *foo() + } else { + *foo() + }); + udrop::<[u8]>({*foo()}); + #[allow(unused_parens)] + udrop::<[u8]>((*foo())); + udrop::<[u8]>((*tfoo()).1); + *afoo() + 42; +} diff --git a/src/test/ui/run-pass/unsized-locals/unsized-parameters.rs b/src/test/ui/run-pass/unsized-locals/unsized-parameters.rs new file mode 100644 index 00000000000..0314fe1d686 --- /dev/null +++ b/src/test/ui/run-pass/unsized-locals/unsized-parameters.rs @@ -0,0 +1,20 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(unsized_locals)] + +pub fn f0(_f: dyn FnOnce()) {} +pub fn f1(_s: str) {} +pub fn f2((_x, _y): (i32, [i32])) {} + +fn main() { + let foo = "foo".to_string().into_boxed_str(); + f1(*foo); +} |
