Skip to content

Commit eff0aa5

Browse files
committed
Handle safe safety keyword for fns (not yet ready, generated unsafe fns)
1 parent 2581bc6 commit eff0aa5

39 files changed

+91
-43
lines changed

compiler/rustc_ast/src/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,7 @@ pub enum Unsafe {
24892489
#[derive(HashStable_Generic)]
24902490
pub enum FnSafety {
24912491
Unsafe(Span),
2492+
Safe(Span),
24922493
Default,
24932494
}
24942495

compiler/rustc_ast/src/mut_visit.rs

+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 FnSafety, vis: &mut T) {
868868
match safety {
869869
FnSafety::Unsafe(span) => vis.visit_span(span),
870+
FnSafety::Safe(span) => vis.visit_span(span),
870871
FnSafety::Default => {}
871872
}
872873
}

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_lowering/src/item.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14111411
pub(super) fn lower_fn_safety(&mut self, u: FnSafety) -> hir::FnSafety {
14121412
match u {
14131413
FnSafety::Unsafe(_) => hir::FnSafety::Unsafe,
1414+
FnSafety::Safe(_) => hir::FnSafety::Safe,
14141415
FnSafety::Default => hir::FnSafety::Default,
14151416
}
14161417
}

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::FnSafety) {
19441944
match s {
19451945
ast::FnSafety::Default => {}
1946+
ast::FnSafety::Safe(_) => self.word_nbsp("safe"),
19461947
ast::FnSafety::Unsafe(_) => self.word_nbsp("unsafe"),
19471948
}
19481949
}

compiler/rustc_hir/src/hir.rs

+3
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 FnSafety {
32103210
Unsafe,
3211+
Safe,
32113212
Default,
32123213
}
32133214

32143215
impl FnSafety {
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 FnSafety {
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
}

compiler/rustc_hir_pretty/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,7 @@ impl<'a> State<'a> {
22902290
fn print_fn_safety(&mut self, s: hir::FnSafety) {
22912291
match s {
22922292
hir::FnSafety::Default => {}
2293+
hir::FnSafety::Safe => self.word_nbsp("safe"),
22932294
hir::FnSafety::Unsafe => self.word_nbsp("unsafe"),
22942295
}
22952296
}

compiler/rustc_parse/src/parser/item.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -2376,9 +2376,9 @@ impl<'a> Parser<'a> {
23762376
// `pub` is added in case users got confused with the ordering like `async pub fn`,
23772377
// only if it wasn't preceded by `default` as `default pub` is invalid.
23782378
let quals: &[Symbol] = if check_pub {
2379-
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
2379+
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
23802380
} else {
2381-
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
2381+
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
23822382
};
23832383
self.check_keyword_case(kw::Fn, case) // Definitely an `fn`.
23842384
// `$qual fn` or `$qual $qual`:
@@ -2513,11 +2513,27 @@ impl<'a> Parser<'a> {
25132513
} else if self.check_keyword(kw::Unsafe) {
25142514
match safety {
25152515
FnSafety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
2516+
FnSafety::Safe(sp) => {
2517+
recover_safety = FnSafety::Unsafe(self.token.span);
2518+
Some(WrongKw::Misplaced(sp))
2519+
}
25162520
FnSafety::Default => {
25172521
recover_safety = FnSafety::Unsafe(self.token.span);
25182522
Some(WrongKw::Misplaced(ext_start_sp))
25192523
}
25202524
}
2525+
} else if self.check_keyword(kw::Safe) {
2526+
match safety {
2527+
FnSafety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
2528+
FnSafety::Unsafe(sp) => {
2529+
recover_safety = FnSafety::Safe(self.token.span);
2530+
Some(WrongKw::Misplaced(sp))
2531+
}
2532+
FnSafety::Default => {
2533+
recover_safety = FnSafety::Safe(self.token.span);
2534+
Some(WrongKw::Misplaced(ext_start_sp))
2535+
}
2536+
}
25212537
} else {
25222538
None
25232539
};

compiler/rustc_parse/src/parser/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,8 @@ impl<'a> Parser<'a> {
12251225
fn parse_fn_safety(&mut self, case: Case) -> FnSafety {
12261226
if self.eat_keyword_case(kw::Unsafe, case) {
12271227
FnSafety::Unsafe(self.prev_token.uninterpolated_span())
1228+
} else if self.eat_keyword_case(kw::Safe, case) {
1229+
FnSafety::Safe(self.prev_token.uninterpolated_span())
12281230
} else {
12291231
FnSafety::Default
12301232
}

compiler/rustc_smir/src/rustc_internal/internal.rs

+1
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ impl RustcInternal for FnSafety {
497497
fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
498498
match self {
499499
FnSafety::Unsafe => rustc_hir::FnSafety::Unsafe,
500+
FnSafety::Safe => rustc_hir::FnSafety::Safe,
500501
FnSafety::Default => rustc_hir::FnSafety::Default,
501502
}
502503
}

compiler/rustc_smir/src/rustc_smir/convert/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::FnSafety {
2424
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
2525
match self {
2626
rustc_hir::FnSafety::Unsafe => stable_mir::mir::FnSafety::Unsafe,
27+
rustc_hir::FnSafety::Safe => stable_mir::mir::FnSafety::Safe,
2728
rustc_hir::FnSafety::Default => stable_mir::mir::FnSafety::Default,
2829
}
2930
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ symbols! {
103103
MacroRules: "macro_rules",
104104
Raw: "raw",
105105
Reuse: "reuse",
106+
Safe: "safe",
106107
Union: "union",
107108
Yeet: "yeet",
108109
}

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
204204
let fn_sig = self_ty.fn_sig(self.tcx);
205205
let shortname = match fn_sig.safety() {
206206
hir::FnSafety::Default => "fn",
207+
hir::FnSafety::Safe => "safe fn",
207208
hir::FnSafety::Unsafe => "unsafe fn",
208209
};
209210
flags.push((sym::_Self, Some(shortname.to_owned())));

compiler/stable_mir/src/mir/body.rs

+1
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ pub enum Safety {
922922
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
923923
pub enum FnSafety {
924924
Unsafe,
925+
Safe,
925926
Default,
926927
}
927928

tests/ui/async-await/no-async-const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
//@ compile-flags: --crate-type lib
33

44
pub async const fn x() {}
5-
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
5+
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
66
//~| ERROR functions cannot be both `const` and `async`

tests/ui/async-await/no-async-const.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
1+
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
22
--> $DIR/no-async-const.rs:4:11
33
|
44
LL | pub async const fn x() {}
55
| ------^^^^^
66
| | |
7-
| | expected one of `extern`, `fn`, or `unsafe`
7+
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
88
| help: `const` must come before `async`: `const async`
99
|
1010
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`

tests/ui/coroutine/async_gen_fn.none.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ LL | async gen fn foo() {}
77
= help: pass `--edition 2021` to `rustc`
88
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
99

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

1616
error: aborting due to 2 previous errors
1717

tests/ui/coroutine/async_gen_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

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

99
fn main() {}

tests/ui/coroutine/gen_fn.none.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
1+
error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
22
--> $DIR/gen_fn.rs:4:1
33
|
44
LL | gen fn foo() {}
5-
| ^^^ expected one of 9 possible tokens
5+
| ^^^ expected one of 10 possible tokens
66

77
error: aborting due to 1 previous error
88

tests/ui/coroutine/gen_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//@[e2024] compile-flags: --edition 2024 -Zunstable-options
33

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

88
fn main() {}

tests/ui/parser/duplicate-visibility.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ fn main() {}
22

33
extern "C" { //~ NOTE while parsing this item list starting here
44
pub pub fn foo();
5-
//~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
6-
//~| NOTE expected one of 8 possible tokens
5+
//~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
6+
//~| NOTE expected one of 9 possible tokens
77
//~| HELP there is already a visibility modifier, remove one
88
//~| NOTE explicit visibility first seen here
99
} //~ NOTE the item list ends here

tests/ui/parser/duplicate-visibility.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
1+
error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
22
--> $DIR/duplicate-visibility.rs:4:9
33
|
44
LL | extern "C" {
55
| - while parsing this item list starting here
66
LL | pub pub fn foo();
77
| ^^^
88
| |
9-
| expected one of 8 possible tokens
9+
| expected one of 9 possible tokens
1010
| help: there is already a visibility modifier, remove one
1111
...
1212
LL | }

tests/ui/parser/issues/issue-76437-async.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
mod t {
44
async pub fn t() {}
5-
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
5+
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
66
//~| HELP visibility `pub` must come before `async`
77
}

tests/ui/parser/issues/issue-76437-async.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
1+
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
22
--> $DIR/issue-76437-async.rs:4:11
33
|
44
LL | async pub fn t() {}
55
| ------^^^
66
| | |
7-
| | expected one of `extern`, `fn`, or `unsafe`
7+
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
88
| help: visibility `pub` must come before `async`: `pub async`
99

1010
error: aborting due to 1 previous error

tests/ui/parser/issues/issue-76437-const-async.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
mod t {
44
const async pub fn t() {}
5-
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
5+
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
66
//~| HELP visibility `pub` must come before `const async`
77
}

tests/ui/parser/issues/issue-76437-const-async.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
1+
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
22
--> $DIR/issue-76437-const-async.rs:4:17
33
|
44
LL | const async pub fn t() {}
55
| ------------^^^
66
| | |
7-
| | expected one of `extern`, `fn`, or `unsafe`
7+
| | expected one of `extern`, `fn`, `safe`, or `unsafe`
88
| help: visibility `pub` must come before `const async`: `pub const async`
99

1010
error: aborting due to 1 previous error

tests/ui/parser/issues/issue-76437-const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
mod t {
44
const pub fn t() {}
5-
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
5+
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
66
//~| HELP visibility `pub` must come before `const`
77
}

tests/ui/parser/issues/issue-76437-const.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
1+
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
22
--> $DIR/issue-76437-const.rs:4:11
33
|
44
LL | const pub fn t() {}
55
| ------^^^
66
| | |
7-
| | expected one of `async`, `extern`, `fn`, or `unsafe`
7+
| | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
88
| help: visibility `pub` must come before `const`: `pub const`
99

1010
error: aborting due to 1 previous error

tests/ui/parser/issues/issue-86895.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
const pub () {}
2-
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`
2+
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
33
pub fn main() {}
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
1+
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
22
--> $DIR/issue-86895.rs:1:7
33
|
44
LL | const pub () {}
5-
| ^^^ expected one of `async`, `extern`, `fn`, or `unsafe`
5+
| ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
66

77
error: aborting due to 1 previous error
88

tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// Test that even when `const` is already present, the proposed fix is to remove the second `const`
44

55
const async const fn test() {}
6-
//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
7-
//~| NOTE expected one of `extern`, `fn`, or `unsafe`
6+
//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
7+
//~| NOTE expected one of `extern`, `fn`, `safe`, or `unsafe`
88
//~| HELP `const` already used earlier, remove this one
99
//~| NOTE `const` first seen here
1010
//~| ERROR functions cannot be both `const` and `async`

tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
1+
error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
22
--> $DIR/const-async-const.rs:5:13
33
|
44
LL | const async const fn test() {}
55
| ^^^^^
66
| |
7-
| expected one of `extern`, `fn`, or `unsafe`
7+
| expected one of `extern`, `fn`, `safe`, or `unsafe`
88
| help: `const` already used earlier, remove this one
99
|
1010
note: `const` first seen here
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub const pub fn test() {}
2-
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
3-
//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
2+
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
3+
//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
44
//~| HELP there is already a visibility modifier, remove one
55
//~| NOTE explicit visibility first seen here

tests/ui/parser/issues/issue-87694-duplicated-pub.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
1+
error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
22
--> $DIR/issue-87694-duplicated-pub.rs:1:11
33
|
44
LL | pub const pub fn test() {}
55
| ^^^
66
| |
7-
| expected one of `async`, `extern`, `fn`, or `unsafe`
7+
| expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
88
| help: there is already a visibility modifier, remove one
99
|
1010
note: explicit visibility first seen here
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const pub fn test() {}
2-
//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
3-
//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
2+
//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
3+
//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
44
//~| HELP visibility `pub` must come before `const`
55
//~| SUGGESTION pub const

0 commit comments

Comments
 (0)