rustc_hir_typeck/
errors.rs

1//! Errors emitted by `rustc_hir_typeck`.
2
3use std::borrow::Cow;
4
5use rustc_errors::codes::*;
6use rustc_errors::{
7    Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
8    Subdiagnostic,
9};
10use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
11use rustc_middle::ty::{self, Ty};
12use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
13use rustc_span::{Ident, Span, Symbol};
14
15use crate::fluent_generated as fluent;
16
17#[derive(Diagnostic)]
18#[diag(hir_typeck_base_expression_double_dot, code = E0797)]
19pub(crate) struct BaseExpressionDoubleDot {
20    #[primary_span]
21    pub span: Span,
22    #[suggestion(
23        hir_typeck_base_expression_double_dot_enable_default_field_values,
24        code = "#![feature(default_field_values)]\n",
25        applicability = "machine-applicable",
26        style = "verbose"
27    )]
28    pub default_field_values_suggestion: Option<Span>,
29    #[subdiagnostic]
30    pub default_field_values_help: Option<BaseExpressionDoubleDotEnableDefaultFieldValues>,
31    #[subdiagnostic]
32    pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
33    #[subdiagnostic]
34    pub remove_dots: Option<BaseExpressionDoubleDotRemove>,
35}
36
37#[derive(Subdiagnostic)]
38#[suggestion(
39    hir_typeck_base_expression_double_dot_remove,
40    code = "",
41    applicability = "machine-applicable",
42    style = "verbose"
43)]
44pub(crate) struct BaseExpressionDoubleDotRemove {
45    #[primary_span]
46    pub span: Span,
47}
48
49#[derive(Subdiagnostic)]
50#[suggestion(
51    hir_typeck_base_expression_double_dot_add_expr,
52    code = "/* expr */",
53    applicability = "has-placeholders",
54    style = "verbose"
55)]
56pub(crate) struct BaseExpressionDoubleDotAddExpr {
57    #[primary_span]
58    pub span: Span,
59}
60
61#[derive(Subdiagnostic)]
62#[help(hir_typeck_base_expression_double_dot_enable_default_field_values)]
63pub(crate) struct BaseExpressionDoubleDotEnableDefaultFieldValues;
64
65#[derive(Diagnostic)]
66#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
67pub(crate) struct FieldMultiplySpecifiedInInitializer {
68    #[primary_span]
69    #[label]
70    pub span: Span,
71    #[label(hir_typeck_previous_use_label)]
72    pub prev_span: Span,
73    pub ident: Ident,
74}
75
76#[derive(Diagnostic)]
77#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
78pub(crate) struct ReturnStmtOutsideOfFnBody {
79    #[primary_span]
80    pub span: Span,
81    #[label(hir_typeck_encl_body_label)]
82    pub encl_body_span: Option<Span>,
83    #[label(hir_typeck_encl_fn_label)]
84    pub encl_fn_span: Option<Span>,
85    pub statement_kind: ReturnLikeStatementKind,
86}
87
88pub(crate) enum ReturnLikeStatementKind {
89    Return,
90    Become,
91}
92
93impl IntoDiagArg for ReturnLikeStatementKind {
94    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
95        let kind = match self {
96            Self::Return => "return",
97            Self::Become => "become",
98        }
99        .into();
100
101        DiagArgValue::Str(kind)
102    }
103}
104
105#[derive(Diagnostic)]
106#[diag(hir_typeck_rustcall_incorrect_args)]
107pub(crate) struct RustCallIncorrectArgs {
108    #[primary_span]
109    pub span: Span,
110}
111
112#[derive(Diagnostic)]
113#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
114pub(crate) struct YieldExprOutsideOfCoroutine {
115    #[primary_span]
116    pub span: Span,
117}
118
119#[derive(Diagnostic)]
120#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
121pub(crate) struct StructExprNonExhaustive {
122    #[primary_span]
123    pub span: Span,
124    pub what: &'static str,
125}
126
127#[derive(Diagnostic)]
128#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
129pub(crate) struct FunctionalRecordUpdateOnNonStruct {
130    #[primary_span]
131    pub span: Span,
132}
133
134#[derive(Diagnostic)]
135#[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
136pub(crate) struct AddressOfTemporaryTaken {
137    #[primary_span]
138    #[label]
139    pub span: Span,
140}
141
142#[derive(Subdiagnostic)]
143pub(crate) enum AddReturnTypeSuggestion {
144    #[suggestion(
145        hir_typeck_add_return_type_add,
146        code = " -> {found}",
147        applicability = "machine-applicable"
148    )]
149    Add {
150        #[primary_span]
151        span: Span,
152        found: String,
153    },
154    #[suggestion(
155        hir_typeck_add_return_type_missing_here,
156        code = " -> _",
157        applicability = "has-placeholders"
158    )]
159    MissingHere {
160        #[primary_span]
161        span: Span,
162    },
163}
164
165#[derive(Subdiagnostic)]
166pub(crate) enum ExpectedReturnTypeLabel<'tcx> {
167    #[label(hir_typeck_expected_default_return_type)]
168    Unit {
169        #[primary_span]
170        span: Span,
171    },
172    #[label(hir_typeck_expected_return_type)]
173    Other {
174        #[primary_span]
175        span: Span,
176        expected: Ty<'tcx>,
177    },
178}
179
180#[derive(Diagnostic)]
181#[diag(hir_typeck_explicit_destructor, code = E0040)]
182pub(crate) struct ExplicitDestructorCall {
183    #[primary_span]
184    #[label]
185    pub span: Span,
186    #[subdiagnostic]
187    pub sugg: ExplicitDestructorCallSugg,
188}
189
190#[derive(Subdiagnostic)]
191pub(crate) enum ExplicitDestructorCallSugg {
192    #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")]
193    Empty(#[primary_span] Span),
194    #[multipart_suggestion(hir_typeck_suggestion, style = "short")]
195    Snippet {
196        #[suggestion_part(code = "drop(")]
197        lo: Span,
198        #[suggestion_part(code = ")")]
199        hi: Span,
200    },
201}
202
203#[derive(Diagnostic)]
204#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
205pub(crate) struct MissingParenthesesInRange {
206    #[primary_span]
207    #[label(hir_typeck_missing_parentheses_in_range)]
208    pub span: Span,
209    pub ty_str: String,
210    pub method_name: String,
211    #[subdiagnostic]
212    pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
213}
214
215#[derive(LintDiagnostic)]
216pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
217    #[help]
218    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
219    Call {
220        #[subdiagnostic]
221        sugg: SuggestAnnotations,
222    },
223    #[help]
224    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
225    Method {
226        #[subdiagnostic]
227        sugg: SuggestAnnotations,
228    },
229    #[help]
230    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
231    Path {
232        #[subdiagnostic]
233        sugg: SuggestAnnotations,
234    },
235    #[help]
236    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
237    UnionField {
238        #[subdiagnostic]
239        sugg: SuggestAnnotations,
240    },
241    #[help]
242    #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
243    Deref {
244        #[subdiagnostic]
245        sugg: SuggestAnnotations,
246    },
247}
248
249#[derive(LintDiagnostic)]
250#[help]
251#[diag(hir_typeck_dependency_on_unit_never_type_fallback)]
252pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
253    #[note]
254    pub obligation_span: Span,
255    pub obligation: ty::Predicate<'tcx>,
256    #[subdiagnostic]
257    pub sugg: SuggestAnnotations,
258}
259
260#[derive(Clone)]
261pub(crate) enum SuggestAnnotation {
262    Unit(Span),
263    Path(Span),
264    Local(Span),
265    Turbo(Span, usize, usize),
266}
267
268#[derive(Clone)]
269pub(crate) struct SuggestAnnotations {
270    pub suggestions: Vec<SuggestAnnotation>,
271}
272impl Subdiagnostic for SuggestAnnotations {
273    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
274        if self.suggestions.is_empty() {
275            return;
276        }
277
278        let mut suggestions = vec![];
279        for suggestion in self.suggestions {
280            match suggestion {
281                SuggestAnnotation::Unit(span) => {
282                    suggestions.push((span, "()".to_string()));
283                }
284                SuggestAnnotation::Path(span) => {
285                    suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
286                    suggestions.push((span.shrink_to_hi(), ">".to_string()));
287                }
288                SuggestAnnotation::Local(span) => {
289                    suggestions.push((span, ": ()".to_string()));
290                }
291                SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
292                    span,
293                    format!(
294                        "::<{}>",
295                        (0..n_args)
296                            .map(|i| if i == idx { "()" } else { "_" })
297                            .collect::<Vec<_>>()
298                            .join(", "),
299                    ),
300                )),
301            }
302        }
303
304        diag.multipart_suggestion_verbose(
305            "use `()` annotations to avoid fallback changes",
306            suggestions,
307            Applicability::MachineApplicable,
308        );
309    }
310}
311
312#[derive(Subdiagnostic)]
313#[multipart_suggestion(
314    hir_typeck_add_missing_parentheses_in_range,
315    style = "verbose",
316    applicability = "maybe-incorrect"
317)]
318pub(crate) struct AddMissingParenthesesInRange {
319    pub func_name: String,
320    #[suggestion_part(code = "(")]
321    pub left: Span,
322    #[suggestion_part(code = ")")]
323    pub right: Span,
324}
325
326pub(crate) struct TypeMismatchFruTypo {
327    /// Span of the LHS of the range
328    pub expr_span: Span,
329    /// Span of the `..RHS` part of the range
330    pub fru_span: Span,
331    /// Rendered expression of the RHS of the range
332    pub expr: Option<String>,
333}
334
335impl Subdiagnostic for TypeMismatchFruTypo {
336    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
337        diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
338
339        // Only explain that `a ..b` is a range if it's split up
340        if self.expr_span.between(self.fru_span).is_empty() {
341            diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note);
342        } else {
343            let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
344            multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr);
345            multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2);
346            diag.span_note(multispan, fluent::hir_typeck_fru_note);
347        }
348
349        diag.span_suggestion(
350            self.expr_span.shrink_to_hi(),
351            fluent::hir_typeck_fru_suggestion,
352            ", ",
353            Applicability::MaybeIncorrect,
354        );
355    }
356}
357
358#[derive(LintDiagnostic)]
359#[diag(hir_typeck_lossy_provenance_int2ptr)]
360#[help]
361pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
362    pub expr_ty: Ty<'tcx>,
363    pub cast_ty: Ty<'tcx>,
364    #[subdiagnostic]
365    pub sugg: LossyProvenanceInt2PtrSuggestion,
366}
367
368#[derive(Diagnostic)]
369#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)]
370#[note]
371#[help]
372pub(crate) struct PtrCastAddAutoToObject {
373    #[primary_span]
374    #[label]
375    pub span: Span,
376    pub traits_len: usize,
377    pub traits: DiagSymbolList<String>,
378}
379
380#[derive(Subdiagnostic)]
381#[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")]
382pub(crate) struct LossyProvenanceInt2PtrSuggestion {
383    #[suggestion_part(code = "(...).with_addr(")]
384    pub lo: Span,
385    #[suggestion_part(code = ")")]
386    pub hi: Span,
387}
388
389#[derive(LintDiagnostic)]
390#[diag(hir_typeck_lossy_provenance_ptr2int)]
391#[help]
392pub(crate) struct LossyProvenancePtr2Int<'tcx> {
393    pub expr_ty: Ty<'tcx>,
394    pub cast_ty: Ty<'tcx>,
395    #[subdiagnostic]
396    pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
397}
398
399#[derive(Subdiagnostic)]
400pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> {
401    #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
402    NeedsParensCast {
403        #[suggestion_part(code = "(")]
404        expr_span: Span,
405        #[suggestion_part(code = ").addr() as {cast_ty}")]
406        cast_span: Span,
407        cast_ty: Ty<'tcx>,
408    },
409    #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
410    NeedsParens {
411        #[suggestion_part(code = "(")]
412        expr_span: Span,
413        #[suggestion_part(code = ").addr()")]
414        cast_span: Span,
415    },
416    #[suggestion(
417        hir_typeck_suggestion,
418        code = ".addr() as {cast_ty}",
419        applicability = "maybe-incorrect"
420    )]
421    NeedsCast {
422        #[primary_span]
423        cast_span: Span,
424        cast_ty: Ty<'tcx>,
425    },
426    #[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")]
427    Other {
428        #[primary_span]
429        cast_span: Span,
430    },
431}
432
433#[derive(Subdiagnostic)]
434pub(crate) enum HelpUseLatestEdition {
435    #[help(hir_typeck_help_set_edition_cargo)]
436    #[note(hir_typeck_note_edition_guide)]
437    Cargo { edition: Edition },
438    #[help(hir_typeck_help_set_edition_standalone)]
439    #[note(hir_typeck_note_edition_guide)]
440    Standalone { edition: Edition },
441}
442
443impl HelpUseLatestEdition {
444    pub(crate) fn new() -> Self {
445        let edition = LATEST_STABLE_EDITION;
446        if rustc_session::utils::was_invoked_from_cargo() {
447            Self::Cargo { edition }
448        } else {
449            Self::Standalone { edition }
450        }
451    }
452}
453
454#[derive(Diagnostic)]
455#[diag(hir_typeck_no_field_on_type, code = E0609)]
456pub(crate) struct NoFieldOnType<'tcx> {
457    #[primary_span]
458    pub(crate) span: Span,
459    pub(crate) ty: Ty<'tcx>,
460    pub(crate) field: Ident,
461}
462
463#[derive(Diagnostic)]
464#[diag(hir_typeck_no_field_on_variant, code = E0609)]
465pub(crate) struct NoFieldOnVariant<'tcx> {
466    #[primary_span]
467    pub(crate) span: Span,
468    pub(crate) container: Ty<'tcx>,
469    pub(crate) ident: Ident,
470    pub(crate) field: Ident,
471    #[label(hir_typeck_no_field_on_variant_enum)]
472    pub(crate) enum_span: Span,
473    #[label(hir_typeck_no_field_on_variant_field)]
474    pub(crate) field_span: Span,
475}
476
477#[derive(Diagnostic)]
478#[diag(hir_typeck_cant_dereference, code = E0614)]
479pub(crate) struct CantDereference<'tcx> {
480    #[primary_span]
481    #[label(hir_typeck_cant_dereference_label)]
482    pub(crate) span: Span,
483    pub(crate) ty: Ty<'tcx>,
484}
485
486#[derive(Diagnostic)]
487#[diag(hir_typeck_expected_array_or_slice, code = E0529)]
488pub(crate) struct ExpectedArrayOrSlice<'tcx> {
489    #[primary_span]
490    #[label(hir_typeck_expected_array_or_slice_label)]
491    pub(crate) span: Span,
492    pub(crate) ty: Ty<'tcx>,
493    pub(crate) slice_pat_semantics: bool,
494    #[subdiagnostic]
495    pub(crate) as_deref: Option<AsDerefSuggestion>,
496    #[subdiagnostic]
497    pub(crate) slicing: Option<SlicingSuggestion>,
498}
499
500#[derive(Subdiagnostic)]
501#[suggestion(
502    hir_typeck_as_deref_suggestion,
503    code = ".as_deref()",
504    style = "verbose",
505    applicability = "maybe-incorrect"
506)]
507pub(crate) struct AsDerefSuggestion {
508    #[primary_span]
509    pub(crate) span: Span,
510}
511
512#[derive(Subdiagnostic)]
513#[suggestion(
514    hir_typeck_slicing_suggestion,
515    code = "[..]",
516    style = "verbose",
517    applicability = "maybe-incorrect"
518)]
519pub(crate) struct SlicingSuggestion {
520    #[primary_span]
521    pub(crate) span: Span,
522}
523
524#[derive(Diagnostic)]
525#[diag(hir_typeck_invalid_callee, code = E0618)]
526pub(crate) struct InvalidCallee<'tcx> {
527    #[primary_span]
528    pub span: Span,
529    pub ty: Ty<'tcx>,
530    pub found: String,
531}
532
533#[derive(Diagnostic)]
534#[diag(hir_typeck_int_to_fat, code = E0606)]
535pub(crate) struct IntToWide<'tcx> {
536    #[primary_span]
537    #[label(hir_typeck_int_to_fat_label)]
538    pub span: Span,
539    pub metadata: &'tcx str,
540    pub expr_ty: Ty<'tcx>,
541    pub cast_ty: Ty<'tcx>,
542    #[label(hir_typeck_int_to_fat_label_nightly)]
543    pub expr_if_nightly: Option<Span>,
544    pub known_wide: bool,
545}
546
547#[derive(Subdiagnostic)]
548pub(crate) enum OptionResultRefMismatch {
549    #[suggestion(
550        hir_typeck_option_result_copied,
551        code = ".copied()",
552        style = "verbose",
553        applicability = "machine-applicable"
554    )]
555    Copied {
556        #[primary_span]
557        span: Span,
558        def_path: String,
559    },
560    #[suggestion(
561        hir_typeck_option_result_cloned,
562        code = ".cloned()",
563        style = "verbose",
564        applicability = "machine-applicable"
565    )]
566    Cloned {
567        #[primary_span]
568        span: Span,
569        def_path: String,
570    },
571    // FIXME: #114050
572    // #[suggestion(
573    //     hir_typeck_option_result_asref,
574    //     code = ".as_ref()",
575    //     style = "verbose",
576    //     applicability = "machine-applicable"
577    // )]
578    // AsRef {
579    //     #[primary_span]
580    //     span: Span,
581    //     def_path: String,
582    //     expected_ty: Ty<'tcx>,
583    //     expr_ty: Ty<'tcx>,
584    // },
585}
586
587pub(crate) struct RemoveSemiForCoerce {
588    pub expr: Span,
589    pub ret: Span,
590    pub semi: Span,
591}
592
593impl Subdiagnostic for RemoveSemiForCoerce {
594    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
595        let mut multispan: MultiSpan = self.semi.into();
596        multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
597        multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
598        multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi);
599        diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce);
600
601        diag.tool_only_span_suggestion(
602            self.semi,
603            fluent::hir_typeck_remove_semi_for_coerce_suggestion,
604            "",
605            Applicability::MaybeIncorrect,
606        );
607    }
608}
609
610#[derive(Diagnostic)]
611#[diag(hir_typeck_const_select_must_be_const)]
612#[help]
613pub(crate) struct ConstSelectMustBeConst {
614    #[primary_span]
615    pub span: Span,
616}
617
618#[derive(Diagnostic)]
619#[diag(hir_typeck_const_select_must_be_fn)]
620#[note]
621#[help]
622pub(crate) struct ConstSelectMustBeFn<'a> {
623    #[primary_span]
624    pub span: Span,
625    pub ty: Ty<'a>,
626}
627
628#[derive(Diagnostic)]
629#[diag(hir_typeck_union_pat_multiple_fields)]
630pub(crate) struct UnionPatMultipleFields {
631    #[primary_span]
632    pub span: Span,
633}
634
635#[derive(Diagnostic)]
636#[diag(hir_typeck_union_pat_dotdot)]
637pub(crate) struct UnionPatDotDot {
638    #[primary_span]
639    pub span: Span,
640}
641
642#[derive(Subdiagnostic)]
643#[multipart_suggestion(
644    hir_typeck_use_is_empty,
645    applicability = "maybe-incorrect",
646    style = "verbose"
647)]
648pub(crate) struct UseIsEmpty<'tcx> {
649    #[suggestion_part(code = "!")]
650    pub lo: Span,
651    #[suggestion_part(code = ".is_empty()")]
652    pub hi: Span,
653    pub expr_ty: Ty<'tcx>,
654}
655
656#[derive(Diagnostic)]
657#[diag(hir_typeck_arg_mismatch_indeterminate)]
658pub(crate) struct ArgMismatchIndeterminate {
659    #[primary_span]
660    pub span: Span,
661}
662
663#[derive(Subdiagnostic)]
664pub(crate) enum SuggestBoxing {
665    #[note(hir_typeck_suggest_boxing_note)]
666    #[multipart_suggestion(
667        hir_typeck_suggest_boxing_when_appropriate,
668        applicability = "machine-applicable"
669    )]
670    Unit {
671        #[suggestion_part(code = "Box::new(())")]
672        start: Span,
673        #[suggestion_part(code = "")]
674        end: Span,
675    },
676    #[note(hir_typeck_suggest_boxing_note)]
677    AsyncBody,
678    #[note(hir_typeck_suggest_boxing_note)]
679    #[multipart_suggestion(
680        hir_typeck_suggest_boxing_when_appropriate,
681        applicability = "machine-applicable"
682    )]
683    Other {
684        #[suggestion_part(code = "Box::new(")]
685        start: Span,
686        #[suggestion_part(code = ")")]
687        end: Span,
688    },
689}
690
691#[derive(Subdiagnostic)]
692#[suggestion(
693    hir_typeck_suggest_ptr_null_mut,
694    applicability = "maybe-incorrect",
695    style = "verbose",
696    code = "core::ptr::null_mut()"
697)]
698pub(crate) struct SuggestPtrNullMut {
699    #[primary_span]
700    pub span: Span,
701}
702
703#[derive(LintDiagnostic)]
704#[diag(hir_typeck_trivial_cast)]
705#[help]
706pub(crate) struct TrivialCast<'tcx> {
707    pub numeric: bool,
708    pub expr_ty: Ty<'tcx>,
709    pub cast_ty: Ty<'tcx>,
710}
711
712#[derive(Diagnostic)]
713#[diag(hir_typeck_no_associated_item, code = E0599)]
714pub(crate) struct NoAssociatedItem {
715    #[primary_span]
716    pub span: Span,
717    pub item_kind: &'static str,
718    pub item_ident: Ident,
719    pub ty_prefix: Cow<'static, str>,
720    pub ty_str: String,
721    pub trait_missing_method: bool,
722}
723
724#[derive(Subdiagnostic)]
725#[note(hir_typeck_candidate_trait_note)]
726pub(crate) struct CandidateTraitNote {
727    #[primary_span]
728    pub span: Span,
729    pub trait_name: String,
730    pub item_name: Ident,
731    pub action_or_ty: String,
732}
733
734#[derive(Diagnostic)]
735#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
736pub(crate) struct CannotCastToBool<'tcx> {
737    #[primary_span]
738    pub span: Span,
739    pub expr_ty: Ty<'tcx>,
740    #[subdiagnostic]
741    pub help: CannotCastToBoolHelp,
742}
743
744#[derive(Diagnostic)]
745#[diag(hir_typeck_cast_enum_drop)]
746pub(crate) struct CastEnumDrop<'tcx> {
747    #[primary_span]
748    pub span: Span,
749    pub expr_ty: Ty<'tcx>,
750    pub cast_ty: Ty<'tcx>,
751}
752
753#[derive(Diagnostic)]
754#[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
755pub(crate) struct CastUnknownPointer {
756    #[primary_span]
757    pub span: Span,
758    pub to: bool,
759    #[subdiagnostic]
760    pub sub: CastUnknownPointerSub,
761}
762
763pub(crate) enum CastUnknownPointerSub {
764    To(Span),
765    From(Span),
766}
767
768impl rustc_errors::Subdiagnostic for CastUnknownPointerSub {
769    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
770        match self {
771            CastUnknownPointerSub::To(span) => {
772                let msg = diag.eagerly_translate(fluent::hir_typeck_label_to);
773                diag.span_label(span, msg);
774                let msg = diag.eagerly_translate(fluent::hir_typeck_note);
775                diag.note(msg);
776            }
777            CastUnknownPointerSub::From(span) => {
778                let msg = diag.eagerly_translate(fluent::hir_typeck_label_from);
779                diag.span_label(span, msg);
780            }
781        }
782    }
783}
784
785#[derive(Subdiagnostic)]
786pub(crate) enum CannotCastToBoolHelp {
787    #[suggestion(
788        hir_typeck_suggestion,
789        applicability = "machine-applicable",
790        code = " != 0",
791        style = "verbose"
792    )]
793    Numeric(#[primary_span] Span),
794    #[label(hir_typeck_label)]
795    Unsupported(#[primary_span] Span),
796}
797
798#[derive(Diagnostic)]
799#[diag(hir_typeck_ctor_is_private, code = E0603)]
800pub(crate) struct CtorIsPrivate {
801    #[primary_span]
802    pub span: Span,
803    pub def: String,
804}
805
806#[derive(Subdiagnostic)]
807#[note(hir_typeck_deref_is_empty)]
808pub(crate) struct DerefImplsIsEmpty<'tcx> {
809    #[primary_span]
810    pub span: Span,
811    pub deref_ty: Ty<'tcx>,
812}
813
814#[derive(Subdiagnostic)]
815#[multipart_suggestion(
816    hir_typeck_convert_using_method,
817    applicability = "machine-applicable",
818    style = "verbose"
819)]
820pub(crate) struct SuggestConvertViaMethod<'tcx> {
821    #[suggestion_part(code = "{sugg}")]
822    pub span: Span,
823    #[suggestion_part(code = "")]
824    pub borrow_removal_span: Option<Span>,
825    pub sugg: String,
826    pub expected: Ty<'tcx>,
827    pub found: Ty<'tcx>,
828}
829
830#[derive(Subdiagnostic)]
831#[note(hir_typeck_note_caller_chooses_ty_for_ty_param)]
832pub(crate) struct NoteCallerChoosesTyForTyParam<'tcx> {
833    pub ty_param_name: Symbol,
834    pub found_ty: Ty<'tcx>,
835}
836
837#[derive(Subdiagnostic)]
838pub(crate) enum SuggestBoxingForReturnImplTrait {
839    #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")]
840    ChangeReturnType {
841        #[suggestion_part(code = "Box<dyn")]
842        start_sp: Span,
843        #[suggestion_part(code = ">")]
844        end_sp: Span,
845    },
846    #[multipart_suggestion(hir_typeck_rpit_box_return_expr, applicability = "maybe-incorrect")]
847    BoxReturnExpr {
848        #[suggestion_part(code = "Box::new(")]
849        starts: Vec<Span>,
850        #[suggestion_part(code = ")")]
851        ends: Vec<Span>,
852    },
853}
854
855#[derive(Diagnostic)]
856#[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)]
857pub(crate) struct SelfCtorFromOuterItem {
858    #[primary_span]
859    pub span: Span,
860    #[label]
861    pub impl_span: Span,
862    #[subdiagnostic]
863    pub sugg: Option<ReplaceWithName>,
864}
865
866#[derive(LintDiagnostic)]
867#[diag(hir_typeck_self_ctor_from_outer_item)]
868pub(crate) struct SelfCtorFromOuterItemLint {
869    #[label]
870    pub impl_span: Span,
871    #[subdiagnostic]
872    pub sugg: Option<ReplaceWithName>,
873}
874
875#[derive(Subdiagnostic)]
876#[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")]
877pub(crate) struct ReplaceWithName {
878    #[primary_span]
879    pub span: Span,
880    pub name: String,
881}
882
883#[derive(Diagnostic)]
884#[diag(hir_typeck_cast_thin_pointer_to_wide_pointer, code = E0607)]
885pub(crate) struct CastThinPointerToWidePointer<'tcx> {
886    #[primary_span]
887    pub span: Span,
888    pub expr_ty: Ty<'tcx>,
889    pub cast_ty: Ty<'tcx>,
890    #[note(hir_typeck_teach_help)]
891    pub(crate) teach: bool,
892}
893
894#[derive(Diagnostic)]
895#[diag(hir_typeck_pass_to_variadic_function, code = E0617)]
896pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
897    #[primary_span]
898    pub span: Span,
899    pub ty: Ty<'tcx>,
900    pub cast_ty: &'a str,
901    #[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")]
902    pub sugg_span: Span,
903    #[note(hir_typeck_teach_help)]
904    pub(crate) teach: bool,
905}
906
907#[derive(Diagnostic)]
908#[diag(hir_typeck_fn_item_to_variadic_function, code = E0617)]
909#[help]
910#[note]
911pub(crate) struct PassFnItemToVariadicFunction {
912    #[primary_span]
913    pub span: Span,
914    #[suggestion(code = " as {replace}", applicability = "machine-applicable", style = "verbose")]
915    pub sugg_span: Span,
916    pub replace: String,
917}
918
919#[derive(Subdiagnostic)]
920#[suggestion(
921    hir_typeck_replace_comma_with_semicolon,
922    applicability = "machine-applicable",
923    style = "verbose",
924    code = "; "
925)]
926pub(crate) struct ReplaceCommaWithSemicolon {
927    #[primary_span]
928    pub comma_span: Span,
929    pub descr: &'static str,
930}
931
932#[derive(LintDiagnostic)]
933#[diag(hir_typeck_supertrait_item_shadowing)]
934pub(crate) struct SupertraitItemShadowing {
935    pub item: Symbol,
936    pub subtrait: Symbol,
937    #[subdiagnostic]
938    pub shadower: SupertraitItemShadower,
939    #[subdiagnostic]
940    pub shadowee: SupertraitItemShadowee,
941}
942
943#[derive(Subdiagnostic)]
944#[note(hir_typeck_supertrait_item_shadower)]
945pub(crate) struct SupertraitItemShadower {
946    pub subtrait: Symbol,
947    #[primary_span]
948    pub span: Span,
949}
950
951#[derive(Subdiagnostic)]
952pub(crate) enum SupertraitItemShadowee {
953    #[note(hir_typeck_supertrait_item_shadowee)]
954    Labeled {
955        #[primary_span]
956        span: Span,
957        supertrait: Symbol,
958    },
959    #[note(hir_typeck_supertrait_item_multiple_shadowee)]
960    Several {
961        #[primary_span]
962        spans: MultiSpan,
963        traits: DiagSymbolList,
964    },
965}