Skip to content

Commit

Permalink
Fail when using safe/unsafe items inside unadorned extern blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed May 3, 2024
1 parent 3ca0577 commit b23643b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ ast_lowering_invalid_register =
ast_lowering_invalid_register_class =
invalid register class `{$reg_class}`: {$error}
ast_lowering_invalid_safety_on_extern = safety is not expected in unadorned extern blocks
ast_lowering_match_arm_with_no_body =
`match` arm with no body
.suggestion = add a body after the pattern
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ pub struct InvalidAbi {
pub suggestion: Option<InvalidAbiSuggestion>,
}

#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_safety_on_extern)]
pub struct InvalidSafetyOnExtern {
#[primary_span]
pub span: Span,
}

pub struct InvalidAbiReason(pub &'static str);

impl Subdiagnostic for InvalidAbiReason {
Expand Down
32 changes: 28 additions & 4 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
use super::errors::{
InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, InvalidSafetyOnExtern,
MisplacedRelaxTraitBound,
};
use super::ResolverAstLoweringExt;
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
use super::{FnDeclKind, LoweringContext, ParamMode};
Expand Down Expand Up @@ -245,9 +248,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
},
ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
items: self.arena.alloc_from_iter(fm.items.iter().map(|x| {
if !span.edition().at_least_rust_2024() && fm.unsafety == Unsafe::No {
match &x.kind {
ForeignItemKind::Static(static_foreign_item)
if matches!(
static_foreign_item.safety,
Safety::Safe(_) | Safety::Unsafe(_)
) =>
{
self.dcx().emit_err(InvalidSafetyOnExtern { span: x.span });
}
ForeignItemKind::Fn(fn_item)
if matches!(
fn_item.sig.header.safety,
Safety::Safe(_) | Safety::Unsafe(_)
) =>
{
self.dcx().emit_err(InvalidSafetyOnExtern { span: x.span });
}
_ => {}
}
}
self.lower_foreign_item_ref(x)
})),
},
ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[allow(missing_unsafe_on_extern)]
extern "C" {
safe fn test1(i: i32);
//~^ ERROR
//~^ ERROR: safety is not expected in unadorned extern blocks
}

fn test2(i: i32) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: safety is not expected in unadorned extern blocks
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:3:5
|
LL | safe fn test1(i: i32);
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

0 comments on commit b23643b

Please sign in to comment.