Skip to content

Commit

Permalink
Handle safe safety keyword for extern block inner items
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Apr 29, 2024
1 parent 3a0ee07 commit 542a307
Show file tree
Hide file tree
Showing 57 changed files with 176 additions and 82 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Expand Up @@ -2491,6 +2491,8 @@ pub enum Unsafe {
pub enum Safety {
/// `unsafe` an item is explicitly marked as `unsafe`.
Unsafe(Span),
/// `safe` an item is explicitly marked as `safe`.
Safe(Span),
/// Default means no value was provided, it will take a default value given the context in
/// which is used.
Default,
Expand Down Expand Up @@ -3142,6 +3144,7 @@ pub struct StaticItem {
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct StaticForeignItem {
pub ty: P<Ty>,
pub safety: Safety,
pub mutability: Mutability,
pub expr: Option<P<Expr>>,
}
Expand All @@ -3150,6 +3153,7 @@ impl From<StaticItem> for StaticForeignItem {
fn from(static_item: StaticItem) -> StaticForeignItem {
StaticForeignItem {
ty: static_item.ty,
safety: Safety::Default,
mutability: static_item.mutability,
expr: static_item.expr,
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Expand Up @@ -867,6 +867,7 @@ fn visit_unsafety<T: MutVisitor>(unsafety: &mut Unsafe, vis: &mut T) {
fn visit_fn_safety<T: MutVisitor>(safety: &mut Safety, vis: &mut T) {
match safety {
Safety::Unsafe(span) => vis.visit_span(span),
Safety::Safe(span) => vis.visit_span(span),
Safety::Default => {}
}
}
Expand Down Expand Up @@ -1268,7 +1269,12 @@ pub fn noop_flat_map_item<K: NoopVisitItemKind>(
impl NoopVisitItemKind for ForeignItemKind {
fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
match self {
ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
ForeignItemKind::Static(box StaticForeignItem {
ty,
mutability: _,
expr,
safety: _,
}) => {
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/token.rs
Expand Up @@ -210,6 +210,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: IdentIsRaw) -> boo
kw::Unsafe,
kw::While,
kw::Yield,
kw::Safe,
kw::Static,
]
.contains(&name)
Expand Down Expand Up @@ -563,6 +564,7 @@ impl Token {
kw::Impl,
kw::Unsafe,
kw::Const,
kw::Safe,
kw::Static,
kw::Union,
kw::Macro,
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_ast/src/visit.rs
Expand Up @@ -642,7 +642,12 @@ impl WalkItemKind for ForeignItemKind {
) -> V::Result {
let &Item { id, span, ident, ref vis, .. } = item;
match self {
ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
ForeignItemKind::Static(box StaticForeignItem {
ty,
mutability: _,
expr,
safety: _,
}) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Expand Up @@ -659,13 +659,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_fn_params_to_names(fdec),
)
});
let safety = self.lower_fn_safety(sig.header.safety);

hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety)
}
ForeignItemKind::Static(box StaticForeignItem { ty, mutability, expr: _ }) => {
ForeignItemKind::Static(box StaticForeignItem {
ty,
mutability,
expr: _,
safety,
}) => {
let ty = self
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
hir::ForeignItemKind::Static(ty, *mutability)
let safety = self.lower_fn_safety(*safety);

hir::ForeignItemKind::Static(ty, *mutability, safety)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
Expand Down Expand Up @@ -1411,6 +1419,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_fn_safety(&mut self, u: Safety) -> hir::Safety {
match u {
Safety::Unsafe(_) => hir::Safety::Unsafe,
Safety::Safe(_) => hir::Safety::Safe,
Safety::Default => hir::Safety::Default,
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/ast_validation.rs
Expand Up @@ -1190,7 +1190,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_foreign_ty_genericless(generics, where_clauses);
self.check_foreign_item_ascii_only(fi.ident);
}
ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability: _, expr }) => {
ForeignItemKind::Static(box StaticForeignItem { expr, .. }) => {
self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
self.check_foreign_item_ascii_only(fi.ident);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Expand Up @@ -1943,6 +1943,7 @@ impl<'a> State<'a> {
fn print_fn_safety(&mut self, s: ast::Safety) {
match s {
ast::Safety::Default => {}
ast::Safety::Safe(_) => self.word_nbsp("safe"),
ast::Safety::Unsafe(_) => self.word_nbsp("unsafe"),
}
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/item.rs
Expand Up @@ -30,7 +30,13 @@ impl<'a> State<'a> {
ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
}
ast::ForeignItemKind::Static(box ast::StaticForeignItem { ty, mutability, expr }) => {
ast::ForeignItemKind::Static(box ast::StaticForeignItem {
ty,
mutability,
expr,
safety,
}) => {
self.print_fn_safety(*safety);
self.print_item_const(
ident,
Some(*mutability),
Expand Down
17 changes: 10 additions & 7 deletions compiler/rustc_hir/src/hir.rs
Expand Up @@ -3208,13 +3208,15 @@ impl fmt::Display for Unsafety {
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum Safety {
Unsafe,
Safe,
Default,
}

impl Safety {
pub fn prefix_str(&self) -> &'static str {
match self {
Self::Unsafe => "unsafe ",
Self::Safe => "safe ",
Self::Default => "",
}
}
Expand All @@ -3224,6 +3226,7 @@ impl fmt::Display for Safety {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
Self::Unsafe => "unsafe",
Self::Safe => "safe",
Self::Default => "normal",
})
}
Expand Down Expand Up @@ -3461,9 +3464,9 @@ impl ForeignItem<'_> {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ForeignItemKind<'hir> {
/// A foreign function.
Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>),
Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>, Safety),
/// A foreign static item (`static ext: u8`).
Static(&'hir Ty<'hir>, Mutability),
Static(&'hir Ty<'hir>, Mutability, Safety),
/// A foreign type.
Type,
}
Expand Down Expand Up @@ -3533,7 +3536,7 @@ impl<'hir> OwnerNode<'hir> {
| OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
| OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
OwnerNode::ForeignItem(ForeignItem {
kind: ForeignItemKind::Fn(fn_decl, _, _),
kind: ForeignItemKind::Fn(fn_decl, _, _, _),
..
}) => Some(fn_decl),
_ => None,
Expand Down Expand Up @@ -3720,9 +3723,9 @@ impl<'hir> Node<'hir> {
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
| Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
Some(fn_decl)
}
| Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Fn(fn_decl, _, _, _), ..
}) => Some(fn_decl),
_ => None,
}
}
Expand Down Expand Up @@ -3806,7 +3809,7 @@ impl<'hir> Node<'hir> {
pub fn generics(self) -> Option<&'hir Generics<'hir>> {
match self {
Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Fn(_, _, generics), ..
kind: ForeignItemKind::Fn(_, _, generics, _), ..
})
| Node::TraitItem(TraitItem { generics, .. })
| Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Expand Up @@ -608,12 +608,14 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
try_visit!(visitor.visit_ident(foreign_item.ident));

match foreign_item.kind {
ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => {
ForeignItemKind::Fn(ref function_declaration, param_names, ref generics, _) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_fn_decl(function_declaration));
walk_list!(visitor, visit_ident, param_names.iter().copied());
}
ForeignItemKind::Static(ref typ, _) => try_visit!(visitor.visit_ty(typ)),
ForeignItemKind::Static(ref typ, _, _) => {
try_visit!(visitor.visit_ty(typ));
}
ForeignItemKind::Type => (),
}
V::Result::output()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Expand Up @@ -809,7 +809,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {

let item = tcx.hir().foreign_item(item.id);
match &item.kind {
hir::ForeignItemKind::Fn(fn_decl, _, _) => {
hir::ForeignItemKind::Fn(fn_decl, _, _, _) => {
require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsic.rs
Expand Up @@ -28,7 +28,7 @@ fn equate_intrinsic_type<'tcx>(
let (own_counts, span) = match tcx.hir_node_by_def_id(def_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
| hir::Node::ForeignItem(hir::ForeignItem {
kind: hir::ForeignItemKind::Fn(.., generics),
kind: hir::ForeignItemKind::Fn(.., generics, _),
..
}) => {
let own_counts = tcx.generics_of(def_id).own_counts();
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_hir_analysis/src/collect.rs
Expand Up @@ -1306,9 +1306,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None)
}

ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
ForeignItem(&hir::ForeignItem {
kind: ForeignItemKind::Fn(fn_decl, _, _, safety), ..
}) => {
let abi = tcx.hir().get_foreign_abi(hir_id);
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi, safety)
}

Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
Expand Down Expand Up @@ -1680,11 +1682,16 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
def_id: LocalDefId,
decl: &'tcx hir::FnDecl<'tcx>,
abi: abi::Abi,
safety: hir::Safety,
) -> ty::PolyFnSig<'tcx> {
let safety = if abi == abi::Abi::RustIntrinsic {
intrinsic_operation_unsafety(tcx, def_id)
} else {
hir::Safety::Unsafe
match safety {
hir::Safety::Safe => hir::Safety::Safe,
// Foreign fns are unsafe by default
_ => hir::Safety::Unsafe,
}
};
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let fty =
Expand Down
Expand Up @@ -603,7 +603,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {

fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
match item.kind {
hir::ForeignItemKind::Fn(_, _, generics) => {
hir::ForeignItemKind::Fn(_, _, generics, _) => {
self.visit_early_late(item.hir_id(), generics, |this| {
intravisit::walk_foreign_item(this, item);
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Expand Up @@ -466,7 +466,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
}
ForeignItemKind::Static(t, _) => icx.lower_ty(t),
ForeignItemKind::Static(t, _, _) => icx.lower_ty(t),
ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
},

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_wf_check.rs
Expand Up @@ -157,7 +157,7 @@ fn diagnostic_hir_wf_check<'tcx>(
},
hir::Node::Field(field) => vec![field.ty],
hir::Node::ForeignItem(ForeignItem {
kind: ForeignItemKind::Static(ty, _), ..
kind: ForeignItemKind::Static(ty, _, _), ..
}) => vec![*ty],
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_hir_pretty/src/lib.rs
Expand Up @@ -342,12 +342,12 @@ impl<'a> State<'a> {
self.maybe_print_comment(item.span.lo());
self.print_outer_attributes(self.attrs(item.hir_id()));
match item.kind {
hir::ForeignItemKind::Fn(decl, arg_names, generics) => {
hir::ForeignItemKind::Fn(decl, arg_names, generics, safety) => {
self.head("");
self.print_fn(
decl,
hir::FnHeader {
safety: hir::Safety::Default,
safety,
constness: hir::Constness::NotConst,
abi: Abi::Rust,
asyncness: hir::IsAsync::NotAsync,
Expand All @@ -361,7 +361,8 @@ impl<'a> State<'a> {
self.word(";");
self.end() // end the outer fn box
}
hir::ForeignItemKind::Static(t, m) => {
hir::ForeignItemKind::Static(t, m, safety) => {
self.print_fn_safety(safety);
self.head("static");
if m.is_mut() {
self.word_space("mut");
Expand Down Expand Up @@ -2290,6 +2291,7 @@ impl<'a> State<'a> {
fn print_fn_safety(&mut self, s: hir::Safety) {
match s {
hir::Safety::Default => {}
hir::Safety::Safe => self.word_nbsp("safe"),
hir::Safety::Unsafe => self.word_nbsp("unsafe"),
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_lint/src/types.rs
Expand Up @@ -1696,13 +1696,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id());

match it.kind {
hir::ForeignItemKind::Fn(decl, _, _) if !vis.is_internal_abi(abi) => {
hir::ForeignItemKind::Fn(decl, _, _, _) if !vis.is_internal_abi(abi) => {
vis.check_foreign_fn(it.owner_id.def_id, decl);
}
hir::ForeignItemKind::Static(ty, _) if !vis.is_internal_abi(abi) => {
hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => {
vis.check_foreign_static(it.owner_id, ty.span);
}
hir::ForeignItemKind::Fn(decl, _, _) => vis.check_fn(it.owner_id.def_id, decl),
hir::ForeignItemKind::Fn(decl, _, _, _) => vis.check_fn(it.owner_id.def_id, decl),
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (),
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Expand Up @@ -856,7 +856,7 @@ impl<'hir> Map<'hir> {
Node::Variant(variant) => named_span(variant.span, variant.ident, None),
Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
Node::ForeignItem(item) => match item.kind {
ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
ForeignItemKind::Fn(decl, _, _, _) => until_within(item.span, decl.output.span()),
_ => named_span(item.span, item.ident, None),
},
Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/mod.rs
Expand Up @@ -201,7 +201,7 @@ pub fn provide(providers: &mut Providers) {
..
})
| Node::ForeignItem(&ForeignItem {
kind: ForeignItemKind::Fn(_, idents, _),
kind: ForeignItemKind::Fn(_, idents, _, _),
..
}) = tcx.hir_node(hir_id)
{
Expand Down

0 comments on commit 542a307

Please sign in to comment.