]> git.lizzy.rs Git - rust.git/blobdiff - src/items.rs
Merge pull request #3472 from devinalvaro/add-print-current-config
[rust.git] / src / items.rs
index 818cf5d6c911918ddf1f0ba11f219da8aefd883a..8cd6010f72f43fa531f04fe4973e58831e790877 100644 (file)
@@ -1,13 +1,3 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
 // Formatting top-level items - functions, structs, enums, traits, impls.
 
 use std::borrow::Cow;
@@ -29,9 +19,7 @@
     format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with,
     ExprType, RhsTactics,
 };
-use crate::lists::{
-    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
-};
+use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
 use crate::macros::{rewrite_macro, MacroPosition};
 use crate::overflow;
 use crate::rewrite::{Rewrite, RewriteContext};
@@ -203,7 +191,7 @@ pub fn from_method_sig(
     ) -> FnSig<'a> {
         FnSig {
             unsafety: method_sig.header.unsafety,
-            is_async: method_sig.header.asyncness,
+            is_async: method_sig.header.asyncness.node,
             constness: method_sig.header.constness.node,
             defaultness: ast::Defaultness::Final,
             abi: method_sig.header.abi,
@@ -225,7 +213,7 @@ pub fn from_fn_kind(
                 generics,
                 abi: fn_header.abi,
                 constness: fn_header.constness.node,
-                is_async: fn_header.asyncness,
+                is_async: fn_header.asyncness.node,
                 defaultness,
                 unsafety: fn_header.unsafety,
                 visibility: visibility.clone(),
@@ -715,7 +703,7 @@ pub fn format_impl(
             false,
         )?;
 
-        // If there is no where clause, we may have missing comments between the trait name and
+        // If there is no where-clause, we may have missing comments between the trait name and
         // the opening brace.
         if generics.where_clause.predicates.is_empty() {
             if let Some(hi) = where_span_end {
@@ -737,7 +725,7 @@ pub fn format_impl(
             result.push_str(&where_clause_str);
             if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) {
                 // if the where_clause contains extra comments AND
-                // there is only one where clause predicate
+                // there is only one where-clause predicate
                 // recover the suppressed comma in single line where_clause formatting
                 if generics.where_clause.predicates.len() == 1 {
                     result.push_str(",");
@@ -868,7 +856,7 @@ fn format_impl_ref_and_type(
         // ` for`
         let trait_ref_overhead = if trait_ref.is_some() { 4 } else { 0 };
         let curly_brace_overhead = if generics.where_clause.predicates.is_empty() {
-            // If there is no where clause adapt budget for type formatting to take space and curly
+            // If there is no where-clause adapt budget for type formatting to take space and curly
             // brace into account.
             match context.config.brace_style() {
                 BraceStyle::AlwaysNextLine => 0,
@@ -1047,7 +1035,7 @@ pub fn format_trait(
             )?;
         }
 
-        // Rewrite where clause.
+        // Rewrite where-clause.
         if !generics.where_clause.predicates.is_empty() {
             let where_density = if context.config.indent_style() == IndentStyle::Block {
                 Density::Compressed
@@ -1074,8 +1062,8 @@ pub fn format_trait(
                 option,
                 false,
             )?;
-            // If the where clause cannot fit on the same line,
-            // put the where clause on a new line
+            // If the where-clause cannot fit on the same line,
+            // put the where-clause on a new line
             if !where_clause_str.contains('\n')
                 && last_line_width(&result) + where_clause_str.len() + offset.width()
                     > context.config.comment_width()
@@ -1426,8 +1414,8 @@ fn format_tuple_struct(
             || offset.block_indent + result.len() + where_clause_str.len() + 1
                 > context.config.max_width())
     {
-        // We need to put the where clause on a new line, but we didn't
-        // know that earlier, so the where clause will not be indented properly.
+        // We need to put the where-clause on a new line, but we didn't
+        // know that earlier, so the where-clause will not be indented properly.
         result.push('\n');
         result.push_str(
             &(offset.block_only() + (context.config.tab_spaces() - 1)).to_string(context.config),
@@ -1842,7 +1830,9 @@ fn is_empty_infer(ty: &ast::Ty, pat_span: Span) -> bool {
 
 impl Rewrite for ast::Arg {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        if is_named_arg(self) {
+        if let Some(ref explicit_self) = self.to_self() {
+            rewrite_explicit_self(context, explicit_self)
+        } else if is_named_arg(self) {
             let mut result = self
                 .pat
                 .rewrite(context, Shape::legacy(shape.width, shape.indent))?;
@@ -1871,9 +1861,8 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
 }
 
 fn rewrite_explicit_self(
-    explicit_self: &ast::ExplicitSelf,
-    args: &[ast::Arg],
     context: &RewriteContext<'_>,
+    explicit_self: &ast::ExplicitSelf,
 ) -> Option<String> {
     match explicit_self.node {
         ast::SelfKind::Region(lt, m) => {
@@ -1889,10 +1878,7 @@ fn rewrite_explicit_self(
                 None => Some(format!("&{}self", mut_str)),
             }
         }
-        ast::SelfKind::Explicit(ref ty, _) => {
-            assert!(!args.is_empty(), "&[ast::Arg] shouldn't be empty.");
-
-            let mutability = explicit_self_mutability(&args[0]);
+        ast::SelfKind::Explicit(ref ty, mutability) => {
             let type_str = ty.rewrite(
                 context,
                 Shape::legacy(context.config.max_width(), Indent::empty()),
@@ -1904,23 +1890,7 @@ fn rewrite_explicit_self(
                 type_str
             ))
         }
-        ast::SelfKind::Value(_) => {
-            assert!(!args.is_empty(), "&[ast::Arg] shouldn't be empty.");
-
-            let mutability = explicit_self_mutability(&args[0]);
-
-            Some(format!("{}self", format_mutability(mutability)))
-        }
-    }
-}
-
-// Hacky solution caused by absence of `Mutability` in `SelfValue` and
-// `SelfExplicit` variants of `ast::ExplicitSelf_`.
-fn explicit_self_mutability(arg: &ast::Arg) -> ast::Mutability {
-    if let ast::PatKind::Ident(ast::BindingMode::ByValue(mutability), _, _) = arg.pat.node {
-        mutability
-    } else {
-        unreachable!()
+        ast::SelfKind::Value(mutability) => Some(format!("{}self", format_mutability(mutability))),
     }
 }
 
@@ -2057,14 +2027,12 @@ fn rewrite_fn_base(
     let arg_str = rewrite_args(
         context,
         &fd.inputs,
-        fd.get_self().as_ref(),
         one_line_budget,
         multi_line_budget,
         indent,
         arg_indent,
         args_span,
-        fd.variadic,
-        generics_str.contains('\n'),
+        fd.c_variadic,
     )?;
 
     let put_args_in_block = match context.config.indent_style() {
@@ -2122,7 +2090,7 @@ fn rewrite_fn_base(
                 // the closing parenthesis of the argument and the arrow '->' is considered.
                 let mut sig_length = result.len() + indent.width() + ret_str_len + 1;
 
-                // If there is no where clause, take into account the space after the return type
+                // If there is no where-clause, take into account the space after the return type
                 // and the brace.
                 if where_clause.predicates.is_empty() {
                     sig_length += 2;
@@ -2139,7 +2107,7 @@ fn rewrite_fn_base(
             } else {
                 // FIXME: we might want to check that using the arg indent
                 // doesn't blow our budget, and if it does, then fallback to
-                // the where clause indent.
+                // the where-clause indent.
                 arg_indent
             };
 
@@ -2215,7 +2183,7 @@ fn rewrite_fn_base(
         option,
         is_args_multi_lined,
     )?;
-    // If there are neither where clause nor return type, we may be missing comments between
+    // If there are neither where-clause nor return type, we may be missing comments between
     // args and `{`.
     if where_clause_str.is_empty() {
         if let ast::FunctionRetTy::Default(ret_span) = fd.output {
@@ -2245,7 +2213,7 @@ fn rewrite_fn_base(
 struct WhereClauseOption {
     suppress_comma: bool, // Force no trailing comma
     snuggle: bool,        // Do not insert newline before `where`
-    compress_where: bool, // Try single line where clause instead of vertical layout
+    compress_where: bool, // Try single line where-clause instead of vertical layout
 }
 
 impl WhereClauseOption {
@@ -2281,130 +2249,46 @@ pub fn snuggle(&mut self) {
 fn rewrite_args(
     context: &RewriteContext<'_>,
     args: &[ast::Arg],
-    explicit_self: Option<&ast::ExplicitSelf>,
     one_line_budget: usize,
     multi_line_budget: usize,
     indent: Indent,
     arg_indent: Indent,
     span: Span,
     variadic: bool,
-    generics_str_contains_newline: bool,
 ) -> Option<String> {
-    let mut arg_item_strs = args
-        .iter()
-        .map(|arg| {
-            arg.rewrite(context, Shape::legacy(multi_line_budget, arg_indent))
-                .unwrap_or_else(|| context.snippet(arg.span()).to_owned())
-        })
-        .collect::<Vec<_>>();
-
-    // Account for sugary self.
-    // FIXME: the comment for the self argument is dropped. This is blocked
-    // on rust issue #27522.
-    let min_args = explicit_self
-        .and_then(|explicit_self| rewrite_explicit_self(explicit_self, args, context))
-        .map_or(1, |self_str| {
-            arg_item_strs[0] = self_str;
-            2
-        });
-
-    // Comments between args.
-    let mut arg_items = Vec::new();
-    if min_args == 2 {
-        arg_items.push(ListItem::from_str(""));
-    }
-
-    // FIXME(#21): if there are no args, there might still be a comment, but
-    // without spans for the comment or parens, there is no chance of
-    // getting it right. You also don't get to put a comment on self, unless
-    // it is explicit.
-    if args.len() >= min_args || variadic {
-        let comment_span_start = if min_args == 2 {
-            let second_arg_start = if arg_has_pattern(&args[1]) {
-                args[1].pat.span.lo()
-            } else {
-                args[1].ty.span.lo()
-            };
-            let reduced_span = mk_sp(span.lo(), second_arg_start);
-
-            context.snippet_provider.span_after_last(reduced_span, ",")
-        } else {
-            span.lo()
-        };
-
-        enum ArgumentKind<'a> {
-            Regular(&'a ast::Arg),
-            Variadic(BytePos),
-        }
-
-        let variadic_arg = if variadic {
-            let variadic_span = mk_sp(args.last().unwrap().ty.span.hi(), span.hi());
-            let variadic_start =
-                context.snippet_provider.span_after(variadic_span, "...") - BytePos(3);
-            Some(ArgumentKind::Variadic(variadic_start))
-        } else {
-            None
-        };
-
-        let more_items = itemize_list(
-            context.snippet_provider,
-            args[min_args - 1..]
-                .iter()
-                .map(ArgumentKind::Regular)
-                .chain(variadic_arg),
-            ")",
-            ",",
-            |arg| match *arg {
-                ArgumentKind::Regular(arg) => span_lo_for_arg(arg),
-                ArgumentKind::Variadic(start) => start,
-            },
-            |arg| match *arg {
-                ArgumentKind::Regular(arg) => arg.ty.span.hi(),
-                ArgumentKind::Variadic(start) => start + BytePos(3),
-            },
-            |arg| match *arg {
-                ArgumentKind::Regular(..) => None,
-                ArgumentKind::Variadic(..) => Some("...".to_owned()),
-            },
-            comment_span_start,
-            span.hi(),
-            false,
-        );
-
-        arg_items.extend(more_items);
-    }
-
-    let fits_in_one_line = !generics_str_contains_newline
-        && (arg_items.is_empty()
-            || arg_items.len() == 1 && arg_item_strs[0].len() <= one_line_budget);
-
-    for (item, arg) in arg_items.iter_mut().zip(arg_item_strs) {
-        item.item = Some(arg);
+    if args.len() == 0 {
+        let comment = context
+            .snippet(mk_sp(
+                span.lo(),
+                // to remove ')'
+                span.hi() - BytePos(1),
+            ))
+            .trim();
+        return Some(comment.to_owned());
     }
-
-    let last_line_ends_with_comment = arg_items
-        .iter()
-        .last()
-        .and_then(|item| item.post_comment.as_ref())
-        .map_or(false, |s| s.trim().starts_with("//"));
-
-    let (indent, trailing_comma) = match context.config.indent_style() {
-        IndentStyle::Block if fits_in_one_line => {
-            (indent.block_indent(context.config), SeparatorTactic::Never)
-        }
-        IndentStyle::Block => (
-            indent.block_indent(context.config),
-            context.config.trailing_comma(),
-        ),
-        IndentStyle::Visual if last_line_ends_with_comment => {
-            (arg_indent, context.config.trailing_comma())
-        }
-        IndentStyle::Visual => (arg_indent, SeparatorTactic::Never),
-    };
+    let arg_items: Vec<_> = itemize_list(
+        context.snippet_provider,
+        args.iter(),
+        ")",
+        ",",
+        |arg| span_lo_for_arg(arg),
+        |arg| arg.ty.span.hi(),
+        |arg| {
+            arg.rewrite(context, Shape::legacy(multi_line_budget, arg_indent))
+                .or_else(|| Some(context.snippet(arg.span()).to_owned()))
+        },
+        span.lo(),
+        span.hi(),
+        false,
+    )
+    .collect();
 
     let tactic = definitive_tactic(
         &arg_items,
-        context.config.fn_args_density().to_list_tactic(),
+        context
+            .config
+            .fn_args_density()
+            .to_list_tactic(arg_items.len()),
         Separator::Comma,
         one_line_budget,
     );
@@ -2412,13 +2296,17 @@ enum ArgumentKind<'a> {
         DefinitiveListTactic::Horizontal => one_line_budget,
         _ => multi_line_budget,
     };
-
-    debug!("rewrite_args: budget: {}, tactic: {:?}", budget, tactic);
-
+    let indent = match context.config.indent_style() {
+        IndentStyle::Block => indent.block_indent(context.config),
+        IndentStyle::Visual => arg_indent,
+    };
     let trailing_separator = if variadic {
         SeparatorTactic::Never
     } else {
-        trailing_comma
+        match context.config.indent_style() {
+            IndentStyle::Block => context.config.trailing_comma(),
+            IndentStyle::Visual => SeparatorTactic::Never,
+        }
     };
     let fmt = ListFormatting::new(Shape::legacy(budget, indent), context.config)
         .tactic(tactic)
@@ -2428,14 +2316,6 @@ enum ArgumentKind<'a> {
     write_list(&arg_items, &fmt)
 }
 
-fn arg_has_pattern(arg: &ast::Arg) -> bool {
-    if let ast::PatKind::Ident(_, ident, _) = arg.pat.node {
-        ident != symbol::keywords::Invalid.ident()
-    } else {
-        true
-    }
-}
-
 fn compute_budgets_for_args(
     context: &RewriteContext<'_>,
     result: &str,
@@ -2515,8 +2395,8 @@ fn rewrite_generics(
     generics: &ast::Generics,
     shape: Shape,
 ) -> Option<String> {
-    // FIXME: convert bounds to where clauses where they get too big or if
-    // there is a where clause at all.
+    // FIXME: convert bounds to where-clauses where they get too big or if
+    // there is a where-clause at all.
 
     if generics.params.is_empty() {
         return Some(ident.to_owned());
@@ -2593,7 +2473,7 @@ fn rewrite_where_clause_rfc_style(
     };
 
     // shape should be vertical only and only if we have `where_single_line` option enabled
-    // and the number of items of the where clause is equal to 1
+    // and the number of items of the where-clause is equal to 1
     let shape_tactic = if where_single_line {
         DefinitiveListTactic::Horizontal
     } else {
@@ -2703,7 +2583,7 @@ fn rewrite_where_clause(
     let tactic = definitive_tactic(&item_vec, ListTactic::Vertical, Separator::Comma, budget);
 
     let mut comma_tactic = context.config.trailing_comma();
-    // Kind of a hack because we don't usually have trailing commas in where clauses.
+    // Kind of a hack because we don't usually have trailing commas in where-clauses.
     if comma_tactic == SeparatorTactic::Vertical || where_clause_option.suppress_comma {
         comma_tactic = SeparatorTactic::Never;
     }
@@ -2945,7 +2825,7 @@ pub fn rewrite_extern_crate(context: &RewriteContext<'_>, item: &ast::Item) -> O
     })
 }
 
-/// Returns true for `mod foo;`, false for `mod foo { .. }`.
+/// Returns `true` for `mod foo;`, false for `mod foo { .. }`.
 pub fn is_mod_decl(item: &ast::Item) -> bool {
     match item.node {
         ast::ItemKind::Mod(ref m) => m.inner.hi() != item.span.hi(),