mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-28 11:38:01 +00:00
Isolate the diagnostic code that expects `thir::Pat` to be printable Currently, `thir::Pat` implements `fmt::Display` (and `IntoDiagArg`) directly, for use by a few diagnostics. That makes it tricky to experiment with alternate representations for THIR patterns, because the patterns currently need to be printable on their own. That immediately rules out possibilities like storing subpatterns as a `PatId` index into a central list (instead of the current directly-owned `Box<Pat>`). This PR therefore takes an incremental step away from that obstacle, by removing `thir::Pat` from diagnostic structs in `rustc_pattern_analysis`, and hiding the pattern-printing process behind a single public `Pat::to_string` method. Doing so makes it easier to identify and update the code that wants to print patterns, and gives a place to pass in additional context in the future if necessary. --- I'm currently not sure whether switching over to `PatId` is actually desirable or not, but I think this change makes sense on its own merits, by reducing the coupling between `thir::Pat` and the pattern-analysis error types.
1004 lines
29 KiB
Rust
1004 lines
29 KiB
Rust
use rustc_errors::codes::*;
|
|
use rustc_errors::{
|
|
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
|
|
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
|
};
|
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
|
use rustc_middle::ty::{self, Ty};
|
|
use rustc_pattern_analysis::errors::Uncovered;
|
|
use rustc_pattern_analysis::rustc::RustcPatCtxt;
|
|
use rustc_span::symbol::Symbol;
|
|
use rustc_span::Span;
|
|
|
|
use crate::fluent_generated as fluent;
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unconditional_recursion)]
|
|
#[help]
|
|
pub(crate) struct UnconditionalRecursion {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[label(mir_build_unconditional_recursion_call_site_label)]
|
|
pub(crate) call_sites: Vec<Span>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_call_to_deprecated_safe_fn_requires_unsafe)]
|
|
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
#[subdiagnostic]
|
|
pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
|
|
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
|
|
pub(crate) indent: String,
|
|
#[suggestion_part(
|
|
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
|
|
)]
|
|
pub(crate) start_of_line: Span,
|
|
#[suggestion_part(code = "unsafe {{ ")]
|
|
pub(crate) left: Span,
|
|
#[suggestion_part(code = " }}")]
|
|
pub(crate) right: Span,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(
|
|
mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe,
|
|
code = E0133
|
|
)]
|
|
#[note]
|
|
pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(
|
|
mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe,
|
|
code = E0133,
|
|
)]
|
|
pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)]
|
|
#[help]
|
|
pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
pub(crate) missing_target_features: DiagArgValue,
|
|
pub(crate) missing_target_features_count: usize,
|
|
#[note]
|
|
pub(crate) note: Option<()>,
|
|
pub(crate) build_target_features: DiagArgValue,
|
|
pub(crate) build_target_features_count: usize,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedLintNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct CallToUnsafeFunctionRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNameless {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(
|
|
mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed,
|
|
code = E0133
|
|
)]
|
|
#[note]
|
|
pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfInlineAssemblyRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct InitializingTypeWithRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(
|
|
mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
|
|
code = E0133
|
|
)]
|
|
#[note]
|
|
pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfMutableStaticRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_extern_static_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfExternStaticRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct DerefOfRawPointerRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_union_field_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct AccessToUnionFieldRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(
|
|
mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
|
|
code = E0133
|
|
)]
|
|
#[note]
|
|
pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)]
|
|
#[note]
|
|
pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(
|
|
mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
|
|
code = E0133
|
|
)]
|
|
#[note]
|
|
pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)]
|
|
#[help]
|
|
pub(crate) struct CallToFunctionWithRequiresUnsafe {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
pub(crate) missing_target_features: DiagArgValue,
|
|
pub(crate) missing_target_features_count: usize,
|
|
#[note]
|
|
pub(crate) note: Option<()>,
|
|
pub(crate) build_target_features: DiagArgValue,
|
|
pub(crate) build_target_features_count: usize,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
|
|
#[help]
|
|
pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) function: String,
|
|
pub(crate) missing_target_features: DiagArgValue,
|
|
pub(crate) missing_target_features_count: usize,
|
|
#[note]
|
|
pub(crate) note: Option<()>,
|
|
pub(crate) build_target_features: DiagArgValue,
|
|
pub(crate) build_target_features_count: usize,
|
|
#[subdiagnostic]
|
|
pub(crate) unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[label(mir_build_unsafe_not_inherited)]
|
|
pub(crate) struct UnsafeNotInheritedNote {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
pub(crate) struct UnsafeNotInheritedLintNote {
|
|
pub(crate) signature_span: Span,
|
|
pub(crate) body_span: Span,
|
|
}
|
|
|
|
impl Subdiagnostic for UnsafeNotInheritedLintNote {
|
|
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
|
self,
|
|
diag: &mut Diag<'_, G>,
|
|
_f: &F,
|
|
) {
|
|
diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body);
|
|
let body_start = self.body_span.shrink_to_lo();
|
|
let body_end = self.body_span.shrink_to_hi();
|
|
diag.tool_only_multipart_suggestion(
|
|
fluent::mir_build_wrap_suggestion,
|
|
vec![(body_start, "{ unsafe ".into()), (body_end, "}".into())],
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unused_unsafe)]
|
|
pub(crate) struct UnusedUnsafe {
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) enclosing: Option<UnusedUnsafeEnclosing>,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
pub(crate) enum UnusedUnsafeEnclosing {
|
|
#[label(mir_build_unused_unsafe_enclosing_block_label)]
|
|
Block {
|
|
#[primary_span]
|
|
span: Span,
|
|
},
|
|
}
|
|
|
|
pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
|
|
pub(crate) cx: &'m RustcPatCtxt<'p, 'tcx>,
|
|
pub(crate) scrut_span: Span,
|
|
pub(crate) braces_span: Option<Span>,
|
|
pub(crate) ty: Ty<'tcx>,
|
|
}
|
|
|
|
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
|
|
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'_, G> {
|
|
let mut diag =
|
|
Diag::new(dcx, level, fluent::mir_build_non_exhaustive_patterns_type_not_empty);
|
|
diag.span(self.scrut_span);
|
|
diag.code(E0004);
|
|
let peeled_ty = self.ty.peel_refs();
|
|
diag.arg("ty", self.ty);
|
|
diag.arg("peeled_ty", peeled_ty);
|
|
|
|
if let ty::Adt(def, _) = peeled_ty.kind() {
|
|
let def_span = self
|
|
.cx
|
|
.tcx
|
|
.hir()
|
|
.get_if_local(def.did())
|
|
.and_then(|node| node.ident())
|
|
.map(|ident| ident.span)
|
|
.unwrap_or_else(|| self.cx.tcx.def_span(def.did()));
|
|
|
|
// workaround to make test pass
|
|
let mut span: MultiSpan = def_span.into();
|
|
span.push_span_label(def_span, "");
|
|
|
|
diag.span_note(span, fluent::mir_build_def_note);
|
|
}
|
|
|
|
let is_variant_list_non_exhaustive = matches!(self.ty.kind(),
|
|
ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local());
|
|
if is_variant_list_non_exhaustive {
|
|
diag.note(fluent::mir_build_non_exhaustive_type_note);
|
|
} else {
|
|
diag.note(fluent::mir_build_type_note);
|
|
}
|
|
|
|
if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
|
|
if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) {
|
|
diag.note(fluent::mir_build_reference_note);
|
|
}
|
|
}
|
|
|
|
let sm = self.cx.tcx.sess.source_map();
|
|
if let Some(braces_span) = self.braces_span {
|
|
// Get the span for the empty match body `{}`.
|
|
let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.scrut_span)
|
|
{
|
|
(format!("\n{snippet}"), " ")
|
|
} else {
|
|
(" ".to_string(), "")
|
|
};
|
|
diag.span_suggestion_verbose(
|
|
braces_span,
|
|
fluent::mir_build_suggestion,
|
|
format!(" {{{indentation}{more}_ => todo!(),{indentation}}}"),
|
|
Applicability::HasPlaceholders,
|
|
);
|
|
} else {
|
|
diag.help(fluent::mir_build_help);
|
|
}
|
|
|
|
diag
|
|
}
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[note(mir_build_non_exhaustive_match_all_arms_guarded)]
|
|
pub(crate) struct NonExhaustiveMatchAllArmsGuarded;
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_static_in_pattern, code = E0158)]
|
|
pub(crate) struct StaticInPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_const_param_in_pattern, code = E0158)]
|
|
pub(crate) struct ConstParamInPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_non_const_path, code = E0080)]
|
|
pub(crate) struct NonConstPath {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_unreachable_pattern)]
|
|
pub(crate) struct UnreachablePattern<'tcx> {
|
|
#[label]
|
|
pub(crate) span: Option<Span>,
|
|
#[subdiagnostic]
|
|
pub(crate) matches_no_values: Option<UnreachableMatchesNoValues<'tcx>>,
|
|
#[label(mir_build_unreachable_covered_by_catchall)]
|
|
pub(crate) covered_by_catchall: Option<Span>,
|
|
#[label(mir_build_unreachable_covered_by_one)]
|
|
pub(crate) covered_by_one: Option<Span>,
|
|
#[note(mir_build_unreachable_covered_by_many)]
|
|
pub(crate) covered_by_many: Option<MultiSpan>,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[note(mir_build_unreachable_matches_no_values)]
|
|
pub(crate) struct UnreachableMatchesNoValues<'tcx> {
|
|
pub(crate) ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
|
|
pub(crate) struct ConstPatternDependsOnGenericParameter {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_could_not_eval_const_pattern)]
|
|
pub(crate) struct CouldNotEvalConstPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)]
|
|
pub(crate) struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
#[note(mir_build_teach_note)]
|
|
pub(crate) teach: Option<()>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_literal_in_range_out_of_bounds)]
|
|
pub(crate) struct LiteralOutOfRange<'tcx> {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) ty: Ty<'tcx>,
|
|
pub(crate) min: i128,
|
|
pub(crate) max: u128,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)]
|
|
pub(crate) struct LowerRangeBoundMustBeLessThanUpper {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_leading_irrefutable_let_patterns)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct LeadingIrrefutableLetPatterns {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_trailing_irrefutable_let_patterns)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct TrailingIrrefutableLetPatterns {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_bindings_with_variant_name, code = E0170)]
|
|
pub(crate) struct BindingsWithVariantName {
|
|
#[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")]
|
|
pub(crate) suggestion: Option<Span>,
|
|
pub(crate) ty_path: String,
|
|
pub(crate) name: Symbol,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_irrefutable_let_patterns_if_let)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct IrrefutableLetPatternsIfLet {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_irrefutable_let_patterns_if_let_guard)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct IrrefutableLetPatternsIfLetGuard {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_irrefutable_let_patterns_let_else)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct IrrefutableLetPatternsLetElse {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_irrefutable_let_patterns_while_let)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct IrrefutableLetPatternsWhileLet {
|
|
pub(crate) count: usize,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_borrow_of_moved_value)]
|
|
pub(crate) struct BorrowOfMovedValue<'tcx> {
|
|
#[primary_span]
|
|
#[label]
|
|
#[label(mir_build_occurs_because_label)]
|
|
pub(crate) binding_span: Span,
|
|
#[label(mir_build_value_borrowed_label)]
|
|
pub(crate) conflicts_ref: Vec<Span>,
|
|
pub(crate) name: Symbol,
|
|
pub(crate) ty: Ty<'tcx>,
|
|
#[suggestion(code = "ref ", applicability = "machine-applicable")]
|
|
pub(crate) suggest_borrowing: Option<Span>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_multiple_mut_borrows)]
|
|
pub(crate) struct MultipleMutBorrows {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) occurrences: Vec<Conflict>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_already_borrowed)]
|
|
pub(crate) struct AlreadyBorrowed {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) occurrences: Vec<Conflict>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_already_mut_borrowed)]
|
|
pub(crate) struct AlreadyMutBorrowed {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) occurrences: Vec<Conflict>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_moved_while_borrowed)]
|
|
pub(crate) struct MovedWhileBorrowed {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) occurrences: Vec<Conflict>,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
pub(crate) enum Conflict {
|
|
#[label(mir_build_mutable_borrow)]
|
|
Mut {
|
|
#[primary_span]
|
|
span: Span,
|
|
name: Symbol,
|
|
},
|
|
#[label(mir_build_borrow)]
|
|
Ref {
|
|
#[primary_span]
|
|
span: Span,
|
|
name: Symbol,
|
|
},
|
|
#[label(mir_build_moved)]
|
|
Moved {
|
|
#[primary_span]
|
|
span: Span,
|
|
name: Symbol,
|
|
},
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_union_pattern)]
|
|
pub(crate) struct UnionPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_type_not_structural)]
|
|
#[note(mir_build_type_not_structural_tip)]
|
|
#[note(mir_build_type_not_structural_more_info)]
|
|
pub(crate) struct TypeNotStructural<'tcx> {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) non_sm_ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_non_partial_eq_match)]
|
|
pub(crate) struct TypeNotPartialEq<'tcx> {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) non_peq_ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_invalid_pattern)]
|
|
pub(crate) struct InvalidPattern<'tcx> {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) non_sm_ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_unsized_pattern)]
|
|
pub(crate) struct UnsizedPattern<'tcx> {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) non_sm_ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_nan_pattern)]
|
|
#[note]
|
|
#[help]
|
|
pub(crate) struct NaNPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_pointer_pattern)]
|
|
pub(crate) struct PointerPattern {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_non_empty_never_pattern)]
|
|
#[note]
|
|
pub(crate) struct NonEmptyNeverPattern<'tcx> {
|
|
#[primary_span]
|
|
#[label]
|
|
pub(crate) span: Span,
|
|
pub(crate) ty: Ty<'tcx>,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_exceeds_mcdc_condition_limit)]
|
|
pub(crate) struct MCDCExceedsConditionLimit {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) num_conditions: usize,
|
|
pub(crate) max_conditions: usize,
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_pattern_not_covered, code = E0005)]
|
|
pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) origin: &'s str,
|
|
#[subdiagnostic]
|
|
pub(crate) uncovered: Uncovered,
|
|
#[subdiagnostic]
|
|
pub(crate) inform: Option<Inform>,
|
|
#[subdiagnostic]
|
|
pub(crate) interpreted_as_const: Option<InterpretedAsConst>,
|
|
#[subdiagnostic]
|
|
pub(crate) adt_defined_here: Option<AdtDefinedHere<'tcx>>,
|
|
#[note(mir_build_privately_uninhabited)]
|
|
pub(crate) witness_1_is_privately_uninhabited: Option<()>,
|
|
#[note(mir_build_pattern_ty)]
|
|
pub(crate) _p: (),
|
|
pub(crate) pattern_ty: Ty<'tcx>,
|
|
#[subdiagnostic]
|
|
pub(crate) let_suggestion: Option<SuggestLet>,
|
|
#[subdiagnostic]
|
|
pub(crate) misc_suggestion: Option<MiscPatternSuggestion>,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[note(mir_build_inform_irrefutable)]
|
|
#[note(mir_build_more_information)]
|
|
pub(crate) struct Inform;
|
|
|
|
pub(crate) struct AdtDefinedHere<'tcx> {
|
|
pub(crate) adt_def_span: Span,
|
|
pub(crate) ty: Ty<'tcx>,
|
|
pub(crate) variants: Vec<Variant>,
|
|
}
|
|
|
|
pub(crate) struct Variant {
|
|
pub(crate) span: Span,
|
|
}
|
|
|
|
impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
|
|
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
|
self,
|
|
diag: &mut Diag<'_, G>,
|
|
_f: &F,
|
|
) {
|
|
diag.arg("ty", self.ty);
|
|
let mut spans = MultiSpan::from(self.adt_def_span);
|
|
|
|
for Variant { span } in self.variants {
|
|
spans.push_span_label(span, fluent::mir_build_variant_defined_here);
|
|
}
|
|
|
|
diag.span_note(spans, fluent::mir_build_adt_defined_here);
|
|
}
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[suggestion(
|
|
mir_build_interpreted_as_const,
|
|
code = "{variable}_var",
|
|
applicability = "maybe-incorrect"
|
|
)]
|
|
#[label(mir_build_confused)]
|
|
pub(crate) struct InterpretedAsConst {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
pub(crate) variable: String,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
pub(crate) enum SuggestLet {
|
|
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
|
|
If {
|
|
#[suggestion_part(code = "if ")]
|
|
start_span: Span,
|
|
#[suggestion_part(code = " {{ todo!() }}")]
|
|
semi_span: Span,
|
|
count: usize,
|
|
},
|
|
#[suggestion(
|
|
mir_build_suggest_let_else,
|
|
code = " else {{ todo!() }}",
|
|
applicability = "has-placeholders"
|
|
)]
|
|
Else {
|
|
#[primary_span]
|
|
end_span: Span,
|
|
count: usize,
|
|
},
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
pub(crate) enum MiscPatternSuggestion {
|
|
#[suggestion(
|
|
mir_build_suggest_attempted_int_lit,
|
|
code = "_",
|
|
applicability = "maybe-incorrect"
|
|
)]
|
|
AttemptedIntegerLiteral {
|
|
#[primary_span]
|
|
start_span: Span,
|
|
},
|
|
}
|
|
|
|
#[derive(Diagnostic)]
|
|
#[diag(mir_build_rustc_box_attribute_error)]
|
|
pub(crate) struct RustcBoxAttributeError {
|
|
#[primary_span]
|
|
pub(crate) span: Span,
|
|
#[subdiagnostic]
|
|
pub(crate) reason: RustcBoxAttrReason,
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
pub(crate) enum RustcBoxAttrReason {
|
|
#[note(mir_build_attributes)]
|
|
Attributes,
|
|
#[note(mir_build_not_box)]
|
|
NotBoxNew,
|
|
#[note(mir_build_missing_box)]
|
|
MissingBox,
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[diag(mir_build_rust_2024_incompatible_pat)]
|
|
pub(crate) struct Rust2024IncompatiblePat {
|
|
#[subdiagnostic]
|
|
pub(crate) sugg: Rust2024IncompatiblePatSugg,
|
|
}
|
|
|
|
pub(crate) struct Rust2024IncompatiblePatSugg {
|
|
pub(crate) suggestion: Vec<(Span, String)>,
|
|
}
|
|
|
|
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
|
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
|
self,
|
|
diag: &mut Diag<'_, G>,
|
|
_f: &F,
|
|
) {
|
|
let applicability =
|
|
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
|
|
Applicability::MachineApplicable
|
|
} else {
|
|
Applicability::MaybeIncorrect
|
|
};
|
|
diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability);
|
|
}
|
|
}
|