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

Expose the Freeze trait again (unstably) and forbid implementing it manually #121840

Merged
merged 2 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
rustc_attrs,
transparent_unions,
auto_traits,
freeze_impls,
thread_local
)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/example/mini_core.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
decl_macro, rustc_attrs, transparent_unions, auto_traits,
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
thread_local
)]
#![no_core]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ declare_features! (
(unstable, fn_align, "1.53.0", Some(82232)),
/// Support delegating implementation of functions to other already implemented functions.
(incomplete, fn_delegation, "1.76.0", Some(118212)),
/// Allows impls for the Freeze trait.
(internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)),
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_session::parse::feature_err;
use rustc_span::{sym, ErrorGuaranteed};
use rustc_trait_selection::traits;

Expand Down Expand Up @@ -49,6 +50,19 @@ fn enforce_trait_manually_implementable(
) -> Result<(), ErrorGuaranteed> {
let impl_header_span = tcx.def_span(impl_def_id);

if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
if !tcx.features().freeze_impls {
feature_err(
&tcx.sess,
sym::freeze_impls,
impl_header_span,
"explicit impls for the `Freeze` trait are not permitted",
)
.with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
.emit();
}
}

// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
if trait_def.deny_explicit_impl {
let trait_name = tcx.item_name(trait_def_id);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ symbols! {
format_placeholder,
format_unsafe_arg,
freeze,
freeze_impls,
freg,
frem_algebraic,
frem_fast,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(platform_intrinsics))]
#![cfg_attr(not(bootstrap), feature(freeze_impls))]
#![feature(abi_unadjusted)]
#![feature(adt_const_params)]
#![feature(allow_internal_unsafe)]
Expand Down
10 changes: 8 additions & 2 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,15 +810,21 @@ pub trait DiscriminantKind {
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
}

/// Compiler-internal trait used to determine whether a type contains
/// Used to determine whether a type contains
/// any `UnsafeCell` internally, but not through an indirection.
/// This affects, for example, whether a `static` of that type is
/// placed in read-only static memory or writable static memory.
/// This can be used to declare that a constant with a generic type
/// will not contain interior mutability, and subsequently allow
/// placing the constant behind references.
#[lang = "freeze"]
pub(crate) unsafe auto trait Freeze {}
#[unstable(feature = "freeze", issue = "121675")]
pub unsafe auto trait Freeze {}

#[unstable(feature = "freeze", issue = "121675")]
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
marker_impls! {
#[unstable(feature = "freeze", issue = "121675")]
unsafe Freeze for
{T: ?Sized} PhantomData<T>,
{T: ?Sized} *const T,
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/min-global-align/min_global_align.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(no_core, lang_items)]
#![feature(no_core, lang_items, freeze_impls)]
#![crate_type = "rlib"]
#![no_core]

Expand Down
9 changes: 6 additions & 3 deletions tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// https://github.com/rust-lang/rust/issues/50159
#![crate_name="foo"]
#![crate_name = "foo"]

pub trait Signal {
type Item;
Expand All @@ -9,15 +9,18 @@ pub trait Signal2 {
type Item2;
}

impl<B, C> Signal2 for B where B: Signal<Item = C> {
impl<B, C> Signal2 for B
where
B: Signal<Item = C>,
{
type Item2 = C;
}

// @has foo/struct.Switch.html
// @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
// @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
pub struct Switch<B: Signal> {
pub inner: <B as Signal2>::Item2,
}
4 changes: 2 additions & 2 deletions tests/rustdoc/empty-section.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#![crate_name = "foo"]

#![feature(negative_impls)]
#![feature(negative_impls, freeze_impls, freeze)]

pub struct Foo;

// @has foo/struct.Foo.html
// @!hasraw - 'Auto Trait Implementations'
impl !Send for Foo {}
impl !Sync for Foo {}
impl !std::marker::Freeze for Foo {}
impl !std::marker::Unpin for Foo {}
impl !std::panic::RefUnwindSafe for Foo {}
impl !std::panic::UnwindSafe for Foo {}
2 changes: 1 addition & 1 deletion tests/rustdoc/synthetic_auto/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send'
// @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync'
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
pub struct Foo<T> {
field: T,
}
2 changes: 1 addition & 1 deletion tests/rustdoc/synthetic_auto/manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// 'impl<T> Send for Foo<T>'
//
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
pub struct Foo<T> {
field: T,
}
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/associated-consts/freeze.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(freeze)]

//@ check-pass

use std::marker::Freeze;

trait Trait<T: Freeze + 'static> {
const VALUE: T;
const VALUE_REF: &'static T = &Self::VALUE;
}

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/feature-gates/feature-gate-freeze-impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(freeze, negative_impls)]

use std::marker::Freeze;

struct Foo;

unsafe impl Freeze for Foo {}
//~^ explicit impls for the `Freeze` trait are not permitted

struct Bar;

impl !Freeze for Bar {}
//~^ explicit impls for the `Freeze` trait are not permitted

fn main() {}
23 changes: 23 additions & 0 deletions tests/ui/feature-gates/feature-gate-freeze-impls.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0658]: explicit impls for the `Freeze` trait are not permitted
--> $DIR/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[E0658]: explicit impls for the `Freeze` trait are not permitted
--> $DIR/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: aborting due to 2 previous errors

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