diff --git a/src/attr.rs b/src/attr.rs index ac9ce2e8796..2dcac117e81 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -93,7 +93,7 @@ fn format_derive( })?; let items = itemize_list( - context.snippet_provider, + context, item_spans, ")", ",", diff --git a/src/closures.rs b/src/closures.rs index 19cd0d9792c..bdc38d02d3f 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -310,7 +310,7 @@ fn rewrite_closure_fn_decl( let ret_str = fn_decl.output.rewrite_result(context, param_shape)?; let param_items = itemize_list( - context.snippet_provider, + context, fn_decl.inputs.iter(), "|", ",", diff --git a/src/expr.rs b/src/expr.rs index b79137c4442..91215f760cc 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1843,7 +1843,7 @@ fn rewrite_struct_lit<'a>( }; let items = itemize_list( - context.snippet_provider, + context, field_iter, "}", ",", @@ -1995,7 +1995,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>( let list_lo = context.snippet_provider.span_after(span, "("); let nested_shape = shape.sub_width(2, span)?.visual_indent(1); let items = itemize_list( - context.snippet_provider, + context, items, ")", ",", diff --git a/src/imports.rs b/src/imports.rs index 2f26791639a..728aa2bfc2c 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -476,7 +476,7 @@ impl UseTree { // Extract comments between nested use items. // This needs to be done before sorting use items. let items = itemize_list( - context.snippet_provider, + context, list.iter().map(|(tree, _)| tree), "}", ",", diff --git a/src/items.rs b/src/items.rs index a2c0e8e0f50..2237c00dd06 100644 --- a/src/items.rs +++ b/src/items.rs @@ -614,9 +614,10 @@ impl<'a> FmtVisitor<'a> { .max() .unwrap_or(&0); + let enum_context = self.get_context(); let itemize_list_with = |one_line_width: usize| { itemize_list( - self.snippet_provider, + &enum_context, enum_def.variants.iter(), "}", ",", @@ -2852,7 +2853,7 @@ fn rewrite_params( return Ok(comment.to_owned()); } let param_items: Vec<_> = itemize_list( - context.snippet_provider, + context, params.iter(), ")", ",", @@ -3130,7 +3131,7 @@ fn rewrite_bounds_on_where_clause( let end_of_preds = predicates[len - 1].span().hi(); let span_end = span_end.unwrap_or(end_of_preds); let items = itemize_list( - context.snippet_provider, + context, predicates.iter(), terminator, ",", @@ -3185,6 +3186,12 @@ fn rewrite_where_clause( return Ok(String::new()); } + if out_of_file_lines_range!(context, where_span) { + return Ok(context + .snippet(mk_sp(span_end_before_where, where_span.hi())) + .to_owned()); + } + if context.config.indent_style() == IndentStyle::Block { return rewrite_where_clause_rfc_style( context, @@ -3216,7 +3223,7 @@ fn rewrite_where_clause( let end_of_preds = predicates[len - 1].span().hi(); let span_end = span_end.unwrap_or(end_of_preds); let items = itemize_list( - context.snippet_provider, + context, predicates.iter(), terminator, ",", diff --git a/src/lists.rs b/src/lists.rs index 9d811e5d9b5..e8e6782ea62 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -10,11 +10,11 @@ use crate::config::lists::*; use crate::config::{Config, IndentStyle}; use crate::rewrite::{ExceedsMaxWidthError, RewriteContext, RewriteError, RewriteResult}; use crate::shape::{Indent, Shape}; +use crate::source_map::LineRangeUtils; use crate::utils::{ count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline, unicode_str_width, }; -use crate::visitor::SnippetProvider; pub(crate) struct ListFormatting<'a> { tactic: DefinitiveListTactic, @@ -564,7 +564,7 @@ pub(crate) struct ListItems<'a, I, F1, F2, F3> where I: Iterator, { - snippet_provider: &'a SnippetProvider, + context: &'a RewriteContext<'a>, inner: Peekable, get_lo: F1, get_hi: F2, @@ -751,10 +751,14 @@ where fn next(&mut self) -> Option { self.inner.next().map(|item| { + let lo = (self.get_lo)(&item); + let hi = (self.get_hi)(&item); + let context = self.context; + // Pre-comment - let pre_snippet = self + let pre_snippet = context .snippet_provider - .span_to_snippet(mk_sp(self.prev_span_end, (self.get_lo)(&item))) + .span_to_snippet(mk_sp(self.prev_span_end, lo)) .unwrap_or(""); let (pre_comment, pre_comment_style) = extract_pre_comment(pre_snippet); @@ -763,9 +767,9 @@ where Some(next_item) => (self.get_lo)(next_item), None => self.next_span_start, }; - let post_snippet = self + let post_snippet = context .snippet_provider - .span_to_snippet(mk_sp((self.get_hi)(&item), next_start)) + .span_to_snippet(mk_sp(hi, next_start)) .unwrap_or(""); let is_last = self.inner.peek().is_none(); let comment_end = @@ -774,14 +778,17 @@ where let post_comment = extract_post_comment(post_snippet, comment_end, self.separator, is_last); - self.prev_span_end = (self.get_hi)(&item) + BytePos(comment_end as u32); + self.prev_span_end = hi + BytePos(comment_end as u32); + let item_span = mk_sp(lo, hi); ListItem { pre_comment, pre_comment_style, // leave_last is set to true only for rewrite_items item: if self.inner.peek().is_none() && self.leave_last { Err(RewriteError::SkipFormatting) + } else if out_of_file_lines_range!(context, item_span) { + Ok(context.snippet(item_span).to_owned()) } else { (self.get_item_string)(&item) }, @@ -795,7 +802,7 @@ where #[allow(clippy::too_many_arguments)] // Creates an iterator over a list's items with associated comments. pub(crate) fn itemize_list<'a, T, I, F1, F2, F3>( - snippet_provider: &'a SnippetProvider, + context: &'a RewriteContext<'a>, inner: I, terminator: &'a str, separator: &'a str, @@ -813,7 +820,7 @@ where F3: Fn(&T) -> RewriteResult, { ListItems { - snippet_provider, + context, inner: inner.peekable(), get_lo, get_hi, diff --git a/src/macros.rs b/src/macros.rs index 2d56021069c..f3909628458 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -465,7 +465,7 @@ pub(crate) fn rewrite_macro_def( } let branch_items = itemize_list( - context.snippet_provider, + context, parsed_def.branches.iter(), "}", ";", diff --git a/src/matches.rs b/src/matches.rs index 4741abbe465..ce102e72752 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -222,7 +222,7 @@ fn rewrite_match_arms( .chain(repeat(true)); let beginning_verts = collect_beginning_verts(context, arms); let items = itemize_list( - context.snippet_provider, + context, arms.iter() .zip(is_last_iter) .zip(beginning_verts.into_iter()) diff --git a/src/overflow.rs b/src/overflow.rs index 4230c89b57b..2a754119f6e 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -625,7 +625,7 @@ impl<'a> Context<'a> { debug!("items: {:?}", self.items); let items = itemize_list( - self.context.snippet_provider, + self.context, self.items.iter(), self.suffix, ",", diff --git a/src/patterns.rs b/src/patterns.rs index df2a8dc5c6f..94a94b82e2a 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -429,7 +429,7 @@ fn rewrite_struct_pat( )?; let items = itemize_list( - context.snippet_provider, + context, fields.iter(), terminator, ",", @@ -651,7 +651,7 @@ fn count_wildcard_suffix_len( let mut suffix_len = 0; let items: Vec<_> = itemize_list( - context.snippet_provider, + context, patterns.iter(), ")", ",", diff --git a/src/reorder.rs b/src/reorder.rs index 6ef6e0bc969..f9285bee1c4 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -110,7 +110,7 @@ fn rewrite_reorderable_or_regroupable_items( let cloned = normalized_items.clone(); // Add comments before merging. let list_items = itemize_list( - context.snippet_provider, + context, cloned.iter(), "", ";", @@ -169,7 +169,7 @@ fn rewrite_reorderable_or_regroupable_items( } _ => { let list_items = itemize_list( - context.snippet_provider, + context, reorderable_items.iter(), "", ";", diff --git a/src/types.rs b/src/types.rs index 94ed42c6ea5..84f9b9f5a33 100644 --- a/src/types.rs +++ b/src/types.rs @@ -380,7 +380,7 @@ where (comment, tactic) } else { let items = itemize_list( - context.snippet_provider, + context, inputs, ")", ",", diff --git a/src/vertical.rs b/src/vertical.rs index 21e34d29710..22c8933c5b2 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -222,7 +222,7 @@ fn rewrite_aligned_items_inner( } let mut items = itemize_list( - context.snippet_provider, + context, fields.iter(), "}", ",", diff --git a/tests/source/file-lines-where-clause-skip.rs b/tests/source/file-lines-where-clause-skip.rs new file mode 100644 index 00000000000..bb2fc80ec97 --- /dev/null +++ b/tests/source/file-lines-where-clause-skip.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-where-clause-skip.rs","range":[8,8]}] + +fn foo() where +T: Clone, +T: Copy, +T: Default, +{ + let x=1; +} diff --git a/tests/source/file-lines-where-clause.rs b/tests/source/file-lines-where-clause.rs new file mode 100644 index 00000000000..31bd865bb7a --- /dev/null +++ b/tests/source/file-lines-where-clause.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-where-clause.rs","range":[5,5]}] + +fn foo() +where + T : Clone + Debug, + U : Copy, + V : Default, +{ +} diff --git a/tests/target/file-lines-where-clause-skip.rs b/tests/target/file-lines-where-clause-skip.rs new file mode 100644 index 00000000000..d9494f60ea0 --- /dev/null +++ b/tests/target/file-lines-where-clause-skip.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-where-clause-skip.rs","range":[8,8]}] + +fn foo() where +T: Clone, +T: Copy, +T: Default, +{ + let x = 1; +} diff --git a/tests/target/file-lines-where-clause.rs b/tests/target/file-lines-where-clause.rs new file mode 100644 index 00000000000..111b6afc3ba --- /dev/null +++ b/tests/target/file-lines-where-clause.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/file-lines-where-clause.rs","range":[5,5]}] + +fn foo() +where + T: Clone + Debug, + U : Copy, + V : Default, +{ +}