Use IntoDiagnosticArg
where it makes sense
This commit is contained in:
parent
74f9973824
commit
3fae3904b1
5 changed files with 61 additions and 41 deletions
|
@ -3,6 +3,11 @@ use rustc_hir::FnRetTy;
|
|||
use rustc_macros::SessionDiagnostic;
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
||||
use crate::infer::error_reporting::{
|
||||
need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
|
||||
ObligationCauseAsDiagArg,
|
||||
};
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(infer::opaque_hidden_type)]
|
||||
pub struct OpaqueHiddenTypeDiag {
|
||||
|
@ -73,7 +78,7 @@ pub struct AmbigousReturn<'a> {
|
|||
pub struct NeedTypeInfoInGenerator<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub generator_kind: &'static str,
|
||||
pub generator_kind: GeneratorKindAsDiagArg,
|
||||
#[subdiagnostic]
|
||||
pub bad_label: InferenceBadError<'a>,
|
||||
}
|
||||
|
@ -85,7 +90,7 @@ pub struct InferenceBadError<'a> {
|
|||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub bad_kind: &'static str,
|
||||
pub prefix_kind: &'static str,
|
||||
pub prefix_kind: UnderspecifiedArgKind,
|
||||
pub has_parent: bool,
|
||||
pub prefix: &'a str,
|
||||
pub parent_prefix: &'a str,
|
||||
|
@ -107,7 +112,7 @@ pub enum SourceKindSubdiag<'a> {
|
|||
type_name: String,
|
||||
kind: &'static str,
|
||||
x_kind: &'static str,
|
||||
prefix_kind: &'static str,
|
||||
prefix_kind: UnderspecifiedArgKind,
|
||||
prefix: &'a str,
|
||||
arg_name: String,
|
||||
},
|
||||
|
@ -199,7 +204,7 @@ pub enum RegionOriginNote<'a> {
|
|||
},
|
||||
WithRequirement {
|
||||
span: Span,
|
||||
requirement: &'static str,
|
||||
requirement: ObligationCauseAsDiagArg<'a>,
|
||||
expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ use crate::traits::{
|
|||
};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
|
||||
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg};
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
|
@ -78,7 +78,7 @@ use std::{cmp, fmt, iter};
|
|||
|
||||
mod note;
|
||||
|
||||
mod need_type_info;
|
||||
pub(crate) mod need_type_info;
|
||||
pub use need_type_info::TypeAnnotationNeeded;
|
||||
|
||||
pub mod nice_region_error;
|
||||
|
@ -2811,7 +2811,6 @@ pub enum FailureCode {
|
|||
pub trait ObligationCauseExt<'tcx> {
|
||||
fn as_failure_code(&self, terr: TypeError<'tcx>) -> FailureCode;
|
||||
fn as_requirement_str(&self) -> &'static str;
|
||||
fn as_requirement_localised(&self) -> &'static str;
|
||||
}
|
||||
|
||||
impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||
|
@ -2880,10 +2879,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
|||
_ => "types are compatible",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn as_requirement_localised(&self) -> &'static str {
|
||||
/// Newtype to allow implementing IntoDiagnosticArg
|
||||
pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>);
|
||||
|
||||
impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
use crate::traits::ObligationCauseCode::*;
|
||||
match self.code() {
|
||||
let kind = match self.0.code() {
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => "method_compat",
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => "type_compat",
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => "const_compat",
|
||||
|
@ -2896,6 +2900,8 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
|||
MethodReceiver => "method_correct_type",
|
||||
_ => "other",
|
||||
}
|
||||
.into();
|
||||
rustc_errors::DiagnosticArgValue::Str(kind)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::errors::{
|
|||
};
|
||||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Namespace};
|
||||
|
@ -65,6 +65,7 @@ pub struct InferenceDiagnosticsParentData {
|
|||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum UnderspecifiedArgKind {
|
||||
Type { prefix: Cow<'static, str> },
|
||||
Const { is_parameter: bool },
|
||||
|
@ -101,7 +102,7 @@ impl InferenceDiagnosticsData {
|
|||
InferenceBadError {
|
||||
span,
|
||||
bad_kind,
|
||||
prefix_kind: self.kind.prefix_kind(),
|
||||
prefix_kind: self.kind.clone(),
|
||||
prefix: self.kind.try_get_prefix().unwrap_or_default(),
|
||||
name: self.name.clone(),
|
||||
has_parent,
|
||||
|
@ -130,14 +131,18 @@ impl InferenceDiagnosticsParentData {
|
|||
}
|
||||
}
|
||||
|
||||
impl UnderspecifiedArgKind {
|
||||
fn prefix_kind(&self) -> &'static str {
|
||||
match self {
|
||||
impl IntoDiagnosticArg for UnderspecifiedArgKind {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
let kind = match self {
|
||||
Self::Type { .. } => "type",
|
||||
Self::Const { is_parameter: true } => "const_with_param",
|
||||
Self::Const { is_parameter: false } => "const",
|
||||
}
|
||||
};
|
||||
rustc_errors::DiagnosticArgValue::Str(kind.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl UnderspecifiedArgKind {
|
||||
fn try_get_prefix(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Type { prefix } => Some(prefix.as_ref()),
|
||||
|
@ -405,7 +410,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
span: insert_span,
|
||||
name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
|
||||
x_kind: arg_data.where_x_is_kind(ty),
|
||||
prefix_kind: arg_data.kind.prefix_kind(),
|
||||
prefix_kind: arg_data.kind.clone(),
|
||||
prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
|
||||
arg_name: arg_data.name,
|
||||
kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
|
||||
|
@ -417,7 +422,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
span: insert_span,
|
||||
name: String::new(),
|
||||
x_kind: arg_data.where_x_is_kind(ty),
|
||||
prefix_kind: arg_data.kind.prefix_kind(),
|
||||
prefix_kind: arg_data.kind.clone(),
|
||||
prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
|
||||
arg_name: arg_data.name,
|
||||
kind: "closure",
|
||||
|
@ -568,12 +573,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
NeedTypeInfoInGenerator {
|
||||
bad_label: data.make_bad_error(span),
|
||||
span,
|
||||
generator_kind: kind.descr(),
|
||||
generator_kind: GeneratorKindAsDiagArg(kind),
|
||||
}
|
||||
.into_diagnostic(&self.tcx.sess.parse_sess)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
|
||||
|
||||
impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
let kind = match self.0 {
|
||||
hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
|
||||
hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
|
||||
hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
|
||||
hir::GeneratorKind::Gen => "generator",
|
||||
};
|
||||
rustc_errors::DiagnosticArgValue::Str(kind.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InferSource<'tcx> {
|
||||
span: Span,
|
||||
|
|
|
@ -1,40 +1,26 @@
|
|||
use crate::errors::RegionOriginNote;
|
||||
use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
|
||||
use crate::infer::error_reporting::note_and_explain_region;
|
||||
use crate::infer::{self, InferCtxt, SubregionOrigin};
|
||||
use rustc_errors::{
|
||||
fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
|
||||
ErrorGuaranteed,
|
||||
fluent, struct_span_err, AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
};
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::{self, Region};
|
||||
|
||||
use super::ObligationCauseAsDiagArg;
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) {
|
||||
let mut label_or_note = |span, msg: DiagnosticMessage| {
|
||||
let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count();
|
||||
let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count();
|
||||
let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span);
|
||||
if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
|
||||
err.span_label(span, msg);
|
||||
} else if span_is_primary && expanded_sub_count == 0 {
|
||||
err.note(msg);
|
||||
} else {
|
||||
err.span_note(span, msg);
|
||||
}
|
||||
};
|
||||
match *origin {
|
||||
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
|
||||
span: trace.cause.span,
|
||||
requirement: trace.cause.as_requirement_localised(),
|
||||
requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
|
||||
expected_found: self.values_str(trace.values),
|
||||
}
|
||||
.add_to_diagnostic(err),
|
||||
infer::Reborrow(span) => {
|
||||
label_or_note(span, fluent::infer::reborrow);
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer::reborrow }
|
||||
.add_to_diagnostic(err)
|
||||
}
|
||||
infer::Reborrow(span) => RegionOriginNote::Plain { span, msg: fluent::infer::reborrow }
|
||||
.add_to_diagnostic(err),
|
||||
infer::ReborrowUpvar(span, ref upvar_id) => {
|
||||
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
|
||||
RegionOriginNote::WithName {
|
||||
|
@ -46,7 +32,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
.add_to_diagnostic(err);
|
||||
}
|
||||
infer::RelateObjectBound(span) => {
|
||||
label_or_note(span, fluent::infer::relate_object_bound);
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer::relate_object_bound }
|
||||
.add_to_diagnostic(err);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue