diff options
Diffstat (limited to 'compiler/rustc_infer/src/errors/mod.rs')
| -rw-r--r-- | compiler/rustc_infer/src/errors/mod.rs | 1623 |
1 files changed, 2 insertions, 1621 deletions
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 2716160d446..1a5c0137219 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1,28 +1,5 @@ -use hir::GenericParamKind; -use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{ - codes::*, Applicability, Diag, DiagMessage, DiagStyledString, EmissionGuarantee, IntoDiagArg, - MultiSpan, SubdiagMessageOp, Subdiagnostic, -}; -use rustc_hir as hir; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::intravisit::{walk_ty, Visitor}; -use rustc_hir::FnRetTy; -use rustc_macros::{Diagnostic, Subdiagnostic}; -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::error_reporting::infer::need_type_info::UnderspecifiedArgKind; -use crate::error_reporting::infer::nice_region_error::placeholder_error::Highlighted; -use crate::error_reporting::infer::ObligationCauseAsDiagArg; -use crate::fluent_generated as fluent; - -use std::path::PathBuf; - -pub mod note_and_explain; +use rustc_macros::Diagnostic; +use rustc_span::Span; #[derive(Diagnostic)] #[diag(infer_opaque_hidden_type)] @@ -35,1599 +12,3 @@ pub struct OpaqueHiddenTypeDiag { #[note(infer_hidden_type)] pub hidden_type: Span, } - -#[derive(Diagnostic)] -#[diag(infer_type_annotations_needed, code = E0282)] -pub struct AnnotationRequired<'a> { - #[primary_span] - pub span: Span, - pub source_kind: &'static str, - pub source_name: &'a str, - #[label] - pub failure_span: Option<Span>, - #[subdiagnostic] - pub bad_label: Option<InferenceBadError<'a>>, - #[subdiagnostic] - pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, - #[subdiagnostic] - pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, - #[note(infer_full_type_written)] - pub was_written: Option<()>, - pub path: PathBuf, -} - -// Copy of `AnnotationRequired` for E0283 -#[derive(Diagnostic)] -#[diag(infer_type_annotations_needed, code = E0283)] -pub struct AmbiguousImpl<'a> { - #[primary_span] - pub span: Span, - pub source_kind: &'static str, - pub source_name: &'a str, - #[label] - pub failure_span: Option<Span>, - #[subdiagnostic] - pub bad_label: Option<InferenceBadError<'a>>, - #[subdiagnostic] - pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, - #[subdiagnostic] - pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, - #[note(infer_full_type_written)] - pub was_written: Option<()>, - pub path: PathBuf, -} - -// Copy of `AnnotationRequired` for E0284 -#[derive(Diagnostic)] -#[diag(infer_type_annotations_needed, code = E0284)] -pub struct AmbiguousReturn<'a> { - #[primary_span] - pub span: Span, - pub source_kind: &'static str, - pub source_name: &'a str, - #[label] - pub failure_span: Option<Span>, - #[subdiagnostic] - pub bad_label: Option<InferenceBadError<'a>>, - #[subdiagnostic] - pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, - #[subdiagnostic] - pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, - #[note(infer_full_type_written)] - pub was_written: Option<()>, - pub path: PathBuf, -} - -// Used when a better one isn't available -#[derive(Subdiagnostic)] -#[label(infer_label_bad)] -pub struct InferenceBadError<'a> { - #[primary_span] - pub span: Span, - pub bad_kind: &'static str, - pub prefix_kind: UnderspecifiedArgKind, - pub has_parent: bool, - pub prefix: &'a str, - pub parent_prefix: &'a str, - pub parent_name: String, - pub name: String, -} - -#[derive(Subdiagnostic)] -pub enum SourceKindSubdiag<'a> { - #[suggestion( - infer_source_kind_subdiag_let, - style = "verbose", - code = ": {type_name}", - applicability = "has-placeholders" - )] - LetLike { - #[primary_span] - span: Span, - name: String, - type_name: String, - kind: &'static str, - x_kind: &'static str, - prefix_kind: UnderspecifiedArgKind, - prefix: &'a str, - arg_name: String, - }, - #[label(infer_source_kind_subdiag_generic_label)] - GenericLabel { - #[primary_span] - span: Span, - is_type: bool, - param_name: String, - parent_exists: bool, - parent_prefix: String, - parent_name: String, - }, - #[suggestion( - infer_source_kind_subdiag_generic_suggestion, - style = "verbose", - code = "::<{args}>", - applicability = "has-placeholders" - )] - GenericSuggestion { - #[primary_span] - span: Span, - arg_count: usize, - args: String, - }, -} - -#[derive(Subdiagnostic)] -pub enum SourceKindMultiSuggestion<'a> { - #[multipart_suggestion( - infer_source_kind_fully_qualified, - style = "verbose", - applicability = "has-placeholders" - )] - FullyQualified { - #[suggestion_part(code = "{def_path}({adjustment}")] - span_lo: Span, - #[suggestion_part(code = "{successor_pos}")] - span_hi: Span, - def_path: String, - adjustment: &'a str, - successor_pos: &'a str, - }, - #[multipart_suggestion( - infer_source_kind_closure_return, - style = "verbose", - applicability = "has-placeholders" - )] - ClosureReturn { - #[suggestion_part(code = "{start_span_code}")] - start_span: Span, - start_span_code: String, - #[suggestion_part(code = " }}")] - end_span: Option<Span>, - }, -} - -impl<'a> SourceKindMultiSuggestion<'a> { - pub fn new_fully_qualified( - span: Span, - def_path: String, - adjustment: &'a str, - successor: (&'a str, BytePos), - ) -> Self { - Self::FullyQualified { - span_lo: span.shrink_to_lo(), - span_hi: span.shrink_to_hi().with_hi(successor.1), - def_path, - adjustment, - successor_pos: successor.0, - } - } - - pub fn new_closure_return( - ty_info: String, - data: &'a FnRetTy<'a>, - should_wrap_expr: Option<Span>, - ) -> Self { - let arrow = match data { - FnRetTy::DefaultReturn(_) => " -> ", - _ => "", - }; - let (start_span, start_span_code, end_span) = match should_wrap_expr { - Some(end_span) => (data.span(), format!("{arrow}{ty_info} {{"), Some(end_span)), - None => (data.span(), format!("{arrow}{ty_info}"), None), - }; - Self::ClosureReturn { start_span, start_span_code, end_span } - } -} - -pub enum RegionOriginNote<'a> { - Plain { - span: Span, - msg: DiagMessage, - }, - WithName { - span: Span, - msg: DiagMessage, - name: &'a str, - continues: bool, - }, - WithRequirement { - span: Span, - requirement: ObligationCauseAsDiagArg<'a>, - expected_found: Option<(DiagStyledString, DiagStyledString)>, - }, -} - -impl Subdiagnostic for RegionOriginNote<'_> { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - let mut label_or_note = |span, msg: DiagMessage| { - let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count(); - let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count(); - let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span); - if span_is_primary && sub_count == 0 && expanded_sub_count == 0 { - diag.span_label(span, msg); - } else if span_is_primary && expanded_sub_count == 0 { - diag.note(msg); - } else { - diag.span_note(span, msg); - } - }; - match self { - RegionOriginNote::Plain { span, msg } => { - label_or_note(span, msg); - } - RegionOriginNote::WithName { span, msg, name, continues } => { - label_or_note(span, msg); - diag.arg("name", name); - diag.arg("continues", continues); - } - RegionOriginNote::WithRequirement { - span, - requirement, - expected_found: Some((expected, found)), - } => { - label_or_note(span, fluent::infer_subtype); - diag.arg("requirement", requirement); - - diag.note_expected_found(&"", expected, &"", found); - } - RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => { - // FIXME: this really should be handled at some earlier stage. Our - // handling of region checking when type errors are present is - // *terrible*. - label_or_note(span, fluent::infer_subtype_2); - diag.arg("requirement", requirement); - } - }; - } -} - -pub enum LifetimeMismatchLabels { - InRet { - param_span: Span, - ret_span: Span, - span: Span, - label_var1: Option<Ident>, - }, - Normal { - hir_equal: bool, - ty_sup: Span, - ty_sub: Span, - span: Span, - sup: Option<Ident>, - sub: Option<Ident>, - }, -} - -impl Subdiagnostic for LifetimeMismatchLabels { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - match self { - LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => { - diag.span_label(param_span, fluent::infer_declared_different); - diag.span_label(ret_span, fluent::infer_nothing); - diag.span_label(span, fluent::infer_data_returned); - diag.arg("label_var1_exists", label_var1.is_some()); - diag.arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default()); - } - LifetimeMismatchLabels::Normal { - hir_equal, - ty_sup, - ty_sub, - span, - sup: label_var1, - sub: label_var2, - } => { - if hir_equal { - diag.span_label(ty_sup, fluent::infer_declared_multiple); - diag.span_label(ty_sub, fluent::infer_nothing); - diag.span_label(span, fluent::infer_data_lifetime_flow); - } else { - diag.span_label(ty_sup, fluent::infer_types_declared_different); - diag.span_label(ty_sub, fluent::infer_nothing); - diag.span_label(span, fluent::infer_data_flows); - diag.arg("label_var1_exists", label_var1.is_some()); - diag.arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default()); - diag.arg("label_var2_exists", label_var2.is_some()); - diag.arg("label_var2", label_var2.map(|x| x.to_string()).unwrap_or_default()); - } - } - } - } -} - -pub struct AddLifetimeParamsSuggestion<'a> { - pub tcx: TyCtxt<'a>, - pub generic_param_scope: LocalDefId, - pub sub: Region<'a>, - pub ty_sup: &'a hir::Ty<'a>, - pub ty_sub: &'a hir::Ty<'a>, - pub add_note: bool, -} - -impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - let mut mk_suggestion = || { - let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub) - else { - return false; - }; - - let node = self.tcx.hir_node_by_def_id(anon_reg.def_id); - let is_impl = matches!(&node, hir::Node::ImplItem(_)); - let (generics, parent_generics) = match node { - hir::Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(_, ref generics, ..), - .. - }) - | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) - | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => ( - generics, - match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.def_id)) - { - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, ref generics, ..), - .. - }) - | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { ref generics, .. }), - .. - }) => Some(generics), - _ => None, - }, - ), - _ => return false, - }; - - let suggestion_param_name = generics - .params - .iter() - .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) - .map(|p| p.name.ident().name) - .find(|i| *i != kw::UnderscoreLifetime); - let introduce_new = suggestion_param_name.is_none(); - - let mut default = "'a".to_string(); - if let Some(parent_generics) = parent_generics { - let used: FxHashSet<_> = parent_generics - .params - .iter() - .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) - .map(|p| p.name.ident().name) - .filter(|i| *i != kw::UnderscoreLifetime) - .map(|l| l.to_string()) - .collect(); - if let Some(lt) = - ('a'..='z').map(|it| format!("'{it}")).find(|it| !used.contains(it)) - { - // We want a lifetime that *isn't* present in the `trait` or `impl` that assoc - // `fn` belongs to. We could suggest reusing one of their lifetimes, but it is - // likely to be an over-constraining lifetime requirement, so we always add a - // lifetime to the `fn`. - default = lt; - } - } - let suggestion_param_name = - suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| default); - - struct ImplicitLifetimeFinder { - suggestions: Vec<(Span, String)>, - suggestion_param_name: String, - } - - impl<'v> Visitor<'v> for ImplicitLifetimeFinder { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - let make_suggestion = |ident: Ident| { - if ident.name == kw::Empty && ident.span.is_empty() { - format!("{}, ", self.suggestion_param_name) - } else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() { - format!("{} ", self.suggestion_param_name) - } else { - self.suggestion_param_name.clone() - } - }; - match ty.kind { - hir::TyKind::Path(hir::QPath::Resolved(_, path)) => { - for segment in path.segments { - if let Some(args) = segment.args { - if args.args.iter().all(|arg| { - matches!( - arg, - hir::GenericArg::Lifetime(lifetime) - if lifetime.ident.name == kw::Empty - ) - }) { - self.suggestions.push(( - segment.ident.span.shrink_to_hi(), - format!( - "<{}>", - args.args - .iter() - .map(|_| self.suggestion_param_name.clone()) - .collect::<Vec<_>>() - .join(", ") - ), - )); - } else { - for arg in args.args { - if let hir::GenericArg::Lifetime(lifetime) = arg - && lifetime.is_anonymous() - { - self.suggestions.push(( - lifetime.ident.span, - make_suggestion(lifetime.ident), - )); - } - } - } - } - } - } - hir::TyKind::Ref(lifetime, ..) if lifetime.is_anonymous() => { - self.suggestions - .push((lifetime.ident.span, make_suggestion(lifetime.ident))); - } - _ => {} - } - walk_ty(self, ty); - } - } - let mut visitor = ImplicitLifetimeFinder { - suggestions: vec![], - suggestion_param_name: suggestion_param_name.clone(), - }; - if let Some(fn_decl) = node.fn_decl() - && let hir::FnRetTy::Return(ty) = fn_decl.output - { - visitor.visit_ty(ty); - } - if visitor.suggestions.is_empty() { - // Do not suggest constraining the `&self` param, but rather the return type. - // If that is wrong (because it is not sufficient), a follow up error will tell the - // user to fix it. This way we lower the chances of *over* constraining, but still - // get the cake of "correctly" contrained in two steps. - visitor.visit_ty(self.ty_sup); - } - visitor.visit_ty(self.ty_sub); - if visitor.suggestions.is_empty() { - return false; - } - if introduce_new { - let new_param_suggestion = if let Some(first) = - generics.params.iter().find(|p| !p.name.ident().span.is_empty()) - { - (first.span.shrink_to_lo(), format!("{suggestion_param_name}, ")) - } else { - (generics.span, format!("<{suggestion_param_name}>")) - }; - - visitor.suggestions.push(new_param_suggestion); - } - diag.multipart_suggestion_verbose( - fluent::infer_lifetime_param_suggestion, - visitor.suggestions, - Applicability::MaybeIncorrect, - ); - diag.arg("is_impl", is_impl); - diag.arg("is_reuse", !introduce_new); - - true - }; - if mk_suggestion() && self.add_note { - diag.note(fluent::infer_lifetime_param_suggestion_elided); - } - } -} - -#[derive(Diagnostic)] -#[diag(infer_lifetime_mismatch, code = E0623)] -pub struct LifetimeMismatch<'a> { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub labels: LifetimeMismatchLabels, - #[subdiagnostic] - pub suggestion: AddLifetimeParamsSuggestion<'a>, -} - -pub struct IntroducesStaticBecauseUnmetLifetimeReq { - pub unmet_requirements: MultiSpan, - pub binding_span: Span, -} - -impl Subdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - mut self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - self.unmet_requirements - .push_span_label(self.binding_span, fluent::infer_msl_introduces_static); - diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req); - } -} - -// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that -#[derive(Subdiagnostic)] -pub enum DoesNotOutliveStaticFromImpl { - #[note(infer_does_not_outlive_static_from_impl)] - Spanned { - #[primary_span] - span: Span, - }, - #[note(infer_does_not_outlive_static_from_impl)] - Unspanned, -} - -#[derive(Subdiagnostic)] -pub enum ImplicitStaticLifetimeSubdiag { - #[note(infer_implicit_static_lifetime_note)] - Note { - #[primary_span] - span: Span, - }, - #[suggestion( - infer_implicit_static_lifetime_suggestion, - style = "verbose", - code = " + '_", - applicability = "maybe-incorrect" - )] - Sugg { - #[primary_span] - span: Span, - }, -} - -#[derive(Diagnostic)] -#[diag(infer_mismatched_static_lifetime)] -pub struct MismatchedStaticLifetime<'a> { - #[primary_span] - pub cause_span: Span, - #[subdiagnostic] - pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq, - #[subdiagnostic] - pub expl: Option<note_and_explain::RegionExplanation<'a>>, - #[subdiagnostic] - pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl, - #[subdiagnostic] - pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>, -} - -#[derive(Diagnostic)] -pub enum ExplicitLifetimeRequired<'a> { - #[diag(infer_explicit_lifetime_required_with_ident, code = E0621)] - WithIdent { - #[primary_span] - #[label] - span: Span, - simple_ident: Ident, - named: String, - #[suggestion( - infer_explicit_lifetime_required_sugg_with_ident, - code = "{new_ty}", - applicability = "unspecified" - )] - new_ty_span: Span, - #[skip_arg] - new_ty: Ty<'a>, - }, - #[diag(infer_explicit_lifetime_required_with_param_type, code = E0621)] - WithParamType { - #[primary_span] - #[label] - span: Span, - named: String, - #[suggestion( - infer_explicit_lifetime_required_sugg_with_param_type, - code = "{new_ty}", - applicability = "unspecified" - )] - new_ty_span: Span, - #[skip_arg] - new_ty: Ty<'a>, - }, -} - -pub enum TyOrSig<'tcx> { - Ty(Highlighted<'tcx, Ty<'tcx>>), - ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>), -} - -impl IntoDiagArg for TyOrSig<'_> { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { - match self { - TyOrSig::Ty(ty) => ty.into_diag_arg(), - TyOrSig::ClosureSig(sig) => sig.into_diag_arg(), - } - } -} - -#[derive(Subdiagnostic)] -pub enum ActualImplExplNotes<'tcx> { - #[note(infer_actual_impl_expl_expected_signature_two)] - ExpectedSignatureTwo { - leading_ellipsis: bool, - 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: 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: 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: TyOrSig<'tcx>, - trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - }, - #[note(infer_actual_impl_expl_expected_passive_two)] - ExpectedPassiveTwo { - leading_ellipsis: bool, - 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: 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: 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: TyOrSig<'tcx>, - trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - }, - #[note(infer_actual_impl_expl_expected_other_two)] - ExpectedOtherTwo { - leading_ellipsis: bool, - 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: 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: 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: TyOrSig<'tcx>, - trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - }, - #[note(infer_actual_impl_expl_but_actually_implements_trait)] - 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: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - has_lifetime: bool, - lifetime: usize, - ty: String, - }, - #[note(infer_actual_impl_expl_but_actually_ty_implements)] - ButActuallyTyImplements { - trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - has_lifetime: bool, - lifetime: usize, - ty: String, - }, -} - -pub enum ActualImplExpectedKind { - Signature, - Passive, - Other, -} - -pub enum ActualImplExpectedLifetimeKind { - Two, - Any, - Some, - Nothing, -} - -impl<'tcx> ActualImplExplNotes<'tcx> { - pub fn new_expected( - kind: ActualImplExpectedKind, - lt_kind: ActualImplExpectedLifetimeKind, - leading_ellipsis: bool, - ty_or_sig: TyOrSig<'tcx>, - trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - lifetime_1: usize, - lifetime_2: usize, - ) -> Self { - match (kind, lt_kind) { - (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => { - Self::ExpectedSignatureTwo { - leading_ellipsis, - ty_or_sig, - trait_path, - lifetime_1, - lifetime_2, - } - } - (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => { - Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => { - Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => { - Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path } - } - (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => { - Self::ExpectedPassiveTwo { - leading_ellipsis, - ty_or_sig, - trait_path, - lifetime_1, - lifetime_2, - } - } - (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => { - Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => { - Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => { - Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path } - } - (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => { - Self::ExpectedOtherTwo { - leading_ellipsis, - ty_or_sig, - trait_path, - lifetime_1, - lifetime_2, - } - } - (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => { - Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => { - Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } - } - (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => { - Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path } - } - } - } -} - -#[derive(Diagnostic)] -#[diag(infer_trait_placeholder_mismatch)] -pub struct TraitPlaceholderMismatch<'tcx> { - #[primary_span] - pub span: Span, - #[label(infer_label_satisfy)] - pub satisfy_span: Option<Span>, - #[label(infer_label_where)] - pub where_span: Option<Span>, - #[label(infer_label_dup)] - pub dup_span: Option<Span>, - pub def_id: String, - pub trait_def_id: String, - - #[subdiagnostic] - pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>, -} - -pub struct ConsiderBorrowingParamHelp { - pub spans: Vec<Span>, -} - -impl Subdiagnostic for ConsiderBorrowingParamHelp { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - f: &F, - ) { - let mut type_param_span: MultiSpan = self.spans.clone().into(); - for &span in &self.spans { - // Seems like we can't call f() here as Into<DiagMessage> is required - type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing); - } - let msg = f(diag, fluent::infer_tid_param_help.into()); - diag.span_help(type_param_span, msg); - } -} - -#[derive(Subdiagnostic)] -#[help(infer_tid_rel_help)] -pub struct RelationshipHelp; - -#[derive(Diagnostic)] -#[diag(infer_trait_impl_diff)] -pub struct TraitImplDiff { - #[primary_span] - #[label(infer_found)] - pub sp: Span, - #[label(infer_expected)] - pub trait_sp: Span, - #[note(infer_expected_found)] - pub note: (), - #[subdiagnostic] - pub param_help: ConsiderBorrowingParamHelp, - #[subdiagnostic] - // Seems like subdiagnostics are always pushed to the end, so this one - // also has to be a subdiagnostic to maintain order. - pub rel_help: Option<RelationshipHelp>, - pub expected: String, - pub found: String, -} - -pub struct DynTraitConstraintSuggestion { - pub span: Span, - pub ident: Ident, -} - -impl Subdiagnostic for DynTraitConstraintSuggestion { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - f: &F, - ) { - let mut multi_span: MultiSpan = vec![self.span].into(); - multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label); - multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement); - let msg = f(diag, fluent::infer_dtcs_has_req_note.into()); - diag.span_note(multi_span, msg); - let msg = f(diag, fluent::infer_dtcs_suggestion.into()); - diag.span_suggestion_verbose( - self.span.shrink_to_hi(), - msg, - " + '_", - Applicability::MaybeIncorrect, - ); - } -} - -#[derive(Diagnostic)] -#[diag(infer_but_calling_introduces, code = E0772)] -pub struct ButCallingIntroduces { - #[label(infer_label1)] - pub param_ty_span: Span, - #[primary_span] - #[label(infer_label2)] - pub cause_span: Span, - - pub has_param_name: bool, - pub param_name: String, - pub has_lifetime: bool, - pub lifetime: String, - pub assoc_item: Symbol, - pub has_impl_path: bool, - pub impl_path: String, -} - -pub struct ReqIntroducedLocations { - pub span: MultiSpan, - pub spans: Vec<Span>, - pub fn_decl_span: Span, - pub cause_span: Span, - pub add_label: bool, -} - -impl Subdiagnostic for ReqIntroducedLocations { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - mut self, - diag: &mut Diag<'_, G>, - f: &F, - ) { - for sp in self.spans { - self.span.push_span_label(sp, fluent::infer_ril_introduced_here); - } - - if self.add_label { - self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by); - } - self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of); - let msg = f(diag, fluent::infer_ril_static_introduced_by.into()); - diag.span_note(self.span, msg); - } -} - -pub struct MoreTargeted { - pub ident: Symbol, -} - -impl Subdiagnostic for MoreTargeted { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - diag.code(E0772); - diag.primary_message(fluent::infer_more_targeted); - diag.arg("ident", self.ident); - } -} - -#[derive(Diagnostic)] -#[diag(infer_but_needs_to_satisfy, code = E0759)] -pub struct ButNeedsToSatisfy { - #[primary_span] - pub sp: Span, - #[label(infer_influencer)] - pub influencer_point: Span, - #[label(infer_used_here)] - pub spans: Vec<Span>, - #[label(infer_require)] - pub require_span_as_label: Option<Span>, - #[note(infer_require)] - pub require_span_as_note: Option<Span>, - #[note(infer_introduced_by_bound)] - pub bound: Option<Span>, - - #[subdiagnostic] - pub req_introduces_loc: Option<ReqIntroducedLocations>, - - pub has_param_name: bool, - pub param_name: String, - pub spans_empty: bool, - pub has_lifetime: bool, - pub lifetime: String, -} - -#[derive(Diagnostic)] -#[diag(infer_outlives_content, code = E0312)] -pub struct OutlivesContent<'a> { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub notes: Vec<note_and_explain::RegionExplanation<'a>>, -} - -#[derive(Diagnostic)] -#[diag(infer_outlives_bound, code = E0476)] -pub struct OutlivesBound<'a> { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub notes: Vec<note_and_explain::RegionExplanation<'a>>, -} - -#[derive(Diagnostic)] -#[diag(infer_fulfill_req_lifetime, code = E0477)] -pub struct FulfillReqLifetime<'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'a>, - #[subdiagnostic] - pub note: Option<note_and_explain::RegionExplanation<'a>>, -} - -#[derive(Diagnostic)] -#[diag(infer_lf_bound_not_satisfied, code = E0478)] -pub struct LfBoundNotSatisfied<'a> { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub notes: Vec<note_and_explain::RegionExplanation<'a>>, -} - -#[derive(Diagnostic)] -#[diag(infer_ref_longer_than_data, code = E0491)] -pub struct RefLongerThanData<'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'a>, - #[subdiagnostic] - pub notes: Vec<note_and_explain::RegionExplanation<'a>>, -} - -#[derive(Subdiagnostic)] -pub enum WhereClauseSuggestions { - #[suggestion( - infer_where_remove, - code = "", - applicability = "machine-applicable", - style = "verbose" - )] - Remove { - #[primary_span] - span: Span, - }, - #[suggestion( - infer_where_copy_predicates, - code = "{space}where {trait_predicates}", - applicability = "machine-applicable", - style = "verbose" - )] - CopyPredicates { - #[primary_span] - span: Span, - space: &'static str, - trait_predicates: String, - }, -} - -#[derive(Subdiagnostic)] -pub enum SuggestRemoveSemiOrReturnBinding { - #[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")] - RemoveAndBox { - #[suggestion_part(code = "Box::new(")] - first_lo: Span, - #[suggestion_part(code = ")")] - first_hi: Span, - #[suggestion_part(code = "Box::new(")] - second_lo: Span, - #[suggestion_part(code = ")")] - second_hi: Span, - #[suggestion_part(code = "")] - sp: Span, - }, - #[suggestion( - infer_srs_remove, - style = "short", - code = "", - applicability = "machine-applicable" - )] - Remove { - #[primary_span] - sp: Span, - }, - #[suggestion( - infer_srs_add, - style = "verbose", - code = "{code}", - applicability = "maybe-incorrect" - )] - Add { - #[primary_span] - sp: Span, - code: String, - ident: Ident, - }, - #[note(infer_srs_add_one)] - AddOne { - #[primary_span] - spans: MultiSpan, - }, -} - -#[derive(Subdiagnostic)] -pub enum ConsiderAddingAwait { - #[help(infer_await_both_futures)] - BothFuturesHelp, - #[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")] - BothFuturesSugg { - #[suggestion_part(code = ".await")] - first: Span, - #[suggestion_part(code = ".await")] - second: Span, - }, - #[suggestion( - infer_await_future, - code = ".await", - style = "verbose", - applicability = "maybe-incorrect" - )] - FutureSugg { - #[primary_span] - span: Span, - }, - #[note(infer_await_note)] - FutureSuggNote { - #[primary_span] - span: Span, - }, - #[multipart_suggestion( - infer_await_future, - style = "verbose", - applicability = "maybe-incorrect" - )] - FutureSuggMultiple { - #[suggestion_part(code = ".await")] - spans: Vec<Span>, - }, -} - -#[derive(Diagnostic)] -pub enum PlaceholderRelationLfNotSatisfied { - #[diag(infer_lf_bound_not_satisfied)] - HasBoth { - #[primary_span] - span: Span, - #[note(infer_prlf_defined_with_sub)] - sub_span: Span, - #[note(infer_prlf_must_outlive_with_sup)] - sup_span: Span, - sub_symbol: Symbol, - sup_symbol: Symbol, - #[note(infer_prlf_known_limitation)] - note: (), - }, - #[diag(infer_lf_bound_not_satisfied)] - HasSub { - #[primary_span] - span: Span, - #[note(infer_prlf_defined_with_sub)] - sub_span: Span, - #[note(infer_prlf_must_outlive_without_sup)] - sup_span: Span, - sub_symbol: Symbol, - #[note(infer_prlf_known_limitation)] - note: (), - }, - #[diag(infer_lf_bound_not_satisfied)] - HasSup { - #[primary_span] - span: Span, - #[note(infer_prlf_defined_without_sub)] - sub_span: Span, - #[note(infer_prlf_must_outlive_with_sup)] - sup_span: Span, - sup_symbol: Symbol, - #[note(infer_prlf_known_limitation)] - note: (), - }, - #[diag(infer_lf_bound_not_satisfied)] - HasNone { - #[primary_span] - span: Span, - #[note(infer_prlf_defined_without_sub)] - sub_span: Span, - #[note(infer_prlf_must_outlive_without_sup)] - sup_span: Span, - #[note(infer_prlf_known_limitation)] - note: (), - }, - #[diag(infer_lf_bound_not_satisfied)] - OnlyPrimarySpan { - #[primary_span] - span: Span, - #[note(infer_prlf_known_limitation)] - note: (), - }, -} - -#[derive(Diagnostic)] -#[diag(infer_opaque_captures_lifetime, code = E0700)] -pub struct OpaqueCapturesLifetime<'tcx> { - #[primary_span] - pub span: Span, - #[label] - pub opaque_ty_span: Span, - pub opaque_ty: Ty<'tcx>, -} - -#[derive(Subdiagnostic)] -pub enum FunctionPointerSuggestion<'a> { - #[suggestion( - infer_fps_use_ref, - code = "&{fn_name}", - style = "verbose", - applicability = "maybe-incorrect" - )] - UseRef { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - }, - #[suggestion( - infer_fps_remove_ref, - code = "{fn_name}", - style = "verbose", - applicability = "maybe-incorrect" - )] - RemoveRef { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - }, - #[suggestion( - infer_fps_cast, - code = "&({fn_name} as {sig})", - style = "verbose", - applicability = "maybe-incorrect" - )] - CastRef { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - #[skip_arg] - sig: Binder<'a, FnSig<'a>>, - }, - #[suggestion( - infer_fps_cast, - code = "{fn_name} as {sig}", - style = "verbose", - applicability = "maybe-incorrect" - )] - Cast { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - #[skip_arg] - sig: Binder<'a, FnSig<'a>>, - }, - #[suggestion( - infer_fps_cast_both, - code = "{fn_name} as {found_sig}", - style = "hidden", - applicability = "maybe-incorrect" - )] - CastBoth { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - #[skip_arg] - found_sig: Binder<'a, FnSig<'a>>, - expected_sig: Binder<'a, FnSig<'a>>, - }, - #[suggestion( - infer_fps_cast_both, - code = "&({fn_name} as {found_sig})", - style = "hidden", - applicability = "maybe-incorrect" - )] - CastBothRef { - #[primary_span] - span: Span, - #[skip_arg] - fn_name: String, - #[skip_arg] - found_sig: Binder<'a, FnSig<'a>>, - expected_sig: Binder<'a, FnSig<'a>>, - }, -} - -#[derive(Subdiagnostic)] -#[note(infer_fps_items_are_distinct)] -pub struct FnItemsAreDistinct; - -#[derive(Subdiagnostic)] -#[note(infer_fn_uniq_types)] -pub struct FnUniqTypes; - -#[derive(Subdiagnostic)] -#[help(infer_fn_consider_casting)] -pub struct FnConsiderCasting { - pub casting: String, -} - -#[derive(Subdiagnostic)] -pub enum SuggestAccessingField<'a> { - #[suggestion( - infer_suggest_accessing_field, - code = "{snippet}.{name}", - applicability = "maybe-incorrect" - )] - Safe { - #[primary_span] - span: Span, - snippet: String, - name: Symbol, - ty: Ty<'a>, - }, - #[suggestion( - infer_suggest_accessing_field, - code = "unsafe {{ {snippet}.{name} }}", - applicability = "maybe-incorrect" - )] - Unsafe { - #[primary_span] - span: Span, - snippet: String, - name: Symbol, - ty: Ty<'a>, - }, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")] -pub struct SuggestTuplePatternOne { - pub variant: String, - #[suggestion_part(code = "{variant}(")] - pub span_low: Span, - #[suggestion_part(code = ")")] - pub span_high: Span, -} - -pub struct SuggestTuplePatternMany { - pub path: String, - pub cause_span: Span, - pub compatible_variants: Vec<String>, -} - -impl Subdiagnostic for SuggestTuplePatternMany { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - f: &F, - ) { - diag.arg("path", self.path); - let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into()); - diag.multipart_suggestions( - message, - self.compatible_variants.into_iter().map(|variant| { - vec![ - (self.cause_span.shrink_to_lo(), format!("{variant}(")), - (self.cause_span.shrink_to_hi(), ")".to_string()), - ] - }), - rustc_errors::Applicability::MaybeIncorrect, - ); - } -} - -#[derive(Subdiagnostic)] -pub enum TypeErrorAdditionalDiags { - #[suggestion( - infer_meant_byte_literal, - code = "b'{code}'", - applicability = "machine-applicable" - )] - MeantByteLiteral { - #[primary_span] - span: Span, - code: String, - }, - #[suggestion( - infer_meant_char_literal, - code = "'{code}'", - applicability = "machine-applicable" - )] - MeantCharLiteral { - #[primary_span] - span: Span, - code: String, - }, - #[multipart_suggestion(infer_meant_str_literal, applicability = "machine-applicable")] - MeantStrLiteral { - #[suggestion_part(code = "\"")] - start: Span, - #[suggestion_part(code = "\"")] - end: Span, - }, - #[suggestion( - infer_consider_specifying_length, - code = "{length}", - applicability = "maybe-incorrect" - )] - ConsiderSpecifyingLength { - #[primary_span] - span: Span, - length: u64, - }, - #[note(infer_try_cannot_convert)] - TryCannotConvert { found: String, expected: String }, - #[suggestion(infer_tuple_trailing_comma, code = ",", applicability = "machine-applicable")] - TupleOnlyComma { - #[primary_span] - span: Span, - }, - #[multipart_suggestion(infer_tuple_trailing_comma, applicability = "machine-applicable")] - TupleAlsoParentheses { - #[suggestion_part(code = "(")] - span_low: Span, - #[suggestion_part(code = ",)")] - span_high: Span, - }, - #[suggestion( - infer_suggest_add_let_for_letchains, - style = "verbose", - applicability = "machine-applicable", - code = "let " - )] - AddLetForLetChains { - #[primary_span] - span: Span, - }, -} - -#[derive(Diagnostic)] -pub enum ObligationCauseFailureCode { - #[diag(infer_oc_method_compat, code = E0308)] - MethodCompat { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_type_compat, code = E0308)] - TypeCompat { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_const_compat, code = E0308)] - ConstCompat { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_try_compat, code = E0308)] - TryCompat { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_match_compat, code = E0308)] - MatchCompat { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_if_else_different, code = E0308)] - IfElseDifferent { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_no_else, code = E0317)] - NoElse { - #[primary_span] - span: Span, - }, - #[diag(infer_oc_no_diverge, code = E0308)] - NoDiverge { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_fn_main_correct_type, code = E0580)] - FnMainCorrectType { - #[primary_span] - span: Span, - }, - #[diag(infer_oc_fn_start_correct_type, code = E0308)] - FnStartCorrectType { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_fn_lang_correct_type, code = E0308)] - FnLangCorrectType { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - lang_item_name: Symbol, - }, - #[diag(infer_oc_intrinsic_correct_type, code = E0308)] - IntrinsicCorrectType { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_method_correct_type, code = E0308)] - MethodCorrectType { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_closure_selfref, code = E0644)] - ClosureSelfref { - #[primary_span] - span: Span, - }, - #[diag(infer_oc_cant_coerce, code = E0308)] - CantCoerce { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, - #[diag(infer_oc_generic, code = E0308)] - Generic { - #[primary_span] - span: Span, - #[subdiagnostic] - subdiags: Vec<TypeErrorAdditionalDiags>, - }, -} - -#[derive(Subdiagnostic)] -pub enum AddPreciseCapturing { - #[suggestion( - infer_precise_capturing_new, - style = "verbose", - code = " + use<{concatenated_bounds}>", - applicability = "machine-applicable" - )] - New { - #[primary_span] - span: Span, - new_lifetime: Symbol, - concatenated_bounds: String, - }, - #[suggestion( - infer_precise_capturing_existing, - style = "verbose", - code = "{pre}{new_lifetime}{post}", - applicability = "machine-applicable" - )] - Existing { - #[primary_span] - span: Span, - new_lifetime: Symbol, - pre: &'static str, - post: &'static str, - }, -} - -pub struct AddPreciseCapturingAndParams { - pub suggs: Vec<(Span, String)>, - pub new_lifetime: Symbol, - pub apit_spans: Vec<Span>, -} - -impl Subdiagnostic for AddPreciseCapturingAndParams { - fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - diag.arg("new_lifetime", self.new_lifetime); - diag.multipart_suggestion_verbose( - fluent::infer_precise_capturing_new_but_apit, - self.suggs, - Applicability::MaybeIncorrect, - ); - diag.span_note(self.apit_spans, fluent::infer_warn_removing_apit_params); - } -} |
