Skip to content

Commit 55339f2

Browse files
committed
small cleanup in ConstEvalErr::struct_generic
1 parent 6457b29 commit 55339f2

File tree

1 file changed

+40
-31
lines changed

1 file changed

+40
-31
lines changed

src/librustc/mir/interpret/error.rs

+40-31
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,15 @@ impl<'tcx> ConstEvalErr<'tcx> {
126126
}
127127
}
128128

129-
/// Sets the message passed in via `message` and adds span labels before handing control back
130-
/// to `emit` to do any final processing. It's the caller's responsibility to call emit(),
131-
/// stash(), etc. within the `emit` function to dispose of the diagnostic properly.
129+
/// Create a diagnostic for this const eval error.
130+
///
131+
/// Sets the message passed in via `message` and adds span labels with detailed error
132+
/// information before handing control back to `emit` to do any final processing.
133+
/// It's the caller's responsibility to call emit(), stash(), etc. within the `emit`
134+
/// function to dispose of the diagnostic properly.
135+
///
136+
/// If `lint_root.is_some()` report it as a lint, else report it as a hard error.
137+
/// (Except that for some errors, we ignore all that -- see `must_error` below.)
132138
fn struct_generic(
133139
&self,
134140
tcx: TyCtxtAt<'tcx>,
@@ -141,6 +147,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
141147
return Err(ErrorHandled::TooGeneric);
142148
}
143149
err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
150+
// We must *always* hard error on these, even if the caller wants just a lint.
144151
err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
145152
_ => false,
146153
};
@@ -155,10 +162,11 @@ impl<'tcx> ConstEvalErr<'tcx> {
155162
err => err.to_string(),
156163
};
157164

158-
let add_span_labels = |err: &mut DiagnosticBuilder<'_>| {
159-
if !must_error {
160-
err.span_label(self.span, err_msg.clone());
165+
let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option<String>| {
166+
if let Some(span_msg) = span_msg {
167+
err.span_label(self.span, span_msg);
161168
}
169+
// Add spans for the stacktrace.
162170
// Skip the last, which is just the environment of the constant. The stacktrace
163171
// is sometimes empty because we create "fake" eval contexts in CTFE to do work
164172
// on constant values.
@@ -167,35 +175,36 @@ impl<'tcx> ConstEvalErr<'tcx> {
167175
err.span_label(frame_info.call_site, frame_info.to_string());
168176
}
169177
}
178+
// Let the caller finish the job.
179+
emit(err)
170180
};
171181

172-
if let (Some(lint_root), false) = (lint_root, must_error) {
173-
let hir_id = self
174-
.stacktrace
175-
.iter()
176-
.rev()
177-
.filter_map(|frame| frame.lint_root)
178-
.next()
179-
.unwrap_or(lint_root);
180-
tcx.struct_span_lint_hir(
181-
rustc_session::lint::builtin::CONST_ERR,
182-
hir_id,
183-
tcx.span,
184-
|lint| {
185-
let mut err = lint.build(message);
186-
add_span_labels(&mut err);
187-
emit(err);
188-
},
189-
);
182+
if must_error {
183+
// The `message` makes little sense here, this is a more serious error than the
184+
// caller thinks anyway.
185+
finish(struct_error(tcx, &err_msg), None);
190186
} else {
191-
let mut err = if must_error {
192-
struct_error(tcx, &err_msg)
187+
// Regular case.
188+
if let Some(lint_root) = lint_root {
189+
// Report as lint.
190+
let hir_id = self
191+
.stacktrace
192+
.iter()
193+
.rev()
194+
.filter_map(|frame| frame.lint_root)
195+
.next()
196+
.unwrap_or(lint_root);
197+
tcx.struct_span_lint_hir(
198+
rustc_session::lint::builtin::CONST_ERR,
199+
hir_id,
200+
tcx.span,
201+
|lint| finish(lint.build(message), Some(err_msg)),
202+
);
193203
} else {
194-
struct_error(tcx, message)
195-
};
196-
add_span_labels(&mut err);
197-
emit(err);
198-
};
204+
// Report as hard error.
205+
finish(struct_error(tcx, message), Some(err_msg));
206+
}
207+
}
199208
Ok(())
200209
}
201210
}

0 commit comments

Comments
 (0)