diff --git a/Cargo.lock b/Cargo.lock index 2ef83ddd1ae6..b932e15ef746 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -275,9 +275,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] diff --git a/Cargo.toml b/Cargo.toml index 8d9c4a7fb20c..764714638a97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ rustfmt-format-diff = [] generic-simd = ["bytecount/generic-simd"] [dependencies] -itertools = "0.9" +itertools = "0.10.1" toml = "0.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/rust-toolchain b/rust-toolchain index d8bf02aec85e..0d407f11994b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-01-23" +channel = "nightly-2022-03-17" components = ["rustc-dev"] diff --git a/src/expr.rs b/src/expr.rs index e1865c8afc2f..4f333cd27cef 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1533,7 +1533,7 @@ fn rewrite_struct_lit<'a>( enum StructLitField<'a> { Regular(&'a ast::ExprField), Base(&'a ast::Expr), - Rest(&'a Span), + Rest(Span), } // 2 = " {".len() @@ -1568,7 +1568,7 @@ fn rewrite_struct_lit<'a>( let field_iter = fields.iter().map(StructLitField::Regular).chain( match struct_rest { ast::StructRest::Base(expr) => Some(StructLitField::Base(&**expr)), - ast::StructRest::Rest(span) => Some(StructLitField::Rest(span)), + ast::StructRest::Rest(span) => Some(StructLitField::Rest(*span)), ast::StructRest::None => None, } .into_iter(), diff --git a/src/items.rs b/src/items.rs index 007609aba249..9b35d28f1195 100644 --- a/src/items.rs +++ b/src/items.rs @@ -694,7 +694,8 @@ pub(crate) fn format_impl( let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause, + &generics.where_clause.predicates, + generics.where_clause.span, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1059,7 +1060,8 @@ pub(crate) fn format_trait( let option = WhereClauseOption::snuggled(&generics_str); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause, + &generics.where_clause.predicates, + generics.where_clause.span, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), where_on_new_line, @@ -1178,7 +1180,8 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let where_str = rewrite_where_clause( context, - &self.generics.where_clause, + &self.generics.where_clause.predicates, + self.generics.where_clause.span, context.config.brace_style(), shape, false, @@ -1441,7 +1444,8 @@ fn format_tuple_struct( let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); rewrite_where_clause( context, - &generics.where_clause, + &generics.where_clause.predicates, + generics.where_clause.span, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1507,6 +1511,8 @@ struct TyAliasRewriteInfo<'c, 'g>( &'c RewriteContext<'c>, Indent, &'g ast::Generics, + (ast::TyAliasWhereClause, ast::TyAliasWhereClause), + usize, symbol::Ident, Span, ); @@ -1525,6 +1531,8 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( ref generics, ref bounds, ref ty, + where_clauses, + where_predicates_split, } = *ty_alias_kind; let ty_opt = ty.as_ref(); let (ident, vis) = match visitor_kind { @@ -1532,7 +1540,15 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), ForeignItem(i) => (i.ident, &i.vis), }; - let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span); + let rw_info = &TyAliasRewriteInfo( + context, + indent, + generics, + where_clauses, + where_predicates_split, + ident, + span, + ); let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. @@ -1568,7 +1584,22 @@ fn rewrite_ty( vis: &ast::Visibility, ) -> Option { let mut result = String::with_capacity(128); - let TyAliasRewriteInfo(context, indent, generics, ident, span) = *rw_info; + let TyAliasRewriteInfo( + context, + indent, + generics, + where_clauses, + where_predicates_split, + ident, + span, + ) = *rw_info; + let (before_where_predicates, after_where_predicates) = generics + .where_clause + .predicates + .split_at(where_predicates_split); + if !after_where_predicates.is_empty() { + return None; + } result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1599,7 +1630,8 @@ fn rewrite_ty( } let where_clause_str = rewrite_where_clause( context, - &generics.where_clause, + before_where_predicates, + where_clauses.0.1, context.config.brace_style(), Shape::legacy(where_budget, indent), false, @@ -1613,7 +1645,7 @@ fn rewrite_ty( if let Some(ty) = rhs { // If there's a where clause, add a newline before the assignment. Otherwise just add a // space. - let has_where = !generics.where_clause.predicates.is_empty(); + let has_where = !before_where_predicates.is_empty(); if has_where { result.push_str(&indent.to_string_with_newline(context.config)); } else { @@ -1623,7 +1655,7 @@ fn rewrite_ty( let comment_span = context .snippet_provider .opt_span_before(span, "=") - .map(|op_lo| mk_sp(generics.where_clause.span.hi(), op_lo)); + .map(|op_lo| mk_sp(where_clauses.0.1.hi(), op_lo)); let lhs = match comment_span { Some(comment_span) @@ -2186,7 +2218,7 @@ fn rewrite_fn_base( let generics_str = rewrite_generics( context, rewrite_ident(context, ident), - fn_sig.generics, + &fn_sig.generics, shape, )?; result.push_str(&generics_str); @@ -2426,7 +2458,8 @@ fn rewrite_fn_base( } let where_clause_str = rewrite_where_clause( context, - where_clause, + &where_clause.predicates, + where_clause.span, context.config.brace_style(), Shape::indented(indent, context.config), true, @@ -2702,7 +2735,8 @@ fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> O fn rewrite_where_clause_rfc_style( context: &RewriteContext<'_>, - where_clause: &ast::WhereClause, + predicates: &[ast::WherePredicate], + where_span: Span, shape: Shape, terminator: &str, span_end: Option, @@ -2711,7 +2745,8 @@ fn rewrite_where_clause_rfc_style( ) -> Option { let (where_keyword, allow_single_line) = rewrite_where_keyword( context, - where_clause, + predicates, + where_span, shape, span_end_before_where, where_clause_option, @@ -2724,12 +2759,12 @@ fn rewrite_where_clause_rfc_style( .block_left(context.config.tab_spaces())? .sub_width(1)?; let force_single_line = context.config.where_single_line() - && where_clause.predicates.len() == 1 + && predicates.len() == 1 && !where_clause_option.veto_single_line; let preds_str = rewrite_bounds_on_where_clause( context, - where_clause, + predicates, clause_shape, terminator, span_end, @@ -2753,7 +2788,8 @@ fn rewrite_where_clause_rfc_style( /// Rewrite `where` and comment around it. fn rewrite_where_keyword( context: &RewriteContext<'_>, - where_clause: &ast::WhereClause, + predicates: &[ast::WherePredicate], + where_span: Span, shape: Shape, span_end_before_where: BytePos, where_clause_option: WhereClauseOption, @@ -2773,7 +2809,7 @@ fn rewrite_where_keyword( }; let (span_before, span_after) = - missing_span_before_after_where(span_end_before_where, where_clause); + missing_span_before_after_where(span_end_before_where, predicates, where_span); let (comment_before, comment_after) = rewrite_comments_before_after_where(context, span_before, span_after, shape)?; @@ -2799,22 +2835,22 @@ fn rewrite_where_keyword( /// Rewrite bounds on a where clause. fn rewrite_bounds_on_where_clause( context: &RewriteContext<'_>, - where_clause: &ast::WhereClause, + predicates: &[ast::WherePredicate], shape: Shape, terminator: &str, span_end: Option, where_clause_option: WhereClauseOption, force_single_line: bool, ) -> Option { - let span_start = where_clause.predicates[0].span().lo(); + let span_start = predicates[0].span().lo(); // If we don't have the start of the next span, then use the end of the // predicates, but that means we miss comments. - let len = where_clause.predicates.len(); - let end_of_preds = where_clause.predicates[len - 1].span().hi(); + let len = predicates.len(); + 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, - where_clause.predicates.iter(), + predicates.iter(), terminator, ",", |pred| pred.span().lo(), @@ -2847,7 +2883,8 @@ fn rewrite_bounds_on_where_clause( fn rewrite_where_clause( context: &RewriteContext<'_>, - where_clause: &ast::WhereClause, + predicates: &[ast::WherePredicate], + where_span: Span, brace_style: BraceStyle, shape: Shape, on_new_line: bool, @@ -2856,14 +2893,15 @@ fn rewrite_where_clause( span_end_before_where: BytePos, where_clause_option: WhereClauseOption, ) -> Option { - if where_clause.predicates.is_empty() { + if predicates.is_empty() { return Some(String::new()); } if context.config.indent_style() == IndentStyle::Block { return rewrite_where_clause_rfc_style( context, - where_clause, + predicates, + where_span, shape, terminator, span_end, @@ -2883,15 +2921,15 @@ fn rewrite_where_clause( // be out by a char or two. let budget = context.config.max_width() - offset.width(); - let span_start = where_clause.predicates[0].span().lo(); + let span_start = predicates[0].span().lo(); // If we don't have the start of the next span, then use the end of the // predicates, but that means we miss comments. - let len = where_clause.predicates.len(); - let end_of_preds = where_clause.predicates[len - 1].span().hi(); + let len = predicates.len(); + 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, - where_clause.predicates.iter(), + predicates.iter(), terminator, ",", |pred| pred.span().lo(), @@ -2946,12 +2984,13 @@ fn rewrite_where_clause( fn missing_span_before_after_where( before_item_span_end: BytePos, - where_clause: &ast::WhereClause, + predicates: &[ast::WherePredicate], + where_span: Span, ) -> (Span, Span) { - let missing_span_before = mk_sp(before_item_span_end, where_clause.span.lo()); + let missing_span_before = mk_sp(before_item_span_end, where_span.lo()); // 5 = `where` - let pos_after_where = where_clause.span.lo() + BytePos(5); - let missing_span_after = mk_sp(pos_after_where, where_clause.predicates[0].span().lo()); + let pos_after_where = where_span.lo() + BytePos(5); + let missing_span_after = mk_sp(pos_after_where, predicates[0].span().lo()); (missing_span_before, missing_span_after) } @@ -3040,7 +3079,8 @@ fn format_generics( } let where_clause_str = rewrite_where_clause( context, - &generics.where_clause, + &generics.where_clause.predicates, + generics.where_clause.span, brace_style, Shape::legacy(budget, offset.block_only()), true, diff --git a/src/modules.rs b/src/modules.rs index 49c99403974e..a65dc66f7972 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -131,7 +131,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { mut self, krate: &'ast ast::Crate, ) -> Result, ModuleResolutionError> { - let root_filename = self.parse_sess.span_to_filename(krate.span); + let root_filename = self.parse_sess.span_to_filename(krate.spans.inner_span); self.directory.path = match root_filename { FileName::Real(ref p) => p.parent().unwrap_or(Path::new("")).to_path_buf(), _ => PathBuf::new(), @@ -142,7 +142,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { self.visit_mod_from_ast(&krate.items)?; } - let snippet_provider = self.parse_sess.snippet_provider(krate.span); + let snippet_provider = self.parse_sess.snippet_provider(krate.spans.inner_span); self.file_map.insert( root_filename, @@ -446,7 +446,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { } } Err(mod_err) if !mods_outside_ast.is_empty() => { - if let ModError::ParserError(mut e) = mod_err { + if let ModError::ParserError(e) = mod_err { e.cancel(); } Ok(Some(SubModKind::MultiExternal(mods_outside_ast))) diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index e10fbe64bcdb..306b6bb745ee 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -57,7 +57,7 @@ fn parse_cfg_if_inner<'a>( let item = match parser.parse_item(ForceCollect::No) { Ok(Some(item_ptr)) => item_ptr.into_inner(), Ok(None) => continue, - Err(mut err) => { + Err(err) => { err.cancel(); parser.sess.span_diagnostic.reset_err_count(); return Err( diff --git a/src/parse/macros/lazy_static.rs b/src/parse/macros/lazy_static.rs index 9c8651aa3faf..4c541de04be0 100644 --- a/src/parse/macros/lazy_static.rs +++ b/src/parse/macros/lazy_static.rs @@ -23,7 +23,7 @@ pub(crate) fn parse_lazy_static( val } } - Err(mut err) => { + Err(err) => { err.cancel(); parser.sess.span_diagnostic.reset_err_count(); return None; diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 2e9ce1d35f40..fd738908170f 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -36,7 +36,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { return Some(MacroArg::$macro_arg($f(x)?)); } } - Err(mut e) => { + Err(e) => { e.cancel(); parser.sess.span_diagnostic.reset_err_count(); } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 657217633f4a..268c72649a65 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -113,9 +113,9 @@ impl<'a> Parser<'a> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { - Ok(result) => Some(result), + Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(mut e) => { - sess.emit_or_cancel_diagnostic(&mut e); + e.emit(); if sess.can_reset_errors() { sess.reset_errors(); } diff --git a/src/parse/session.rs b/src/parse/session.rs index a95324bbb0e4..bf9acd435b92 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -61,7 +61,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter { None } fn emit_diagnostic(&mut self, db: &Diagnostic) { - if db.level == DiagnosticLevel::Fatal { + if db.level() == DiagnosticLevel::Fatal { return self.handle_non_ignoreable_error(db); } if let Some(primary_span) = &db.span.primary_span() { @@ -260,17 +260,6 @@ impl ParseSess { } } - pub(crate) fn emit_or_cancel_diagnostic(&self, diagnostic: &mut Diagnostic) { - self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic); - // The Handler will check whether the diagnostic should be emitted - // based on the user's rustfmt configuration and the originating file - // that caused the parser error. If the Handler determined it should skip - // emission then we need to ensure the diagnostic is cancelled. - if !diagnostic.cancelled() { - diagnostic.cancel(); - } - } - pub(super) fn can_reset_errors(&self) -> bool { self.can_reset_errors.load(Ordering::Acquire) } @@ -322,7 +311,7 @@ mod tests { use super::*; use crate::config::IgnoreList; use crate::utils::mk_sp; - use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName, DUMMY_SP}; + use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName}; use std::path::PathBuf; use std::sync::atomic::AtomicU32; @@ -340,16 +329,12 @@ mod tests { } fn build_diagnostic(level: DiagnosticLevel, span: Option) -> Diagnostic { - Diagnostic { - level, - code: None, - message: vec![], - children: vec![], - suggestions: vec![], - span: span.unwrap_or_else(MultiSpan::new), - sort_span: DUMMY_SP, - is_lint: false, + let mut diag = Diagnostic::new(level, ""); + diag.message.clear(); + if let Some(span) = span { + diag.span = span; } + diag } fn build_emitter( diff --git a/src/visitor.rs b/src/visitor.rs index 0177689958aa..3ebfa551d1cb 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -915,7 +915,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let ident_str = rewrite_ident(&self.get_context(), ident).to_owned(); self.push_str(&ident_str); - if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, inner_span) = mod_kind { + if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind { + let ast::ModSpans { + inner_span, + inject_use_span: _, + } = *spans; match self.config.brace_style() { BraceStyle::AlwaysNextLine => { let indent_str = self.block_indent.to_string_with_newline(self.config);