Skip to content

Commit 905ca54

Browse files
ding-youngytmimi
authored andcommitted
add rewrite_result method to Rewrite trait
impl rewrite_result for ast::Local, ast::FieldDef, ast::Param, ast::FnRetTy
1 parent 533b760 commit 905ca54

File tree

3 files changed

+142
-34
lines changed

3 files changed

+142
-34
lines changed

src/items.rs

Lines changed: 113 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::expr::{
2424
use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
2525
use crate::macros::{rewrite_macro, MacroPosition};
2626
use crate::overflow;
27-
use crate::rewrite::{Rewrite, RewriteContext};
27+
use crate::rewrite::{Rewrite, RewriteContext, RewriteError};
2828
use crate::shape::{Indent, Shape};
2929
use crate::source_map::{LineRangeUtils, SpanUtils};
3030
use crate::spanned::Spanned;
@@ -48,18 +48,26 @@ fn type_annotation_separator(config: &Config) -> &str {
4848
// let pat: ty = init; or let pat: ty = init else { .. };
4949
impl Rewrite for ast::Local {
5050
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
51+
self.rewrite_result(context, shape).ok()
52+
}
53+
54+
fn rewrite_result(
55+
&self,
56+
context: &RewriteContext<'_>,
57+
shape: Shape,
58+
) -> Result<String, RewriteError> {
5159
debug!(
5260
"Local::rewrite {:?} {} {:?}",
5361
self, shape.width, shape.indent
5462
);
5563

56-
skip_out_of_file_lines_range!(context, self.span);
64+
skip_out_of_file_lines_range_err!(context, self.span);
5765

5866
if contains_skip(&self.attrs) {
59-
return None;
67+
return Err(RewriteError::SkipFormatting);
6068
}
6169

62-
let attrs_str = self.attrs.rewrite(context, shape)?;
70+
let attrs_str = self.attrs.rewrite_result(context, shape)?;
6371
let mut result = if attrs_str.is_empty() {
6472
"let ".to_owned()
6573
} else {
@@ -73,15 +81,27 @@ impl Rewrite for ast::Local {
7381
),
7482
shape,
7583
false,
76-
)?
84+
)
85+
.ok_or_else(|| RewriteError::Unknown)?
7786
};
7887
let let_kw_offset = result.len() - "let ".len();
7988

8089
// 4 = "let ".len()
81-
let pat_shape = shape.offset_left(4)?;
90+
let pat_shape = shape.offset_left(4).ok_or_else(|| RewriteError::Unknown)?;
8291
// 1 = ;
83-
let pat_shape = pat_shape.sub_width(1)?;
84-
let pat_str = self.pat.rewrite(context, pat_shape)?;
92+
let pat_shape = pat_shape
93+
.sub_width(1)
94+
.ok_or_else(|| RewriteError::ExceedsMaxWidth {
95+
configured_width: shape.width,
96+
span: self.span(),
97+
})?;
98+
let pat_str =
99+
self.pat
100+
.rewrite(context, pat_shape)
101+
.ok_or_else(|| RewriteError::ExceedsMaxWidth {
102+
configured_width: shape.width,
103+
span: self.span(),
104+
})?;
85105
result.push_str(&pat_str);
86106

87107
// String that is placed within the assignment pattern and expression.
@@ -95,11 +115,19 @@ impl Rewrite for ast::Local {
95115
} else {
96116
shape
97117
}
98-
.offset_left(last_line_width(&result) + separator.len())?
118+
.offset_left(last_line_width(&result) + separator.len())
119+
.ok_or_else(|| RewriteError::ExceedsMaxWidth {
120+
configured_width: shape.width,
121+
span: self.span(),
122+
})?
99123
// 2 = ` =`
100-
.sub_width(2)?;
124+
.sub_width(2)
125+
.ok_or_else(|| RewriteError::ExceedsMaxWidth {
126+
configured_width: shape.width,
127+
span: self.span(),
128+
})?;
101129

102-
let rewrite = ty.rewrite(context, ty_shape)?;
130+
let rewrite = ty.rewrite_result(context, ty_shape)?;
103131

104132
infix.push_str(separator);
105133
infix.push_str(&rewrite);
@@ -116,15 +144,16 @@ impl Rewrite for ast::Local {
116144

117145
if let Some((init, else_block)) = self.kind.init_else_opt() {
118146
// 1 = trailing semicolon;
119-
let nested_shape = shape.sub_width(1)?;
147+
let nested_shape = shape.sub_width(1).ok_or_else(|| RewriteError::Unknown)?;
120148

121149
result = rewrite_assign_rhs(
122150
context,
123151
result,
124152
init,
125153
&RhsAssignKind::Expr(&init.kind, init.span),
126154
nested_shape,
127-
)?;
155+
)
156+
.ok_or_else(|| RewriteError::Unknown)?;
128157

129158
if let Some(block) = else_block {
130159
let else_kw_span = init.span.between(block.span);
@@ -166,7 +195,8 @@ impl Rewrite for ast::Local {
166195
&& allow_single_line_let_else_block(assign_str_with_else_kw, block);
167196

168197
let mut rw_else_block =
169-
rewrite_let_else_block(block, allow_single_line, context, shape)?;
198+
rewrite_let_else_block(block, allow_single_line, context, shape)
199+
.ok_or_else(|| RewriteError::Unknown)?;
170200

171201
let single_line_else = !rw_else_block.contains('\n');
172202
// +1 for the trailing `;`
@@ -175,15 +205,16 @@ impl Rewrite for ast::Local {
175205
if allow_single_line && single_line_else && else_block_exceeds_width {
176206
// writing this on one line would exceed the available width
177207
// so rewrite the else block over multiple lines.
178-
rw_else_block = rewrite_let_else_block(block, false, context, shape)?;
208+
rw_else_block = rewrite_let_else_block(block, false, context, shape)
209+
.ok_or_else(|| RewriteError::Unknown)?;
179210
}
180211

181212
result.push_str(&rw_else_block);
182213
};
183214
}
184215

185216
result.push(';');
186-
Some(result)
217+
Ok(result)
187218
}
188219
}
189220

@@ -1845,7 +1876,15 @@ pub(crate) fn rewrite_struct_field_prefix(
18451876

18461877
impl Rewrite for ast::FieldDef {
18471878
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
1848-
rewrite_struct_field(context, self, shape, 0)
1879+
self.rewrite_result(context, shape).ok()
1880+
}
1881+
1882+
fn rewrite_result(
1883+
&self,
1884+
context: &RewriteContext<'_>,
1885+
shape: Shape,
1886+
) -> Result<String, RewriteError> {
1887+
rewrite_struct_field(context, self, shape, 0).ok_or_else(|| RewriteError::Unknown)
18491888
}
18501889
}
18511890

@@ -2071,20 +2110,40 @@ impl<'a> Rewrite for OpaqueType<'a> {
20712110

20722111
impl Rewrite for ast::FnRetTy {
20732112
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
2113+
self.rewrite_result(context, shape).ok()
2114+
}
2115+
fn rewrite_result(
2116+
&self,
2117+
context: &RewriteContext<'_>,
2118+
shape: Shape,
2119+
) -> Result<String, RewriteError> {
20742120
match *self {
2075-
ast::FnRetTy::Default(_) => Some(String::new()),
2121+
ast::FnRetTy::Default(_) => Ok(String::new()),
20762122
ast::FnRetTy::Ty(ref ty) => {
20772123
if context.config.version() == Version::One
20782124
|| context.config.indent_style() == IndentStyle::Visual
20792125
{
2080-
let inner_width = shape.width.checked_sub(3)?;
2126+
let inner_width = shape.width.checked_sub(3).ok_or_else(|| {
2127+
RewriteError::ExceedsMaxWidth {
2128+
configured_width: shape.width,
2129+
span: self.span(),
2130+
}
2131+
})?;
20812132
return ty
2082-
.rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
2133+
.rewrite_result(context, Shape::legacy(inner_width, shape.indent + 3))
20832134
.map(|r| format!("-> {}", r));
20842135
}
20852136

2086-
ty.rewrite(context, shape.offset_left(3)?)
2087-
.map(|s| format!("-> {}", s))
2137+
ty.rewrite_result(
2138+
context,
2139+
shape
2140+
.offset_left(3)
2141+
.ok_or_else(|| RewriteError::ExceedsMaxWidth {
2142+
configured_width: shape.width,
2143+
span: self.span(),
2144+
})?,
2145+
)
2146+
.map(|s| format!("-> {}", s))
20882147
}
20892148
}
20902149
}
@@ -2135,9 +2194,17 @@ fn get_missing_param_comments(
21352194

21362195
impl Rewrite for ast::Param {
21372196
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
2197+
self.rewrite_result(context, shape).ok()
2198+
}
2199+
2200+
fn rewrite_result(
2201+
&self,
2202+
context: &RewriteContext<'_>,
2203+
shape: Shape,
2204+
) -> Result<String, RewriteError> {
21382205
let param_attrs_result = self
21392206
.attrs
2140-
.rewrite(context, Shape::legacy(shape.width, shape.indent))?;
2207+
.rewrite_result(context, Shape::legacy(shape.width, shape.indent))?;
21412208
// N.B. Doc comments aren't typically valid syntax, but could appear
21422209
// in the presence of certain macros - https://github.com/rust-lang/rustfmt/issues/4936
21432210
let (span, has_multiple_attr_lines, has_doc_comments) = if !self.attrs.is_empty() {
@@ -2160,18 +2227,20 @@ impl Rewrite for ast::Param {
21602227
shape,
21612228
has_multiple_attr_lines,
21622229
)
2230+
.ok_or_else(|| RewriteError::Unknown)
21632231
} else if is_named_param(self) {
21642232
let param_name = &self
21652233
.pat
2166-
.rewrite(context, Shape::legacy(shape.width, shape.indent))?;
2234+
.rewrite_result(context, Shape::legacy(shape.width, shape.indent))?;
21672235
let mut result = combine_strs_with_missing_comments(
21682236
context,
21692237
&param_attrs_result,
21702238
param_name,
21712239
span,
21722240
shape,
21732241
!has_multiple_attr_lines && !has_doc_comments,
2174-
)?;
2242+
)
2243+
.ok_or_else(|| RewriteError::Unknown)?;
21752244

21762245
if !is_empty_infer(&*self.ty, self.pat.span) {
21772246
let (before_comment, after_comment) =
@@ -2180,10 +2249,15 @@ impl Rewrite for ast::Param {
21802249
result.push_str(colon_spaces(context.config));
21812250
result.push_str(&after_comment);
21822251
let overhead = last_line_width(&result);
2183-
let max_width = shape.width.checked_sub(overhead)?;
2184-
if let Some(ty_str) = self
2252+
let max_width = shape.width.checked_sub(overhead).ok_or_else(|| {
2253+
RewriteError::ExceedsMaxWidth {
2254+
configured_width: shape.width,
2255+
span: self.span(),
2256+
}
2257+
})?;
2258+
if let Ok(ty_str) = self
21852259
.ty
2186-
.rewrite(context, Shape::legacy(max_width, shape.indent))
2260+
.rewrite_result(context, Shape::legacy(max_width, shape.indent))
21872261
{
21882262
result.push_str(&ty_str);
21892263
} else {
@@ -2200,22 +2274,28 @@ impl Rewrite for ast::Param {
22002274
span,
22012275
shape,
22022276
!has_multiple_attr_lines,
2203-
)?;
2277+
)
2278+
.ok_or_else(|| RewriteError::Unknown)?;
22042279
result.push_str(&before_comment);
22052280
result.push_str(colon_spaces(context.config));
22062281
result.push_str(&after_comment);
22072282
let overhead = last_line_width(&result);
2208-
let max_width = shape.width.checked_sub(overhead)?;
2283+
let max_width = shape.width.checked_sub(overhead).ok_or_else(|| {
2284+
RewriteError::ExceedsMaxWidth {
2285+
configured_width: shape.width,
2286+
span: self.span(),
2287+
}
2288+
})?;
22092289
let ty_str = self
22102290
.ty
2211-
.rewrite(context, Shape::legacy(max_width, shape.indent))?;
2291+
.rewrite_result(context, Shape::legacy(max_width, shape.indent))?;
22122292
result.push_str(&ty_str);
22132293
}
22142294
}
22152295

2216-
Some(result)
2296+
Ok(result)
22172297
} else {
2218-
self.ty.rewrite(context, shape)
2298+
self.ty.rewrite_result(context, shape)
22192299
}
22202300
}
22212301
}

src/rewrite.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::rc::Rc;
55

66
use rustc_ast::ptr;
77
use rustc_span::Span;
8+
use thiserror::Error;
89

910
use crate::config::{Config, IndentStyle};
1011
use crate::parse::session::ParseSess;
@@ -16,6 +17,13 @@ use crate::FormatReport;
1617
pub(crate) trait Rewrite {
1718
/// Rewrite self into shape.
1819
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>;
20+
fn rewrite_result(
21+
&self,
22+
context: &RewriteContext<'_>,
23+
shape: Shape,
24+
) -> Result<String, RewriteError> {
25+
self.rewrite(context, shape).ok_or(RewriteError::Unknown)
26+
}
1927
}
2028

2129
impl<T: Rewrite> Rewrite for ptr::P<T> {
@@ -24,6 +32,19 @@ impl<T: Rewrite> Rewrite for ptr::P<T> {
2432
}
2533
}
2634

35+
#[derive(Error, Debug)]
36+
pub(crate) enum RewriteError {
37+
#[error("Formatting was skipped due to skip attribute or out of file range.")]
38+
SkipFormatting,
39+
40+
#[error("It exceeds the required width of {configured_width} for the span: {span:?}")]
41+
ExceedsMaxWidth { configured_width: usize, span: Span },
42+
43+
/// Format failure that does not fit to above categories.
44+
#[error("An unknown error occurred during formatting.")]
45+
Unknown,
46+
}
47+
2748
#[derive(Clone)]
2849
pub(crate) struct RewriteContext<'a> {
2950
pub(crate) psess: &'a ParseSess,
@@ -44,7 +65,6 @@ pub(crate) struct RewriteContext<'a> {
4465
pub(crate) skip_context: SkipContext,
4566
pub(crate) skipped_range: Rc<RefCell<Vec<(usize, usize)>>>,
4667
}
47-
4868
pub(crate) struct InsideMacroGuard {
4969
is_nested_macro_context: bool,
5070
inside_macro_ref: Rc<Cell<bool>>,

src/utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,14 @@ macro_rules! skip_out_of_file_lines_range {
375375
};
376376
}
377377

378+
macro_rules! skip_out_of_file_lines_range_err {
379+
($self:ident, $span:expr) => {
380+
if out_of_file_lines_range!($self, $span) {
381+
return Err(RewriteError::SkipFormatting);
382+
}
383+
};
384+
}
385+
378386
macro_rules! skip_out_of_file_lines_range_visitor {
379387
($self:ident, $span:expr) => {
380388
if out_of_file_lines_range!($self, $span) {

0 commit comments

Comments
 (0)