diff --git a/src/types.rs b/src/types.rs index c0bf9482b11..b48461fab6d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -17,7 +17,7 @@ use crate::macros::{rewrite_macro, MacroPosition}; use crate::overflow; use crate::pairs::{rewrite_pair, PairParts}; -use crate::rewrite::{Rewrite, RewriteContext}; +use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult}; use crate::shape::Shape; use crate::source_map::SpanUtils; use crate::spanned::Spanned; @@ -220,12 +220,16 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option impl Rewrite for ast::AssocItemConstraintKind { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + self.rewrite_result(context, shape).ok() + } + + fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match self { ast::AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => ty.rewrite(context, shape), - Term::Const(c) => c.rewrite(context, shape), + Term::Ty(ty) => ty.rewrite_result(context, shape), + Term::Const(c) => c.rewrite_result(context, shape), }, - ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape), + ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite_result(context, shape), } } } @@ -297,7 +301,7 @@ fn format_function_type<'a, I>( span: Span, context: &RewriteContext<'_>, shape: Shape, -) -> Option +) -> RewriteResult where I: ExactSizeIterator, ::Item: Deref, @@ -307,12 +311,12 @@ fn format_function_type<'a, I>( let ty_shape = match context.config.indent_style() { // 4 = " -> " - IndentStyle::Block => shape.offset_left(4)?, - IndentStyle::Visual => shape.block_left(4)?, + IndentStyle::Block => shape.offset_left(4).max_width_error(shape.width, span)?, + IndentStyle::Visual => shape.block_left(4).max_width_error(shape.width, span)?, }; let output = match *output { FnRetTy::Ty(ref ty) => { - let type_str = ty.rewrite(context, ty_shape)?; + let type_str = ty.rewrite_result(context, ty_shape)?; format!(" -> {type_str}") } FnRetTy::Default(..) => String::new(), @@ -325,7 +329,10 @@ fn format_function_type<'a, I>( ) } else { // 2 for () - let budget = shape.width.checked_sub(2)?; + let budget = shape + .width + .checked_sub(2) + .max_width_error(shape.width, span)?; // 1 for ( let offset = shape.indent + 1; Shape::legacy(budget, offset) @@ -338,7 +345,8 @@ fn format_function_type<'a, I>( let list_hi = context.snippet_provider.span_before(span, ")"); let comment = context .snippet_provider - .span_to_snippet(mk_sp(list_lo, list_hi))? + .span_to_snippet(mk_sp(list_lo, list_hi)) + .unknown_error()? .trim(); let comment = if comment.starts_with("//") { format!( @@ -378,7 +386,7 @@ fn format_function_type<'a, I>( .trailing_separator(trailing_separator) .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) .preserve_newline(true); - (write_list(&item_vec, &fmt)?, tactic) + (write_list(&item_vec, &fmt).unknown_error()?, tactic) }; let args = if tactic == DefinitiveListTactic::Horizontal @@ -395,9 +403,9 @@ fn format_function_type<'a, I>( ) }; if output.is_empty() || last_line_width(&args) + first_line_width(&output) <= shape.width { - Some(format!("{args}{output}")) + Ok(format!("{args}{output}")) } else { - Some(format!( + Ok(format!( "{}\n{}{}", args, list_shape.indent.to_string(context.config), @@ -469,10 +477,14 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option impl Rewrite for ast::GenericArg { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + self.rewrite_result(context, shape).ok() + } + + fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match *self { - ast::GenericArg::Lifetime(ref lt) => lt.rewrite(context, shape), - ast::GenericArg::Type(ref ty) => ty.rewrite(context, shape), - ast::GenericArg::Const(ref const_) => const_.rewrite(context, shape), + ast::GenericArg::Lifetime(ref lt) => lt.rewrite_result(context, shape), + ast::GenericArg::Type(ref ty) => ty.rewrite_result(context, shape), + ast::GenericArg::Const(ref const_) => const_.rewrite_result(context, shape), } } } @@ -507,7 +519,8 @@ fn rewrite_generic_args( data.span, context, shape, - ), + ) + .ok(), _ => Some("".to_owned()), } } @@ -549,6 +562,10 @@ fn rewrite(&self, context: &RewriteContext<'_>, _: Shape) -> Option { impl Rewrite for ast::GenericBound { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + self.rewrite_result(context, shape).ok() + } + + fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match *self { ast::GenericBound::Trait( ref poly_trait_ref, @@ -569,16 +586,19 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option asyncness.push(' '); } let polarity = polarity.as_str(); - let shape = shape.offset_left(constness.len() + polarity.len())?; + let shape = shape + .offset_left(constness.len() + polarity.len()) + .max_width_error(shape.width, self.span())?; poly_trait_ref - .rewrite(context, shape) + .rewrite_result(context, shape) .map(|s| format!("{constness}{asyncness}{polarity}{s}")) .map(|s| if has_paren { format!("({})", s) } else { s }) } ast::GenericBound::Use(ref args, span) => { overflow::rewrite_with_angle_brackets(context, "use", args.iter(), shape, span) + .unknown_error() } - ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape), + ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite_result(context, shape), } } } @@ -697,15 +717,29 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option impl Rewrite for ast::Ty { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + self.rewrite_result(context, shape).ok() + } + + fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match self.kind { ast::TyKind::TraitObject(ref bounds, tobj_syntax) => { // we have to consider 'dyn' keyword is used or not!!! let (shape, prefix) = match tobj_syntax { - ast::TraitObjectSyntax::Dyn => (shape.offset_left(4)?, "dyn "), - ast::TraitObjectSyntax::DynStar => (shape.offset_left(5)?, "dyn* "), + ast::TraitObjectSyntax::Dyn => ( + shape + .offset_left(4) + .max_width_error(shape.width, self.span())?, + "dyn ", + ), + ast::TraitObjectSyntax::DynStar => ( + shape + .offset_left(5) + .max_width_error(shape.width, self.span())?, + "dyn* ", + ), ast::TraitObjectSyntax::None => (shape, ""), }; - let mut res = bounds.rewrite(context, shape)?; + let mut res = bounds.rewrite_result(context, shape)?; // We may have falsely removed a trailing `+` inside macro call. if context.inside_macro() && bounds.len() == 1 @@ -714,7 +748,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { res.push('+'); } - Some(format!("{prefix}{res}")) + Ok(format!("{prefix}{res}")) } ast::TyKind::Ptr(ref mt) => { let prefix = match mt.mutbl { @@ -722,7 +756,7 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option Mutability::Not => "*const ", }; - rewrite_unary_prefix(context, prefix, &*mt.ty, shape) + rewrite_unary_prefix(context, prefix, &*mt.ty, shape).unknown_error() } ast::TyKind::Ref(ref lifetime, ref mt) => { let mut_str = format_mutability(mt.mutbl); @@ -733,8 +767,11 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option let mut cmnt_lo = ref_hi; if let Some(ref lifetime) = *lifetime { - let lt_budget = shape.width.checked_sub(2 + mut_len)?; - let lt_str = lifetime.rewrite( + let lt_budget = shape + .width + .checked_sub(2 + mut_len) + .max_width_error(shape.width, self.span())?; + let lt_str = lifetime.rewrite_result( context, Shape::legacy(lt_budget, shape.indent + 2 + mut_len), )?; @@ -747,7 +784,8 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option before_lt_span, shape, true, - )?; + ) + .unknown_error()?; } else { result.push_str(<_str); } @@ -766,7 +804,8 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option before_mut_span, shape, true, - )?; + ) + .unknown_error()?; } else { result.push_str(mut_str); } @@ -778,21 +817,26 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option result = combine_strs_with_missing_comments( context, result.trim_end(), - &mt.ty.rewrite(context, shape)?, + &mt.ty.rewrite_result(context, shape)?, before_ty_span, shape, true, - )?; + ) + .unknown_error()?; } else { let used_width = last_line_width(&result); - let budget = shape.width.checked_sub(used_width)?; - let ty_str = mt - .ty - .rewrite(context, Shape::legacy(budget, shape.indent + used_width))?; + let budget = shape + .width + .checked_sub(used_width) + .max_width_error(shape.width, self.span())?; + let ty_str = mt.ty.rewrite_result( + context, + Shape::legacy(budget, shape.indent + used_width), + )?; result.push_str(&ty_str); } - Some(result) + Ok(result) } // FIXME: we drop any comments here, even though it's a silly place to put // comments. @@ -800,17 +844,20 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option if context.config.version() == Version::One || context.config.indent_style() == IndentStyle::Visual { - let budget = shape.width.checked_sub(2)?; + let budget = shape + .width + .checked_sub(2) + .max_width_error(shape.width, self.span())?; return ty - .rewrite(context, Shape::legacy(budget, shape.indent + 1)) + .rewrite_result(context, Shape::legacy(budget, shape.indent + 1)) .map(|ty_str| format!("({})", ty_str)); } // 2 = () if let Some(sh) = shape.sub_width(2) { - if let Some(ref s) = ty.rewrite(context, sh) { + if let Ok(ref s) = ty.rewrite_result(context, sh) { if !s.contains('\n') { - return Some(format!("({s})")); + return Ok(format!("({s})")); } } } @@ -819,8 +866,8 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option let shape = shape .block_indent(context.config.tab_spaces()) .with_max_width(context.config); - let rw = ty.rewrite(context, shape)?; - Some(format!( + let rw = ty.rewrite_result(context, shape)?; + Ok(format!( "({}{}{})", shape.to_string_with_newline(context.config), rw, @@ -828,17 +875,21 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option )) } ast::TyKind::Slice(ref ty) => { - let budget = shape.width.checked_sub(4)?; - ty.rewrite(context, Shape::legacy(budget, shape.indent + 1)) + let budget = shape + .width + .checked_sub(4) + .max_width_error(shape.width, self.span())?; + ty.rewrite_result(context, Shape::legacy(budget, shape.indent + 1)) .map(|ty_str| format!("[{}]", ty_str)) } ast::TyKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1) + .unknown_error() } - ast::TyKind::AnonStruct(..) => Some(context.snippet(self.span).to_owned()), - ast::TyKind::AnonUnion(..) => Some(context.snippet(self.span).to_owned()), + ast::TyKind::AnonStruct(..) => Ok(context.snippet(self.span).to_owned()), + ast::TyKind::AnonUnion(..) => Ok(context.snippet(self.span).to_owned()), ast::TyKind::Path(ref q_self, ref path) => { - rewrite_path(context, PathContext::Type, q_self, path, shape) + rewrite_path(context, PathContext::Type, q_self, path, shape).unknown_error() } ast::TyKind::Array(ref ty, ref repeats) => rewrite_pair( &**ty, @@ -847,48 +898,53 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option context, shape, SeparatorPlace::Back, - ), + ) + .unknown_error(), ast::TyKind::Infer => { if shape.width >= 1 { - Some("_".to_owned()) + Ok("_".to_owned()) } else { - None + Err(RewriteError::ExceedsMaxWidth { + configured_width: shape.width, + span: self.span(), + }) } } ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape), - ast::TyKind::Never => Some(String::from("!")), + ast::TyKind::Never => Ok(String::from("!")), ast::TyKind::MacCall(ref mac) => { - rewrite_macro(mac, None, context, shape, MacroPosition::Expression) + rewrite_macro(mac, None, context, shape, MacroPosition::Expression).unknown_error() } - ast::TyKind::ImplicitSelf => Some(String::from("")), + ast::TyKind::ImplicitSelf => Ok(String::from("")), ast::TyKind::ImplTrait(_, ref it) => { // Empty trait is not a parser error. if it.is_empty() { - return Some("impl".to_owned()); + return Ok("impl".to_owned()); } let rw = if context.config.version() == Version::One { - it.rewrite(context, shape) + it.rewrite_result(context, shape) } else { - join_bounds(context, shape, it, false) + join_bounds(context, shape, it, false).unknown_error() }; rw.map(|it_str| { let space = if it_str.is_empty() { "" } else { " " }; format!("impl{}{}", space, it_str) }) } - ast::TyKind::CVarArgs => Some("...".to_owned()), - ast::TyKind::Dummy | ast::TyKind::Err(_) => Some(context.snippet(self.span).to_owned()), + ast::TyKind::CVarArgs => Ok("...".to_owned()), + ast::TyKind::Dummy | ast::TyKind::Err(_) => Ok(context.snippet(self.span).to_owned()), ast::TyKind::Typeof(ref anon_const) => rewrite_call( context, "typeof", &[anon_const.value.clone()], self.span, shape, - ), + ) + .unknown_error(), ast::TyKind::Pat(ref ty, ref pat) => { - let ty = ty.rewrite(context, shape)?; - let pat = pat.rewrite(context, shape)?; - Some(format!("{ty} is {pat}")) + let ty = ty.rewrite_result(context, shape)?; + let pat = pat.rewrite_result(context, shape)?; + Ok(format!("{ty} is {pat}")) } } } @@ -899,7 +955,7 @@ fn rewrite_bare_fn( span: Span, context: &RewriteContext<'_>, shape: Shape, -) -> Option { +) -> RewriteResult { debug!("rewrite_bare_fn {:#?}", shape); let mut result = String::with_capacity(128); @@ -923,9 +979,14 @@ fn rewrite_bare_fn( result.push_str("fn"); let func_ty_shape = if context.use_block_indent() { - shape.offset_left(result.len())? + shape + .offset_left(result.len()) + .max_width_error(shape.width, span)? } else { - shape.visual_indent(result.len()).sub_width(result.len())? + shape + .visual_indent(result.len()) + .sub_width(result.len()) + .max_width_error(shape.width, span)? }; let rewrite = format_function_type( @@ -939,7 +1000,7 @@ fn rewrite_bare_fn( result.push_str(&rewrite); - Some(result) + Ok(result) } fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {