Skip to content

Commit

Permalink
Migrate rustc_hir_analysis to session diagnostic
Browse files Browse the repository at this point in the history
Part one, lib.rs file
  • Loading branch information
obeis committed Feb 24, 2023
1 parent 07c993e commit 34966aa
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 63 deletions.
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

0 comments on commit 34966aa

Please sign in to comment.