Skip to content
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

Make Copy unsafe to implement for ADTs with unsafe fields #134008

Merged
merged 1 commit into from
Dec 10, 2024

Conversation

jswrenn
Copy link
Member

@jswrenn jswrenn commented Dec 7, 2024

As a rule, the application of unsafe to a declaration requires that use-sites of that declaration also entail unsafe. For example, a field declared unsafe may only be read in the lexical context of an unsafe block.

For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing Clone (a safe trait) for a type with unsafe fields will require unsafe to clone those fields.

Prior to this commit, Copy violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of Self.

This commit resolves this by making Copy conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.

Tracking: #132922

r? @compiler-errors

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 7, 2024
@rustbot
Copy link
Collaborator

rustbot commented Dec 7, 2024

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@rust-log-analyzer

This comment has been minimized.

@jswrenn jswrenn force-pushed the unsafe-fields-copy branch from c19cba7 to d66fa52 Compare December 7, 2024 14:16
@rust-log-analyzer

This comment has been minimized.

@jswrenn jswrenn force-pushed the unsafe-fields-copy branch from d66fa52 to 96fc9a9 Compare December 7, 2024 18:32
match (trait_def.safety, unsafe_attr, trait_header.safety, trait_header.polarity) {
let is_copy = tcx.is_lang_item(trait_def.def_id, LangItem::Copy);
let trait_def_safety = if is_copy {
use rustc_type_ir::inherent::*;
Copy link
Member

Choose a reason for hiding this comment

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

don't do this lol

Copy link
Member

Choose a reason for hiding this comment

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

inherent is only for the solver

Copy link
Member Author

@jswrenn jswrenn Dec 7, 2024

Choose a reason for hiding this comment

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

What's your recommendation? The intent of this PR is to implement the suggestion in the RFC discussion that Copy is conditionally (un)safe to implement depending on whether the Self type has unsafe fields. Is there a better way to achieve this? Misunderstood what you were commenting on.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah gotcha. Hm.

Copy link
Member

Choose a reason for hiding this comment

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

just duplicate the method on ty or whatever

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 import inherent::Ty here because it provides the has_unsafe_fields helper. Should I also add that function as an inherent method on rustc_middle::ty::Ty?

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do!

Copy link
Member Author

Choose a reason for hiding this comment

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

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 7, 2024
@jswrenn jswrenn force-pushed the unsafe-fields-copy branch from 96fc9a9 to 47454f3 Compare December 7, 2024 18:51
@rust-log-analyzer

This comment has been minimized.

@jswrenn jswrenn force-pushed the unsafe-fields-copy branch from 47454f3 to ae4c896 Compare December 7, 2024 20:09
@rustbot
Copy link
Collaborator

rustbot commented Dec 7, 2024

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Comment on lines 57 to +77
#[lang = "copy"]
pub unsafe trait Copy {}

unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for u128 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for f32 {}
unsafe impl Copy for f64 {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
unsafe impl<T: ?Sized> Copy for *mut T {}
unsafe impl<T: Copy> Copy for Option<T> {}
pub trait Copy {}

impl Copy for bool {}
impl Copy for u8 {}
impl Copy for u16 {}
impl Copy for u32 {}
impl Copy for u64 {}
impl Copy for u128 {}
impl Copy for usize {}
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for isize {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for char {}
impl<'a, T: ?Sized> Copy for &'a T {}
impl<T: ?Sized> Copy for *const T {}
impl<T: ?Sized> Copy for *mut T {}
impl<T: Copy> Copy for Option<T> {}
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 presume we don't have an obligation to support #[lang = "copy"] unsafe trait Copy {}, since no_core and lang_items are unstable.

Copy link
Member

Choose a reason for hiding this comment

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

That is correct.

@rust-log-analyzer

This comment has been minimized.

As a rule, the application of `unsafe` to a declaration requires that use-sites
of that declaration also require `unsafe`. For example, a field declared
`unsafe` may only be read in the lexical context of an `unsafe` block.

For nearly all safe traits, the safety obligations of fields are explicitly
discharged when they are mentioned in method definitions. For example,
idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields
will require `unsafe` to clone those fields.

Prior to this commit, `Copy` violated this rule. The trait is marked safe, and
although it has no explicit methods, its implementation permits reads of `Self`.

This commit resolves this by making `Copy` conditionally safe to implement. It
remains safe to implement for ADTs without unsafe fields, but unsafe to
implement for ADTs with unsafe fields.

Tracking: rust-lang#132922
@jswrenn jswrenn force-pushed the unsafe-fields-copy branch from ae4c896 to 3ce35a4 Compare December 7, 2024 20:50
@rustbot
Copy link
Collaborator

rustbot commented Dec 7, 2024

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 8, 2024
@compiler-errors
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Dec 9, 2024

📌 Commit 3ce35a4 has been approved by compiler-errors

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 Dec 9, 2024
fmease added a commit to fmease/rust that referenced this pull request Dec 9, 2024
…iler-errors

Make `Copy` unsafe to implement for ADTs with `unsafe` fields

As a rule, the application of `unsafe` to a declaration requires that use-sites of that declaration also entail `unsafe`. For example, a field declared `unsafe` may only be read in the lexical context of an `unsafe` block.

For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields will require `unsafe` to clone those fields.

Prior to this commit, `Copy` violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of `Self`.

This commit resolves this by making `Copy` conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.

Tracking: rust-lang#132922

r? `@compiler-errors`
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 10, 2024
Rollup of 9 pull requests

Successful merges:

 - rust-lang#133967 ([AIX] Pass -bnoipath when adding rust upstream dynamic crates)
 - rust-lang#133970 ([AIX] Replace sa_sigaction with sa_union.__su_sigaction for AIX)
 - rust-lang#133980 ([AIX] Remove option "-n" from AIX "ln" command)
 - rust-lang#134008 (Make `Copy` unsafe to implement for ADTs with `unsafe` fields)
 - rust-lang#134017 (Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction)
 - rust-lang#134023 (handle cygwin environment in `install::sanitize_sh`)
 - rust-lang#134041 (Use SourceMap to load debugger visualizer files)
 - rust-lang#134065 (Move `write_graphviz_results`)
 - rust-lang#134070 (Some asm! diagnostic adjustments and a papercut fix)

r? `@ghost`
`@rustbot` modify labels: rollup
fmease added a commit to fmease/rust that referenced this pull request Dec 10, 2024
…iler-errors

Make `Copy` unsafe to implement for ADTs with `unsafe` fields

As a rule, the application of `unsafe` to a declaration requires that use-sites of that declaration also entail `unsafe`. For example, a field declared `unsafe` may only be read in the lexical context of an `unsafe` block.

For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields will require `unsafe` to clone those fields.

Prior to this commit, `Copy` violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of `Self`.

This commit resolves this by making `Copy` conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.

Tracking: rust-lang#132922

r? ``@compiler-errors``
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 10, 2024
Rollup of 11 pull requests

Successful merges:

 - rust-lang#133478 (jsondocck: Parse, don't validate commands.)
 - rust-lang#133967 ([AIX] Pass -bnoipath when adding rust upstream dynamic crates)
 - rust-lang#133970 ([AIX] Replace sa_sigaction with sa_union.__su_sigaction for AIX)
 - rust-lang#133980 ([AIX] Remove option "-n" from AIX "ln" command)
 - rust-lang#134008 (Make `Copy` unsafe to implement for ADTs with `unsafe` fields)
 - rust-lang#134017 (Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction)
 - rust-lang#134023 (handle cygwin environment in `install::sanitize_sh`)
 - rust-lang#134041 (Use SourceMap to load debugger visualizer files)
 - rust-lang#134065 (Move `write_graphviz_results`)
 - rust-lang#134106 (Add compiler-maintainers who requested to be on review rotation)
 - rust-lang#134123 (bootstrap: Forward cargo JSON output to stdout, not stderr)

Failed merges:

 - rust-lang#134120 (Remove Felix from ping groups and review rotation)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 3eaa785 into rust-lang:master Dec 10, 2024
6 checks passed
@rustbot rustbot added this to the 1.85.0 milestone Dec 10, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 10, 2024
Rollup merge of rust-lang#134008 - jswrenn:unsafe-fields-copy, r=compiler-errors

Make `Copy` unsafe to implement for ADTs with `unsafe` fields

As a rule, the application of `unsafe` to a declaration requires that use-sites of that declaration also entail `unsafe`. For example, a field declared `unsafe` may only be read in the lexical context of an `unsafe` block.

For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields will require `unsafe` to clone those fields.

Prior to this commit, `Copy` violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of `Self`.

This commit resolves this by making `Copy` conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.

Tracking: rust-lang#132922

r? ```@compiler-errors```
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-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants