Skip to content

Commit 7715295

Browse files
authored
Rollup merge of rust-lang#127106 - spastorino:improve-unsafe-extern-blocks-diagnostics, r=compiler-errors
Improve unsafe extern blocks diagnostics Closes rust-lang#126327 For this code: ```rust extern { pub fn foo(); pub safe fn bar(); } ``` We get ... ``` error: items in unadorned `extern` blocks cannot have safety qualifiers --> test.rs:3:5 | 3 | pub safe fn bar(); | ^^^^^^^^^^^^^^^^^^ | help: add unsafe to this `extern` block | 1 | unsafe extern { | ++++++ error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental --> test.rs:3:9 | 3 | pub safe fn bar(); | ^^^^ | = note: see issue rust-lang#123743 <rust-lang#123743> for more information = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. ``` And then making the extern block unsafe, we get ... ``` error: extern block cannot be declared unsafe --> test.rs:1:1 | 1 | unsafe extern { | ^^^^^^ | = note: see issue rust-lang#123743 <rust-lang#123743> for more information = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable error: items in unadorned `extern` blocks cannot have safety qualifiers --> test.rs:3:5 | 3 | pub safe fn bar(); | ^^^^^^^^^^^^^^^^^^ error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental --> test.rs:3:9 | 3 | pub safe fn bar(); | ^^^^ | = note: see issue rust-lang#123743 <rust-lang#123743> for more information = help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. ``` r? ``@compiler-errors``
2 parents fafb2ea + 15d5dac commit 7715295

File tree

5 files changed

+34
-14
lines changed

5 files changed

+34
-14
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,18 @@ impl<'a> AstValidator<'a> {
469469
fn check_item_safety(&self, span: Span, safety: Safety) {
470470
match self.extern_mod_safety {
471471
Some(extern_safety) => {
472-
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
473-
&& (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks)
474-
{
475-
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
476-
item_span: span,
477-
block: self.current_extern_span().shrink_to_lo(),
478-
});
472+
if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) {
473+
if extern_safety == Safety::Default {
474+
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
475+
item_span: span,
476+
block: Some(self.current_extern_span().shrink_to_lo()),
477+
});
478+
} else if !self.features.unsafe_extern_blocks {
479+
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
480+
item_span: span,
481+
block: None,
482+
});
483+
}
479484
}
480485
}
481486
None => {
@@ -1098,7 +1103,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10981103
}
10991104
}
11001105
} else if let &Safety::Unsafe(span) = safety {
1101-
this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
1106+
let mut diag = this
1107+
.dcx()
1108+
.create_err(errors::UnsafeItem { span, kind: "extern block" });
1109+
rustc_session::parse::add_feature_diagnostics(
1110+
&mut diag,
1111+
self.session,
1112+
sym::unsafe_extern_blocks,
1113+
);
1114+
diag.emit();
11021115
}
11031116

11041117
if abi.is_none() {

compiler/rustc_ast_passes/src/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ pub struct InvalidSafetyOnExtern {
222222
#[primary_span]
223223
pub item_span: Span,
224224
#[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")]
225-
pub block: Span,
225+
pub block: Option<Span>,
226226
}
227227

228228
#[derive(Diagnostic)]

tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe
33
|
44
LL | unsafe extern "C" {
55
| ^^^^^^
6+
|
7+
= note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
8+
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
610

711
error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental
812
--> $DIR/feature-gate-unsafe-extern-blocks.rs:9:5

tests/ui/parser/unsafe-foreign-mod-2.stderr

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ error: extern block cannot be declared unsafe
99
|
1010
LL | extern "C" unsafe {
1111
| ^^^^^^
12+
|
13+
= note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
14+
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
15+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1216

1317
error: items in unadorned `extern` blocks cannot have safety qualifiers
1418
--> $DIR/unsafe-foreign-mod-2.rs:4:5
1519
|
1620
LL | unsafe fn foo();
1721
| ^^^^^^^^^^^^^^^^
18-
|
19-
help: add unsafe to this `extern` block
20-
|
21-
LL | unsafe extern "C" unsafe {
22-
| ++++++
2322

2423
error: aborting due to 3 previous errors
2524

tests/ui/parser/unsafe-foreign-mod.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe
33
|
44
LL | unsafe extern "C" {
55
| ^^^^^^
6+
|
7+
= note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information
8+
= help: add `#![feature(unsafe_extern_blocks)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
610

711
error: aborting due to 1 previous error
812

0 commit comments

Comments
 (0)