Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #19650 from Veykril/push-rkxrprnwqktr
fix: Support unstable `UnsafePinned` struct in type layout calc
Lukas Wirth 2025-04-21
parent 66e3b58 · parent d16b862 · commit c673dc8
-rw-r--r--crates/hir-def/src/lang_item.rs1
-rw-r--r--crates/hir-def/src/signatures.rs3
-rw-r--r--crates/hir-ty/src/lang_items.rs6
-rw-r--r--crates/hir-ty/src/layout/adt.rs19
-rw-r--r--crates/intern/src/symbol/symbols.rs1
5 files changed, 16 insertions, 14 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index e7784f345b..5431ec9679 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -345,6 +345,7 @@ language_item_table! {
IndexMut, sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1);
UnsafeCell, sym::unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None;
+ UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, Target::Struct, GenericRequirement::None;
VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None;
Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs
index 4800a1c9f3..d1d250a09e 100644
--- a/crates/hir-def/src/signatures.rs
+++ b/crates/hir-def/src/signatures.rs
@@ -62,6 +62,8 @@ bitflags! {
const IS_MANUALLY_DROP = 1 << 5;
/// Indicates whether this struct is `UnsafeCell`.
const IS_UNSAFE_CELL = 1 << 6;
+ /// Indicates whether this struct is `UnsafePinned`.
+ const IS_UNSAFE_PINNED = 1 << 7;
}
}
@@ -84,6 +86,7 @@ impl StructSignature {
LangItem::OwnedBox => flags |= StructFlags::IS_BOX,
LangItem::ManuallyDrop => flags |= StructFlags::IS_MANUALLY_DROP,
LangItem::UnsafeCell => flags |= StructFlags::IS_UNSAFE_CELL,
+ LangItem::UnsafePinned => flags |= StructFlags::IS_UNSAFE_PINNED,
_ => (),
}
}
diff --git a/crates/hir-ty/src/lang_items.rs b/crates/hir-ty/src/lang_items.rs
index 8ec3aeee11..10e880da99 100644
--- a/crates/hir-ty/src/lang_items.rs
+++ b/crates/hir-ty/src/lang_items.rs
@@ -11,12 +11,6 @@ pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
db.struct_signature(id).flags.contains(StructFlags::IS_BOX)
}
-pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {
- let AdtId::StructId(id) = adt else { return false };
-
- db.struct_signature(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
-}
-
pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, LangItem)> {
use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering};
Some(match op {
diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs
index de6a82a098..67e0e370b7 100644
--- a/crates/hir-ty/src/layout/adt.rs
+++ b/crates/hir-ty/src/layout/adt.rs
@@ -5,7 +5,7 @@ use std::{cmp, ops::Bound};
use hir_def::{
AdtId, VariantId,
layout::{Integer, ReprOptions, TargetDataLayout},
- signatures::VariantFields,
+ signatures::{StructFlags, VariantFields},
};
use intern::sym;
use rustc_index::IndexVec;
@@ -16,7 +16,6 @@ use triomphe::Arc;
use crate::{
Substitution, TraitEnvironment,
db::HirDatabase,
- lang_items::is_unsafe_cell,
layout::{Layout, LayoutError, field_ty},
};
@@ -40,18 +39,22 @@ pub fn layout_of_adt_query(
.map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &subst), trait_env.clone()))
.collect::<Result<Vec<_>, _>>()
};
- let (variants, repr) = match def {
+ let (variants, repr, is_special_no_niche) = match def {
AdtId::StructId(s) => {
- let data = db.struct_signature(s);
+ let sig = db.struct_signature(s);
let mut r = SmallVec::<[_; 1]>::new();
r.push(handle_variant(s.into(), &db.variant_fields(s.into()))?);
- (r, data.repr.unwrap_or_default())
+ (
+ r,
+ sig.repr.unwrap_or_default(),
+ sig.flags.intersects(StructFlags::IS_UNSAFE_CELL | StructFlags::IS_UNSAFE_PINNED),
+ )
}
AdtId::UnionId(id) => {
let data = db.union_signature(id);
let mut r = SmallVec::new();
r.push(handle_variant(id.into(), &db.variant_fields(id.into()))?);
- (r, data.repr.unwrap_or_default())
+ (r, data.repr.unwrap_or_default(), false)
}
AdtId::EnumId(e) => {
let variants = db.enum_variants(e);
@@ -60,7 +63,7 @@ pub fn layout_of_adt_query(
.iter()
.map(|&(v, _)| handle_variant(v.into(), &db.variant_fields(v.into())))
.collect::<Result<SmallVec<_>, _>>()?;
- (r, db.enum_signature(e).repr.unwrap_or_default())
+ (r, db.enum_signature(e).repr.unwrap_or_default(), false)
}
};
let variants = variants
@@ -75,7 +78,7 @@ pub fn layout_of_adt_query(
&repr,
&variants,
matches!(def, AdtId::EnumId(..)),
- is_unsafe_cell(db, def),
+ is_special_no_niche,
layout_scalar_valid_range(db, def),
|min, max| repr_discr(dl, &repr, min, max).unwrap_or((Integer::I8, false)),
variants.iter_enumerated().filter_map(|(id, _)| {
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index a9ed1857de..49c1c955b2 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -512,6 +512,7 @@ define_symbols! {
unreachable_2021,
unreachable,
unsafe_cell,
+ unsafe_pinned,
unsize,
unstable,
usize,