Skip to content

Commit e94c1ca

Browse files
authored
Unrolled build for rust-lang#121840
Rollup merge of rust-lang#121840 - oli-obk:freeze, r=dtolnay Expose the Freeze trait again (unstably) and forbid implementing it manually non-emoji version of rust-lang#121501 cc rust-lang#60715 This trait is useful for generic constants (associated consts of generic traits). See the test (`tests/ui/associated-consts/freeze.rs`) added in this PR for a usage example. The builtin `Freeze` trait is the only way to do it, users cannot work around this issue. It's also a useful trait for building some very specific abstrations, as shown by the usage by the `zerocopy` crate: google/zerocopy#941 cc ```@RalfJung``` T-lang signed off on reexposing this unstably: rust-lang#121501 (comment)
2 parents 6639672 + 7849230 commit e94c1ca

File tree

15 files changed

+89
-11
lines changed

15 files changed

+89
-11
lines changed

compiler/rustc_codegen_cranelift/example/mini_core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
rustc_attrs,
99
transparent_unions,
1010
auto_traits,
11+
freeze_impls,
1112
thread_local
1213
)]
1314
#![no_core]

compiler/rustc_codegen_gcc/example/mini_core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![feature(
22
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
3-
decl_macro, rustc_attrs, transparent_unions, auto_traits,
3+
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
44
thread_local
55
)]
66
#![no_core]

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ declare_features! (
471471
(unstable, fn_align, "1.53.0", Some(82232)),
472472
/// Support delegating implementation of functions to other already implemented functions.
473473
(incomplete, fn_delegation, "1.76.0", Some(118212)),
474+
/// Allows impls for the Freeze trait.
475+
(internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)),
474476
/// Allows defining gen blocks and `gen fn`.
475477
(unstable, gen_blocks, "1.75.0", Some(117078)),
476478
/// Infer generic args for both consts and types.

compiler/rustc_hir_analysis/src/coherence/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
1010
use rustc_hir::def_id::{DefId, LocalDefId};
1111
use rustc_middle::query::Providers;
1212
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
13+
use rustc_session::parse::feature_err;
1314
use rustc_span::{sym, ErrorGuaranteed};
1415
use rustc_trait_selection::traits;
1516

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

53+
if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
54+
if !tcx.features().freeze_impls {
55+
feature_err(
56+
&tcx.sess,
57+
sym::freeze_impls,
58+
impl_header_span,
59+
"explicit impls for the `Freeze` trait are not permitted",
60+
)
61+
.with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
62+
.emit();
63+
}
64+
}
65+
5266
// Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
5367
if trait_def.deny_explicit_impl {
5468
let trait_name = tcx.item_name(trait_def_id);

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ symbols! {
864864
format_placeholder,
865865
format_unsafe_arg,
866866
freeze,
867+
freeze_impls,
867868
freg,
868869
frem_algebraic,
869870
frem_fast,

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@
204204
// tidy-alphabetical-start
205205
#![cfg_attr(bootstrap, feature(diagnostic_namespace))]
206206
#![cfg_attr(bootstrap, feature(platform_intrinsics))]
207+
#![cfg_attr(not(bootstrap), feature(freeze_impls))]
207208
#![feature(abi_unadjusted)]
208209
#![feature(adt_const_params)]
209210
#![feature(allow_internal_unsafe)]

library/core/src/marker.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -810,15 +810,21 @@ pub trait DiscriminantKind {
810810
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
811811
}
812812

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

824+
#[unstable(feature = "freeze", issue = "121675")]
820825
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
821826
marker_impls! {
827+
#[unstable(feature = "freeze", issue = "121675")]
822828
unsafe Freeze for
823829
{T: ?Sized} PhantomData<T>,
824830
{T: ?Sized} *const T,

tests/run-make/min-global-align/min_global_align.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(no_core, lang_items)]
1+
#![feature(no_core, lang_items, freeze_impls)]
22
#![crate_type = "rlib"]
33
#![no_core]
44

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// https://github.com/rust-lang/rust/issues/50159
2-
#![crate_name="foo"]
2+
#![crate_name = "foo"]
33

44
pub trait Signal {
55
type Item;
@@ -9,15 +9,18 @@ pub trait Signal2 {
99
type Item2;
1010
}
1111

12-
impl<B, C> Signal2 for B where B: Signal<Item = C> {
12+
impl<B, C> Signal2 for B
13+
where
14+
B: Signal<Item = C>,
15+
{
1316
type Item2 = C;
1417
}
1518

1619
// @has foo/struct.Switch.html
1720
// @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
1821
// @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
1922
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
20-
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
23+
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
2124
pub struct Switch<B: Signal> {
2225
pub inner: <B as Signal2>::Item2,
2326
}

tests/rustdoc/empty-section.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#![crate_name = "foo"]
2-
3-
#![feature(negative_impls)]
2+
#![feature(negative_impls, freeze_impls, freeze)]
43

54
pub struct Foo;
65

76
// @has foo/struct.Foo.html
87
// @!hasraw - 'Auto Trait Implementations'
98
impl !Send for Foo {}
109
impl !Sync for Foo {}
10+
impl !std::marker::Freeze for Foo {}
1111
impl !std::marker::Unpin for Foo {}
1212
impl !std::panic::RefUnwindSafe for Foo {}
1313
impl !std::panic::UnwindSafe for Foo {}

tests/rustdoc/synthetic_auto/basic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send'
33
// @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync'
44
// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
5-
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
5+
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
66
pub struct Foo<T> {
77
field: T,
88
}

tests/rustdoc/synthetic_auto/manual.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// 'impl<T> Send for Foo<T>'
77
//
88
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
9-
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
9+
// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
1010
pub struct Foo<T> {
1111
field: T,
1212
}

tests/ui/associated-consts/freeze.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(freeze)]
2+
3+
//@ check-pass
4+
5+
use std::marker::Freeze;
6+
7+
trait Trait<T: Freeze + 'static> {
8+
const VALUE: T;
9+
const VALUE_REF: &'static T = &Self::VALUE;
10+
}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(freeze, negative_impls)]
2+
3+
use std::marker::Freeze;
4+
5+
struct Foo;
6+
7+
unsafe impl Freeze for Foo {}
8+
//~^ explicit impls for the `Freeze` trait are not permitted
9+
10+
struct Bar;
11+
12+
impl !Freeze for Bar {}
13+
//~^ explicit impls for the `Freeze` trait are not permitted
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0658]: explicit impls for the `Freeze` trait are not permitted
2+
--> $DIR/feature-gate-freeze-impls.rs:7:1
3+
|
4+
LL | unsafe impl Freeze for Foo {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
6+
|
7+
= note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
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+
11+
error[E0658]: explicit impls for the `Freeze` trait are not permitted
12+
--> $DIR/feature-gate-freeze-impls.rs:12:1
13+
|
14+
LL | impl !Freeze for Bar {}
15+
| ^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
16+
|
17+
= note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
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+
21+
error: aborting due to 2 previous errors
22+
23+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)