diff options
| author | bors <bors@rust-lang.org> | 2015-08-06 19:11:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-08-06 19:11:17 +0000 |
| commit | 11deb083f5bc3e57e73fc82de4bef7b1d4dad7b1 (patch) | |
| tree | 0f575e98b114fe6b854a1fd53ff1f7749ba3621c /src/test | |
| parent | fb92de75c1c4b7eaaf5d425fb2587407c00701fc (diff) | |
| parent | 83e43bb728b95d52039824d63b1ba5bbde5c5d7b (diff) | |
| download | rust-11deb083f5bc3e57e73fc82de4bef7b1d4dad7b1.tar.gz rust-11deb083f5bc3e57e73fc82de4bef7b1d4dad7b1.zip | |
Auto merge of #27296 - jroesch:type-macros, r=huonw
This pull request implements the functionality for [RFC 873](https://github.com/rust-lang/rfcs/blob/master/text/0873-type-macros.md). This is currently just an update of @freebroccolo's branch from January, the corresponding commits are linked in each commit message. @nikomatsakis and I had talked about updating the macro language to support a lifetime fragment specifier, and it is possible to do that work on this branch as well. If so we can (collectively) talk about it next week during the pre-RustCamp work week.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/compile-fail/type-macros-fail.rs | 22 | ||||
| -rw-r--r-- | src/test/parse-fail/better-expected.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/empty-impl-semicolon.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/multitrait.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/removed-syntax-closure-lifetime.rs | 3 | ||||
| -rw-r--r-- | src/test/parse-fail/removed-syntax-fixed-vec.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/removed-syntax-mut-vec-ty.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/removed-syntax-ptr-lifetime.rs | 2 | ||||
| -rw-r--r-- | src/test/parse-fail/removed-syntax-uniq-mut-ty.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/type-macros-hlist.rs | 89 | ||||
| -rw-r--r-- | src/test/run-pass/type-macros-simple.rs | 19 |
11 files changed, 139 insertions, 8 deletions
diff --git a/src/test/compile-fail/type-macros-fail.rs b/src/test/compile-fail/type-macros-fail.rs new file mode 100644 index 00000000000..f854e540ee8 --- /dev/null +++ b/src/test/compile-fail/type-macros-fail.rs @@ -0,0 +1,22 @@ +// 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. + +macro_rules! Id { + { $T:tt } => $T +} + +struct Foo<T> { + x: Id!(T) + //~^ ERROR: type macros are experimental (see issue: #27336) +} + +fn main() { + let foo = Foo { x: i32 }; +} diff --git a/src/test/parse-fail/better-expected.rs b/src/test/parse-fail/better-expected.rs index 3f0e0d36d8f..b60201c251d 100644 --- a/src/test/parse-fail/better-expected.rs +++ b/src/test/parse-fail/better-expected.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only fn main() { - let x: [isize 3]; //~ ERROR expected one of `(`, `+`, `::`, `;`, `<`, or `]`, found `3` + let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3` } diff --git a/src/test/parse-fail/empty-impl-semicolon.rs b/src/test/parse-fail/empty-impl-semicolon.rs index d9f8add8cfb..9939f1e36ea 100644 --- a/src/test/parse-fail/empty-impl-semicolon.rs +++ b/src/test/parse-fail/empty-impl-semicolon.rs @@ -10,4 +10,4 @@ // compile-flags: -Z parse-only -impl Foo; //~ ERROR expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;` +impl Foo; //~ ERROR expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;` diff --git a/src/test/parse-fail/multitrait.rs b/src/test/parse-fail/multitrait.rs index 2a8d6d99957..b7c9b165884 100644 --- a/src/test/parse-fail/multitrait.rs +++ b/src/test/parse-fail/multitrait.rs @@ -15,7 +15,7 @@ struct S { } impl Cmp, ToString for S { -//~^ ERROR: expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,` +//~^ ERROR: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,` fn eq(&&other: S) { false } fn to_string(&self) -> String { "hi".to_string() } } diff --git a/src/test/parse-fail/removed-syntax-closure-lifetime.rs b/src/test/parse-fail/removed-syntax-closure-lifetime.rs index 04d3757dcda..b305b1894a8 100644 --- a/src/test/parse-fail/removed-syntax-closure-lifetime.rs +++ b/src/test/parse-fail/removed-syntax-closure-lifetime.rs @@ -10,4 +10,5 @@ // compile-flags: -Z parse-only -type closure = Box<lt/fn()>; //~ ERROR expected one of `(`, `+`, `,`, `::`, `<`, or `>`, found `/` +type closure = Box<lt/fn()>; +//~^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `/` diff --git a/src/test/parse-fail/removed-syntax-fixed-vec.rs b/src/test/parse-fail/removed-syntax-fixed-vec.rs index ae61d1ea858..0f34db08852 100644 --- a/src/test/parse-fail/removed-syntax-fixed-vec.rs +++ b/src/test/parse-fail/removed-syntax-fixed-vec.rs @@ -10,4 +10,4 @@ // compile-flags: -Z parse-only -type v = [isize * 3]; //~ ERROR expected one of `(`, `+`, `::`, `;`, `<`, or `]`, found `*` +type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*` diff --git a/src/test/parse-fail/removed-syntax-mut-vec-ty.rs b/src/test/parse-fail/removed-syntax-mut-vec-ty.rs index 00ea593656a..91918f01bb0 100644 --- a/src/test/parse-fail/removed-syntax-mut-vec-ty.rs +++ b/src/test/parse-fail/removed-syntax-mut-vec-ty.rs @@ -12,4 +12,4 @@ type v = [mut isize]; //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `(`, `+`, `::`, `;`, `<`, or `]`, found `isize` + //~^^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `isize` diff --git a/src/test/parse-fail/removed-syntax-ptr-lifetime.rs b/src/test/parse-fail/removed-syntax-ptr-lifetime.rs index e586753087a..ebef0e56e3e 100644 --- a/src/test/parse-fail/removed-syntax-ptr-lifetime.rs +++ b/src/test/parse-fail/removed-syntax-ptr-lifetime.rs @@ -10,4 +10,4 @@ // compile-flags: -Z parse-only -type bptr = &lifetime/isize; //~ ERROR expected one of `(`, `+`, `::`, `;`, or `<`, found `/` +type bptr = &lifetime/isize; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, or `<`, found `/` diff --git a/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs b/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs index 77e64e7c997..e1637901266 100644 --- a/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs +++ b/src/test/parse-fail/removed-syntax-uniq-mut-ty.rs @@ -12,4 +12,4 @@ type mut_box = Box<mut isize>; //~^ ERROR expected identifier, found keyword `mut` - //~^^ ERROR expected one of `(`, `+`, `,`, `::`, `<`, or `>`, found `isize` + //~^^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `isize` diff --git a/src/test/run-pass/type-macros-hlist.rs b/src/test/run-pass/type-macros-hlist.rs new file mode 100644 index 00000000000..803b0eae99e --- /dev/null +++ b/src/test/run-pass/type-macros-hlist.rs @@ -0,0 +1,89 @@ +// 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(type_macros)] + +use std::ops::*; + +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct Nil; + // empty HList +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct Cons<H, T: HList>(H, T); + // cons cell of HList + + // trait to classify valid HLists +trait HList { } +impl HList for Nil { } +impl <H, T: HList> HList for Cons<H, T> { } + +// term-level macro for HLists +macro_rules! hlist({ } => { Nil } ; { $ head : expr } => { + Cons ( $ head , Nil ) } ; { + $ head : expr , $ ( $ tail : expr ) , * } => { + Cons ( $ head , hlist ! ( $ ( $ tail ) , * ) ) } ;); + +// type-level macro for HLists +macro_rules! HList({ } => { Nil } ; { $ head : ty } => { + Cons < $ head , Nil > } ; { + $ head : ty , $ ( $ tail : ty ) , * } => { + Cons < $ head , HList ! ( $ ( $ tail ) , * ) > } ;); + +// nil case for HList append +impl <Ys: HList> Add<Ys> for Nil { + type + Output + = + Ys; + + fn add(self, rhs: Ys) -> Ys { rhs } +} + +// cons case for HList append +impl <Rec: HList + Sized, X, Xs: HList, Ys: HList> Add<Ys> for Cons<X, Xs> + where Xs: Add<Ys, Output = Rec> { + type + Output + = + Cons<X, Rec>; + + fn add(self, rhs: Ys) -> Cons<X, Rec> { Cons(self.0, self.1 + rhs) } +} + +// type macro Expr allows us to expand the + operator appropriately +macro_rules! Expr({ ( $ ( $ LHS : tt ) + ) } => { Expr ! ( $ ( $ LHS ) + ) } ; + { HList ! [ $ ( $ LHS : tt ) * ] + $ ( $ RHS : tt ) + } => { + < Expr ! ( HList ! [ $ ( $ LHS ) * ] ) as Add < Expr ! ( + $ ( $ RHS ) + ) >> :: Output } ; { + $ LHS : tt + $ ( $ RHS : tt ) + } => { + < Expr ! ( $ LHS ) as Add < Expr ! ( $ ( $ RHS ) + ) >> :: + Output } ; { $ LHS : ty } => { $ LHS } ;); + +// test demonstrating term level `xs + ys` and type level `Expr!(Xs + Ys)` +fn main() { + fn aux<Xs: HList, Ys: HList>(xs: Xs, ys: Ys) -> Expr!(Xs + Ys) where + Xs: Add<Ys> { + xs + ys + } + + let xs: HList!(& str , bool , Vec < u64 >) = + hlist!("foo" , false , vec ! [ ]); + let ys: HList!(u64 , [ u8 ; 3 ] , ( )) = + hlist!(0 , [ 0 , 1 , 2 ] , ( )); + + // demonstrate recursive expansion of Expr! + let zs: + Expr!(( + HList ! [ & str ] + HList ! [ bool ] + HList ! [ Vec < u64 > + ] ) + ( HList ! [ u64 ] + HList ! [ [ u8 ; 3 ] , ( ) ] ) + + HList ! [ ]) = aux(xs, ys); + assert_eq!(zs , hlist ! [ + "foo" , false , vec ! [ ] , 0 , [ 0 , 1 , 2 ] , ( ) ]) +} diff --git a/src/test/run-pass/type-macros-simple.rs b/src/test/run-pass/type-macros-simple.rs new file mode 100644 index 00000000000..22dfd507f7e --- /dev/null +++ b/src/test/run-pass/type-macros-simple.rs @@ -0,0 +1,19 @@ +// 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(type_macros)] + +macro_rules! Tuple { + { $A:ty,$B:ty } => { ($A, $B) } +} + +fn main() { + let x: Tuple!(i32, i32) = (1, 2); +} |
