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> {

746760

fn visit_ty_common(&mut self, ty: &'a Ty) {

747761

match &ty.kind {

748762

TyKind::BareFn(bfty) => {

763+

self.check_bare_fn_safety(bfty.decl_span, bfty.safety);

749764

self.check_fn_decl(&bfty.decl, SelfSemantic::No);

750765

Self::check_decl_no_pat(&bfty.decl, |span, _, _| {

751766

self.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

}

11831202

ItemKind::TyAlias(

11841203

ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },

@@ -1212,7 +1231,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

12121231

fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {

12131232

match &fi.kind {

12141233

ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {

1215-

self.check_foreign_item_safety(fi.span, sig.header.safety);

12161234

self.check_defaultness(fi.span, *defaultness);

12171235

self.check_foreign_fn_bodyless(fi.ident, body.as_deref());

12181236

self.check_foreign_fn_headerless(sig.header);

@@ -1233,7 +1251,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

12331251

self.check_foreign_item_ascii_only(fi.ident);

12341252

}

12351253

ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => {

1236-

self.check_foreign_item_safety(fi.span, *safety);

1254+

self.check_item_safety(fi.span, *safety);

12371255

self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));

12381256

self.check_foreign_item_ascii_only(fi.ident);

12391257

}

@@ -1453,6 +1471,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

14531471

};

14541472

self.check_fn_decl(fk.decl(), self_semantic);

145514731474+

if let Some(&FnHeader { safety, .. }) = fk.header() {

1475+

self.check_item_safety(span, safety);

1476+

}

1477+14561478

self.check_c_variadic_type(fk);

1457147914581480

// Functions cannot both be `const async` or `const gen`