1 use crate::thir
::pattern
::deconstruct_pat
::DeconstructedPat
;
2 use crate::thir
::pattern
::MatchCheckCtxt
;
3 use rustc_errors
::Handler
;
5 error_code
, AddToDiagnostic
, Applicability
, Diagnostic
, DiagnosticBuilder
, ErrorGuaranteed
,
6 IntoDiagnostic
, MultiSpan
, SubdiagnosticMessage
,
8 use rustc_hir
::def
::Res
;
9 use rustc_macros
::{Diagnostic, LintDiagnostic, Subdiagnostic}
;
10 use rustc_middle
::thir
::Pat
;
11 use rustc_middle
::ty
::{self, Ty}
;
12 use rustc_span
::{symbol::Ident, Span}
;
14 #[derive(LintDiagnostic)]
15 #[diag(mir_build_unconditional_recursion)]
17 pub struct UnconditionalRecursion
{
20 #[label(mir_build_unconditional_recursion_call_site_label)]
21 pub call_sites
: Vec
<Span
>,
24 #[derive(LintDiagnostic)]
25 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
27 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe
<'a
> {
30 pub function
: &'a
str,
33 #[derive(LintDiagnostic)]
34 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)]
36 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless
{
41 #[derive(LintDiagnostic)]
42 #[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)]
44 pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe
{
49 #[derive(LintDiagnostic)]
50 #[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)]
52 pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe
{
57 #[derive(LintDiagnostic)]
58 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)]
60 pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe
{
65 #[derive(LintDiagnostic)]
66 #[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)]
68 pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe
{
73 #[derive(LintDiagnostic)]
74 #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)]
76 pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe
{
81 #[derive(LintDiagnostic)]
82 #[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe)]
84 pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe
{
89 #[derive(LintDiagnostic)]
90 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)]
92 pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe
{
97 #[derive(LintDiagnostic)]
98 #[diag(mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)]
99 pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe
{
104 #[derive(LintDiagnostic)]
105 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
107 pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe
<'a
> {
110 pub function
: &'a
str,
113 #[derive(Diagnostic)]
114 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = "E0133")]
116 pub struct CallToUnsafeFunctionRequiresUnsafe
<'a
> {
120 pub function
: &'a
str,
123 #[derive(Diagnostic)]
124 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")]
126 pub struct CallToUnsafeFunctionRequiresUnsafeNameless
{
132 #[derive(Diagnostic)]
133 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
135 pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed
<'a
> {
139 pub function
: &'a
str,
142 #[derive(Diagnostic)]
144 mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed
,
148 pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed
{
154 #[derive(Diagnostic)]
155 #[diag(mir_build_inline_assembly_requires_unsafe, code = "E0133")]
157 pub struct UseOfInlineAssemblyRequiresUnsafe
{
163 #[derive(Diagnostic)]
164 #[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
166 pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
172 #[derive(Diagnostic)]
173 #[diag(mir_build_initializing_type_with_requires_unsafe, code = "E0133")]
175 pub struct InitializingTypeWithRequiresUnsafe
{
181 #[derive(Diagnostic)]
183 mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
,
187 pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
193 #[derive(Diagnostic)]
194 #[diag(mir_build_mutable_static_requires_unsafe, code = "E0133")]
196 pub struct UseOfMutableStaticRequiresUnsafe
{
202 #[derive(Diagnostic)]
203 #[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
205 pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
211 #[derive(Diagnostic)]
212 #[diag(mir_build_extern_static_requires_unsafe, code = "E0133")]
214 pub struct UseOfExternStaticRequiresUnsafe
{
220 #[derive(Diagnostic)]
221 #[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
223 pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
229 #[derive(Diagnostic)]
230 #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = "E0133")]
232 pub struct DerefOfRawPointerRequiresUnsafe
{
238 #[derive(Diagnostic)]
239 #[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
241 pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
247 #[derive(Diagnostic)]
248 #[diag(mir_build_union_field_requires_unsafe, code = "E0133")]
250 pub struct AccessToUnionFieldRequiresUnsafe
{
256 #[derive(Diagnostic)]
257 #[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
259 pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
265 #[derive(Diagnostic)]
266 #[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")]
268 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe
{
274 #[derive(Diagnostic)]
276 mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
,
280 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
286 #[derive(Diagnostic)]
287 #[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")]
289 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe
{
295 #[derive(Diagnostic)]
297 mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed
,
301 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
{
307 #[derive(Diagnostic)]
308 #[diag(mir_build_call_to_fn_with_requires_unsafe, code = "E0133")]
310 pub struct CallToFunctionWithRequiresUnsafe
<'a
> {
314 pub function
: &'a
str,
317 #[derive(Diagnostic)]
318 #[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
320 pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed
<'a
> {
324 pub function
: &'a
str,
327 #[derive(LintDiagnostic)]
328 #[diag(mir_build_unused_unsafe)]
329 pub struct UnusedUnsafe
{
333 pub enclosing
: Option
<UnusedUnsafeEnclosing
>,
336 #[derive(Subdiagnostic)]
337 pub enum UnusedUnsafeEnclosing
{
338 #[label(mir_build_unused_unsafe_enclosing_block_label)]
343 #[label(mir_build_unused_unsafe_enclosing_fn_label)]
350 pub(crate) struct NonExhaustivePatternsTypeNotEmpty
<'p
, 'tcx
, 'm
> {
351 pub cx
: &'m MatchCheckCtxt
<'p
, 'tcx
>,
357 impl<'a
> IntoDiagnostic
<'a
> for NonExhaustivePatternsTypeNotEmpty
<'_
, '_
, '_
> {
358 fn into_diagnostic(self, handler
: &'a Handler
) -> DiagnosticBuilder
<'_
, ErrorGuaranteed
> {
359 let mut diag
= handler
.struct_span_err_with_code(
361 rustc_errors
::fluent
::mir_build_non_exhaustive_patterns_type_not_empty
,
365 let peeled_ty
= self.ty
.peel_refs();
366 diag
.set_arg("ty", self.ty
);
367 diag
.set_arg("peeled_ty", peeled_ty
);
369 if let ty
::Adt(def
, _
) = peeled_ty
.kind() {
374 .get_if_local(def
.did())
375 .and_then(|node
| node
.ident())
376 .map(|ident
| ident
.span
)
377 .unwrap_or_else(|| self.cx
.tcx
.def_span(def
.did()));
379 // workaround to make test pass
380 let mut span
: MultiSpan
= def_span
.into();
381 span
.push_span_label(def_span
, "");
383 diag
.span_note(span
, rustc_errors
::fluent
::def_note
);
386 let is_variant_list_non_exhaustive
= match self.ty
.kind() {
387 ty
::Adt(def
, _
) if def
.is_variant_list_non_exhaustive() && !def
.did().is_local() => {
393 if is_variant_list_non_exhaustive
{
394 diag
.note(rustc_errors
::fluent
::non_exhaustive_type_note
);
396 diag
.note(rustc_errors
::fluent
::type_note
);
399 if let ty
::Ref(_
, sub_ty
, _
) = self.ty
.kind() {
400 if !sub_ty
.is_inhabited_from(self.cx
.tcx
, self.cx
.module
, self.cx
.param_env
) {
401 diag
.note(rustc_errors
::fluent
::reference_note
);
405 let mut suggestion
= None
;
406 let sm
= self.cx
.tcx
.sess
.source_map();
407 if self.span
.eq_ctxt(self.expr_span
) {
408 // Get the span for the empty match body `{}`.
409 let (indentation
, more
) = if let Some(snippet
) = sm
.indentation_before(self.span
) {
410 (format
!("\n{}", snippet
), " ")
412 (" ".to_string(), "")
415 self.span
.shrink_to_hi().with_hi(self.expr_span
.hi()),
417 " {{{indentation}{more}_ => todo!(),{indentation}}}",
418 indentation
= indentation
,
424 if let Some((span
, sugg
)) = suggestion
{
425 diag
.span_suggestion_verbose(
427 rustc_errors
::fluent
::suggestion
,
429 Applicability
::HasPlaceholders
,
432 diag
.help(rustc_errors
::fluent
::help
);
439 #[derive(Diagnostic)]
440 #[diag(mir_build_static_in_pattern, code = "E0158")]
441 pub struct StaticInPattern
{
446 #[derive(Diagnostic)]
447 #[diag(mir_build_assoc_const_in_pattern, code = "E0158")]
448 pub struct AssocConstInPattern
{
453 #[derive(Diagnostic)]
454 #[diag(mir_build_const_param_in_pattern, code = "E0158")]
455 pub struct ConstParamInPattern
{
460 #[derive(Diagnostic)]
461 #[diag(mir_build_non_const_path, code = "E0080")]
462 pub struct NonConstPath
{
467 #[derive(LintDiagnostic)]
468 #[diag(mir_build_unreachable_pattern)]
469 pub struct UnreachablePattern
{
471 pub span
: Option
<Span
>,
472 #[label(catchall_label)]
473 pub catchall
: Option
<Span
>,
476 #[derive(Diagnostic)]
477 #[diag(mir_build_const_pattern_depends_on_generic_parameter)]
478 pub struct ConstPatternDependsOnGenericParameter
{
483 #[derive(Diagnostic)]
484 #[diag(mir_build_could_not_eval_const_pattern)]
485 pub struct CouldNotEvalConstPattern
{
490 #[derive(Diagnostic)]
491 #[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")]
492 pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper
{
497 pub teach
: Option
<()>,
500 #[derive(Diagnostic)]
501 #[diag(mir_build_literal_in_range_out_of_bounds)]
502 pub struct LiteralOutOfRange
<'tcx
> {
510 #[derive(Diagnostic)]
511 #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")]
512 pub struct LowerRangeBoundMustBeLessThanUpper
{
517 #[derive(LintDiagnostic)]
518 #[diag(mir_build_leading_irrefutable_let_patterns)]
521 pub struct LeadingIrrefutableLetPatterns
{
525 #[derive(LintDiagnostic)]
526 #[diag(mir_build_trailing_irrefutable_let_patterns)]
529 pub struct TrailingIrrefutableLetPatterns
{
533 #[derive(LintDiagnostic)]
534 #[diag(mir_build_bindings_with_variant_name, code = "E0170")]
535 pub struct BindingsWithVariantName
{
536 #[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")]
537 pub suggestion
: Option
<Span
>,
542 #[derive(LintDiagnostic)]
543 #[diag(mir_build_irrefutable_let_patterns_generic_let)]
546 pub struct IrrefutableLetPatternsGenericLet
{
550 #[derive(LintDiagnostic)]
551 #[diag(mir_build_irrefutable_let_patterns_if_let)]
554 pub struct IrrefutableLetPatternsIfLet
{
558 #[derive(LintDiagnostic)]
559 #[diag(mir_build_irrefutable_let_patterns_if_let_guard)]
562 pub struct IrrefutableLetPatternsIfLetGuard
{
566 #[derive(LintDiagnostic)]
567 #[diag(mir_build_irrefutable_let_patterns_let_else)]
570 pub struct IrrefutableLetPatternsLetElse
{
574 #[derive(LintDiagnostic)]
575 #[diag(mir_build_irrefutable_let_patterns_while_let)]
578 pub struct IrrefutableLetPatternsWhileLet
{
582 #[derive(Diagnostic)]
583 #[diag(mir_build_borrow_of_moved_value)]
584 pub struct BorrowOfMovedValue
<'tcx
> {
588 #[label(occurs_because_label)]
589 pub binding_span
: Span
,
590 #[label(value_borrowed_label)]
591 pub conflicts_ref
: Vec
<Span
>,
594 #[suggestion(code = "ref ", applicability = "machine-applicable")]
595 pub suggest_borrowing
: Option
<Span
>,
598 #[derive(Diagnostic)]
599 #[diag(mir_build_multiple_mut_borrows)]
600 pub struct MultipleMutBorrows
{
604 pub binding_span
: Span
,
606 pub occurences
: Vec
<MultipleMutBorrowOccurence
>,
610 #[derive(Subdiagnostic)]
611 pub enum MultipleMutBorrowOccurence
{
612 #[label(mutable_borrow)]
618 #[label(immutable_borrow)]
632 #[derive(Diagnostic)]
633 #[diag(mir_build_union_pattern)]
634 pub struct UnionPattern
{
639 #[derive(Diagnostic)]
640 #[diag(mir_build_type_not_structural)]
641 pub struct TypeNotStructural
<'tcx
> {
644 pub non_sm_ty
: Ty
<'tcx
>,
647 #[derive(Diagnostic)]
648 #[diag(mir_build_invalid_pattern)]
649 pub struct InvalidPattern
<'tcx
> {
652 pub non_sm_ty
: Ty
<'tcx
>,
655 #[derive(Diagnostic)]
656 #[diag(mir_build_unsized_pattern)]
657 pub struct UnsizedPattern
<'tcx
> {
660 pub non_sm_ty
: Ty
<'tcx
>,
663 #[derive(LintDiagnostic)]
664 #[diag(mir_build_float_pattern)]
665 pub struct FloatPattern
;
667 #[derive(LintDiagnostic)]
668 #[diag(mir_build_pointer_pattern)]
669 pub struct PointerPattern
;
671 #[derive(LintDiagnostic)]
672 #[diag(mir_build_indirect_structural_match)]
673 pub struct IndirectStructuralMatch
<'tcx
> {
674 pub non_sm_ty
: Ty
<'tcx
>,
677 #[derive(LintDiagnostic)]
678 #[diag(mir_build_nontrivial_structural_match)]
679 pub struct NontrivialStructuralMatch
<'tcx
> {
680 pub non_sm_ty
: Ty
<'tcx
>,
683 #[derive(LintDiagnostic)]
684 #[diag(mir_build_overlapping_range_endpoints)]
686 pub struct OverlappingRangeEndpoints
<'tcx
> {
690 pub overlap
: Vec
<Overlap
<'tcx
>>,
693 pub struct Overlap
<'tcx
> {
695 pub range
: Pat
<'tcx
>,
698 impl<'tcx
> AddToDiagnostic
for Overlap
<'tcx
> {
699 fn add_to_diagnostic_with
<F
>(self, diag
: &mut Diagnostic
, _
: F
)
701 F
: Fn(&mut Diagnostic
, SubdiagnosticMessage
) -> SubdiagnosticMessage
,
703 let Overlap { span, range }
= self;
705 // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
706 // does not support `#[subdiagnostic(eager)]`...
707 let message
= format
!("this range overlaps on `{range}`...");
708 diag
.span_label(span
, message
);
712 #[derive(LintDiagnostic)]
713 #[diag(mir_build_non_exhaustive_omitted_pattern)]
716 pub(crate) struct NonExhaustiveOmittedPattern
<'tcx
> {
717 pub scrut_ty
: Ty
<'tcx
>,
719 pub uncovered
: Uncovered
<'tcx
>,
722 #[derive(Subdiagnostic)]
723 #[label(mir_build_uncovered)]
724 pub(crate) struct Uncovered
<'tcx
> {
728 witness_1
: Pat
<'tcx
>,
729 witness_2
: Pat
<'tcx
>,
730 witness_3
: Pat
<'tcx
>,
734 impl<'tcx
> Uncovered
<'tcx
> {
737 cx
: &MatchCheckCtxt
<'p
, 'tcx
>,
738 witnesses
: Vec
<DeconstructedPat
<'p
, 'tcx
>>,
740 let witness_1
= witnesses
.get(0).unwrap().to_pat(cx
);
743 count
: witnesses
.len(),
744 // Substitute dummy values if witnesses is smaller than 3. These will never be read.
745 witness_2
: witnesses
.get(1).map(|w
| w
.to_pat(cx
)).unwrap_or_else(|| witness_1
.clone()),
746 witness_3
: witnesses
.get(2).map(|w
| w
.to_pat(cx
)).unwrap_or_else(|| witness_1
.clone()),
748 remainder
: witnesses
.len().saturating_sub(3),
753 #[derive(Diagnostic)]
754 #[diag(mir_build_pattern_not_covered, code = "E0005")]
755 pub(crate) struct PatternNotCovered
<'s
, 'tcx
> {
760 pub uncovered
: Uncovered
<'tcx
>,
762 pub inform
: Option
<Inform
>,
764 pub interpreted_as_const
: Option
<InterpretedAsConst
>,
766 pub adt_defined_here
: Option
<AdtDefinedHere
<'tcx
>>,
769 pub pattern_ty
: Ty
<'tcx
>,
771 pub let_suggestion
: Option
<SuggestLet
>,
773 pub misc_suggestion
: Option
<MiscPatternSuggestion
>,
775 pub res_defined_here
: Option
<ResDefinedHere
>,
778 #[derive(Subdiagnostic)]
779 #[note(mir_build_inform_irrefutable)]
780 #[note(mir_build_more_information)]
783 pub struct AdtDefinedHere
<'tcx
> {
784 pub adt_def_span
: Span
,
786 pub variants
: Vec
<Variant
>,
793 impl<'tcx
> AddToDiagnostic
for AdtDefinedHere
<'tcx
> {
794 fn add_to_diagnostic_with
<F
>(self, diag
: &mut Diagnostic
, _
: F
)
796 F
: Fn(&mut Diagnostic
, SubdiagnosticMessage
) -> SubdiagnosticMessage
,
798 diag
.set_arg("ty", self.ty
);
799 let mut spans
= MultiSpan
::from(self.adt_def_span
);
801 for Variant { span }
in self.variants
{
802 spans
.push_span_label(span
, rustc_errors
::fluent
::mir_build_variant_defined_here
);
805 diag
.span_note(spans
, rustc_errors
::fluent
::mir_build_adt_defined_here
);
809 #[derive(Subdiagnostic)]
810 #[label(mir_build_res_defined_here)]
811 pub struct ResDefinedHere
{
817 #[derive(Subdiagnostic)]
819 mir_build_interpreted_as_const
,
820 code
= "{variable}_var",
821 applicability
= "maybe-incorrect"
823 #[label(mir_build_confused)]
824 pub struct InterpretedAsConst
{
827 pub article
: &'
static str,
828 pub variable
: String
,
832 #[derive(Subdiagnostic)]
833 pub enum SuggestLet
{
834 #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
836 #[suggestion_part(code = "if ")]
838 #[suggestion_part(code = " {{ todo!() }}")]
843 mir_build_suggest_let_else
,
844 code
= " else {{ todo!() }}",
845 applicability
= "has-placeholders"
854 #[derive(Subdiagnostic)]
855 pub enum MiscPatternSuggestion
{
857 mir_build_suggest_attempted_int_lit
,
859 applicability
= "maybe-incorrect"
861 AttemptedIntegerLiteral
{