1
Fork 0

Use IntoDiagnosticArg where it makes sense

This commit is contained in:
Nikita Tomashevich 2022-08-24 15:46:29 +03:00
parent 74f9973824
commit 3fae3904b1
No known key found for this signature in database
GPG key ID: B29791D4D878E345
5 changed files with 61 additions and 41 deletions

View file

@ -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)>,
},
}

View file

@ -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)
}
}

View file

@ -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,

View file

@ -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);
}