diff --git a/src/test/compile-fail/feature-gate-non_exhaustive.rs b/src/test/compile-fail/feature-gate-non_exhaustive.rs new file mode 100644 index 00000000000..d2711084a4d --- /dev/null +++ b/src/test/compile-fail/feature-gate-non_exhaustive.rs @@ -0,0 +1,20 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//#![feature(non_exhaustive)] + +#[non_exhaustive] //~ERROR non exhaustive is an experimental feature (see issue #44109) +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +fn main() { } diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/enums.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/enums.rs new file mode 100644 index 00000000000..12d1bf9ea91 --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/enums.rs @@ -0,0 +1,19 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/structs.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/structs.rs new file mode 100644 index 00000000000..4d083cc5315 --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/structs.rs @@ -0,0 +1,37 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +pub struct UnitStruct; + +#[non_exhaustive] +pub struct TupleStruct(pub u16, pub u16); + +#[derive(Debug)] +#[non_exhaustive] +pub struct FunctionalRecord { + pub first_field: u16, + pub second_field: u16, + pub third_field: bool +} + +impl Default for FunctionalRecord { + fn default() -> FunctionalRecord { + FunctionalRecord { first_field: 640, second_field: 480, third_field: false } + } +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/variants.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/variants.rs new file mode 100644 index 00000000000..d04c1073ad9 --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/auxiliary/variants.rs @@ -0,0 +1,18 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(non_exhaustive)] + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/enum.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/enum.rs new file mode 100644 index 00000000000..0c19210e4a0 --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/enum.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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:enums.rs +extern crate enums; + +use enums::NonExhaustiveEnum; + +fn main() { + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { + //~^ ERROR non-exhaustive patterns: `_` not covered [E0004] + NonExhaustiveEnum::Unit => "first", + NonExhaustiveEnum::Tuple(_) => "second", + NonExhaustiveEnum::Struct { .. } => "third" + }; +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/structs.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/structs.rs new file mode 100644 index 00000000000..74c9c7c61ac --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/structs.rs @@ -0,0 +1,47 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:structs.rs +extern crate structs; + +use structs::{NormalStruct, UnitStruct, TupleStruct, FunctionalRecord}; + +fn main() { + let fr = FunctionalRecord { + //~^ ERROR cannot create non-exhaustive struct + first_field: 1920, + second_field: 1080, + ..FunctionalRecord::default() + }; + + let ns = NormalStruct { first_field: 640, second_field: 480 }; + //~^ ERROR cannot create non-exhaustive struct + + let NormalStruct { first_field, second_field } = ns; + //~^ ERROR `..` required with struct marked as non-exhaustive + + let ts = TupleStruct(640, 480); + //~^ ERROR expected function, found struct `TupleStruct` [E0423] + + let ts_explicit = structs::TupleStruct(640, 480); + //~^ ERROR tuple struct `TupleStruct` is private [E0603] + + let TupleStruct { 0: first_field, 1: second_field } = ts; + //~^ ERROR `..` required with struct marked as non-exhaustive + + let us = UnitStruct; + //~^ ERROR expected value, found struct `UnitStruct` [E0423] + + let us_explicit = structs::UnitStruct; + //~^ ERROR unit struct `UnitStruct` is private [E0603] + + let UnitStruct { } = us; + //~^ ERROR `..` required with struct marked as non-exhaustive +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/variants.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/variants.rs new file mode 100644 index 00000000000..d1b65ac1f3e --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/variants.rs @@ -0,0 +1,36 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:variants.rs +extern crate variants; + +use variants::NonExhaustiveVariants; + +/* + * The initial implementation of #[non_exhaustive] (RFC 2008) does not include support for + * variants. See issue #44109 and PR 45394. + */ +// ignore-test + +fn main() { + let variant_struct = NonExhaustiveVariants::Struct { field: 640 }; + //~^ ERROR cannot create non-exhaustive variant + + let variant_tuple = NonExhaustiveVariants::Tuple { 0: 640 }; + //~^ ERROR cannot create non-exhaustive variant + + match variant_struct { + NonExhaustiveVariants::Unit => "", + NonExhaustiveVariants::Tuple(fe_tpl) => "", + //~^ ERROR `..` required with variant marked as non-exhaustive + NonExhaustiveVariants::Struct { field } => "" + //~^ ERROR `..` required with variant marked as non-exhaustive + }; +} diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/variants_create.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/variants_create.rs new file mode 100644 index 00000000000..f4e4b1bb84b --- /dev/null +++ b/src/test/compile-fail/rfc-2008-non-exhaustive/variants_create.rs @@ -0,0 +1,27 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +/* + * The initial implementation of #[non_exhaustive] (RFC 2008) does not include support for + * variants. See issue #44109 and PR 45394. + */ + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + //~^ ERROR #[non_exhaustive] is not yet supported on variants + #[non_exhaustive] Tuple(u32), + //~^ ERROR #[non_exhaustive] is not yet supported on variants + #[non_exhaustive] Struct { field: u32 } + //~^ ERROR #[non_exhaustive] is not yet supported on variants +} + +fn main() { } diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/enums.rs b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/enums.rs new file mode 100644 index 00000000000..12d1bf9ea91 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/enums.rs @@ -0,0 +1,19 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/structs.rs b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/structs.rs new file mode 100644 index 00000000000..a2c6f8c05e2 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/structs.rs @@ -0,0 +1,23 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +pub struct UnitStruct; + +#[non_exhaustive] +pub struct TupleStruct (pub u16, pub u16); diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/variants.rs b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/variants.rs new file mode 100644 index 00000000000..d04c1073ad9 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/auxiliary/variants.rs @@ -0,0 +1,18 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(non_exhaustive)] + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/enums.rs b/src/test/run-pass/rfc-2008-non-exhaustive/enums.rs new file mode 100644 index 00000000000..aaee70d6d80 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/enums.rs @@ -0,0 +1,31 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:enums.rs +extern crate enums; + +use enums::NonExhaustiveEnum; + +fn main() { + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { + NonExhaustiveEnum::Unit => 1, + NonExhaustiveEnum::Tuple(_) => 2, + // This particular arm tests that a enum marked as non-exhaustive + // will not error if its variants are matched exhaustively. + NonExhaustiveEnum::Struct { field } => field, + _ => 0 // no error with wildcard + }; + + match enum_unit { + _ => "no error with only wildcard" + }; +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/enums_same_crate.rs b/src/test/run-pass/rfc-2008-non-exhaustive/enums_same_crate.rs new file mode 100644 index 00000000000..8f1ba364b0e --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/enums_same_crate.rs @@ -0,0 +1,28 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +fn main() { + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { + NonExhaustiveEnum::Unit => "first", + NonExhaustiveEnum::Tuple(_) => "second", + NonExhaustiveEnum::Struct { .. } => "third", + }; +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/structs.rs b/src/test/run-pass/rfc-2008-non-exhaustive/structs.rs new file mode 100644 index 00000000000..bb65e10da27 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/structs.rs @@ -0,0 +1,27 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:structs.rs +extern crate structs; + +use structs::{NormalStruct, UnitStruct, TupleStruct}; + +// We only test matching here as we cannot create non-exhaustive +// structs from another crate. ie. they'll never pass in run-pass tests. + +fn match_structs(ns: NormalStruct, ts: TupleStruct, us: UnitStruct) { + let NormalStruct { first_field, second_field, .. } = ns; + + let TupleStruct { 0: first, 1: second, .. } = ts; + + let UnitStruct { .. } = us; +} + +fn main() { } diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/structs_same_crate.rs b/src/test/run-pass/rfc-2008-non-exhaustive/structs_same_crate.rs new file mode 100644 index 00000000000..175782f10fc --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/structs_same_crate.rs @@ -0,0 +1,40 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +#[non_exhaustive] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +pub struct UnitStruct; + +#[non_exhaustive] +pub struct TupleStruct (pub u16, pub u16); + +fn main() { + let ns = NormalStruct { first_field: 640, second_field: 480 }; + + let NormalStruct { first_field, second_field } = ns; + + let ts = TupleStruct { 0: 340, 1: 480 }; + let ts_constructor = TupleStruct(340, 480); + + let TupleStruct { 0: first, 1: second } = ts; + let TupleStruct(first, second) = ts_constructor; + + let us = UnitStruct {}; + let us_constructor = UnitStruct; + + let UnitStruct { } = us; +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/variants.rs b/src/test/run-pass/rfc-2008-non-exhaustive/variants.rs new file mode 100644 index 00000000000..2658c59a699 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/variants.rs @@ -0,0 +1,31 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:variants.rs +extern crate variants; + +use variants::NonExhaustiveVariants; + +/* + * The initial implementation of #[non_exhaustive] (RFC 2008) does not include support for + * variants. See issue #44109 and PR 45394. + */ +// ignore-test + +fn main() { + let variant_tuple = NonExhaustiveVariants::Tuple { 0: 340 }; + let variant_struct = NonExhaustiveVariants::Struct { field: 340 }; + + match variant_struct { + NonExhaustiveVariants::Unit => "", + NonExhaustiveVariants::Struct { field, .. } => "", + NonExhaustiveVariants::Tuple(fe_tpl, ..) => "" + }; +} diff --git a/src/test/run-pass/rfc-2008-non-exhaustive/variants_same_crate.rs b/src/test/run-pass/rfc-2008-non-exhaustive/variants_same_crate.rs new file mode 100644 index 00000000000..a1c376c1798 --- /dev/null +++ b/src/test/run-pass/rfc-2008-non-exhaustive/variants_same_crate.rs @@ -0,0 +1,34 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(non_exhaustive)] + +/* + * The initial implementation of #[non_exhaustive] (RFC 2008) does not include support for + * variants. See issue #44109 and PR 45394. + */ +// ignore-test + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} + +fn main() { + let variant_tuple = NonExhaustiveVariants::Tuple(340); + let variant_struct = NonExhaustiveVariants::Struct { field: 340 }; + + match variant_tuple { + NonExhaustiveVariants::Unit => "", + NonExhaustiveVariants::Tuple(fe_tpl) => "", + NonExhaustiveVariants::Struct { field } => "" + }; +}