diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index e7784f345bad..5431ec9679c5 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 4800a1c9f3b9..d1d250a09e64 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 8ec3aeee11ce..10e880da9908 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 de6a82a098f1..67e0e370b7b7 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::, _>>() }; - 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::, _>>()?; - (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 a9ed1857de69..49c1c955b2dd 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,