1use std::borrow::Cow;
4
5use rustc_abi::ExternAbi;
6use rustc_ast::Label;
7use rustc_errors::codes::*;
8use rustc_errors::{
9 Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic,
10 EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
11};
12use rustc_hir as hir;
13use rustc_hir::ExprKind;
14use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
15use rustc_middle::ty::{self, Ty};
16use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
17use rustc_span::{Ident, Span, Symbol};
18
19use crate::fluent_generated as fluent;
20
21#[derive(Diagnostic)]
22#[diag(hir_typeck_base_expression_double_dot, code = E0797)]
23pub(crate) struct BaseExpressionDoubleDot {
24 #[primary_span]
25 pub span: Span,
26 #[suggestion(
27 hir_typeck_base_expression_double_dot_enable_default_field_values,
28 code = "#![feature(default_field_values)]\n",
29 applicability = "machine-applicable",
30 style = "verbose"
31 )]
32 pub default_field_values_suggestion: Option<Span>,
33 #[subdiagnostic]
34 pub add_expr: Option<BaseExpressionDoubleDotAddExpr>,
35 #[subdiagnostic]
36 pub remove_dots: Option<BaseExpressionDoubleDotRemove>,
37}
38
39#[derive(Subdiagnostic)]
40#[suggestion(
41 hir_typeck_base_expression_double_dot_remove,
42 code = "",
43 applicability = "machine-applicable",
44 style = "verbose"
45)]
46pub(crate) struct BaseExpressionDoubleDotRemove {
47 #[primary_span]
48 pub span: Span,
49}
50
51#[derive(Subdiagnostic)]
52#[suggestion(
53 hir_typeck_base_expression_double_dot_add_expr,
54 code = "/* expr */",
55 applicability = "has-placeholders",
56 style = "verbose"
57)]
58pub(crate) struct BaseExpressionDoubleDotAddExpr {
59 #[primary_span]
60 pub span: Span,
61}
62
63#[derive(Diagnostic)]
64#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
65pub(crate) struct FieldMultiplySpecifiedInInitializer {
66 #[primary_span]
67 #[label]
68 pub span: Span,
69 #[label(hir_typeck_previous_use_label)]
70 pub prev_span: Span,
71 pub ident: Ident,
72}
73
74#[derive(Diagnostic)]
75#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
76pub(crate) struct ReturnStmtOutsideOfFnBody {
77 #[primary_span]
78 pub span: Span,
79 #[label(hir_typeck_encl_body_label)]
80 pub encl_body_span: Option<Span>,
81 #[label(hir_typeck_encl_fn_label)]
82 pub encl_fn_span: Option<Span>,
83 pub statement_kind: ReturnLikeStatementKind,
84}
85
86pub(crate) enum ReturnLikeStatementKind {
87 Return,
88 Become,
89}
90
91impl IntoDiagArg for ReturnLikeStatementKind {
92 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
93 let kind = match self {
94 Self::Return => "return",
95 Self::Become => "become",
96 }
97 .into();
98
99 DiagArgValue::Str(kind)
100 }
101}
102
103#[derive(Diagnostic)]
104#[diag(hir_typeck_rustcall_incorrect_args)]
105pub(crate) struct RustCallIncorrectArgs {
106 #[primary_span]
107 pub span: Span,
108}
109
110#[derive(Diagnostic)]
111#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
112pub(crate) struct YieldExprOutsideOfCoroutine {
113 #[primary_span]
114 pub span: Span,
115}
116
117#[derive(Diagnostic)]
118#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
119pub(crate) struct StructExprNonExhaustive {
120 #[primary_span]
121 pub span: Span,
122 pub what: &'static str,
123}
124
125#[derive(Diagnostic)]
126#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
127pub(crate) struct FunctionalRecordUpdateOnNonStruct {
128 #[primary_span]
129 pub span: Span,
130}
131
132#[derive(Diagnostic)]
133#[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
134pub(crate) struct AddressOfTemporaryTaken {
135 #[primary_span]
136 #[label]
137 pub span: Span,
138}
139
140#[derive(Subdiagnostic)]
141pub(crate) enum AddReturnTypeSuggestion {
142 #[suggestion(
143 hir_typeck_add_return_type_add,
144 code = " -> {found}",
145 applicability = "machine-applicable"
146 )]
147 Add {
148 #[primary_span]
149 span: Span,
150 found: String,
151 },
152 #[suggestion(
153 hir_typeck_add_return_type_missing_here,
154 code = " -> _",
155 applicability = "has-placeholders"
156 )]
157 MissingHere {
158 #[primary_span]
159 span: Span,
160 },
161}
162
163#[derive(Subdiagnostic)]
164pub(crate) enum ExpectedReturnTypeLabel<'tcx> {
165 #[label(hir_typeck_expected_default_return_type)]
166 Unit {
167 #[primary_span]
168 span: Span,
169 },
170 #[label(hir_typeck_expected_return_type)]
171 Other {
172 #[primary_span]
173 span: Span,
174 expected: Ty<'tcx>,
175 },
176}
177
178#[derive(Diagnostic)]
179#[diag(hir_typeck_explicit_destructor, code = E0040)]
180pub(crate) struct ExplicitDestructorCall {
181 #[primary_span]
182 #[label]
183 pub span: Span,
184 #[subdiagnostic]
185 pub sugg: ExplicitDestructorCallSugg,
186}
187
188#[derive(Subdiagnostic)]
189pub(crate) enum ExplicitDestructorCallSugg {
190 #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")]
191 Empty(#[primary_span] Span),
192 #[multipart_suggestion(hir_typeck_suggestion, style = "short")]
193 Snippet {
194 #[suggestion_part(code = "drop(")]
195 lo: Span,
196 #[suggestion_part(code = ")")]
197 hi: Span,
198 },
199}
200
201#[derive(Diagnostic)]
202#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
203pub(crate) struct MissingParenthesesInRange {
204 #[primary_span]
205 #[label(hir_typeck_missing_parentheses_in_range)]
206 pub span: Span,
207 pub ty_str: String,
208 pub method_name: String,
209 #[subdiagnostic]
210 pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
211}
212
213#[derive(LintDiagnostic)]
214pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
215 #[help]
216 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
217 Call {
218 #[subdiagnostic]
219 sugg: SuggestAnnotations,
220 },
221 #[help]
222 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
223 Method {
224 #[subdiagnostic]
225 sugg: SuggestAnnotations,
226 },
227 #[help]
228 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
229 Path {
230 #[subdiagnostic]
231 sugg: SuggestAnnotations,
232 },
233 #[help]
234 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
235 UnionField {
236 #[subdiagnostic]
237 sugg: SuggestAnnotations,
238 },
239 #[help]
240 #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
241 Deref {
242 #[subdiagnostic]
243 sugg: SuggestAnnotations,
244 },
245}
246
247#[derive(LintDiagnostic)]
248#[help]
249#[diag(hir_typeck_dependency_on_unit_never_type_fallback)]
250pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
251 #[note]
252 pub obligation_span: Span,
253 pub obligation: ty::Predicate<'tcx>,
254 #[subdiagnostic]
255 pub sugg: SuggestAnnotations,
256}
257
258#[derive(Clone)]
259pub(crate) enum SuggestAnnotation {
260 Unit(Span),
261 Path(Span),
262 Local(Span),
263 Turbo(Span, usize, usize),
264}
265
266#[derive(Clone)]
267pub(crate) struct SuggestAnnotations {
268 pub suggestions: Vec<SuggestAnnotation>,
269}
270impl Subdiagnostic for SuggestAnnotations {
271 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
272 if self.suggestions.is_empty() {
273 return;
274 }
275
276 let mut suggestions = vec![];
277 for suggestion in self.suggestions {
278 match suggestion {
279 SuggestAnnotation::Unit(span) => {
280 suggestions.push((span, "()".to_string()));
281 }
282 SuggestAnnotation::Path(span) => {
283 suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
284 suggestions.push((span.shrink_to_hi(), ">".to_string()));
285 }
286 SuggestAnnotation::Local(span) => {
287 suggestions.push((span, ": ()".to_string()));
288 }
289 SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
290 span,
291 format!(
292 "::<{}>",
293 (0..n_args)
294 .map(|i| if i == idx { "()" } else { "_" })
295 .collect::<Vec<_>>()
296 .join(", "),
297 ),
298 )),
299 }
300 }
301
302 diag.multipart_suggestion_verbose(
303 "use `()` annotations to avoid fallback changes",
304 suggestions,
305 Applicability::MachineApplicable,
306 );
307 }
308}
309
310#[derive(Subdiagnostic)]
311#[multipart_suggestion(
312 hir_typeck_add_missing_parentheses_in_range,
313 style = "verbose",
314 applicability = "maybe-incorrect"
315)]
316pub(crate) struct AddMissingParenthesesInRange {
317 pub func_name: String,
318 #[suggestion_part(code = "(")]
319 pub left: Span,
320 #[suggestion_part(code = ")")]
321 pub right: Span,
322}
323
324pub(crate) struct TypeMismatchFruTypo {
325 pub expr_span: Span,
327 pub fru_span: Span,
329 pub expr: Option<String>,
331}
332
333impl Subdiagnostic for TypeMismatchFruTypo {
334 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
335 diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
336
337 if self.expr_span.between(self.fru_span).is_empty() {
339 diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note);
340 } else {
341 let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into();
342 multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr);
343 multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2);
344 diag.span_note(multispan, fluent::hir_typeck_fru_note);
345 }
346
347 diag.span_suggestion(
348 self.expr_span.shrink_to_hi(),
349 fluent::hir_typeck_fru_suggestion,
350 ", ",
351 Applicability::MaybeIncorrect,
352 );
353 }
354}
355
356#[derive(LintDiagnostic)]
357#[diag(hir_typeck_lossy_provenance_int2ptr)]
358#[help]
359pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
360 pub expr_ty: Ty<'tcx>,
361 pub cast_ty: Ty<'tcx>,
362 #[subdiagnostic]
363 pub sugg: LossyProvenanceInt2PtrSuggestion,
364}
365
366#[derive(Diagnostic)]
367#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)]
368#[note]
369#[help]
370pub(crate) struct PtrCastAddAutoToObject {
371 #[primary_span]
372 #[label]
373 pub span: Span,
374 pub traits_len: usize,
375 pub traits: DiagSymbolList<String>,
376}
377
378#[derive(Subdiagnostic)]
379#[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")]
380pub(crate) struct LossyProvenanceInt2PtrSuggestion {
381 #[suggestion_part(code = "(...).with_addr(")]
382 pub lo: Span,
383 #[suggestion_part(code = ")")]
384 pub hi: Span,
385}
386
387#[derive(LintDiagnostic)]
388#[diag(hir_typeck_lossy_provenance_ptr2int)]
389#[help]
390pub(crate) struct LossyProvenancePtr2Int<'tcx> {
391 pub expr_ty: Ty<'tcx>,
392 pub cast_ty: Ty<'tcx>,
393 #[subdiagnostic]
394 pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
395}
396
397#[derive(Subdiagnostic)]
398pub(crate) enum LossyProvenancePtr2IntSuggestion<'tcx> {
399 #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
400 NeedsParensCast {
401 #[suggestion_part(code = "(")]
402 expr_span: Span,
403 #[suggestion_part(code = ").addr() as {cast_ty}")]
404 cast_span: Span,
405 cast_ty: Ty<'tcx>,
406 },
407 #[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
408 NeedsParens {
409 #[suggestion_part(code = "(")]
410 expr_span: Span,
411 #[suggestion_part(code = ").addr()")]
412 cast_span: Span,
413 },
414 #[suggestion(
415 hir_typeck_suggestion,
416 code = ".addr() as {cast_ty}",
417 applicability = "maybe-incorrect"
418 )]
419 NeedsCast {
420 #[primary_span]
421 cast_span: Span,
422 cast_ty: Ty<'tcx>,
423 },
424 #[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")]
425 Other {
426 #[primary_span]
427 cast_span: Span,
428 },
429}
430
431#[derive(Subdiagnostic)]
432pub(crate) enum HelpUseLatestEdition {
433 #[help(hir_typeck_help_set_edition_cargo)]
434 #[note(hir_typeck_note_edition_guide)]
435 Cargo { edition: Edition },
436 #[help(hir_typeck_help_set_edition_standalone)]
437 #[note(hir_typeck_note_edition_guide)]
438 Standalone { edition: Edition },
439}
440
441impl HelpUseLatestEdition {
442 pub(crate) fn new() -> Self {
443 let edition = LATEST_STABLE_EDITION;
444 if rustc_session::utils::was_invoked_from_cargo() {
445 Self::Cargo { edition }
446 } else {
447 Self::Standalone { edition }
448 }
449 }
450}
451
452#[derive(Diagnostic)]
453#[diag(hir_typeck_no_field_on_type, code = E0609)]
454pub(crate) struct NoFieldOnType<'tcx> {
455 #[primary_span]
456 pub(crate) span: Span,
457 pub(crate) ty: Ty<'tcx>,
458 pub(crate) field: Ident,
459}
460
461#[derive(Diagnostic)]
462#[diag(hir_typeck_no_field_on_variant, code = E0609)]
463pub(crate) struct NoFieldOnVariant<'tcx> {
464 #[primary_span]
465 pub(crate) span: Span,
466 pub(crate) container: Ty<'tcx>,
467 pub(crate) ident: Ident,
468 pub(crate) field: Ident,
469 #[label(hir_typeck_no_field_on_variant_enum)]
470 pub(crate) enum_span: Span,
471 #[label(hir_typeck_no_field_on_variant_field)]
472 pub(crate) field_span: Span,
473}
474
475#[derive(Diagnostic)]
476#[diag(hir_typeck_cant_dereference, code = E0614)]
477pub(crate) struct CantDereference<'tcx> {
478 #[primary_span]
479 #[label(hir_typeck_cant_dereference_label)]
480 pub(crate) span: Span,
481 pub(crate) ty: Ty<'tcx>,
482}
483
484#[derive(Diagnostic)]
485#[diag(hir_typeck_expected_array_or_slice, code = E0529)]
486pub(crate) struct ExpectedArrayOrSlice<'tcx> {
487 #[primary_span]
488 #[label(hir_typeck_expected_array_or_slice_label)]
489 pub(crate) span: Span,
490 pub(crate) ty: Ty<'tcx>,
491 pub(crate) slice_pat_semantics: bool,
492 #[subdiagnostic]
493 pub(crate) as_deref: Option<AsDerefSuggestion>,
494 #[subdiagnostic]
495 pub(crate) slicing: Option<SlicingSuggestion>,
496}
497
498#[derive(Subdiagnostic)]
499#[suggestion(
500 hir_typeck_as_deref_suggestion,
501 code = ".as_deref()",
502 style = "verbose",
503 applicability = "maybe-incorrect"
504)]
505pub(crate) struct AsDerefSuggestion {
506 #[primary_span]
507 pub(crate) span: Span,
508}
509
510#[derive(Subdiagnostic)]
511#[suggestion(
512 hir_typeck_slicing_suggestion,
513 code = "[..]",
514 style = "verbose",
515 applicability = "maybe-incorrect"
516)]
517pub(crate) struct SlicingSuggestion {
518 #[primary_span]
519 pub(crate) span: Span,
520}
521
522#[derive(Diagnostic)]
523#[diag(hir_typeck_invalid_callee, code = E0618)]
524pub(crate) struct InvalidCallee<'tcx> {
525 #[primary_span]
526 pub span: Span,
527 pub ty: Ty<'tcx>,
528 pub found: String,
529}
530
531#[derive(Diagnostic)]
532#[diag(hir_typeck_int_to_fat, code = E0606)]
533pub(crate) struct IntToWide<'tcx> {
534 #[primary_span]
535 #[label(hir_typeck_int_to_fat_label)]
536 pub span: Span,
537 pub metadata: &'tcx str,
538 pub expr_ty: Ty<'tcx>,
539 pub cast_ty: Ty<'tcx>,
540 #[label(hir_typeck_int_to_fat_label_nightly)]
541 pub expr_if_nightly: Option<Span>,
542 pub known_wide: bool,
543}
544
545#[derive(Subdiagnostic)]
546pub(crate) enum OptionResultRefMismatch {
547 #[suggestion(
548 hir_typeck_option_result_copied,
549 code = ".copied()",
550 style = "verbose",
551 applicability = "machine-applicable"
552 )]
553 Copied {
554 #[primary_span]
555 span: Span,
556 def_path: String,
557 },
558 #[suggestion(
559 hir_typeck_option_result_cloned,
560 code = ".cloned()",
561 style = "verbose",
562 applicability = "machine-applicable"
563 )]
564 Cloned {
565 #[primary_span]
566 span: Span,
567 def_path: String,
568 },
569 }
584
585pub(crate) struct RemoveSemiForCoerce {
586 pub expr: Span,
587 pub ret: Span,
588 pub semi: Span,
589}
590
591impl Subdiagnostic for RemoveSemiForCoerce {
592 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
593 let mut multispan: MultiSpan = self.semi.into();
594 multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
595 multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
596 multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi);
597 diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce);
598
599 diag.tool_only_span_suggestion(
600 self.semi,
601 fluent::hir_typeck_remove_semi_for_coerce_suggestion,
602 "",
603 Applicability::MaybeIncorrect,
604 );
605 }
606}
607
608#[derive(Diagnostic)]
609#[diag(hir_typeck_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 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}