Skip to content

Commit 8f0c075

Browse files
committed
Handle safe safety keyword for extern block inner items
1 parent be091ee commit 8f0c075

File tree

58 files changed

+177
-82
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+177
-82
lines changed

compiler/rustc_ast/src/ast.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2491,6 +2491,8 @@ pub enum Unsafe {
24912491
pub enum Safety {
24922492
/// `unsafe` an item is explicitly marked as `unsafe`.
24932493
Unsafe(Span),
2494+
/// `safe` an item is explicitly marked as `safe`.
2495+
Safe(Span),
24942496
/// Default means no value was provided, it will take a default value given the context in
24952497
/// which is used.
24962498
Default,
@@ -3142,6 +3144,7 @@ pub struct StaticItem {
31423144
#[derive(Clone, Encodable, Decodable, Debug)]
31433145
pub struct StaticForeignItem {
31443146
pub ty: P<Ty>,
3147+
pub safety: Safety,
31453148
pub mutability: Mutability,
31463149
pub expr: Option<P<Expr>>,
31473150
}
@@ -3150,6 +3153,7 @@ impl From<StaticItem> for StaticForeignItem {
31503153
fn from(static_item: StaticItem) -> StaticForeignItem {
31513154
StaticForeignItem {
31523155
ty: static_item.ty,
3156+
safety: Safety::Default,
31533157
mutability: static_item.mutability,
31543158
expr: static_item.expr,
31553159
}

compiler/rustc_ast/src/mut_visit.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ fn visit_unsafety<T: MutVisitor>(unsafety: &mut Unsafe, vis: &mut T) {
867867
fn visit_fn_safety<T: MutVisitor>(safety: &mut Safety, vis: &mut T) {
868868
match safety {
869869
Safety::Unsafe(span) => vis.visit_span(span),
870+
Safety::Safe(span) => vis.visit_span(span),
870871
Safety::Default => {}
871872
}
872873
}
@@ -1268,7 +1269,12 @@ pub fn noop_flat_map_item<K: NoopVisitItemKind>(
12681269
impl NoopVisitItemKind for ForeignItemKind {
12691270
fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
12701271
match self {
1271-
ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
1272+
ForeignItemKind::Static(box StaticForeignItem {
1273+
ty,
1274+
mutability: _,
1275+
expr,
1276+
safety: _,
1277+
}) => {
12721278
visitor.visit_ty(ty);
12731279
visit_opt(expr, |expr| visitor.visit_expr(expr));
12741280
}

compiler/rustc_ast/src/token.rs

+2
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: IdentIsRaw) -> boo
210210
kw::Unsafe,
211211
kw::While,
212212
kw::Yield,
213+
kw::Safe,
213214
kw::Static,
214215
]
215216
.contains(&name)
@@ -563,6 +564,7 @@ impl Token {
563564
kw::Impl,
564565
kw::Unsafe,
565566
kw::Const,
567+
kw::Safe,
566568
kw::Static,
567569
kw::Union,
568570
kw::Macro,

compiler/rustc_ast/src/visit.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,12 @@ impl WalkItemKind for ForeignItemKind {
642642
) -> V::Result {
643643
let &Item { id, span, ident, ref vis, .. } = item;
644644
match self {
645-
ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
645+
ForeignItemKind::Static(box StaticForeignItem {
646+
ty,
647+
mutability: _,
648+
expr,
649+
safety: _,
650+
}) => {
646651
try_visit!(visitor.visit_ty(ty));
647652
visit_opt!(visitor, visit_expr, expr);
648653
}

compiler/rustc_ast_lowering/src/item.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -659,13 +659,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
659659
this.lower_fn_params_to_names(fdec),
660660
)
661661
});
662+
let safety = self.lower_fn_safety(sig.header.safety);
662663

663-
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
664+
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety)
664665
}
665-
ForeignItemKind::Static(box StaticForeignItem { ty, mutability, expr: _ }) => {
666+
ForeignItemKind::Static(box StaticForeignItem {
667+
ty,
668+
mutability,
669+
expr: _,
670+
safety,
671+
}) => {
666672
let ty = self
667673
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
668-
hir::ForeignItemKind::Static(ty, *mutability)
674+
let safety = self.lower_fn_safety(*safety);
675+
676+
hir::ForeignItemKind::Static(ty, *mutability, safety)
669677
}
670678
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
671679
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
@@ -1411,6 +1419,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14111419
pub(super) fn lower_fn_safety(&mut self, u: Safety) -> hir::Safety {
14121420
match u {
14131421
Safety::Unsafe(_) => hir::Safety::Unsafe,
1422+
Safety::Safe(_) => hir::Safety::Safe,
14141423
Safety::Default => hir::Safety::Default,
14151424
}
14161425
}

compiler/rustc_ast_passes/src/ast_validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11901190
self.check_foreign_ty_genericless(generics, where_clauses);
11911191
self.check_foreign_item_ascii_only(fi.ident);
11921192
}
1193-
ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability: _, expr }) => {
1193+
ForeignItemKind::Static(box StaticForeignItem { expr, .. }) => {
11941194
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
11951195
self.check_foreign_item_ascii_only(fi.ident);
11961196
}

compiler/rustc_ast_pretty/src/pprust/state.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,7 @@ impl<'a> State<'a> {
19431943
fn print_fn_safety(&mut self, s: ast::Safety) {
19441944
match s {
19451945
ast::Safety::Default => {}
1946+
ast::Safety::Safe(_) => self.word_nbsp("safe"),
19461947
ast::Safety::Unsafe(_) => self.word_nbsp("unsafe"),
19471948
}
19481949
}

compiler/rustc_ast_pretty/src/pprust/state/item.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ impl<'a> State<'a> {
3030
ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
3131
self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
3232
}
33-
ast::ForeignItemKind::Static(box ast::StaticForeignItem { ty, mutability, expr }) => {
33+
ast::ForeignItemKind::Static(box ast::StaticForeignItem {
34+
ty,
35+
mutability,
36+
expr,
37+
safety,
38+
}) => {
39+
self.print_fn_safety(*safety);
3440
self.print_item_const(
3541
ident,
3642
Some(*mutability),

compiler/rustc_hir/src/hir.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -3208,13 +3208,15 @@ impl fmt::Display for Unsafety {
32083208
#[derive(Encodable, Decodable, HashStable_Generic)]
32093209
pub enum Safety {
32103210
Unsafe,
3211+
Safe,
32113212
Default,
32123213
}
32133214

32143215
impl Safety {
32153216
pub fn prefix_str(&self) -> &'static str {
32163217
match self {
32173218
Self::Unsafe => "unsafe ",
3219+
Self::Safe => "safe ",
32183220
Self::Default => "",
32193221
}
32203222
}
@@ -3224,6 +3226,7 @@ impl fmt::Display for Safety {
32243226
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32253227
f.write_str(match *self {
32263228
Self::Unsafe => "unsafe",
3229+
Self::Safe => "safe",
32273230
Self::Default => "normal",
32283231
})
32293232
}
@@ -3461,9 +3464,9 @@ impl ForeignItem<'_> {
34613464
#[derive(Debug, Clone, Copy, HashStable_Generic)]
34623465
pub enum ForeignItemKind<'hir> {
34633466
/// A foreign function.
3464-
Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>),
3467+
Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>, Safety),
34653468
/// A foreign static item (`static ext: u8`).
3466-
Static(&'hir Ty<'hir>, Mutability),
3469+
Static(&'hir Ty<'hir>, Mutability, Safety),
34673470
/// A foreign type.
34683471
Type,
34693472
}
@@ -3533,7 +3536,7 @@ impl<'hir> OwnerNode<'hir> {
35333536
| OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
35343537
| OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
35353538
OwnerNode::ForeignItem(ForeignItem {
3536-
kind: ForeignItemKind::Fn(fn_decl, _, _),
3539+
kind: ForeignItemKind::Fn(fn_decl, _, _, _),
35373540
..
35383541
}) => Some(fn_decl),
35393542
_ => None,
@@ -3720,9 +3723,9 @@ impl<'hir> Node<'hir> {
37203723
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
37213724
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
37223725
Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
3723-
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
3724-
Some(fn_decl)
3725-
}
3726+
| Node::ForeignItem(ForeignItem {
3727+
kind: ForeignItemKind::Fn(fn_decl, _, _, _), ..
3728+
}) => Some(fn_decl),
37263729
_ => None,
37273730
}
37283731
}
@@ -3806,7 +3809,7 @@ impl<'hir> Node<'hir> {
38063809
pub fn generics(self) -> Option<&'hir Generics<'hir>> {
38073810
match self {
38083811
Node::ForeignItem(ForeignItem {
3809-
kind: ForeignItemKind::Fn(_, _, generics), ..
3812+
kind: ForeignItemKind::Fn(_, _, generics, _), ..
38103813
})
38113814
| Node::TraitItem(TraitItem { generics, .. })
38123815
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),

compiler/rustc_hir/src/intravisit.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -608,12 +608,14 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
608608
try_visit!(visitor.visit_ident(foreign_item.ident));
609609

610610
match foreign_item.kind {
611-
ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => {
611+
ForeignItemKind::Fn(ref function_declaration, param_names, ref generics, _) => {
612612
try_visit!(visitor.visit_generics(generics));
613613
try_visit!(visitor.visit_fn_decl(function_declaration));
614614
walk_list!(visitor, visit_ident, param_names.iter().copied());
615615
}
616-
ForeignItemKind::Static(ref typ, _) => try_visit!(visitor.visit_ty(typ)),
616+
ForeignItemKind::Static(ref typ, _, _) => {
617+
try_visit!(visitor.visit_ty(typ));
618+
}
617619
ForeignItemKind::Type => (),
618620
}
619621
V::Result::output()

compiler/rustc_hir_analysis/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
809809

810810
let item = tcx.hir().foreign_item(item.id);
811811
match &item.kind {
812-
hir::ForeignItemKind::Fn(fn_decl, _, _) => {
812+
hir::ForeignItemKind::Fn(fn_decl, _, _, _) => {
813813
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
814814
}
815815
hir::ForeignItemKind::Static(..) => {

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn equate_intrinsic_type<'tcx>(
2828
let (own_counts, span) = match tcx.hir_node_by_def_id(def_id) {
2929
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
3030
| hir::Node::ForeignItem(hir::ForeignItem {
31-
kind: hir::ForeignItemKind::Fn(.., generics),
31+
kind: hir::ForeignItemKind::Fn(.., generics, _),
3232
..
3333
}) => {
3434
let own_counts = tcx.generics_of(def_id).own_counts();

compiler/rustc_hir_analysis/src/collect.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1306,9 +1306,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
13061306
icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None)
13071307
}
13081308

1309-
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
1309+
ForeignItem(&hir::ForeignItem {
1310+
kind: ForeignItemKind::Fn(fn_decl, _, _, safety), ..
1311+
}) => {
13101312
let abi = tcx.hir().get_foreign_abi(hir_id);
1311-
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1313+
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi, safety)
13121314
}
13131315

13141316
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
@@ -1680,11 +1682,16 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
16801682
def_id: LocalDefId,
16811683
decl: &'tcx hir::FnDecl<'tcx>,
16821684
abi: abi::Abi,
1685+
safety: hir::Safety,
16831686
) -> ty::PolyFnSig<'tcx> {
16841687
let safety = if abi == abi::Abi::RustIntrinsic {
16851688
intrinsic_operation_unsafety(tcx, def_id)
16861689
} else {
1687-
hir::Safety::Unsafe
1690+
match safety {
1691+
hir::Safety::Safe => hir::Safety::Safe,
1692+
// Foreign fns are unsafe by default
1693+
_ => hir::Safety::Unsafe,
1694+
}
16881695
};
16891696
let hir_id = tcx.local_def_id_to_hir_id(def_id);
16901697
let fty =

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
603603

604604
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
605605
match item.kind {
606-
hir::ForeignItemKind::Fn(_, _, generics) => {
606+
hir::ForeignItemKind::Fn(_, _, generics, _) => {
607607
self.visit_early_late(item.hir_id(), generics, |this| {
608608
intravisit::walk_foreign_item(this, item);
609609
})

compiler/rustc_hir_analysis/src/collect/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
466466
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
467467
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
468468
}
469-
ForeignItemKind::Static(t, _) => icx.lower_ty(t),
469+
ForeignItemKind::Static(t, _, _) => icx.lower_ty(t),
470470
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
471471
},
472472

compiler/rustc_hir_analysis/src/hir_wf_check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn diagnostic_hir_wf_check<'tcx>(
157157
},
158158
hir::Node::Field(field) => vec![field.ty],
159159
hir::Node::ForeignItem(ForeignItem {
160-
kind: ForeignItemKind::Static(ty, _), ..
160+
kind: ForeignItemKind::Static(ty, _, _), ..
161161
}) => vec![*ty],
162162
hir::Node::GenericParam(hir::GenericParam {
163163
kind: hir::GenericParamKind::Type { default: Some(ty), .. },

compiler/rustc_hir_pretty/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ impl<'a> State<'a> {
342342
self.maybe_print_comment(item.span.lo());
343343
self.print_outer_attributes(self.attrs(item.hir_id()));
344344
match item.kind {
345-
hir::ForeignItemKind::Fn(decl, arg_names, generics) => {
345+
hir::ForeignItemKind::Fn(decl, arg_names, generics, safety) => {
346346
self.head("");
347347
self.print_fn(
348348
decl,
349349
hir::FnHeader {
350-
safety: hir::Safety::Default,
350+
safety,
351351
constness: hir::Constness::NotConst,
352352
abi: Abi::Rust,
353353
asyncness: hir::IsAsync::NotAsync,
@@ -361,7 +361,8 @@ impl<'a> State<'a> {
361361
self.word(";");
362362
self.end() // end the outer fn box
363363
}
364-
hir::ForeignItemKind::Static(t, m) => {
364+
hir::ForeignItemKind::Static(t, m, safety) => {
365+
self.print_fn_safety(safety);
365366
self.head("static");
366367
if m.is_mut() {
367368
self.word_space("mut");
@@ -2290,6 +2291,7 @@ impl<'a> State<'a> {
22902291
fn print_fn_safety(&mut self, s: hir::Safety) {
22912292
match s {
22922293
hir::Safety::Default => {}
2294+
hir::Safety::Safe => self.word_nbsp("safe"),
22932295
hir::Safety::Unsafe => self.word_nbsp("unsafe"),
22942296
}
22952297
}

compiler/rustc_lint/src/types.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1696,13 +1696,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
16961696
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id());
16971697

16981698
match it.kind {
1699-
hir::ForeignItemKind::Fn(decl, _, _) if !vis.is_internal_abi(abi) => {
1699+
hir::ForeignItemKind::Fn(decl, _, _, _) if !vis.is_internal_abi(abi) => {
17001700
vis.check_foreign_fn(it.owner_id.def_id, decl);
17011701
}
1702-
hir::ForeignItemKind::Static(ty, _) if !vis.is_internal_abi(abi) => {
1702+
hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => {
17031703
vis.check_foreign_static(it.owner_id, ty.span);
17041704
}
1705-
hir::ForeignItemKind::Fn(decl, _, _) => vis.check_fn(it.owner_id.def_id, decl),
1705+
hir::ForeignItemKind::Fn(decl, _, _, _) => vis.check_fn(it.owner_id.def_id, decl),
17061706
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (),
17071707
}
17081708
}

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ impl<'hir> Map<'hir> {
856856
Node::Variant(variant) => named_span(variant.span, variant.ident, None),
857857
Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
858858
Node::ForeignItem(item) => match item.kind {
859-
ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
859+
ForeignItemKind::Fn(decl, _, _, _) => until_within(item.span, decl.output.span()),
860860
_ => named_span(item.span, item.ident, None),
861861
},
862862
Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)),

compiler/rustc_middle/src/hir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ pub fn provide(providers: &mut Providers) {
201201
..
202202
})
203203
| Node::ForeignItem(&ForeignItem {
204-
kind: ForeignItemKind::Fn(_, idents, _),
204+
kind: ForeignItemKind::Fn(_, idents, _, _),
205205
..
206206
}) = tcx.hir_node(hir_id)
207207
{

0 commit comments

Comments
 (0)