Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macro input future proofing #20563

Merged
merged 5 commits into from
Jan 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions src/doc/guide-macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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) }
Expand Down Expand Up @@ -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) }
Expand All @@ -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 ),*
)
}
Expand All @@ -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 ),*
);
)
Expand All @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,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.
Expand Down
21 changes: 10 additions & 11 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,16 @@ 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 {
self.0.len()
}
}
};
($te:ty in $ti:ty) => {
($te:ty : $ti:ty) => {
#[stable]
impl<'a> Iterator for $ti {
type Item = $te;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -1165,25 +1164,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)]
Expand Down
Loading