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:
commit
d4de1f230c
134 changed files with 1497 additions and 1143 deletions
|
@ -14,6 +14,7 @@ use crate::traits::{
|
|||
PredicateObligations, SelectionContext,
|
||||
};
|
||||
//use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
|
@ -50,7 +51,7 @@ pub struct OverlapResult<'tcx> {
|
|||
pub involves_placeholder: bool,
|
||||
}
|
||||
|
||||
pub fn add_placeholder_note(err: &mut rustc_errors::DiagnosticBuilder<'_>) {
|
||||
pub fn add_placeholder_note(err: &mut Diagnostic) {
|
||||
err.note(
|
||||
"this behavior recently changed as a result of a bug fix; \
|
||||
see rust-lang/rust#56105 for details",
|
||||
|
|
|
@ -12,7 +12,9 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod
|
|||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||
use rustc_errors::{
|
||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorReported,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
|
@ -100,7 +102,7 @@ pub trait InferCtxtExt<'tcx> {
|
|||
expected_args: Vec<ArgKind>,
|
||||
found_args: Vec<ArgKind>,
|
||||
is_closure: bool,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
) -> DiagnosticBuilder<'tcx, ErrorReported>;
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
|
@ -1017,7 +1019,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
expected_args: Vec<ArgKind>,
|
||||
found_args: Vec<ArgKind>,
|
||||
is_closure: bool,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
) -> DiagnosticBuilder<'tcx, ErrorReported> {
|
||||
let kind = if is_closure { "closure" } else { "function" };
|
||||
|
||||
let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {
|
||||
|
@ -1174,7 +1176,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
|
|||
fn report_similar_impl_candidates(
|
||||
&self,
|
||||
impl_candidates: Vec<ImplCandidate<'tcx>>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
|
||||
/// Gets the parent trait chain start
|
||||
|
@ -1186,11 +1188,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
|
|||
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
|
||||
/// with the same path as `trait_ref`, a help message about
|
||||
/// a probable version mismatch is added to `err`
|
||||
fn note_version_mismatch(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
);
|
||||
fn note_version_mismatch(&self, err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>);
|
||||
|
||||
/// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
|
||||
/// `trait_ref`.
|
||||
|
@ -1215,35 +1213,26 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
|
|||
pred: ty::PolyTraitRef<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn note_obligation_cause(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
);
|
||||
fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>);
|
||||
|
||||
fn suggest_unsized_bound_if_applicable(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
);
|
||||
|
||||
fn annotate_source_of_ambiguity(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
impls: &[DefId],
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
);
|
||||
|
||||
fn maybe_suggest_unsized_generics(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
span: Span,
|
||||
node: Node<'hir>,
|
||||
);
|
||||
fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'hir>);
|
||||
|
||||
fn maybe_indirection_for_unsized(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
item: &'hir Item<'hir>,
|
||||
param: &'hir GenericParam<'hir>,
|
||||
) -> bool;
|
||||
|
@ -1572,7 +1561,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn report_similar_impl_candidates(
|
||||
&self,
|
||||
impl_candidates: Vec<ImplCandidate<'tcx>>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
) {
|
||||
if impl_candidates.is_empty() {
|
||||
return;
|
||||
|
@ -1649,11 +1638,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
|
||||
/// with the same path as `trait_ref`, a help message about
|
||||
/// a probable version mismatch is added to `err`
|
||||
fn note_version_mismatch(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
) {
|
||||
fn note_version_mismatch(&self, err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>) {
|
||||
let get_trait_impl = |trait_def_id| {
|
||||
self.tcx.find_map_relevant_impl(trait_def_id, trait_ref.skip_binder().self_ty(), Some)
|
||||
};
|
||||
|
@ -1944,7 +1929,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn annotate_source_of_ambiguity(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
impls: &[DefId],
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
) {
|
||||
|
@ -1977,7 +1962,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
// Avoid complaining about other inference issues for expressions like
|
||||
// `42 >> 1`, where the types are still `{integer}`, but we want to
|
||||
// Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too?
|
||||
err.cancel();
|
||||
// NOTE(eddyb) this was `.cancel()`, but `err`
|
||||
// is borrowed, so we can't fully defuse it.
|
||||
err.downgrade_to_delayed_bug();
|
||||
return;
|
||||
}
|
||||
let post = if post.len() > 4 {
|
||||
|
@ -2088,11 +2075,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn note_obligation_cause(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>) {
|
||||
// First, attempt to add note to this error with an async-await-specific
|
||||
// message, and fall back to regular note otherwise.
|
||||
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
|
||||
|
@ -2110,7 +2093,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn suggest_unsized_bound_if_applicable(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
let (pred, item_def_id, span) = match (
|
||||
|
@ -2139,7 +2122,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn maybe_suggest_unsized_generics<'hir>(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
node: Node<'hir>,
|
||||
) {
|
||||
|
@ -2206,7 +2189,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn maybe_indirection_for_unsized<'hir>(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
item: &'hir Item<'hir>,
|
||||
param: &'hir GenericParam<'hir>,
|
||||
) -> bool {
|
||||
|
|
|
@ -10,7 +10,8 @@ use crate::traits::normalize_projection_type;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
|
||||
error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder,
|
||||
ErrorReported, Style,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
@ -47,7 +48,7 @@ pub enum GeneratorInteriorOrUpvar {
|
|||
pub trait InferCtxtExt<'tcx> {
|
||||
fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
body_id: hir::HirId,
|
||||
);
|
||||
|
@ -55,28 +56,23 @@ pub trait InferCtxtExt<'tcx> {
|
|||
fn suggest_dereferences(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn get_closure_name(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
msg: &str,
|
||||
) -> Option<String>;
|
||||
fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String>;
|
||||
|
||||
fn suggest_fn_call(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
has_custom_message: bool,
|
||||
) -> bool;
|
||||
|
@ -84,27 +80,23 @@ pub trait InferCtxtExt<'tcx> {
|
|||
fn suggest_remove_reference(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_remove_await(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
);
|
||||
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic);
|
||||
|
||||
fn suggest_change_mut(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_semicolon_removal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
@ -113,7 +105,7 @@ pub trait InferCtxtExt<'tcx> {
|
|||
|
||||
fn suggest_impl_trait(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
|
@ -121,7 +113,7 @@ pub trait InferCtxtExt<'tcx> {
|
|||
|
||||
fn point_at_returns_when_relevant(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
);
|
||||
|
||||
|
@ -131,11 +123,11 @@ pub trait InferCtxtExt<'tcx> {
|
|||
found_span: Option<Span>,
|
||||
expected_ref: ty::PolyTraitRef<'tcx>,
|
||||
found: ty::PolyTraitRef<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx>;
|
||||
) -> DiagnosticBuilder<'tcx, ErrorReported>;
|
||||
|
||||
fn suggest_fully_qualified_path(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
trait_ref: DefId,
|
||||
|
@ -143,13 +135,13 @@ pub trait InferCtxtExt<'tcx> {
|
|||
|
||||
fn maybe_note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
interior_or_upvar_span: GeneratorInteriorOrUpvar,
|
||||
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
|
||||
inner_generator_body: Option<&hir::Body<'tcx>>,
|
||||
|
@ -163,7 +155,7 @@ pub trait InferCtxtExt<'tcx> {
|
|||
|
||||
fn note_obligation_cause_code<T>(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
predicate: &T,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
|
@ -172,12 +164,12 @@ pub trait InferCtxtExt<'tcx> {
|
|||
) where
|
||||
T: fmt::Display;
|
||||
|
||||
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>);
|
||||
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
|
||||
|
||||
/// Suggest to await before try: future? => future.await?
|
||||
fn suggest_await_before_try(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
span: Span,
|
||||
|
@ -202,7 +194,7 @@ fn suggest_restriction<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
generics: &hir::Generics<'tcx>,
|
||||
msg: &str,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
fn_sig: Option<&hir::FnSig<'_>>,
|
||||
projection: Option<&ty::ProjectionTy<'_>>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
|
@ -329,7 +321,7 @@ fn suggest_restriction<'tcx>(
|
|||
impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
mut err: &mut DiagnosticBuilder<'_>,
|
||||
mut err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
body_id: hir::HirId,
|
||||
) {
|
||||
|
@ -493,7 +485,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_dereferences(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
// It only make sense when suggesting dereferences for arguments
|
||||
|
@ -549,26 +541,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// Given a closure's `DefId`, return the given name of the closure.
|
||||
///
|
||||
/// This doesn't account for reassignments, but it's only used for suggestions.
|
||||
fn get_closure_name(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
msg: &str,
|
||||
) -> Option<String> {
|
||||
let get_name =
|
||||
|err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind<'_>| -> Option<String> {
|
||||
// Get the local name of this closure. This can be inaccurate because
|
||||
// of the possibility of reassignment, but this should be good enough.
|
||||
match &kind {
|
||||
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => {
|
||||
Some(format!("{}", name))
|
||||
}
|
||||
_ => {
|
||||
err.note(&msg);
|
||||
None
|
||||
}
|
||||
fn get_closure_name(&self, def_id: DefId, err: &mut Diagnostic, msg: &str) -> Option<String> {
|
||||
let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<String> {
|
||||
// Get the local name of this closure. This can be inaccurate because
|
||||
// of the possibility of reassignment, but this should be good enough.
|
||||
match &kind {
|
||||
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => {
|
||||
Some(format!("{}", name))
|
||||
}
|
||||
};
|
||||
_ => {
|
||||
err.note(&msg);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let hir = self.tcx.hir();
|
||||
let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?);
|
||||
|
@ -590,7 +576,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_fn_call(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
let self_ty = match trait_pred.self_ty().no_bound_vars() {
|
||||
|
@ -683,7 +669,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
poly_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
has_custom_message: bool,
|
||||
) -> bool {
|
||||
|
@ -817,7 +803,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_remove_reference(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
let span = obligation.cause.span;
|
||||
|
@ -874,11 +860,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_remove_await(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
) {
|
||||
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) {
|
||||
let span = obligation.cause.span;
|
||||
|
||||
if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives() {
|
||||
|
@ -936,7 +918,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_change_mut(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
let points_at_arg = matches!(
|
||||
|
@ -1012,7 +994,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
fn suggest_semicolon_removal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
|
@ -1063,7 +1045,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// emitted.
|
||||
fn suggest_impl_trait(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
|
@ -1256,7 +1238,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn point_at_returns_when_relevant(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
match obligation.cause.code().peel_derives() {
|
||||
|
@ -1290,7 +1272,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
found_span: Option<Span>,
|
||||
expected_ref: ty::PolyTraitRef<'tcx>,
|
||||
found: ty::PolyTraitRef<'tcx>,
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
) -> DiagnosticBuilder<'tcx, ErrorReported> {
|
||||
crate fn build_fn_sig_string<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
|
@ -1345,7 +1327,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn suggest_fully_qualified_path(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
trait_ref: DefId,
|
||||
|
@ -1411,7 +1393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// Returns `true` if an async-await specific note was added to the diagnostic.
|
||||
fn maybe_note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> bool {
|
||||
debug!(
|
||||
|
@ -1639,7 +1621,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
/// `maybe_note_obligation_cause_for_async_await`'s documentation comment.
|
||||
fn note_obligation_cause_for_async_await(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
interior_or_upvar_span: GeneratorInteriorOrUpvar,
|
||||
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
|
||||
inner_generator_body: Option<&hir::Body<'tcx>>,
|
||||
|
@ -1896,7 +1878,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn note_obligation_cause_code<T>(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
predicate: &T,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
|
@ -2133,7 +2115,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||
let ty = parent_trait_ref.skip_binder().self_ty();
|
||||
if parent_trait_ref.references_error() {
|
||||
err.cancel();
|
||||
// NOTE(eddyb) this was `.cancel()`, but `err`
|
||||
// is borrowed, so we can't fully defuse it.
|
||||
err.downgrade_to_delayed_bug();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2412,7 +2396,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) {
|
||||
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) {
|
||||
let suggested_limit = match self.tcx.recursion_limit() {
|
||||
Limit(0) => Limit(2),
|
||||
limit => limit * 2,
|
||||
|
@ -2427,7 +2411,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn suggest_await_before_try(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
span: Span,
|
||||
|
@ -2615,7 +2599,7 @@ impl NextTypeParamName for &[hir::GenericParam<'_>] {
|
|||
}
|
||||
|
||||
fn suggest_trait_object_return_type_alternatives(
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
err: &mut Diagnostic,
|
||||
ret_ty: Span,
|
||||
trait_obj: &str,
|
||||
is_object_safe: bool,
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::traits::project::ProjectionCacheKeyExt;
|
|||
use crate::traits::ProjectionCacheKey;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_errors::{Diagnostic, ErrorReported};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
|
@ -64,7 +64,7 @@ pub enum IntercrateAmbiguityCause {
|
|||
impl IntercrateAmbiguityCause {
|
||||
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
|
||||
/// See #23980 for details.
|
||||
pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) {
|
||||
pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) {
|
||||
err.note(&self.intercrate_ambiguity_hint());
|
||||
}
|
||||
|
||||
|
|
|
@ -450,7 +450,7 @@ fn report_conflicting_impls(
|
|||
sg.has_errored = true;
|
||||
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));
|
||||
decorate(LintDiagnosticBuilder::new(err.forget_guarantee()));
|
||||
} else {
|
||||
tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_errors::DiagnosticBuilder;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_span::Span;
|
||||
use smallvec::smallvec;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -43,12 +43,7 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {
|
|||
|
||||
/// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate
|
||||
/// trait aliases.
|
||||
pub fn label_with_exp_info(
|
||||
&self,
|
||||
diag: &mut DiagnosticBuilder<'_>,
|
||||
top_label: &str,
|
||||
use_desc: &str,
|
||||
) {
|
||||
pub fn label_with_exp_info(&self, diag: &mut Diagnostic, top_label: &str, use_desc: &str) {
|
||||
diag.span_label(self.top().1, top_label);
|
||||
if self.path.len() > 1 {
|
||||
for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue