-
-
Notifications
You must be signed in to change notification settings - Fork 12
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
Move handling of #[nested] to Visitor #67
Conversation
596d503
to
d8fddc9
Compare
dc4d96f
to
518e1b6
Compare
bors r+ |
67: Move handling of #[nested] to Visitor r=taiki-e a=taiki-e In the current implementation, enum is generated for each `#[auto_enum]` and `#[nested]` is only effective on the last expression of each branch. This PR changes `#[nested]` to be applicable to all branches in each branch. `#[nested]` can be used basically in the same place as `#[auto_enum]`, except that `#[nested]` cannot be used in functions. ### Examples ```rust #[auto_enum(Iterator)] let z = if x { #[nested] let z = if y { iter.map(|i| /* do something */) } else { iter.flat_map(|i| /* do something */) }; // do something z } else { std::iter::empty() } ``` ```rust #[auto_enum(Iterator)] let z = if x { #[nested] let z = match y { Some(iter) => iter.flat_map(|i| /* do something */), None => make_new_iter().map(|i| /* do something */), }; // do something z } else { std::iter::empty() } ``` Closes #64 70: Enable std::future::Future support only in 1.36 or later r=taiki-e a=taiki-e Co-authored-by: Taiki Endo <te316e89@gmail.com>
Build succeeded
|
@taiki-e Thanks! Does this mean that no matter how many nested levels there are ( |
Yeah, For example, the example in description of this PR generates the following code: let z = {
// 1 enum with 3 variants is generated.
enum Enum<V1, V2, V3> {
V1(V1),
V2(V2),
V3(V3),
}
// impl<V1, V2, V3> Iterator for Enum<V1, V2, V3> { ...
if x {
// If #[nested] is contained in a branch, the generation of
// a variant that wrap this entire branch is skipped.
let z = if y {
// Instead, each branch of the expression that #[nested]
// is used is wrapped with a variant.
Enum::V2(iter.map(|i| /* ... */))
} else {
Enum::V3(iter.flat_map(|i| /* ... */))
};
z
} else {
// Expressions that do not contain #[nested] are wrapped directly.
Enum::V1(std::iter::empty())
}
} Also, if there is extra wrapping such as the following code, a compilation error will occur. match e {
0 => Enum::A(0_u8),
_ => Enum::B(match e {
1 => Enum::C(0_u16),
_ => Enum::D(0_u32),
}),
} |
In the current implementation, enum is generated for each
#[auto_enum]
and#[nested]
is only effective on the last expression of each branch. This PR changes#[nested]
to be applicable to all branches in each branch.#[nested]
can be used basically in the same place as#[auto_enum]
, except that#[nested]
cannot be used in functions.Examples
Closes #64