Auto merge of #127357 - oli-obk:structureddiag, r=fmease
Remove `StructuredDiag` follow-up to https://github.com/rust-lang/rust/pull/127319 This trait was an experiment that didn't pan out.
This commit is contained in:
commit
cd3d98b3be
10 changed files with 81 additions and 161 deletions
|
@ -373,10 +373,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
|
|||
hir_analysis_parenthesized_fn_trait_expansion =
|
||||
parenthesized trait syntax expands to `{$expanded_type}`
|
||||
|
||||
hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function
|
||||
.suggestion = cast the value to `{$cast_ty}`
|
||||
.help = cast the value to `{$cast_ty}`
|
||||
|
||||
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
|
||||
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
|
||||
.label = this type is the same as the inner type without a pattern
|
||||
|
|
|
@ -9,6 +9,7 @@ use rustc_middle::ty::Ty;
|
|||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
mod pattern_types;
|
||||
pub use pattern_types::*;
|
||||
pub mod wrong_number_of_generic_args;
|
||||
|
||||
mod precise_captures;
|
||||
pub(crate) use precise_captures::*;
|
||||
|
@ -692,20 +693,6 @@ pub(crate) struct TypeOf<'tcx> {
|
|||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_pass_to_variadic_function, code = E0617)]
|
||||
pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub cast_ty: &'a str,
|
||||
#[suggestion(code = "{replace}", applicability = "machine-applicable")]
|
||||
pub sugg_span: Option<Span>,
|
||||
pub replace: String,
|
||||
#[help]
|
||||
pub help: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_union_field, code = E0740)]
|
||||
pub(crate) struct InvalidUnionField {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::structured_errors::StructuredDiag;
|
||||
use rustc_errors::{codes::*, pluralize, Applicability, Diag, MultiSpan};
|
||||
use rustc_errors::{
|
||||
codes::*, pluralize, Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::def_id::DefId;
|
||||
use std::iter;
|
||||
|
||||
|
@ -541,14 +541,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn start_diagnostics(&self) -> Diag<'tcx> {
|
||||
let span = self.path_segment.ident.span;
|
||||
let msg = self.create_error_message();
|
||||
self.tcx.dcx().struct_span_err(span, msg).with_code(self.code())
|
||||
}
|
||||
|
||||
/// Builds the `expected 1 type argument / supplied 2 type arguments` message.
|
||||
fn notify(&self, err: &mut Diag<'_>) {
|
||||
fn notify(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
let (quantifier, bound) = self.get_quantifier_and_bound();
|
||||
let provided_args = self.num_provided_args();
|
||||
|
||||
|
@ -600,7 +594,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest(&self, err: &mut Diag<'_>) {
|
||||
fn suggest(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
debug!(
|
||||
"suggest(self.provided {:?}, self.gen_args.span(): {:?})",
|
||||
self.num_provided_args(),
|
||||
|
@ -628,7 +622,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
/// ```text
|
||||
/// type Map = HashMap<String>;
|
||||
/// ```
|
||||
fn suggest_adding_args(&self, err: &mut Diag<'_>) {
|
||||
fn suggest_adding_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
if self.gen_args.parenthesized != hir::GenericArgsParentheses::No {
|
||||
return;
|
||||
}
|
||||
|
@ -647,7 +641,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_>) {
|
||||
fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
|
||||
let num_missing_args = self.num_missing_lifetime_args();
|
||||
let num_params_to_take = num_missing_args;
|
||||
|
@ -701,7 +695,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_>) {
|
||||
fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
let num_missing_args = self.num_missing_type_or_const_args();
|
||||
let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
|
||||
|
||||
|
@ -761,7 +755,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
/// ```compile_fail
|
||||
/// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
|
||||
/// ```
|
||||
fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diag<'_>) {
|
||||
fn suggest_moving_args_from_assoc_fn_to_trait(
|
||||
&self,
|
||||
err: &mut Diag<'_, impl EmissionGuarantee>,
|
||||
) {
|
||||
let trait_ = match self.tcx.trait_of_item(self.def_id) {
|
||||
Some(def_id) => def_id,
|
||||
None => return,
|
||||
|
@ -817,7 +814,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
|
||||
fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
err: &mut Diag<'_, impl EmissionGuarantee>,
|
||||
qpath: &'tcx hir::QPath<'tcx>,
|
||||
msg: String,
|
||||
num_assoc_fn_excess_args: usize,
|
||||
|
@ -850,7 +847,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
|
||||
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
err: &mut Diag<'_, impl EmissionGuarantee>,
|
||||
trait_def_id: DefId,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
msg: String,
|
||||
|
@ -904,7 +901,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
/// ```text
|
||||
/// type Map = HashMap<String, String, String, String>;
|
||||
/// ```
|
||||
fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_>) {
|
||||
fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
let num_provided_lt_args = self.num_provided_lifetime_args();
|
||||
let num_provided_type_const_args = self.num_provided_type_or_const_args();
|
||||
let unbound_types = self.get_unbound_associated_types();
|
||||
|
@ -922,7 +919,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
let provided_args_matches_unbound_traits =
|
||||
unbound_types.len() == num_redundant_type_or_const_args;
|
||||
|
||||
let remove_lifetime_args = |err: &mut Diag<'_>| {
|
||||
let remove_lifetime_args = |err: &mut Diag<'_, _>| {
|
||||
let mut lt_arg_spans = Vec::new();
|
||||
let mut found_redundant = false;
|
||||
for arg in self.gen_args.args {
|
||||
|
@ -963,7 +960,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
);
|
||||
};
|
||||
|
||||
let remove_type_or_const_args = |err: &mut Diag<'_>| {
|
||||
let remove_type_or_const_args = |err: &mut Diag<'_, _>| {
|
||||
let mut gen_arg_spans = Vec::new();
|
||||
let mut found_redundant = false;
|
||||
for arg in self.gen_args.args {
|
||||
|
@ -1060,7 +1057,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Builds the `type defined here` message.
|
||||
fn show_definition(&self, err: &mut Diag<'_>) {
|
||||
fn show_definition(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) {
|
||||
if self.tcx.sess.source_map().is_span_accessible(def_span) {
|
||||
def_span.into()
|
||||
|
@ -1111,7 +1108,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Add note if `impl Trait` is explicitly specified.
|
||||
fn note_synth_provided(&self, err: &mut Diag<'_>) {
|
||||
fn note_synth_provided(&self, err: &mut Diag<'_, impl EmissionGuarantee>) {
|
||||
if !self.is_synth_provided() {
|
||||
return;
|
||||
}
|
||||
|
@ -1120,17 +1117,16 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> StructuredDiag<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
|
||||
fn session(&self) -> &Session {
|
||||
self.tcx.sess
|
||||
}
|
||||
|
||||
fn code(&self) -> ErrCode {
|
||||
E0107
|
||||
}
|
||||
|
||||
fn diagnostic_common(&self) -> Diag<'tcx> {
|
||||
let mut err = self.start_diagnostics();
|
||||
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for WrongNumberOfGenericArgs<'_, '_> {
|
||||
fn into_diag(
|
||||
self,
|
||||
dcx: rustc_errors::DiagCtxtHandle<'a>,
|
||||
level: rustc_errors::Level,
|
||||
) -> Diag<'a, G> {
|
||||
let msg = self.create_error_message();
|
||||
let mut err = Diag::new(dcx, level, msg);
|
||||
err.code(E0107);
|
||||
err.span(self.path_segment.ident.span);
|
||||
|
||||
self.notify(&mut err);
|
||||
self.suggest(&mut err);
|
|
@ -1,9 +1,9 @@
|
|||
use super::IsMethodCall;
|
||||
use crate::errors::wrong_number_of_generic_args::{GenericArgsInfo, WrongNumberOfGenericArgs};
|
||||
use crate::hir_ty_lowering::{
|
||||
errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch,
|
||||
GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
|
||||
};
|
||||
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
|
||||
use rustc_ast::ast::ParamKindOrd;
|
||||
use rustc_errors::{
|
||||
codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan,
|
||||
|
@ -486,7 +486,7 @@ pub(crate) fn check_generic_arg_count(
|
|||
GenericArgsInfo::MissingLifetimes { num_missing_args }
|
||||
};
|
||||
|
||||
let reported = WrongNumberOfGenericArgs::new(
|
||||
let reported = tcx.dcx().emit_err(WrongNumberOfGenericArgs::new(
|
||||
tcx,
|
||||
gen_args_info,
|
||||
seg,
|
||||
|
@ -494,9 +494,7 @@ pub(crate) fn check_generic_arg_count(
|
|||
has_self as usize,
|
||||
gen_args,
|
||||
def_id,
|
||||
)
|
||||
.diagnostic()
|
||||
.emit();
|
||||
));
|
||||
|
||||
Err(reported)
|
||||
};
|
||||
|
@ -573,17 +571,17 @@ pub(crate) fn check_generic_arg_count(
|
|||
debug!(?gen_args_info);
|
||||
|
||||
let reported = gen_args.has_err().unwrap_or_else(|| {
|
||||
WrongNumberOfGenericArgs::new(
|
||||
tcx,
|
||||
gen_args_info,
|
||||
seg,
|
||||
gen_params,
|
||||
params_offset,
|
||||
gen_args,
|
||||
def_id,
|
||||
)
|
||||
.diagnostic()
|
||||
.emit_unless(all_params_are_binded)
|
||||
tcx.dcx()
|
||||
.create_err(WrongNumberOfGenericArgs::new(
|
||||
tcx,
|
||||
gen_args_info,
|
||||
seg,
|
||||
gen_params,
|
||||
params_offset,
|
||||
gen_args,
|
||||
def_id,
|
||||
))
|
||||
.emit_unless(all_params_are_binded)
|
||||
});
|
||||
|
||||
Err(reported)
|
||||
|
|
|
@ -92,7 +92,6 @@ mod errors;
|
|||
pub mod hir_wf_check;
|
||||
mod impl_wf_check;
|
||||
mod outlives;
|
||||
pub mod structured_errors;
|
||||
mod variance;
|
||||
|
||||
use rustc_hir as hir;
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
mod missing_cast_for_variadic_arg;
|
||||
mod wrong_number_of_generic_args;
|
||||
|
||||
pub use self::{missing_cast_for_variadic_arg::*, wrong_number_of_generic_args::*};
|
||||
|
||||
use rustc_errors::{Diag, ErrCode};
|
||||
use rustc_session::Session;
|
||||
|
||||
pub trait StructuredDiag<'tcx> {
|
||||
fn session(&self) -> &Session;
|
||||
|
||||
fn code(&self) -> ErrCode;
|
||||
|
||||
fn diagnostic(&self) -> Diag<'tcx> {
|
||||
let err = self.diagnostic_common();
|
||||
|
||||
if self.session().teach(self.code()) {
|
||||
self.diagnostic_extended(err)
|
||||
} else {
|
||||
self.diagnostic_regular(err)
|
||||
}
|
||||
}
|
||||
|
||||
fn diagnostic_common(&self) -> Diag<'tcx>;
|
||||
|
||||
fn diagnostic_regular(&self, err: Diag<'tcx>) -> Diag<'tcx> {
|
||||
err
|
||||
}
|
||||
|
||||
fn diagnostic_extended(&self, err: Diag<'tcx>) -> Diag<'tcx> {
|
||||
err
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
use crate::{errors, structured_errors::StructuredDiag};
|
||||
use rustc_errors::{codes::*, Diag};
|
||||
use rustc_middle::ty::{Ty, TypeVisitableExt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Span;
|
||||
|
||||
pub struct MissingCastForVariadicArg<'tcx, 's> {
|
||||
pub sess: &'tcx Session,
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub cast_ty: &'s str,
|
||||
}
|
||||
|
||||
impl<'tcx> StructuredDiag<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
|
||||
fn session(&self) -> &Session {
|
||||
self.sess
|
||||
}
|
||||
|
||||
fn code(&self) -> ErrCode {
|
||||
E0617
|
||||
}
|
||||
|
||||
fn diagnostic_common(&self) -> Diag<'tcx> {
|
||||
let (sugg_span, replace, help) =
|
||||
if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) {
|
||||
(Some(self.span), format!("{} as {}", snippet, self.cast_ty), None)
|
||||
} else {
|
||||
(None, "".to_string(), Some(()))
|
||||
};
|
||||
|
||||
let mut err = self.sess.dcx().create_err(errors::PassToVariadicFunction {
|
||||
span: self.span,
|
||||
ty: self.ty,
|
||||
cast_ty: self.cast_ty,
|
||||
help,
|
||||
replace,
|
||||
sugg_span,
|
||||
});
|
||||
|
||||
if self.ty.references_error() {
|
||||
err.downgrade_to_delayed_bug();
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
fn diagnostic_extended(&self, mut err: Diag<'tcx>) -> Diag<'tcx> {
|
||||
err.note(format!(
|
||||
"certain types, like `{}`, must be casted before passing them to a \
|
||||
variadic function, because of arcane ABI rules dictated by the C \
|
||||
standard",
|
||||
self.ty
|
||||
));
|
||||
|
||||
err
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ hir_typeck_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_t
|
|||
|
||||
For more information about casts, take a look at The Book:
|
||||
https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",
|
||||
|
||||
hir_typeck_cast_unknown_pointer = cannot cast {$to ->
|
||||
[true] to
|
||||
*[false] from
|
||||
|
@ -138,6 +139,11 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte
|
|||
hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
|
||||
hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
|
||||
|
||||
hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
|
||||
.suggestion = cast the value to `{$cast_ty}`
|
||||
.help = cast the value to `{$cast_ty}`
|
||||
.teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard
|
||||
|
||||
hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len ->
|
||||
[1] an auto trait {$traits}
|
||||
*[other] auto traits {$traits}
|
||||
|
|
|
@ -708,3 +708,19 @@ pub(crate) struct CastThinPointerToFatPointer<'tcx> {
|
|||
#[note(hir_typeck_teach_help)]
|
||||
pub(crate) teach: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_pass_to_variadic_function, code = E0617)]
|
||||
pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub cast_ty: &'a str,
|
||||
#[suggestion(code = "{replace}", applicability = "machine-applicable")]
|
||||
pub sugg_span: Option<Span>,
|
||||
pub replace: String,
|
||||
#[help]
|
||||
pub help: Option<()>,
|
||||
#[note(hir_typeck_teach_help)]
|
||||
pub(crate) teach: Option<()>,
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ use rustc_hir::{ExprKind, HirId, Node, QPath};
|
|||
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
||||
use rustc_hir_analysis::check::potentially_plural_count;
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||
use rustc_hir_analysis::structured_errors::StructuredDiag;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
|
@ -406,9 +405,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
cast_ty: &str,
|
||||
) {
|
||||
use rustc_hir_analysis::structured_errors::MissingCastForVariadicArg;
|
||||
let (sugg_span, replace, help) =
|
||||
if let Ok(snippet) = sess.source_map().span_to_snippet(span) {
|
||||
(Some(span), format!("{snippet} as {cast_ty}"), None)
|
||||
} else {
|
||||
(None, "".to_string(), Some(()))
|
||||
};
|
||||
|
||||
MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
|
||||
sess.dcx().emit_err(errors::PassToVariadicFunction {
|
||||
span,
|
||||
ty,
|
||||
cast_ty,
|
||||
help,
|
||||
replace,
|
||||
sugg_span,
|
||||
teach: sess.teach(E0617).then_some(()),
|
||||
});
|
||||
}
|
||||
|
||||
// There are a few types which get autopromoted when passed via varargs
|
||||
|
|
Loading…
Add table
Reference in a new issue