@@ -249,12 +249,7 @@ impl Rewrite for ast::MetaItemInner {
249249 }
250250
251251 fn rewrite_result ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> RewriteResult {
252- match self {
253- ast:: MetaItemInner :: MetaItem ( ref meta_item) => meta_item. rewrite_result ( context, shape) ,
254- ast:: MetaItemInner :: Lit ( ref l) => {
255- rewrite_literal ( context, l. as_token_lit ( ) , l. span , shape)
256- }
257- }
252+ rewrite_meta_item_inner_result ( self , context, shape, false )
258253 }
259254}
260255
@@ -283,45 +278,96 @@ impl Rewrite for ast::MetaItem {
283278 }
284279
285280 fn rewrite_result ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> RewriteResult {
286- Ok ( match self . kind {
287- ast:: MetaItemKind :: Word => {
288- rewrite_path ( context, PathContext :: Type , & None , & self . path , shape) ?
289- }
290- ast:: MetaItemKind :: List ( ref list) => {
291- let path = rewrite_path ( context, PathContext :: Type , & None , & self . path , shape) ?;
292- let has_trailing_comma = crate :: expr:: span_ends_with_comma ( context, self . span ) ;
293- overflow:: rewrite_with_parens (
294- context,
295- & path,
296- list. iter ( ) ,
297- // 1 = "]"
298- shape. sub_width ( 1 ) . max_width_error ( shape. width , self . span ) ?,
299- self . span ,
300- context. config . attr_fn_like_width ( ) ,
301- Some ( if has_trailing_comma {
302- SeparatorTactic :: Always
281+ rewrite_meta_item_result ( self , context, shape, false )
282+ }
283+ }
284+
285+ pub ( crate ) fn rewrite_meta_item_inner_result (
286+ this : & ast:: MetaItemInner ,
287+ context : & RewriteContext < ' _ > ,
288+ shape : Shape ,
289+ line_break_list : bool ,
290+ ) -> RewriteResult {
291+ match this {
292+ ast:: MetaItemInner :: MetaItem ( ref meta_item) => {
293+ rewrite_meta_item_result ( meta_item, context, shape, line_break_list)
294+ }
295+ ast:: MetaItemInner :: Lit ( ref l) => rewrite_literal ( context, l. as_token_lit ( ) , l. span , shape) ,
296+ }
297+ }
298+
299+ pub ( crate ) fn rewrite_meta_item_result (
300+ this : & ast:: MetaItem ,
301+ context : & RewriteContext < ' _ > ,
302+ shape : Shape ,
303+ line_break_list : bool ,
304+ ) -> RewriteResult {
305+ let path = rewrite_path ( context, PathContext :: Type , & None , & this. path , shape) ?;
306+
307+ match this. kind {
308+ ast:: MetaItemKind :: Word => {
309+ // E.g., `#[test]`, which lacks any arguments after `test`.
310+ Ok ( path)
311+ }
312+ ast:: MetaItemKind :: List ( ref list) => {
313+ // E.g., `#[derive(..)]`, where the `list` represents the `..`.
314+
315+ let separator_tactic = if crate :: expr:: span_ends_with_comma ( context, this. span ) {
316+ SeparatorTactic :: Always
317+ } else {
318+ SeparatorTactic :: Never
319+ } ;
320+
321+ overflow:: rewrite_with_parens (
322+ context,
323+ & path,
324+ list. iter ( ) ,
325+ shape
326+ . sub_width ( "]" . len ( ) )
327+ . max_width_error ( shape. width , this. span ) ?,
328+ this. span ,
329+ context. config . attr_fn_like_width ( ) ,
330+ Some ( separator_tactic) ,
331+ )
332+ }
333+ ast:: MetaItemKind :: NameValue ( ref lit) => {
334+ // E.g., `#[feature = "foo"]`, where the `lit` represents the `"foo"`.
335+
336+ let lit_shape = shape
337+ . shrink_left ( path. len ( ) + " = " . len ( ) )
338+ . max_width_error ( shape. width , this. span ) ?;
339+
340+ // `rewrite_literal` returns `None` when `lit` exceeds max
341+ // width. Since a literal is basically unformattable unless it
342+ // is a string literal (and only if `format_strings` is set),
343+ // we might be better off ignoring the fact that the attribute
344+ // is longer than the max width and continue on formatting.
345+ // See #2479 for example.
346+
347+ match rewrite_literal ( context, lit. as_token_lit ( ) , lit. span , lit_shape) {
348+ Ok ( value) => {
349+ // The whole meta item fits on one line.
350+ Ok ( format ! ( "{path} = {value}" ) )
351+ }
352+ Err ( _) => {
353+ // `lit` exceeded the maximum width of its Shape.
354+ if line_break_list {
355+ // Insert a line break before the `=`.
356+ let mut result = String :: new ( ) ;
357+ result. push_str ( & path) ;
358+ result. push_str ( & shape. indent . to_string_with_newline ( context. config ) ) ;
359+ result. push_str ( "= " ) ;
360+ result. push_str ( context. snippet ( lit. span ) ) ;
361+
362+ Ok ( result)
303363 } else {
304- SeparatorTactic :: Never
305- } ) ,
306- ) ?
307- }
308- ast:: MetaItemKind :: NameValue ( ref lit) => {
309- let path = rewrite_path ( context, PathContext :: Type , & None , & self . path , shape) ?;
310- // 3 = ` = `
311- let lit_shape = shape
312- . shrink_left ( path. len ( ) + 3 )
313- . max_width_error ( shape. width , self . span ) ?;
314- // `rewrite_literal` returns `None` when `lit` exceeds max
315- // width. Since a literal is basically unformattable unless it
316- // is a string literal (and only if `format_strings` is set),
317- // we might be better off ignoring the fact that the attribute
318- // is longer than the max width and continue on formatting.
319- // See #2479 for example.
320- let value = rewrite_literal ( context, lit. as_token_lit ( ) , lit. span , lit_shape)
321- . unwrap_or_else ( |_| context. snippet ( lit. span ) . to_owned ( ) ) ;
322- format ! ( "{path} = {value}" )
364+ // Just format on a single line anyway.
365+ let value = context. snippet ( lit. span ) ;
366+ Ok ( format ! ( "{path} = {value}" ) )
367+ }
368+ }
323369 }
324- } )
370+ }
325371 }
326372}
327373
0 commit comments