Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate rustc_hir_analysis to session diagnostic [Part One] #108434

Merged
merged 1 commit into from
Feb 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions compiler/rustc_hir_analysis/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,26 @@ hir_analysis_where_clause_on_main = `main` function is not allowed to have a `wh
hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
.label = `main` function is not allowed to be `#[track_caller]`
hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]`
.label = `start` is not allowed to be `#[track_caller]`
hir_analysis_start_not_async = `start` is not allowed to be `async`
.label = `start` is not allowed to be `async`
hir_analysis_start_function_where = start function is not allowed to have a `where` clause
.label = start function cannot have a `where` clause
hir_analysis_start_function_parameters = start function is not allowed to have type parameters
.label = start function cannot have type parameters
hir_analysis_main_function_return_type_generic = `main` function return type is not allowed to have generic parameters
hir_analysis_main_function_async = `main` function is not allowed to be `async`
.label = `main` function is not allowed to be `async`
hir_analysis_main_function_generic_parameters = `main` function is not allowed to have generic parameters
.label = `main` cannot have generic parameters
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
.label = C-variadic function must have a compatible calling convention
67 changes: 67 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,70 @@ pub(crate) struct TrackCallerOnMain {
#[label]
pub annotated: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_not_track_caller)]
pub(crate) struct StartTrackCaller {
#[primary_span]
pub span: Span,
#[label]
pub start: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_not_async, code = "E0752")]
pub(crate) struct StartAsync {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_function_where, code = "E0647")]
pub(crate) struct StartFunctionWhere {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_start_function_parameters, code = "E0132")]
pub(crate) struct StartFunctionParameters {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")]
pub(crate) struct MainFunctionReturnTypeGeneric {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_main_function_async, code = "E0752")]
pub(crate) struct MainFunctionAsync {
#[primary_span]
pub span: Span,
#[label]
pub asyncness: Option<Span>,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")]
pub(crate) struct MainFunctionGenericParameters {
#[primary_span]
pub span: Span,
#[label]
pub label_span: Option<Span>,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")]
pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
#[primary_span]
#[label]
pub span: Span,
pub conventions: &'a str,
}
80 changes: 17 additions & 63 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ mod outlives;
pub mod structured_errors;
mod variance;

use rustc_errors::{struct_span_err, ErrorGuaranteed};
use rustc_errors::ErrorGuaranteed;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::Node;
Expand All @@ -123,7 +123,6 @@ use bounds::Bounds;
fluent_messages! { "../locales/en-US.ftl" }

fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention";
const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
const UNSTABLE_EXPLAIN: &str =
Expand Down Expand Up @@ -155,8 +154,7 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
(true, false) => CONVENTIONS_UNSTABLE,
};

let mut err = struct_span_err!(tcx.sess, span, E0045, "{}, like {}", ERROR_HEAD, conventions);
err.span_label(span, ERROR_HEAD).emit();
tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
}

fn require_same_types<'tcx>(
Expand Down Expand Up @@ -258,15 +256,10 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let main_fn_predicates = tcx.predicates_of(main_def_id);
if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
let msg = "`main` function is not allowed to have generic \
parameters";
let mut diag =
struct_span_err!(tcx.sess, generics_param_span.unwrap_or(main_span), E0131, "{}", msg);
if let Some(generics_param_span) = generics_param_span {
let label = "`main` cannot have generic parameters";
diag.span_label(generics_param_span, label);
}
diag.emit();
tcx.sess.emit_err(errors::MainFunctionGenericParameters {
span: generics_param_span.unwrap_or(main_span),
label_span: generics_param_span,
});
error = true;
} else if !main_fn_predicates.predicates.is_empty() {
// generics may bring in implicit predicates, so we skip this check if generics is present.
Expand All @@ -280,17 +273,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {

let main_asyncness = tcx.asyncness(main_def_id);
if let hir::IsAsync::Async = main_asyncness {
let mut diag = struct_span_err!(
tcx.sess,
main_span,
E0752,
"`main` function is not allowed to be `async`"
);
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
if let Some(asyncness_span) = asyncness_span {
diag.span_label(asyncness_span, "`main` function is not allowed to be `async`");
}
diag.emit();
tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
error = true;
}

Expand All @@ -308,9 +292,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
let return_ty = main_fnsig.output();
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
if !return_ty.bound_vars().is_empty() {
let msg = "`main` function return type is not allowed to have generic \
parameters";
struct_span_err!(tcx.sess, return_ty_span, E0131, "{}", msg).emit();
tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
error = true;
}
let return_ty = return_ty.skip_binder();
Expand Down Expand Up @@ -367,56 +349,28 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
let mut error = false;
if !generics.params.is_empty() {
struct_span_err!(
tcx.sess,
generics.span,
E0132,
"start function is not allowed to have type parameters"
)
.span_label(generics.span, "start function cannot have type parameters")
.emit();
tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
error = true;
}
if generics.has_where_clause_predicates {
struct_span_err!(
tcx.sess,
generics.where_clause_span,
E0647,
"start function is not allowed to have a `where` clause"
)
.span_label(
generics.where_clause_span,
"start function cannot have a `where` clause",
)
.emit();
tcx.sess.emit_err(errors::StartFunctionWhere {
span: generics.where_clause_span,
});
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
let span = tcx.def_span(it.owner_id);
struct_span_err!(
tcx.sess,
span,
E0752,
"`start` is not allowed to be `async`"
)
.span_label(span, "`start` is not allowed to be `async`")
.emit();
tcx.sess.emit_err(errors::StartAsync { span: span });
error = true;
}

let attrs = tcx.hir().attrs(start_id);
for attr in attrs {
if attr.has_name(sym::track_caller) {
tcx.sess
.struct_span_err(
attr.span,
"`start` is not allowed to be `#[track_caller]`",
)
.span_label(
start_span,
"`start` is not allowed to be `#[track_caller]`",
)
.emit();
tcx.sess.emit_err(errors::StartTrackCaller {
span: attr.span,
start: start_span,
});
error = true;
}
}
Expand Down