1 use hir::GenericParamKind; 2 use rustc_errors::{ 3 AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, 4 IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage, 5 }; 6 use rustc_hir as hir; 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}; 14 15 use crate::fluent_generated as fluent; 16 use crate::infer::error_reporting::{ 17 need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind}, 18 nice_region_error::placeholder_error::Highlighted, 19 ObligationCauseAsDiagArg, 20 }; 21 22 pub mod note_and_explain; 23 24 #[derive(Diagnostic)] 25 #[diag(infer_opaque_hidden_type)] 26 pub struct OpaqueHiddenTypeDiag { 27 #[primary_span] 28 #[label] 29 pub span: Span, 30 #[note(infer_opaque_type)] 31 pub opaque_type: Span, 32 #[note(infer_hidden_type)] 33 pub hidden_type: Span, 34 } 35 36 #[derive(Diagnostic)] 37 #[diag(infer_type_annotations_needed, code = "E0282")] 38 pub struct AnnotationRequired<'a> { 39 #[primary_span] 40 pub span: Span, 41 pub source_kind: &'static str, 42 pub source_name: &'a str, 43 #[label] 44 pub failure_span: Option<Span>, 45 #[subdiagnostic] 46 pub bad_label: Option<InferenceBadError<'a>>, 47 #[subdiagnostic] 48 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, 49 #[subdiagnostic] 50 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, 51 } 52 53 // Copy of `AnnotationRequired` for E0283 54 #[derive(Diagnostic)] 55 #[diag(infer_type_annotations_needed, code = "E0283")] 56 pub struct AmbiguousImpl<'a> { 57 #[primary_span] 58 pub span: Span, 59 pub source_kind: &'static str, 60 pub source_name: &'a str, 61 #[label] 62 pub failure_span: Option<Span>, 63 #[subdiagnostic] 64 pub bad_label: Option<InferenceBadError<'a>>, 65 #[subdiagnostic] 66 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, 67 #[subdiagnostic] 68 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, 69 } 70 71 // Copy of `AnnotationRequired` for E0284 72 #[derive(Diagnostic)] 73 #[diag(infer_type_annotations_needed, code = "E0284")] 74 pub struct AmbiguousReturn<'a> { 75 #[primary_span] 76 pub span: Span, 77 pub source_kind: &'static str, 78 pub source_name: &'a str, 79 #[label] 80 pub failure_span: Option<Span>, 81 #[subdiagnostic] 82 pub bad_label: Option<InferenceBadError<'a>>, 83 #[subdiagnostic] 84 pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, 85 #[subdiagnostic] 86 pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, 87 } 88 89 #[derive(Diagnostic)] 90 #[diag(infer_need_type_info_in_generator, code = "E0698")] 91 pub struct NeedTypeInfoInGenerator<'a> { 92 #[primary_span] 93 pub span: Span, 94 pub generator_kind: GeneratorKindAsDiagArg, 95 #[subdiagnostic] 96 pub bad_label: InferenceBadError<'a>, 97 } 98 99 // Used when a better one isn't available 100 #[derive(Subdiagnostic)] 101 #[label(infer_label_bad)] 102 pub struct InferenceBadError<'a> { 103 #[primary_span] 104 pub span: Span, 105 pub bad_kind: &'static str, 106 pub prefix_kind: UnderspecifiedArgKind, 107 pub has_parent: bool, 108 pub prefix: &'a str, 109 pub parent_prefix: &'a str, 110 pub parent_name: String, 111 pub name: String, 112 } 113 114 #[derive(Subdiagnostic)] 115 pub enum SourceKindSubdiag<'a> { 116 #[suggestion( 117 infer_source_kind_subdiag_let, 118 style = "verbose", 119 code = ": {type_name}", 120 applicability = "has-placeholders" 121 )] 122 LetLike { 123 #[primary_span] 124 span: Span, 125 name: String, 126 type_name: String, 127 kind: &'static str, 128 x_kind: &'static str, 129 prefix_kind: UnderspecifiedArgKind, 130 prefix: &'a str, 131 arg_name: String, 132 }, 133 #[label(infer_source_kind_subdiag_generic_label)] 134 GenericLabel { 135 #[primary_span] 136 span: Span, 137 is_type: bool, 138 param_name: String, 139 parent_exists: bool, 140 parent_prefix: String, 141 parent_name: String, 142 }, 143 #[suggestion( 144 infer_source_kind_subdiag_generic_suggestion, 145 style = "verbose", 146 code = "::<{args}>", 147 applicability = "has-placeholders" 148 )] 149 GenericSuggestion { 150 #[primary_span] 151 span: Span, 152 arg_count: usize, 153 args: String, 154 }, 155 } 156 157 #[derive(Subdiagnostic)] 158 pub enum SourceKindMultiSuggestion<'a> { 159 #[multipart_suggestion( 160 infer_source_kind_fully_qualified, 161 style = "verbose", 162 applicability = "has-placeholders" 163 )] 164 FullyQualified { 165 #[suggestion_part(code = "{def_path}({adjustment}")] 166 span_lo: Span, 167 #[suggestion_part(code = "{successor_pos}")] 168 span_hi: Span, 169 def_path: String, 170 adjustment: &'a str, 171 successor_pos: &'a str, 172 }, 173 #[multipart_suggestion( 174 infer_source_kind_closure_return, 175 style = "verbose", 176 applicability = "has-placeholders" 177 )] 178 ClosureReturn { 179 #[suggestion_part(code = "{start_span_code}")] 180 start_span: Span, 181 start_span_code: String, 182 #[suggestion_part(code = " }}")] 183 end_span: Option<Span>, 184 }, 185 } 186 187 impl<'a> SourceKindMultiSuggestion<'a> { new_fully_qualified( span: Span, def_path: String, adjustment: &'a str, successor: (&'a str, BytePos), ) -> Self188 pub fn new_fully_qualified( 189 span: Span, 190 def_path: String, 191 adjustment: &'a str, 192 successor: (&'a str, BytePos), 193 ) -> Self { 194 Self::FullyQualified { 195 span_lo: span.shrink_to_lo(), 196 span_hi: span.shrink_to_hi().with_hi(successor.1), 197 def_path, 198 adjustment, 199 successor_pos: successor.0, 200 } 201 } 202 new_closure_return( ty_info: String, data: &'a FnRetTy<'a>, should_wrap_expr: Option<Span>, ) -> Self203 pub fn new_closure_return( 204 ty_info: String, 205 data: &'a FnRetTy<'a>, 206 should_wrap_expr: Option<Span>, 207 ) -> Self { 208 let (arrow, post) = match data { 209 FnRetTy::DefaultReturn(_) => ("-> ", " "), 210 _ => ("", ""), 211 }; 212 let (start_span, start_span_code, end_span) = match should_wrap_expr { 213 Some(end_span) => { 214 (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span)) 215 } 216 None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None), 217 }; 218 Self::ClosureReturn { start_span, start_span_code, end_span } 219 } 220 } 221 222 pub enum RegionOriginNote<'a> { 223 Plain { 224 span: Span, 225 msg: DiagnosticMessage, 226 }, 227 WithName { 228 span: Span, 229 msg: DiagnosticMessage, 230 name: &'a str, 231 continues: bool, 232 }, 233 WithRequirement { 234 span: Span, 235 requirement: ObligationCauseAsDiagArg<'a>, 236 expected_found: Option<(DiagnosticStyledString, DiagnosticStyledString)>, 237 }, 238 } 239 240 impl AddToDiagnostic for RegionOriginNote<'_> { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,241 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) 242 where 243 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 244 { 245 let mut label_or_note = |span, msg: DiagnosticMessage| { 246 let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count(); 247 let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count(); 248 let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span); 249 if span_is_primary && sub_count == 0 && expanded_sub_count == 0 { 250 diag.span_label(span, msg); 251 } else if span_is_primary && expanded_sub_count == 0 { 252 diag.note(msg); 253 } else { 254 diag.span_note(span, msg); 255 } 256 }; 257 match self { 258 RegionOriginNote::Plain { span, msg } => { 259 label_or_note(span, msg); 260 } 261 RegionOriginNote::WithName { span, msg, name, continues } => { 262 label_or_note(span, msg); 263 diag.set_arg("name", name); 264 diag.set_arg("continues", continues); 265 } 266 RegionOriginNote::WithRequirement { 267 span, 268 requirement, 269 expected_found: Some((expected, found)), 270 } => { 271 label_or_note(span, fluent::infer_subtype); 272 diag.set_arg("requirement", requirement); 273 274 diag.note_expected_found(&"", expected, &"", found); 275 } 276 RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => { 277 // FIXME: this really should be handled at some earlier stage. Our 278 // handling of region checking when type errors are present is 279 // *terrible*. 280 label_or_note(span, fluent::infer_subtype_2); 281 diag.set_arg("requirement", requirement); 282 } 283 }; 284 } 285 } 286 287 pub enum LifetimeMismatchLabels { 288 InRet { 289 param_span: Span, 290 ret_span: Span, 291 span: Span, 292 label_var1: Option<Ident>, 293 }, 294 Normal { 295 hir_equal: bool, 296 ty_sup: Span, 297 ty_sub: Span, 298 span: Span, 299 sup: Option<Ident>, 300 sub: Option<Ident>, 301 }, 302 } 303 304 impl AddToDiagnostic for LifetimeMismatchLabels { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,305 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) 306 where 307 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 308 { 309 match self { 310 LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => { 311 diag.span_label(param_span, fluent::infer_declared_different); 312 diag.span_label(ret_span, fluent::infer_nothing); 313 diag.span_label(span, fluent::infer_data_returned); 314 diag.set_arg("label_var1_exists", label_var1.is_some()); 315 diag.set_arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default()); 316 } 317 LifetimeMismatchLabels::Normal { 318 hir_equal, 319 ty_sup, 320 ty_sub, 321 span, 322 sup: label_var1, 323 sub: label_var2, 324 } => { 325 if hir_equal { 326 diag.span_label(ty_sup, fluent::infer_declared_multiple); 327 diag.span_label(ty_sub, fluent::infer_nothing); 328 diag.span_label(span, fluent::infer_data_lifetime_flow); 329 } else { 330 diag.span_label(ty_sup, fluent::infer_types_declared_different); 331 diag.span_label(ty_sub, fluent::infer_nothing); 332 diag.span_label(span, fluent::infer_data_flows); 333 diag.set_arg("label_var1_exists", label_var1.is_some()); 334 diag.set_arg( 335 "label_var1", 336 label_var1.map(|x| x.to_string()).unwrap_or_default(), 337 ); 338 diag.set_arg("label_var2_exists", label_var2.is_some()); 339 diag.set_arg( 340 "label_var2", 341 label_var2.map(|x| x.to_string()).unwrap_or_default(), 342 ); 343 } 344 } 345 } 346 } 347 } 348 349 pub struct AddLifetimeParamsSuggestion<'a> { 350 pub tcx: TyCtxt<'a>, 351 pub sub: Region<'a>, 352 pub ty_sup: &'a hir::Ty<'a>, 353 pub ty_sub: &'a hir::Ty<'a>, 354 pub add_note: bool, 355 } 356 357 impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,358 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) 359 where 360 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 361 { 362 let mut mk_suggestion = || { 363 let ( 364 hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. }, 365 hir::Ty { kind: hir::TyKind::Ref(lifetime_sup, _), .. }, 366 ) = (self.ty_sub, self.ty_sup) else { 367 return false; 368 }; 369 370 if !lifetime_sub.is_anonymous() || !lifetime_sup.is_anonymous() { 371 return false; 372 }; 373 374 let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else { 375 return false; 376 }; 377 378 let hir_id = self.tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); 379 380 let node = self.tcx.hir().get(hir_id); 381 let is_impl = matches!(&node, hir::Node::ImplItem(_)); 382 let generics = match node { 383 hir::Node::Item(&hir::Item { 384 kind: hir::ItemKind::Fn(_, ref generics, ..), 385 .. 386 }) 387 | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) 388 | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics, 389 _ => return false, 390 }; 391 392 let suggestion_param_name = generics 393 .params 394 .iter() 395 .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) 396 .map(|p| p.name.ident().name) 397 .find(|i| *i != kw::UnderscoreLifetime); 398 let introduce_new = suggestion_param_name.is_none(); 399 let suggestion_param_name = 400 suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned()); 401 402 debug!(?lifetime_sup.ident.span); 403 debug!(?lifetime_sub.ident.span); 404 let make_suggestion = |ident: Ident| { 405 let sugg = if ident.name == kw::Empty { 406 format!("{}, ", suggestion_param_name) 407 } else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() { 408 format!("{} ", suggestion_param_name) 409 } else { 410 suggestion_param_name.clone() 411 }; 412 (ident.span, sugg) 413 }; 414 let mut suggestions = 415 vec![make_suggestion(lifetime_sub.ident), make_suggestion(lifetime_sup.ident)]; 416 417 if introduce_new { 418 let new_param_suggestion = if let Some(first) = 419 generics.params.iter().find(|p| !p.name.ident().span.is_empty()) 420 { 421 (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) 422 } else { 423 (generics.span, format!("<{}>", suggestion_param_name)) 424 }; 425 426 suggestions.push(new_param_suggestion); 427 } 428 429 diag.multipart_suggestion( 430 fluent::infer_lifetime_param_suggestion, 431 suggestions, 432 Applicability::MaybeIncorrect, 433 ); 434 diag.set_arg("is_impl", is_impl); 435 true 436 }; 437 if mk_suggestion() && self.add_note { 438 diag.note(fluent::infer_lifetime_param_suggestion_elided); 439 } 440 } 441 } 442 443 #[derive(Diagnostic)] 444 #[diag(infer_lifetime_mismatch, code = "E0623")] 445 pub struct LifetimeMismatch<'a> { 446 #[primary_span] 447 pub span: Span, 448 #[subdiagnostic] 449 pub labels: LifetimeMismatchLabels, 450 #[subdiagnostic] 451 pub suggestion: AddLifetimeParamsSuggestion<'a>, 452 } 453 454 pub struct IntroducesStaticBecauseUnmetLifetimeReq { 455 pub unmet_requirements: MultiSpan, 456 pub binding_span: Span, 457 } 458 459 impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq { add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,460 fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F) 461 where 462 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 463 { 464 self.unmet_requirements 465 .push_span_label(self.binding_span, fluent::infer_msl_introduces_static); 466 diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req); 467 } 468 } 469 470 // FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that 471 #[derive(Subdiagnostic)] 472 pub enum DoesNotOutliveStaticFromImpl { 473 #[note(infer_does_not_outlive_static_from_impl)] 474 Spanned { 475 #[primary_span] 476 span: Span, 477 }, 478 #[note(infer_does_not_outlive_static_from_impl)] 479 Unspanned, 480 } 481 482 #[derive(Subdiagnostic)] 483 pub enum ImplicitStaticLifetimeSubdiag { 484 #[note(infer_implicit_static_lifetime_note)] 485 Note { 486 #[primary_span] 487 span: Span, 488 }, 489 #[suggestion( 490 infer_implicit_static_lifetime_suggestion, 491 style = "verbose", 492 code = " + '_", 493 applicability = "maybe-incorrect" 494 )] 495 Sugg { 496 #[primary_span] 497 span: Span, 498 }, 499 } 500 501 #[derive(Diagnostic)] 502 #[diag(infer_mismatched_static_lifetime)] 503 pub struct MismatchedStaticLifetime<'a> { 504 #[primary_span] 505 pub cause_span: Span, 506 #[subdiagnostic] 507 pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq, 508 #[subdiagnostic] 509 pub expl: Option<note_and_explain::RegionExplanation<'a>>, 510 #[subdiagnostic] 511 pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl, 512 #[subdiagnostic] 513 pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>, 514 } 515 516 #[derive(Diagnostic)] 517 pub enum ExplicitLifetimeRequired<'a> { 518 #[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")] 519 WithIdent { 520 #[primary_span] 521 #[label] 522 span: Span, 523 simple_ident: Ident, 524 named: String, 525 #[suggestion( 526 infer_explicit_lifetime_required_sugg_with_ident, 527 code = "{new_ty}", 528 applicability = "unspecified" 529 )] 530 new_ty_span: Span, 531 #[skip_arg] 532 new_ty: Ty<'a>, 533 }, 534 #[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")] 535 WithParamType { 536 #[primary_span] 537 #[label] 538 span: Span, 539 named: String, 540 #[suggestion( 541 infer_explicit_lifetime_required_sugg_with_param_type, 542 code = "{new_ty}", 543 applicability = "unspecified" 544 )] 545 new_ty_span: Span, 546 #[skip_arg] 547 new_ty: Ty<'a>, 548 }, 549 } 550 551 pub enum TyOrSig<'tcx> { 552 Ty(Highlighted<'tcx, Ty<'tcx>>), 553 ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>), 554 } 555 556 impl IntoDiagnosticArg for TyOrSig<'_> { into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static>557 fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { 558 match self { 559 TyOrSig::Ty(ty) => ty.into_diagnostic_arg(), 560 TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(), 561 } 562 } 563 } 564 565 #[derive(Subdiagnostic)] 566 pub enum ActualImplExplNotes<'tcx> { 567 #[note(infer_actual_impl_expl_expected_signature_two)] 568 ExpectedSignatureTwo { 569 leading_ellipsis: bool, 570 ty_or_sig: TyOrSig<'tcx>, 571 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 572 lifetime_1: usize, 573 lifetime_2: usize, 574 }, 575 #[note(infer_actual_impl_expl_expected_signature_any)] 576 ExpectedSignatureAny { 577 leading_ellipsis: bool, 578 ty_or_sig: TyOrSig<'tcx>, 579 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 580 lifetime_1: usize, 581 }, 582 #[note(infer_actual_impl_expl_expected_signature_some)] 583 ExpectedSignatureSome { 584 leading_ellipsis: bool, 585 ty_or_sig: TyOrSig<'tcx>, 586 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 587 lifetime_1: usize, 588 }, 589 #[note(infer_actual_impl_expl_expected_signature_nothing)] 590 ExpectedSignatureNothing { 591 leading_ellipsis: bool, 592 ty_or_sig: TyOrSig<'tcx>, 593 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 594 }, 595 #[note(infer_actual_impl_expl_expected_passive_two)] 596 ExpectedPassiveTwo { 597 leading_ellipsis: bool, 598 ty_or_sig: TyOrSig<'tcx>, 599 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 600 lifetime_1: usize, 601 lifetime_2: usize, 602 }, 603 #[note(infer_actual_impl_expl_expected_passive_any)] 604 ExpectedPassiveAny { 605 leading_ellipsis: bool, 606 ty_or_sig: TyOrSig<'tcx>, 607 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 608 lifetime_1: usize, 609 }, 610 #[note(infer_actual_impl_expl_expected_passive_some)] 611 ExpectedPassiveSome { 612 leading_ellipsis: bool, 613 ty_or_sig: TyOrSig<'tcx>, 614 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 615 lifetime_1: usize, 616 }, 617 #[note(infer_actual_impl_expl_expected_passive_nothing)] 618 ExpectedPassiveNothing { 619 leading_ellipsis: bool, 620 ty_or_sig: TyOrSig<'tcx>, 621 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 622 }, 623 #[note(infer_actual_impl_expl_expected_other_two)] 624 ExpectedOtherTwo { 625 leading_ellipsis: bool, 626 ty_or_sig: TyOrSig<'tcx>, 627 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 628 lifetime_1: usize, 629 lifetime_2: usize, 630 }, 631 #[note(infer_actual_impl_expl_expected_other_any)] 632 ExpectedOtherAny { 633 leading_ellipsis: bool, 634 ty_or_sig: TyOrSig<'tcx>, 635 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 636 lifetime_1: usize, 637 }, 638 #[note(infer_actual_impl_expl_expected_other_some)] 639 ExpectedOtherSome { 640 leading_ellipsis: bool, 641 ty_or_sig: TyOrSig<'tcx>, 642 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 643 lifetime_1: usize, 644 }, 645 #[note(infer_actual_impl_expl_expected_other_nothing)] 646 ExpectedOtherNothing { 647 leading_ellipsis: bool, 648 ty_or_sig: TyOrSig<'tcx>, 649 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 650 }, 651 #[note(infer_actual_impl_expl_but_actually_implements_trait)] 652 ButActuallyImplementsTrait { 653 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 654 has_lifetime: bool, 655 lifetime: usize, 656 }, 657 #[note(infer_actual_impl_expl_but_actually_implemented_for_ty)] 658 ButActuallyImplementedForTy { 659 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 660 has_lifetime: bool, 661 lifetime: usize, 662 ty: String, 663 }, 664 #[note(infer_actual_impl_expl_but_actually_ty_implements)] 665 ButActuallyTyImplements { 666 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 667 has_lifetime: bool, 668 lifetime: usize, 669 ty: String, 670 }, 671 } 672 673 pub enum ActualImplExpectedKind { 674 Signature, 675 Passive, 676 Other, 677 } 678 679 pub enum ActualImplExpectedLifetimeKind { 680 Two, 681 Any, 682 Some, 683 Nothing, 684 } 685 686 impl<'tcx> ActualImplExplNotes<'tcx> { 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, ) -> Self687 pub fn new_expected( 688 kind: ActualImplExpectedKind, 689 lt_kind: ActualImplExpectedLifetimeKind, 690 leading_ellipsis: bool, 691 ty_or_sig: TyOrSig<'tcx>, 692 trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, 693 lifetime_1: usize, 694 lifetime_2: usize, 695 ) -> Self { 696 match (kind, lt_kind) { 697 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => { 698 Self::ExpectedSignatureTwo { 699 leading_ellipsis, 700 ty_or_sig, 701 trait_path, 702 lifetime_1, 703 lifetime_2, 704 } 705 } 706 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => { 707 Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 708 } 709 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => { 710 Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 711 } 712 (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => { 713 Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path } 714 } 715 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => { 716 Self::ExpectedPassiveTwo { 717 leading_ellipsis, 718 ty_or_sig, 719 trait_path, 720 lifetime_1, 721 lifetime_2, 722 } 723 } 724 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => { 725 Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 726 } 727 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => { 728 Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 729 } 730 (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => { 731 Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path } 732 } 733 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => { 734 Self::ExpectedOtherTwo { 735 leading_ellipsis, 736 ty_or_sig, 737 trait_path, 738 lifetime_1, 739 lifetime_2, 740 } 741 } 742 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => { 743 Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 744 } 745 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => { 746 Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } 747 } 748 (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => { 749 Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path } 750 } 751 } 752 } 753 } 754 755 #[derive(Diagnostic)] 756 #[diag(infer_trait_placeholder_mismatch)] 757 pub struct TraitPlaceholderMismatch<'tcx> { 758 #[primary_span] 759 pub span: Span, 760 #[label(infer_label_satisfy)] 761 pub satisfy_span: Option<Span>, 762 #[label(infer_label_where)] 763 pub where_span: Option<Span>, 764 #[label(infer_label_dup)] 765 pub dup_span: Option<Span>, 766 pub def_id: String, 767 pub trait_def_id: String, 768 769 #[subdiagnostic] 770 pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>, 771 } 772 773 pub struct ConsiderBorrowingParamHelp { 774 pub spans: Vec<Span>, 775 } 776 777 impl AddToDiagnostic for ConsiderBorrowingParamHelp { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,778 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F) 779 where 780 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 781 { 782 let mut type_param_span: MultiSpan = self.spans.clone().into(); 783 for &span in &self.spans { 784 // Seems like we can't call f() here as Into<DiagnosticMessage> is required 785 type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing); 786 } 787 let msg = f(diag, fluent::infer_tid_param_help.into()); 788 diag.span_help(type_param_span, msg); 789 } 790 } 791 792 #[derive(Subdiagnostic)] 793 #[help(infer_tid_rel_help)] 794 pub struct RelationshipHelp; 795 796 #[derive(Diagnostic)] 797 #[diag(infer_trait_impl_diff)] 798 pub struct TraitImplDiff { 799 #[primary_span] 800 #[label(infer_found)] 801 pub sp: Span, 802 #[label(infer_expected)] 803 pub trait_sp: Span, 804 #[note(infer_expected_found)] 805 pub note: (), 806 #[subdiagnostic] 807 pub param_help: ConsiderBorrowingParamHelp, 808 #[subdiagnostic] 809 // Seems like subdiagnostics are always pushed to the end, so this one 810 // also has to be a subdiagnostic to maintain order. 811 pub rel_help: Option<RelationshipHelp>, 812 pub expected: String, 813 pub found: String, 814 } 815 816 pub struct DynTraitConstraintSuggestion { 817 pub span: Span, 818 pub ident: Ident, 819 } 820 821 impl AddToDiagnostic for DynTraitConstraintSuggestion { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,822 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F) 823 where 824 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 825 { 826 let mut multi_span: MultiSpan = vec![self.span].into(); 827 multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label); 828 multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement); 829 let msg = f(diag, fluent::infer_dtcs_has_req_note.into()); 830 diag.span_note(multi_span, msg); 831 let msg = f(diag, fluent::infer_dtcs_suggestion.into()); 832 diag.span_suggestion_verbose( 833 self.span.shrink_to_hi(), 834 msg, 835 " + '_", 836 Applicability::MaybeIncorrect, 837 ); 838 } 839 } 840 841 #[derive(Diagnostic)] 842 #[diag(infer_but_calling_introduces, code = "E0772")] 843 pub struct ButCallingIntroduces { 844 #[label(infer_label1)] 845 pub param_ty_span: Span, 846 #[primary_span] 847 #[label(infer_label2)] 848 pub cause_span: Span, 849 850 pub has_param_name: bool, 851 pub param_name: String, 852 pub has_lifetime: bool, 853 pub lifetime: String, 854 pub assoc_item: Symbol, 855 pub has_impl_path: bool, 856 pub impl_path: String, 857 } 858 859 pub struct ReqIntroducedLocations { 860 pub span: MultiSpan, 861 pub spans: Vec<Span>, 862 pub fn_decl_span: Span, 863 pub cause_span: Span, 864 pub add_label: bool, 865 } 866 867 impl AddToDiagnostic for ReqIntroducedLocations { add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,868 fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, f: F) 869 where 870 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 871 { 872 for sp in self.spans { 873 self.span.push_span_label(sp, fluent::infer_ril_introduced_here); 874 } 875 876 if self.add_label { 877 self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by); 878 } 879 self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of); 880 let msg = f(diag, fluent::infer_ril_static_introduced_by.into()); 881 diag.span_note(self.span, msg); 882 } 883 } 884 885 pub struct MoreTargeted { 886 pub ident: Symbol, 887 } 888 889 impl AddToDiagnostic for MoreTargeted { add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,890 fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _f: F) 891 where 892 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 893 { 894 diag.code(rustc_errors::error_code!(E0772)); 895 diag.set_primary_message(fluent::infer_more_targeted); 896 diag.set_arg("ident", self.ident); 897 } 898 } 899 900 #[derive(Diagnostic)] 901 #[diag(infer_but_needs_to_satisfy, code = "E0759")] 902 pub struct ButNeedsToSatisfy { 903 #[primary_span] 904 pub sp: Span, 905 #[label(infer_influencer)] 906 pub influencer_point: Span, 907 #[label(infer_used_here)] 908 pub spans: Vec<Span>, 909 #[label(infer_require)] 910 pub require_span_as_label: Option<Span>, 911 #[note(infer_require)] 912 pub require_span_as_note: Option<Span>, 913 #[note(infer_introduced_by_bound)] 914 pub bound: Option<Span>, 915 916 #[subdiagnostic] 917 pub req_introduces_loc: Option<ReqIntroducedLocations>, 918 919 pub has_param_name: bool, 920 pub param_name: String, 921 pub spans_empty: bool, 922 pub has_lifetime: bool, 923 pub lifetime: String, 924 } 925 926 #[derive(Diagnostic)] 927 #[diag(infer_outlives_content, code = "E0312")] 928 pub struct OutlivesContent<'a> { 929 #[primary_span] 930 pub span: Span, 931 #[subdiagnostic] 932 pub notes: Vec<note_and_explain::RegionExplanation<'a>>, 933 } 934 935 #[derive(Diagnostic)] 936 #[diag(infer_outlives_bound, code = "E0476")] 937 pub struct OutlivesBound<'a> { 938 #[primary_span] 939 pub span: Span, 940 #[subdiagnostic] 941 pub notes: Vec<note_and_explain::RegionExplanation<'a>>, 942 } 943 944 #[derive(Diagnostic)] 945 #[diag(infer_fulfill_req_lifetime, code = "E0477")] 946 pub struct FulfillReqLifetime<'a> { 947 #[primary_span] 948 pub span: Span, 949 pub ty: Ty<'a>, 950 #[subdiagnostic] 951 pub note: Option<note_and_explain::RegionExplanation<'a>>, 952 } 953 954 #[derive(Diagnostic)] 955 #[diag(infer_lf_bound_not_satisfied, code = "E0478")] 956 pub struct LfBoundNotSatisfied<'a> { 957 #[primary_span] 958 pub span: Span, 959 #[subdiagnostic] 960 pub notes: Vec<note_and_explain::RegionExplanation<'a>>, 961 } 962 963 #[derive(Diagnostic)] 964 #[diag(infer_ref_longer_than_data, code = "E0491")] 965 pub struct RefLongerThanData<'a> { 966 #[primary_span] 967 pub span: Span, 968 pub ty: Ty<'a>, 969 #[subdiagnostic] 970 pub notes: Vec<note_and_explain::RegionExplanation<'a>>, 971 } 972 973 #[derive(Subdiagnostic)] 974 pub enum WhereClauseSuggestions { 975 #[suggestion( 976 infer_where_remove, 977 code = "", 978 applicability = "machine-applicable", 979 style = "verbose" 980 )] 981 Remove { 982 #[primary_span] 983 span: Span, 984 }, 985 #[suggestion( 986 infer_where_copy_predicates, 987 code = "{space}where {trait_predicates}", 988 applicability = "machine-applicable", 989 style = "verbose" 990 )] 991 CopyPredicates { 992 #[primary_span] 993 span: Span, 994 space: &'static str, 995 trait_predicates: String, 996 }, 997 } 998 999 #[derive(Subdiagnostic)] 1000 pub enum SuggestRemoveSemiOrReturnBinding { 1001 #[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")] 1002 RemoveAndBox { 1003 #[suggestion_part(code = "Box::new(")] 1004 first_lo: Span, 1005 #[suggestion_part(code = ")")] 1006 first_hi: Span, 1007 #[suggestion_part(code = "Box::new(")] 1008 second_lo: Span, 1009 #[suggestion_part(code = ")")] 1010 second_hi: Span, 1011 #[suggestion_part(code = "")] 1012 sp: Span, 1013 }, 1014 #[suggestion( 1015 infer_srs_remove, 1016 style = "short", 1017 code = "", 1018 applicability = "machine-applicable" 1019 )] 1020 Remove { 1021 #[primary_span] 1022 sp: Span, 1023 }, 1024 #[suggestion( 1025 infer_srs_add, 1026 style = "verbose", 1027 code = "{code}", 1028 applicability = "maybe-incorrect" 1029 )] 1030 Add { 1031 #[primary_span] 1032 sp: Span, 1033 code: String, 1034 ident: Ident, 1035 }, 1036 #[note(infer_srs_add_one)] 1037 AddOne { 1038 #[primary_span] 1039 spans: MultiSpan, 1040 }, 1041 } 1042 1043 #[derive(Subdiagnostic)] 1044 pub enum ConsiderAddingAwait { 1045 #[help(infer_await_both_futures)] 1046 BothFuturesHelp, 1047 #[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")] 1048 BothFuturesSugg { 1049 #[suggestion_part(code = ".await")] 1050 first: Span, 1051 #[suggestion_part(code = ".await")] 1052 second: Span, 1053 }, 1054 #[suggestion( 1055 infer_await_future, 1056 code = ".await", 1057 style = "verbose", 1058 applicability = "maybe-incorrect" 1059 )] 1060 FutureSugg { 1061 #[primary_span] 1062 span: Span, 1063 }, 1064 #[note(infer_await_note)] 1065 FutureSuggNote { 1066 #[primary_span] 1067 span: Span, 1068 }, 1069 #[multipart_suggestion( 1070 infer_await_future, 1071 style = "verbose", 1072 applicability = "maybe-incorrect" 1073 )] 1074 FutureSuggMultiple { 1075 #[suggestion_part(code = ".await")] 1076 spans: Vec<Span>, 1077 }, 1078 } 1079 1080 #[derive(Diagnostic)] 1081 pub enum PlaceholderRelationLfNotSatisfied { 1082 #[diag(infer_lf_bound_not_satisfied)] 1083 HasBoth { 1084 #[primary_span] 1085 span: Span, 1086 #[note(infer_prlf_defined_with_sub)] 1087 sub_span: Span, 1088 #[note(infer_prlf_must_outlive_with_sup)] 1089 sup_span: Span, 1090 sub_symbol: Symbol, 1091 sup_symbol: Symbol, 1092 #[note(infer_prlf_known_limitation)] 1093 note: (), 1094 }, 1095 #[diag(infer_lf_bound_not_satisfied)] 1096 HasSub { 1097 #[primary_span] 1098 span: Span, 1099 #[note(infer_prlf_defined_with_sub)] 1100 sub_span: Span, 1101 #[note(infer_prlf_must_outlive_without_sup)] 1102 sup_span: Span, 1103 sub_symbol: Symbol, 1104 #[note(infer_prlf_known_limitation)] 1105 note: (), 1106 }, 1107 #[diag(infer_lf_bound_not_satisfied)] 1108 HasSup { 1109 #[primary_span] 1110 span: Span, 1111 #[note(infer_prlf_defined_without_sub)] 1112 sub_span: Span, 1113 #[note(infer_prlf_must_outlive_with_sup)] 1114 sup_span: Span, 1115 sup_symbol: Symbol, 1116 #[note(infer_prlf_known_limitation)] 1117 note: (), 1118 }, 1119 #[diag(infer_lf_bound_not_satisfied)] 1120 HasNone { 1121 #[primary_span] 1122 span: Span, 1123 #[note(infer_prlf_defined_without_sub)] 1124 sub_span: Span, 1125 #[note(infer_prlf_must_outlive_without_sup)] 1126 sup_span: Span, 1127 #[note(infer_prlf_known_limitation)] 1128 note: (), 1129 }, 1130 #[diag(infer_lf_bound_not_satisfied)] 1131 OnlyPrimarySpan { 1132 #[primary_span] 1133 span: Span, 1134 #[note(infer_prlf_known_limitation)] 1135 note: (), 1136 }, 1137 } 1138 1139 #[derive(Diagnostic)] 1140 #[diag(infer_opaque_captures_lifetime, code = "E0700")] 1141 pub struct OpaqueCapturesLifetime<'tcx> { 1142 #[primary_span] 1143 pub span: Span, 1144 #[label] 1145 pub opaque_ty_span: Span, 1146 pub opaque_ty: Ty<'tcx>, 1147 } 1148 1149 #[derive(Subdiagnostic)] 1150 pub enum FunctionPointerSuggestion<'a> { 1151 #[suggestion( 1152 infer_fps_use_ref, 1153 code = "&{fn_name}", 1154 style = "verbose", 1155 applicability = "maybe-incorrect" 1156 )] 1157 UseRef { 1158 #[primary_span] 1159 span: Span, 1160 #[skip_arg] 1161 fn_name: String, 1162 }, 1163 #[suggestion( 1164 infer_fps_remove_ref, 1165 code = "{fn_name}", 1166 style = "verbose", 1167 applicability = "maybe-incorrect" 1168 )] 1169 RemoveRef { 1170 #[primary_span] 1171 span: Span, 1172 #[skip_arg] 1173 fn_name: String, 1174 }, 1175 #[suggestion( 1176 infer_fps_cast, 1177 code = "&({fn_name} as {sig})", 1178 style = "verbose", 1179 applicability = "maybe-incorrect" 1180 )] 1181 CastRef { 1182 #[primary_span] 1183 span: Span, 1184 #[skip_arg] 1185 fn_name: String, 1186 #[skip_arg] 1187 sig: Binder<'a, FnSig<'a>>, 1188 }, 1189 #[suggestion( 1190 infer_fps_cast, 1191 code = "{fn_name} as {sig}", 1192 style = "verbose", 1193 applicability = "maybe-incorrect" 1194 )] 1195 Cast { 1196 #[primary_span] 1197 span: Span, 1198 #[skip_arg] 1199 fn_name: String, 1200 #[skip_arg] 1201 sig: Binder<'a, FnSig<'a>>, 1202 }, 1203 #[suggestion( 1204 infer_fps_cast_both, 1205 code = "{fn_name} as {found_sig}", 1206 style = "hidden", 1207 applicability = "maybe-incorrect" 1208 )] 1209 CastBoth { 1210 #[primary_span] 1211 span: Span, 1212 #[skip_arg] 1213 fn_name: String, 1214 #[skip_arg] 1215 found_sig: Binder<'a, FnSig<'a>>, 1216 expected_sig: Binder<'a, FnSig<'a>>, 1217 }, 1218 #[suggestion( 1219 infer_fps_cast_both, 1220 code = "&({fn_name} as {found_sig})", 1221 style = "hidden", 1222 applicability = "maybe-incorrect" 1223 )] 1224 CastBothRef { 1225 #[primary_span] 1226 span: Span, 1227 #[skip_arg] 1228 fn_name: String, 1229 #[skip_arg] 1230 found_sig: Binder<'a, FnSig<'a>>, 1231 expected_sig: Binder<'a, FnSig<'a>>, 1232 }, 1233 } 1234 1235 #[derive(Subdiagnostic)] 1236 #[note(infer_fps_items_are_distinct)] 1237 pub struct FnItemsAreDistinct; 1238 1239 #[derive(Subdiagnostic)] 1240 #[note(infer_fn_uniq_types)] 1241 pub struct FnUniqTypes; 1242 1243 #[derive(Subdiagnostic)] 1244 #[help(infer_fn_consider_casting)] 1245 pub struct FnConsiderCasting { 1246 pub casting: String, 1247 } 1248 1249 #[derive(Subdiagnostic)] 1250 pub enum SuggestAccessingField<'a> { 1251 #[suggestion( 1252 infer_suggest_accessing_field, 1253 code = "{snippet}.{name}", 1254 applicability = "maybe-incorrect" 1255 )] 1256 Safe { 1257 #[primary_span] 1258 span: Span, 1259 snippet: String, 1260 name: Symbol, 1261 ty: Ty<'a>, 1262 }, 1263 #[suggestion( 1264 infer_suggest_accessing_field, 1265 code = "unsafe {{ {snippet}.{name} }}", 1266 applicability = "maybe-incorrect" 1267 )] 1268 Unsafe { 1269 #[primary_span] 1270 span: Span, 1271 snippet: String, 1272 name: Symbol, 1273 ty: Ty<'a>, 1274 }, 1275 } 1276 1277 #[derive(Subdiagnostic)] 1278 pub enum SuggestBoxingForReturnImplTrait { 1279 #[multipart_suggestion(infer_sbfrit_change_return_type, applicability = "maybe-incorrect")] 1280 ChangeReturnType { 1281 #[suggestion_part(code = "Box<dyn")] 1282 start_sp: Span, 1283 #[suggestion_part(code = ">")] 1284 end_sp: Span, 1285 }, 1286 #[multipart_suggestion(infer_sbfrit_box_return_expr, applicability = "maybe-incorrect")] 1287 BoxReturnExpr { 1288 #[suggestion_part(code = "Box::new(")] 1289 starts: Vec<Span>, 1290 #[suggestion_part(code = ")")] 1291 ends: Vec<Span>, 1292 }, 1293 } 1294 1295 #[derive(Subdiagnostic)] 1296 #[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")] 1297 pub struct SuggestTuplePatternOne { 1298 pub variant: String, 1299 #[suggestion_part(code = "{variant}(")] 1300 pub span_low: Span, 1301 #[suggestion_part(code = ")")] 1302 pub span_high: Span, 1303 } 1304 1305 pub struct SuggestTuplePatternMany { 1306 pub path: String, 1307 pub cause_span: Span, 1308 pub compatible_variants: Vec<String>, 1309 } 1310 1311 impl AddToDiagnostic for SuggestTuplePatternMany { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,1312 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F) 1313 where 1314 F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, 1315 { 1316 diag.set_arg("path", self.path); 1317 let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into()); 1318 diag.multipart_suggestions( 1319 message, 1320 self.compatible_variants.into_iter().map(|variant| { 1321 vec![ 1322 (self.cause_span.shrink_to_lo(), format!("{}(", variant)), 1323 (self.cause_span.shrink_to_hi(), ")".to_string()), 1324 ] 1325 }), 1326 rustc_errors::Applicability::MaybeIncorrect, 1327 ); 1328 } 1329 } 1330 1331 #[derive(Subdiagnostic)] 1332 pub enum TypeErrorAdditionalDiags { 1333 #[suggestion( 1334 infer_meant_byte_literal, 1335 code = "b'{code}'", 1336 applicability = "machine-applicable" 1337 )] 1338 MeantByteLiteral { 1339 #[primary_span] 1340 span: Span, 1341 code: String, 1342 }, 1343 #[suggestion( 1344 infer_meant_char_literal, 1345 code = "'{code}'", 1346 applicability = "machine-applicable" 1347 )] 1348 MeantCharLiteral { 1349 #[primary_span] 1350 span: Span, 1351 code: String, 1352 }, 1353 #[suggestion( 1354 infer_meant_str_literal, 1355 code = "\"{code}\"", 1356 applicability = "machine-applicable" 1357 )] 1358 MeantStrLiteral { 1359 #[primary_span] 1360 span: Span, 1361 code: String, 1362 }, 1363 #[suggestion( 1364 infer_consider_specifying_length, 1365 code = "{length}", 1366 applicability = "maybe-incorrect" 1367 )] 1368 ConsiderSpecifyingLength { 1369 #[primary_span] 1370 span: Span, 1371 length: u64, 1372 }, 1373 #[note(infer_try_cannot_convert)] 1374 TryCannotConvert { found: String, expected: String }, 1375 #[suggestion(infer_tuple_trailing_comma, code = ",", applicability = "machine-applicable")] 1376 TupleOnlyComma { 1377 #[primary_span] 1378 span: Span, 1379 }, 1380 #[multipart_suggestion(infer_tuple_trailing_comma, applicability = "machine-applicable")] 1381 TupleAlsoParentheses { 1382 #[suggestion_part(code = "(")] 1383 span_low: Span, 1384 #[suggestion_part(code = ",)")] 1385 span_high: Span, 1386 }, 1387 #[suggestion( 1388 infer_suggest_add_let_for_letchains, 1389 style = "verbose", 1390 applicability = "machine-applicable", 1391 code = "let " 1392 )] 1393 AddLetForLetChains { 1394 #[primary_span] 1395 span: Span, 1396 }, 1397 } 1398 1399 #[derive(Diagnostic)] 1400 pub enum ObligationCauseFailureCode { 1401 #[diag(infer_oc_method_compat, code = "E0308")] 1402 MethodCompat { 1403 #[primary_span] 1404 span: Span, 1405 #[subdiagnostic] 1406 subdiags: Vec<TypeErrorAdditionalDiags>, 1407 }, 1408 #[diag(infer_oc_type_compat, code = "E0308")] 1409 TypeCompat { 1410 #[primary_span] 1411 span: Span, 1412 #[subdiagnostic] 1413 subdiags: Vec<TypeErrorAdditionalDiags>, 1414 }, 1415 #[diag(infer_oc_const_compat, code = "E0308")] 1416 ConstCompat { 1417 #[primary_span] 1418 span: Span, 1419 #[subdiagnostic] 1420 subdiags: Vec<TypeErrorAdditionalDiags>, 1421 }, 1422 #[diag(infer_oc_try_compat, code = "E0308")] 1423 TryCompat { 1424 #[primary_span] 1425 span: Span, 1426 #[subdiagnostic] 1427 subdiags: Vec<TypeErrorAdditionalDiags>, 1428 }, 1429 #[diag(infer_oc_match_compat, code = "E0308")] 1430 MatchCompat { 1431 #[primary_span] 1432 span: Span, 1433 #[subdiagnostic] 1434 subdiags: Vec<TypeErrorAdditionalDiags>, 1435 }, 1436 #[diag(infer_oc_if_else_different, code = "E0308")] 1437 IfElseDifferent { 1438 #[primary_span] 1439 span: Span, 1440 #[subdiagnostic] 1441 subdiags: Vec<TypeErrorAdditionalDiags>, 1442 }, 1443 #[diag(infer_oc_no_else, code = "E0317")] 1444 NoElse { 1445 #[primary_span] 1446 span: Span, 1447 }, 1448 #[diag(infer_oc_no_diverge, code = "E0308")] 1449 NoDiverge { 1450 #[primary_span] 1451 span: Span, 1452 #[subdiagnostic] 1453 subdiags: Vec<TypeErrorAdditionalDiags>, 1454 }, 1455 #[diag(infer_oc_fn_main_correct_type, code = "E0580")] 1456 FnMainCorrectType { 1457 #[primary_span] 1458 span: Span, 1459 }, 1460 #[diag(infer_oc_fn_start_correct_type, code = "E0308")] 1461 FnStartCorrectType { 1462 #[primary_span] 1463 span: Span, 1464 #[subdiagnostic] 1465 subdiags: Vec<TypeErrorAdditionalDiags>, 1466 }, 1467 #[diag(infer_oc_intrinsic_correct_type, code = "E0308")] 1468 IntrinsicCorrectType { 1469 #[primary_span] 1470 span: Span, 1471 #[subdiagnostic] 1472 subdiags: Vec<TypeErrorAdditionalDiags>, 1473 }, 1474 #[diag(infer_oc_method_correct_type, code = "E0308")] 1475 MethodCorrectType { 1476 #[primary_span] 1477 span: Span, 1478 #[subdiagnostic] 1479 subdiags: Vec<TypeErrorAdditionalDiags>, 1480 }, 1481 #[diag(infer_oc_closure_selfref, code = "E0644")] 1482 ClosureSelfref { 1483 #[primary_span] 1484 span: Span, 1485 }, 1486 #[diag(infer_oc_cant_coerce, code = "E0308")] 1487 CantCoerce { 1488 #[primary_span] 1489 span: Span, 1490 #[subdiagnostic] 1491 subdiags: Vec<TypeErrorAdditionalDiags>, 1492 }, 1493 #[diag(infer_oc_generic, code = "E0308")] 1494 Generic { 1495 #[primary_span] 1496 span: Span, 1497 #[subdiagnostic] 1498 subdiags: Vec<TypeErrorAdditionalDiags>, 1499 }, 1500 } 1501