1 use hir::GenericParamKind;
3 fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
4 IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
7 use rustc_hir::FnRetTy;
8 use rustc_macros::{Diagnostic, Subdiagnostic};
9 use rustc_middle::ty::print::TraitRefPrintOnlyTraitPath;
10 use rustc_middle::ty::{Binder, FnSig, Region, Ty, TyCtxt};
11 use rustc_span::symbol::kw;
12 use rustc_span::Symbol;
13 use rustc_span::{symbol::Ident, BytePos, Span};
15 use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted;
16 use crate::infer::error_reporting::{
17 need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
18 ObligationCauseAsDiagArg,
21 pub mod note_and_explain;
24 #[diag(infer_opaque_hidden_type)]
25 pub struct OpaqueHiddenTypeDiag {
30 pub opaque_type: Span,
32 pub hidden_type: Span,
36 #[diag(infer_type_annotations_needed, code = "E0282")]
37 pub struct AnnotationRequired<'a> {
40 pub source_kind: &'static str,
41 pub source_name: &'a str,
43 pub failure_span: Option<Span>,
45 pub bad_label: Option<InferenceBadError<'a>>,
47 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
49 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
52 // Copy of `AnnotationRequired` for E0283
54 #[diag(infer_type_annotations_needed, code = "E0283")]
55 pub struct AmbigousImpl<'a> {
58 pub source_kind: &'static str,
59 pub source_name: &'a str,
61 pub failure_span: Option<Span>,
63 pub bad_label: Option<InferenceBadError<'a>>,
65 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
67 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
70 // Copy of `AnnotationRequired` for E0284
72 #[diag(infer_type_annotations_needed, code = "E0284")]
73 pub struct AmbigousReturn<'a> {
76 pub source_kind: &'static str,
77 pub source_name: &'a str,
79 pub failure_span: Option<Span>,
81 pub bad_label: Option<InferenceBadError<'a>>,
83 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
85 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
89 #[diag(infer_need_type_info_in_generator, code = "E0698")]
90 pub struct NeedTypeInfoInGenerator<'a> {
93 pub generator_kind: GeneratorKindAsDiagArg,
95 pub bad_label: InferenceBadError<'a>,
98 // Used when a better one isn't available
99 #[derive(Subdiagnostic)]
100 #[label(infer_label_bad)]
101 pub struct InferenceBadError<'a> {
104 pub bad_kind: &'static str,
105 pub prefix_kind: UnderspecifiedArgKind,
106 pub has_parent: bool,
108 pub parent_prefix: &'a str,
109 pub parent_name: String,
113 #[derive(Subdiagnostic)]
114 pub enum SourceKindSubdiag<'a> {
116 infer_source_kind_subdiag_let,
118 code = ": {type_name}",
119 applicability = "has-placeholders"
127 x_kind: &'static str,
128 prefix_kind: UnderspecifiedArgKind,
132 #[label(infer_source_kind_subdiag_generic_label)]
139 parent_prefix: String,
143 infer_source_kind_subdiag_generic_suggestion,
146 applicability = "has-placeholders"
156 #[derive(Subdiagnostic)]
157 pub enum SourceKindMultiSuggestion<'a> {
158 #[multipart_suggestion(
159 infer_source_kind_fully_qualified,
161 applicability = "has-placeholders"
164 #[suggestion_part(code = "{def_path}({adjustment}")]
166 #[suggestion_part(code = "{successor_pos}")]
170 successor_pos: &'a str,
172 #[multipart_suggestion(
173 infer_source_kind_closure_return,
175 applicability = "has-placeholders"
178 #[suggestion_part(code = "{start_span_code}")]
180 start_span_code: String,
181 #[suggestion_part(code = " }}")]
182 end_span: Option<Span>,
186 #[derive(Subdiagnostic)]
188 infer_suggest_add_let_for_letchains,
190 applicability = "machine-applicable",
193 pub(crate) struct SuggAddLetForLetChains {
198 impl<'a> SourceKindMultiSuggestion<'a> {
199 pub fn new_fully_qualified(
203 successor: (&'a str, BytePos),
205 Self::FullyQualified {
206 span_lo: span.shrink_to_lo(),
207 span_hi: span.shrink_to_hi().with_hi(successor.1),
210 successor_pos: successor.0,
214 pub fn new_closure_return(
216 data: &'a FnRetTy<'a>,
217 should_wrap_expr: Option<Span>,
219 let (arrow, post) = match data {
220 FnRetTy::DefaultReturn(_) => ("-> ", " "),
223 let (start_span, start_span_code, end_span) = match should_wrap_expr {
225 (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span))
227 None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None),
229 Self::ClosureReturn { start_span, start_span_code, end_span }
233 pub enum RegionOriginNote<'a> {
236 msg: DiagnosticMessage,
240 msg: DiagnosticMessage,
246 requirement: ObligationCauseAsDiagArg<'a>,
247 expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>,
251 impl AddToDiagnostic for RegionOriginNote<'_> {
252 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
254 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
256 let mut label_or_note = |span, msg: DiagnosticMessage| {
257 let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
258 let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
259 let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
260 if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
261 diag.span_label(span, msg);
262 } else if span_is_primary && expanded_sub_count == 0 {
265 diag.span_note(span, msg);
269 RegionOriginNote::Plain { span, msg } => {
270 label_or_note(span, msg);
272 RegionOriginNote::WithName { span, msg, name, continues } => {
273 label_or_note(span, msg);
274 diag.set_arg("name", name);
275 diag.set_arg("continues", continues);
277 RegionOriginNote::WithRequirement {
280 expected_found: Some((expected, found)),
282 label_or_note(span, fluent::infer_subtype);
283 diag.set_arg("requirement", requirement);
285 diag.note_expected_found(&"", expected, &"", found);
287 RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
288 // FIXME: this really should be handled at some earlier stage. Our
289 // handling of region checking when type errors are present is
291 label_or_note(span, fluent::infer_subtype_2);
292 diag.set_arg("requirement", requirement);
298 pub enum LifetimeMismatchLabels {
303 label_var1: Option<Ident>,
315 impl AddToDiagnostic for LifetimeMismatchLabels {
316 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
318 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
321 LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
322 diag.span_label(param_span, fluent::infer_declared_different);
323 diag.span_label(ret_span, fluent::infer_nothing);
324 diag.span_label(span, fluent::infer_data_returned);
325 diag.set_arg("label_var1_exists", label_var1.is_some());
326 diag.set_arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default());
328 LifetimeMismatchLabels::Normal {
337 diag.span_label(ty_sup, fluent::infer_declared_multiple);
338 diag.span_label(ty_sub, fluent::infer_nothing);
339 diag.span_label(span, fluent::infer_data_lifetime_flow);
341 diag.span_label(ty_sup, fluent::infer_types_declared_different);
342 diag.span_label(ty_sub, fluent::infer_nothing);
343 diag.span_label(span, fluent::infer_data_flows);
344 diag.set_arg("label_var1_exists", label_var1.is_some());
347 label_var1.map(|x| x.to_string()).unwrap_or_default(),
349 diag.set_arg("label_var2_exists", label_var2.is_some());
352 label_var2.map(|x| x.to_string()).unwrap_or_default(),
360 pub struct AddLifetimeParamsSuggestion<'a> {
363 pub ty_sup: &'a hir::Ty<'a>,
364 pub ty_sub: &'a hir::Ty<'a>,
368 impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
369 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
371 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
373 let mut mk_suggestion = || {
375 hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. },
376 hir::Ty { kind: hir::TyKind::Ref(lifetime_sup, _), .. },
377 ) = (self.ty_sub, self.ty_sup) else {
381 if !lifetime_sub.is_anonymous() || !lifetime_sup.is_anonymous() {
385 let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else {
389 let hir_id = self.tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
391 let node = self.tcx.hir().get(hir_id);
392 let is_impl = matches!(&node, hir::Node::ImplItem(_));
393 let generics = match node {
394 hir::Node::Item(&hir::Item {
395 kind: hir::ItemKind::Fn(_, ref generics, ..),
398 | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
399 | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
403 let suggestion_param_name = generics
406 .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
407 .map(|p| p.name.ident().name)
408 .find(|i| *i != kw::UnderscoreLifetime);
409 let introduce_new = suggestion_param_name.is_none();
410 let suggestion_param_name =
411 suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
413 debug!(?lifetime_sup.ident.span);
414 debug!(?lifetime_sub.ident.span);
415 let make_suggestion = |ident: Ident| {
416 let sugg = if ident.name == kw::Empty {
417 format!("{}, ", suggestion_param_name)
418 } else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() {
419 format!("{} ", suggestion_param_name)
421 suggestion_param_name.clone()
425 let mut suggestions =
426 vec![make_suggestion(lifetime_sub.ident), make_suggestion(lifetime_sup.ident)];
429 let new_param_suggestion = if let Some(first) =
430 generics.params.iter().find(|p| !p.name.ident().span.is_empty())
432 (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
434 (generics.span, format!("<{}>", suggestion_param_name))
437 suggestions.push(new_param_suggestion);
440 diag.multipart_suggestion(
441 fluent::infer_lifetime_param_suggestion,
443 Applicability::MaybeIncorrect,
445 diag.set_arg("is_impl", is_impl);
448 if mk_suggestion() && self.add_note {
449 diag.note(fluent::infer_lifetime_param_suggestion_elided);
454 #[derive(Diagnostic)]
455 #[diag(infer_lifetime_mismatch, code = "E0623")]
456 pub struct LifetimeMismatch<'a> {
460 pub labels: LifetimeMismatchLabels,
462 pub suggestion: AddLifetimeParamsSuggestion<'a>,
465 pub struct IntroducesStaticBecauseUnmetLifetimeReq {
466 pub unmet_requirements: MultiSpan,
467 pub binding_span: Span,
470 impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
471 fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F)
473 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
475 self.unmet_requirements
476 .push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
477 diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
481 // FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
482 #[derive(Subdiagnostic)]
483 pub enum DoesNotOutliveStaticFromImpl {
484 #[note(infer_does_not_outlive_static_from_impl)]
489 #[note(infer_does_not_outlive_static_from_impl)]
493 #[derive(Subdiagnostic)]
494 pub enum ImplicitStaticLifetimeSubdiag {
495 #[note(infer_implicit_static_lifetime_note)]
501 infer_implicit_static_lifetime_suggestion,
504 applicability = "maybe-incorrect"
512 #[derive(Diagnostic)]
513 #[diag(infer_mismatched_static_lifetime)]
514 pub struct MismatchedStaticLifetime<'a> {
516 pub cause_span: Span,
518 pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq,
520 pub expl: Option<note_and_explain::RegionExplanation<'a>>,
522 pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
524 pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
527 #[derive(Diagnostic)]
528 pub enum ExplicitLifetimeRequired<'a> {
529 #[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")]
537 infer_explicit_lifetime_required_sugg_with_ident,
539 applicability = "unspecified"
545 #[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")]
552 infer_explicit_lifetime_required_sugg_with_param_type,
554 applicability = "unspecified"
562 pub enum TyOrSig<'tcx> {
563 Ty(Highlighted<'tcx, Ty<'tcx>>),
564 ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>),
567 impl IntoDiagnosticArg for TyOrSig<'_> {
568 fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
570 TyOrSig::Ty(ty) => ty.into_diagnostic_arg(),
571 TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(),
576 #[derive(Subdiagnostic)]
577 pub enum ActualImplExplNotes<'tcx> {
578 #[note(infer_actual_impl_expl_expected_signature_two)]
579 ExpectedSignatureTwo {
580 leading_ellipsis: bool,
581 ty_or_sig: TyOrSig<'tcx>,
582 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
586 #[note(infer_actual_impl_expl_expected_signature_any)]
587 ExpectedSignatureAny {
588 leading_ellipsis: bool,
589 ty_or_sig: TyOrSig<'tcx>,
590 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
593 #[note(infer_actual_impl_expl_expected_signature_some)]
594 ExpectedSignatureSome {
595 leading_ellipsis: bool,
596 ty_or_sig: TyOrSig<'tcx>,
597 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
600 #[note(infer_actual_impl_expl_expected_signature_nothing)]
601 ExpectedSignatureNothing {
602 leading_ellipsis: bool,
603 ty_or_sig: TyOrSig<'tcx>,
604 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
606 #[note(infer_actual_impl_expl_expected_passive_two)]
608 leading_ellipsis: bool,
609 ty_or_sig: TyOrSig<'tcx>,
610 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
614 #[note(infer_actual_impl_expl_expected_passive_any)]
616 leading_ellipsis: bool,
617 ty_or_sig: TyOrSig<'tcx>,
618 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
621 #[note(infer_actual_impl_expl_expected_passive_some)]
622 ExpectedPassiveSome {
623 leading_ellipsis: bool,
624 ty_or_sig: TyOrSig<'tcx>,
625 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
628 #[note(infer_actual_impl_expl_expected_passive_nothing)]
629 ExpectedPassiveNothing {
630 leading_ellipsis: bool,
631 ty_or_sig: TyOrSig<'tcx>,
632 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
634 #[note(infer_actual_impl_expl_expected_other_two)]
636 leading_ellipsis: bool,
637 ty_or_sig: TyOrSig<'tcx>,
638 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
642 #[note(infer_actual_impl_expl_expected_other_any)]
644 leading_ellipsis: bool,
645 ty_or_sig: TyOrSig<'tcx>,
646 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
649 #[note(infer_actual_impl_expl_expected_other_some)]
651 leading_ellipsis: bool,
652 ty_or_sig: TyOrSig<'tcx>,
653 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
656 #[note(infer_actual_impl_expl_expected_other_nothing)]
657 ExpectedOtherNothing {
658 leading_ellipsis: bool,
659 ty_or_sig: TyOrSig<'tcx>,
660 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
662 #[note(infer_actual_impl_expl_but_actually_implements_trait)]
663 ButActuallyImplementsTrait {
664 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
668 #[note(infer_actual_impl_expl_but_actually_implemented_for_ty)]
669 ButActuallyImplementedForTy {
670 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
675 #[note(infer_actual_impl_expl_but_actually_ty_implements)]
676 ButActuallyTyImplements {
677 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
684 pub enum ActualImplExpectedKind {
690 pub enum ActualImplExpectedLifetimeKind {
697 impl<'tcx> ActualImplExplNotes<'tcx> {
699 kind: ActualImplExpectedKind,
700 lt_kind: ActualImplExpectedLifetimeKind,
701 leading_ellipsis: bool,
702 ty_or_sig: TyOrSig<'tcx>,
703 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
707 match (kind, lt_kind) {
708 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => {
709 Self::ExpectedSignatureTwo {
717 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => {
718 Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
720 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => {
721 Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
723 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => {
724 Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path }
726 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => {
727 Self::ExpectedPassiveTwo {
735 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => {
736 Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
738 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => {
739 Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
741 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => {
742 Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path }
744 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => {
745 Self::ExpectedOtherTwo {
753 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => {
754 Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
756 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => {
757 Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
759 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => {
760 Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path }
766 #[derive(Diagnostic)]
767 #[diag(infer_trait_placeholder_mismatch)]
768 pub struct TraitPlaceholderMismatch<'tcx> {
771 #[label(label_satisfy)]
772 pub satisfy_span: Option<Span>,
773 #[label(label_where)]
774 pub where_span: Option<Span>,
776 pub dup_span: Option<Span>,
778 pub trait_def_id: String,
781 pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>,
784 pub struct ConsiderBorrowingParamHelp {
785 pub spans: Vec<Span>,
788 impl AddToDiagnostic for ConsiderBorrowingParamHelp {
789 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
791 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
793 let mut type_param_span: MultiSpan = self.spans.clone().into();
794 for &span in &self.spans {
795 // Seems like we can't call f() here as Into<DiagnosticMessage> is required
796 type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing);
798 let msg = f(diag, fluent::infer_tid_param_help.into());
799 diag.span_help(type_param_span, msg);
803 #[derive(Subdiagnostic)]
804 #[help(infer_tid_rel_help)]
805 pub struct RelationshipHelp;
807 #[derive(Diagnostic)]
808 #[diag(infer_trait_impl_diff)]
809 pub struct TraitImplDiff {
815 #[note(expected_found)]
818 pub param_help: ConsiderBorrowingParamHelp,
820 // Seems like subdiagnostics are always pushed to the end, so this one
821 // also has to be a subdiagnostic to maintain order.
822 pub rel_help: Option<RelationshipHelp>,
823 pub expected: String,
827 pub struct DynTraitConstraintSuggestion {
832 impl AddToDiagnostic for DynTraitConstraintSuggestion {
833 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
835 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
837 let mut multi_span: MultiSpan = vec![self.span].into();
838 multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
839 multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement);
840 let msg = f(diag, fluent::infer_dtcs_has_req_note.into());
841 diag.span_note(multi_span, msg);
842 let msg = f(diag, fluent::infer_dtcs_suggestion.into());
843 diag.span_suggestion_verbose(
844 self.span.shrink_to_hi(),
847 Applicability::MaybeIncorrect,
852 #[derive(Diagnostic)]
853 #[diag(infer_but_calling_introduces, code = "E0772")]
854 pub struct ButCallingIntroduces {
856 pub param_ty_span: Span,
859 pub cause_span: Span,
861 pub has_param_name: bool,
862 pub param_name: String,
863 pub has_lifetime: bool,
864 pub lifetime: String,
865 pub assoc_item: Symbol,
866 pub has_impl_path: bool,
867 pub impl_path: String,
870 pub struct ReqIntroducedLocations {
872 pub spans: Vec<Span>,
873 pub fn_decl_span: Span,
874 pub cause_span: Span,
878 impl AddToDiagnostic for ReqIntroducedLocations {
879 fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, f: F)
881 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
883 for sp in self.spans {
884 self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
888 self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by);
890 self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of);
891 let msg = f(diag, fluent::infer_ril_static_introduced_by.into());
892 diag.span_note(self.span, msg);
896 pub struct MoreTargeted {
900 impl AddToDiagnostic for MoreTargeted {
901 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _f: F)
903 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
905 diag.code(rustc_errors::error_code!(E0772));
906 diag.set_primary_message(fluent::infer_more_targeted);
907 diag.set_arg("ident", self.ident);
911 #[derive(Diagnostic)]
912 #[diag(infer_but_needs_to_satisfy, code = "E0759")]
913 pub struct ButNeedsToSatisfy {
917 pub influencer_point: Span,
919 pub spans: Vec<Span>,
921 pub require_span_as_label: Option<Span>,
923 pub require_span_as_note: Option<Span>,
924 #[note(introduced_by_bound)]
925 pub bound: Option<Span>,
928 pub req_introduces_loc: Option<ReqIntroducedLocations>,
930 pub spans_empty: bool,
931 pub has_lifetime: bool,
932 pub lifetime: String,