Enforce crate level attributes checks
This commit is contained in:
parent
6ec2474622
commit
3641a37455
10 changed files with 377 additions and 372 deletions
|
@ -19,8 +19,8 @@ use rustc_hir::{
|
|||
use rustc_hir::{MethodKind, Target};
|
||||
use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
pub(crate) fn target_from_impl_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -821,6 +821,33 @@ fn is_c_like_enum(item: &Item<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
||||
const ATTRS_TO_CHECK: &[Symbol] = &[
|
||||
sym::macro_export,
|
||||
sym::repr,
|
||||
sym::path,
|
||||
sym::automatically_derived,
|
||||
sym::start,
|
||||
sym::main,
|
||||
];
|
||||
|
||||
for attr in attrs {
|
||||
for attr_to_check in ATTRS_TO_CHECK {
|
||||
if tcx.sess.check_name(attr, *attr_to_check) {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
&format!(
|
||||
"`{}` attribute cannot be used at crate level",
|
||||
attr_to_check.to_ident_string()
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
||||
tcx.hir()
|
||||
.visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor());
|
||||
|
@ -828,10 +855,11 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
|||
CheckAttrVisitor { tcx }.check_attributes(
|
||||
CRATE_HIR_ID,
|
||||
tcx.hir().krate_attrs(),
|
||||
&tcx.hir().span(CRATE_HIR_ID),
|
||||
&DUMMY_SP,
|
||||
Target::Mod,
|
||||
None,
|
||||
);
|
||||
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,29 +78,38 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
|
|||
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
|
||||
// (with `ast::Item`), so make sure to keep them in sync.
|
||||
fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPointType {
|
||||
match item.kind {
|
||||
ItemKind::Fn(..) => {
|
||||
if sess.contains_name(&item.attrs, sym::start) {
|
||||
EntryPointType::Start
|
||||
} else if sess.contains_name(&item.attrs, sym::main) {
|
||||
EntryPointType::MainAttr
|
||||
} else if item.ident.name == sym::main {
|
||||
if at_root {
|
||||
// This is a top-level function so can be `main`.
|
||||
EntryPointType::MainNamed
|
||||
} else {
|
||||
EntryPointType::OtherMain
|
||||
}
|
||||
} else {
|
||||
EntryPointType::None
|
||||
}
|
||||
if sess.contains_name(&item.attrs, sym::start) {
|
||||
EntryPointType::Start
|
||||
} else if sess.contains_name(&item.attrs, sym::main) {
|
||||
EntryPointType::MainAttr
|
||||
} else if item.ident.name == sym::main {
|
||||
if at_root {
|
||||
// This is a top-level function so can be `main`.
|
||||
EntryPointType::MainNamed
|
||||
} else {
|
||||
EntryPointType::OtherMain
|
||||
}
|
||||
_ => EntryPointType::None,
|
||||
} else {
|
||||
EntryPointType::None
|
||||
}
|
||||
}
|
||||
|
||||
fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
|
||||
sess.struct_span_err(span, &format!("`{}` attribute can only be used on functions", attr))
|
||||
.emit();
|
||||
}
|
||||
|
||||
fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
|
||||
match entry_point_type(&ctxt.session, item, at_root) {
|
||||
EntryPointType::None => (),
|
||||
_ if !matches!(item.kind, ItemKind::Fn(..)) => {
|
||||
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::start) {
|
||||
throw_attr_err(&ctxt.session, attr.span, "start");
|
||||
}
|
||||
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::main) {
|
||||
throw_attr_err(&ctxt.session, attr.span, "main");
|
||||
}
|
||||
}
|
||||
EntryPointType::MainNamed => {
|
||||
if ctxt.main_fn.is_none() {
|
||||
ctxt.main_fn = Some((item.hir_id, item.span));
|
||||
|
@ -137,7 +146,6 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
|
|||
.emit();
|
||||
}
|
||||
}
|
||||
EntryPointType::None => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue