Skip to content

std::marker::Freeze disallows blanket impl since it "could be implemented on Cell and UnsafeCell in the future" #133714

@ds84182

Description

@ds84182

I tried this code:

#![feature(freeze)]
use std::{cell::Cell, marker::Freeze};

unsafe trait IntoFreeze {
  type Frozen: Freeze;
}

unsafe impl<T: Freeze> IntoFreeze for T {
  type Frozen = T;
}

unsafe impl<T: IntoFreeze> IntoFreeze for Cell<T> {
  type Frozen = T::Frozen;
}

I expected to see this happen: Code should compile since Freeze will never be implemented for Cell and UnsafeCell.

Instead, this happened:

error[E0119]: conflicting implementations of trait `IntoFreeze` for type `Cell<_>`
  --> src/lib.rs:12:1
   |
8  | unsafe impl<T: Freeze> IntoFreeze for T {
   | --------------------------------------- first implementation here
...
12 | unsafe impl<T: IntoFreeze> IntoFreeze for Cell<T> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cell<_>`
   |
   = note: upstream crates may add a new impl of trait `std::marker::Freeze` for type `std::cell::Cell<_>` in future versions

For more information about this error, try `rustc --explain E0119`.

Meta

rustc --version --verbose:

1.85.0-nightly (2024-11-30 7442931d49b199ad0a1c)

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Dec 1, 2024
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
F-freeze`#![feature(freeze)]`
on Dec 2, 2024
jieyouxu

jieyouxu commented on Dec 2, 2024

@jieyouxu
Member

I think this is intentional, but cc @oli-obk just in case.

removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Dec 2, 2024
oli-obk

oli-obk commented on Dec 2, 2024

@oli-obk
Contributor

We explicitly impl<T: ?Sized> !Freeze for UnsafeCell<T> {} which I assumed should allow at least "overlapping" impls for UnsafeCell, but that may not be true for auto traits? Or does reasoning about negative impls require another feature and only work on nightly?

zachs18

zachs18 commented on Dec 2, 2024

@zachs18
Contributor

Note that with #![feature(with_negative_coherence)], the UnsafeCell impl is allowed (due to the explicit impl !Freeze for UnsafeCell<_>), but the Cell impl is still disallowed (IIUC since it gets its "!Freeze-ness" via auto trait impl instead of an explicit negative impl): playground link.


I'm not sure if the original code not being allowed is related to Freeze being an auto trait, and don't know of any non-auto traits with negative impls to compare to off the top of my head. Maybe the impl !Fn for &str? But Fn is #[fundamental] which may also affect things. I misremembered, that is unrelated to negative impls; Fn being #[fundamental] is why there doesn't need to be an impl !Fn for &str source

Hmm, though that would indicate that Freeze being #[fundamental] would allow the impls in the OP? but would also make adding or removing interior mutability from a type be a semver-breaking change, but IIRC thas already somewhat of an issue due to consts?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-freeze`#![feature(freeze)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @oli-obk@ds84182@zachs18@jieyouxu@rustbot

        Issue actions

          `std::marker::Freeze` disallows blanket impl since it "could be implemented on `Cell` and `UnsafeCell` in the future" · Issue #133714 · rust-lang/rust