about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNick Cameron <nrc@ncameron.org>2018-07-10 08:34:04 +1200
committerGitHub <noreply@github.com>2018-07-10 08:34:04 +1200
commitfba6b68bf2eee8c47da423a7e1204486eb77b489 (patch)
tree5c798fc1369c19cf6742b328a0188ac96e0b7165 /src
parent4bfd47caac731e3e706b8e8772367927a14dd84e (diff)
parent60ce411b5310c8af09de2d552e67b0593f3f1d4b (diff)
Merge pull request #2836 from topecongiro/async-closure
Format async closure
Diffstat (limited to 'src')
-rw-r--r--src/closures.rs20
-rw-r--r--src/config/mod.rs3
-rw-r--r--src/config/options.rs15
-rw-r--r--src/expr.rs4
-rw-r--r--src/lib.rs2
5 files changed, 33 insertions, 11 deletions
diff --git a/src/closures.rs b/src/closures.rs
index 5f1102a36fc..5e2f01053f1 100644
--- a/src/closures.rs
+++ b/src/closures.rs
@@ -31,9 +31,9 @@ use utils::{last_line_width, left_most_sub_expr, stmt_expr};
 //     statement without needing a semi-colon), then adding or removing braces
 //     can change whether it is treated as an expression or statement.
 
-// FIXME(topecongiro) Format async closures (#2813).
 pub fn rewrite_closure(
     capture: ast::CaptureBy,
+    asyncness: ast::IsAsync,
     movability: ast::Movability,
     fn_decl: &ast::FnDecl,
     body: &ast::Expr,
@@ -43,8 +43,9 @@ pub fn rewrite_closure(
 ) -> Option<String> {
     debug!("rewrite_closure {:?}", body);
 
-    let (prefix, extra_offset) =
-        rewrite_closure_fn_decl(capture, movability, fn_decl, body, span, context, shape)?;
+    let (prefix, extra_offset) = rewrite_closure_fn_decl(
+        capture, asyncness, movability, fn_decl, body, span, context, shape,
+    )?;
     // 1 = space between `|...|` and body.
     let body_shape = shape.offset_left(extra_offset)?;
 
@@ -198,6 +199,7 @@ fn rewrite_closure_block(
 // Return type is (prefix, extra_offset)
 fn rewrite_closure_fn_decl(
     capture: ast::CaptureBy,
+    asyncness: ast::IsAsync,
     movability: ast::Movability,
     fn_decl: &ast::FnDecl,
     body: &ast::Expr,
@@ -205,12 +207,12 @@ fn rewrite_closure_fn_decl(
     context: &RewriteContext,
     shape: Shape,
 ) -> Option<(String, usize)> {
+    let is_async = if asyncness.is_async() { "async " } else { "" };
     let mover = if capture == ast::CaptureBy::Value {
         "move "
     } else {
         ""
     };
-
     let immovable = if movability == ast::Movability::Static {
         "static "
     } else {
@@ -219,7 +221,7 @@ fn rewrite_closure_fn_decl(
     // 4 = "|| {".len(), which is overconservative when the closure consists of
     // a single expression.
     let nested_shape = shape
-        .shrink_left(mover.len() + immovable.len())?
+        .shrink_left(is_async.len() + mover.len() + immovable.len())?
         .sub_width(4)?;
 
     // 1 = |
@@ -265,7 +267,7 @@ fn rewrite_closure_fn_decl(
         config: context.config,
     };
     let list_str = write_list(&item_vec, &fmt)?;
-    let mut prefix = format!("{}{}|{}|", immovable, mover, list_str);
+    let mut prefix = format!("{}{}{}|{}|", is_async, immovable, mover, list_str);
 
     if !ret_str.is_empty() {
         if prefix.contains('\n') {
@@ -289,7 +291,9 @@ pub fn rewrite_last_closure(
     expr: &ast::Expr,
     shape: Shape,
 ) -> Option<String> {
-    if let ast::ExprKind::Closure(capture, _, movability, ref fn_decl, ref body, _) = expr.node {
+    if let ast::ExprKind::Closure(capture, asyncness, movability, ref fn_decl, ref body, _) =
+        expr.node
+    {
         let body = match body.node {
             ast::ExprKind::Block(ref block, _)
                 if !is_unsafe_block(block)
@@ -300,7 +304,7 @@ pub fn rewrite_last_closure(
             _ => body,
         };
         let (prefix, extra_offset) = rewrite_closure_fn_decl(
-            capture, movability, fn_decl, body, expr.span, context, shape,
+            capture, asyncness, movability, fn_decl, body, expr.span, context, shape,
         )?;
         // If the closure goes multi line before its body, do not overflow the closure.
         if prefix.contains('\n') {
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 71bdefeea79..fcda529ea89 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -104,6 +104,7 @@ create_config! {
         "Maximum number of blank lines which can be put between items.";
     blank_lines_lower_bound: usize, 0, false,
         "Minimum number of blank lines which must be put between items.";
+    edition: Edition, Edition::Edition2015, false, "The edition of the parser. (RFC 2052)";
 
     // Options that can change the source code beyond whitespace/blocks (somewhat linty things)
     merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one";
@@ -111,7 +112,7 @@ create_config! {
     use_field_init_shorthand: bool, false, true, "Use field initialization shorthand if possible";
     force_explicit_abi: bool, true, true, "Always print the abi for extern items";
     condense_wildcard_suffixes: bool, false, false, "Replace strings of _ wildcards by a single .. \
-                                              in tuple patterns";
+                                                     in tuple patterns";
 
     // Control options (changes the operation of rustfmt, rather than the formatting)
     color: Color, Color::Auto, false,
diff --git a/src/config/options.rs b/src/config/options.rs
index b3599c230f4..5fa0a048313 100644
--- a/src/config/options.rs
+++ b/src/config/options.rs
@@ -340,3 +340,18 @@ pub trait CliOptions {
     fn apply_to(self, config: &mut Config);
     fn config_path(&self) -> Option<&Path>;
 }
+
+/// The edition of the compiler (RFC 2052)
+configuration_option_enum!{ Edition:
+    Edition2015,
+    Edition2018,
+}
+
+impl Edition {
+    pub(crate) fn to_libsyntax_pos_edition(&self) -> syntax_pos::edition::Edition {
+        match self {
+            Edition::Edition2015 => syntax_pos::edition::Edition::Edition2015,
+            Edition::Edition2018 => syntax_pos::edition::Edition::Edition2018,
+        }
+    }
+}
diff --git a/src/expr.rs b/src/expr.rs
index ca31b0b82ef..6928b77f360 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -183,9 +183,9 @@ pub fn format_expr(
         } else {
             Some("yield".to_string())
         },
-        ast::ExprKind::Closure(capture, _, movability, ref fn_decl, ref body, _) => {
+        ast::ExprKind::Closure(capture, asyncness, movability, ref fn_decl, ref body, _) => {
             closures::rewrite_closure(
-                capture, movability, fn_decl, body, expr.span, context, shape,
+                capture, asyncness, movability, fn_decl, body, expr.span, context, shape,
             )
         }
         ast::ExprKind::Try(..) | ast::ExprKind::Field(..) | ast::ExprKind::MethodCall(..) => {
diff --git a/src/lib.rs b/src/lib.rs
index 114e72c4847..817ed426e52 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,6 +33,7 @@ extern crate serde;
 extern crate serde_derive;
 extern crate serde_json;
 extern crate syntax;
+extern crate syntax_pos;
 extern crate toml;
 extern crate unicode_segmentation;
 
@@ -793,6 +794,7 @@ fn format_input_inner<T: Write>(
     config: &Config,
     mut out: Option<&mut T>,
 ) -> Result<(Summary, FileMap, FormatReport), (ErrorKind, Summary)> {
+    syntax_pos::hygiene::set_default_edition(config.edition().to_libsyntax_pos_edition());
     let mut summary = Summary::default();
     if config.disable_all_formatting() {
         // When the input is from stdin, echo back the input.