rustc_hir_typeck/
errors.rs

1//! Errors emitted by `rustc_hir_typeck`.
2
3use 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    /// Span of the LHS of the range
326    pub expr_span: Span,
327    /// Span of the `..RHS` part of the range
328    pub fru_span: Span,
329    /// Rendered expression of the RHS of the range
330    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        // Only explain that `a ..b` is a range if it's split up
338        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    // FIXME: #114050
570    // #[suggestion(
571    //     hir_typeck_option_result_asref,
572    //     code = ".as_ref()",
573    //     style = "verbose",
574    //     applicability = "machine-applicable"
575    // )]
576    // AsRef {
577    //     #[primary_span]
578    //     span: Span,
579    //     def_path: String,
580    //     expected_ty: Ty<'tcx>,
581    //     expr_ty: Ty<'tcx>,
582    // },
583}
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_union_pat_multiple_fields)]
610pub(crate) struct UnionPatMultipleFields {
611    #[primary_span]
612    pub span: Span,
613}
614
615#[derive(Diagnostic)]
616#[diag(hir_typeck_union_pat_dotdot)]
617pub(crate) struct UnionPatDotDot {
618    #[primary_span]
619    pub span: Span,
620}
621
622#[derive(Subdiagnostic)]
623#[multipart_suggestion(
624    hir_typeck_use_is_empty,
625    applicability = "maybe-incorrect",
626    style = "verbose"
627)]
628pub(crate) struct UseIsEmpty<'tcx> {
629    #[suggestion_part(code = "!")]
630    pub lo: Span,
631    #[suggestion_part(code = ".is_empty()")]
632    pub hi: Span,
633    pub expr_ty: Ty<'tcx>,
634}
635
636#[derive(Diagnostic)]
637#[diag(hir_typeck_arg_mismatch_indeterminate)]
638pub(crate) struct ArgMismatchIndeterminate {
639    #[primary_span]
640    pub span: Span,
641}
642
643#[derive(Subdiagnostic)]
644pub(crate) enum SuggestBoxing {
645    #[note(hir_typeck_suggest_boxing_note)]
646    #[multipart_suggestion(
647        hir_typeck_suggest_boxing_when_appropriate,
648        applicability = "machine-applicable"
649    )]
650    Unit {
651        #[suggestion_part(code = "Box::new(())")]
652        start: Span,
653        #[suggestion_part(code = "")]
654        end: Span,
655    },
656    #[note(hir_typeck_suggest_boxing_note)]
657    AsyncBody,
658    #[note(hir_typeck_suggest_boxing_note)]
659    #[multipart_suggestion(
660        hir_typeck_suggest_boxing_when_appropriate,
661        applicability = "machine-applicable"
662    )]
663    ExprFieldShorthand {
664        #[suggestion_part(code = "{ident}: Box::new(")]
665        start: Span,
666        #[suggestion_part(code = ")")]
667        end: Span,
668        ident: Ident,
669    },
670    #[note(hir_typeck_suggest_boxing_note)]
671    #[multipart_suggestion(
672        hir_typeck_suggest_boxing_when_appropriate,
673        applicability = "machine-applicable"
674    )]
675    Other {
676        #[suggestion_part(code = "Box::new(")]
677        start: Span,
678        #[suggestion_part(code = ")")]
679        end: Span,
680    },
681}
682
683#[derive(Subdiagnostic)]
684#[suggestion(
685    hir_typeck_suggest_ptr_null_mut,
686    applicability = "maybe-incorrect",
687    style = "verbose",
688    code = "core::ptr::null_mut()"
689)]
690pub(crate) struct SuggestPtrNullMut {
691    #[primary_span]
692    pub span: Span,
693}
694
695#[derive(LintDiagnostic)]
696#[diag(hir_typeck_trivial_cast)]
697#[help]
698pub(crate) struct TrivialCast<'tcx> {
699    pub numeric: bool,
700    pub expr_ty: Ty<'tcx>,
701    pub cast_ty: Ty<'tcx>,
702}
703
704pub(crate) struct BreakNonLoop<'a> {
705    pub span: Span,
706    pub head: Option<Span>,
707    pub kind: &'a str,
708    pub suggestion: String,
709    pub loop_label: Option<Label>,
710    pub break_label: Option<Label>,
711    pub break_expr_kind: &'a ExprKind<'a>,
712    pub break_expr_span: Span,
713}
714
715impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> {
716    #[track_caller]
717    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
718        let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop);
719        diag.span(self.span);
720        diag.code(E0571);
721        diag.arg("kind", self.kind);
722        diag.span_label(self.span, fluent::hir_typeck_label);
723        if let Some(head) = self.head {
724            diag.span_label(head, fluent::hir_typeck_label2);
725        }
726        diag.span_suggestion(
727            self.span,
728            fluent::hir_typeck_suggestion,
729            self.suggestion,
730            Applicability::MaybeIncorrect,
731        );
732        if let (Some(label), None) = (self.loop_label, self.break_label) {
733            match self.break_expr_kind {
734                ExprKind::Path(hir::QPath::Resolved(
735                    None,
736                    hir::Path { segments: [segment], res: hir::def::Res::Err, .. },
737                )) if label.ident.to_string() == format!("'{}", segment.ident) => {
738                    // This error is redundant, we will have already emitted a
739                    // suggestion to use the label when `segment` wasn't found
740                    // (hence the `Res::Err` check).
741                    diag.downgrade_to_delayed_bug();
742                }
743                _ => {
744                    diag.span_suggestion(
745                        self.break_expr_span,
746                        fluent::hir_typeck_break_expr_suggestion,
747                        label.ident,
748                        Applicability::MaybeIncorrect,
749                    );
750                }
751            }
752        }
753        diag
754    }
755}
756
757#[derive(Diagnostic)]
758#[diag(hir_typeck_continue_labeled_block, code = E0696)]
759pub(crate) struct ContinueLabeledBlock {
760    #[primary_span]
761    #[label]
762    pub span: Span,
763    #[label(hir_typeck_block_label)]
764    pub block_span: Span,
765}
766
767#[derive(Diagnostic)]
768#[diag(hir_typeck_break_inside_closure, code = E0267)]
769pub(crate) struct BreakInsideClosure<'a> {
770    #[primary_span]
771    #[label]
772    pub span: Span,
773    #[label(hir_typeck_closure_label)]
774    pub closure_span: Span,
775    pub name: &'a str,
776}
777
778#[derive(Diagnostic)]
779#[diag(hir_typeck_break_inside_coroutine, code = E0267)]
780pub(crate) struct BreakInsideCoroutine<'a> {
781    #[primary_span]
782    #[label]
783    pub span: Span,
784    #[label(hir_typeck_coroutine_label)]
785    pub coroutine_span: Span,
786    pub name: &'a str,
787    pub kind: &'a str,
788    pub source: &'a str,
789}
790
791#[derive(Diagnostic)]
792#[diag(hir_typeck_outside_loop, code = E0268)]
793pub(crate) struct OutsideLoop<'a> {
794    #[primary_span]
795    #[label]
796    pub spans: Vec<Span>,
797    pub name: &'a str,
798    pub is_break: bool,
799    #[subdiagnostic]
800    pub suggestion: Option<OutsideLoopSuggestion>,
801}
802#[derive(Subdiagnostic)]
803#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")]
804pub(crate) struct OutsideLoopSuggestion {
805    #[suggestion_part(code = "'block: ")]
806    pub block_span: Span,
807    #[suggestion_part(code = " 'block")]
808    pub break_spans: Vec<Span>,
809}
810
811#[derive(Diagnostic)]
812#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)]
813pub(crate) struct UnlabeledInLabeledBlock<'a> {
814    #[primary_span]
815    #[label]
816    pub span: Span,
817    pub cf_type: &'a str,
818}
819
820#[derive(Diagnostic)]
821#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)]
822pub(crate) struct UnlabeledCfInWhileCondition<'a> {
823    #[primary_span]
824    #[label]
825    pub span: Span,
826    pub cf_type: &'a str,
827}
828
829#[derive(Diagnostic)]
830#[diag(hir_typeck_no_associated_item, code = E0599)]
831pub(crate) struct NoAssociatedItem {
832    #[primary_span]
833    pub span: Span,
834    pub item_kind: &'static str,
835    pub item_ident: Ident,
836    pub ty_prefix: Cow<'static, str>,
837    pub ty_str: String,
838    pub trait_missing_method: bool,
839}
840
841#[derive(Subdiagnostic)]
842#[note(hir_typeck_candidate_trait_note)]
843pub(crate) struct CandidateTraitNote {
844    #[primary_span]
845    pub span: Span,
846    pub trait_name: String,
847    pub item_name: Ident,
848    pub action_or_ty: String,
849}
850
851#[derive(Diagnostic)]
852#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
853pub(crate) struct CannotCastToBool<'tcx> {
854    #[primary_span]
855    pub span: Span,
856    pub expr_ty: Ty<'tcx>,
857    #[subdiagnostic]
858    pub help: CannotCastToBoolHelp,
859}
860
861#[derive(Diagnostic)]
862#[diag(hir_typeck_cast_enum_drop)]
863pub(crate) struct CastEnumDrop<'tcx> {
864    #[primary_span]
865    pub span: Span,
866    pub expr_ty: Ty<'tcx>,
867    pub cast_ty: Ty<'tcx>,
868}
869
870#[derive(Diagnostic)]
871#[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
872pub(crate) struct CastUnknownPointer {
873    #[primary_span]
874    pub span: Span,
875    pub to: bool,
876    #[subdiagnostic]
877    pub sub: CastUnknownPointerSub,
878}
879
880pub(crate) enum CastUnknownPointerSub {
881    To(Span),
882    From(Span),
883}
884
885impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
886    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
887        match self {
888            CastUnknownPointerSub::To(span) => {
889                let msg = diag.eagerly_translate(fluent::hir_typeck_label_to);
890                diag.span_label(span, msg);
891                let msg = diag.eagerly_translate(fluent::hir_typeck_note);
892                diag.note(msg);
893            }
894            CastUnknownPointerSub::From(span) => {
895                let msg = diag.eagerly_translate(fluent::hir_typeck_label_from);
896                diag.span_label(span, msg);
897            }
898        }
899    }
900}
901
902#[derive(Subdiagnostic)]
903pub(crate) enum CannotCastToBoolHelp {
904    #[suggestion(
905        hir_typeck_suggestion,
906        applicability = "machine-applicable",
907        code = " != 0",
908        style = "verbose"
909    )]
910    Numeric(#[primary_span] Span),
911    #[label(hir_typeck_label)]
912    Unsupported(#[primary_span] Span),
913}
914
915#[derive(Diagnostic)]
916#[diag(hir_typeck_ctor_is_private, code = E0603)]
917pub(crate) struct CtorIsPrivate {
918    #[primary_span]
919    pub span: Span,
920    pub def: String,
921}
922
923#[derive(Subdiagnostic)]
924#[note(hir_typeck_deref_is_empty)]
925pub(crate) struct DerefImplsIsEmpty<'tcx> {
926    #[primary_span]
927    pub span: Span,
928    pub deref_ty: Ty<'tcx>,
929}
930
931#[derive(Subdiagnostic)]
932#[multipart_suggestion(
933    hir_typeck_convert_using_method,
934    applicability = "machine-applicable",
935    style = "verbose"
936)]
937pub(crate) struct SuggestConvertViaMethod<'tcx> {
938    #[suggestion_part(code = "{sugg}")]
939    pub span: Span,
940    #[suggestion_part(code = "")]
941    pub borrow_removal_span: Option<Span>,
942    pub sugg: String,
943    pub expected: Ty<'tcx>,
944    pub found: Ty<'tcx>,
945}
946
947#[derive(Subdiagnostic)]
948#[note(hir_typeck_note_caller_chooses_ty_for_ty_param)]
949pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> {
950    pub ty_param_name: Symbol,
951    pub found_ty: Ty<'tcx>,
952}
953
954#[derive(Subdiagnostic)]
955pub(crate) enum SuggestBoxingForReturnImplTrait {
956    #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")]
957    ChangeReturnType {
958        #[suggestion_part(code = "Box<dyn")]
959        start_sp: Span,
960        #[suggestion_part(code = ">")]
961        end_sp: Span,
962    },
963    #[multipart_suggestion(hir_typeck_rpit_box_return_expr, applicability = "maybe-incorrect")]
964    BoxReturnExpr {
965        #[suggestion_part(code = "Box::new(")]
966        starts: Vec<Span>,
967        #[suggestion_part(code = ")")]
968        ends: Vec<Span>,
969    },
970}
971
972#[derive(Diagnostic)]
973#[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)]
974pub(crate) struct SelfCtorFromOuterItem {
975    #[primary_span]
976    pub span: Span,
977    #[label]
978    pub impl_span: Span,
979    #[subdiagnostic]
980    pub sugg: Option<ReplaceWithName>,
981}
982
983#[derive(LintDiagnostic)]
984#[diag(hir_typeck_self_ctor_from_outer_item)]
985pub(crate) struct SelfCtorFromOuterItemLint {
986    #[label]
987    pub impl_span: Span,
988    #[subdiagnostic]
989    pub sugg: Option<ReplaceWithName>,
990}
991
992#[derive(Subdiagnostic)]
993#[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")]
994pub(crate) struct ReplaceWithName {
995    #[primary_span]
996    pub span: Span,
997    pub name: String,
998}
999
1000#[derive(Diagnostic)]
1001#[diag(hir_typeck_cast_thin_pointer_to_wide_pointer, code = E0607)]
1002pub(crate) struct CastThinPointerToWidePointer<'tcx> {
1003    #[primary_span]
1004    pub span: Span,
1005    pub expr_ty: Ty<'tcx>,
1006    pub cast_ty: Ty<'tcx>,
1007    #[note(hir_typeck_teach_help)]
1008    pub(crate) teach: bool,
1009}
1010
1011#[derive(Diagnostic)]
1012#[diag(hir_typeck_pass_to_variadic_function, code = E0617)]
1013pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
1014    #[primary_span]
1015    pub span: Span,
1016    pub ty: Ty<'tcx>,
1017    pub cast_ty: &'a str,
1018    #[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")]
1019    pub sugg_span: Span,
1020    #[note(hir_typeck_teach_help)]
1021    pub(crate) teach: bool,
1022}
1023
1024#[derive(Diagnostic)]
1025#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)]
1026#[help]
1027#[note]
1028pub(crate) struct PassFnItemToVariadicFunction {
1029    #[primary_span]
1030    pub span: Span,
1031    #[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")]
1032    pub sugg_span: Span,
1033    pub replace: String,
1034}
1035
1036#[derive(Subdiagnostic)]
1037#[suggestion(
1038    hir_typeck_replace_comma_with_semicolon,
1039    applicability = "machine-applicable",
1040    style = "verbose",
1041    code = "; "
1042)]
1043pub(crate) struct ReplaceCommaWithSemicolon {
1044    #[primary_span]
1045    pub comma_span: Span,
1046    pub descr: &'static str,
1047}
1048
1049#[derive(LintDiagnostic)]
1050#[diag(hir_typeck_supertrait_item_shadowing)]
1051pub(crate) struct SupertraitItemShadowing {
1052    pub item: Symbol,
1053    pub subtrait: Symbol,
1054    #[subdiagnostic]
1055    pub shadower: SupertraitItemShadower,
1056    #[subdiagnostic]
1057    pub shadowee: SupertraitItemShadowee,
1058}
1059
1060#[derive(Subdiagnostic)]
1061#[note(hir_typeck_supertrait_item_shadower)]
1062pub(crate) struct SupertraitItemShadower {
1063    pub subtrait: Symbol,
1064    #[primary_span]
1065    pub span: Span,
1066}
1067
1068#[derive(Subdiagnostic)]
1069pub(crate) enum SupertraitItemShadowee {
1070    #[note(hir_typeck_supertrait_item_shadowee)]
1071    Labeled {
1072        #[primary_span]
1073        span: Span,
1074        supertrait: Symbol,
1075    },
1076    #[note(hir_typeck_supertrait_item_multiple_shadowee)]
1077    Several {
1078        #[primary_span]
1079        spans: MultiSpan,
1080        traits: DiagSymbolList,
1081    },
1082}
1083
1084#[derive(Diagnostic)]
1085#[diag(hir_typeck_register_type_unstable)]
1086pub(crate) struct RegisterTypeUnstable<'a> {
1087    #[primary_span]
1088    pub span: Span,
1089    pub ty: Ty<'a>,
1090}
1091
1092#[derive(Diagnostic)]
1093#[diag(hir_typeck_naked_asm_outside_naked_fn)]
1094pub(crate) struct NakedAsmOutsideNakedFn {
1095    #[primary_span]
1096    pub span: Span,
1097}
1098
1099#[derive(Diagnostic)]
1100#[diag(hir_typeck_no_patterns)]
1101pub(crate) struct NoPatterns {
1102    #[primary_span]
1103    pub span: Span,
1104}
1105
1106#[derive(Diagnostic)]
1107#[diag(hir_typeck_params_not_allowed)]
1108#[help]
1109pub(crate) struct ParamsNotAllowed {
1110    #[primary_span]
1111    pub span: Span,
1112}
1113
1114pub(crate) struct NakedFunctionsAsmBlock {
1115    pub span: Span,
1116    pub multiple_asms: Vec<Span>,
1117    pub non_asms: Vec<Span>,
1118}
1119
1120impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
1121    #[track_caller]
1122    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
1123        let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block);
1124        diag.span(self.span);
1125        diag.code(E0787);
1126        for span in self.multiple_asms.iter() {
1127            diag.span_label(*span, fluent::hir_typeck_label_multiple_asm);
1128        }
1129        for span in self.non_asms.iter() {
1130            diag.span_label(*span, fluent::hir_typeck_label_non_asm);
1131        }
1132        diag
1133    }
1134}
1135
1136#[derive(Diagnostic)]
1137#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)]
1138pub(crate) struct NakedFunctionsMustNakedAsm {
1139    #[primary_span]
1140    #[label]
1141    pub span: Span,
1142}
1143
1144#[derive(Diagnostic)]
1145#[diag(hir_typeck_abi_cannot_be_called)]
1146pub(crate) struct AbiCannotBeCalled {
1147    #[primary_span]
1148    #[note]
1149    pub span: Span,
1150    pub abi: ExternAbi,
1151}
1152
1153#[derive(Diagnostic)]
1154#[diag(hir_typeck_const_continue_bad_label)]
1155pub(crate) struct ConstContinueBadLabel {
1156    #[primary_span]
1157    pub span: Span,
1158}