Skip to content

Commit

Permalink
Remove never option in argument position
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Aug 19, 2019
1 parent 96e0134 commit b4e31cc
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 109 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

* Renamed `#[rec]` to `#[nested]`.

* [Removed `never` option in argument position in favor of `#[enum_derive]` attribute.][48]

* Added `"ops"` crate feature, and made `[std|core]::ops`'s `Deref`, `DerefMut`, `Index`, `IndexMut`, and `RangeBounds` traits optional.

* Added `"convert"` crate feature, and made `[std|core]::convert`'s `AsRef` and `AsMut` traits optional.
Expand All @@ -14,6 +16,8 @@

* Improved error messages.

[48]: https://github.com/taiki-e/auto_enums/pull/48

# 0.5.10 - 2019-08-15

* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
Expand Down
31 changes: 9 additions & 22 deletions core/src/auto_enum/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,38 +74,25 @@ macro_rules! error {
};
}

pub(super) fn parse_group(group: TokenStream) -> Result<(Vec<Arg>, Option<String>, bool)> {
pub(super) fn parse_group(group: TokenStream) -> Result<(Vec<Arg>, Option<String>)> {
syn::parse2::<Group>(group).and_then(|group| parse_args(group.stream()))
}

pub(super) fn parse_args(args: TokenStream) -> Result<(Vec<Arg>, Option<String>, bool)> {
pub(super) fn parse_args(args: TokenStream) -> Result<(Vec<Arg>, Option<String>)> {
const ERR: &str = "expected one of `,`, `::`, or identifier, found ";

let mut iter = args.into_iter();
let mut args = Vec::new();
let mut marker = None;
let mut never = false;
while let Some(tt) = iter.next() {
match tt {
TokenTree::Ident(i) => match &*i.to_string() {
"marker" => marker_opt(i, &mut iter, &mut args, &mut marker)?,
"never" => {
match iter.next() {
None => {}
Some(TokenTree::Punct(ref p)) if p.as_char() == ',' => {}
tt => {
args.push(path_or_ident(i, tt, &mut iter)?);
continue;
}
}

if never {
error!(i, "multiple `never` option")
}
never = true;
TokenTree::Ident(i) => {
if i == "marker" {
marker_opt(i, &mut iter, &mut args, &mut marker)?;
} else {
args.push(path_or_ident(i, iter.next(), &mut iter)?);
}
_ => args.push(path_or_ident(i, iter.next(), &mut iter)?),
},
}
TokenTree::Punct(p) => match p.as_char() {
',' => {}
':' => args.push(parse_path(vec![p.into()], &mut iter)?),
Expand All @@ -115,7 +102,7 @@ pub(super) fn parse_args(args: TokenStream) -> Result<(Vec<Arg>, Option<String>,
}
}

Ok((args, marker, never))
Ok((args, marker))
}

fn parse_path(mut path: Vec<TokenTree>, iter: &mut IntoIter) -> Result<Arg> {
Expand Down
26 changes: 7 additions & 19 deletions core/src/auto_enum/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(super) enum VisitLastMode {
item_fn: `fn _() -> Fn*() { || {} }`
*/
Closure,
/// `Stmt::Semi(..)` or `never` option - never visit last expr
/// `Stmt::Semi(..)` - never visit last expr
Never,
}

Expand All @@ -63,13 +63,7 @@ pub(super) struct Context {
}

impl Context {
fn new(
span: impl ToTokens,
args: Vec<Arg>,
marker: Option<String>,
never: bool,
root: bool,
) -> Self {
fn new(span: impl ToTokens, args: Vec<Arg>, marker: Option<String>, root: bool) -> Self {
Self {
span: Some(span.into_token_stream()),
args,
Expand All @@ -78,24 +72,18 @@ impl Context {
// depth: 0,
root,
visit_mode: VisitMode::Default,
visit_last_mode: if never { VisitLastMode::Never } else { VisitLastMode::Default },
visit_last_mode: VisitLastMode::Default,
other_attr: false,
error: false,
}
}

pub(super) fn root(
span: impl ToTokens,
(args, marker, never): (Vec<Arg>, Option<String>, bool),
) -> Self {
Self::new(span, args, marker, never, true)
pub(super) fn root(span: impl ToTokens, (args, marker): (Vec<Arg>, Option<String>)) -> Self {
Self::new(span, args, marker, true)
}

pub(super) fn child(
span: impl ToTokens,
(args, marker, never): (Vec<Arg>, Option<String>, bool),
) -> Self {
Self::new(span, args, marker, never, false)
pub(super) fn child(span: impl ToTokens, (args, marker): (Vec<Arg>, Option<String>)) -> Self {
Self::new(span, args, marker, false)
}

pub(super) fn span(&mut self) -> TokenStream {
Expand Down
22 changes: 0 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,28 +469,6 @@
//! # fn main() { let _ = foo(0); }
//! ```
//!
//! You can also skip all branches by `never` option.
//!
//! ```rust
//! # #![cfg_attr(feature = "try_trait", feature(try_trait))]
//! # use auto_enums::auto_enum;
//! #[auto_enum(never, Iterator)]
//! fn foo(x: i32) -> impl Iterator<Item = i32> {
//! match x {
//! 0 => loop {
//! return marker!(1..10);
//! },
//! 1 => loop {
//! panic!()
//! },
//! _ => loop {
//! return marker!(vec![5, 10].into_iter());
//! },
//! }
//! }
//! # fn main() { let _ = foo(0); }
//! ```
//!
//! ### Expression level marker (`marker!` macro)
//!
//! `#[auto_enum]` replaces `marker!` macros with variants.
Expand Down
13 changes: 0 additions & 13 deletions tests/auto_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,19 +647,6 @@ fn nightly() {
assert_eq!(iter.sum::<i32>(), *x);
}

// never opt
for (i, x) in ANS.iter().enumerate() {
#[auto_enum(never, Iterator)]
let iter = match i {
0 => marker!(1..8),
5..=10 => loop {
panic!()
},
_ => marker!(vec![1, 2, 0].into_iter()),
};
assert_eq!(iter.sum::<i32>(), *x);
}

// never attr
for (i, x) in ANS.iter().enumerate() {
#[rustfmt::skip]
Expand Down
8 changes: 0 additions & 8 deletions tests/ui/auto_enum/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ fn unexpected_token_2(x: usize) -> impl Iterator<Item = i32> {
mod marker {
use auto_enums::auto_enum;

#[auto_enum(never, never, Iterator)] //~ ERROR multiple `never` option
fn multiple_never(x: usize) -> impl Iterator<Item = i32> {
match x {
0 => 1..=8,
_ => 0..2,
}
}

#[auto_enum(marker{f}, Iterator)] //~ ERROR invalid delimiter
fn marker_invalid_delimiter_1(x: usize) -> impl Iterator<Item = i32> {
match x {
Expand Down
44 changes: 19 additions & 25 deletions tests/ui/auto_enum/args.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,65 +10,59 @@ error: expected one of `,`, `::`, or identifier, found `;`
16 | #[auto_enum(Iterator,;)] //~ ERROR expected one of `,`, `::`, or identifier, found `;`
| ^

error: multiple `never` option
--> $DIR/args.rs:27:24
|
27 | #[auto_enum(never, never, Iterator)] //~ ERROR multiple `never` option
| ^^^^^

error: invalid delimiter
--> $DIR/args.rs:35:23
--> $DIR/args.rs:27:23
|
35 | #[auto_enum(marker{f}, Iterator)] //~ ERROR invalid delimiter
27 | #[auto_enum(marker{f}, Iterator)] //~ ERROR invalid delimiter
| ^^^

error: invalid delimiter
--> $DIR/args.rs:43:23
--> $DIR/args.rs:35:23
|
43 | #[auto_enum(marker[f], Iterator)] //~ ERROR invalid delimiter
35 | #[auto_enum(marker[f], Iterator)] //~ ERROR invalid delimiter
| ^^^

error: multiple `marker` option
--> $DIR/args.rs:51:35
--> $DIR/args.rs:43:35
|
51 | #[auto_enum(marker(f), marker(g), Iterator)] //~ ERROR multiple `marker` option
43 | #[auto_enum(marker(f), marker(g), Iterator)] //~ ERROR multiple `marker` option
| ^

error: empty `marker` option
--> $DIR/args.rs:59:23
--> $DIR/args.rs:51:23
|
59 | #[auto_enum(marker(), Iterator)] //~ ERROR empty `marker` option
51 | #[auto_enum(marker(), Iterator)] //~ ERROR empty `marker` option
| ^^

error: multiple identifier in `marker` option
--> $DIR/args.rs:67:27
--> $DIR/args.rs:59:27
|
67 | #[auto_enum(marker(f, g), Iterator)] //~ ERROR multiple identifier in `marker` option
59 | #[auto_enum(marker(f, g), Iterator)] //~ ERROR multiple identifier in `marker` option
| ^

error: multiple identifier in `marker` option
--> $DIR/args.rs:75:26
--> $DIR/args.rs:67:26
|
75 | #[auto_enum(marker(f t), Iterator)] //~ ERROR multiple identifier in `marker` option
67 | #[auto_enum(marker(f t), Iterator)] //~ ERROR multiple identifier in `marker` option
| ^

error: multiple `marker` option
--> $DIR/args.rs:83:34
--> $DIR/args.rs:75:34
|
83 | #[auto_enum(marker=f, marker=g, Iterator)] //~ ERROR multiple `marker` option
75 | #[auto_enum(marker=f, marker=g, Iterator)] //~ ERROR multiple `marker` option
| ^

error: expected an identifier, found `,`
--> $DIR/args.rs:91:24
--> $DIR/args.rs:83:24
|
91 | #[auto_enum(marker=, Iterator)] //~ ERROR empty `marker` option
83 | #[auto_enum(marker=, Iterator)] //~ ERROR empty `marker` option
| ^

error: expected `,`, found `t`
--> $DIR/args.rs:99:26
--> $DIR/args.rs:91:26
|
99 | #[auto_enum(marker=f t, Iterator)] //~ ERROR expected `,`, found `t`
91 | #[auto_enum(marker=f t, Iterator)] //~ ERROR expected `,`, found `t`
| ^

error: aborting due to 12 previous errors
error: aborting due to 11 previous errors

0 comments on commit b4e31cc

Please sign in to comment.