use hir::GenericParamKind;
use rustc_errors::{
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
- MultiSpan, SubdiagnosticMessage,
+ IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
};
use rustc_hir as hir;
use rustc_hir::FnRetTy;
use rustc_macros::{Diagnostic, Subdiagnostic};
-use rustc_middle::ty::{Region, Ty, TyCtxt};
+use rustc_middle::ty::print::TraitRefPrintOnlyTraitPath;
+use rustc_middle::ty::{Binder, FnSig, Region, Ty, TyCtxt};
use rustc_span::symbol::kw;
use rustc_span::Symbol;
use rustc_span::{symbol::Ident, BytePos, Span};
+use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted;
use crate::infer::error_reporting::{
need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
ObligationCauseAsDiagArg,
},
}
+pub enum TyOrSig<'tcx> {
+ Ty(Highlighted<'tcx, Ty<'tcx>>),
+ ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>),
+}
+
+impl IntoDiagnosticArg for TyOrSig<'_> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ match self {
+ TyOrSig::Ty(ty) => ty.into_diagnostic_arg(),
+ TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(),
+ }
+ }
+}
+
#[derive(Subdiagnostic)]
-pub enum ActualImplExplNotes {
+pub enum ActualImplExplNotes<'tcx> {
#[note(infer_actual_impl_expl_expected_signature_two)]
ExpectedSignatureTwo {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note(infer_actual_impl_expl_expected_signature_any)]
ExpectedSignatureAny {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_signature_some)]
ExpectedSignatureSome {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_signature_nothing)]
- ExpectedSignatureNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String },
+ ExpectedSignatureNothing {
+ leading_ellipsis: bool,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ },
#[note(infer_actual_impl_expl_expected_passive_two)]
ExpectedPassiveTwo {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note(infer_actual_impl_expl_expected_passive_any)]
ExpectedPassiveAny {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_passive_some)]
ExpectedPassiveSome {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_passive_nothing)]
- ExpectedPassiveNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String },
+ ExpectedPassiveNothing {
+ leading_ellipsis: bool,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ },
#[note(infer_actual_impl_expl_expected_other_two)]
ExpectedOtherTwo {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note(infer_actual_impl_expl_expected_other_any)]
ExpectedOtherAny {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_other_some)]
ExpectedOtherSome {
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(infer_actual_impl_expl_expected_other_nothing)]
- ExpectedOtherNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String },
+ ExpectedOtherNothing {
+ leading_ellipsis: bool,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ },
#[note(infer_actual_impl_expl_but_actually_implements_trait)]
- ButActuallyImplementsTrait { trait_path: String, has_lifetime: bool, lifetime: usize },
+ ButActuallyImplementsTrait {
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ has_lifetime: bool,
+ lifetime: usize,
+ },
#[note(infer_actual_impl_expl_but_actually_implemented_for_ty)]
ButActuallyImplementedForTy {
- trait_path: String,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
has_lifetime: bool,
lifetime: usize,
ty: String,
},
#[note(infer_actual_impl_expl_but_actually_ty_implements)]
- ButActuallyTyImplements { trait_path: String, has_lifetime: bool, lifetime: usize, ty: String },
+ ButActuallyTyImplements {
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
+ has_lifetime: bool,
+ lifetime: usize,
+ ty: String,
+ },
}
pub enum ActualImplExpectedKind {
Nothing,
}
-impl ActualImplExplNotes {
+impl<'tcx> ActualImplExplNotes<'tcx> {
pub fn new_expected(
kind: ActualImplExpectedKind,
lt_kind: ActualImplExpectedLifetimeKind,
leading_ellipsis: bool,
- ty_or_sig: String,
- trait_path: String,
+ ty_or_sig: TyOrSig<'tcx>,
+ trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
) -> Self {
#[derive(Diagnostic)]
#[diag(infer_trait_placeholder_mismatch)]
-pub struct TraitPlaceholderMismatch {
+pub struct TraitPlaceholderMismatch<'tcx> {
#[primary_span]
pub span: Span,
#[label(label_satisfy)]
pub trait_def_id: String,
#[subdiagnostic(eager)]
- pub actual_impl_expl_notes: Vec<ActualImplExplNotes>,
+ pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>,
}
pub struct ConsiderBorrowingParamHelp {
use crate::errors::{
ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
- TraitPlaceholderMismatch,
+ TraitPlaceholderMismatch, TyOrSig,
};
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::ExpectedFound;
use std::fmt;
+// HACK(eddyb) maybe move this in a more central location.
+#[derive(Copy, Clone)]
+pub struct Highlighted<'tcx, T> {
+ tcx: TyCtxt<'tcx>,
+ highlight: RegionHighlightMode<'tcx>,
+ value: T,
+}
+
+impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T>
+where
+ T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>,
+{
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ rustc_errors::DiagnosticArgValue::Str(self.to_string().into())
+ }
+}
+
+impl<'tcx, T> Highlighted<'tcx, T> {
+ fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> {
+ Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value) }
+ }
+}
+
+impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
+where
+ T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS);
+ printer.region_highlight_mode = self.highlight;
+
+ let s = self.value.print(printer)?.into_buffer();
+ f.write_str(&s)
+ }
+}
+
impl<'tcx> NiceRegionError<'_, 'tcx> {
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
/// an anonymous region, emit a descriptive diagnostic error.
actual_has_vid: Option<usize>,
any_self_ty_has_vid: bool,
leading_ellipsis: bool,
- ) -> Vec<ActualImplExplNotes> {
- // HACK(eddyb) maybe move this in a more central location.
- #[derive(Copy, Clone)]
- struct Highlighted<'tcx, T> {
- tcx: TyCtxt<'tcx>,
- highlight: RegionHighlightMode<'tcx>,
- value: T,
- }
-
- impl<'tcx, T> Highlighted<'tcx, T> {
- fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> {
- Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value) }
- }
- }
-
- impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
- where
- T: for<'a> Print<
- 'tcx,
- FmtPrinter<'a, 'tcx>,
- Error = fmt::Error,
- Output = FmtPrinter<'a, 'tcx>,
- >,
- {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS);
- printer.region_highlight_mode = self.highlight;
-
- let s = self.value.print(printer)?.into_buffer();
- f.write_str(&s)
- }
- }
-
+ ) -> Vec<ActualImplExplNotes<'tcx>> {
// The weird thing here with the `maybe_highlighting_region` calls and the
// the match inside is meant to be like this:
//
});
(
ActualImplExpectedKind::Signature,
- closure_sig.to_string(),
- expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(),
+ TyOrSig::ClosureSig(closure_sig),
+ expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
} else {
(
ActualImplExpectedKind::Other,
- self_ty.to_string(),
- expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(),
+ TyOrSig::Ty(self_ty),
+ expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
}
} else if passive_voice {
(
ActualImplExpectedKind::Passive,
- expected_trait_ref.map(|tr| tr.self_ty()).to_string(),
- expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(),
+ TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
+ expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
} else {
(
ActualImplExpectedKind::Other,
- expected_trait_ref.map(|tr| tr.self_ty()).to_string(),
- expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(),
+ TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
+ expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
};
None => true,
};
- let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string();
+ let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path());
let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string();
let has_lifetime = actual_has_vid.is_some();
let lifetime = actual_has_vid.unwrap_or_default();