Skip to content

Commit

Permalink
Do not allow safe usafe on static and fn items
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Jun 20, 2024
1 parent cb8a7ea commit 8711347
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 5 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have quali
.label = in this `extern` block
.suggestion = remove this qualifier
ast_passes_item_invalid_safety = items cannot be declared with `safe` safety qualifier
.suggestion = remove safe to this item
ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers
.suggestion = add unsafe to this `extern` block
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ impl<'a> AstValidator<'a> {
}
}

fn check_item_safety(&self, span: Span, safety: Safety) {
if matches!(safety, Safety::Safe(_)) {
self.dcx().emit_err(errors::InvalidSafetyOnItem { span });
}
}

fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
&& (self.extern_mod_safety == Some(Safety::Default)
Expand Down Expand Up @@ -1015,6 +1021,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
self.check_defaultness(item.span, *defaultness);
self.check_item_safety(item.span, sig.header.safety);

if body.is_none() {
self.dcx().emit_err(errors::FnWithoutBody {
Expand Down Expand Up @@ -1174,11 +1181,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
}
}
ItemKind::Static(box StaticItem { expr: None, .. }) => {
self.dcx().emit_err(errors::StaticWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
});
ItemKind::Static(box StaticItem { expr, safety, .. }) => {
self.check_item_safety(item.span, *safety);

if expr.is_none() {
self.dcx().emit_err(errors::StaticWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
});
}
}
ItemKind::TyAlias(
ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. },
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ pub struct InvalidSafetyOnExtern {
pub block: Span,
}

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

#[derive(Diagnostic)]
#[diag(ast_passes_bound_in_context)]
pub struct BoundInContext<'a> {
Expand Down
7 changes: 7 additions & 0 deletions tests/ui/rust-2024/safe-outside-extern.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
safe fn foo() {}
//~^ ERROR: items cannot be declared with `safe` safety qualifier

safe static FOO: i32 = 1;
//~^ ERROR: items cannot be declared with `safe` safety qualifier

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/rust-2024/safe-outside-extern.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: items cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:1:1
|
LL | safe fn foo() {}
| ^^^^^^^^^^^^^^^^

error: items cannot be declared with `safe` safety qualifier
--> $DIR/safe-outside-extern.rs:4:1
|
LL | safe static FOO: i32 = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

0 comments on commit 8711347

Please sign in to comment.