1use std::borrow::Cow;
4
5use rustc_abi::ExternAbi;
6use rustc_ast::Label;
7use rustc_errors::codes::*;
8use rustc_errors::{
9 Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic,
10 EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
11};
12use rustc_hir as hir;
13use rustc_hir::ExprKind;
14use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
15use rustc_middle::ty::{self, Ty};
16use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
17use rustc_span::{Ident, Span, Symbol};
18
19use crate::fluent_generated as fluent;
20
21#[derive(Diagnostic)]
22#[diag(hir_typeck_base_expression_double_dot, code = E0797)]
23pub(crate) struct BaseExpressionDoubleDot {
24 #[primary_span]
25 pub span: Span,
26 #[suggestion(
27 hir_typeck_base_expression_double_dot_enable_default_field_values,
28 code = "#![feature(default_field_values)]\n",
29 applicability = "machine-applicable",
30 style = "verbose"
31 )]
32 pub default_field_values_suggestion: Option<Span>,
33 #[subdiagnostic]
34 pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
35 #[subdiagnostic]
36 pub remove_dots: Option<BaseExpressionDoubleDotRemove>,
37}
38
39#[derive(Subdiagnostic)]
40#[suggestion(
41 hir_typeck_base_expression_double_dot_remove,
42 code = "",
43 applicability = "machine-applicable",
44 style = "verbose"
45)]
46pub(crate) struct BaseExpressionDoubleDotRemove {
47 #[primary_span]
48 pub span: Span,
49}
50
51#[derive(Subdiagnostic)]
52#[suggestion(
53 hir_typeck_base_expression_double_dot_add_expr,
54 code = "/* expr */",
55 applicability = "has-placeholders",
56 style = "verbose"
57)]
58pub(crate) struct BaseExpressionDoubleDotAddExpr {
59 #[primary_span]
60 pub span: Span,
61}
62
63#[derive(Diagnostic)]
64#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
65pub(crate) struct FieldMultiplySpecifiedInInitializer {
66 #[primary_span]
67 #[label]
68 pub span: Span,
69 #[label(hir_typeck_previous_use_label)]
70 pub prev_span: Span,
71 pub ident: Ident,
72}
73
74#[derive(Diagnostic)]
75#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
76pub(crate) struct ReturnStmtOutsideOfFnBody {
77 #[primary_span]
78 pub span: Span,
79 #[label(hir_typeck_encl_body_label)]
80 pub encl_body_span: Option<Span>,
81 #[label(hir_typeck_encl_fn_label)]
82 pub encl_fn_span: Option<Span>,
83 pub statement_kind: ReturnLikeStatementKind,
84}
85
86pub(crate) enum ReturnLikeStatementKind {
87 Return,
88 Become,
89}
90
91impl IntoDiagArg for ReturnLikeStatementKind {
92 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
93 let kind = match self {
94 Self::Return => "return",
95 Self::Become => "become",
96 }
97 .into();
98
99 DiagArgValue::Str(kind)
100 }
101}
102
103#[derive(Diagnostic)]
104#[diag(hir_typeck_rustcall_incorrect_args)]
105pub(crate) struct RustCallIncorrectArgs {
106 #[primary_span]
107 pub span: Span,
108}
109
110#[derive(Diagnostic)]
111#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
112pub(crate) struct YieldExprOutsideOfCoroutine {
113 #[primary_span]
114 pub span: Span,
115}
116
117#[derive(Diagnostic)]
118#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
119pub(crate) struct StructExprNonExhaustive {
120 #[primary_span]
121 pub span: Span,
122 pub what: &'static str,
123}
124
125#[derive(Diagnostic)]
126#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
127pub(crate) struct FunctionalRecordUpdateOnNonStruct {
128 #[primary_span]
129 pub span: Span,
130}
131
132#[derive(Diagnostic)]
133#[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
134pub(crate) struct AddressOfTemporaryTaken {
135 #[primary_span]
136 #[label]
137 pub span: Span,
138}
139
140#[derive(Subdiagnostic)]
141pub(crate) enum AddReturnTypeSuggestion {
142 #[suggestion(
143 hir_typeck_add_return_type_add,
144 code = " -> {found}",
145 applicability = "machine-applicable"
146 )]
147 Add {
148 #[primary_span]
149 span: Span,
150 found: String,
151 },
152 #[suggestion(
153 hir_typeck_add_return_type_missing_here,
154 code = " -> _",
155 applicability = "has-placeholders"
156 )]
157 MissingHere {
158 #[primary_span]
159 span: Span,
160 },
161}
162
163#[derive(Subdiagnostic)]
164pub(crate) enum ExpectedReturnTypeLabel<'tcx> {
165 #[label(hir_typeck_expected_default_return_type)]
166 Unit {
167 #[primary_span]
168 span: Span,
169 },
170 #[label(hir_typeck_expected_return_type)]
171 Other {
172 #[primary_span]
173 span: Span,
174 expected: Ty<'tcx>,
175 },
176}
177
178#[derive(Diagnostic)]
179#[diag(hir_typeck_explicit_destructor, code = E0040)]
180pub(crate) struct ExplicitDestructorCall {
181 #[primary_span]
182 #[label]
183 pub span: Span,
184 #[subdiagnostic]
185 pub sugg: ExplicitDestructorCallSugg,
186}
187
188#[derive(Subdiagnostic)]
189pub(crate) enum ExplicitDestructorCallSugg {
190 #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")]
191 Empty(#[primary_span] Span),
192 #[multipart_suggestion(hir_typeck_suggestion, style = "short")]
193 Snippet {
194 #[suggestion_part(code = "drop(")]
195 lo: Span,
196 #[suggestion_part(code = ")")]
197 hi: Span,
198 },
199}
200
201#[derive(Diagnostic)]
202#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
203pub(crate) struct MissingParenthesesInRange {
204 #[primary_span]
205 #[label(hir_typeck_missing_parentheses_in_range)]
206 pub span: Span,
207 pub ty_str: String,
208 pub method_name: String,
209 #[subdiagnostic]
210 pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
211}
212
213#[derive(LintDiagnostic)]
214pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
215 #[help]
216 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
217 Call {
218 #[subdiagnostic]
219 sugg: SuggestAnnotations,
220 },
221 #[help]
222 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
223 Method {
224 #[subdiagnostic]
225 sugg: SuggestAnnotations,
226 },
227 #[help]
228 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
229 Path {
230 #[subdiagnostic]
231 sugg: SuggestAnnotations,
232 },
233 #[help]
234 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
235 UnionField {
236 #[subdiagnostic]
237 sugg: SuggestAnnotations,
238 },
239 #[help]
240 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
241 Deref {
242 #[subdiagnostic]
243 sugg: SuggestAnnotations,
244 },
245}
246
247#[derive(LintDiagnostic)]
248#[help]
249#[diag(hir_typeck_dependency_on_unit_never_type_fallback)]
250pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
251 #[note]
252 pub obligation_span: Span,
253 pub obligation: ty::Predicate<'tcx>,
254 #[subdiagnostic]
255 pub sugg: SuggestAnnotations,
256}
257
258#[derive(Clone)]
259pub(crate) enum SuggestAnnotation {
260 Unit(Span),
261 Path(Span),
262 Local(Span),
263 Turbo(Span, usize, usize),
264}
265
266#[derive(Clone)]
267pub(crate) struct SuggestAnnotations {
268 pub suggestions: Vec<SuggestAnnotation>,
269}
270impl Subdiagnostic for SuggestAnnotations {
271 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
272 if self.suggestions.is_empty() {
273 return;
274 }
275
276 let mut suggestions = vec![];
277 for suggestion in self.suggestions {
278 match suggestion {
279 SuggestAnnotation::Unit(span) => {
280 suggestions.push((span, "()".to_string()));
281 }
282 SuggestAnnotation::Path(span) => {
283 suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
284 suggestions.push((span.shrink_to_hi(), ">".to_string()));
285 }
286 SuggestAnnotation::Local(span) => {
287 suggestions.push((span, ": ()".to_string()));
288 }
289 SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
290 span,
291 format!(
292 "::<{}>",
293 (0..n_args)
294 .map(|i| if i == idx { "()" } else { "_" })
295 .collect::<Vec<_>>()
296 .join(", "),
297 ),
298 )),
299 }
300 }
301
302 diag.multipart_suggestion_verbose(
303 "use `()` annotations to avoid fallback changes",
304 suggestions,
305 Applicability::MachineApplicable,
306 );
307 }
308}
309
310#[derive(Subdiagnostic)]
311#[multipart_suggestion(
312 hir_typeck_add_missing_parentheses_in_range,
313 style = "verbose",
314 applicability = "maybe-incorrect"
315)]
316pub(crate) struct AddMissingParenthesesInRange {
317 pub func_name: String,
318 #[suggestion_part(code = "(")]
319 pub left: Span,
320 #[suggestion_part(code = ")")]
321 pub right: Span,
322}
323
324pub(crate) struct TypeMismatchFruTypo {
325 pub expr_span: Span,
327 pub fru_span: Span,
329 pub expr: Option<String>,
331}
332
333impl Subdiagnostic for TypeMismatchFruTypo {
334 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
335 diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
336
337 if self.expr_span.between(self.fru_span).is_empty() {
339 diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note);
340 } else {
341 let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
342 multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr);
343 multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2);
344 diag.span_note(multispan, fluent::hir_typeck_fru_note);
345 }
346
347 diag.span_suggestion(
348 self.expr_span.shrink_to_hi(),
349 fluent::hir_typeck_fru_suggestion,
350 ", ",
351 Applicability::MaybeIncorrect,
352 );
353 }
354}
355
356#[derive(LintDiagnostic)]
357#[diag(hir_typeck_lossy_provenance_int2ptr)]
358#[help]
359pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
360 pub expr_ty: Ty<'tcx>,
361 pub cast_ty: Ty<'tcx>,
362 #[subdiagnostic]
363 pub sugg: LossyProvenanceInt2PtrSuggestion,
364}
365
366#[derive(Diagnostic)]
367#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)]
368#[note]
369#[help]
370pub(crate) struct PtrCastAddAutoToObject {
371 #[primary_span]
372 #[label]
373 pub span: Span,
374 pub traits_len: usize,
375 pub traits: DiagSymbolList<String>,
376}
377
378#[derive(Subdiagnostic)]
379#[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")]
380pub(crate) struct LossyProvenanceInt2PtrSuggestion {
381 #[suggestion_part(code = "(...).with_addr(")]
382 pub lo: Span,
383 #[suggestion_part(code = ")")]
384 pub hi: Span,
385}
386
387#[derive(LintDiagnostic)]
388#[diag(hir_typeck_lossy_provenance_ptr2int)]
389#[help]
390pub(crate) struct LossyProvenancePtr2Int<'tcx> {
391 pub expr_ty: Ty<'tcx>,
392 pub cast_ty: Ty<'tcx>,
393 #[subdiagnostic]
394 pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
395}
396
397#[derive(Subdiagnostic)]
398pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> {
399 #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
400 NeedsParensCast {
401 #[suggestion_part(code = "(")]
402 expr_span: Span,
403 #[suggestion_part(code = ").addr() as {cast_ty}")]
404 cast_span: Span,
405 cast_ty: Ty<'tcx>,
406 },
407 #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
408 NeedsParens {
409 #[suggestion_part(code = "(")]
410 expr_span: Span,
411 #[suggestion_part(code = ").addr()")]
412 cast_span: Span,
413 },
414 #[suggestion(
415 hir_typeck_suggestion,
416 code = ".addr() as {cast_ty}",
417 applicability = "maybe-incorrect"
418 )]
419 NeedsCast {
420 #[primary_span]
421 cast_span: Span,
422 cast_ty: Ty<'tcx>,
423 },
424 #[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")]
425 Other {
426 #[primary_span]
427 cast_span: Span,
428 },
429}
430
431#[derive(Subdiagnostic)]
432pub(crate) enum HelpUseLatestEdition {
433 #[help(hir_typeck_help_set_edition_cargo)]
434 #[note(hir_typeck_note_edition_guide)]
435 Cargo { edition: Edition },
436 #[help(hir_typeck_help_set_edition_standalone)]
437 #[note(hir_typeck_note_edition_guide)]
438 Standalone { edition: Edition },
439}
440
441impl HelpUseLatestEdition {
442 pub(crate) fn new() -> Self {
443 let edition = LATEST_STABLE_EDITION;
444 if rustc_session::utils::was_invoked_from_cargo() {
445 Self::Cargo { edition }
446 } else {
447 Self::Standalone { edition }
448 }
449 }
450}
451
452#[derive(Diagnostic)]
453#[diag(hir_typeck_no_field_on_type, code = E0609)]
454pub(crate) struct NoFieldOnType<'tcx> {
455 #[primary_span]
456 pub(crate) span: Span,
457 pub(crate) ty: Ty<'tcx>,
458 pub(crate) field: Ident,
459}
460
461#[derive(Diagnostic)]
462#[diag(hir_typeck_no_field_on_variant, code = E0609)]
463pub(crate) struct NoFieldOnVariant<'tcx> {
464 #[primary_span]
465 pub(crate) span: Span,
466 pub(crate) container: Ty<'tcx>,
467 pub(crate) ident: Ident,
468 pub(crate) field: Ident,
469 #[label(hir_typeck_no_field_on_variant_enum)]
470 pub(crate) enum_span: Span,
471 #[label(hir_typeck_no_field_on_variant_field)]
472 pub(crate) field_span: Span,
473}
474
475#[derive(Diagnostic)]
476#[diag(hir_typeck_cant_dereference, code = E0614)]
477pub(crate) struct CantDereference<'tcx> {
478 #[primary_span]
479 #[label(hir_typeck_cant_dereference_label)]
480 pub(crate) span: Span,
481 pub(crate) ty: Ty<'tcx>,
482}
483
484#[derive(Diagnostic)]
485#[diag(hir_typeck_expected_array_or_slice, code = E0529)]
486pub(crate) struct ExpectedArrayOrSlice<'tcx> {
487 #[primary_span]
488 #[label(hir_typeck_expected_array_or_slice_label)]
489 pub(crate) span: Span,
490 pub(crate) ty: Ty<'tcx>,
491 pub(crate) slice_pat_semantics: bool,
492 #[subdiagnostic]
493 pub(crate) as_deref: Option<AsDerefSuggestion>,
494 #[subdiagnostic]
495 pub(crate) slicing: Option<SlicingSuggestion>,
496}
497
498#[derive(Subdiagnostic)]
499#[suggestion(
500 hir_typeck_as_deref_suggestion,
501 code = ".as_deref()",
502 style = "verbose",
503 applicability = "maybe-incorrect"
504)]
505pub(crate) struct AsDerefSuggestion {
506 #[primary_span]
507 pub(crate) span: Span,
508}
509
510#[derive(Subdiagnostic)]
511#[suggestion(
512 hir_typeck_slicing_suggestion,
513 code = "[..]",
514 style = "verbose",
515 applicability = "maybe-incorrect"
516)]
517pub(crate) struct SlicingSuggestion {
518 #[primary_span]
519 pub(crate) span: Span,
520}
521
522#[derive(Diagnostic)]
523#[diag(hir_typeck_invalid_callee, code = E0618)]
524pub(crate) struct InvalidCallee<'tcx> {
525 #[primary_span]
526 pub span: Span,
527 pub ty: Ty<'tcx>,
528 pub found: String,
529}
530
531#[derive(Diagnostic)]
532#[diag(hir_typeck_int_to_fat, code = E0606)]
533pub(crate) struct IntToWide<'tcx> {
534 #[primary_span]
535 #[label(hir_typeck_int_to_fat_label)]
536 pub span: Span,
537 pub metadata: &'tcx str,
538 pub expr_ty: Ty<'tcx>,
539 pub cast_ty: Ty<'tcx>,
540 #[label(hir_typeck_int_to_fat_label_nightly)]
541 pub expr_if_nightly: Option<Span>,
542 pub known_wide: bool,
543}
544
545#[derive(Subdiagnostic)]
546pub(crate) enum OptionResultRefMismatch {
547 #[suggestion(
548 hir_typeck_option_result_copied,
549 code = ".copied()",
550 style = "verbose",
551 applicability = "machine-applicable"
552 )]
553 Copied {
554 #[primary_span]
555 span: Span,
556 def_path: String,
557 },
558 #[suggestion(
559 hir_typeck_option_result_cloned,
560 code = ".cloned()",
561 style = "verbose",
562 applicability = "machine-applicable"
563 )]
564 Cloned {
565 #[primary_span]
566 span: Span,
567 def_path: String,
568 },
569 }
584
585pub(crate) struct RemoveSemiForCoerce {
586 pub expr: Span,
587 pub ret: Span,
588 pub semi: Span,
589}
590
591impl Subdiagnostic for RemoveSemiForCoerce {
592 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
593 let mut multispan: MultiSpan = self.semi.into();
594 multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
595 multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
596 multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi);
597 diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce);
598
599 diag.tool_only_span_suggestion(
600 self.semi,
601 fluent::hir_typeck_remove_semi_for_coerce_suggestion,
602 "",
603 Applicability::MaybeIncorrect,
604 );
605 }
606}
607
608#[derive(Diagnostic)]
609#[diag(hir_typeck_const_select_must_be_const)]
610#[help]
611pub(crate) struct ConstSelectMustBeConst {
612 #[primary_span]
613 pub span: Span,
614}
615
616#[derive(Diagnostic)]
617#[diag(hir_typeck_const_select_must_be_fn)]
618#[note]
619#[help]
620pub(crate) struct ConstSelectMustBeFn<'a> {
621 #[primary_span]
622 pub span: Span,
623 pub ty: Ty<'a>,
624}
625
626#[derive(Diagnostic)]
627#[diag(hir_typeck_union_pat_multiple_fields)]
628pub(crate) struct UnionPatMultipleFields {
629 #[primary_span]
630 pub span: Span,
631}
632
633#[derive(Diagnostic)]
634#[diag(hir_typeck_union_pat_dotdot)]
635pub(crate) struct UnionPatDotDot {
636 #[primary_span]
637 pub span: Span,
638}
639
640#[derive(Subdiagnostic)]
641#[multipart_suggestion(
642 hir_typeck_use_is_empty,
643 applicability = "maybe-incorrect",
644 style = "verbose"
645)]
646pub(crate) struct UseIsEmpty<'tcx> {
647 #[suggestion_part(code = "!")]
648 pub lo: Span,
649 #[suggestion_part(code = ".is_empty()")]
650 pub hi: Span,
651 pub expr_ty: Ty<'tcx>,
652}
653
654#[derive(Diagnostic)]
655#[diag(hir_typeck_arg_mismatch_indeterminate)]
656pub(crate) struct ArgMismatchIndeterminate {
657 #[primary_span]
658 pub span: Span,
659}
660
661#[derive(Subdiagnostic)]
662pub(crate) enum SuggestBoxing {
663 #[note(hir_typeck_suggest_boxing_note)]
664 #[multipart_suggestion(
665 hir_typeck_suggest_boxing_when_appropriate,
666 applicability = "machine-applicable"
667 )]
668 Unit {
669 #[suggestion_part(code = "Box::new(())")]
670 start: Span,
671 #[suggestion_part(code = "")]
672 end: Span,
673 },
674 #[note(hir_typeck_suggest_boxing_note)]
675 AsyncBody,
676 #[note(hir_typeck_suggest_boxing_note)]
677 #[multipart_suggestion(
678 hir_typeck_suggest_boxing_when_appropriate,
679 applicability = "machine-applicable"
680 )]
681 ExprFieldShorthand {
682 #[suggestion_part(code = "{ident}: Box::new(")]
683 start: Span,
684 #[suggestion_part(code = ")")]
685 end: Span,
686 ident: Ident,
687 },
688 #[note(hir_typeck_suggest_boxing_note)]
689 #[multipart_suggestion(
690 hir_typeck_suggest_boxing_when_appropriate,
691 applicability = "machine-applicable"
692 )]
693 Other {
694 #[suggestion_part(code = "Box::new(")]
695 start: Span,
696 #[suggestion_part(code = ")")]
697 end: Span,
698 },
699}
700
701#[derive(Subdiagnostic)]
702#[suggestion(
703 hir_typeck_suggest_ptr_null_mut,
704 applicability = "maybe-incorrect",
705 style = "verbose",
706 code = "core::ptr::null_mut()"
707)]
708pub(crate) struct SuggestPtrNullMut {
709 #[primary_span]
710 pub span: Span,
711}
712
713#[derive(LintDiagnostic)]
714#[diag(hir_typeck_trivial_cast)]
715#[help]
716pub(crate) struct TrivialCast<'tcx> {
717 pub numeric: bool,
718 pub expr_ty: Ty<'tcx>,
719 pub cast_ty: Ty<'tcx>,
720}
721
722pub(crate) struct BreakNonLoop<'a> {
723 pub span: Span,
724 pub head: Option<Span>,
725 pub kind: &'a str,
726 pub suggestion: String,
727 pub loop_label: Option<Label>,
728 pub break_label: Option<Label>,
729 pub break_expr_kind: &'a ExprKind<'a>,
730 pub break_expr_span: Span,
731}
732
733impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
734 #[track_caller]
735 fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
736 let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop);
737 diag.span(self.span);
738 diag.code(E0571);
739 diag.arg("kind", self.kind);
740 diag.span_label(self.span, fluent::hir_typeck_label);
741 if let Some(head) = self.head {
742 diag.span_label(head, fluent::hir_typeck_label2);
743 }
744 diag.span_suggestion(
745 self.span,
746 fluent::hir_typeck_suggestion,
747 self.suggestion,
748 Applicability::MaybeIncorrect,
749 );
750 if let (Some(label), None) = (self.loop_label, self.break_label) {
751 match self.break_expr_kind {
752 ExprKind::Path(hir::QPath::Resolved(
753 None,
754 hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
755 )) if label.ident.to_string() == format!("'{}", segment.ident) => {
756 diag.downgrade_to_delayed_bug();
760 }
761 _ => {
762 diag.span_suggestion(
763 self.break_expr_span,
764 fluent::hir_typeck_break_expr_suggestion,
765 label.ident,
766 Applicability::MaybeIncorrect,
767 );
768 }
769 }
770 }
771 diag
772 }
773}
774
775#[derive(Diagnostic)]
776#[diag(hir_typeck_continue_labeled_block, code = E0696)]
777pub(crate) struct ContinueLabeledBlock {
778 #[primary_span]
779 #[label]
780 pub span: Span,
781 #[label(hir_typeck_block_label)]
782 pub block_span: Span,
783}
784
785#[derive(Diagnostic)]
786#[diag(hir_typeck_break_inside_closure, code = E0267)]
787pub(crate) struct BreakInsideClosure<'a> {
788 #[primary_span]
789 #[label]
790 pub span: Span,
791 #[label(hir_typeck_closure_label)]
792 pub closure_span: Span,
793 pub name: &'a str,
794}
795
796#[derive(Diagnostic)]
797#[diag(hir_typeck_break_inside_coroutine, code = E0267)]
798pub(crate) struct BreakInsideCoroutine<'a> {
799 #[primary_span]
800 #[label]
801 pub span: Span,
802 #[label(hir_typeck_coroutine_label)]
803 pub coroutine_span: Span,
804 pub name: &'a str,
805 pub kind: &'a str,
806 pub source: &'a str,
807}
808
809#[derive(Diagnostic)]
810#[diag(hir_typeck_outside_loop, code = E0268)]
811pub(crate) struct OutsideLoop<'a> {
812 #[primary_span]
813 #[label]
814 pub spans: Vec<Span>,
815 pub name: &'a str,
816 pub is_break: bool,
817 #[subdiagnostic]
818 pub suggestion: Option<OutsideLoopSuggestion>,
819}
820#[derive(Subdiagnostic)]
821#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")]
822pub(crate) struct OutsideLoopSuggestion {
823 #[suggestion_part(code = "'block: ")]
824 pub block_span: Span,
825 #[suggestion_part(code = " 'block")]
826 pub break_spans: Vec<Span>,
827}
828
829#[derive(Diagnostic)]
830#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)]
831pub(crate) struct UnlabeledInLabeledBlock<'a> {
832 #[primary_span]
833 #[label]
834 pub span: Span,
835 pub cf_type: &'a str,
836}
837
838#[derive(Diagnostic)]
839#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)]
840pub(crate) struct UnlabeledCfInWhileCondition<'a> {
841 #[primary_span]
842 #[label]
843 pub span: Span,
844 pub cf_type: &'a str,
845}
846
847#[derive(Diagnostic)]
848#[diag(hir_typeck_no_associated_item, code = E0599)]
849pub(crate) struct NoAssociatedItem {
850 #[primary_span]
851 pub span: Span,
852 pub item_kind: &'static str,
853 pub item_ident: Ident,
854 pub ty_prefix: Cow<'static, str>,
855 pub ty_str: String,
856 pub trait_missing_method: bool,
857}
858
859#[derive(Subdiagnostic)]
860#[note(hir_typeck_candidate_trait_note)]
861pub(crate) struct CandidateTraitNote {
862 #[primary_span]
863 pub span: Span,
864 pub trait_name: String,
865 pub item_name: Ident,
866 pub action_or_ty: String,
867}
868
869#[derive(Diagnostic)]
870#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
871pub(crate) struct CannotCastToBool<'tcx> {
872 #[primary_span]
873 pub span: Span,
874 pub expr_ty: Ty<'tcx>,
875 #[subdiagnostic]
876 pub help: CannotCastToBoolHelp,
877}
878
879#[derive(Diagnostic)]
880#[diag(hir_typeck_cast_enum_drop)]
881pub(crate) struct CastEnumDrop<'tcx> {
882 #[primary_span]
883 pub span: Span,
884 pub expr_ty: Ty<'tcx>,
885 pub cast_ty: Ty<'tcx>,
886}
887
888#[derive(Diagnostic)]
889#[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
890pub(crate) struct CastUnknownPointer {
891 #[primary_span]
892 pub span: Span,
893 pub to: bool,
894 #[subdiagnostic]
895 pub sub: CastUnknownPointerSub,
896}
897
898pub(crate) enum CastUnknownPointerSub {
899 To(Span),
900 From(Span),
901}
902
903impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
904 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
905 match self {
906 CastUnknownPointerSub::To(span) => {
907 let msg = diag.eagerly_translate(fluent::hir_typeck_label_to);
908 diag.span_label(span, msg);
909 let msg = diag.eagerly_translate(fluent::hir_typeck_note);
910 diag.note(msg);
911 }
912 CastUnknownPointerSub::From(span) => {
913 let msg = diag.eagerly_translate(fluent::hir_typeck_label_from);
914 diag.span_label(span, msg);
915 }
916 }
917 }
918}
919
920#[derive(Subdiagnostic)]
921pub(crate) enum CannotCastToBoolHelp {
922 #[suggestion(
923 hir_typeck_suggestion,
924 applicability = "machine-applicable",
925 code = " != 0",
926 style = "verbose"
927 )]
928 Numeric(#[primary_span] Span),
929 #[label(hir_typeck_label)]
930 Unsupported(#[primary_span] Span),
931}
932
933#[derive(Diagnostic)]
934#[diag(hir_typeck_ctor_is_private, code = E0603)]
935pub(crate) struct CtorIsPrivate {
936 #[primary_span]
937 pub span: Span,
938 pub def: String,
939}
940
941#[derive(Subdiagnostic)]
942#[note(hir_typeck_deref_is_empty)]
943pub(crate) struct DerefImplsIsEmpty<'tcx> {
944 #[primary_span]
945 pub span: Span,
946 pub deref_ty: Ty<'tcx>,
947}
948
949#[derive(Subdiagnostic)]
950#[multipart_suggestion(
951 hir_typeck_convert_using_method,
952 applicability = "machine-applicable",
953 style = "verbose"
954)]
955pub(crate) struct SuggestConvertViaMethod<'tcx> {
956 #[suggestion_part(code = "{sugg}")]
957 pub span: Span,
958 #[suggestion_part(code = "")]
959 pub borrow_removal_span: Option<Span>,
960 pub sugg: String,
961 pub expected: Ty<'tcx>,
962 pub found: Ty<'tcx>,
963}
964
965#[derive(Subdiagnostic)]
966#[note(hir_typeck_note_caller_chooses_ty_for_ty_param)]
967pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> {
968 pub ty_param_name: Symbol,
969 pub found_ty: Ty<'tcx>,
970}
971
972#[derive(Subdiagnostic)]
973pub(crate) enum SuggestBoxingForReturnImplTrait {
974 #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")]
975 ChangeReturnType {
976 #[suggestion_part(code = "Box<dyn")]
977 start_sp: Span,
978 #[suggestion_part(code = ">")]
979 end_sp: Span,
980 },
981 #[multipart_suggestion(hir_typeck_rpit_box_return_expr, applicability = "maybe-incorrect")]
982 BoxReturnExpr {
983 #[suggestion_part(code = "Box::new(")]
984 starts: Vec<Span>,
985 #[suggestion_part(code = ")")]
986 ends: Vec<Span>,
987 },
988}
989
990#[derive(Diagnostic)]
991#[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)]
992pub(crate) struct SelfCtorFromOuterItem {
993 #[primary_span]
994 pub span: Span,
995 #[label]
996 pub impl_span: Span,
997 #[subdiagnostic]
998 pub sugg: Option<ReplaceWithName>,
999}
1000
1001#[derive(LintDiagnostic)]
1002#[diag(hir_typeck_self_ctor_from_outer_item)]
1003pub(crate) struct SelfCtorFromOuterItemLint {
1004 #[label]
1005 pub impl_span: Span,
1006 #[subdiagnostic]
1007 pub sugg: Option<ReplaceWithName>,
1008}
1009
1010#[derive(Subdiagnostic)]
1011#[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")]
1012pub(crate) struct ReplaceWithName {
1013 #[primary_span]
1014 pub span: Span,
1015 pub name: String,
1016}
1017
1018#[derive(Diagnostic)]
1019#[diag(hir_typeck_cast_thin_pointer_to_wide_pointer, code = E0607)]
1020pub(crate) struct CastThinPointerToWidePointer<'tcx> {
1021 #[primary_span]
1022 pub span: Span,
1023 pub expr_ty: Ty<'tcx>,
1024 pub cast_ty: Ty<'tcx>,
1025 #[note(hir_typeck_teach_help)]
1026 pub(crate) teach: bool,
1027}
1028
1029#[derive(Diagnostic)]
1030#[diag(hir_typeck_pass_to_variadic_function, code = E0617)]
1031pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
1032 #[primary_span]
1033 pub span: Span,
1034 pub ty: Ty<'tcx>,
1035 pub cast_ty: &'a str,
1036 #[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")]
1037 pub sugg_span: Span,
1038 #[note(hir_typeck_teach_help)]
1039 pub(crate) teach: bool,
1040}
1041
1042#[derive(Diagnostic)]
1043#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)]
1044#[help]
1045#[note]
1046pub(crate) struct PassFnItemToVariadicFunction {
1047 #[primary_span]
1048 pub span: Span,
1049 #[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")]
1050 pub sugg_span: Span,
1051 pub replace: String,
1052}
1053
1054#[derive(Subdiagnostic)]
1055#[suggestion(
1056 hir_typeck_replace_comma_with_semicolon,
1057 applicability = "machine-applicable",
1058 style = "verbose",
1059 code = "; "
1060)]
1061pub(crate) struct ReplaceCommaWithSemicolon {
1062 #[primary_span]
1063 pub comma_span: Span,
1064 pub descr: &'static str,
1065}
1066
1067#[derive(LintDiagnostic)]
1068#[diag(hir_typeck_supertrait_item_shadowing)]
1069pub(crate) struct SupertraitItemShadowing {
1070 pub item: Symbol,
1071 pub subtrait: Symbol,
1072 #[subdiagnostic]
1073 pub shadower: SupertraitItemShadower,
1074 #[subdiagnostic]
1075 pub shadowee: SupertraitItemShadowee,
1076}
1077
1078#[derive(Subdiagnostic)]
1079#[note(hir_typeck_supertrait_item_shadower)]
1080pub(crate) struct SupertraitItemShadower {
1081 pub subtrait: Symbol,
1082 #[primary_span]
1083 pub span: Span,
1084}
1085
1086#[derive(Subdiagnostic)]
1087pub(crate) enum SupertraitItemShadowee {
1088 #[note(hir_typeck_supertrait_item_shadowee)]
1089 Labeled {
1090 #[primary_span]
1091 span: Span,
1092 supertrait: Symbol,
1093 },
1094 #[note(hir_typeck_supertrait_item_multiple_shadowee)]
1095 Several {
1096 #[primary_span]
1097 spans: MultiSpan,
1098 traits: DiagSymbolList,
1099 },
1100}
1101
1102#[derive(Diagnostic)]
1103#[diag(hir_typeck_register_type_unstable)]
1104pub(crate) struct RegisterTypeUnstable<'a> {
1105 #[primary_span]
1106 pub span: Span,
1107 pub ty: Ty<'a>,
1108}
1109
1110#[derive(Diagnostic)]
1111#[diag(hir_typeck_naked_asm_outside_naked_fn)]
1112pub(crate) struct NakedAsmOutsideNakedFn {
1113 #[primary_span]
1114 pub span: Span,
1115}
1116
1117#[derive(Diagnostic)]
1118#[diag(hir_typeck_no_patterns)]
1119pub(crate) struct NoPatterns {
1120 #[primary_span]
1121 pub span: Span,
1122}
1123
1124#[derive(Diagnostic)]
1125#[diag(hir_typeck_params_not_allowed)]
1126#[help]
1127pub(crate) struct ParamsNotAllowed {
1128 #[primary_span]
1129 pub span: Span,
1130}
1131
1132pub(crate) struct NakedFunctionsAsmBlock {
1133 pub span: Span,
1134 pub multiple_asms: Vec<Span>,
1135 pub non_asms: Vec<Span>,
1136}
1137
1138impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
1139 #[track_caller]
1140 fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
1141 let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block);
1142 diag.span(self.span);
1143 diag.code(E0787);
1144 for span in self.multiple_asms.iter() {
1145 diag.span_label(*span, fluent::hir_typeck_label_multiple_asm);
1146 }
1147 for span in self.non_asms.iter() {
1148 diag.span_label(*span, fluent::hir_typeck_label_non_asm);
1149 }
1150 diag
1151 }
1152}
1153
1154#[derive(Diagnostic)]
1155#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)]
1156pub(crate) struct NakedFunctionsMustNakedAsm {
1157 #[primary_span]
1158 #[label]
1159 pub span: Span,
1160}
1161
1162#[derive(Diagnostic)]
1163#[diag(hir_typeck_abi_cannot_be_called)]
1164pub(crate) struct AbiCannotBeCalled {
1165 #[primary_span]
1166 #[note]
1167 pub span: Span,
1168 pub abi: ExternAbi,
1169}
1170
1171#[derive(Diagnostic)]
1172#[diag(hir_typeck_const_continue_bad_label)]
1173pub(crate) struct ConstContinueBadLabel {
1174 #[primary_span]
1175 pub span: Span,
1176}