about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-06 15:49:15 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-06 15:49:15 -0800
commit26cd8eae48ea99bda183c5224bc423991ccfaf1f (patch)
tree26492380aa79b1b1f70acb2a624e30ca097374df /src
parent34a63d336419e80d3afec16c730d1ad5fa11dc73 (diff)
parente9cbdd866d1c9c01e9affaf6875e37e58a073758 (diff)
downloadrust-26cd8eae48ea99bda183c5224bc423991ccfaf1f.tar.gz
rust-26cd8eae48ea99bda183c5224bc423991ccfaf1f.zip
rollup merge of #20563: cmr/macro-input-future-proofing
Diffstat (limited to 'src')
-rw-r--r--src/doc/guide-macros.md36
-rw-r--r--src/libcore/macros.rs9
-rw-r--r--src/libcore/str/mod.rs21
-rw-r--r--src/librustc_trans/trans/context.rs220
-rw-r--r--src/libserialize/serialize.rs2
-rw-r--r--src/libstd/rt/macros.rs16
-rw-r--r--src/libstd/sys/common/backtrace.rs28
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs193
-rw-r--r--src/libsyntax/parse/token.rs1
-rw-r--r--src/test/compile-fail/macro-input-future-proofing.rs30
-rw-r--r--src/test/run-pass/const-polymorphic-paths.rs51
-rw-r--r--src/test/run-pass/nullable-pointer-iotareduction.rs22
12 files changed, 423 insertions, 206 deletions
diff --git a/src/doc/guide-macros.md b/src/doc/guide-macros.md
index dc6d281307a..9cb4d154de7 100644
--- a/src/doc/guide-macros.md
+++ b/src/doc/guide-macros.md
@@ -161,7 +161,7 @@ instead of `*` to mean "at least one".
 # let input_1 = T::SpecialA(0);
 # let input_2 = T::SpecialA(0);
 macro_rules! early_return {
-    ($inp:expr, [ $($sp:path)|+ ]) => (
+    ($inp:expr, [ $($sp:path),+ ]) => (
         match $inp {
             $(
                 $sp(x) => { return x; }
@@ -171,7 +171,7 @@ macro_rules! early_return {
     )
 }
 // ...
-early_return!(input_1, [T::SpecialA|T::SpecialC|T::SpecialD]);
+early_return!(input_1, [T::SpecialA,T::SpecialC,T::SpecialD]);
 // ...
 early_return!(input_2, [T::SpecialB]);
 # return 0;
@@ -245,7 +245,7 @@ can solve the problem:
 ~~~~
 macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
-    ( ($e:expr) ~ ($p:pat) else $err:stmt ;
+    ( ($e:expr) -> ($p:pat) else $err:stmt ;
       binds $bind_res:ident
     ) => (
         let $bind_res = match $e {
@@ -254,7 +254,7 @@ macro_rules! biased_match {
         };
     );
     // more than one name; use a tuple
-    ( ($e:expr) ~ ($p:pat) else $err:stmt ;
+    ( ($e:expr) -> ($p:pat) else $err:stmt ;
       binds $( $bind_res:ident ),*
     ) => (
         let ( $( $bind_res ),* ) = match $e {
@@ -268,9 +268,9 @@ macro_rules! biased_match {
 # struct T2 { body: T3 }
 # enum T3 { Good2(uint), Bad2}
 # fn f(x: T1) -> uint {
-biased_match!((x)       ~ (T1::Good1(g1, val)) else { return 0 };
+biased_match!((x)       -> (T1::Good1(g1, val)) else { return 0 };
               binds g1, val );
-biased_match!((g1.body) ~ (T3::Good2(result) )
+biased_match!((g1.body) -> (T3::Good2(result) )
                   else { panic!("Didn't get good_2") };
               binds result );
 // complicated stuff goes here
@@ -286,7 +286,7 @@ pattern we want is clear:
 ~~~~
 # fn main() {}
 # macro_rules! b {
-    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
+    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
       binds $( $bind_res:ident ),*
     )
 # => (0) }
@@ -317,8 +317,8 @@ input patterns:
 ~~~~
 # fn main() {}
 # macro_rules! b {
-    (    ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
-      $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
+    (    ($e     :expr) -> ($p     :pat) else $err     :stmt ;
+      $( ($e_rest:expr) -> ($p_rest:pat) else $err_rest:stmt ; )*
       binds  $( $bind_res:ident ),*
     )
 # => (0) }
@@ -333,14 +333,14 @@ piece of syntax (the `let`) which we only want to transcribe once.
 
 macro_rules! biased_match_rec {
     // Handle the first layer
-    (   ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
-     $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
+    (   ($e     :expr) -> ($p     :pat) else $err     :stmt ;
+     $( ($e_rest:expr) -> ($p_rest:pat) else $err_rest:stmt ; )*
      binds $( $bind_res:ident ),*
     ) => (
         match $e {
             $p => {
                 // Recursively handle the next layer
-                biased_match_rec!($( ($e_rest) ~ ($p_rest) else $err_rest ; )*
+                biased_match_rec!($( ($e_rest) -> ($p_rest) else $err_rest ; )*
                                   binds $( $bind_res ),*
                 )
             }
@@ -354,20 +354,20 @@ macro_rules! biased_match_rec {
 // Wrap the whole thing in a `let`.
 macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
-    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
+    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
       binds $bind_res:ident
     ) => (
         let $bind_res = biased_match_rec!(
-            $( ($e) ~ ($p) else $err ; )*
+            $( ($e) -> ($p) else $err ; )*
             binds $bind_res
         );
     );
     // more than one name: use a tuple
-    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
+    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
       binds  $( $bind_res:ident ),*
     ) => (
         let ( $( $bind_res ),* ) = biased_match_rec!(
-            $( ($e) ~ ($p) else $err ; )*
+            $( ($e) -> ($p) else $err ; )*
             binds $( $bind_res ),*
         );
     )
@@ -379,8 +379,8 @@ macro_rules! biased_match {
 # enum T3 { Good2(uint), Bad2}
 # fn f(x: T1) -> uint {
 biased_match!(
-    (x)       ~ (T1::Good1(g1, val)) else { return 0 };
-    (g1.body) ~ (T3::Good2(result) ) else { panic!("Didn't get Good2") };
+    (x)       -> (T1::Good1(g1, val)) else { return 0 };
+    (g1.body) -> (T3::Good2(result) ) else { panic!("Didn't get Good2") };
     binds val, result );
 // complicated stuff goes here
 return result + val;
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index d01621fc6d8..00bfe56a622 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -179,9 +179,12 @@ macro_rules! write {
 #[macro_export]
 #[stable]
 macro_rules! writeln {
-    ($dst:expr, $fmt:expr $($arg:tt)*) => (
-        write!($dst, concat!($fmt, "\n") $($arg)*)
-    )
+    ($dst:expr, $fmt:expr) => (
+        write!($dst, concat!($fmt, "\n"))
+    );
+    ($dst:expr, $fmt:expr, $($arg:expr),*) => (
+        write!($dst, concat!($fmt, "\n"), $($arg,)*)
+    );
 }
 
 /// A utility macro for indicating unreachable code.
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index d633f822ff7..3f8ce000e21 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -35,9 +35,8 @@ use slice::{self, SliceExt};
 use uint;
 
 macro_rules! delegate_iter {
-    (exact $te:ty in $ti:ty) => {
-        delegate_iter!{$te in $ti}
-        #[stable]
+    (exact $te:ty : $ti:ty) => {
+        delegate_iter!{$te : $ti}
         impl<'a> ExactSizeIterator for $ti {
             #[inline]
             fn len(&self) -> uint {
@@ -45,7 +44,7 @@ macro_rules! delegate_iter {
             }
         }
     };
-    ($te:ty in $ti:ty) => {
+    ($te:ty : $ti:ty) => {
         #[stable]
         impl<'a> Iterator for $ti {
             type Item = $te;
@@ -67,7 +66,7 @@ macro_rules! delegate_iter {
             }
         }
     };
-    (pattern $te:ty in $ti:ty) => {
+    (pattern $te:ty : $ti:ty) => {
         #[stable]
         impl<'a, P: CharEq> Iterator for $ti {
             type Item = $te;
@@ -89,7 +88,7 @@ macro_rules! delegate_iter {
             }
         }
     };
-    (pattern forward $te:ty in $ti:ty) => {
+    (pattern forward $te:ty : $ti:ty) => {
         #[stable]
         impl<'a, P: CharEq> Iterator for $ti {
             type Item = $te;
@@ -415,7 +414,7 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> {
 #[stable]
 #[derive(Clone)]
 pub struct Bytes<'a>(Map<&'a u8, u8, slice::Iter<'a, u8>, BytesDeref>);
-delegate_iter!{exact u8 in Bytes<'a>}
+delegate_iter!{exact u8 : Bytes<'a>}
 
 /// A temporary fn new type that ensures that the `Bytes` iterator
 /// is cloneable.
@@ -1172,25 +1171,25 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str {
 #[derive(Clone)]
 #[stable]
 pub struct Split<'a, P>(CharSplits<'a, P>);
-delegate_iter!{pattern &'a str in Split<'a, P>}
+delegate_iter!{pattern &'a str : Split<'a, P>}
 
 /// Return type of `StrExt::split_terminator`
 #[derive(Clone)]
 #[unstable = "might get removed in favour of a constructor method on Split"]
 pub struct SplitTerminator<'a, P>(CharSplits<'a, P>);
-delegate_iter!{pattern &'a str in SplitTerminator<'a, P>}
+delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
 
 /// Return type of `StrExt::splitn`
 #[derive(Clone)]
 #[stable]
 pub struct SplitN<'a, P>(CharSplitsN<'a, P>);
-delegate_iter!{pattern forward &'a str in SplitN<'a, P>}
+delegate_iter!{pattern forward &'a str : SplitN<'a, P>}
 
 /// Return type of `StrExt::rsplitn`
 #[derive(Clone)]
 #[stable]
 pub struct RSplitN<'a, P>(CharSplitsN<'a, P>);
-delegate_iter!{pattern forward &'a str in RSplitN<'a, P>}
+delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
 
 /// Methods for string slices
 #[allow(missing_docs)]
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 585b338b026..35fb34eafb4 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -737,7 +737,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
 
 fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
     macro_rules! ifn {
-        ($name:expr fn() -> $ret:expr) => (
+        ($name:expr, fn() -> $ret:expr) => (
             if *key == $name {
                 let f = base::decl_cdecl_fn(
                     ccx, $name, Type::func(&[], &$ret),
@@ -746,7 +746,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
                 return Some(f);
             }
         );
-        ($name:expr fn($($arg:expr),*) -> $ret:expr) => (
+        ($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
             if *key == $name {
                 let f = base::decl_cdecl_fn(ccx, $name,
                                   Type::func(&[$($arg),*], &$ret), ty::mk_nil(ccx.tcx()));
@@ -769,111 +769,111 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
     let t_f32 = Type::f32(ccx);
     let t_f64 = Type::f64(ccx);
 
-    ifn!("llvm.memcpy.p0i8.p0i8.i32" fn(i8p, i8p, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memcpy.p0i8.p0i8.i64" fn(i8p, i8p, t_i64, t_i32, i1) -> void);
-    ifn!("llvm.memmove.p0i8.p0i8.i32" fn(i8p, i8p, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memmove.p0i8.p0i8.i64" fn(i8p, i8p, t_i64, t_i32, i1) -> void);
-    ifn!("llvm.memset.p0i8.i32" fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memset.p0i8.i64" fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
-
-    ifn!("llvm.trap" fn() -> void);
-    ifn!("llvm.debugtrap" fn() -> void);
-    ifn!("llvm.frameaddress" fn(t_i32) -> i8p);
-
-    ifn!("llvm.powi.f32" fn(t_f32, t_i32) -> t_f32);
-    ifn!("llvm.powi.f64" fn(t_f64, t_i32) -> t_f64);
-    ifn!("llvm.pow.f32" fn(t_f32, t_f32) -> t_f32);
-    ifn!("llvm.pow.f64" fn(t_f64, t_f64) -> t_f64);
-
-    ifn!("llvm.sqrt.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.sqrt.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.sin.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.sin.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.cos.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.cos.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.exp.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.exp.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.exp2.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.exp2.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.log.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.log.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.log10.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.log10.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.log2.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.log2.f64" fn(t_f64) -> t_f64);
-
-    ifn!("llvm.fma.f32" fn(t_f32, t_f32, t_f32) -> t_f32);
-    ifn!("llvm.fma.f64" fn(t_f64, t_f64, t_f64) -> t_f64);
-
-    ifn!("llvm.fabs.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.fabs.f64" fn(t_f64) -> t_f64);
-
-    ifn!("llvm.floor.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.floor.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.ceil.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.ceil.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.trunc.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.trunc.f64" fn(t_f64) -> t_f64);
-
-    ifn!("llvm.rint.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.rint.f64" fn(t_f64) -> t_f64);
-    ifn!("llvm.nearbyint.f32" fn(t_f32) -> t_f32);
-    ifn!("llvm.nearbyint.f64" fn(t_f64) -> t_f64);
-
-    ifn!("llvm.ctpop.i8" fn(t_i8) -> t_i8);
-    ifn!("llvm.ctpop.i16" fn(t_i16) -> t_i16);
-    ifn!("llvm.ctpop.i32" fn(t_i32) -> t_i32);
-    ifn!("llvm.ctpop.i64" fn(t_i64) -> t_i64);
-
-    ifn!("llvm.ctlz.i8" fn(t_i8 , i1) -> t_i8);
-    ifn!("llvm.ctlz.i16" fn(t_i16, i1) -> t_i16);
-    ifn!("llvm.ctlz.i32" fn(t_i32, i1) -> t_i32);
-    ifn!("llvm.ctlz.i64" fn(t_i64, i1) -> t_i64);
-
-    ifn!("llvm.cttz.i8" fn(t_i8 , i1) -> t_i8);
-    ifn!("llvm.cttz.i16" fn(t_i16, i1) -> t_i16);
-    ifn!("llvm.cttz.i32" fn(t_i32, i1) -> t_i32);
-    ifn!("llvm.cttz.i64" fn(t_i64, i1) -> t_i64);
-
-    ifn!("llvm.bswap.i16" fn(t_i16) -> t_i16);
-    ifn!("llvm.bswap.i32" fn(t_i32) -> t_i32);
-    ifn!("llvm.bswap.i64" fn(t_i64) -> t_i64);
-
-    ifn!("llvm.sadd.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.sadd.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.sadd.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.sadd.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.uadd.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.uadd.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.uadd.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.uadd.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.ssub.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.ssub.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.ssub.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.ssub.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.usub.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.usub.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.usub.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.usub.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.smul.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.smul.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.smul.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.smul.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.umul.with.overflow.i8" fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.umul.with.overflow.i16" fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.umul.with.overflow.i32" fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.umul.with.overflow.i64" fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-
-    ifn!("llvm.lifetime.start" fn(t_i64,i8p) -> void);
-    ifn!("llvm.lifetime.end" fn(t_i64, i8p) -> void);
-
-    ifn!("llvm.expect.i1" fn(i1, i1) -> i1);
-    ifn!("llvm.assume" fn(i1) -> void);
+    ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
+    ifn!("llvm.memcpy.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
+    ifn!("llvm.memmove.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
+    ifn!("llvm.memmove.p0i8.p0i8.i64", fn(i8p, i8p, t_i64, t_i32, i1) -> void);
+    ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
+    ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
+
+    ifn!("llvm.trap", fn() -> void);
+    ifn!("llvm.debugtrap", fn() -> void);
+    ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
+
+    ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
+    ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
+    ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
+    ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
+
+    ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
+
+    ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
+    ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
+
+    ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
+
+    ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
+
+    ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
+    ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.nearbyint.f64", fn(t_f64) -> t_f64);
+
+    ifn!("llvm.ctpop.i8", fn(t_i8) -> t_i8);
+    ifn!("llvm.ctpop.i16", fn(t_i16) -> t_i16);
+    ifn!("llvm.ctpop.i32", fn(t_i32) -> t_i32);
+    ifn!("llvm.ctpop.i64", fn(t_i64) -> t_i64);
+
+    ifn!("llvm.ctlz.i8", fn(t_i8 , i1) -> t_i8);
+    ifn!("llvm.ctlz.i16", fn(t_i16, i1) -> t_i16);
+    ifn!("llvm.ctlz.i32", fn(t_i32, i1) -> t_i32);
+    ifn!("llvm.ctlz.i64", fn(t_i64, i1) -> t_i64);
+
+    ifn!("llvm.cttz.i8", fn(t_i8 , i1) -> t_i8);
+    ifn!("llvm.cttz.i16", fn(t_i16, i1) -> t_i16);
+    ifn!("llvm.cttz.i32", fn(t_i32, i1) -> t_i32);
+    ifn!("llvm.cttz.i64", fn(t_i64, i1) -> t_i64);
+
+    ifn!("llvm.bswap.i16", fn(t_i16) -> t_i16);
+    ifn!("llvm.bswap.i32", fn(t_i32) -> t_i32);
+    ifn!("llvm.bswap.i64", fn(t_i64) -> t_i64);
+
+    ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.sadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.uadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.uadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.uadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.uadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.ssub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.ssub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.ssub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.ssub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.usub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.usub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.usub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.usub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.smul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.smul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.smul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.smul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.umul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+    ifn!("llvm.umul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+    ifn!("llvm.umul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+    ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+
+    ifn!("llvm.lifetime.start", fn(t_i64,i8p) -> void);
+    ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void);
+
+    ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
+    ifn!("llvm.assume", fn(i1) -> void);
 
     // Some intrinsics were introduced in later versions of LLVM, but they have
     // fallbacks in libc or libm and such. Currently, all of these intrinsics
@@ -882,7 +882,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
         ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr) => (
             if unsafe { llvm::LLVMVersionMinor() >= 4 } {
                 // The `if key == $name` is already in ifn!
-                ifn!($name fn($($arg),*) -> $ret);
+                ifn!($name, fn($($arg),*) -> $ret);
             } else if *key == $name {
                 let f = base::decl_cdecl_fn(ccx, stringify!($cname),
                                       Type::func(&[$($arg),*], &$ret),
@@ -900,8 +900,8 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
 
 
     if ccx.sess().opts.debuginfo != NoDebugInfo {
-        ifn!("llvm.dbg.declare" fn(Type::metadata(ccx), Type::metadata(ccx)) -> void);
-        ifn!("llvm.dbg.value" fn(Type::metadata(ccx), t_i64, Type::metadata(ccx)) -> void);
+        ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void);
+        ifn!("llvm.dbg.value", fn(Type::metadata(ccx), t_i64, Type::metadata(ccx)) -> void);
     }
     return None;
 }
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index d80a14422e9..6a04565312d 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -499,7 +499,7 @@ macro_rules! peel {
 /// Evaluates to the number of identifiers passed to it, for example: `count_idents!(a, b, c) == 3
 macro_rules! count_idents {
     () => { 0u };
-    ($_i:ident $(, $rest:ident)*) => { 1 + count_idents!($($rest),*) }
+    ($_i:ident, $($rest:ident),*) => { 1 + count_idents!($($rest),*) }
 }
 
 macro_rules! tuple {
diff --git a/src/libstd/rt/macros.rs b/src/libstd/rt/macros.rs
index bbc96d0b19f..1e3ab6d34da 100644
--- a/src/libstd/rt/macros.rs
+++ b/src/libstd/rt/macros.rs
@@ -14,16 +14,24 @@
 //! they aren't defined anywhere outside of the `rt` module.
 
 macro_rules! rterrln {
-    ($fmt:expr $($arg:tt)*) => ( {
-        ::rt::util::dumb_print(format_args!(concat!($fmt, "\n") $($arg)*))
+    ($fmt:expr) => ( {
+        ::rt::util::dumb_print(format_args!(concat!($fmt, "\n")))
+    } );
+    ($fmt:expr, $($arg:expr),*) => ( {
+        ::rt::util::dumb_print(format_args!(concat!($fmt, "\n"), $($arg)*))
     } )
 }
 
 // Some basic logging. Enabled by passing `--cfg rtdebug` to the libstd build.
 macro_rules! rtdebug {
-    ($($arg:tt)*) => ( {
+    ($arg:expr) => ( {
         if cfg!(rtdebug) {
-            rterrln!($($arg)*)
+            rterrln!($arg)
+        }
+    } );
+    ($str:expr, $($arg:expr),*) => ( {
+        if cfg!(rtdebug) {
+            rterrln!($str, $($arg)*)
         }
     })
 }
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index d4039fd96ff..be44aa99f49 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -88,7 +88,7 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
             while rest.len() > 0 {
                 if rest.starts_with("$") {
                     macro_rules! demangle {
-                        ($($pat:expr => $demangled:expr),*) => ({
+                        ($($pat:expr, => $demangled:expr),*) => ({
                             $(if rest.starts_with($pat) {
                                 try!(writer.write_str($demangled));
                                 rest = rest.slice_from($pat.len());
@@ -103,22 +103,22 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
 
                     // see src/librustc/back/link.rs for these mappings
                     demangle! (
-                        "$SP$" => "@",
-                        "$UP$" => "Box",
-                        "$RP$" => "*",
-                        "$BP$" => "&",
-                        "$LT$" => "<",
-                        "$GT$" => ">",
-                        "$LP$" => "(",
-                        "$RP$" => ")",
-                        "$C$"  => ",",
+                        "$SP$", => "@",
+                        "$UP$", => "Box",
+                        "$RP$", => "*",
+                        "$BP$", => "&",
+                        "$LT$", => "<",
+                        "$GT$", => ">",
+                        "$LP$", => "(",
+                        "$RP$", => ")",
+                        "$C$", => ",",
 
                         // in theory we can demangle any Unicode code point, but
                         // for simplicity we just catch the common ones.
-                        "$u{20}" => " ",
-                        "$u{27}" => "'",
-                        "$u{5b}" => "[",
-                        "$u{5d}" => "]"
+                        "$u{20}", => " ",
+                        "$u{27}", => "'",
+                        "$u{5b}", => "[",
+                        "$u{5d}", => "]"
                     )
                 } else {
                     let idx = match rest.find('$') {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index fdf749e1285..95240cd7a87 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Ident, TtDelimited, TtSequence, TtToken};
+use ast::{TokenTree, TtDelimited, TtSequence, TtToken};
 use ast;
 use codemap::{Span, DUMMY_SP};
 use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
@@ -19,8 +19,8 @@ use ext::tt::macro_parser::{parse, parse_or_else};
 use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
 use parse::parser::Parser;
 use parse::attr::ParserAttr;
-use parse::token::{special_idents, gensym_ident};
-use parse::token::{MatchNt, NtTT};
+use parse::token::{special_idents, gensym_ident, NtTT, Token};
+use parse::token::Token::*;
 use parse::token;
 use print;
 use ptr::P;
@@ -109,8 +109,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
 }
 
 struct MacroRulesMacroExpander {
-    name: Ident,
-    imported_from: Option<Ident>,
+    name: ast::Ident,
+    imported_from: Option<ast::Ident>,
     lhses: Vec<Rc<NamedMatch>>,
     rhses: Vec<Rc<NamedMatch>>,
 }
@@ -134,8 +134,8 @@ impl TTMacroExpander for MacroRulesMacroExpander {
 /// Given `lhses` and `rhses`, this is the new macro we create
 fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                           sp: Span,
-                          name: Ident,
-                          imported_from: Option<Ident>,
+                          name: ast::Ident,
+                          imported_from: Option<ast::Ident>,
                           arg: &[ast::TokenTree],
                           lhses: &[Rc<NamedMatch>],
                           rhses: &[Rc<NamedMatch>])
@@ -261,6 +261,10 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
         _ => cx.span_bug(def.span, "wrong-structured lhs")
     };
 
+    for lhs in lhses.iter() {
+        check_lhs_nt_follows(cx, &**lhs, def.span);
+    }
+
     let rhses = match *argument_map[rhs_nm] {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
         _ => cx.span_bug(def.span, "wrong-structured rhs")
@@ -275,3 +279,176 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
 
     NormalTT(exp, Some(def.span))
 }
+
+fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) {
+    // lhs is going to be like MatchedNonterminal(NtTT(TtDelimited(...))), where
+    // the entire lhs is those tts.
+    // if ever we get box/deref patterns, this could turn into an `if let
+    // &MatchedNonterminal(NtTT(box TtDelimited(...))) = lhs`
+    let matcher = match lhs {
+        &MatchedNonterminal(NtTT(ref inner)) => match &**inner {
+            &TtDelimited(_, ref tts) => tts.tts[],
+            _ => cx.span_bug(sp, "wrong-structured lhs for follow check")
+        },
+        _ => cx.span_bug(sp, "wrong-structured lhs for follow check")
+    };
+
+    check_matcher(cx, matcher.iter(), &Eof);
+    // we don't abort on errors on rejection, the driver will do that for us
+    // after parsing/expansion. we can report every error in every macro this way.
+}
+
+// returns the last token that was checked, for TtSequence. this gets used later on.
+fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
+-> Option<(Span, Token)> where I: Iterator<Item=&'a TokenTree> {
+    use print::pprust::token_to_string;
+
+    let mut last = None;
+
+    // 2. For each token T in M:
+    let mut tokens = matcher.peekable();
+    while let Some(token) = tokens.next() {
+        last = match *token {
+            TtToken(sp, MatchNt(ref name, ref frag_spec, _, _)) => {
+                // ii. If T is a simple NT, look ahead to the next token T' in
+                // M.
+                let next_token = match tokens.peek() {
+                    // If T' closes a complex NT, replace T' with F
+                    Some(&&TtToken(_, CloseDelim(_))) => follow.clone(),
+                    Some(&&TtToken(_, ref tok)) => tok.clone(),
+                    Some(&&TtSequence(sp, _)) => {
+                        cx.span_err(sp, format!("`${0}:{1}` is followed by a sequence \
+                                                 repetition, which is not allowed for `{1}` \
+                                                 fragments", name.as_str(), frag_spec.as_str())[]);
+                        Eof
+                    },
+                    // die next iteration
+                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
+                    // else, we're at the end of the macro or sequence
+                    None => follow.clone()
+                };
+
+                let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
+                // If T' is in the set FOLLOW(NT), continue. Else, reject.
+                match &next_token {
+                    &Eof => return Some((sp, tok.clone())),
+                    _ if is_in_follow(cx, &next_token, frag_spec.as_str()) => continue,
+                    next => {
+                        cx.span_err(sp, format!("`${0}:{1}` is followed by `{2}`, which \
+                                                 is not allowed for `{1}` fragments",
+                                                 name.as_str(), frag_spec.as_str(),
+                                                 token_to_string(next))[]);
+                        continue
+                    },
+                }
+            },
+            TtSequence(sp, ref seq) => {
+                // iii. Else, T is a complex NT.
+                match seq.separator {
+                    // If T has the form $(...)U+ or $(...)U* for some token U,
+                    // run the algorithm on the contents with F set to U. If it
+                    // accepts, continue, else, reject.
+                    Some(ref u) => {
+                        let last = check_matcher(cx, seq.tts.iter(), u);
+                        match last {
+                            // Since the delimiter isn't required after the last repetition, make
+                            // sure that the *next* token is sane. This doesn't actually compute
+                            // the FIRST of the rest of the matcher yet, it only considers single
+                            // tokens and simple NTs. This is imprecise, but conservatively
+                            // correct.
+                            Some((span, tok)) => {
+                                let fol = match tokens.peek() {
+                                    Some(&&TtToken(_, ref tok)) => tok.clone(),
+                                    Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
+                                    Some(_) => {
+                                        cx.span_err(sp, "sequence repetition followed by \
+                                                another sequence repetition, which is not allowed");
+                                        Eof
+                                    },
+                                    None => Eof
+                                };
+                                check_matcher(cx, Some(&TtToken(span, tok.clone())).into_iter(),
+                                              &fol)
+                            },
+                            None => last,
+                        }
+                    },
+                    // If T has the form $(...)+ or $(...)*, run the algorithm on the contents with
+                    // F set to the token following the sequence. If it accepts, continue, else,
+                    // reject.
+                    None => {
+                        let fol = match tokens.peek() {
+                            Some(&&TtToken(_, ref tok)) => tok.clone(),
+                            Some(&&TtDelimited(_, ref delim)) => delim.close_token(),
+                            Some(_) => {
+                                cx.span_err(sp, "sequence repetition followed by another \
+                                             sequence repetition, which is not allowed");
+                                Eof
+                            },
+                            None => Eof
+                        };
+                        check_matcher(cx, seq.tts.iter(), &fol)
+                    }
+                }
+            },
+            TtToken(..) => {
+                // i. If T is not an NT, continue.
+                continue
+            },
+            TtDelimited(_, ref tts) => {
+                // if we don't pass in that close delimiter, we'll incorrectly consider the matcher
+                // `{ $foo:ty }` as having a follow that isn't `RBrace`
+                check_matcher(cx, tts.tts.iter(), &tts.close_token())
+            }
+        }
+    }
+    last
+}
+
+fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool {
+    if let &CloseDelim(_) = tok {
+        return true;
+    }
+
+    match frag {
+        "item" => {
+            // since items *must* be followed by either a `;` or a `}`, we can
+            // accept anything after them
+            true
+        },
+        "block" => {
+            // anything can follow block, the braces provide a easy boundary to
+            // maintain
+            true
+        },
+        "stmt" | "expr"  => {
+            match *tok {
+                FatArrow | Comma | Semi => true,
+                _ => false
+            }
+        },
+        "pat" => {
+            match *tok {
+                FatArrow | Comma | Eq => true,
+                _ => false
+            }
+        },
+        "path" | "ty" => {
+            match *tok {
+                Comma | FatArrow | Colon | Eq | Gt => true,
+                Ident(i, _) if i.as_str() == "as" => true,
+                _ => false
+            }
+        },
+        "ident" => {
+            // being a single token, idents are harmless
+            true
+        },
+        "meta" | "tt" => {
+            // being either a single token or a delimited sequence, tt is
+            // harmless
+            true
+        },
+        _ => cx.bug(format!("unrecognized builtin nonterminal {}", frag)[]),
+    }
+}
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index bdf96104697..013bce1755b 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -392,6 +392,7 @@ impl fmt::Show for Nonterminal {
     }
 }
 
+
 // Get the first "argument"
 macro_rules! first {
     ( $first:expr, $( $remainder:expr, )* ) => ( $first )
diff --git a/src/test/compile-fail/macro-input-future-proofing.rs b/src/test/compile-fail/macro-input-future-proofing.rs
new file mode 100644
index 00000000000..15f6d88fd89
--- /dev/null
+++ b/src/test/compile-fail/macro-input-future-proofing.rs
@@ -0,0 +1,30 @@
+// 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! errors_everywhere {
+    ($ty:ty <) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty`
+    ($ty:ty < foo ,) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty`
+    ($ty:ty , ) => ();
+    ( ( $ty:ty ) ) => ();
+    ( { $ty:ty } ) => ();
+    ( [ $ty:ty ] ) => ();
+    ($bl:block < ) => ();
+    ($pa:pat >) => (); //~ ERROR `$pa:pat` is followed by `>`, which is not allowed for `pat`
+    ($pa:pat , ) => ();
+    ($pa:pat | ) => (); //~ ERROR `$pa:pat` is followed by `|`
+    ($pa:pat $pb:pat $ty:ty ,) => ();
+    //~^ ERROR `$pa:pat` is followed by `$pb:pat`, which is not allowed
+    //~^^ ERROR `$pb:pat` is followed by `$ty:ty`, which is not allowed
+    ($($ty:ty)* -) => (); //~ ERROR `$ty:ty` is followed by `-`
+    ($($a:ty, $b:ty)* -) => (); //~ ERROR `$b:ty` is followed by `-`
+    ($($ty:ty)-+) => (); //~ ERROR `$ty:ty` is followed by `-`, which is not allowed for `ty`
+}
+
+fn main() { }
diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs
index 25c1464adfa..28b346c9ed4 100644
--- a/src/test/run-pass/const-polymorphic-paths.rs
+++ b/src/test/run-pass/const-polymorphic-paths.rs
@@ -29,7 +29,7 @@ fn odd(x: uint) -> bool { x % 2 == 1 }
 fn dummy_rng() -> DummyRng { DummyRng::new_unseeded() }
 
 macro_rules! tests {
-    ($($expr:expr: $ty:ty /($($test:expr),*);)+) => (pub fn main() {$({
+    ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({
         const C: $ty = $expr;
         static S: $ty = $expr;
         assert!(eq(C($($test),*), $expr($($test),*)));
@@ -40,45 +40,44 @@ macro_rules! tests {
 
 tests! {
     // Free function.
-    id: fn(int) -> int /(5);
-    id::<int>: fn(int) -> int /(5);
+    id, fn(int) -> int, (5);
+    id::<int>, fn(int) -> int, (5);
 
     // Enum variant constructor.
-    Some: fn(int) -> Option<int> /(5);
-    Some::<int>: fn(int) -> Option<int> /(5);
+    Some, fn(int) -> Option<int>, (5);
+    Some::<int>, fn(int) -> Option<int>, (5);
 
     // Tuple struct constructor.
-    Newt: fn(int) -> Newt<int> /(5);
-    Newt::<int>: fn(int) -> Newt<int> /(5);
+    Newt, fn(int) -> Newt<int>, (5);
+    Newt::<int>, fn(int) -> Newt<int>, (5);
 
     // Inherent static methods.
-    Vec::new: fn() -> Vec<()> /();
-    Vec::<()>::new: fn() -> Vec<()> /();
-    Vec::with_capacity: fn(uint) -> Vec<()> /(5);
-    Vec::<()>::with_capacity: fn(uint) -> Vec<()> /(5);
-    Bitv::from_fn: fn(uint, fn(uint) -> bool) -> Bitv /(5, odd);
-    Bitv::from_fn::<fn(uint) -> bool>: fn(uint, fn(uint) -> bool) -> Bitv /(5, odd);
+    Vec::new, fn() -> Vec<()>, ();
+    Vec::<()>::new, fn() -> Vec<()>, ();
+    Vec::with_capacity, fn(uint) -> Vec<()>, (5);
+    Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5);
+    Bitv::from_fn, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
+    Bitv::from_fn::<fn(uint) -> bool>, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
 
     // Inherent non-static method.
-    Vec::map_in_place: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-        /(vec![b'f', b'o', b'o'], u8_as_i8);
-    Vec::map_in_place::<i8, fn(u8) -> i8>: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-        /(vec![b'f', b'o', b'o'], u8_as_i8);
+    Vec::map_in_place, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>, (vec![b'f', b'o', b'o'], u8_as_i8);
+    Vec::map_in_place::<i8, fn(u8) -> i8>, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>,
+        (vec![b'f', b'o', b'o'], u8_as_i8);
     // FIXME these break with "type parameter might not appear here pointing at `<u8>`.
     // Vec::<u8>::map_in_place: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-    //     /(vec![b'f', b'o', b'o'], u8_as_i8);
+    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
     // Vec::<u8>::map_in_place::<i8, fn(u8) -> i8>: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-    //     /(vec![b'f', b'o', b'o'], u8_as_i8);
+    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
 
     // Trait static methods.
     // FIXME qualified path expressions aka UFCS i.e. <T as Trait>::method.
-    Default::default: fn() -> int /();
-    Rand::rand: fn(&mut DummyRng) -> int /(&mut dummy_rng());
-    Rand::rand::<DummyRng>: fn(&mut DummyRng) -> int /(&mut dummy_rng());
+    Default::default, fn() -> int, ();
+    Rand::rand, fn(&mut DummyRng) -> int, (&mut dummy_rng());
+    Rand::rand::<DummyRng>, fn(&mut DummyRng) -> int, (&mut dummy_rng());
 
     // Trait non-static methods.
-    Clone::clone: fn(&int) -> int /(&5);
-    FromIterator::from_iter: fn(OptionIter<int>) -> Vec<int> /(Some(5).into_iter());
-    FromIterator::from_iter::<OptionIter<int>>: fn(OptionIter<int>) -> Vec<int>
-        /(Some(5).into_iter());
+    Clone::clone, fn(&int) -> int, (&5);
+    FromIterator::from_iter, fn(OptionIter<int>) -> Vec<int>, (Some(5).into_iter());
+    FromIterator::from_iter::<OptionIter<int>>, fn(OptionIter<int>) -> Vec<int>
+       , (Some(5).into_iter());
 }
diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs
index 9b9a7f68995..0293c4e36ac 100644
--- a/src/test/run-pass/nullable-pointer-iotareduction.rs
+++ b/src/test/run-pass/nullable-pointer-iotareduction.rs
@@ -35,10 +35,10 @@ impl<T> E<T> {
 }
 
 macro_rules! check_option {
-    ($e:expr: $T:ty) => {{
-        check_option!($e: $T, |ptr| assert!(*ptr == $e));
+    ($e:expr, $T:ty) => {{
+        check_option!($e, $T, |ptr| assert!(*ptr == $e));
     }};
-    ($e:expr: $T:ty, |$v:ident| $chk:expr) => {{
+    ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
         assert!(option::Option::None::<$T>.is_none());
         let e = $e;
         let s_ = option::Option::Some::<$T>(e);
@@ -48,10 +48,10 @@ macro_rules! check_option {
 }
 
 macro_rules! check_fancy {
-    ($e:expr: $T:ty) => {{
-        check_fancy!($e: $T, |ptr| assert!(*ptr == $e));
+    ($e:expr, $T:ty) => {{
+        check_fancy!($e, $T, |ptr| assert!(*ptr == $e));
     }};
-    ($e:expr: $T:ty, |$v:ident| $chk:expr) => {{
+    ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
         assert!(E::Nothing::<$T>((), ((), ()), [23i8; 0]).is_none());
         let e = $e;
         let t_ = E::Thing::<$T>(23, e);
@@ -71,12 +71,12 @@ macro_rules! check_type {
 }
 
 pub fn main() {
-    check_type!(&17: &int);
-    check_type!(box 18: Box<int>);
-    check_type!("foo".to_string(): String);
-    check_type!(vec!(20, 22): Vec<int> );
+    check_type!(&17, &int);
+    check_type!(box 18, Box<int>);
+    check_type!("foo".to_string(), String);
+    check_type!(vec!(20, 22), Vec<int> );
     let mint: uint = unsafe { mem::transmute(main) };
-    check_type!(main: fn(), |pthing| {
+    check_type!(main, fn(), |pthing| {
         assert!(mint == unsafe { mem::transmute(*pthing) })
     });
 }