Do not allow safe usafe on static and fn items
This commit is contained in:
parent
d40f30e1df
commit
22831ed117
8 changed files with 219 additions and 34 deletions
|
@ -456,15 +456,29 @@ impl<'a> AstValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
|
||||
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
|
||||
&& (self.extern_mod_safety == Some(Safety::Default)
|
||||
|| !self.features.unsafe_extern_blocks)
|
||||
{
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
|
||||
item_span,
|
||||
block: self.current_extern_span(),
|
||||
});
|
||||
fn check_item_safety(&self, span: Span, safety: Safety) {
|
||||
match self.extern_mod_safety {
|
||||
Some(extern_safety) => {
|
||||
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
|
||||
&& (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks)
|
||||
{
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
|
||||
item_span: span,
|
||||
block: self.current_extern_span(),
|
||||
});
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if matches!(safety, Safety::Safe(_)) {
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnItem { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_bare_fn_safety(&self, span: Span, safety: Safety) {
|
||||
if matches!(safety, Safety::Safe(_)) {
|
||||
self.dcx().emit_err(errors::InvalidSafetyOnBareFn { span });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,6 +760,7 @@ impl<'a> AstValidator<'a> {
|
|||
fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
match &ty.kind {
|
||||
TyKind::BareFn(bfty) => {
|
||||
self.check_bare_fn_safety(bfty.decl_span, bfty.safety);
|
||||
self.check_fn_decl(&bfty.decl, SelfSemantic::No);
|
||||
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
|
||||
self.dcx().emit_err(errors::PatternFnPointer { span });
|
||||
|
@ -1174,11 +1189,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
});
|
||||
}
|
||||
}
|
||||
ItemKind::Static(box StaticItem { expr: None, .. }) => {
|
||||
self.dcx().emit_err(errors::StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
ItemKind::Static(box StaticItem { expr, safety, .. }) => {
|
||||
self.check_item_safety(item.span, *safety);
|
||||
|
||||
if expr.is_none() {
|
||||
self.dcx().emit_err(errors::StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
ItemKind::TyAlias(
|
||||
ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
|
||||
|
@ -1212,7 +1231,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||
match &fi.kind {
|
||||
ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
|
||||
self.check_foreign_item_safety(fi.span, sig.header.safety);
|
||||
self.check_defaultness(fi.span, *defaultness);
|
||||
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
|
||||
self.check_foreign_fn_headerless(sig.header);
|
||||
|
@ -1233,7 +1251,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {
|
||||
self.check_foreign_item_safety(fi.span, *safety);
|
||||
self.check_item_safety(fi.span, *safety);
|
||||
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
|
||||
self.check_foreign_item_ascii_only(fi.ident);
|
||||
}
|
||||
|
@ -1453,6 +1471,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
};
|
||||
self.check_fn_decl(fk.decl(), self_semantic);
|
||||
|
||||
if let Some(&FnHeader { safety, .. }) = fk.header() {
|
||||
self.check_item_safety(span, safety);
|
||||
}
|
||||
|
||||
self.check_c_variadic_type(fk);
|
||||
|
||||
// Functions cannot both be `const async` or `const gen`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue