about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-08-06 19:11:17 +0000
committerbors <bors@rust-lang.org>2015-08-06 19:11:17 +0000
commit11deb083f5bc3e57e73fc82de4bef7b1d4dad7b1 (patch)
tree0f575e98b114fe6b854a1fd53ff1f7749ba3621c /src/test
parentfb92de75c1c4b7eaaf5d425fb2587407c00701fc (diff)
parent83e43bb728b95d52039824d63b1ba5bbde5c5d7b (diff)
downloadrust-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.rs22
-rw-r--r--src/test/parse-fail/better-expected.rs2
-rw-r--r--src/test/parse-fail/empty-impl-semicolon.rs2
-rw-r--r--src/test/parse-fail/multitrait.rs2
-rw-r--r--src/test/parse-fail/removed-syntax-closure-lifetime.rs3
-rw-r--r--src/test/parse-fail/removed-syntax-fixed-vec.rs2
-rw-r--r--src/test/parse-fail/removed-syntax-mut-vec-ty.rs2
-rw-r--r--src/test/parse-fail/removed-syntax-ptr-lifetime.rs2
-rw-r--r--src/test/parse-fail/removed-syntax-uniq-mut-ty.rs2
-rw-r--r--src/test/run-pass/type-macros-hlist.rs89
-rw-r--r--src/test/run-pass/type-macros-simple.rs19
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);
+}