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_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                    // This error is redundant, we will have already emitted a
757                    // suggestion to use the label when `segment` wasn't found
758                    // (hence the `Res::Err` check).
759                    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}