Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22959 from ChayimFriedman2/covariant-unsafe-cell
feat: Support `CovariantUnsafeCell`
Chayim Refael Friedman 10 days ago
parent b2abc7e · parent 6338f27 · commit ad35b20
-rw-r--r--crates/hir-def/src/signatures.rs7
-rw-r--r--crates/hir-ty/src/variance.rs10
-rw-r--r--crates/intern/src/symbol/symbols.rs1
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,