Skip to content

Commit 266b878

Browse files
committed
clean up
1 parent 0e668e0 commit 266b878

File tree

2 files changed

+162
-68
lines changed

2 files changed

+162
-68
lines changed

src/librustc_errors/emitter.rs

Lines changed: 157 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,80 @@ impl HumanReadableErrorType {
5757
}
5858
}
5959

60+
#[derive(Clone, Copy, Debug)]
61+
struct Margin {
62+
pub whitespace_left: usize,
63+
pub span_left: usize,
64+
pub span_right: usize,
65+
pub line_len: usize,
66+
pub computed_left: usize,
67+
pub computed_right: usize,
68+
pub column_width: usize,
69+
pub label_right: usize,
70+
}
71+
72+
impl Margin {
73+
fn new(
74+
whitespace_left: usize,
75+
span_left: usize,
76+
span_right: usize,
77+
label_right: usize,
78+
) -> Self {
79+
Margin {
80+
whitespace_left,
81+
span_left,
82+
span_right,
83+
line_len: 0,
84+
computed_left: 0,
85+
computed_right: 0,
86+
column_width: 140,
87+
label_right,
88+
}
89+
}
90+
91+
fn was_cut_left(&self) -> bool {
92+
self.computed_left > 0
93+
}
94+
95+
fn was_cut_right(&self) -> bool {
96+
self.computed_right < self.line_len
97+
}
98+
99+
fn compute(&mut self) {
100+
self.computed_left = if self.whitespace_left > 20 {
101+
self.whitespace_left - 16 // We want some padding.
102+
} else {
103+
0
104+
};
105+
self.computed_right = self.column_width + self.computed_left;
106+
107+
if self.computed_right - self.computed_left > self.column_width {
108+
// Trimming only whitespace isn't enough, let's get craftier.
109+
if self.label_right - self.whitespace_left <= self.column_width {
110+
self.computed_left = self.whitespace_left;
111+
self.computed_right = self.computed_left + self.column_width;
112+
} else if self.label_right - self.span_left - 20 <= self.column_width {
113+
self.computed_left = self.span_left - 20;
114+
self.computed_right = self.computed_left + self.column_width;
115+
} else if self.label_right - self.span_left <= self.column_width {
116+
self.computed_left = self.span_left;
117+
self.computed_right = self.computed_left + self.column_width;
118+
} else if self.span_right - self.span_left <= self.column_width {
119+
self.computed_left = self.span_left;
120+
self.computed_right = self.computed_left + self.column_width;
121+
} else { // mostly give up but still don't show the full line
122+
self.computed_left = self.span_left;
123+
self.computed_right = self.span_right;
124+
}
125+
}
126+
self.computed_left = std::cmp::min(self.computed_left, self.line_len);
127+
if self.computed_right > self.line_len {
128+
self.computed_right = self.line_len;
129+
}
130+
self.computed_right = std::cmp::min(self.computed_right, self.line_len);
131+
}
132+
}
133+
60134
const ANONYMIZED_LINE_NUM: &str = "LL";
61135

62136
/// Emitter trait for emitting errors.
@@ -179,7 +253,6 @@ pub struct EmitterWriter {
179253
sm: Option<Lrc<SourceMapperDyn>>,
180254
short_message: bool,
181255
teach: bool,
182-
strip_margin: bool,
183256
ui_testing: bool,
184257
}
185258

@@ -202,7 +275,6 @@ impl EmitterWriter {
202275
sm: source_map,
203276
short_message,
204277
teach,
205-
strip_margin: false,
206278
ui_testing: false,
207279
}
208280
}
@@ -219,7 +291,6 @@ impl EmitterWriter {
219291
sm: source_map,
220292
short_message,
221293
teach,
222-
strip_margin: false,
223294
ui_testing: false,
224295
}
225296
}
@@ -244,8 +315,7 @@ impl EmitterWriter {
244315
line: &Line,
245316
width_offset: usize,
246317
code_offset: usize,
247-
margin: usize,
248-
right_span_margin: usize
318+
mut margin: Margin,
249319
) -> Vec<(usize, Style)> {
250320
// Draw:
251321
//
@@ -260,6 +330,7 @@ impl EmitterWriter {
260330
// | | when there's too much wasted space to the left, we trim it to focus where it matters
261331
// | vertical divider between the column number and the code
262332
// column number
333+
263334
if line.line_index == 0 {
264335
return Vec::new();
265336
}
@@ -271,26 +342,27 @@ impl EmitterWriter {
271342

272343
let line_offset = buffer.num_lines();
273344

274-
let left_margin = std::cmp::min(margin, source_string.len());
275-
let right_margin = if source_string.len() > right_span_margin + 120 {
276-
right_span_margin + 120
277-
} else {
278-
source_string.len()
279-
};
345+
margin.line_len = source_string.len();
346+
margin.compute();
280347
// Create the source line we will highlight.
281348
buffer.puts(
282349
line_offset,
283350
code_offset,
284-
&source_string[left_margin..right_margin], // On long lines, we strip the source line
351+
// On long lines, we strip the source line
352+
&source_string[margin.computed_left..margin.computed_right],
285353
Style::Quotation,
286354
);
287-
if margin > 0 { // We have stripped some code/whitespace from the beginning, make it clear.
355+
if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear.
288356
buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
289357
}
290-
if right_margin != source_string.len() {
358+
if margin.was_cut_right() {
291359
// We have stripped some code after the right-most span end, make it clear we did so.
292-
let offset = code_offset + right_margin - left_margin;
293-
buffer.puts(line_offset, offset, "...", Style::LineNumber);
360+
buffer.puts(
361+
line_offset,
362+
margin.computed_right - margin.computed_left + code_offset,
363+
"...",
364+
Style::LineNumber,
365+
);
294366
}
295367
buffer.puts(line_offset, 0, &self.maybe_anonymized(line.line_index), Style::LineNumber);
296368

@@ -546,13 +618,13 @@ impl EmitterWriter {
546618
'_',
547619
line_offset + pos,
548620
width_offset + depth,
549-
code_offset + annotation.start_col - margin,
621+
code_offset + annotation.start_col - margin.computed_left,
550622
style);
551623
}
552624
_ if self.teach => {
553625
buffer.set_style_range(line_offset,
554-
code_offset + annotation.start_col - margin,
555-
code_offset + annotation.end_col - margin,
626+
code_offset + annotation.start_col - margin.computed_left,
627+
code_offset + annotation.end_col - margin.computed_left,
556628
style,
557629
annotation.is_primary);
558630
}
@@ -582,7 +654,7 @@ impl EmitterWriter {
582654
if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
583655
for p in line_offset + 1..=line_offset + pos {
584656
buffer.putc(p,
585-
code_offset + annotation.start_col - margin,
657+
code_offset + annotation.start_col - margin.computed_left,
586658
'|',
587659
style);
588660
}
@@ -626,9 +698,9 @@ impl EmitterWriter {
626698
Style::LabelSecondary
627699
};
628700
let (pos, col) = if pos == 0 {
629-
(pos + 1, annotation.end_col + 1 - margin)
701+
(pos + 1, annotation.end_col + 1 - margin.computed_left)
630702
} else {
631-
(pos + 2, annotation.start_col - margin)
703+
(pos + 2, annotation.start_col - margin.computed_left)
632704
};
633705
if let Some(ref label) = annotation.label {
634706
buffer.puts(line_offset + pos,
@@ -670,7 +742,7 @@ impl EmitterWriter {
670742
};
671743
for p in annotation.start_col..annotation.end_col {
672744
buffer.putc(line_offset + 1,
673-
code_offset + p - margin,
745+
code_offset + p - margin.computed_left,
674746
underline,
675747
style);
676748
}
@@ -1010,22 +1082,30 @@ impl EmitterWriter {
10101082
let buffer_msg_line_offset = buffer.num_lines();
10111083

10121084
buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber);
1013-
buffer.append(buffer_msg_line_offset,
1014-
&format!("{}:{}:{}",
1015-
loc.file.name,
1016-
sm.doctest_offset_line(&loc.file.name, loc.line),
1017-
loc.col.0 + 1),
1018-
Style::LineAndColumn);
1085+
buffer.append(
1086+
buffer_msg_line_offset,
1087+
&format!(
1088+
"{}:{}:{}",
1089+
loc.file.name,
1090+
sm.doctest_offset_line(&loc.file.name, loc.line),
1091+
loc.col.0 + 1,
1092+
),
1093+
Style::LineAndColumn,
1094+
);
10191095
for _ in 0..max_line_num_len {
10201096
buffer.prepend(buffer_msg_line_offset, " ", Style::NoStyle);
10211097
}
10221098
} else {
1023-
buffer.prepend(0,
1024-
&format!("{}:{}:{}: ",
1025-
loc.file.name,
1026-
sm.doctest_offset_line(&loc.file.name, loc.line),
1027-
loc.col.0 + 1),
1028-
Style::LineAndColumn);
1099+
buffer.prepend(
1100+
0,
1101+
&format!(
1102+
"{}:{}:{}: ",
1103+
loc.file.name,
1104+
sm.doctest_offset_line(&loc.file.name, loc.line),
1105+
loc.col.0 + 1,
1106+
),
1107+
Style::LineAndColumn,
1108+
);
10291109
}
10301110
} else if !self.short_message {
10311111
// remember where we are in the output buffer for easy reference
@@ -1069,7 +1149,7 @@ impl EmitterWriter {
10691149
let mut multilines = FxHashMap::default();
10701150

10711151
// Get the left-side margin to remove it
1072-
let mut margin = std::usize::MAX;
1152+
let mut whitespace_margin = std::usize::MAX;
10731153
for line_idx in 0..annotated_file.lines.len() {
10741154
let file = annotated_file.file.clone();
10751155
let line = &annotated_file.lines[line_idx];
@@ -1079,14 +1159,15 @@ impl EmitterWriter {
10791159
.take_while(|c| c.is_whitespace())
10801160
.count();
10811161
if source_string.chars().any(|c| !c.is_whitespace()) {
1082-
margin = std::cmp::min(margin, leading_whitespace);
1162+
whitespace_margin = std::cmp::min(
1163+
whitespace_margin,
1164+
leading_whitespace,
1165+
);
10831166
}
10841167
}
10851168
}
1086-
if margin >= 20 { // On errors with generous margins, trim it
1087-
margin = margin - 16; // Keep at least 4 spaces margin
1088-
} else if margin == std::usize::MAX || !self.strip_margin {
1089-
margin = 0;
1169+
if whitespace_margin == std::usize::MAX {
1170+
whitespace_margin = 0;
10901171
}
10911172

10921173
// Left-most column any visible span points at.
@@ -1100,18 +1181,27 @@ impl EmitterWriter {
11001181
if span_left_margin == std::usize::MAX {
11011182
span_left_margin = 0;
11021183
}
1103-
if span_left_margin > 160 {
1104-
margin = std::cmp::max(margin, span_left_margin - 100);
1105-
}
11061184

11071185
// Right-most column any visible span points at.
11081186
let mut span_right_margin = 0;
1187+
let mut label_right_margin = 0;
11091188
for line in &annotated_file.lines {
11101189
for ann in &line.annotations {
11111190
span_right_margin = std::cmp::max(span_right_margin, ann.start_col);
11121191
span_right_margin = std::cmp::max(span_right_margin, ann.end_col);
1192+
label_right_margin = std::cmp::max(
1193+
label_right_margin,
1194+
// TODO: account for labels not in the same line
1195+
ann.end_col + ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0),
1196+
);
11131197
}
11141198
}
1199+
let margin = Margin::new(
1200+
whitespace_margin,
1201+
span_left_margin,
1202+
span_right_margin,
1203+
label_right_margin,
1204+
);
11151205

11161206
// Next, output the annotate source for this file
11171207
for line_idx in 0..annotated_file.lines.len() {
@@ -1131,7 +1221,6 @@ impl EmitterWriter {
11311221
width_offset,
11321222
code_offset,
11331223
margin,
1134-
span_right_margin,
11351224
);
11361225

11371226
let mut to_add = FxHashMap::default();
@@ -1179,24 +1268,29 @@ impl EmitterWriter {
11791268

11801269
let last_buffer_line_num = buffer.num_lines();
11811270

1182-
buffer.puts(last_buffer_line_num,
1183-
0,
1184-
&self.maybe_anonymized(annotated_file.lines[line_idx + 1]
1185-
.line_index - 1),
1186-
Style::LineNumber);
1187-
draw_col_separator(&mut buffer,
1188-
last_buffer_line_num,
1189-
1 + max_line_num_len);
1190-
let left_margin = std::cmp::min(margin, unannotated_line.len());
1191-
let right_margin = if unannotated_line.len() > span_right_margin + 120 {
1192-
span_right_margin + 120
1193-
} else {
1194-
unannotated_line.len()
1195-
};
1196-
buffer.puts(last_buffer_line_num,
1197-
code_offset,
1198-
&unannotated_line[left_margin..right_margin],
1199-
Style::Quotation);
1271+
buffer.puts(
1272+
last_buffer_line_num,
1273+
0,
1274+
&self.maybe_anonymized(
1275+
annotated_file.lines[line_idx + 1].line_index - 1,
1276+
),
1277+
Style::LineNumber,
1278+
);
1279+
draw_col_separator(
1280+
&mut buffer,
1281+
last_buffer_line_num,
1282+
1 + max_line_num_len,
1283+
);
1284+
1285+
let mut margin = margin;
1286+
margin.line_len = unannotated_line.len();
1287+
margin.compute();
1288+
buffer.puts(
1289+
last_buffer_line_num,
1290+
code_offset,
1291+
&unannotated_line[margin.computed_left..margin.computed_right],
1292+
Style::Quotation,
1293+
);
12001294

12011295
for (depth, style) in &multilines {
12021296
draw_multiline_line(&mut buffer,

src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0499]: cannot borrow `*f` as mutable more than once at a time
22
--> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:20:27
33
|
4-
LL | ... (f.c)(f, true);
5-
| ----- ^ second mutable borrow occurs here
6-
| |
7-
| first mutable borrow occurs here
8-
| first borrow later used by call
4+
LL | (f.c)(f, true);
5+
| ----- ^ second mutable borrow occurs here
6+
| |
7+
| first mutable borrow occurs here
8+
| first borrow later used by call
99

1010
error[E0382]: borrow of moved value: `f`
1111
--> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:32:5

0 commit comments

Comments
 (0)