Skip to content

Commit dec05e9

Browse files
committed
Factor decorate closure out into a method
1 parent 98dc76a commit dec05e9

File tree

1 file changed

+65
-70
lines changed
  • compiler/rustc_const_eval/src/const_eval

1 file changed

+65
-70
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

+65-70
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,59 @@ impl<'tcx> ConstEvalErr<'tcx> {
8686
self.report_decorated(tcx, message, |_| {})
8787
}
8888

89+
#[instrument(level = "trace", skip(self, decorate))]
90+
pub(super) fn decorate(&self, err: &mut Diagnostic, decorate: impl FnOnce(&mut Diagnostic)) {
91+
trace!("reporting const eval failure at {:?}", self.span);
92+
// Add some more context for select error types.
93+
match self.error {
94+
InterpError::Unsupported(
95+
UnsupportedOpInfo::ReadPointerAsBytes
96+
| UnsupportedOpInfo::PartialPointerOverwrite(_)
97+
| UnsupportedOpInfo::PartialPointerCopy(_),
98+
) => {
99+
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
100+
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
101+
}
102+
_ => {}
103+
}
104+
// Add spans for the stacktrace. Don't print a single-line backtrace though.
105+
if self.stacktrace.len() > 1 {
106+
// Helper closure to print duplicated lines.
107+
let mut flush_last_line = |last_frame, times| {
108+
if let Some((line, span)) = last_frame {
109+
err.span_note(span, &line);
110+
// Don't print [... additional calls ...] if the number of lines is small
111+
if times < 3 {
112+
for _ in 0..times {
113+
err.span_note(span, &line);
114+
}
115+
} else {
116+
err.span_note(
117+
span,
118+
format!("[... {} additional calls {} ...]", times, &line),
119+
);
120+
}
121+
}
122+
};
123+
124+
let mut last_frame = None;
125+
let mut times = 0;
126+
for frame_info in &self.stacktrace {
127+
let frame = (frame_info.to_string(), frame_info.span);
128+
if last_frame.as_ref() == Some(&frame) {
129+
times += 1;
130+
} else {
131+
flush_last_line(last_frame, times);
132+
last_frame = Some(frame);
133+
times = 0;
134+
}
135+
}
136+
flush_last_line(last_frame, times);
137+
}
138+
// Let the caller attach any additional information it wants.
139+
decorate(err);
140+
}
141+
89142
/// Create a diagnostic for this const eval error.
90143
///
91144
/// Sets the message passed in via `message` and adds span labels with detailed error
@@ -101,88 +154,30 @@ impl<'tcx> ConstEvalErr<'tcx> {
101154
message: &str,
102155
decorate: impl FnOnce(&mut Diagnostic),
103156
) -> ErrorHandled {
104-
let finish = |err: &mut Diagnostic, span_msg: Option<String>| {
105-
trace!("reporting const eval failure at {:?}", self.span);
106-
if let Some(span_msg) = span_msg {
107-
err.span_label(self.span, span_msg);
108-
}
109-
// Add some more context for select error types.
110-
match self.error {
111-
InterpError::Unsupported(
112-
UnsupportedOpInfo::ReadPointerAsBytes
113-
| UnsupportedOpInfo::PartialPointerOverwrite(_)
114-
| UnsupportedOpInfo::PartialPointerCopy(_),
115-
) => {
116-
err.help("this code performed an operation that depends on the underlying bytes representing a pointer");
117-
err.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
118-
}
119-
_ => {}
120-
}
121-
// Add spans for the stacktrace. Don't print a single-line backtrace though.
122-
if self.stacktrace.len() > 1 {
123-
// Helper closure to print duplicated lines.
124-
let mut flush_last_line = |last_frame, times| {
125-
if let Some((line, span)) = last_frame {
126-
err.span_note(span, &line);
127-
// Don't print [... additional calls ...] if the number of lines is small
128-
if times < 3 {
129-
for _ in 0..times {
130-
err.span_note(span, &line);
131-
}
132-
} else {
133-
err.span_note(
134-
span,
135-
format!("[... {} additional calls {} ...]", times, &line),
136-
);
137-
}
138-
}
139-
};
140-
141-
let mut last_frame = None;
142-
let mut times = 0;
143-
for frame_info in &self.stacktrace {
144-
let frame = (frame_info.to_string(), frame_info.span);
145-
if last_frame.as_ref() == Some(&frame) {
146-
times += 1;
147-
} else {
148-
flush_last_line(last_frame, times);
149-
last_frame = Some(frame);
150-
times = 0;
151-
}
152-
}
153-
flush_last_line(last_frame, times);
154-
}
155-
// Let the caller attach any additional information it wants.
156-
decorate(err);
157-
};
158-
159157
debug!("self.error: {:?}", self.error);
160158
// Special handling for certain errors
161159
match &self.error {
162160
// Don't emit a new diagnostic for these errors
163161
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
164-
return ErrorHandled::TooGeneric;
165-
}
166-
err_inval!(AlreadyReported(error_reported)) => {
167-
return ErrorHandled::Reported(*error_reported);
162+
ErrorHandled::TooGeneric
168163
}
164+
err_inval!(AlreadyReported(error_reported)) => ErrorHandled::Reported(*error_reported),
169165
err_inval!(Layout(LayoutError::SizeOverflow(_))) => {
170166
// We must *always* hard error on these, even if the caller wants just a lint.
171167
// The `message` makes little sense here, this is a more serious error than the
172168
// caller thinks anyway.
173169
// See <https://github.com/rust-lang/rust/pull/63152>.
174170
let mut err = struct_error(tcx, &self.error.to_string());
175-
finish(&mut err, None);
176-
return ErrorHandled::Reported(err.emit());
171+
self.decorate(&mut err, decorate);
172+
ErrorHandled::Reported(err.emit())
177173
}
178-
_ => {}
179-
};
180-
181-
let err_msg = self.error.to_string();
182-
183-
// Report as hard error.
184-
let mut err = struct_error(tcx, message);
185-
finish(&mut err, Some(err_msg));
186-
ErrorHandled::Reported(err.emit())
174+
_ => {
175+
// Report as hard error.
176+
let mut err = struct_error(tcx, message);
177+
err.span_label(self.span, self.error.to_string());
178+
self.decorate(&mut err, decorate);
179+
ErrorHandled::Reported(err.emit())
180+
}
181+
}
187182
}
188183
}

0 commit comments

Comments
 (0)