Skip to content

unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract #141471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 7, 2025

Conversation

RalfJung
Copy link
Member

Inspired by discussion in #139368.
Cc @hanna-kruppe

@rustbot
Copy link
Collaborator

rustbot commented May 23, 2025

r? @thomcc

rustbot has assigned @thomcc.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 23, 2025
@RalfJung
Copy link
Member Author

RalfJung commented Jun 5, 2025

@traviscross maybe you could take a look at this? It came out of discussion in #139368 which you also participated in.

Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modulo the changes mentioned, this looks right to me.

/// its callers must uphold -- the fact that `idx < LEN`.
/// to contend with. Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation
/// does not get to just pick an arbitrary safety contract! It *has* to use the safety contract
/// defined by the trait (or a stronger contract, i.e., weaker preconditions).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// defined by the trait (or a stronger contract, i.e., weaker preconditions).
/// defined by the trait or one with strictly weaker preconditions.

This is both shorter and avoids getting into the question of "from whose perspective is the contract stronger?"

/// obligations of its callees. (We enabled `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked`
/// is not implicitly an unsafe block.) For that purpose it can make use of the contract that all
/// its callers must uphold -- the fact that `idx < LEN`.
/// to contend with. Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the implementation of get_unchecked has no proof obligation to contend with.

I might suggest a parenthetical here that hints at what will follow in the next paragraph. Almost always, such an implementation will have an unsafe block within.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the next paragraph might as well be removed entirely as that's the only thing it says.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reordered things so the point about "there'll be an unsafe block within" comes first. Do you think that is better?

Comment on lines 2164 to 2165
/// `unsafe` *block* to indicate it discharged the proof obligations of its callees. (We enabled
/// `unsafe_op_in_unsafe_fn`, so the body of `idx_unchecked` is not implicitly an unsafe block.) For
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We turned this lint on by default in Rust 2024. This should no longer be written as though it needs to be turned on (there are separately other updates that should be made in this chapter due to this).

Copy link
Member Author

@RalfJung RalfJung Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like feature creep to extend my PR to also account for this update :/

This is not new text.

@RalfJung RalfJung force-pushed the unsafe-fn-in-trait branch from e55f37a to 66fd846 Compare June 6, 2025 14:42
@traviscross
Copy link
Contributor

Looks good. Thanks @RalfJung. Rebase if you want, then r=me.

r? traviscross

@rustbot rustbot assigned traviscross and unassigned thomcc Jun 6, 2025
@RalfJung RalfJung force-pushed the unsafe-fn-in-trait branch from 66fd846 to 910a59d Compare June 6, 2025 20:34
@RalfJung
Copy link
Member Author

RalfJung commented Jun 6, 2025

Thanks for the review!

@bors r=traviscross rollup

@bors
Copy link
Collaborator

bors commented Jun 6, 2025

📌 Commit 910a59d has been approved by traviscross

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests

Successful merges:

 - #140418 (Reexport types from `c_size_t` in `std`)
 - #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
 - #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
 - #142043 (Verbose suggestion to make param `const`)
 - #142086 (duduplicate more AST visitor methods)
 - #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
 - #142105 (remove extraneous text)
 - #142112 (fix typo)
 - #142113 (Reduce confusion of some drop order tests)
 - #142114 (Compute number of digits instead of relying on constant value for u128 display code)
 - #142118 (rustc_lexer: typo fix + small cleanups)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 15d9b96 into rust-lang:master Jun 7, 2025
10 checks passed
@rustbot rustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #141471 - RalfJung:unsafe-fn-in-trait, r=traviscross

unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract

Inspired by discussion in #139368.
Cc `@hanna-kruppe`
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
 - rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
 - rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
 - rust-lang/rust#142043 (Verbose suggestion to make param `const`)
 - rust-lang/rust#142086 (duduplicate more AST visitor methods)
 - rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
 - rust-lang/rust#142105 (remove extraneous text)
 - rust-lang/rust#142112 (fix typo)
 - rust-lang/rust#142113 (Reduce confusion of some drop order tests)
 - rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
 - rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)

r? `@ghost`
`@rustbot` modify labels: rollup
@RalfJung RalfJung deleted the unsafe-fn-in-trait branch June 7, 2025 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants