sess.diagnostic().delay_span_bug(
span,
"unexpected delimiter in key-value attribute's value",
- )
+ );
}
unwrap_single_token(sess, tokens, span)
}
attr.span,
"allow, cfg, cfg_attr, deny, \
forbid, and warn are the only allowed built-in attributes in function parameters",
- )
+ );
}
});
}
"wasm ABI is experimental and subject to change"
);
}
- abi => self
- .sess
- .parse_sess
- .span_diagnostic
- .delay_span_bug(span, &format!("unrecognized ABI not caught in lowering: {}", abi)),
+ abi => {
+ self.sess.parse_sess.span_diagnostic.delay_span_bug(
+ span,
+ &format!("unrecognized ABI not caught in lowering: {}", abi),
+ );
+ }
}
}
// Gather the upvars of a closure, if any.
let tables = tcx.typeck_opt_const_arg(def);
- if let Some(ErrorGuaranteed) = tables.tainted_by_errors {
+ if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
infcx.set_tainted_by_errors();
errors.set_tainted_by_errors();
}
}
mod error {
+ use rustc_errors::ErrorGuaranteed;
+
use super::*;
pub struct BorrowckErrors<'tcx> {
// FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
// set before any emission actually happens (weakening the guarantee).
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
- self.tainted_by_errors = Some(ErrorGuaranteed {});
+ self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
t.buffer(&mut self.buffered);
}
}
pub fn set_tainted_by_errors(&mut self) {
- self.tainted_by_errors = Some(ErrorGuaranteed {});
+ self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
}
//! Handling of `static`s, `const`s and promoted allocations
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::ErrorGuaranteed;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{
read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
{
all_constants_ok = false;
match err {
- ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {
+ ErrorHandled::Reported(_) | ErrorHandled::Linted => {
fx.tcx.sess.span_err(constant.span, "erroneous constant encountered");
}
ErrorHandled::TooGeneric => {
use crate::traits::*;
-use rustc_errors::ErrorGuaranteed;
use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
all_consts_ok = false;
match err {
// errored or at least linted
- ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {}
+ ErrorHandled::Reported(_) | ErrorHandled::Linted => {}
ErrorHandled::TooGeneric => {
span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err)
}
-use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty};
if ecx.tcx.is_ctfe_mir_available(def.did) {
Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
} else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst {
- ecx.tcx.sess.delay_span_bug(
+ let guar = ecx.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"This is likely a const item that is missing from its impl",
);
- throw_inval!(AlreadyReported(ErrorGuaranteed {}));
+ throw_inval!(AlreadyReported(guar));
} else {
let path = ecx.tcx.def_path_str(def.did);
Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path))
} else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) {
// Codegen does not like dangling pointers, and generally `tcx` assumes that
// all allocations referenced anywhere actually exist. So, make sure we error here.
- ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant");
- return Err(ErrorGuaranteed);
+ let reported = ecx
+ .tcx
+ .sess
+ .span_err(ecx.tcx.span, "encountered dangling pointer in final constant");
+ return Err(reported);
} else if ecx.tcx.get_global_alloc(alloc_id).is_none() {
// We have hit an `AllocId` that is neither in local or global memory and isn't
// marked as dangling by local memory. That should be impossible.
use std::convert::TryFrom;
use std::fmt::Write;
-use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::Namespace;
use rustc_macros::HashStable;
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
-use rustc_middle::ty::{ConstInt, Ty};
+use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
use rustc_middle::{mir, ty};
use rustc_target::abi::{Abi, HasDataLayout, Size, TagEncoding};
use rustc_target::abi::{VariantIdx, Variants};
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val.val() {
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
- ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorGuaranteed)),
+ ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => {
+ throw_inval!(AlreadyReported(reported))
+ }
ty::ConstKind::Unevaluated(uv) => {
let instance = self.resolve(uv.def, uv.substs)?;
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
self.tcx.sess.diagnostic().emit_diagnostic(&error);
}
} else {
- assert!(self.tcx.sess.has_errors());
+ assert!(self.tcx.sess.has_errors().is_some());
}
}
match op.importance() {
ops::DiagnosticImportance::Primary => {
- self.error_emitted = Some(ErrorGuaranteed);
- err.emit();
+ let reported = err.emit();
+ self.error_emitted = Some(reported);
}
ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors),
};
match make_input(config.opts.error_format, &matches.free) {
- Err(ErrorGuaranteed) => return Err(ErrorGuaranteed),
+ Err(reported) => return Err(reported),
Ok(Some((input, input_file_path))) => {
config.input = input;
config.input_path = input_file_path;
if io::stdin().read_to_string(&mut src).is_err() {
// Immediately stop compilation if there was an issue reading
// the input (for example if the input stream is not UTF-8).
- early_error_no_abort(
+ let reported = early_error_no_abort(
error_format,
"couldn't read from stdin, as it did not contain valid UTF-8",
);
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuaranteed> {
catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| {
if value.is::<rustc_errors::FatalErrorMarker>() {
- ErrorGuaranteed
+ ErrorGuaranteed::unchecked_claim_error_was_emitted()
} else {
panic::resume_unwind(value);
}
DiagnosticBuilderState::Emittable(handler) => {
db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
- handler.emit_diagnostic(&db.inner.diagnostic);
+ let guar = handler.emit_diagnostic(&db.inner.diagnostic);
// Only allow a guarantee if the `level` wasn't switched to a
// non-error - the field isn't `pub`, but the whole `Diagnostic`
from `DiagnosticBuilder<ErrorGuaranteed>`",
db.inner.diagnostic.level,
);
- ErrorGuaranteed
+ guar.unwrap()
}
// `.emit()` was previously called, disallowed from repeating it,
// but can take advantage of the previous `.emit()`'s guarantee
became non-error ({:?}), after original `.emit()`",
db.inner.diagnostic.level,
);
- ErrorGuaranteed
+ ErrorGuaranteed::unchecked_claim_error_was_emitted()
}
}
}
impl error::Error for ExplicitBug {}
pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic};
-pub use diagnostic_builder::DiagnosticBuilder;
+pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
use std::backtrace::Backtrace;
/// A handler deals with errors and other compiler output.
}
/// Emit all stashed diagnostics.
- pub fn emit_stashed_diagnostics(&self) {
- self.inner.borrow_mut().emit_stashed_diagnostics();
+ pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
+ self.inner.borrow_mut().emit_stashed_diagnostics()
}
/// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
FatalError.raise()
}
- pub fn span_err(&self, span: impl Into<MultiSpan>, msg: &str) {
- self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span);
+ pub fn span_err(&self, span: impl Into<MultiSpan>, msg: &str) -> ErrorGuaranteed {
+ self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap()
}
pub fn span_err_with_code(&self, span: impl Into<MultiSpan>, msg: &str, code: DiagnosticId) {
}
#[track_caller]
- pub fn delay_span_bug(&self, span: impl Into<MultiSpan>, msg: &str) {
+ pub fn delay_span_bug(&self, span: impl Into<MultiSpan>, msg: &str) -> ErrorGuaranteed {
self.inner.borrow_mut().delay_span_bug(span, msg)
}
self.inner.borrow_mut().fatal(msg)
}
- pub fn err(&self, msg: &str) {
- self.inner.borrow_mut().err(msg);
+ pub fn err(&self, msg: &str) -> ErrorGuaranteed {
+ self.inner.borrow_mut().err(msg)
}
pub fn warn(&self, msg: &str) {
self.inner.borrow().err_count()
}
- pub fn has_errors(&self) -> bool {
- self.inner.borrow().has_errors()
+ pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
+ if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None }
}
- pub fn has_errors_or_lint_errors(&self) -> bool {
- self.inner.borrow().has_errors_or_lint_errors()
+ pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
+ if self.inner.borrow().has_errors_or_lint_errors() {
+ Some(ErrorGuaranteed(()))
+ } else {
+ None
+ }
}
pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
self.inner.borrow().has_errors_or_delayed_span_bugs()
self.inner.borrow_mut().force_print_diagnostic(db)
}
- pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
+ pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> {
self.inner.borrow_mut().emit_diagnostic(diagnostic)
}
- fn emit_diag_at_span(&self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) {
+ fn emit_diag_at_span(
+ &self,
+ mut diag: Diagnostic,
+ sp: impl Into<MultiSpan>,
+ ) -> Option<ErrorGuaranteed> {
let mut inner = self.inner.borrow_mut();
- inner.emit_diagnostic(diag.set_span(sp));
+ inner.emit_diagnostic(diag.set_span(sp))
}
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
}
/// Emit all stashed diagnostics.
- fn emit_stashed_diagnostics(&mut self) {
+ fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
- diags.iter().for_each(|diag| self.emit_diagnostic(diag));
+ let mut reported = None;
+ diags.iter().for_each(|diag| {
+ if diag.is_error() {
+ reported = Some(ErrorGuaranteed(()));
+ }
+ self.emit_diagnostic(diag);
+ });
+ reported
}
// FIXME(eddyb) this should ideally take `diagnostic` by value.
- fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) {
+ fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option<ErrorGuaranteed> {
if diagnostic.level == Level::DelayedBug {
// FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `delayed_span_bugs`
self.delayed_span_bugs.push(diagnostic.clone());
if !self.flags.report_delayed_bugs {
- return;
+ return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
}
if diagnostic.has_future_breakage() {
(*TRACK_DIAGNOSTICS)(diagnostic);
}
- return;
+ return None;
}
// The `LintExpectationId` can be stable or unstable depending on when it was created.
// a stable one by the `LintLevelsBuilder`.
if let Level::Expect(LintExpectationId::Unstable { .. }) = diagnostic.level {
self.unstable_expect_diagnostics.push(diagnostic.clone());
- return;
+ return None;
}
(*TRACK_DIAGNOSTICS)(diagnostic);
if let Level::Expect(expectation_id) = diagnostic.level {
self.fulfilled_expectations.insert(expectation_id);
- return;
+ return None;
} else if diagnostic.level == Allow {
- return;
+ return None;
}
if let Some(ref code) = diagnostic.code {
} else {
self.bump_err_count();
}
+
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
} else {
self.bump_warn_count();
+
+ None
}
}
}
#[track_caller]
- fn delay_span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) {
+ fn delay_span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> ErrorGuaranteed {
// This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before
// incrementing `err_count` by one, so we need to +1 the comparing.
// FIXME: Would be nice to increment err_count in a more coherent way.
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
diagnostic.set_span(sp.into());
diagnostic.note(&format!("delayed at {}", std::panic::Location::caller()));
- self.emit_diagnostic(&diagnostic)
+ self.emit_diagnostic(&diagnostic).unwrap()
}
// FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
}
fn fatal(&mut self, msg: &str) -> FatalError {
- self.emit_error(Fatal, msg);
+ self.emit(Fatal, msg);
FatalError
}
- fn err(&mut self, msg: &str) {
- self.emit_error(Error { lint: false }, msg);
+ fn err(&mut self, msg: &str) -> ErrorGuaranteed {
+ self.emit(Error { lint: false }, msg)
}
/// Emit an error; level should be `Error` or `Fatal`.
- fn emit_error(&mut self, level: Level, msg: &str) {
+ fn emit(&mut self, level: Level, msg: &str) -> ErrorGuaranteed {
if self.treat_err_as_bug() {
self.bug(msg);
}
- self.emit_diagnostic(&Diagnostic::new(level, msg));
+ self.emit_diagnostic(&Diagnostic::new(level, msg)).unwrap()
}
fn bug(&mut self, msg: &str) -> ! {
);
}
-// Useful type to use with `Result<>` indicate that an error has already
-// been reported to the user, so no need to continue checking.
-#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq)]
-pub struct ErrorGuaranteed;
+/// Useful type to use with `Result<>` indicate that an error has already
+/// been reported to the user, so no need to continue checking.
+#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct ErrorGuaranteed(());
+
+impl ErrorGuaranteed {
+ /// To be used only if you really know what you are doing... ideally, we would find a way to
+ /// eliminate all calls to this method.
+ pub fn unchecked_claim_error_was_emitted() -> Self {
+ ErrorGuaranteed(())
+ }
+}
rustc_data_structures::impl_stable_hash_via_hash!(ErrorGuaranteed);
let attributes_attr = list.get(1);
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
if !attr.has_name(sym::attributes) {
- diag.span_err(attr.span(), "second argument must be `attributes`")
+ diag.span_err(attr.span(), "second argument must be `attributes`");
}
attr.meta_item_list()
.unwrap_or_else(|| {
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
match transparency_error {
Some(TransparencyError::UnknownTransparency(value, span)) => {
- diag.span_err(span, &format!("unknown macro transparency: `{}`", value))
+ diag.span_err(span, &format!("unknown macro transparency: `{}`", value));
}
Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => {
- diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes")
+ diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes");
}
None => {}
}
fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
match *rhs {
mbe::TokenTree::Delimited(..) => return true,
- _ => sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"),
+ _ => {
+ sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited");
+ }
}
false
}
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
- err.emit();
- ErrorGuaranteed
+ err.emit()
})
}
}
if let Some(s) = e.as_str() {
err.help(&format!("message: {}", s));
}
- err.emit();
- ErrorGuaranteed
+ err.emit()
})
}
}
let crate_dir = match crate_dir.canonicalize() {
Ok(v) => v,
Err(err) => {
- sess.err(&format!(
+ let reported = sess.err(&format!(
"incremental compilation: error canonicalizing path `{}`: {}",
crate_dir.display(),
err
));
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
};
Ok(())
}
Err(err) => {
- sess.err(&format!(
+ let reported = sess.err(&format!(
"Could not create incremental compilation {} \
directory `{}`: {}",
dir_tag,
path.display(),
err
));
- Err(ErrorGuaranteed)
+ Err(reported)
}
}
}
);
}
}
- err.emit();
- Err(ErrorGuaranteed)
+ Err(err.emit())
}
}
}
self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err);
- err.emit();
- Some(ErrorGuaranteed)
+ let reported = err.emit();
+ Some(reported)
}
fn suggest_adding_lifetime_params(
let impl_span = self.tcx().def_span(*impl_def_id);
err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
}
- err.emit();
- Some(ErrorGuaranteed)
+ let reported = err.emit();
+ Some(reported)
}
}
pub fn try_report(&self) -> Option<ErrorGuaranteed> {
self.try_report_from_nll()
- .map(|mut diag| {
- diag.emit();
- ErrorGuaranteed
- })
+ .map(|mut diag| diag.emit())
.or_else(|| self.try_report_impl_not_conforming_to_trait())
.or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_static_impl_trait())
),
);
if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
- err.emit();
- return Some(ErrorGuaranteed);
+ let reported = err.emit();
+ return Some(reported);
} else {
err.cancel();
}
Some((param.param_ty_span, param.param_ty.to_string())),
);
- err.emit();
- Some(ErrorGuaranteed)
+ let reported = err.emit();
+ Some(reported)
}
}
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
&& sup_expected_found == sub_expected_found
{
- self.emit_err(
+ let guar = self.emit_err(
var_origin.span(),
sub_expected,
sub_found,
*trait_item_def_id,
);
- return Some(ErrorGuaranteed);
+ return Some(guar);
}
if let RegionResolutionError::ConcreteFailure(origin, _, _)
| RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone()
trait_item_def_id,
} = origin
{
- self.emit_associated_type_err(
+ let guar = self.emit_associated_type_err(
span,
self.infcx.tcx.item_name(impl_item_def_id),
impl_item_def_id,
trait_item_def_id,
);
- return Some(ErrorGuaranteed);
+ return Some(guar);
}
None
}
- fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) {
+ fn emit_err(
+ &self,
+ sp: Span,
+ expected: Ty<'tcx>,
+ found: Ty<'tcx>,
+ trait_def_id: DefId,
+ ) -> ErrorGuaranteed {
let trait_sp = self.tcx().def_span(trait_def_id);
let mut err = self
.tcx()
argument, the other inputs and its output",
);
}
- err.emit();
+ err.emit()
}
fn emit_associated_type_err(
item_name: Symbol,
impl_item_def_id: DefId,
trait_item_def_id: DefId,
- ) {
+ ) -> ErrorGuaranteed {
let impl_sp = self.tcx().def_span(impl_item_def_id);
let trait_sp = self.tcx().def_span(trait_item_def_id);
let mut err = self
err.span_label(impl_sp, "found");
err.span_label(trait_sp, "expected");
- err.emit();
+ err.emit()
}
}
self.tcx.sess.delay_span_bug(
origin.span(),
&format!("no region-bound-pairs for {:?}", body_id),
- )
+ );
}
}
}
if recursion_limit_hit {
// If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
// with a large AST
- Err(ErrorGuaranteed)
+ Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
} else {
Ok(krate)
}
);
msg.warn("The generated documentation may be incorrect");
- msg.emit()
+ msg.emit();
} else {
krate = sess.time("maybe_create_a_macro_crate", || {
let is_test_crate = sess.opts.test;
if let Some(ref input_path) = compiler.input_path {
if sess.opts.will_create_output_file() {
if output_contains_path(&output_paths, input_path) {
- sess.err(&format!(
+ let reported = sess.err(&format!(
"the input file \"{}\" would be overwritten by the generated \
executable",
input_path.display()
));
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
if let Some(dir_path) = output_conflicts_with_dir(&output_paths) {
- sess.err(&format!(
+ let reported = sess.err(&format!(
"the generated executable for the input file \"{}\" conflicts with the \
existing directory \"{}\"",
input_path.display(),
dir_path.display()
));
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
}
}
if let Some(ref dir) = compiler.temps_dir {
if fs::create_dir_all(dir).is_err() {
- sess.err("failed to find or create the directory specified by `--temps-dir`");
- return Err(ErrorGuaranteed);
+ let reported =
+ sess.err("failed to find or create the directory specified by `--temps-dir`");
+ return Err(reported);
}
}
if !only_dep_info {
if let Some(ref dir) = compiler.output_dir {
if fs::create_dir_all(dir).is_err() {
- sess.err("failed to find or create the directory specified by `--out-dir`");
- return Err(ErrorGuaranteed);
+ let reported =
+ sess.err("failed to find or create the directory specified by `--out-dir`");
+ return Err(reported);
}
}
}
// lot of annoying errors in the ui tests (basically,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
- if sess.has_errors() {
- return Err(ErrorGuaranteed);
+ if let Some(reported) = sess.has_errors() {
+ return Err(reported);
}
sess.time("misc_checking_3", || {
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
-use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_incremental::DepGraphFuture;
use rustc_lint::LintStore;
pub fn parse(&self) -> Result<&Query<ast::Crate>> {
self.parse.compute(|| {
- passes::parse(self.session(), &self.compiler.input).map_err(|mut parse_error| {
- parse_error.emit();
- ErrorGuaranteed
- })
+ passes::parse(self.session(), &self.compiler.input)
+ .map_err(|mut parse_error| parse_error.emit())
})
}
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
if leaf_ty.is_box() {
cx.struct_span_lint(BOX_POINTERS, span, |lint| {
- lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit()
+ lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit();
});
}
}
&self,
cx: &EarlyContext<'_>,
span: Span,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
// This comes from a macro that has `#[allow_internal_unsafe]`.
if span.allows_unsafe() {
macros using unsafe without triggering \
the `unsafe_code` lint at their call site",
)
- .emit()
+ .emit();
});
}
}
// Don't warn about generated blocks; that'll just pollute the output.
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
self.report_unsafe(cx, blk.span, |lint| {
- lint.build("usage of an `unsafe` block").emit()
+ lint.build("usage of an `unsafe` block").emit();
});
}
}
match it.kind {
ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self
.report_unsafe(cx, it.span, |lint| {
- lint.build("declaration of an `unsafe` trait").emit()
+ lint.build("declaration of an `unsafe` trait").emit();
}),
ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self
.report_unsafe(cx, it.span, |lint| {
- lint.build("implementation of an `unsafe` trait").emit()
+ lint.build("implementation of an `unsafe` trait").emit();
}),
ast::ItemKind::Fn(..) => {
FnCtxt::Assoc(_) if body.is_none() => "declaration of an `unsafe` method",
FnCtxt::Assoc(_) => "implementation of an `unsafe` method",
};
- self.report_unsafe(cx, span, |lint| lint.build(msg).emit());
+ self.report_unsafe(cx, span, |lint| {
+ lint.build(msg).emit();
+ });
}
}
}
MISSING_DOCS,
cx.tcx.sess.source_map().guess_head_span(sp),
|lint| {
- lint.build(&format!("missing documentation for {} {}", article, desc)).emit()
+ lint.build(&format!("missing documentation for {} {}", article, desc)).emit();
},
);
}
"type could implement `Copy`; consider adding `impl \
Copy`",
)
- .emit()
+ .emit();
})
}
}
or a manual implementation",
cx.tcx.def_path_str(debug)
))
- .emit()
+ .emit();
});
}
}
if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not {
let msg = "transmuting &T to &mut T is undefined behavior, \
even if the reference is unused, consider instead using an UnsafeCell";
- cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| lint.build(msg).emit());
+ cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| {
+ lint.build(msg).emit();
+ });
}
}
if let Some(items) = attr.meta_item_list() {
for item in items {
cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| {
- lint.build("unstable feature").emit()
+ lint.build("unstable feature").emit();
});
}
}
or lifetime parameters",
predicate_kind_name, predicate
))
- .emit()
+ .emit();
});
}
}
let attrs = cx.tcx.hir().attrs(it.hir_id());
if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) {
cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| {
- lint.build("cannot test inner items").emit()
+ lint.build("cannot test inner items").emit();
});
}
}
format!("r#{}", ident),
Applicability::MachineApplicable,
)
- .emit()
+ .emit();
});
}
}
"this signature doesn't match the previous declaration",
)
.note_expected_found(&"", expected_str, &"", found_str)
- .emit()
+ .emit();
},
);
}
&self,
lint: &'static Lint,
span: Option<impl Into<MultiSpan>>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
diagnostic: BuiltinLintDiagnostics,
) {
self.lookup(lint, span, |lint| {
&self,
lint: &'static Lint,
span: Option<S>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
);
fn struct_span_lint<S: Into<MultiSpan>>(
&self,
lint: &'static Lint,
span: S,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
self.lookup(lint, Some(span), decorate);
}
/// Emit a lint at the appropriate level, with no associated span.
- fn lint(&self, lint: &'static Lint, decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>)) {
+ fn lint(
+ &self,
+ lint: &'static Lint,
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
+ ) {
self.lookup(lint, None as Option<Span>, decorate);
}
}
&self,
lint: &'static Lint,
span: Option<S>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
let hir_id = self.last_node_with_lint_attrs;
&self,
lint: &'static Lint,
span: Option<S>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
self.builder.struct_lint(lint, span.map(|s| s.into()), decorate)
}
self.context.lookup_with_diagnostics(
lint_id.lint,
Some(span),
- |lint| lint.build(&msg).emit(),
+ |lint| {
+ lint.build(&msg).emit();
+ },
diagnostic,
);
}
&self,
lint: &'static Lint,
span: Option<MultiSpan>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level(lint);
struct_lint_level(self.sess, lint, level, src, span, decorate)
}
has_non_ascii_idents = true;
cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| {
- lint.build("identifier contains non-ASCII characters").emit()
+ lint.build("identifier contains non-ASCII characters").emit();
});
if check_uncommon_codepoints
&& !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
{
cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| {
- lint.build("identifier contains uncommon Unicode codepoints").emit()
+ lint.build("identifier contains uncommon Unicode codepoints").emit();
})
}
}
let char_info = format!("'{}' (U+{:04X})", ch, ch as u32);
note += &char_info;
}
- lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit()
+ lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit();
});
}
}
let method = &call.ident.name;
let message =
format!("call to `.{}()` on a reference in this situation does nothing", &method,);
- lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit()
+ lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit();
});
}
}
predicate,
cx.tcx.def_path_str(needs_drop)
);
- lint.build(&msg).emit()
+ lint.build(&msg).emit();
});
}
}
instead using `{}` to detect whether a type is trivially dropped",
cx.tcx.def_path_str(needs_drop)
);
- lint.build(&msg).emit()
+ lint.build(&msg).emit();
});
}
}
min,
max,
))
- .emit()
+ .emit();
});
}
}
hir::ExprKind::Binary(binop, ref l, ref r) => {
if is_comparison(binop) && !check_limits(cx, binop, &l, &r) {
cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| {
- lint.build("comparison is useless due to type limits").emit()
+ lint.build("comparison is useless due to type limits").emit();
});
}
}
larger ({} bytes) than the next largest",
largest
))
- .emit()
+ .emit();
},
);
}
if !(type_permits_lack_of_use || fn_warned || op_warned) {
cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| {
- lint.build(&format!("unused result of type `{}`", ty)).emit()
+ lint.build(&format!("unused result of type `{}`", ty)).emit();
});
}
} else {
lint.span_help(s.span, "use `drop` to clarify the intent");
}
- lint.emit()
+ lint.emit();
} else {
- lint.build("path statement with no effect").emit()
+ lint.build("path statement with no effect").emit();
}
});
}
};
cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| {
- lint.build(&format!("braces around {} is unnecessary", node_name)).emit()
+ lint.build(&format!("braces around {} is unnecessary", node_name)).emit();
});
}
}
"unnecessary allocation, use `&mut` instead"
}
};
- lint.build(msg).emit()
+ lint.build(msg).emit();
});
}
}
for (_, data) in self.cstore.iter_crate_data() {
if data.has_global_allocator() {
match global_allocator {
- Some(other_crate) => self.sess.err(&format!(
+ Some(other_crate) => {
+ self.sess.err(&format!(
"the `#[global_allocator]` in {} conflicts with global allocator in: {}",
other_crate,
data.name()
- )),
+ ));
+ }
None => global_allocator = Some(data.name()),
}
}
// don't perform this validation if the session has errors, as one of
// those errors may indicate a circular dependency which could cause
// this to stack overflow.
- if self.sess.has_errors() {
+ if self.sess.has_errors().is_some() {
return;
}
("bundle", NativeLibKind::Static { bundle, .. }) => {
*bundle = Some(value);
}
- ("bundle", _) => sess.span_err(
- span,
- "bundle linking modifier is only compatible with \
+ ("bundle", _) => {
+ sess.span_err(
+ span,
+ "bundle linking modifier is only compatible with \
`static` linking kind",
- ),
+ );
+ }
("verbatim", _) => lib.verbatim = Some(value),
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
*whole_archive = Some(value);
}
- ("whole-archive", _) => sess.span_err(
- span,
- "whole-archive linking modifier is only compatible with \
+ ("whole-archive", _) => {
+ sess.span_err(
+ span,
+ "whole-archive linking modifier is only compatible with \
`static` linking kind",
- ),
+ );
+ }
("as-needed", NativeLibKind::Dylib { as_needed })
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
*as_needed = Some(value);
}
- ("as-needed", _) => sess.span_err(
- span,
- "as-needed linking modifier is only compatible with \
+ ("as-needed", _) => {
+ sess.span_err(
+ span,
+ "as-needed linking modifier is only compatible with \
`dylib` and `framework` linking kinds",
- ),
+ );
+ }
- _ => sess.span_err(
- span,
- &format!(
- "unrecognized linking modifier `{}`, expected one \
+ _ => {
+ sess.span_err(
+ span,
+ &format!(
+ "unrecognized linking modifier `{}`, expected one \
of: bundle, verbatim, whole-archive, as-needed",
- modifier
- ),
- ),
+ modifier
+ ),
+ );
+ }
}
}
} else {
Some(span) => {
struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit();
}
- None => self.tcx.sess.err(msg),
+ None => {
+ self.tcx.sess.err(msg);
+ }
}
}
if lib.cfg.is_some() && !self.tcx.features().link_cfg {
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId};
+use rustc_errors::{
+ Diagnostic, DiagnosticBuilder, DiagnosticId, EmissionGuarantee, ErrorGuaranteed,
+};
use rustc_hir::HirId;
use rustc_index::vec::IndexVec;
use rustc_query_system::ich::StableHashingContext;
}
}
-pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a, ()>);
+pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>);
-impl<'a> LintDiagnosticBuilder<'a> {
- /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`.
- pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, ()> {
+impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> {
+ /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`.
+ pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, G> {
self.0.set_primary_message(msg);
self.0.set_is_lint();
self.0
}
- /// Create a LintDiagnosticBuilder from some existing DiagnosticBuilder.
- pub fn new(err: DiagnosticBuilder<'a, ()>) -> LintDiagnosticBuilder<'a> {
+ /// Create a `LintDiagnosticBuilder` from some existing `DiagnosticBuilder`.
+ pub fn new(err: DiagnosticBuilder<'a, G>) -> LintDiagnosticBuilder<'a, G> {
LintDiagnosticBuilder(err)
}
}
+impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> {
+ pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> {
+ LintDiagnosticBuilder(self.0.forget_guarantee())
+ }
+}
+
pub fn explain_lint_level_source(
sess: &Session,
lint: &'static Lint,
level: Level,
src: LintLevelSource,
span: Option<MultiSpan>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd,
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) + 'd,
) {
// Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
// the "real" work.
level: Level,
src: LintLevelSource,
span: Option<MultiSpan>,
- decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b>) + 'd>,
+ decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) + 'd>,
) {
// Check for future incompatibility lints and issue a stronger warning.
let future_incompatible = lint.future_incompatible;
let kind = tcx.def_kind(def_id).descr(def_id);
deprecation_suggestion(&mut diag, kind, suggestion, method_span);
}
- diag.emit()
+ diag.emit();
});
}
) {
let soft_handler = |lint, span, msg: &_| {
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
- lint.build(msg).emit()
+ lint.build(msg).emit();
})
};
match self.eval_stability(def_id, id, span, method_span) {
impl From<ErrorHandled> for InterpErrorInfo<'_> {
fn from(err: ErrorHandled) -> Self {
match err {
- ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {
+ ErrorHandled::Reported(ErrorGuaranteed { .. }) | ErrorHandled::Linted => {
err_inval!(ReferencedConstant)
}
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
match self {
TooGeneric => write!(f, "encountered overly generic constant"),
ReferencedConstant => write!(f, "referenced constant has errors"),
- AlreadyReported(ErrorGuaranteed) => {
+ AlreadyReported(ErrorGuaranteed { .. }) => {
write!(f, "encountered constants with type errors, stopping evaluation")
}
Layout(ref err) => write!(f, "{}", err),
}
/// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
- query thir_body(key: ty::WithOptConstParam<LocalDefId>) -> (&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId) {
+ query thir_body(key: ty::WithOptConstParam<LocalDefId>)
+ -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed>
+ {
// Perf tests revealed that hashing THIR is inefficient (see #85729).
no_hash
desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
pub children: DefIdMap<Children>,
/// Whether an error was emitted while constructing the graph.
- pub has_errored: bool,
+ pub has_errored: Option<ErrorGuaranteed>,
}
impl Graph {
pub fn new() -> Graph {
- Graph { parent: Default::default(), children: Default::default(), has_errored: false }
+ Graph { parent: Default::default(), children: Default::default(), has_errored: None }
}
/// The parent of a given impl, which is the `DefId` of the trait when the
) -> Result<Ancestors<'tcx>, ErrorGuaranteed> {
let specialization_graph = tcx.specialization_graph_of(trait_def_id);
- if specialization_graph.has_errored || tcx.type_of(start_from_impl).references_error() {
- Err(ErrorGuaranteed)
+ if let Some(reported) = specialization_graph.has_errored {
+ Err(reported)
+ } else if let Some(reported) = tcx.type_of(start_from_impl).error_reported() {
+ Err(reported)
} else {
Ok(Ancestors {
trait_def_id,
use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::HashingControls;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
}
Err(err) => {
let msg = match err {
- ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {
+ ErrorHandled::Reported(_) | ErrorHandled::Linted => {
"enum discriminant evaluation failed"
}
ErrorHandled::TooGeneric => "enum discriminant depends on generics",
if let Some(val) = self.val().try_eval(tcx, param_env) {
match val {
Ok(val) => Const::from_value(tcx, val, self.ty()),
- Err(ErrorGuaranteed) => tcx.const_error(self.ty()),
+ Err(ErrorGuaranteed { .. }) => tcx.const_error(self.ty()),
}
} else {
self
/// except through the error-reporting functions on a [`tcx`][TyCtxt].
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[derive(TyEncodable, TyDecodable, HashStable)]
-pub struct DelaySpanBugEmitted(());
+pub struct DelaySpanBugEmitted {
+ pub reported: ErrorGuaranteed,
+ _priv: (),
+}
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
/// ensure it gets used.
#[track_caller]
pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
- self.sess.delay_span_bug(span, msg);
- self.mk_ty(Error(DelaySpanBugEmitted(())))
+ let reported = self.sess.delay_span_bug(span, msg);
+ self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () }))
}
/// Like [TyCtxt::ty_error] but for constants.
span: S,
msg: &str,
) -> Const<'tcx> {
- self.sess.delay_span_bug(span, msg);
- self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
+ let reported = self.sess.delay_span_bug(span, msg);
+ self.mk_const(ty::ConstS {
+ val: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }),
+ ty,
+ })
}
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
lint: &'static Lint,
hir_id: HirId,
span: impl Into<MultiSpan>,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level_at_node(lint, hir_id);
struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
self,
lint: &'static Lint,
id: HirId,
- decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>),
+ decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
) {
let (level, src) = self.lint_level_at_node(lint, id);
struct_lint_level(self.sess, lint, level, src, None, decorate);
//! ```
use crate::mir;
use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
+use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_data_structures::fx::FxHashSet;
fn references_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_ERROR)
}
+ fn error_reported(&self) -> Option<ErrorGuaranteed> {
+ if self.references_error() {
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ } else {
+ None
+ }
+ }
fn has_param_types_or_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
}
};
let body = tcx.hir().body(body_id);
- let (thir, expr) = tcx.thir_body(def);
+ let (thir, expr) = tcx
+ .thir_body(def)
+ .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)));
// We ran all queries that depended on THIR at the beginning
// of `mir_build`, so now we can steal it
let thir = thir.steal();
let return_ty = typeck_results.node_type(id);
- let (thir, expr) = tcx.thir_body(def);
+ let (thir, expr) = tcx
+ .thir_body(def)
+ .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)));
// We ran all queries that depended on THIR at the beginning
// of `mir_build`, so now we can steal it
let thir = thir.steal();
} else {
ty::WithOptConstParam::unknown(closure_id)
};
- let (closure_thir, expr) = self.tcx.thir_body(closure_def);
+ let (closure_thir, expr) = self.tcx.thir_body(closure_def).unwrap_or_else(|_| {
+ (self.tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))
+ });
let closure_thir = &closure_thir.borrow();
let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id);
let mut closure_visitor =
return;
}
- let (thir, expr) = tcx.thir_body(def);
+ let (thir, expr) = match tcx.thir_body(def) {
+ Ok(body) => body,
+ Err(_) => return,
+ };
let thir = &thir.borrow();
// If `thir` is empty, a type error occurred, skip this body.
if thir.exprs.is_empty() {
use rustc_ast as ast;
use rustc_data_structures::steal::Steal;
+use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::HirId;
crate fn thir_body<'tcx>(
tcx: TyCtxt<'tcx>,
owner_def: ty::WithOptConstParam<LocalDefId>,
-) -> (&'tcx Steal<Thir<'tcx>>, ExprId) {
+) -> Result<(&'tcx Steal<Thir<'tcx>>, ExprId), ErrorGuaranteed> {
let hir = tcx.hir();
let body = hir.body(hir.body_owned_by(hir.local_def_id_to_hir_id(owner_def.did)));
let mut cx = Cx::new(tcx, owner_def);
- if cx.typeck_results.tainted_by_errors.is_some() {
- return (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0));
+ if let Some(reported) = cx.typeck_results.tainted_by_errors {
+ return Err(reported);
}
let expr = cx.mirror_expr(&body.value);
- (tcx.alloc_steal_thir(cx.thir), expr)
+ Ok((tcx.alloc_steal_thir(cx.thir), expr))
}
crate fn thir_tree<'tcx>(
tcx: TyCtxt<'tcx>,
owner_def: ty::WithOptConstParam<LocalDefId>,
) -> String {
- format!("{:#?}", thir_body(tcx, owner_def).0.steal())
+ match thir_body(tcx, owner_def) {
+ Ok((thir, _)) => format!("{:#?}", thir.steal()),
+ Err(_) => "error".into(),
+ }
}
struct Cx<'tcx> {
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
self.id,
self.span,
- |lint| lint.build(&msg).emit(),
+ |lint| {
+ lint.build(&msg).emit();
+ },
);
} else {
debug!(
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
id,
span,
- |lint| lint.build("floating-point types cannot be used in patterns").emit(),
+ |lint| {
+ lint.build("floating-point types cannot be used in patterns").emit();
+ },
);
}
PatKind::Constant { value: cv }
if self.include_lint_checks {
tcx.sess.span_err(span, msg);
} else {
- tcx.sess.delay_span_bug(span, msg)
+ tcx.sess.delay_span_bug(span, msg);
}
PatKind::Wild
}
if self.include_lint_checks {
tcx.sess.span_err(self.span, &msg);
} else {
- tcx.sess.delay_span_bug(self.span, &msg)
+ tcx.sess.delay_span_bug(self.span, &msg);
}
PatKind::Wild
}
cv.ty(),
cv.ty(),
);
- lint.build(&msg).emit()
+ lint.build(&msg).emit();
},
);
}
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
- tcx.sess.delay_span_bug(span, &msg)
+ tcx.sess.delay_span_bug(span, &msg);
}
PatKind::Wild
}
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
- tcx.sess.delay_span_bug(span, &msg)
+ tcx.sess.delay_span_bug(span, &msg);
}
PatKind::Wild
}
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
self.id,
self.span,
- |lint| lint.build(&msg).emit(),
+ |lint| {lint.build(&msg).emit();},
);
}
PatKind::Constant { value: cv }
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
- tcx.sess.delay_span_bug(span, &msg)
+ tcx.sess.delay_span_bug(span, &msg);
}
}
PatKind::Wild
lint::builtin::POINTER_STRUCTURAL_MATCH,
id,
span,
- |lint| lint.build(&msg).emit(),
+ |lint| {
+ lint.build(&msg).emit();
+ },
);
}
PatKind::Constant { value: cv }
if self.include_lint_checks {
tcx.sess.span_err(span, &msg);
} else {
- tcx.sess.delay_span_bug(span, &msg)
+ tcx.sess.delay_span_bug(span, &msg);
}
PatKind::Wild
}
lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH,
id,
span,
- |lint| lint.build(&msg).emit(),
+ |lint| {
+ lint.build(&msg).emit();
+ },
);
}
place: &Place<'tcx>,
const_item: DefId,
location: Location,
- decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b, ()>,
+ decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) -> DiagnosticBuilder<'b, ()>,
) {
// Don't lint on borrowing/assigning when a dereference is involved.
// If we 'leave' the temporary via a dereference, we must
|lint| {
decorate(lint)
.span_note(self.tcx.def_span(const_item), "`const` item defined here")
- .emit()
+ .emit();
},
);
}
does not derive Copy (error E0133)"
.to_string()
};
- lint.build(&message).emit()
+ lint.build(&message).emit();
});
}
reference with a raw pointer and use `read_unaligned`/`write_unaligned` \
(loads and stores via `*p` must be properly aligned even when using raw pointers)"
)
- .emit()
+ .emit();
},
);
}
self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
let mut err = lint.build(message);
err.span_label(source_info.span, format!("{:?}", panic));
- err.emit()
+ err.emit();
});
}
}
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
-use rustc_errors::{ErrorGuaranteed, FatalError};
+use rustc_errors::FatalError;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
match self.tcx.const_eval_resolve(param_env, ct, None) {
// The `monomorphize` call should have evaluated that constant already.
Ok(val) => val,
- Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => {
- return;
- }
+ Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return,
Err(ErrorHandled::TooGeneric) => span_bug!(
self.body.source_info(location).span,
"collection encountered polymorphic constant: {:?}",
substituted_constant,
val
),
- Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => {}
+ Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {}
Err(ErrorHandled::TooGeneric) => span_bug!(
self.body.source_info(location).span,
"collection encountered polymorphic constant: {}",
|lint| {
let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes()));
err.span_label(source_info.span, "value moved from here");
- err.emit()
+ err.emit();
},
);
}
diag.emit();
}
EscapeError::TooShortHexEscape => {
- handler.span_err(span, "numeric character escape is too short")
+ handler.span_err(span, "numeric character escape is too short");
}
EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
let (c, span) = last_char();
if let Err(mut e) = self.expect_semi() {
match tree.kind {
UseTreeKind::Glob => {
- e.note("the wildcard token must be last on the path").emit();
+ e.note("the wildcard token must be last on the path");
}
UseTreeKind::Nested(..) => {
- e.note("glob-like brace syntax must be last on the path").emit();
+ e.note("glob-like brace syntax must be last on the path");
}
_ => (),
}
// Make sure an error was emitted (either by recovering an angle bracket,
// or by finding an identifier as the next token), since we're
// going to continue parsing
- assert!(self.sess.span_diagnostic.has_errors());
+ assert!(self.sess.span_diagnostic.has_errors().is_some());
} else {
return Err(err);
}
}
ast::AttrStyle::Inner => "crate-level attribute should be in the root module",
};
- lint.build(msg).emit()
+ lint.build(msg).emit();
});
}
}
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
- lint.build("`#[inline]` is ignored on function prototypes").emit()
+ lint.build("`#[inline]` is ignored on function prototypes").emit();
});
true
}
shorthands,
Applicability::MachineApplicable,
);
- err.emit()
+ err.emit();
},
);
} else {
non_shorthands,
Applicability::MachineApplicable,
);
- err.emit()
+ err.emit();
},
);
}
String::new(),
rustc_errors::Applicability::MachineApplicable,
)
- .emit()
+ .emit();
});
}
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
item.hir_id(),
span,
- |lint| lint
+ |lint| {lint
.build("an `#[unstable]` annotation here has no effect")
.note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information")
- .emit()
+ .emit();}
);
}
}
descr,
self.tcx.crate_name(def_id.krate)
))
- .emit()
+ .emit();
},
);
}
lint::builtin::PRIVATE_IN_PUBLIC,
hir_id,
span,
- |lint| lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(),
+ |lint| {
+ lint.build(&format!("{} (error {})", make_msg(), err_code)).emit();
+ },
);
}
}
Vec::new(),
&[],
);
- db.emit()
+ db.emit();
},
);
}
for bound in lifetime_i.bounds {
match bound {
hir::GenericBound::Outlives(ref lt) => match lt.name {
- hir::LifetimeName::Underscore => self.tcx.sess.delay_span_bug(
- lt.span,
- "use of `'_` in illegal place, but not caught by lowering",
- ),
+ hir::LifetimeName::Underscore => {
+ self.tcx.sess.delay_span_bug(
+ lt.span,
+ "use of `'_` in illegal place, but not caught by lowering",
+ );
+ }
hir::LifetimeName::Static => {
self.insert_lifetime(lt, Region::Static);
self.tcx
lt.span,
"lowering generated `ImplicitObjectLifetimeDefault` \
outside of an object type",
- )
+ );
}
hir::LifetimeName::Error => {
// No need to do anything, error already reported.
match sp {
Some(sp) => sess.span_err(sp, s),
None => sess.err(s),
- }
+ };
err_count += 1;
};
if s.is_empty() {
}
diag.emit();
// If we should err, make sure we did.
- if must_err && !self.has_errors() {
+ if must_err && !self.has_errors().is_some() {
// We have skipped a feature gate, and not run into other errors... reject.
self.err(
"`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
self.span_err(sp, msg);
}
}
- pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
+ pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ErrorGuaranteed {
self.diagnostic().span_err(sp, msg)
}
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
self.diagnostic().span_err_with_code(sp, &msg, code)
}
- pub fn err(&self, msg: &str) {
+ pub fn err(&self, msg: &str) -> ErrorGuaranteed {
self.diagnostic().err(msg)
}
pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed {
pub fn err_count(&self) -> usize {
self.diagnostic().err_count()
}
- pub fn has_errors(&self) -> bool {
+ pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.diagnostic().has_errors()
}
pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
self.diagnostic().abort_if_errors();
}
pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> {
- if self.diagnostic().has_errors_or_lint_errors() {
- self.diagnostic().emit_stashed_diagnostics();
- Err(ErrorGuaranteed)
+ if let Some(reported) = self.diagnostic().has_errors_or_lint_errors() {
+ let _ = self.diagnostic().emit_stashed_diagnostics();
+ Err(reported)
} else {
Ok(())
}
{
let old_count = self.err_count();
let result = f();
- if self.err_count() == old_count { Ok(result) } else { Err(ErrorGuaranteed) }
+ if self.err_count() == old_count {
+ Ok(result)
+ } else {
+ Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ }
}
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.diagnostic().span_warn(sp, msg)
}
/// Delay a span_bug() call until abort_if_errors()
#[track_caller]
- pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
+ pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ErrorGuaranteed {
self.diagnostic().delay_span_bug(sp, msg)
}
let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers;
match unsupported_sanitizers.into_iter().count() {
0 => {}
- 1 => sess
- .err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)),
- _ => sess.err(&format!(
- "{} sanitizers are not supported for this target",
- unsupported_sanitizers
- )),
+ 1 => {
+ sess.err(&format!(
+ "{} sanitizer is not supported for this target",
+ unsupported_sanitizers
+ ));
+ }
+ _ => {
+ sess.err(&format!(
+ "{} sanitizers are not supported for this target",
+ unsupported_sanitizers
+ ));
+ }
}
// Cannot mix and match sanitizers.
let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter();
InvalidBecauseOfErrors { session_directory: PathBuf },
}
-pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) {
+pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed {
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
}
};
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
- handler.struct_fatal(msg).emit();
+ let reported = handler.struct_fatal(msg).emit();
+ reported
}
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
// leading to an ambiguous result. So report this as an
// overflow bug, since I believe this is the only case
// where ambiguity can result.
- infcx.tcx.sess.delay_span_bug(
+ let reported = infcx.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
&format!(
"encountered ambiguity selecting `{:?}` during codegen, presuming due to \
trait_ref
),
);
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
Err(Unimplemented) => {
// This can trigger when we probe for the source of a `'static` lifetime requirement
// on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
// This can also trigger when we have a global bound that is not actually satisfied,
// but was included during typeck due to the trivial_bounds feature.
- infcx.tcx.sess.delay_span_bug(
+ let guar = infcx.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
&format!(
"Encountered error `Unimplemented` selecting `{:?}` during codegen",
trait_ref
),
);
- return Err(ErrorGuaranteed);
+ return Err(guar);
}
Err(e) => {
bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref)
use rustc_middle::thir;
use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
use rustc_middle::ty::subst::{Subst, SubstsRef};
-use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, DelaySpanBugEmitted, TyCtxt, TypeFoldable};
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::Span;
false => NotConstEvaluatable::MentionsParam,
}),
Err(ErrorHandled::Linted) => {
- infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
- Err(NotConstEvaluatable::Error(ErrorGuaranteed))
+ let reported =
+ infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
+ Err(NotConstEvaluatable::Error(reported))
}
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
Ok(_) => Ok(()),
) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
match ct.val() {
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
- ty::ConstKind::Error(_) => Err(ErrorGuaranteed),
+ ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported),
_ => Ok(None),
}
}
}
fn error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
- self.tcx
+ let reported = self
+ .tcx
.sess
.struct_span_err(self.root_span(), "overly complex generic constant")
.span_label(span, msg)
.help("consider moving this anonymous constant into a `const` function")
.emit();
- Err(ErrorGuaranteed)
+ Err(reported)
}
fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> {
- self.tcx
+ let reported = self
+ .tcx
.sess
.struct_span_err(self.root_span(), "overly complex generic constant")
.span_label(span, msg)
.note("this operation may be supported in the future")
.emit();
- Err(ErrorGuaranteed)
+ Err(reported)
}
fn new(
_ => return Ok(None),
}
- let body = tcx.thir_body(def);
- if body.0.borrow().exprs.is_empty() {
- // type error in constant, there is no thir
- return Err(ErrorGuaranteed);
- }
+ let body = tcx.thir_body(def)?;
AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))?
.map(AbstractConstBuilder::build)
Ok(false)
})()
- .unwrap_or_else(|ErrorGuaranteed| true)
+ .unwrap_or_else(|_: ErrorGuaranteed| true)
// FIXME(generic_const_exprs): We should instead have this
// method return the resulting `ty::Const` and return `ConstKind::Error`
// on `ErrorGuaranteed`.
errors: &[FulfillmentError<'tcx>],
body_id: Option<hir::BodyId>,
fallback_has_occurred: bool,
- );
+ ) -> ErrorGuaranteed;
fn report_overflow_error<T>(
&self,
errors: &[FulfillmentError<'tcx>],
body_id: Option<hir::BodyId>,
fallback_has_occurred: bool,
- ) {
+ ) -> ErrorGuaranteed {
#[derive(Debug)]
struct ErrorDescriptor<'tcx> {
predicate: ty::Predicate<'tcx>,
self.report_fulfillment_error(error, body_id, fallback_has_occurred);
}
}
+
+ self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors")
}
/// Reports that an overflow has occurred and halts compilation. We
let predicate_is_const = ty::BoundConstness::ConstIfConst
== trait_predicate.skip_binder().constness;
- if self.tcx.sess.has_errors() && trait_predicate.references_error() {
+ if self.tcx.sess.has_errors().is_some()
+ && trait_predicate.references_error()
+ {
return;
}
let trait_ref = trait_predicate.to_poly_trait_ref();
}
// Already reported in the query.
- SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorGuaranteed)) => {
+ SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) => {
// FIXME(eddyb) remove this once `ErrorGuaranteed` becomes a proof token.
self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error");
return;
// Same hacky approach as above to avoid deluging user
// with error messages.
if arg.references_error()
- || self.tcx.sess.has_errors()
+ || self.tcx.sess.has_errors().is_some()
|| self.is_tainted_by_errors()
{
return;
ty::PredicateKind::Subtype(data) => {
if data.references_error()
- || self.tcx.sess.has_errors()
+ || self.tcx.sess.has_errors().is_some()
|| self.is_tainted_by_errors()
{
// no need to overload user in such cases
}
_ => {
- if self.tcx.sess.has_errors() || self.is_tainted_by_errors() {
+ if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() {
return;
}
let mut err = struct_span_err!(
use rustc_data_structures::obligation_forest::ProcessResult;
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
-use rustc_errors::ErrorGuaranteed;
use rustc_infer::traits::ProjectionCacheKey;
use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation};
use rustc_middle::mir::interpret::ErrorHandled;
),
}
}
- (Err(ErrorHandled::Reported(ErrorGuaranteed)), _)
- | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => {
- ProcessResult::Error(CodeSelectionError(
- SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(
- ErrorGuaranteed,
- )),
- ))
- }
+ (Err(ErrorHandled::Reported(reported)), _)
+ | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error(
+ CodeSelectionError(SelectionError::NotConstEvaluatable(
+ NotConstEvaluatable::Error(reported),
+ )),
+ ),
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
span_bug!(
obligation.cause.span(self.selcx.tcx()),
match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) {
Ok(predicates) => predicates,
Err(errors) => {
- infcx.report_fulfillment_errors(&errors, None, false);
- return Err(ErrorGuaranteed);
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
}
};
// represents a legitimate failure due to some kind of
// unconstrained variable, and it seems better not to ICE,
// all things considered.
- tcx.sess.span_err(span, &fixup_err.to_string());
- return Err(ErrorGuaranteed);
+ let reported = tcx.sess.span_err(span, &fixup_err.to_string());
+ return Err(reported);
}
};
if predicates.needs_infer() {
- tcx.sess.delay_span_bug(span, "encountered inference variables after `fully_resolve`");
- Err(ErrorGuaranteed)
+ let reported = tcx
+ .sess
+ .delay_span_bug(span, "encountered inference variables after `fully_resolve`");
+ Err(reported)
} else {
Ok(predicates)
}
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
#[derive(Clone, Debug)]
pub struct OnUnimplementedFormatString(Symbol);
if let Some(note) = note {
diag.note(note);
}
- diag.emit();
- ErrorGuaranteed
+ diag.emit()
}
impl<'tcx> OnUnimplementedDirective {
span: Span,
is_root: bool,
) -> Result<Self, ErrorGuaranteed> {
- let mut errored = false;
+ let mut errored = None;
let mut item_iter = items.iter();
let parse_value = |value_str| {
)
})?;
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| {
- if let Some(symbol) = item.value_str() && parse_value(symbol).is_err() {
- errored = true;
+ if let Some(symbol) = item.value_str() && let Err(guar) = parse_value(symbol) {
+ errored = Some(guar);
}
true
});
&& note.is_none()
{
if let Some(items) = item.meta_item_list() {
- if let Ok(subcommand) =
- Self::parse(tcx, item_def_id, &items, item.span(), false)
- {
- subcommands.push(subcommand);
- } else {
- errored = true;
- }
+ match Self::parse(tcx, item_def_id, &items, item.span(), false) {
+ Ok(subcommand) => subcommands.push(subcommand),
+ Err(reported) => errored = Some(reported),
+ };
continue;
}
} else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() {
);
}
- if errored {
- Err(ErrorGuaranteed)
+ if let Some(reported) = errored {
+ Err(reported)
} else {
Ok(OnUnimplementedDirective {
condition,
append_const_msg: None,
}))
} else {
- return Err(ErrorGuaranteed);
+ let reported =
+ tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str");
+ return Err(reported);
};
debug!("of_item({:?}) = {:?}", item_def_id, result);
result
match generics.params.iter().find(|param| param.name == s) {
Some(_) => (),
None => {
- struct_span_err!(
+ let reported = struct_span_err!(
tcx.sess,
span,
E0230,
}
)
.emit();
- result = Err(ErrorGuaranteed);
+ result = Err(reported);
}
}
}
// `{:1}` and `{}` are not to be used
Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => {
- struct_span_err!(
+ let reported = struct_span_err!(
tcx.sess,
span,
E0231,
"only named substitution parameters are allowed"
)
.emit();
- result = Err(ErrorGuaranteed);
+ result = Err(reported);
}
},
}
// `rustc_ty_utils::instance::resolve_associated_item()`.
let node_item =
assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
- .map_err(|ErrorGuaranteed| ())?;
+ .map_err(|ErrorGuaranteed { .. }| ())?;
if node_item.is_final() {
// Non-specializable items are always projectable.
use crate::traits::ProjectionCacheKey;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{Diagnostic, ErrorGuaranteed};
+use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::LateBoundRegionConversionTime;
Err(_) => Ok(EvaluatedToErr),
}
}
- (Err(ErrorHandled::Reported(ErrorGuaranteed)), _)
- | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => Ok(EvaluatedToErr),
+ (Err(ErrorHandled::Reported(_)), _)
+ | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr),
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
span_bug!(
obligation.cause.span(self.tcx()),
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::struct_span_err;
+use rustc_errors::{struct_span_err, EmissionGuarantee};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
-use rustc_span::DUMMY_SP;
+use rustc_span::{Span, DUMMY_SP};
use super::util::impl_trait_ref_and_oblig;
use super::{FulfillmentContext, SelectionContext};
}
}
- sg.has_errored = true;
- err.emit();
+ sg.has_errored = Some(err.emit());
}
fn report_conflicting_impls(
// Work to be done after we've built the DiagnosticBuilder. We have to define it
// now because the struct_lint methods don't return back the DiagnosticBuilder
// that's passed in.
- let decorate = |err: LintDiagnosticBuilder<'_>| {
+ fn decorate<G: EmissionGuarantee>(
+ tcx: TyCtxt<'_>,
+ overlap: OverlapError,
+ used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
+ impl_span: Span,
+ err: LintDiagnosticBuilder<'_, G>,
+ ) -> G {
let msg = format!(
"conflicting implementations of trait `{}`{}{}",
overlap.trait_desc,
coherence::add_placeholder_note(&mut err);
}
err.emit()
- };
+ }
match used_to_be_allowed {
None => {
- sg.has_errored = true;
- if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) {
+ let reported = if overlap.with_impl.is_local()
+ || !tcx.orphan_check_crate(()).contains(&impl_def_id)
+ {
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
- decorate(LintDiagnosticBuilder::new(err.forget_guarantee()));
+ Some(decorate(
+ tcx,
+ overlap,
+ used_to_be_allowed,
+ impl_span,
+ LintDiagnosticBuilder::new(err),
+ ))
} else {
- tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check");
- }
+ Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
+ };
+ sg.has_errored = reported;
}
Some(kind) => {
let lint = match kind {
lint,
tcx.hir().local_def_id_to_hir_id(impl_def_id),
impl_span,
- decorate,
- )
+ |ldb| {
+ decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb);
+ },
+ );
}
};
}
resolved_ty,
);
let span = tcx.def_span(leaf_def.item.def_id);
- tcx.sess.delay_span_bug(span, &msg);
+ let reported = tcx.sess.delay_span_bug(span, &msg);
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
}
use crate::astconv::AstConv;
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{pluralize, struct_span_err, Applicability};
+use rustc_errors::{pluralize, struct_span_err, Applicability, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty;
ty_param_name: &str,
assoc_name: Ident,
span: Span,
- ) where
+ ) -> ErrorGuaranteed
+ where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
{
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
err.span_label(span, format!("associated type `{}` not found", assoc_name));
}
- err.emit();
+ err.emit()
}
/// When there are any missing associated types, emit an E0191 error and attempt to supply a
use crate::errors::AssocTypeBindingNotAllowed;
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd;
-use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{struct_span_err, Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
let mut invalid_args = vec![];
- let mut check_lifetime_args = |min_expected_args: usize,
- max_expected_args: usize,
- provided_args: usize,
- late_bounds_ignore: bool|
- -> bool {
- if (min_expected_args..=max_expected_args).contains(&provided_args) {
- return true;
- }
+ let mut check_lifetime_args =
+ |min_expected_args: usize,
+ max_expected_args: usize,
+ provided_args: usize,
+ late_bounds_ignore: bool| {
+ if (min_expected_args..=max_expected_args).contains(&provided_args) {
+ return Ok(());
+ }
- if late_bounds_ignore {
- return true;
- }
+ if late_bounds_ignore {
+ return Ok(());
+ }
- if provided_args > max_expected_args {
- invalid_args.extend(
- gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()),
- );
- };
+ if provided_args > max_expected_args {
+ invalid_args.extend(
+ gen_args.args[max_expected_args..provided_args]
+ .iter()
+ .map(|arg| arg.span()),
+ );
+ };
- let gen_args_info = if provided_args > min_expected_args {
- invalid_args.extend(
- gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()),
- );
- let num_redundant_args = provided_args - min_expected_args;
- GenericArgsInfo::ExcessLifetimes { num_redundant_args }
- } else {
- let num_missing_args = min_expected_args - provided_args;
- GenericArgsInfo::MissingLifetimes { num_missing_args }
+ let gen_args_info = if provided_args > min_expected_args {
+ invalid_args.extend(
+ gen_args.args[min_expected_args..provided_args]
+ .iter()
+ .map(|arg| arg.span()),
+ );
+ let num_redundant_args = provided_args - min_expected_args;
+ GenericArgsInfo::ExcessLifetimes { num_redundant_args }
+ } else {
+ let num_missing_args = min_expected_args - provided_args;
+ GenericArgsInfo::MissingLifetimes { num_missing_args }
+ };
+
+ let reported = WrongNumberOfGenericArgs::new(
+ tcx,
+ gen_args_info,
+ seg,
+ gen_params,
+ has_self as usize,
+ gen_args,
+ def_id,
+ )
+ .diagnostic()
+ .emit();
+
+ Err(reported)
};
- WrongNumberOfGenericArgs::new(
- tcx,
- gen_args_info,
- seg,
- gen_params,
- has_self as usize,
- gen_args,
- def_id,
- )
- .diagnostic()
- .emit();
-
- false
- };
-
let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes };
let max_expected_lifetime_args = param_counts.lifetimes;
let num_provided_lifetime_args = gen_args.num_lifetime_params();
"check_types_and_consts"
);
if (expected_min..=expected_max).contains(&provided) {
- return true;
+ return Ok(());
}
let num_default_params = expected_max - expected_min;
debug!(?gen_args_info);
- WrongNumberOfGenericArgs::new(
+ let reported = WrongNumberOfGenericArgs::new(
tcx,
gen_args_info,
seg,
.diagnostic()
.emit_unless(gen_args.has_err());
- false
+ Err(reported)
};
let args_correct = {
GenericArgCountResult {
explicit_late_bound,
- correct: if lifetimes_correct && args_correct {
- Ok(())
- } else {
- Err(GenericArgCountMismatch { reported: Some(ErrorGuaranteed), invalid_args })
- },
+ correct: lifetimes_correct.and(args_correct).map_err(|reported| {
+ GenericArgCountMismatch { reported: Some(reported), invalid_args }
+ }),
}
}
LATE_BOUND_LIFETIME_ARGUMENTS,
args.args[0].id(),
multispan,
- |lint| lint.build(msg).emit(),
+ |lint| {
+ lint.build(msg).emit();
+ },
);
}
type_str: &str,
trait_str: &str,
name: Symbol,
- ) {
+ ) -> ErrorGuaranteed {
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
if let (true, Ok(snippet)) = (
self.tcx()
Applicability::HasPlaceholders,
);
}
- err.emit();
+ err.emit()
}
// Search for a bound on a type parameter which includes the associated item
(Some(bound), _) => (bound, matching_candidates.next()),
(None, Some(bound)) => (bound, const_candidates.next()),
(None, None) => {
- self.complain_about_assoc_type_not_found(
+ let reported = self.complain_about_assoc_type_not_found(
all_candidates,
&ty_param_name(),
assoc_name,
span,
);
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
};
debug!("one_bound_for_assoc_type: bound = {:?}", bound);
where_bounds.join(",\n"),
));
}
- err.emit();
+ let reported = err.emit();
if !where_bounds.is_empty() {
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
}
// trait reference.
let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
// A cycle error occurred, most likely.
- return Err(ErrorGuaranteed);
+ let guar = tcx.sess.delay_span_bug(span, "expected cycle error");
+ return Err(guar);
};
self.one_bound_for_assoc_type(
| Res::Def(DefKind::TyParam, param_did),
) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?,
_ => {
- if variant_resolution.is_some() {
+ let reported = if variant_resolution.is_some() {
// Variant in type position
let msg = format!("expected type, found variant `{}`", assoc_ident);
- tcx.sess.span_err(span, &msg);
+ tcx.sess.span_err(span, &msg)
} else if qself_ty.is_enum() {
let mut err = struct_span_err!(
tcx.sess,
err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
}
- err.emit();
- } else if !qself_ty.references_error() {
+ err.emit()
+ } else if let Some(reported) = qself_ty.error_reported() {
+ reported
+ } else {
// Don't print `TyErr` to the user.
self.report_ambiguous_associated_type(
span,
&qself_ty.to_string(),
"Trait",
assoc_ident.name,
- );
- }
- return Err(ErrorGuaranteed);
+ )
+ };
+ return Err(reported);
}
};
// but it was used in a type position.
let Some(item) = item else {
let msg = format!("found associated const `{assoc_ident}` when type was expected");
- tcx.sess.struct_span_err(span, &msg).emit();
- return Err(ErrorGuaranteed);
+ let guar = tcx.sess.struct_span_err(span, &msg).emit();
+ return Err(guar);
};
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound);
sugg,
Applicability::MachineApplicable,
)
- .emit()
+ .emit();
},
);
}
let t = self.resolve_vars_if_possible(t);
- if t.references_error() {
- return Err(ErrorGuaranteed);
+ if let Some(reported) = t.error_reported() {
+ return Err(reported);
}
if self.type_is_known_to_be_sized_modulo_regions(t, span) {
| ty::Adt(..)
| ty::Never
| ty::Error(_) => {
- self.tcx
+ let reported = self
+ .tcx
.sess
.delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t));
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
})
}
}
impl From<ErrorGuaranteed> for CastError {
- fn from(ErrorGuaranteed: ErrorGuaranteed) -> Self {
+ fn from(_: ErrorGuaranteed) -> Self {
CastError::ErrorGuaranteed
}
}
// inference is more completely known.
match cast_ty.kind() {
ty::Dynamic(..) | ty::Slice(..) => {
- check.report_cast_to_unsized_type(fcx);
- Err(ErrorGuaranteed)
+ let reported = check.report_cast_to_unsized_type(fcx);
+ Err(reported)
}
_ => Ok(check),
}
}
}
- fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) {
- if self.cast_ty.references_error() || self.expr_ty.references_error() {
- return;
+ fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) -> ErrorGuaranteed {
+ if let Some(reported) =
+ self.cast_ty.error_reported().or_else(|| self.expr_ty.error_reported())
+ {
+ return reported;
}
let tstr = fcx.ty_to_string(self.cast_ty);
err.span_help(self.expr.span, "consider using a box or reference as appropriate");
}
}
- err.emit();
+ err.emit()
}
fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
}
None => {
tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
- lint.build("use of calling convention not supported on this target").emit()
+ lint.build("use of calling convention not supported on this target").emit();
});
}
}
};
if let Some(header) = item {
- tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple")
+ tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple");
}
};
origin: &hir::OpaqueTyOrigin,
) -> Result<(), ErrorGuaranteed> {
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
- match origin {
+ let reported = match origin {
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
_ => opaque_type_cycle_error(tcx, def_id, span),
- }
- Err(ErrorGuaranteed)
+ };
+ Err(reported)
} else {
Ok(())
}
trace!(?hidden_type);
match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) {
Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
- Err(ty_err) => tcx.sess.delay_span_bug(
- span,
- &format!(
- "could not check bounds on revealed type `{}`:\n{}",
- hidden_type, ty_err,
- ),
- ),
+ Err(ty_err) => {
+ tcx.sess.delay_span_bug(
+ span,
+ &format!(
+ "could not check bounds on revealed type `{}`:\n{}",
+ hidden_type, ty_err,
+ ),
+ );
+ }
}
}
if ty.references_error() {
// If there is already another error, do not emit
// an error for not using a type parameter.
- assert!(tcx.sess.has_errors());
+ assert!(tcx.sess.has_errors().is_some());
return;
}
pub(super) use wfcheck::check_impl_item as check_impl_item_well_formed;
-fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) {
+fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
.span_label(span, "recursive `async fn`")
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
.note(
"consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
)
- .emit();
+ .emit()
}
/// Emit an error for recursive opaque types.
///
/// If all the return expressions evaluate to `!`, then we explain that the error will go away
/// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
-fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
+fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> ErrorGuaranteed {
let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
let mut label = false;
if !label {
err.span_label(span, "cannot resolve opaque type");
}
- err.emit();
+ err.emit()
}
let impl_m_span = tcx.sess.source_map().guess_head_span(impl_m_span);
- if let Err(ErrorGuaranteed) =
- compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)
- {
+ if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) {
return;
}
- if let Err(ErrorGuaranteed) =
- compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span)
- {
+ if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
return;
}
- if let Err(ErrorGuaranteed) =
+ if let Err(_) =
compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)
{
return;
}
- if let Err(ErrorGuaranteed) = compare_synthetic_generics(tcx, impl_m, trait_m) {
+ if let Err(_) = compare_synthetic_generics(tcx, impl_m, trait_m) {
return;
}
- if let Err(ErrorGuaranteed) =
- compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)
+ if let Err(_) = compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)
{
return;
}
- if let Err(ErrorGuaranteed) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) {
+ if let Err(_) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) {
return;
}
}
&terr,
false,
);
- diag.emit();
- return Err(ErrorGuaranteed);
+
+ return Err(diag.emit());
}
// Check that all obligations are satisfied by the implementation's
// version.
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
if !errors.is_empty() {
- infcx.report_fulfillment_errors(&errors, None, false);
- return Err(ErrorGuaranteed);
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
}
// Finally, resolve all regions. This catches wily misuses of
.map_or(def_sp, |g| g.span)
});
- tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
+ let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind,
ident: impl_m.ident(tcx),
generics_span,
});
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
Ok(())
} else {
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
}
- err.emit();
- return Err(ErrorGuaranteed);
+ let reported = err.emit();
+ return Err(reported);
}
(true, false) => {
} else {
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
}
- err.emit();
- return Err(ErrorGuaranteed);
+ let reported = err.emit();
+ return Err(reported);
}
}
let item_kind = assoc_item_kind_str(impl_);
- let mut err_occurred = false;
+ let mut err_occurred = None;
for (kind, trait_count, impl_count) in matchings {
if impl_count != trait_count {
- err_occurred = true;
-
let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
let trait_item = tcx.hir().expect_trait_item(def_id);
if trait_item.generics.params.is_empty() {
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
}
- err.emit();
+ let reported = err.emit();
+ err_occurred = Some(reported);
}
}
- if err_occurred { Err(ErrorGuaranteed) } else { Ok(()) }
+ if let Some(reported) = err_occurred { Err(reported) } else { Ok(()) }
}
fn compare_number_of_method_arguments<'tcx>(
impl_number_args
),
);
- err.emit();
- return Err(ErrorGuaranteed);
+ let reported = err.emit();
+ return Err(reported);
}
Ok(())
// 2. Explanation as to what is going on
// If we get here, we already have the same number of generics, so the zip will
// be okay.
- let mut error_found = false;
+ let mut error_found = None;
let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_m.def_id);
let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
}
_ => unreachable!(),
}
- err.emit();
- error_found = true;
+ let reported = err.emit();
+ error_found = Some(reported);
}
}
- if error_found { Err(ErrorGuaranteed) } else { Ok(()) }
+ if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
}
fn compare_const_param_types<'tcx>(
trait_ty
),
);
- err.emit();
- return Err(ErrorGuaranteed);
+ let reported = err.emit();
+ return Err(reported);
}
}
// version.
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
if !errors.is_empty() {
- infcx.report_fulfillment_errors(&errors, None, false);
- return Err(ErrorGuaranteed);
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
}
// Finally, resolve all regions. This catches wily misuses of
// version.
let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
if !errors.is_empty() {
- infcx.report_fulfillment_errors(&errors, None, false);
- return Err(ErrorGuaranteed);
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
}
// Finally, resolve all regions. This catches wily misuses of
// already checked by coherence, but compilation may
// not have been terminated.
let span = tcx.def_span(drop_impl_did);
- tcx.sess.delay_span_bug(
+ let reported = tcx.sess.delay_span_bug(
span,
&format!("should have been rejected by coherence check: {}", dtor_self_type),
);
- Err(ErrorGuaranteed)
+ Err(reported)
}
}
}
Err(_) => {
let item_span = tcx.def_span(self_type_did);
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
- struct_span_err!(
+ let reported = struct_span_err!(
tcx.sess,
drop_impl_span,
E0366,
),
)
.emit();
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
}
let errors = fulfillment_cx.select_all_or_error(&infcx);
if !errors.is_empty() {
// this could be reached when we get lazy normalization
- infcx.report_fulfillment_errors(&errors, None, false);
- return Err(ErrorGuaranteed);
+ let reported = infcx.report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
}
// NB. It seems a bit... suspicious to use an empty param-env
if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) {
let item_span = tcx.def_span(self_type_did);
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id());
- struct_span_err!(
+ let reported = struct_span_err!(
tcx.sess,
predicate_sp,
E0367,
)
.span_note(item_span, "the implementor must specify the same requirement")
.emit();
- result = Err(ErrorGuaranteed);
+ result = Err(reported);
}
}
// else an error would have been flagged by the
// `loops` pass for using break with an expression
// where you are not supposed to.
- assert!(expr_opt.is_none() || self.tcx.sess.has_errors());
+ assert!(expr_opt.is_none() || self.tcx.sess.has_errors().is_some());
}
// If we encountered a `break`, then (no surprise) it may be possible to break from the
deferred_cast_checks.push(cast_check);
t_cast
}
- Err(ErrorGuaranteed) => self.tcx.ty_error(),
+ Err(_) => self.tcx.ty_error(),
}
}
}
}
// FIXME: currently we never try to compose autoderefs
// and ReifyFnPointer/UnsafeFnPointer, but we could.
- _ => self.tcx.sess.delay_span_bug(
- expr.span,
- &format!(
- "while adjusting {:?}, can't compose {:?} and {:?}",
- expr,
- entry.get(),
- adj
- ),
- ),
- };
+ _ => {
+ self.tcx.sess.delay_span_bug(
+ expr.span,
+ &format!(
+ "while adjusting {:?}, can't compose {:?} and {:?}",
+ expr,
+ entry.get(),
+ adj
+ ),
+ );
+ }
+ }
*entry.get_mut() = adj;
}
}
.or_else(|error| {
let result = match error {
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
- _ => Err(ErrorGuaranteed),
+ _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()),
};
// If we have a path like `MyTrait::missing_method`, then don't register
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
scope_expr_id,
span,
- |lint| lint.build("type annotations needed").emit(),
+ |lint| {
+ lint.build("type annotations needed").emit();
+ },
);
}
} else {
if self.is_tainted_by_errors() {
// FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
- wbcx.typeck_results.tainted_by_errors = Some(ErrorGuaranteed);
+ wbcx.typeck_results.tainted_by_errors =
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results);
// users of the typeck results don't produce extra errors, or worse, ICEs.
if resolver.replaced_with_error {
// FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted.
- self.typeck_results.tainted_by_errors = Some(ErrorGuaranteed);
+ self.typeck_results.tainted_by_errors =
+ Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
x
}
fn report_type_error(&self, t: Ty<'tcx>) {
- if !self.tcx.sess.has_errors() {
+ if !self.tcx.sess.has_errors().is_some() {
self.infcx
.emit_inference_failure_err(
Some(self.body.id()),
}
fn report_const_error(&self, c: ty::Const<'tcx>) {
- if !self.tcx.sess.has_errors() {
+ if self.tcx.sess.has_errors().is_none() {
self.infcx
.emit_inference_failure_err(
Some(self.body.id()),
for &impl_of_trait in impls_of_trait {
match orphan_check_impl(tcx, impl_of_trait) {
Ok(()) => {}
- Err(ErrorGuaranteed) => errors.push(impl_of_trait),
+ Err(_) => errors.push(impl_of_trait),
}
}
};
if let Some((msg, label)) = msg {
- struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit();
- return Err(ErrorGuaranteed);
+ let reported =
+ struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit();
+ return Err(reported);
}
}
if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() {
- tcx.sess
+ let reported = tcx
+ .sess
.struct_span_err(sp, "cannot implement trait on type alias impl trait")
.span_note(tcx.def_span(def_id), "type alias impl trait defined here")
.emit();
- return Err(ErrorGuaranteed);
+ return Err(reported);
}
Ok(())
-use rustc_errors::{Applicability, ErrorGuaranteed, StashKey};
+use rustc_errors::{Applicability, StashKey};
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, LocalDefId};
owner, def_id,
),
);
- if let Some(ErrorGuaranteed) =
+ if let Some(_) =
tcx.typeck(owner).tainted_by_errors
{
// Some error in the
// struct; however, when EUV is run during typeck, it
// may not. This will generate an error earlier in typeck,
// so we can just ignore it.
- if !self.tcx().sess.has_errors() {
+ if !self.tcx().sess.has_errors().is_some() {
span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
}
}
check_unused::check_crate(tcx);
check_for_entry_fn(tcx);
- if tcx.sess.err_count() == 0 { Ok(()) } else { Err(ErrorGuaranteed) }
+ if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) }
}
/// A quasi-deprecated helper used in rustdoc and clippy to get
{
match Cfg::parse(cfg_mi) {
Ok(new_cfg) => cfg &= new_cfg,
- Err(e) => sess.span_err(e.span, e.msg),
+ Err(e) => {
+ sess.span_err(e.span, e.msg);
+ }
}
}
}
}
}
- if tcx.sess.diagnostic().has_errors_or_lint_errors() {
+ if tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() {
rustc_errors::FatalError.raise();
}
collector
});
- if compiler.session().diagnostic().has_errors_or_lint_errors() {
+ if compiler.session().diagnostic().has_errors_or_lint_errors().is_some() {
FatalError.raise();
}
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() {
Some(args) => main_args(&args),
- _ => Err(ErrorGuaranteed),
+ _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()),
});
process::exit(exit_code);
}
// codes from `from_matches` here.
let options = match config::Options::from_matches(&matches) {
Ok(opts) => opts,
- Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorGuaranteed) },
+ Err(code) => {
+ return if code == 0 {
+ Ok(())
+ } else {
+ Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
+ };
+ }
};
rustc_interface::util::run_in_thread_pool_with_globals(
options.edition,
match res {
Ok(()) => Ok(()),
Err(err) => {
- diag.struct_err(&err).emit();
- Err(ErrorGuaranteed)
+ let reported = diag.struct_err(&err).emit();
+ Err(reported)
}
}
}
(resolver.clone(), resolver_caches)
};
- if sess.diagnostic().has_errors_or_lint_errors() {
+ if sess.diagnostic().has_errors_or_lint_errors().is_some() {
sess.fatal("Compilation failed, aborting rustdoc");
}
format!("<{}>", url),
Applicability::MachineApplicable,
)
- .emit()
+ .emit();
});
};
// lambda that will use the lint to start a new diagnostic and add
// a suggestion to it when needed.
- let diag_builder = |lint: LintDiagnosticBuilder<'_>| {
+ let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| {
let explanation = if is_ignore {
"`ignore` code blocks require valid Rust code for syntax highlighting; \
mark blocks that do not contain Rust code as text"
crate::lint::MISSING_DOC_CODE_EXAMPLES,
hir_id,
sp,
- |lint| lint.build("missing code example in this documentation").emit(),
+ |lint| {
+ lint.build("missing code example in this documentation").emit();
+ },
);
}
} else if tests.found_tests > 0
crate::lint::PRIVATE_DOC_TESTS,
hir_id,
item.attr_span(cx.tcx),
- |lint| lint.build("documentation test in private item").emit(),
+ |lint| {
+ lint.build("documentation test in private item").emit();
+ },
);
}
}
let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr");
if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) {
cx.lint(MISSING_ALLOWED_ATTR, |lint| {
- lint.build("Missing 'allowed_attr' attribute").set_span(span).emit()
+ lint.build("Missing 'allowed_attr' attribute").set_span(span).emit();
});
}
}
if !cx.sess().contains_name(attrs, $attr) {
cx.lint(CRATE_NOT_OKAY, |lint| {
let msg = format!("crate is not marked with #![{}]", $attr);
- lint.build(&msg).set_span(span).emit()
+ lint.build(&msg).set_span(span).emit();
});
}
)*
let span = cx.tcx.def_span(CRATE_DEF_ID);
if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) {
cx.lint(CRATE_NOT_OKAY, |lint| {
- lint.build("crate is not marked with #![crate_okay]").set_span(span).emit()
+ lint.build("crate is not marked with #![crate_okay]").set_span(span).emit();
});
}
}
fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) {
match it.ident.as_str() {
"lintme" => cx.lint(TEST_LINT, |lint| {
- lint.build("item is named 'lintme'").set_span(it.span).emit()
+ lint.build("item is named 'lintme'").set_span(it.span).emit();
}),
"pleaselintme" => cx.lint(PLEASE_LINT, |lint| {
- lint.build("item is named 'pleaselintme'").set_span(it.span).emit()
+ lint.build("item is named 'pleaselintme'").set_span(it.span).emit();
}),
_ => {}
}
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
if it.ident.name.as_str() == "lintme" {
cx.lint(TEST_LINT, |lint| {
- lint.build("item is named 'lintme'").set_span(it.span).emit()
+ lint.build("item is named 'lintme'").set_span(it.span).emit();
});
}
}
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
if it.ident.name.as_str() == "lintme" {
cx.lint(TEST_LINT, |lint| {
- lint.build("item is named 'lintme'").set_span(it.span).emit()
+ lint.build("item is named 'lintme'").set_span(it.span).emit();
});
}
if it.ident.name.as_str() == "lintmetoo" {
cx.lint(TEST_GROUP, |lint| {
- lint.build("item is named 'lintmetoo'").set_span(it.span).emit()
+ lint.build("item is named 'lintmetoo'").set_span(it.span).emit();
});
}
}
($method:ident $(,)* $($arg:expr),* $(,)*) => {
match parser.$method($($arg,)*) {
Ok(val) => {
- if parser.sess.span_diagnostic.has_errors() {
+ if parser.sess.span_diagnostic.has_errors().is_some() {
parser.sess.span_diagnostic.reset_err_count();
return None;
} else {
let mut cloned_parser = (*parser).clone();
match $parser(&mut cloned_parser) {
Ok(x) => {
- if parser.sess.span_diagnostic.has_errors() {
+ if parser.sess.span_diagnostic.has_errors().is_some() {
parser.sess.span_diagnostic.reset_err_count();
} else {
// Parsing succeeded.
}
pub(super) fn has_errors(&self) -> bool {
- self.parse_sess.span_diagnostic.has_errors()
+ self.parse_sess.span_diagnostic.has_errors().is_some()
}
pub(super) fn reset_errors(&self) {