1
Fork 0

Auto merge of #93368 - eddyb:diagbld-guarantee, r=estebank

rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".

That is, `DiagnosticBuilder` is now generic over the return type of `.emit()`, so we'll now have:
* `DiagnosticBuilder<ErrorReported>` for error (incl. fatal/bug) diagnostics
  * can only be created via a `const L: Level`-generic constructor, that limits allowed variants via a `where` clause, so not even `rustc_errors` can accidentally bypass this limitation
  * asserts `diagnostic.is_error()` on emission, just in case the construction restriction was bypassed (e.g. by replacing the whole `Diagnostic` inside `DiagnosticBuilder`)
  * `.emit()` returns `ErrorReported`, as a "proof" token that `.emit()` was called
    (though note that this isn't a real guarantee until after completing the work on
     #69426)
* `DiagnosticBuilder<()>` for everything else (warnings, notes, etc.)
  * can also be obtained from other `DiagnosticBuilder`s by calling `.forget_guarantee()`

This PR is a companion to other ongoing work, namely:
* #69426
  and it's ongoing implementation:
  #93222
  the API changes in this PR are needed to get statically-checked "only errors produce `ErrorReported` from `.emit()`", but doesn't itself provide any really strong guarantees without those other `ErrorReported` changes
* #93244
  would make the choices of API changes (esp. naming) in this PR fit better overall

In order to be able to let `.emit()` return anything trustable, several changes had to be made:
* `Diagnostic`'s `level` field is now private to `rustc_errors`, to disallow arbitrary "downgrade"s from "some kind of error" to "warning" (or anything else that doesn't cause compilation to fail)
  * it's still possible to replace the whole `Diagnostic` inside the `DiagnosticBuilder`, sadly, that's harder to fix, but it's unlikely enough that we can paper over it with asserts on `.emit()`
* `.cancel()` now consumes `DiagnosticBuilder`, preventing `.emit()` calls on a cancelled diagnostic
  * it's also now done internally, through `DiagnosticBuilder`-private state, instead of having a `Level::Cancelled` variant that can be read (or worse, written) by the user
  * this removes a hazard of calling `.cancel()` on an error then continuing to attach details to it, and even expect to be able to `.emit()` it
  * warnings were switched to *only* `can_emit_warnings` on emission (instead of pre-cancelling early)
  * `struct_dummy` was removed (as it relied on a pre-`Cancelled` `Diagnostic`)
* since `.emit()` doesn't consume the `DiagnosticBuilder` <sub>(I tried and gave up, it's much more work than this PR)</sub>,
  we have to make `.emit()` idempotent wrt the guarantees it returns
  * thankfully, `err.emit(); err.emit();` can return `ErrorReported` both times, as the second `.emit()` call has no side-effects *only* because the first one did do the appropriate emission
* `&mut Diagnostic` is now used in a lot of function signatures, which used to take `&mut DiagnosticBuilder` (in the interest of not having to make those functions generic)
  * the APIs were already mostly identical, allowing for low-effort porting to this new setup
  * only some of the suggestion methods needed some rework, to have the extra `DiagnosticBuilder` functionality on the `Diagnostic` methods themselves (that change is also present in #93259)
  * `.emit()`/`.cancel()` aren't available, but IMO calling them from an "error decorator/annotator" function isn't a good practice, and can lead to strange behavior (from the caller's perspective)
  * `.downgrade_to_delayed_bug()` was added, letting you convert any `.is_error()` diagnostic into a `delay_span_bug` one (which works because in both cases the guarantees available are the same)

This PR should ideally be reviewed commit-by-commit, since there is a lot of fallout in each.

r? `@estebank` cc `@Manishearth` `@nikomatsakis` `@mark-i-m`
This commit is contained in:
bors 2022-02-25 00:46:04 +00:00
commit d4de1f230c
134 changed files with 1497 additions and 1143 deletions

View file

@ -6,7 +6,7 @@ use crate::astconv::{
use crate::errors::AssocTypeBindingNotAllowed;
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
@ -49,7 +49,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| {
let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut Diagnostic| {
let suggestions = vec![
(arg.span().shrink_to_lo(), String::from("{ ")),
(arg.span().shrink_to_hi(), String::from(" }")),

View file

@ -15,7 +15,7 @@ use crate::middle::resolve_lifetime as rl;
use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported, FatalError};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -2618,7 +2618,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self,
constrained_regions: FxHashSet<ty::BoundRegionKind>,
referenced_regions: FxHashSet<ty::BoundRegionKind>,
generate_err: impl Fn(&str) -> rustc_errors::DiagnosticBuilder<'tcx>,
generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx, ErrorReported>,
) {
for br in referenced_regions.difference(&constrained_regions) {
let br_name = match *br {

View file

@ -1,6 +1,6 @@
use crate::check::coercion::{AsCoercionSite, CoerceMany};
use crate::check::{Diverges, Expectation, FnCtxt, Needs};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::{self as hir, ExprKind};
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::Obligation;
@ -132,7 +132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&cause,
Some(&arm.body),
arm_ty,
Some(&mut |err: &mut DiagnosticBuilder<'_>| {
Some(&mut |err: &mut Diagnostic| {
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
Some(ret_coercion) if self.in_tail_expr => {
let ret_ty = ret_coercion.borrow().expected_ty();

View file

@ -2,7 +2,7 @@ use super::method::MethodCallee;
use super::{Expectation, FnCtxt, TupleArgumentsFlag};
use crate::type_error_struct;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@ -277,7 +277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// likely intention is to call the closure, suggest `(||{})()`. (#55851)
fn identify_bad_closure_def_and_call(
&self,
err: &mut DiagnosticBuilder<'a>,
err: &mut Diagnostic,
hir_id: hir::HirId,
callee_node: &hir::ExprKind<'_>,
callee_span: Span,
@ -304,7 +304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// likely intention is to create an array containing tuples.
fn maybe_suggest_bad_array_definition(
&self,
err: &mut DiagnosticBuilder<'a>,
err: &mut Diagnostic,
call_expr: &'tcx hir::Expr<'tcx>,
callee_expr: &'tcx hir::Expr<'tcx>,
) -> bool {

View file

@ -179,7 +179,7 @@ fn make_invalid_casting_error<'a, 'tcx>(
expr_ty: Ty<'tcx>,
cast_ty: Ty<'tcx>,
fcx: &FnCtxt<'a, 'tcx>,
) -> DiagnosticBuilder<'a> {
) -> DiagnosticBuilder<'a, ErrorReported> {
type_error_struct!(
sess,
span,

View file

@ -37,14 +37,16 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) {
pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
match tcx.sess.target.is_abi_supported(abi) {
Some(true) => (),
Some(false) => struct_span_err!(
tcx.sess,
span,
E0570,
"`{}` is not a supported ABI for the current target",
abi
)
.emit(),
Some(false) => {
struct_span_err!(
tcx.sess,
span,
E0570,
"`{}` is not a supported ABI for the current target",
abi
)
.emit();
}
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()
@ -60,7 +62,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
E0781,
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
)
.emit()
.emit();
}
}

View file

@ -37,7 +37,7 @@
use crate::astconv::AstConv;
use crate::check::FnCtxt;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -1307,7 +1307,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
&mut self,
fcx: &FnCtxt<'a, 'tcx>,
cause: &ObligationCause<'tcx>,
augment_error: &mut dyn FnMut(&mut DiagnosticBuilder<'_>),
augment_error: &mut dyn FnMut(&mut Diagnostic),
label_unit_as_expected: bool,
) {
self.coerce_inner(
@ -1330,7 +1330,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
cause: &ObligationCause<'tcx>,
expression: Option<&'tcx hir::Expr<'tcx>>,
mut expression_ty: Ty<'tcx>,
augment_error: Option<&mut dyn FnMut(&mut DiagnosticBuilder<'_>)>,
augment_error: Option<&mut dyn FnMut(&mut Diagnostic)>,
label_expression_as_expected: bool,
) {
// Incorporate whatever type inference information we have
@ -1520,7 +1520,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx: &FnCtxt<'a, 'tcx>,
id: hir::HirId,
expression: Option<(&'tcx hir::Expr<'tcx>, hir::HirId)>,
) -> DiagnosticBuilder<'a> {
) -> DiagnosticBuilder<'a, ErrorReported> {
let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err);
let mut pointing_at_return_type = false;
@ -1603,7 +1603,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fn add_impl_trait_explanation<'a>(
&self,
err: &mut DiagnosticBuilder<'a>,
err: &mut Diagnostic,
cause: &ObligationCause<'tcx>,
fcx: &FnCtxt<'a, 'tcx>,
expected: Ty<'tcx>,

View file

@ -4,7 +4,7 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::ObligationCause;
use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{is_range_literal, Node};
@ -23,7 +23,7 @@ use std::iter;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn emit_coerce_suggestions(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
expr_ty: Ty<'tcx>,
expected: Ty<'tcx>,
@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
}
@ -67,7 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
match self.at(cause, self.param_env).sup(expected, actual) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations);
@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sp: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
}
@ -97,7 +97,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
match self.at(cause, self.param_env).eq(expected, actual) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations);
@ -134,7 +134,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
allow_two_phase: AllowTwoPhase,
) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx>>) {
) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx, ErrorReported>>) {
let expected = self.resolve_vars_with_obligations(expected);
let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase, None) {
@ -155,7 +155,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn annotate_expected_due_to_let_ty(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
error: TypeError<'_>,
) {
@ -251,7 +251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !lhs.is_syntactic_place_expr() {
// We already emitted E0070 "invalid left-hand side of assignment", so we
// silence this.
err.delay_as_bug();
err.downgrade_to_delayed_bug();
}
}
_ => {}
@ -262,7 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// sole field is of the found type, suggest such variants. (Issue #42764)
fn suggest_compatible_variants(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
expr_ty: Ty<'tcx>,
@ -899,7 +899,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn check_for_cast(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
checked_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>,
@ -1039,7 +1039,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id);
let suggest_fallible_into_or_lhs_from =
|err: &mut DiagnosticBuilder<'_>, exp_to_found_is_fallible: bool| {
|err: &mut Diagnostic, exp_to_found_is_fallible: bool| {
// If we know the expression the expected type is derived from, we might be able
// to suggest a widening conversion rather than a narrowing one (which may
// panic). For example, given x: u8 and y: u32, if we know the span of "x",
@ -1083,7 +1083,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let suggest_to_change_suffix_or_into =
|err: &mut DiagnosticBuilder<'_>,
|err: &mut Diagnostic,
found_to_exp_is_fallible: bool,
exp_to_found_is_fallible: bool| {
let exp_is_lhs =
@ -1282,11 +1282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
// Report the type inferred by the return statement.
fn report_closure_inferred_return_type(
&self,
err: &mut DiagnosticBuilder<'_>,
expected: Ty<'tcx>,
) {
fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
if let Some(sp) = self.ret_coercion_span.get() {
// If the closure has an explicit return type annotation, or if
// the closure's return type has been inferred from outside

View file

@ -25,6 +25,7 @@ use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructEx
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::Diagnostic;
use rustc_errors::ErrorReported;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_hir as hir;
@ -60,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>,
extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
extend_err: impl Fn(&mut Diagnostic),
) -> Ty<'tcx> {
self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected), extend_err)
}
@ -69,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr<'tcx>,
expected: Expectation<'tcx>,
extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
extend_err: impl Fn(&mut Diagnostic),
) -> Ty<'tcx> {
let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
let mut ty = self.check_expr_with_expectation(expr, expected);
@ -485,7 +486,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
});
if !is_named {
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span })
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span });
}
}
@ -1469,14 +1470,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_predicates(obligations)
}
// FIXME: Need better diagnostics for `FieldMisMatch` error
Err(_) => self
.report_mismatched_types(
Err(_) => {
self.report_mismatched_types(
&cause,
target_ty,
fru_ty,
FieldMisMatch(variant.name, ident.name),
)
.emit(),
.emit();
}
}
}
fru_ty
@ -1484,22 +1486,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect()
}
_ => {
return self
.report_mismatched_types(
&self.misc(base_expr.span),
adt_ty,
base_ty,
Sorts(ExpectedFound::new(true, adt_ty, base_ty)),
)
.emit();
self.report_mismatched_types(
&self.misc(base_expr.span),
adt_ty,
base_ty,
Sorts(ExpectedFound::new(true, adt_ty, base_ty)),
)
.emit();
return;
}
}
}
_ => {
return self
.tcx
self.tcx
.sess
.emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
return;
}
}
} else {
@ -1528,10 +1530,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
.collect(),
_ => {
return self
.tcx
self.tcx
.sess
.emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
return;
}
}
};
@ -1923,7 +1925,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_await_on_field_access(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
field_ident: Ident,
base: &'tcx hir::Expr<'tcx>,
ty: Ty<'tcx>,
@ -2123,7 +2125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit();
}
fn point_at_param_definition(&self, err: &mut DiagnosticBuilder<'_>, param: ty::ParamTy) {
fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) {
let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
let generic_param = generics.type_param(&param, self.tcx);
if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param.kind {
@ -2142,7 +2144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_fields_on_recordish(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
def: &'tcx ty::AdtDef,
field: Ident,
access_span: Span,
@ -2171,7 +2173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn maybe_suggest_array_indexing(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
base: &hir::Expr<'_>,
field: Ident,
@ -2195,7 +2197,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_first_deref_field(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
base: &hir::Expr<'_>,
field: Ident,
@ -2212,7 +2214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: Ident,
expr_t: Ty<'tcx>,
id: HirId,
) -> DiagnosticBuilder<'_> {
) -> DiagnosticBuilder<'_, ErrorReported> {
let span = field.span;
debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);

View file

@ -8,7 +8,7 @@ use crate::check::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
use rustc_errors::{Applicability, Diagnostic, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
@ -953,7 +953,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn note_internal_mutation_in_method(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -998,7 +998,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn note_need_for_fn_pointer(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expected: Ty<'tcx>,
found: Ty<'tcx>,
) {

View file

@ -11,7 +11,7 @@ use crate::check::{
use rustc_ast as ast;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_errors::{Applicability, Diagnostic, DiagnosticId};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
@ -460,7 +460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
use crate::structured_errors::MissingCastForVariadicArg;
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit()
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
}
for arg in provided_args.iter().skip(expected_arg_count) {
@ -837,7 +837,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
..
})) => {
err.delay_as_bug();
err.downgrade_to_delayed_bug();
}
_ => {}
}
@ -890,7 +890,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
blk: &'tcx hir::Block<'tcx>,
expected_ty: Ty<'tcx>,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
) {
if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
if let StatementAsExpression::NeedsBoxing = boxed {

View file

@ -4,7 +4,7 @@ use crate::astconv::AstConv;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_span::{self, MultiSpan, Span};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::lang_items::LangItem;
@ -22,11 +22,7 @@ use rustc_middle::ty::subst::GenericArgKind;
use std::iter;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_semicolon_at_end(
&self,
span: Span,
err: &mut DiagnosticBuilder<'_>,
) {
pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
err.span_suggestion_short(
span.shrink_to_hi(),
"consider using a semicolon here",
@ -42,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// - Possible missing return type if the return type is the default, and not `fn main()`.
pub fn suggest_mismatched_types_on_tail(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -81,7 +77,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ```
fn suggest_fn_call(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -211,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn suggest_deref_ref_or_into(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -312,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// in the heap by calling `Box::new()`.
pub(in super::super) fn suggest_boxing_when_appropriate(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -347,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// suggest a non-capturing closure
pub(in super::super) fn suggest_no_capture_closure(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expected: Ty<'tcx>,
found: Ty<'tcx>,
) {
@ -382,7 +378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self, err))]
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -477,7 +473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// it suggests adding a semicolon.
fn suggest_missing_semicolon(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expression: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>,
) {
@ -518,7 +514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// type.
pub(in super::super) fn suggest_missing_return_type(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
fn_decl: &hir::FnDecl<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
@ -580,7 +576,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ```
fn try_suggest_return_impl_trait(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expected: Ty<'tcx>,
found: Ty<'tcx>,
fn_id: hir::HirId,
@ -681,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_missing_break_or_return_expr(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &'tcx hir::Expr<'tcx>,
fn_decl: &hir::FnDecl<'_>,
expected: Ty<'tcx>,
@ -751,7 +747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_missing_parentheses(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
) {
let sp = self.tcx.sess.source_map().start_point(expr.span);

View file

@ -14,7 +14,7 @@ pub use self::MethodError::*;
use crate::check::FnCtxt;
use crate::ObligationCause;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId;
@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self, err, call_expr))]
crate fn suggest_method_call(
&self,
err: &mut DiagnosticBuilder<'a>,
err: &mut Diagnostic,
msg: &str,
method_name: Ident,
self_ty: Ty<'tcx>,

View file

@ -3,7 +3,9 @@
use crate::check::FnCtxt;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported,
};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
@ -91,14 +93,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
source: SelfSource<'tcx>,
error: MethodError<'tcx>,
args: Option<&'tcx [hir::Expr<'tcx>]>,
) -> Option<DiagnosticBuilder<'_>> {
) -> Option<DiagnosticBuilder<'_, ErrorReported>> {
// Avoid suggestions when we don't know what's going on.
if rcvr_ty.references_error() {
return None;
}
let report_candidates = |span: Span,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
mut sources: Vec<CandidateSource>,
sugg_span: Span| {
sources.sort();
@ -268,7 +270,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(None, true) => "variant",
}
};
let mut err = if !actual.references_error() {
// FIXME(eddyb) this intendation is probably unnecessary.
let mut err = {
// Suggest clamping down the type if the method that is being attempted to
// be used exists at all, and the type is an ambiguous numeric type
// ({integer}/{float}).
@ -461,10 +464,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
err
}
} else {
tcx.sess.diagnostic().struct_dummy()
};
if actual.references_error() {
err.downgrade_to_delayed_bug();
}
if let Some(def) = actual.ty_adt_def() {
if let Some(full_sp) = tcx.hir().span_if_local(def.did) {
let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
@ -625,10 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if self.is_fn_ty(rcvr_ty, span) {
fn report_function<T: std::fmt::Display>(
err: &mut DiagnosticBuilder<'_>,
name: T,
) {
fn report_function<T: std::fmt::Display>(err: &mut Diagnostic, name: T) {
err.note(
&format!("`{}` is a function, perhaps you wish to call it", name,),
);
@ -1111,7 +1113,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
crate fn note_unmet_impls_on_type(
&self,
err: &mut rustc_errors::DiagnosticBuilder<'_>,
err: &mut Diagnostic,
errors: Vec<FulfillmentError<'tcx>>,
) {
let all_local_types_needing_impls =
@ -1187,7 +1189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_derive(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
unsatisfied_predicates: &[(
ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
@ -1287,7 +1289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_await_before_method(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
item_name: Ident,
ty: Ty<'tcx>,
call: &hir::Expr<'_>,
@ -1311,7 +1313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_use_candidates(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
mut msg: String,
candidates: Vec<DefId>,
) {
@ -1416,7 +1418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_valid_traits(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
valid_out_of_scope_traits: Vec<DefId>,
) -> bool {
if !valid_out_of_scope_traits.is_empty() {
@ -1454,7 +1456,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_traits_to_import(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
span: Span,
rcvr_ty: Ty<'tcx>,
item_name: Ident,
@ -1983,7 +1985,7 @@ fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Op
fn print_disambiguation_help<'tcx>(
item_name: Ident,
args: Option<&'tcx [hir::Expr<'tcx>]>,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
trait_name: String,
rcvr_ty: Ty<'_>,
kind: ty::AssocKind,

View file

@ -139,11 +139,13 @@ pub use self::Expectation::*;
#[macro_export]
macro_rules! type_error_struct {
($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
let mut err = rustc_errors::struct_span_err!($session, $span, $code, $($message)*);
if $typ.references_error() {
$session.diagnostic().struct_dummy()
} else {
rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
err.downgrade_to_delayed_bug();
}
err
})
}

View file

@ -3,7 +3,7 @@
use super::method::MethodCallee;
use super::{has_expected_num_generic_args, FnCtxt};
use rustc_ast as ast;
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{self, struct_span_err, Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::adjustment::{
@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// suggest calling the function. Returns `true` if suggestion would apply (even if not given).
fn add_type_neq_err_label(
&self,
err: &mut rustc_errors::DiagnosticBuilder<'_>,
err: &mut Diagnostic,
span: Span,
ty: Ty<'tcx>,
other_ty: Ty<'tcx>,
@ -545,7 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_expr: &'tcx hir::Expr<'tcx>,
lhs_ty: Ty<'tcx>,
rhs_ty: Ty<'tcx>,
err: &mut rustc_errors::DiagnosticBuilder<'_>,
err: &mut Diagnostic,
is_assign: IsAssign,
op: hir::BinOp,
) -> bool {
@ -937,7 +937,7 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool
fn suggest_constraining_param(
tcx: TyCtxt<'_>,
body_id: hir::HirId,
mut err: &mut DiagnosticBuilder<'_>,
mut err: &mut Diagnostic,
lhs_ty: Ty<'_>,
rhs_ty: Ty<'_>,
missing_trait: &str,

View file

@ -2,7 +2,9 @@ use crate::check::FnCtxt;
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
@ -98,7 +100,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
expected: Ty<'tcx>,
actual: Ty<'tcx>,
ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
}
@ -512,7 +514,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
}
fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) {
fn endpoint_has_type(&self, err: &mut Diagnostic, span: Span, ty: Ty<'_>) {
if !ty.references_error() {
err.span_label(span, &format!("this is of type `{}`", ty));
}
@ -645,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn borrow_pat_suggestion(
&self,
err: &mut DiagnosticBuilder<'_>,
err: &mut Diagnostic,
pat: &Pat<'_>,
inner: &Pat<'_>,
expected: Ty<'tcx>,
@ -783,7 +785,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn maybe_suggest_range_literal(
&self,
e: &mut DiagnosticBuilder<'_>,
e: &mut Diagnostic,
opt_def_id: Option<hir::def_id::DefId>,
ident: Ident,
) -> bool {
@ -817,7 +819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn emit_bad_pat_path<'b>(
&self,
mut e: DiagnosticBuilder<'_>,
mut e: DiagnosticBuilder<'_, ErrorReported>,
pat_span: Span,
res: Res,
pat_res: Res,
@ -1368,7 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant: &VariantDef,
pat: &'_ Pat<'_>,
fields: &[hir::PatField<'_>],
) -> Option<DiagnosticBuilder<'_>> {
) -> Option<DiagnosticBuilder<'_, ErrorReported>> {
// if this is a tuple struct, then all field names will be numbers
// so if any fields in a struct pattern use shorthand syntax, they will
// be invalid identifiers (for example, Foo { 0, 1 }).
@ -1441,7 +1443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
inexistent_fields: &[Ident],
unmentioned_fields: &mut Vec<(&ty::FieldDef, Ident)>,
variant: &ty::VariantDef,
) -> DiagnosticBuilder<'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let tcx = self.tcx;
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
(format!("a field named `{}`", inexistent_fields[0]), "this", "")
@ -1537,7 +1539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>],
variant: &ty::VariantDef,
) -> Option<DiagnosticBuilder<'tcx>> {
) -> Option<DiagnosticBuilder<'tcx, ErrorReported>> {
if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) {
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
s.print_qpath(qpath, false)
@ -1619,7 +1621,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>],
) -> DiagnosticBuilder<'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = self
.tcx
.sess
@ -1711,7 +1713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unmentioned_fields: &[(&ty::FieldDef, Ident)],
have_inaccessible_fields: bool,
fields: &'tcx [hir::PatField<'tcx>],
) -> DiagnosticBuilder<'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
let field_names = if unmentioned_fields.len() == 1 {
format!("field `{}`{}", unmentioned_fields[0].1, inaccessible)

View file

@ -4,7 +4,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit as hir_visit;
@ -448,7 +448,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
for more information",
);
err.emit()
err.emit();
}
}
}
@ -843,7 +843,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
"using {} as const generic parameters is forbidden",
unsupported_type
),
)
);
} else {
let mut err = tcx.sess.struct_span_err(
hir_ty.span,
@ -858,7 +858,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
"more complex types are supported with `#![feature(adt_const_params)]`",
);
}
err.emit()
err.emit();
}
};
@ -1729,12 +1729,14 @@ fn check_variances_for_type_defn<'tcx>(
match param.name {
hir::ParamName::Error => {}
_ => report_bivariance(tcx, param),
_ => {
report_bivariance(tcx, param);
}
}
}
}
fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) {
fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> ErrorReported {
let span = param.span;
let param_name = param.name.ident().name;
let mut err = error_392(tcx, span, param_name);
@ -1943,7 +1945,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
fn error_392(
tcx: TyCtxt<'_>,
span: Span,
param_name: Symbol,
) -> DiagnosticBuilder<'_, ErrorReported> {
let mut err =
struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name);
err.span_label(span, "unused parameter");

View file

@ -94,7 +94,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
for span in fields.iter().map(|f| tcx.def_span(f.did)) {
err.span_label(span, "this field does not implement `Copy`");
}
err.emit()
err.emit();
}
Err(CopyImplementationError::NotAnAdt) => {
let item = tcx.hir().expect_item(impl_did);

View file

@ -159,7 +159,7 @@ fn emit_orphan_check_error<'tcx>(
generics: &hir::Generics<'tcx>,
err: traits::OrphanCheckErr<'tcx>,
) -> Result<!, ErrorReported> {
match err {
Err(match err {
traits::OrphanCheckErr::NonLocalInputType(tys) => {
let mut err = struct_span_err!(
tcx.sess,
@ -269,9 +269,7 @@ fn emit_orphan_check_error<'tcx>(
.emit(),
}
}
}
Err(ErrorReported)
})
}
#[derive(Default)]

View file

@ -26,7 +26,7 @@ use rustc_ast::{MetaItemKind, NestedMetaItem};
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, Applicability};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@ -321,7 +321,7 @@ fn bad_placeholder<'tcx>(
tcx: TyCtxt<'tcx>,
mut spans: Vec<Span>,
kind: &'static str,
) -> rustc_errors::DiagnosticBuilder<'tcx> {
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) };
spans.sort();
@ -1277,19 +1277,21 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
return None;
}
Some(item) => tcx
.sess
.struct_span_err(item.span, "Not a function")
.span_note(attr_span, "required by this annotation")
.note(
"All `#[rustc_must_implement_one_of]` arguments \
Some(item) => {
tcx.sess
.struct_span_err(item.span, "Not a function")
.span_note(attr_span, "required by this annotation")
.note(
"All `#[rustc_must_implement_one_of]` arguments \
must be associated function names",
)
.emit(),
None => tcx
.sess
.struct_span_err(ident.span, "Function not found in this trait")
.emit(),
)
.emit();
}
None => {
tcx.sess
.struct_span_err(ident.span, "Function not found in this trait")
.emit();
}
}
Some(())

View file

@ -393,13 +393,14 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
tcx.def_path_str(trait_ref.def_id),
),
)
.emit()
.emit();
}
}
_ => tcx
.sess
.struct_span_err(span, &format!("cannot specialize on `{:?}`", predicate))
.emit(),
_ => {
tcx.sess
.struct_span_err(span, &format!("cannot specialize on `{:?}`", predicate))
.emit();
}
}
}

View file

@ -6,7 +6,7 @@ pub use self::{
missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
};
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_session::Session;
pub trait StructuredDiagnostic<'tcx> {
@ -14,7 +14,7 @@ pub trait StructuredDiagnostic<'tcx> {
fn code(&self) -> DiagnosticId;
fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
fn diagnostic(&self) -> DiagnosticBuilder<'tcx, ErrorReported> {
let err = self.diagnostic_common();
if self.session().teach(&self.code()) {
@ -24,13 +24,19 @@ pub trait StructuredDiagnostic<'tcx> {
}
}
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx>;
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported>;
fn diagnostic_regular(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
fn diagnostic_regular(
&self,
err: DiagnosticBuilder<'tcx, ErrorReported>,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
err
}
fn diagnostic_extended(&self, err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
fn diagnostic_extended(
&self,
err: DiagnosticBuilder<'tcx, ErrorReported>,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
err
}
}

View file

@ -1,5 +1,5 @@
use crate::structured_errors::StructuredDiagnostic;
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_middle::ty::{Ty, TypeFoldable};
use rustc_session::Session;
use rustc_span::Span;
@ -20,16 +20,16 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx> {
rustc_errors::error_code!(E0617)
}
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
let mut err = if self.ty.references_error() {
self.sess.diagnostic().struct_dummy()
} else {
self.sess.struct_span_fatal_with_code(
self.span,
&format!("can't pass `{}` to variadic function", self.ty),
self.code(),
)
};
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = self.sess.struct_span_fatal_with_code(
self.span,
&format!("can't pass `{}` to variadic function", self.ty),
self.code(),
);
if self.ty.references_error() {
err.downgrade_to_delayed_bug();
}
if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
err.span_suggestion(
@ -45,7 +45,10 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx> {
err
}
fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
fn diagnostic_extended(
&self,
mut err: DiagnosticBuilder<'tcx, ErrorReported>,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
err.note(&format!(
"certain types, like `{}`, must be casted before passing them to a \
variadic function, because of arcane ABI rules dictated by the C \

View file

@ -1,5 +1,5 @@
use crate::structured_errors::StructuredDiagnostic;
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_middle::ty::{Ty, TypeFoldable};
use rustc_session::Session;
use rustc_span::Span;
@ -20,22 +20,27 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> {
rustc_errors::error_code!(E0607)
}
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = self.sess.struct_span_fatal_with_code(
self.span,
&format!(
"cannot cast thin pointer `{}` to fat pointer `{}`",
self.expr_ty, self.cast_ty
),
self.code(),
);
if self.expr_ty.references_error() {
self.sess.diagnostic().struct_dummy()
} else {
self.sess.struct_span_fatal_with_code(
self.span,
&format!(
"cannot cast thin pointer `{}` to fat pointer `{}`",
self.expr_ty, self.cast_ty
),
self.code(),
)
err.downgrade_to_delayed_bug();
}
err
}
fn diagnostic_extended(&self, mut err: DiagnosticBuilder<'tcx>) -> DiagnosticBuilder<'tcx> {
fn diagnostic_extended(
&self,
mut err: DiagnosticBuilder<'tcx, ErrorReported>,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
err.help(
"Thin pointers are \"simple\" pointers: they are purely a reference to a
memory address.

View file

@ -1,5 +1,7 @@
use crate::structured_errors::StructuredDiagnostic;
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_errors::{
pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported,
};
use rustc_hir as hir;
use rustc_middle::hir::map::fn_sig;
use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
@ -362,7 +364,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> {
fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx, ErrorReported> {
let span = self.path_segment.ident.span;
let msg = self.create_error_message();
@ -370,7 +372,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
/// Builds the `expected 1 type argument / supplied 2 type arguments` message.
fn notify(&self, err: &mut DiagnosticBuilder<'_>) {
fn notify(&self, err: &mut Diagnostic) {
let (quantifier, bound) = self.get_quantifier_and_bound();
let provided_args = self.num_provided_args();
@ -422,7 +424,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
fn suggest(&self, err: &mut DiagnosticBuilder<'_>) {
fn suggest(&self, err: &mut Diagnostic) {
debug!(
"suggest(self.provided {:?}, self.gen_args.span(): {:?})",
self.num_provided_args(),
@ -449,7 +451,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
/// ```text
/// type Map = HashMap<String>;
/// ```
fn suggest_adding_args(&self, err: &mut DiagnosticBuilder<'_>) {
fn suggest_adding_args(&self, err: &mut Diagnostic) {
if self.gen_args.parenthesized {
return;
}
@ -465,7 +467,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
fn suggest_adding_lifetime_args(&self, err: &mut DiagnosticBuilder<'_>) {
fn suggest_adding_lifetime_args(&self, err: &mut Diagnostic) {
debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
let num_missing_args = self.num_missing_lifetime_args();
let num_params_to_take = num_missing_args;
@ -547,7 +549,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
}
fn suggest_adding_type_and_const_args(&self, err: &mut DiagnosticBuilder<'_>) {
fn suggest_adding_type_and_const_args(&self, err: &mut Diagnostic) {
let num_missing_args = self.num_missing_type_or_const_args();
let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
@ -602,7 +604,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
/// ```text
/// type Map = HashMap<String, String, String, String>;
/// ```
fn suggest_removing_args_or_generics(&self, err: &mut DiagnosticBuilder<'_>) {
fn suggest_removing_args_or_generics(&self, err: &mut Diagnostic) {
let num_provided_lt_args = self.num_provided_lifetime_args();
let num_provided_type_const_args = self.num_provided_type_or_const_args();
let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
@ -617,7 +619,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
let remove_lifetime_args = |err: &mut DiagnosticBuilder<'_>| {
let remove_lifetime_args = |err: &mut Diagnostic| {
let mut lt_arg_spans = Vec::new();
let mut found_redundant = false;
for arg in self.gen_args.args {
@ -659,7 +661,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
);
};
let remove_type_or_const_args = |err: &mut DiagnosticBuilder<'_>| {
let remove_type_or_const_args = |err: &mut Diagnostic| {
let mut gen_arg_spans = Vec::new();
let mut found_redundant = false;
for arg in self.gen_args.args {
@ -729,7 +731,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}
/// Builds the `type defined here` message.
fn show_definition(&self, err: &mut DiagnosticBuilder<'_>) {
fn show_definition(&self, err: &mut Diagnostic) {
let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) {
if self.tcx.sess.source_map().span_to_snippet(def_span).is_ok() {
def_span.into()
@ -789,7 +791,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
rustc_errors::error_code!(E0107)
}
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = self.start_diagnostics();
self.notify(&mut err);