Rollup merge of #108760 - clubby789:autolintstuff, r=wesleywiser

Add lint to deny diagnostics composed of static strings

r? ghost

I'm hoping to have a lint that semi-automatically converts simple diagnostics such as `struct_span_err(span, "msg").help("msg").span_note(span2, "msg").emit()` to typed session diagnostics. It's quite hacky and not entirely working because of problems with `x fix` but should hopefully help reduce some of the work.
I'm going to start trying to apply what I can from this, but opening this as a draft in case anyone wants to develop on it.

cc #100717
This commit is contained in:
Matthias Krüger 2023-04-26 18:51:40 +02:00 committed by GitHub
commit 309496cf29
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 578 additions and 201 deletions

View file

@ -170,9 +170,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if matches!(tcx.def_kind(def_id), DefKind::Static(_)
if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) =>
{
tcx.sess
.struct_span_err(span, "extern static is too large for the current architecture")
.emit();
tcx.sess.emit_err(errors::TooLargeStatic { span });
return;
}
// Generic statics are rejected, but we still reach this case.

View file

@ -5,6 +5,7 @@
// done by the orphan and overlap modules. Then we build up various
// mappings. That mapping code resides here.
use crate::errors;
use rustc_errors::{error_code, struct_span_err};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::query::Providers;
@ -67,13 +68,7 @@ fn enforce_trait_manually_implementable(
tcx.trait_def(trait_def_id).specialization_kind
{
if !tcx.features().specialization && !tcx.features().min_specialization {
tcx.sess
.struct_span_err(
impl_header_span,
"implementing `rustc_specialization_trait` traits is unstable",
)
.help("add `#![feature(min_specialization)]` to the crate attributes to enable")
.emit();
tcx.sess.emit_err(errors::SpecializationTrait { span: impl_header_span });
return;
}
}

View file

@ -455,13 +455,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
.collect::<Vec<_>>();
if !infer_spans.is_empty() {
self.tcx.sess
.struct_span_err(
infer_spans,
"implicit types in closure signatures are forbidden when `for<...>` is present",
)
.span_label(for_sp, "`for<...>` is here")
.emit();
self.tcx
.sess
.emit_err(errors::ClosureImplicitHrtb { spans: infer_spans, for_sp });
}
}

View file

@ -633,6 +633,7 @@ pub(crate) struct SIMDFFIHighlyExperimental {
}
#[derive(Diagnostic)]
pub enum ImplNotMarkedDefault {
#[diag(hir_analysis_impl_not_marked_default, code = "E0520")]
#[note]
@ -769,3 +770,48 @@ pub(crate) struct TransparentNonZeroSized<'a> {
pub field_count: usize,
pub desc: &'a str,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_too_large_static)]
pub(crate) struct TooLargeStatic {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_specialization_trait)]
#[help]
pub(crate) struct SpecializationTrait {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_closure_implicit_hrtb)]
pub(crate) struct ClosureImplicitHrtb {
#[primary_span]
pub spans: Vec<Span>,
#[label]
pub for_sp: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_const_specialize)]
pub(crate) struct ConstSpecialize {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_static_specialize)]
pub(crate) struct StaticSpecialize {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_missing_tilde_const)]
pub(crate) struct MissingTildeConst {
#[primary_span]
pub span: Span,
}

View file

@ -65,8 +65,8 @@
//! cause use after frees with purely safe code in the same way as specializing
//! on traits with methods can.
use crate::constrained_generic_params as cgp;
use crate::errors::SubstsOnOverriddenImpl;
use crate::{constrained_generic_params as cgp, errors};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
@ -137,9 +137,7 @@ fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node,
if let hir::Constness::Const = impl2_constness {
if let hir::Constness::NotConst = impl1_constness {
tcx.sess
.struct_span_err(span, "cannot specialize on const impl with non-const impl")
.emit();
tcx.sess.emit_err(errors::ConstSpecialize { span });
}
}
}
@ -293,7 +291,7 @@ fn check_static_lifetimes<'tcx>(
span: Span,
) {
if tcx.any_free_region_meets(parent_substs, |r| r.is_static()) {
tcx.sess.struct_span_err(span, "cannot specialize on `'static` lifetime").emit();
tcx.sess.emit_err(errors::StaticSpecialize { span });
}
}
@ -438,7 +436,7 @@ fn trait_predicates_eq<'tcx>(
// the one on the base.
match (trait_pred2.constness, trait_pred1.constness) {
(ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
tcx.sess.struct_span_err(span, "missing `~const` qualifier for specialization").emit();
tcx.sess.emit_err(errors::MissingTildeConst { span });
}
_ => {}
}