Bad parse error on token sequences `safe unsafe` and `unsafe safe`
Open
Nobody has claimed this yet.
A-diagnostics
A-parser
D-confusing
D-incorrect
D-invalid-suggestion
D-terse
T-compiler
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
// #1
unsafe extern {
safe unsafe fn foo();
unsafe safe fn bar();
}
// #2
unsafe safe fn baz() {}
safe unsafe fn qux() {}
// #3
unsafe safe extern "C" fn ham() {}
safe unsafe extern "C" fn egg() {}
Current output
# example #1:
`safe` must come before `unsafe`: `safe unsafe`
`unsafe` must come before `safe`: `unsafe safe`
# Example #2
items outside an `unsafe extern {...} block may not be annotated with `safe``
`safe` must come before `unsafe`: `safe unsafe`
`unsafe` must come before `safe`: `unsafe safe`
# example #3 is the same as #2
Desired output
# Example #1
error: `safe` and `unsafe` are incompatible
note: extern functions are unsafe by default
help: if you want to make this function safe, remove `unsafe`
# Example #2
error: items outside an `unsafe extern {...}` block may not be annotated with `safe`
help: remove `safe`
# example #3
error: items outside an `unsafe extern {...}` block may not be annotated with `safe`
note: extern functions are safe by default
help: remove `safe`
Rationale and extra context
look at the errors for #2 and #3:
`safe` must come before `unsafe`: `safe unsafe`
`unsafe` must come before `safe`: `unsafe safe`
this means that it thinks that the order is incorrect
which is likely because they are both included in the check for order
Other cases
// #1
unsafe safe static FOO: i32 = 42;
unsafe safe const BAR: i32 = 42;
unsafe safe trait Baz {}
unsafe trait _X {}
unsafe safe impl _X for i32 {}
// #2
unsafe extern {
unsafe safe static QUX: usize = 42;
// the rest of the examples just copy pasted
}
Output:
# #1
items outside an `unsafe extern` blocks cannot be `safe`
# shuffle safe and unsafe like usual
# #2
# same as 1 but without the 'items outside `unsafe extern` ...'
Rust Version
$ rustc --version --verbose
rustc 1.83.0 (90b35a623 2024-11-26)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: x86_64-unknown-linux-gnu
release: 1.83.0
LLVM version: 19.1.1
Anything else?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the Rust code examples with rustc 1.83.0 and compare the current diagnostics with the desired output. No source file or test is named; trace the compiler diagnostics for safe/unsafe ordering and add coverage for the extern-block and standalone-item cases, with completion defined by matching the requested errors, notes, and help messages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100