Skip to content

Commit 2fb6bd3

Browse files
authored
Merge pull request #2400 from csmoe/support_immovable_generators
Support immovable generators
2 parents ba3dec2 + 28bb16a commit 2fb6bd3

File tree

6 files changed

+93
-58
lines changed

6 files changed

+93
-58
lines changed

Cargo.lock

+31-31
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ env_logger = "0.4"
4444
getopts = "0.2"
4545
derive-new = "0.5"
4646
cargo_metadata = "0.4"
47-
rustc-ap-syntax = "12.0.0"
48-
rustc-ap-rustc_errors = "12.0.0"
47+
rustc-ap-syntax = "26.0.0"
48+
rustc-ap-rustc_errors = "26.0.0"
4949

5050
[dev-dependencies]
5151
lazy_static = "1.0.0"

src/closures.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use utils::{last_line_width, left_most_sub_expr, stmt_expr};
3333

3434
pub fn rewrite_closure(
3535
capture: ast::CaptureBy,
36+
movability: ast::Movability,
3637
fn_decl: &ast::FnDecl,
3738
body: &ast::Expr,
3839
span: Span,
@@ -42,7 +43,7 @@ pub fn rewrite_closure(
4243
debug!("rewrite_closure {:?}", body);
4344

4445
let (prefix, extra_offset) =
45-
rewrite_closure_fn_decl(capture, fn_decl, body, span, context, shape)?;
46+
rewrite_closure_fn_decl(capture, movability, fn_decl, body, span, context, shape)?;
4647
// 1 = space between `|...|` and body.
4748
let body_shape = shape.offset_left(extra_offset)?;
4849

@@ -194,6 +195,7 @@ fn rewrite_closure_block(
194195
// Return type is (prefix, extra_offset)
195196
fn rewrite_closure_fn_decl(
196197
capture: ast::CaptureBy,
198+
movability: ast::Movability,
197199
fn_decl: &ast::FnDecl,
198200
body: &ast::Expr,
199201
span: Span,
@@ -205,9 +207,17 @@ fn rewrite_closure_fn_decl(
205207
} else {
206208
""
207209
};
210+
211+
let immovable = if movability == ast::Movability::Static {
212+
"static "
213+
} else {
214+
""
215+
};
208216
// 4 = "|| {".len(), which is overconservative when the closure consists of
209217
// a single expression.
210-
let nested_shape = shape.shrink_left(mover.len())?.sub_width(4)?;
218+
let nested_shape = shape
219+
.shrink_left(mover.len() + immovable.len())?
220+
.sub_width(4)?;
211221

212222
// 1 = |
213223
let argument_offset = nested_shape.indent + 1;
@@ -254,7 +264,7 @@ fn rewrite_closure_fn_decl(
254264
config: context.config,
255265
};
256266
let list_str = write_list(&item_vec, &fmt)?;
257-
let mut prefix = format!("{}|{}|", mover, list_str);
267+
let mut prefix = format!("{}{}|{}|", immovable, mover, list_str);
258268

259269
if !ret_str.is_empty() {
260270
if prefix.contains('\n') {
@@ -278,7 +288,7 @@ pub fn rewrite_last_closure(
278288
expr: &ast::Expr,
279289
shape: Shape,
280290
) -> Option<String> {
281-
if let ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) = expr.node {
291+
if let ast::ExprKind::Closure(capture, movability, ref fn_decl, ref body, _) = expr.node {
282292
let body = match body.node {
283293
ast::ExprKind::Block(ref block)
284294
if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
@@ -287,8 +297,15 @@ pub fn rewrite_last_closure(
287297
}
288298
_ => body,
289299
};
290-
let (prefix, extra_offset) =
291-
rewrite_closure_fn_decl(capture, fn_decl, body, expr.span, context, shape)?;
300+
let (prefix, extra_offset) = rewrite_closure_fn_decl(
301+
capture,
302+
movability,
303+
fn_decl,
304+
body,
305+
expr.span,
306+
context,
307+
shape,
308+
)?;
292309
// If the closure goes multi line before its body, do not overflow the closure.
293310
if prefix.contains('\n') {
294311
return None;

src/expr.rs

+23-19
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,16 @@ pub fn format_expr(
135135
ast::ExprKind::AssignOp(ref op, ref lhs, ref rhs) => {
136136
rewrite_assignment(context, lhs, rhs, Some(op), shape)
137137
}
138-
ast::ExprKind::Continue(ref opt_ident) => {
139-
let id_str = match *opt_ident {
140-
Some(ident) => format!(" {}", ident.node),
138+
ast::ExprKind::Continue(ref opt_label) => {
139+
let id_str = match *opt_label {
140+
Some(label) => format!(" {}", label.ident),
141141
None => String::new(),
142142
};
143143
Some(format!("continue{}", id_str))
144144
}
145-
ast::ExprKind::Break(ref opt_ident, ref opt_expr) => {
146-
let id_str = match *opt_ident {
147-
Some(ident) => format!(" {}", ident.node),
145+
ast::ExprKind::Break(ref opt_label, ref opt_expr) => {
146+
let id_str = match *opt_label {
147+
Some(label) => format!(" {}", label.ident),
148148
None => String::new(),
149149
};
150150

@@ -159,8 +159,16 @@ pub fn format_expr(
159159
} else {
160160
Some("yield".to_string())
161161
},
162-
ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
163-
closures::rewrite_closure(capture, fn_decl, body, expr.span, context, shape)
162+
ast::ExprKind::Closure(capture, movability, ref fn_decl, ref body, _) => {
163+
closures::rewrite_closure(
164+
capture,
165+
movability,
166+
fn_decl,
167+
body,
168+
expr.span,
169+
context,
170+
shape,
171+
)
164172
}
165173
ast::ExprKind::Try(..)
166174
| ast::ExprKind::Field(..)
@@ -718,7 +726,7 @@ struct ControlFlow<'a> {
718726
cond: Option<&'a ast::Expr>,
719727
block: &'a ast::Block,
720728
else_block: Option<&'a ast::Expr>,
721-
label: Option<ast::SpannedIdent>,
729+
label: Option<ast::Label>,
722730
pat: Option<&'a ast::Pat>,
723731
keyword: &'a str,
724732
matcher: &'a str,
@@ -795,11 +803,7 @@ impl<'a> ControlFlow<'a> {
795803
}
796804
}
797805

798-
fn new_loop(
799-
block: &'a ast::Block,
800-
label: Option<ast::SpannedIdent>,
801-
span: Span,
802-
) -> ControlFlow<'a> {
806+
fn new_loop(block: &'a ast::Block, label: Option<ast::Label>, span: Span) -> ControlFlow<'a> {
803807
ControlFlow {
804808
cond: None,
805809
block: block,
@@ -819,7 +823,7 @@ impl<'a> ControlFlow<'a> {
819823
pat: Option<&'a ast::Pat>,
820824
cond: &'a ast::Expr,
821825
block: &'a ast::Block,
822-
label: Option<ast::SpannedIdent>,
826+
label: Option<ast::Label>,
823827
span: Span,
824828
) -> ControlFlow<'a> {
825829
ControlFlow {
@@ -844,7 +848,7 @@ impl<'a> ControlFlow<'a> {
844848
pat: &'a ast::Pat,
845849
cond: &'a ast::Expr,
846850
block: &'a ast::Block,
847-
label: Option<ast::SpannedIdent>,
851+
label: Option<ast::Label>,
848852
span: Span,
849853
) -> ControlFlow<'a> {
850854
ControlFlow {
@@ -1166,9 +1170,9 @@ impl<'a> Rewrite for ControlFlow<'a> {
11661170
}
11671171
}
11681172

1169-
fn rewrite_label(label: Option<ast::SpannedIdent>) -> Cow<'static, str> {
1170-
match label {
1171-
Some(ident) => Cow::from(format!("{}: ", ident.node)),
1173+
fn rewrite_label(opt_label: Option<ast::Label>) -> Cow<'static, str> {
1174+
match opt_label {
1175+
Some(label) => Cow::from(format!("{}: ", label.ident)),
11721176
None => Cow::from(""),
11731177
}
11741178
}

tests/source/immovable_generators.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(generators)]
2+
3+
unsafe fn foo() {
4+
let mut ga = static || {
5+
yield 1;
6+
};
7+
}

tests/target/immovable_generators.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(generators)]
2+
3+
unsafe fn foo() {
4+
let mut ga = static || {
5+
yield 1;
6+
};
7+
}

0 commit comments

Comments
 (0)