Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22959 from ChayimFriedman2/covariant-unsafe-cell
feat: Support `CovariantUnsafeCell`
| -rw-r--r-- | crates/hir-def/src/signatures.rs | 7 | ||||
| -rw-r--r-- | crates/hir-ty/src/variance.rs | 10 | ||||
| -rw-r--r-- | crates/intern/src/symbol/symbols.rs | 1 |
3 files changed, 16 insertions, 2 deletions
diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs index 45dab8859d..ab5d377387 100644 --- a/crates/hir-def/src/signatures.rs +++ b/crates/hir-def/src/signatures.rs @@ -52,7 +52,7 @@ pub struct StructSignature { bitflags! { #[derive(Debug, Copy, Clone, PartialEq, Eq)] - pub struct StructFlags: u8 { + pub struct StructFlags: u16 { /// Indicates whether this struct has `#[repr]`. const HAS_REPR = 1 << 0; /// Indicates whether the struct has a `#[rustc_has_incoherent_inherent_impls]` attribute. @@ -69,6 +69,8 @@ bitflags! { const IS_UNSAFE_CELL = 1 << 6; /// Indicates whether this struct is `UnsafePinned`. const IS_UNSAFE_PINNED = 1 << 7; + /// Indicates whether this struct is `CovariantUnsafeCell`. + const IS_COVARIANT_UNSAFE_CELL = 1 << 8; } } @@ -104,6 +106,9 @@ impl StructSignature { _ if lang == sym::owned_box => flags |= StructFlags::IS_BOX, _ if lang == sym::manually_drop => flags |= StructFlags::IS_MANUALLY_DROP, _ if lang == sym::unsafe_cell => flags |= StructFlags::IS_UNSAFE_CELL, + _ if lang == sym::covariant_unsafe_cell => { + flags |= StructFlags::IS_COVARIANT_UNSAFE_CELL + } _ if lang == sym::unsafe_pinned => flags |= StructFlags::IS_UNSAFE_PINNED, _ => (), } diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index 9e04353087..2690297283 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -49,7 +49,9 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance let types = || crate::next_solver::default_types(db); if flags.contains(StructFlags::IS_UNSAFE_CELL) { return types().one_invariant.store(); - } else if flags.contains(StructFlags::IS_PHANTOM_DATA) { + } else if flags.intersects( + StructFlags::IS_PHANTOM_DATA | StructFlags::IS_COVARIANT_UNSAFE_CELL, + ) { return types().one_covariant.store(); } } @@ -433,6 +435,7 @@ struct Covariant<A> { check( r#" //- minicore: cell +#![feature(lang_items)] use core::cell::UnsafeCell; @@ -461,6 +464,10 @@ enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o] Bar(Contravariant<B>),` Zed(Covariant<C>,Contravariant<C>) } + +#[repr(transparent)] +#[lang = "covariant_unsafe_cell"] +pub struct CovariantUnsafeCell<T: ?Sized>(UnsafeCell<T>); //~ ERROR [T: +] "#, expect![[r#" InvariantMut['a: covariant, A: invariant, B: invariant] @@ -469,6 +476,7 @@ enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o] Covariant[A: covariant] Contravariant[A: contravariant] Enum[A: covariant, B: contravariant, C: invariant] + CovariantUnsafeCell[T: covariant] "#]], ); } diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs index fe303aa0e0..9a566ee687 100644 --- a/crates/intern/src/symbol/symbols.rs +++ b/crates/intern/src/symbol/symbols.rs @@ -597,6 +597,7 @@ define_symbols! { unreachable_2021, unreachable, unsafe_cell, + covariant_unsafe_cell, unsafe_pinned, unsize, unstable, |