Skip to content

prevent Freeze and UnsafeUnpin from being implemented outside of core - #161811

Open
joboet wants to merge 1 commit into
rust-lang:mainfrom
joboet:impl_crate_marker_traits
Open

joboet wants to merge 1 commit into
rust-lang:mainfrom
joboet:impl_crate_marker_traits

Conversation

@joboet

@joboet joboet commented Aug 26, 2026 •

Copy link
Copy Markdown
Member

Fixes #161630

impl(crate) only prevents explicit implementations, but not the automatically derived ones (playground), so we can use it to the same effect as #[rustc_deny_explicit_impl] while still having the fundamental implementations of these traits in core.

@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 Aug 26, 2026
@rustbot

rustbot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

r? @clarfonthey

rustbot has assigned @clarfonthey.
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

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from JohnTitor, Mark-Simulacrum, clarfonthey, nia-e

Comment thread library/core/src/pat.rs
@@ -85,7 +85,3 @@ impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<pattern_type!(*const U is !
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<pattern_type!(U is !null)> for pattern_type!(T is !null) {}

impl<T: PointeeSized> Unpin for pattern_type!(*const T is !null) {}

unsafe impl<T: PointeeSized> Freeze for pattern_type!(*const T is !null) {}

@joboet joboet Aug 26, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The UnsafeUnpin implementation already lives in marker, so I've moved this too for consistency.

View changes since the review

#[lang = "freeze"]
#[unstable(feature = "freeze", issue = "121675")]
pub unsafe auto trait Freeze {}
pub impl(crate) unsafe auto trait Freeze {}

@bjorn3 bjorn3 Aug 26, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can these be impl(self)?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There is a manual Freeze implementation for NonZero that's used to provide nicer error messages. Since it's in core, I don't think it matters too much, but I can change it if you want.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I figured impl(self) would make it less likely that someone adds a manual impl outside this module not knowing that it is probably a bad idea. But a manual impl for better error messages makes sense I guess.

@joboet joboet Aug 27, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

On second thought, it's very unlikely for this to show up anyway: there's no way to require the absence of a trait, and NonZero is Freeze for all types that can implement ZeroablePrimitive. So I think you could never run into a situation where the error is "NonZero doesn't implement Freeze because <T as ZeroablePrimitive>::NonZeroInner doesn't implement it". I'll constrain it to impl(self).

Wait, it's about the documentation, so this is still relevant. Nevermind!

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
---- [ui] tests/ui/feature-gates/feature-gate-freeze-impls.rs stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/feature-gates/feature-gate-freeze-impls/feature-gate-freeze-impls.stderr`
diff of stderr:

8    = help: add `#![feature(freeze_impls)]` 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
10 
+ error: trait cannot be implemented outside `core`
+   --> $DIR/feature-gate-freeze-impls.rs:7:1
+    |
+ LL | unsafe impl Freeze for Foo {}
---
11 error[E0658]: explicit impls for the `Freeze` trait are not permitted
12   --> $DIR/feature-gate-freeze-impls.rs:12:1
13    |

18    = help: add `#![feature(freeze_impls)]` to the crate attributes to enable
19    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20 
- error: aborting due to 2 previous errors
+ error: trait cannot be implemented outside `core`
+   --> $DIR/feature-gate-freeze-impls.rs:12:1
+    |
+ LL | impl !Freeze for Bar {}
+    | ^^^^^^^^^^^^^^^^^^^^
+    |
+ note: trait restricted here
+   --> $SRC_DIR/core/src/marker.rs:LL:COL
+ 
---
+ 
+ error: trait cannot be implemented outside `core`
+   --> $DIR/feature-gate-freeze-impls.rs:12:1
+    |
+ LL | impl !Freeze for Bar {}
+    | ^^^^^^^^^^^^^^^^^^^^
+    |
+ note: trait restricted here
+   --> $SRC_DIR/core/src/marker.rs:LL:COL
+ 
---
To only update this specific test, also pass `--test-args feature-gates/feature-gate-freeze-impls.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/feature-gates/feature-gate-freeze-impls.rs" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/feature-gates/feature-gate-freeze-impls" "-Znext-solver=coherence" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0658]: explicit impls for the `Freeze` trait are not permitted
##[error]  --> /checkout/tests/ui/feature-gates/feature-gate-freeze-impls.rs:7:1
   |
LL | unsafe impl Freeze for Foo {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
   |
   = note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
   = help: add `#![feature(freeze_impls)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: trait cannot be implemented outside `core`
##[error]  --> /checkout/tests/ui/feature-gates/feature-gate-freeze-impls.rs:7:1
   |
LL | unsafe impl Freeze for Foo {}
---

error[E0658]: explicit impls for the `Freeze` trait are not permitted
##[error]  --> /checkout/tests/ui/feature-gates/feature-gate-freeze-impls.rs:12:1
   |
LL | impl !Freeze for Bar {}
   | ^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
   |
   = note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
   = help: add `#![feature(freeze_impls)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: trait cannot be implemented outside `core`
##[error]  --> /checkout/tests/ui/feature-gates/feature-gate-freeze-impls.rs:12:1
   |
LL | impl !Freeze for Bar {}
   | ^^^^^^^^^^^^^^^^^^^^
   |
note: trait restricted here
  --> /rustc/FAKE_PREFIX/library/core/src/marker.rs:904:4

@ChayimFriedman2

ChayimFriedman2 commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Wait, does that mean we can get rid of rustc_deny_explicit_impl now (edit: except maybe for better error messages)?

@clarfonthey

Copy link
Copy Markdown
Contributor

Hmm, is the behaviour on derived impls something explicitly documented anywhere? The code looks fine otherwise, but I would like at least some assurance that this isn't going to change down the line.

@clarfonthey

clarfonthey commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Wait, never mind, I misinterpreted "auto-derived" to mean… ones that came from derive, not ones that came from auto, and now I understand. (No, we don't derive these. Obviously.)

Yes, this makes a lot more sense. We should be able to merge this once tests are good.

@joboet

joboet commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

I think this means we could also get rid of the freeze_impls feature that previously restricted manual impl Freezes, CC @oli-obk since you added this in 7849230. Should I go ahead and do that here?

@jhpratt

jhpratt commented Aug 28, 2026

Copy link
Copy Markdown
Member

For behavior on auto-impls (i.e. from an auto trait), this was never explicitly documented anywhere (nor discussed). I can't imagine any situation where that behavior changes.

@mejrs

mejrs commented Aug 28, 2026

Copy link
Copy Markdown
Member

Wait, does that mean we can get rid of rustc_deny_explicit_impl now (edit: except maybe for better error messages)?

No, these traits still need to be implemented, it's just done by the compiler.

@clarfonthey

Copy link
Copy Markdown
Contributor

@rustbot author

@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 Aug 31, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. 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.

You can implement UnsafeUnpinned yourself

8 participants