Improve error message for extern "C" unsafe fn()
This was handled correctly already for `extern unsafe fn()`. Co-authored-by: Folkert <folkert@folkertdev.nl>
This commit is contained in:
parent
33dd288ef1
commit
3fdc99193e
5 changed files with 30 additions and 14 deletions
|
@ -2483,12 +2483,15 @@ impl<'a> Parser<'a> {
|
||||||
/// `check_pub` adds additional `pub` to the checks in case users place it
|
/// `check_pub` adds additional `pub` to the checks in case users place it
|
||||||
/// wrongly, can be used to ensure `pub` never comes after `default`.
|
/// wrongly, can be used to ensure `pub` never comes after `default`.
|
||||||
pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
|
pub(super) fn check_fn_front_matter(&mut self, check_pub: bool, case: Case) -> bool {
|
||||||
|
const ALL_QUALS: &[Symbol] =
|
||||||
|
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern];
|
||||||
|
|
||||||
// We use an over-approximation here.
|
// We use an over-approximation here.
|
||||||
// `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
|
// `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
|
||||||
// `pub` is added in case users got confused with the ordering like `async pub fn`,
|
// `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.
|
// only if it wasn't preceded by `default` as `default pub` is invalid.
|
||||||
let quals: &[Symbol] = if check_pub {
|
let quals: &[Symbol] = if check_pub {
|
||||||
&[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
|
ALL_QUALS
|
||||||
} else {
|
} else {
|
||||||
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
|
&[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
|
||||||
};
|
};
|
||||||
|
@ -2518,9 +2521,9 @@ impl<'a> Parser<'a> {
|
||||||
|| self.check_keyword_case(kw::Extern, case)
|
|| self.check_keyword_case(kw::Extern, case)
|
||||||
&& self.look_ahead(1, |t| t.can_begin_string_literal())
|
&& self.look_ahead(1, |t| t.can_begin_string_literal())
|
||||||
&& (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) ||
|
&& (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) ||
|
||||||
// this branch is only for better diagnostic in later, `pub` is not allowed here
|
// this branch is only for better diagnostics; `pub`, `unsafe`, etc. are not allowed here
|
||||||
(self.may_recover()
|
(self.may_recover()
|
||||||
&& self.look_ahead(2, |t| t.is_keyword(kw::Pub))
|
&& self.look_ahead(2, |t| ALL_QUALS.iter().any(|&kw| t.is_keyword(kw)))
|
||||||
&& self.look_ahead(3, |t| t.is_keyword_case(kw::Fn, case))))
|
&& self.look_ahead(3, |t| t.is_keyword_case(kw::Fn, case))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
trait T {
|
trait T {
|
||||||
extern "Rust" unsafe fn foo();
|
extern "Rust" unsafe fn foo();
|
||||||
//~^ ERROR expected `{`, found keyword `unsafe`
|
//~^ ERROR expected `fn`, found keyword `unsafe`
|
||||||
|
//~| NOTE expected `fn`
|
||||||
|
//~| HELP `unsafe` must come before `extern "Rust"`
|
||||||
|
//~| SUGGESTION unsafe extern "Rust"
|
||||||
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
error: expected `{`, found keyword `unsafe`
|
error: expected `fn`, found keyword `unsafe`
|
||||||
--> $DIR/issue-19398.rs:2:19
|
--> $DIR/issue-19398.rs:2:19
|
||||||
|
|
|
|
||||||
LL | trait T {
|
|
||||||
| - while parsing this item list starting here
|
|
||||||
LL | extern "Rust" unsafe fn foo();
|
LL | extern "Rust" unsafe fn foo();
|
||||||
| ^^^^^^ expected `{`
|
| --------------^^^^^^
|
||||||
LL |
|
| | |
|
||||||
LL | }
|
| | expected `fn`
|
||||||
| - the item list ends here
|
| help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"`
|
||||||
|
|
|
||||||
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
// Visibilities are tested elsewhere.
|
// Visibilities are tested elsewhere.
|
||||||
|
|
||||||
extern "C" unsafe fn test() {}
|
extern "C" unsafe fn test() {}
|
||||||
//~^ ERROR
|
//~^ ERROR expected `fn`, found keyword `unsafe`
|
||||||
|
//~| NOTE expected `fn`
|
||||||
|
//~| HELP `unsafe` must come before `extern "C"`
|
||||||
|
//~| SUGGESTION unsafe extern "C"
|
||||||
|
//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
error: expected `{`, found keyword `unsafe`
|
error: expected `fn`, found keyword `unsafe`
|
||||||
--> $DIR/wrong-unsafe-abi.rs:9:12
|
--> $DIR/wrong-unsafe-abi.rs:9:12
|
||||||
|
|
|
|
||||||
LL | extern "C" unsafe fn test() {}
|
LL | extern "C" unsafe fn test() {}
|
||||||
| ^^^^^^ expected `{`
|
| -----------^^^^^^
|
||||||
|
| | |
|
||||||
|
| | expected `fn`
|
||||||
|
| help: `unsafe` must come before `extern "C"`: `unsafe extern "C"`
|
||||||
|
|
|
||||||
|
= note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue