Do not allow safe usafe on static and fn items · rust-lang/rust@22831ed
@@ -456,15 +456,29 @@ impl<'a> AstValidator<'a> {
456456}
457457}
458458459-fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
460-if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
461-&& (self.extern_mod_safety == Some(Safety::Default)
462- || !self.features.unsafe_extern_blocks)
463-{
464-self.dcx().emit_err(errors::InvalidSafetyOnExtern {
465- item_span,
466-block: self.current_extern_span(),
467-});
459+fn check_item_safety(&self, span: Span, safety: Safety) {
460+match self.extern_mod_safety {
461+Some(extern_safety) => {
462+if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
463+&& (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks)
464+{
465+self.dcx().emit_err(errors::InvalidSafetyOnExtern {
466+item_span: span,
467+block: self.current_extern_span(),
468+});
469+}
470+}
471+None => {
472+if matches!(safety, Safety::Safe(_)) {
473+self.dcx().emit_err(errors::InvalidSafetyOnItem { span });
474+}
475+}
476+}
477+}
478+479+fn check_bare_fn_safety(&self, span: Span, safety: Safety) {
480+if matches!(safety, Safety::Safe(_)) {
481+self.dcx().emit_err(errors::InvalidSafetyOnBareFn { span });
468482}
469483}
470484@@ -746,6 +760,7 @@ impl<'a> AstValidator<'a> {
746760fn visit_ty_common(&mut self, ty: &'a Ty) {
747761match &ty.kind {
748762TyKind::BareFn(bfty) => {
763+self.check_bare_fn_safety(bfty.decl_span, bfty.safety);
749764self.check_fn_decl(&bfty.decl, SelfSemantic::No);
750765Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
751766self.dcx().emit_err(errors::PatternFnPointer { span });
@@ -1174,11 +1189,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11741189});
11751190}
11761191}
1177-ItemKind::Static(box StaticItem { expr: None, .. }) => {
1178-self.dcx().emit_err(errors::StaticWithoutBody {
1179-span: item.span,
1180-replace_span: self.ending_semi_or_hi(item.span),
1181-});
1192+ItemKind::Static(box StaticItem { expr, safety, .. }) => {
1193+self.check_item_safety(item.span, *safety);
1194+1195+if expr.is_none() {
1196+self.dcx().emit_err(errors::StaticWithoutBody {
1197+span: item.span,
1198+replace_span: self.ending_semi_or_hi(item.span),
1199+});
1200+}
11821201}
11831202ItemKind::TyAlias(
11841203 ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
@@ -1212,7 +1231,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12121231fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
12131232match &fi.kind {
12141233ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
1215-self.check_foreign_item_safety(fi.span, sig.header.safety);
12161234self.check_defaultness(fi.span, *defaultness);
12171235self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
12181236self.check_foreign_fn_headerless(sig.header);
@@ -1233,7 +1251,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12331251self.check_foreign_item_ascii_only(fi.ident);
12341252}
12351253ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {
1236-self.check_foreign_item_safety(fi.span, *safety);
1254+self.check_item_safety(fi.span, *safety);
12371255self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
12381256self.check_foreign_item_ascii_only(fi.ident);
12391257}
@@ -1453,6 +1471,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14531471};
14541472self.check_fn_decl(fk.decl(), self_semantic);
145514731474+if let Some(&FnHeader { safety, .. }) = fk.header() {
1475+self.check_item_safety(span, safety);
1476+}
1477+14561478self.check_c_variadic_type(fk);
1457147914581480// Functions cannot both be `const async` or `const gen`