Skip to content

Commit

Permalink
Handle safe safety keyword for fns (not yet ready, generated unsafe…
Browse files Browse the repository at this point in the history
… fns)
  • Loading branch information
spastorino committed Apr 28, 2024
1 parent 2581bc6 commit eff0aa5
Show file tree
Hide file tree
Showing 39 changed files with 91 additions and 43 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,7 @@ pub enum Unsafe {
#[derive(HashStable_Generic)]
pub enum FnSafety {
Unsafe(Span),
Safe(Span),
Default,
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
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 FnSafety, vis: &mut T) {
match safety {
FnSafety::Unsafe(span) => vis.visit_span(span),
FnSafety::Safe(span) => vis.visit_span(span),
FnSafety::Default => {}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
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
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_fn_safety(&mut self, u: FnSafety) -> hir::FnSafety {
match u {
FnSafety::Unsafe(_) => hir::FnSafety::Unsafe,
FnSafety::Safe(_) => hir::FnSafety::Safe,
FnSafety::Default => hir::FnSafety::Default,
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,7 @@ impl<'a> State<'a> {
fn print_fn_safety(&mut self, s: ast::FnSafety) {
match s {
ast::FnSafety::Default => {}
ast::FnSafety::Safe(_) => self.word_nbsp("safe"),
ast::FnSafety::Unsafe(_) => self.word_nbsp("unsafe"),
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3208,13 +3208,15 @@ impl fmt::Display for Unsafety {
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum FnSafety {
Unsafe,
Safe,
Default,
}

impl FnSafety {
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 FnSafety {
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
1 change: 1 addition & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2290,6 +2290,7 @@ impl<'a> State<'a> {
fn print_fn_safety(&mut self, s: hir::FnSafety) {
match s {
hir::FnSafety::Default => {}
hir::FnSafety::Safe => self.word_nbsp("safe"),
hir::FnSafety::Unsafe => self.word_nbsp("unsafe"),
}
}
Expand Down
20 changes: 18 additions & 2 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2376,9 +2376,9 @@ impl<'a> Parser<'a> {
// `pub` is added in case users got confused with the ordering like `async pub fn`,
// only if it wasn't preceded by `default` as `default pub` is invalid.
let quals: &[Symbol] = if check_pub {
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
} else {
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
};
self.check_keyword_case(kw::Fn, case) // Definitely an `fn`.
// `$qual fn` or `$qual $qual`:
Expand Down Expand Up @@ -2513,11 +2513,27 @@ impl<'a> Parser<'a> {
} else if self.check_keyword(kw::Unsafe) {
match safety {
FnSafety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
FnSafety::Safe(sp) => {
recover_safety = FnSafety::Unsafe(self.token.span);
Some(WrongKw::Misplaced(sp))
}
FnSafety::Default => {
recover_safety = FnSafety::Unsafe(self.token.span);
Some(WrongKw::Misplaced(ext_start_sp))
}
}
} else if self.check_keyword(kw::Safe) {
match safety {
FnSafety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
FnSafety::Unsafe(sp) => {
recover_safety = FnSafety::Safe(self.token.span);
Some(WrongKw::Misplaced(sp))
}
FnSafety::Default => {
recover_safety = FnSafety::Safe(self.token.span);
Some(WrongKw::Misplaced(ext_start_sp))
}
}
} else {
None
};
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,8 @@ impl<'a> Parser<'a> {
fn parse_fn_safety(&mut self, case: Case) -> FnSafety {
if self.eat_keyword_case(kw::Unsafe, case) {
FnSafety::Unsafe(self.prev_token.uninterpolated_span())
} else if self.eat_keyword_case(kw::Safe, case) {
FnSafety::Safe(self.prev_token.uninterpolated_span())
} else {
FnSafety::Default
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_internal/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ impl RustcInternal for FnSafety {
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
match self {
FnSafety::Unsafe => rustc_hir::FnSafety::Unsafe,
FnSafety::Safe => rustc_hir::FnSafety::Safe,
FnSafety::Default => rustc_hir::FnSafety::Default,
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::FnSafety {
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
match self {
rustc_hir::FnSafety::Unsafe => stable_mir::mir::FnSafety::Unsafe,
rustc_hir::FnSafety::Safe => stable_mir::mir::FnSafety::Safe,
rustc_hir::FnSafety::Default => stable_mir::mir::FnSafety::Default,
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ symbols! {
MacroRules: "macro_rules",
Raw: "raw",
Reuse: "reuse",
Safe: "safe",
Union: "union",
Yeet: "yeet",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let fn_sig = self_ty.fn_sig(self.tcx);
let shortname = match fn_sig.safety() {
hir::FnSafety::Default => "fn",
hir::FnSafety::Safe => "safe fn",
hir::FnSafety::Unsafe => "unsafe fn",
};
flags.push((sym::_Self, Some(shortname.to_owned())));
Expand Down
1 change: 1 addition & 0 deletions compiler/stable_mir/src/mir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ pub enum Safety {
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum FnSafety {
Unsafe,
Safe,
Default,
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/async-await/no-async-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
//@ compile-flags: --crate-type lib

pub async const fn x() {}
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
//~| ERROR functions cannot be both `const` and `async`
4 changes: 2 additions & 2 deletions tests/ui/async-await/no-async-const.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
--> $DIR/no-async-const.rs:4:11
|
LL | pub async const fn x() {}
| ------^^^^^
| | |
| | expected one of `extern`, `fn`, or `unsafe`
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
| help: `const` must come before `async`: `const async`
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/coroutine/async_gen_fn.none.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ LL | async gen fn foo() {}
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide

error: expected one of `extern`, `fn`, or `unsafe`, found `gen`
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen`
--> $DIR/async_gen_fn.rs:4:7
|
LL | async gen fn foo() {}
| ^^^ expected one of `extern`, `fn`, or `unsafe`
| ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe`

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/coroutine/async_gen_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

async gen fn foo() {}
//[none]~^ ERROR: `async fn` is not permitted in Rust 2015
//[none]~| ERROR: expected one of `extern`, `fn`, or `unsafe`, found `gen`
//[none]~| ERROR: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen`
//[e2024]~^^^ ERROR: gen blocks are experimental

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/coroutine/gen_fn.none.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
--> $DIR/gen_fn.rs:4:1
|
LL | gen fn foo() {}
| ^^^ expected one of 9 possible tokens
| ^^^ expected one of 10 possible tokens

error: aborting due to 1 previous error

2 changes: 1 addition & 1 deletion tests/ui/coroutine/gen_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@[e2024] compile-flags: --edition 2024 -Zunstable-options

gen fn foo() {}
//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
//[e2024]~^^ ERROR: gen blocks are experimental

fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/parser/duplicate-visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ fn main() {}

extern "C" { //~ NOTE while parsing this item list starting here
pub pub fn foo();
//~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
//~| NOTE expected one of 8 possible tokens
//~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
//~| NOTE expected one of 9 possible tokens
//~| HELP there is already a visibility modifier, remove one
//~| NOTE explicit visibility first seen here
} //~ NOTE the item list ends here
4 changes: 2 additions & 2 deletions tests/ui/parser/duplicate-visibility.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
--> $DIR/duplicate-visibility.rs:4:9
|
LL | extern "C" {
| - while parsing this item list starting here
LL | pub pub fn foo();
| ^^^
| |
| expected one of 8 possible tokens
| expected one of 9 possible tokens
| help: there is already a visibility modifier, remove one
...
LL | }
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-76437-async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

mod t {
async pub fn t() {}
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
//~| HELP visibility `pub` must come before `async`
}
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-76437-async.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
--> $DIR/issue-76437-async.rs:4:11
|
LL | async pub fn t() {}
| ------^^^
| | |
| | expected one of `extern`, `fn`, or `unsafe`
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
| help: visibility `pub` must come before `async`: `pub async`

error: aborting due to 1 previous error
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-76437-const-async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

mod t {
const async pub fn t() {}
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
//~| HELP visibility `pub` must come before `const async`
}
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-76437-const-async.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
--> $DIR/issue-76437-const-async.rs:4:17
|
LL | const async pub fn t() {}
| ------------^^^
| | |
| | expected one of `extern`, `fn`, or `unsafe`
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
| help: visibility `pub` must come before `const async`: `pub const async`

error: aborting due to 1 previous error
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-76437-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

mod t {
const pub fn t() {}
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
//~| HELP visibility `pub` must come before `const`
}
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-76437-const.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
--> $DIR/issue-76437-const.rs:4:11
|
LL | const pub fn t() {}
| ------^^^
| | |
| | expected one of `async`, `extern`, `fn`, or `unsafe`
| | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
| help: visibility `pub` must come before `const`: `pub const`

error: aborting due to 1 previous error
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-86895.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const pub () {}
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
pub fn main() {}
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-86895.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
--> $DIR/issue-86895.rs:1:7
|
LL | const pub () {}
| ^^^ expected one of `async`, `extern`, `fn`, or `unsafe`
| ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Test that even when `const` is already present, the proposed fix is to remove the second `const`

const async const fn test() {}
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
//~| NOTE expected one of `extern`, `fn`, or `unsafe`
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
//~| NOTE expected one of `extern`, `fn`, `safe`, or `unsafe`
//~| HELP `const` already used earlier, remove this one
//~| NOTE `const` first seen here
//~| ERROR functions cannot be both `const` and `async`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
--> $DIR/const-async-const.rs:5:13
|
LL | const async const fn test() {}
| ^^^^^
| |
| expected one of `extern`, `fn`, or `unsafe`
| expected one of `extern`, `fn`, `safe`, or `unsafe`
| help: `const` already used earlier, remove this one
|
note: `const` first seen here
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-87694-duplicated-pub.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub const pub fn test() {}
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
//~| HELP there is already a visibility modifier, remove one
//~| NOTE explicit visibility first seen here
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-87694-duplicated-pub.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
--> $DIR/issue-87694-duplicated-pub.rs:1:11
|
LL | pub const pub fn test() {}
| ^^^
| |
| expected one of `async`, `extern`, `fn`, or `unsafe`
| expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
| help: there is already a visibility modifier, remove one
|
note: explicit visibility first seen here
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/parser/issues/issue-87694-misplaced-pub.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const pub fn test() {}
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
//~| HELP visibility `pub` must come before `const`
//~| SUGGESTION pub const

0 comments on commit eff0aa5

Please sign in to comment.