about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/db.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs52
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/signatures.rs90
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/visibility.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs59
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs39
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs2
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs2
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/minicore.rs140
39 files changed, 348 insertions, 194 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index e472072e32a..c67bb2422ac 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -29,7 +29,6 @@ use crate::{
     signatures::{
         ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
         StructSignature, TraitAliasSignature, TraitSignature, TypeAliasSignature, UnionSignature,
-        VariantFields,
     },
     tt,
     visibility::{self, Visibility},
@@ -113,17 +112,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
 
     // region:data
 
-    #[salsa::invoke(VariantFields::query)]
-    fn variant_fields_with_source_map(
-        &self,
-        id: VariantId,
-    ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>);
-
-    #[salsa::tracked]
-    fn variant_fields(&self, id: VariantId) -> Arc<VariantFields> {
-        self.variant_fields_with_source_map(id).0
-    }
-
     #[salsa::tracked]
     fn trait_signature(&self, trait_: TraitId) -> Arc<TraitSignature> {
         self.trait_signature_with_source_map(trait_).0
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
index f617c3225ae..85bd193223f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs
@@ -9,7 +9,10 @@ pub mod scope;
 #[cfg(test)]
 mod tests;
 
-use std::ops::{Deref, Index};
+use std::{
+    ops::{Deref, Index},
+    sync::LazyLock,
+};
 
 use cfg::{CfgExpr, CfgOptions};
 use either::Either;
@@ -19,6 +22,7 @@ use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
 use span::{Edition, SyntaxContext};
 use syntax::{AstPtr, SyntaxNodePtr, ast};
+use triomphe::Arc;
 use tt::TextRange;
 
 use crate::{
@@ -220,6 +224,12 @@ impl ExpressionStoreBuilder {
 }
 
 impl ExpressionStore {
+    pub fn empty_singleton() -> Arc<Self> {
+        static EMPTY: LazyLock<Arc<ExpressionStore>> =
+            LazyLock::new(|| Arc::new(ExpressionStoreBuilder::default().finish()));
+        EMPTY.clone()
+    }
+
     /// Returns an iterator over all block expressions in this store that define inner items.
     pub fn blocks<'a>(
         &'a self,
@@ -636,6 +646,12 @@ impl Index<PathId> for ExpressionStore {
 // FIXME: Change `node_` prefix to something more reasonable.
 // Perhaps `expr_syntax` and `expr_id`?
 impl ExpressionStoreSourceMap {
+    pub fn empty_singleton() -> Arc<Self> {
+        static EMPTY: LazyLock<Arc<ExpressionStoreSourceMap>> =
+            LazyLock::new(|| Arc::new(ExpressionStoreSourceMap::default()));
+        EMPTY.clone()
+    }
+
     pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> {
         match id {
             ExprOrPatId::ExprId(id) => self.expr_syntax(id),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
index d15c855aa6a..c0e51b338b4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -2250,7 +2250,7 @@ impl ExprCollector<'_> {
                         Some(ModuleDefId::ConstId(_)) => (None, Pat::Path(name.into())),
                         Some(ModuleDefId::EnumVariantId(variant))
                         // FIXME: This can cause a cycle if the user is writing invalid code
-                            if self.db.variant_fields(variant.into()).shape != FieldsShape::Record =>
+                            if variant.fields(self.db).shape != FieldsShape::Record =>
                         {
                             (None, Pat::Path(name.into()))
                         }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
index 56c7655f9ea..87bcd33ed7b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
@@ -121,7 +121,7 @@ pub fn print_variant_body_hir(db: &dyn DefDatabase, owner: VariantId, edition: E
         VariantId::UnionId(it) => format!("union {}", item_name(db, it, "<missing>")),
     };
 
-    let fields = db.variant_fields(owner);
+    let fields = owner.fields(db);
 
     let mut p = Printer {
         db,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
index fff62b11c64..750308026ee 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lang_item.rs
@@ -308,6 +308,8 @@ impl LangItem {
 language_item_table! {
 //  Variant name,            Name,                     Getter method name,         Target                  Generic requirements;
     Sized,                   sym::sized,               sized_trait,                Target::Trait,          GenericRequirement::Exact(0);
+    MetaSized,               sym::meta_sized,          sized_trait,                Target::Trait,          GenericRequirement::Exact(0);
+    PointeeSized,            sym::pointee_sized,       sized_trait,                Target::Trait,          GenericRequirement::Exact(0);
     Unsize,                  sym::unsize,              unsize_trait,               Target::Trait,          GenericRequirement::Minimum(1);
     /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
     StructuralPeq,           sym::structural_peq,      structural_peq_trait,       Target::Trait,          GenericRequirement::None;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index eb74c97a7d1..bdf8b453e2d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -87,6 +87,7 @@ use crate::{
     attr::Attrs,
     builtin_type::BuiltinType,
     db::DefDatabase,
+    expr_store::ExpressionStoreSourceMap,
     hir::generics::{LocalLifetimeParamId, LocalTypeOrConstParamId},
     nameres::{
         LocalDefMap,
@@ -254,9 +255,35 @@ impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
 type StructLoc = ItemLoc<ast::Struct>;
 impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
 
+impl StructId {
+    pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
+        VariantFields::firewall(db, self.into())
+    }
+
+    pub fn fields_with_source_map(
+        self,
+        db: &dyn DefDatabase,
+    ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
+        VariantFields::query(db, self.into())
+    }
+}
+
 pub type UnionLoc = ItemLoc<ast::Union>;
 impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
 
+impl UnionId {
+    pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
+        VariantFields::firewall(db, self.into())
+    }
+
+    pub fn fields_with_source_map(
+        self,
+        db: &dyn DefDatabase,
+    ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
+        VariantFields::query(db, self.into())
+    }
+}
+
 pub type EnumLoc = ItemLoc<ast::Enum>;
 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
 
@@ -337,6 +364,20 @@ pub struct EnumVariantLoc {
 }
 impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
 impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
+
+impl EnumVariantId {
+    pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
+        VariantFields::firewall(db, self.into())
+    }
+
+    pub fn fields_with_source_map(
+        self,
+        db: &dyn DefDatabase,
+    ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
+        VariantFields::query(db, self.into())
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Macro2Loc {
     pub container: ModuleId,
@@ -1024,8 +1065,15 @@ pub enum VariantId {
 impl_from!(EnumVariantId, StructId, UnionId for VariantId);
 
 impl VariantId {
-    pub fn variant_data(self, db: &dyn DefDatabase) -> Arc<VariantFields> {
-        db.variant_fields(self)
+    pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
+        VariantFields::firewall(db, self)
+    }
+
+    pub fn fields_with_source_map(
+        self,
+        db: &dyn DefDatabase,
+    ) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
+        VariantFields::query(db, self)
     }
 
     pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
index 377a545ebf4..1958eb6c6a1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/signatures.rs
@@ -1,6 +1,6 @@
 //! Item signature IR definitions
 
-use std::ops::Not as _;
+use std::{cell::LazyCell, ops::Not as _};
 
 use bitflags::bitflags;
 use cfg::{CfgExpr, CfgOptions};
@@ -731,29 +731,26 @@ pub struct VariantFields {
     pub store: Arc<ExpressionStore>,
     pub shape: FieldsShape,
 }
+
+#[salsa::tracked]
 impl VariantFields {
-    #[inline]
+    #[salsa::tracked(returns(clone))]
     pub(crate) fn query(
         db: &dyn DefDatabase,
         id: VariantId,
     ) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
-        let (shape, (fields, store, source_map)) = match id {
+        let (shape, result) = match id {
             VariantId::EnumVariantId(id) => {
                 let loc = id.lookup(db);
                 let parent = loc.parent.lookup(db);
                 let source = loc.source(db);
                 let shape = adt_shape(source.value.kind());
-                let span_map = db.span_map(source.file_id);
-                let override_visibility = visibility_from_ast(
-                    db,
-                    source.value.parent_enum().visibility(),
-                    &mut |range| span_map.span_for_range(range).ctx,
-                );
+                let enum_vis = Some(source.value.parent_enum().visibility());
                 let fields = lower_field_list(
                     db,
                     parent.container,
                     source.map(|src| src.field_list()),
-                    Some(override_visibility),
+                    enum_vis,
                 );
                 (shape, fields)
             }
@@ -777,10 +774,29 @@ impl VariantFields {
                 (FieldsShape::Record, fields)
             }
         };
+        match result {
+            Some((fields, store, source_map)) => (
+                Arc::new(VariantFields { fields, store: Arc::new(store), shape }),
+                Arc::new(source_map),
+            ),
+            None => (
+                Arc::new(VariantFields {
+                    fields: Arena::default(),
+                    store: ExpressionStore::empty_singleton(),
+                    shape,
+                }),
+                ExpressionStoreSourceMap::empty_singleton(),
+            ),
+        }
+    }
 
-        (Arc::new(VariantFields { fields, store: Arc::new(store), shape }), Arc::new(source_map))
+    #[salsa::tracked(returns(deref))]
+    pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> {
+        Self::query(db, id).0
     }
+}
 
+impl VariantFields {
     pub fn len(&self) -> usize {
         self.fields.len()
     }
@@ -798,31 +814,24 @@ fn lower_field_list(
     db: &dyn DefDatabase,
     module: ModuleId,
     fields: InFile<Option<ast::FieldList>>,
-    override_visibility: Option<RawVisibility>,
-) -> (Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap) {
+    override_visibility: Option<Option<ast::Visibility>>,
+) -> Option<(Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap)> {
     let file_id = fields.file_id;
-    match fields.value {
-        Some(ast::FieldList::RecordFieldList(fields)) => lower_fields(
+    match fields.value? {
+        ast::FieldList::RecordFieldList(fields) => lower_fields(
             db,
             module,
             InFile::new(file_id, fields.fields().map(|field| (field.ty(), field))),
             |_, field| as_name_opt(field.name()),
             override_visibility,
         ),
-        Some(ast::FieldList::TupleFieldList(fields)) => lower_fields(
+        ast::FieldList::TupleFieldList(fields) => lower_fields(
             db,
             module,
             InFile::new(file_id, fields.fields().map(|field| (field.ty(), field))),
             |idx, _| Name::new_tuple_field(idx),
             override_visibility,
         ),
-        None => lower_fields(
-            db,
-            module,
-            InFile::new(file_id, std::iter::empty::<(Option<ast::Type>, ast::RecordField)>()),
-            |_, _| Name::missing(),
-            None,
-        ),
     }
 }
 
@@ -831,22 +840,34 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
     module: ModuleId,
     fields: InFile<impl Iterator<Item = (Option<ast::Type>, Field)>>,
     mut field_name: impl FnMut(usize, &Field) -> Name,
-    override_visibility: Option<RawVisibility>,
-) -> (Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap) {
-    let mut arena = Arena::new();
+    override_visibility: Option<Option<ast::Visibility>>,
+) -> Option<(Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap)> {
     let cfg_options = module.krate.cfg_options(db);
     let mut col = ExprCollector::new(db, module, fields.file_id);
+    let override_visibility = override_visibility.map(|vis| {
+        LazyCell::new(|| {
+            let span_map = db.span_map(fields.file_id);
+            visibility_from_ast(db, vis, &mut |range| span_map.span_for_range(range).ctx)
+        })
+    });
+
+    let mut arena = Arena::new();
     let mut idx = 0;
+    let mut has_fields = false;
     for (ty, field) in fields.value {
+        has_fields = true;
         match Attrs::is_cfg_enabled_for(db, &field, col.span_map(), cfg_options) {
             Ok(()) => {
                 let type_ref =
                     col.lower_type_ref_opt(ty, &mut ExprCollector::impl_trait_error_allocator);
-                let visibility = override_visibility.clone().unwrap_or_else(|| {
-                    visibility_from_ast(db, field.visibility(), &mut |range| {
-                        col.span_map().span_for_range(range).ctx
-                    })
-                });
+                let visibility = override_visibility.as_ref().map_or_else(
+                    || {
+                        visibility_from_ast(db, field.visibility(), &mut |range| {
+                            col.span_map().span_for_range(range).ctx
+                        })
+                    },
+                    |it| RawVisibility::clone(it),
+                );
                 let is_unsafe = field
                     .syntax()
                     .children_with_tokens()
@@ -867,9 +888,12 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
             }
         }
     }
+    if !has_fields {
+        return None;
+    }
     let store = col.store.finish();
     arena.shrink_to_fit();
-    (arena, store, col.source_map)
+    Some((arena, store, col.source_map))
 }
 
 #[derive(Debug, PartialEq, Eq)]
@@ -948,7 +972,7 @@ impl EnumVariants {
         self.variants.iter().all(|&(v, _, _)| {
             // The condition check order is slightly modified from rustc
             // to improve performance by early returning with relatively fast checks
-            let variant = &db.variant_fields(v.into());
+            let variant = v.fields(db);
             if !variant.fields().is_empty() {
                 return false;
             }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
index 2514e88864f..b5eb84c25f2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs
@@ -273,7 +273,7 @@ pub(crate) fn field_visibilities_query(
     db: &dyn DefDatabase,
     variant_id: VariantId,
 ) -> Arc<ArenaMap<LocalFieldId, Visibility>> {
-    let variant_fields = db.variant_fields(variant_id);
+    let variant_fields = variant_id.fields(db);
     let fields = variant_fields.fields();
     if fields.is_empty() {
         return Arc::default();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
index 04a4635da41..26b635298a6 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
@@ -801,7 +801,7 @@ pub(crate) fn adt_datum_query(
 
     // this slows down rust-analyzer by quite a bit unfortunately, so enabling this is currently not worth it
     let _variant_id_to_fields = |id: VariantId| {
-        let variant_data = &id.variant_data(db);
+        let variant_data = &id.fields(db);
         let fields = if variant_data.fields().is_empty() {
             vec![]
         } else {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
index 1873f12fb7c..9c0f8f40080 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -307,7 +307,7 @@ impl<'a> DeclValidator<'a> {
 
     /// Check incorrect names for struct fields.
     fn validate_struct_fields(&mut self, struct_id: StructId) {
-        let data = self.db.variant_fields(struct_id.into());
+        let data = struct_id.fields(self.db);
         if data.shape != FieldsShape::Record {
             return;
         };
@@ -468,7 +468,7 @@ impl<'a> DeclValidator<'a> {
 
     /// Check incorrect names for fields of enum variant.
     fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) {
-        let variant_data = self.db.variant_fields(variant_id.into());
+        let variant_data = variant_id.fields(self.db);
         if variant_data.shape != FieldsShape::Record {
             return;
         };
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
index 6e95daca051..5d56957be6d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/expr.rs
@@ -558,7 +558,7 @@ pub fn record_literal_missing_fields(
         return None;
     }
 
-    let variant_data = variant_def.variant_data(db);
+    let variant_data = variant_def.fields(db);
 
     let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
     let missed_fields: Vec<LocalFieldId> = variant_data
@@ -588,7 +588,7 @@ pub fn record_pattern_missing_fields(
         return None;
     }
 
-    let variant_data = variant_def.variant_data(db);
+    let variant_data = variant_def.fields(db);
 
     let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
     let missed_fields: Vec<LocalFieldId> = variant_data
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
index 916876d4ac9..0bce32a6778 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check.rs
@@ -169,13 +169,13 @@ impl<'a> PatCtxt<'a> {
             }
 
             hir_def::hir::Pat::TupleStruct { ref args, ellipsis, .. } if variant.is_some() => {
-                let expected_len = variant.unwrap().variant_data(self.db).fields().len();
+                let expected_len = variant.unwrap().fields(self.db).fields().len();
                 let subpatterns = self.lower_tuple_subpats(args, expected_len, ellipsis);
                 self.lower_variant_or_leaf(pat, ty, subpatterns)
             }
 
             hir_def::hir::Pat::Record { ref args, .. } if variant.is_some() => {
-                let variant_data = variant.unwrap().variant_data(self.db);
+                let variant_data = variant.unwrap().fields(self.db);
                 let subpatterns = args
                     .iter()
                     .map(|field| {
@@ -345,7 +345,7 @@ impl HirDisplay for Pat {
                         )?,
                     };
 
-                    let variant_data = variant.variant_data(f.db);
+                    let variant_data = variant.fields(f.db);
                     if variant_data.shape == FieldsShape::Record {
                         write!(f, " {{ ")?;
 
@@ -377,7 +377,7 @@ impl HirDisplay for Pat {
                 }
 
                 let num_fields =
-                    variant.map_or(subpatterns.len(), |v| v.variant_data(f.db).fields().len());
+                    variant.map_or(subpatterns.len(), |v| v.fields(f.db).fields().len());
                 if num_fields != 0 || variant.is_none() {
                     write!(f, "(")?;
                     let subpats = (0..num_fields).map(|i| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 2873a3e09e7..b79c8c2ab19 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -146,7 +146,7 @@ impl<'db> MatchCheckCtx<'db> {
         let (_, substs) = ty.as_adt().unwrap();
 
         let field_tys = self.db.field_types(variant);
-        let fields_len = variant.variant_data(self.db).fields().len() as u32;
+        let fields_len = variant.fields(self.db).fields().len() as u32;
 
         (0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| {
             let ty = field_tys[fid].clone().substitute(Interner, substs);
@@ -229,7 +229,7 @@ impl<'db> MatchCheckCtx<'db> {
                             }
                         };
                         let variant = Self::variant_id_for_adt(self.db, &ctor, adt).unwrap();
-                        arity = variant.variant_data(self.db).fields().len();
+                        arity = variant.fields(self.db).fields().len();
                     }
                     _ => {
                         never!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, &pat.ty);
@@ -349,7 +349,7 @@ impl PatCx for MatchCheckCtx<'_> {
                         1
                     } else {
                         let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap();
-                        variant.variant_data(self.db).fields().len()
+                        variant.fields(self.db).fields().len()
                     }
                 }
                 _ => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index 41f495b238a..507bab29208 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -888,7 +888,7 @@ fn render_const_scalar(
                     write!(f, "{}", data.name.display(f.db, f.edition()))?;
                     let field_types = f.db.field_types(s.into());
                     render_variant_after_name(
-                        &f.db.variant_fields(s.into()),
+                        s.fields(f.db),
                         f,
                         &field_types,
                         f.db.trait_environment(adt.0.into()),
@@ -920,7 +920,7 @@ fn render_const_scalar(
                     )?;
                     let field_types = f.db.field_types(var_id.into());
                     render_variant_after_name(
-                        &f.db.variant_fields(var_id.into()),
+                        var_id.fields(f.db),
                         f,
                         &field_types,
                         f.db.trait_environment(adt.0.into()),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
index 8d345defdc1..4e95eca3f94 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/cast.rs
@@ -382,7 +382,7 @@ fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<Pointe
                 return Err(());
             };
 
-            let struct_data = table.db.variant_fields(id.into());
+            let struct_data = id.fields(table.db);
             if let Some((last_field, _)) = struct_data.fields().iter().last() {
                 let last_field_ty =
                     table.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
index 0b54df7e0a7..65a273cdf8d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs
@@ -677,7 +677,7 @@ impl CapturedItem {
             match proj {
                 ProjectionElem::Deref => {}
                 ProjectionElem::Field(Either::Left(f)) => {
-                    let variant_data = f.parent.variant_data(db);
+                    let variant_data = f.parent.fields(db);
                     match variant_data.shape {
                         FieldsShape::Record => {
                             result.push('_');
@@ -720,7 +720,7 @@ impl CapturedItem {
                 // In source code autoderef kicks in.
                 ProjectionElem::Deref => {}
                 ProjectionElem::Field(Either::Left(f)) => {
-                    let variant_data = f.parent.variant_data(db);
+                    let variant_data = f.parent.fields(db);
                     match variant_data.shape {
                         FieldsShape::Record => format_to!(
                             result,
@@ -782,7 +782,7 @@ impl CapturedItem {
                     if field_need_paren {
                         result = format!("({result})");
                     }
-                    let variant_data = f.parent.variant_data(db);
+                    let variant_data = f.parent.fields(db);
                     let field = match variant_data.shape {
                         FieldsShape::Record => {
                             variant_data.fields()[f.local_id].name.as_str().to_owned()
@@ -1559,7 +1559,7 @@ impl InferenceContext<'_> {
                             self.consume_place(place)
                         }
                         VariantId::StructId(s) => {
-                            let vd = &*self.db.variant_fields(s.into());
+                            let vd = s.fields(self.db);
                             for field_pat in args.iter() {
                                 let arg = field_pat.pat;
                                 let Some(local_id) = vd.field(&field_pat.name) else {
@@ -1611,7 +1611,7 @@ impl InferenceContext<'_> {
                             self.consume_place(place)
                         }
                         VariantId::StructId(s) => {
-                            let vd = &*self.db.variant_fields(s.into());
+                            let vd = s.fields(self.db);
                             let (al, ar) =
                                 args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
                             let fields = vd.fields().iter();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index a8392bb14c1..d40d52c134d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -542,7 +542,7 @@ impl InferenceContext<'_> {
                     _ if fields.is_empty() => {}
                     Some(def) => {
                         let field_types = self.db.field_types(def);
-                        let variant_data = def.variant_data(self.db);
+                        let variant_data = def.fields(self.db);
                         let visibilities = self.db.field_visibilities(def);
                         for field in fields.iter() {
                             let field_def = {
@@ -1566,12 +1566,12 @@ impl InferenceContext<'_> {
                     });
                 }
                 &TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref parameters) => {
-                    let local_id = self.db.variant_fields(s.into()).field(name)?;
+                    let local_id = s.fields(self.db).field(name)?;
                     let field = FieldId { parent: s.into(), local_id };
                     (field, parameters.clone())
                 }
                 &TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), ref parameters) => {
-                    let local_id = self.db.variant_fields(u.into()).field(name)?;
+                    let local_id = u.fields(self.db).field(name)?;
                     let field = FieldId { parent: u.into(), local_id };
                     (field, parameters.clone())
                 }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
index 4bc3e167ebf..99d3b5c7a84 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs
@@ -38,7 +38,7 @@ impl InferenceContext<'_> {
         decl: Option<DeclContext>,
     ) -> Ty {
         let (ty, def) = self.resolve_variant(id.into(), path, true);
-        let var_data = def.map(|it| it.variant_data(self.db));
+        let var_data = def.map(|it| it.fields(self.db));
         if let Some(variant) = def {
             self.write_variant_resolution(id.into(), variant);
         }
@@ -60,7 +60,7 @@ impl InferenceContext<'_> {
             _ if subs.is_empty() => {}
             Some(def) => {
                 let field_types = self.db.field_types(def);
-                let variant_data = def.variant_data(self.db);
+                let variant_data = def.fields(self.db);
                 let visibilities = self.db.field_visibilities(def);
 
                 let (pre, post) = match ellipsis {
@@ -129,7 +129,7 @@ impl InferenceContext<'_> {
             _ if subs.len() == 0 => {}
             Some(def) => {
                 let field_types = self.db.field_types(def);
-                let variant_data = def.variant_data(self.db);
+                let variant_data = def.fields(self.db);
                 let visibilities = self.db.field_visibilities(def);
 
                 let substs = ty.as_adt().map(TupleExt::tail);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index ce8a790ef64..c07755535f2 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -1001,7 +1001,7 @@ impl<'a> InferenceTable<'a> {
             // Must use a loop here and not recursion because otherwise users will conduct completely
             // artificial examples of structs that have themselves as the tail field and complain r-a crashes.
             while let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
-                let struct_data = self.db.variant_fields(id.into());
+                let struct_data = id.fields(self.db);
                 if let Some((last_field, _)) = struct_data.fields().iter().next_back() {
                     let last_field_ty = self.db.field_types(id.into())[last_field]
                         .clone()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
index 79a99321f10..b16b6a11784 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs
@@ -132,7 +132,7 @@ impl UninhabitedFrom<'_> {
         variant: VariantId,
         subst: &Substitution,
     ) -> ControlFlow<VisiblyUninhabited> {
-        let variant_data = self.db.variant_fields(variant);
+        let variant_data = variant.fields(self.db);
         let fields = variant_data.fields();
         if fields.is_empty() {
             return CONTINUE_OPAQUELY_INHABITED;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index c58bd1b773e..3fa2bfbd1b7 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -375,7 +375,7 @@ pub(crate) fn layout_of_ty_cycle_result(
 fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
     match pointee.kind(Interner) {
         &TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), ref subst) => {
-            let data = db.variant_fields(i.into());
+            let data = i.fields(db);
             let mut it = data.fields().iter().rev();
             match it.next() {
                 Some((f, _)) => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index dff986fec3c..236f316366d 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -42,7 +42,7 @@ pub fn layout_of_adt_query(
         AdtId::StructId(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.push(handle_variant(s.into(), s.fields(db))?);
             (
                 r,
                 sig.repr.unwrap_or_default(),
@@ -52,7 +52,7 @@ pub fn layout_of_adt_query(
         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.push(handle_variant(id.into(), id.fields(db))?);
             (r, data.repr.unwrap_or_default(), false)
         }
         AdtId::EnumId(e) => {
@@ -60,7 +60,7 @@ pub fn layout_of_adt_query(
             let r = variants
                 .variants
                 .iter()
-                .map(|&(v, _, _)| handle_variant(v.into(), &db.variant_fields(v.into())))
+                .map(|&(v, _, _)| handle_variant(v.into(), v.fields(db)))
                 .collect::<Result<SmallVec<_>, _>>()?;
             (r, db.enum_signature(e).repr.unwrap_or_default(), false)
         }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index 3c733302240..f32b6af4d85 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -581,11 +581,28 @@ impl<'a> TyLoweringContext<'a> {
         match bound {
             &TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
                 // FIXME Don't silently drop the hrtb lifetimes here
-                if let Some((trait_ref, ctx)) = self.lower_trait_ref_from_path(path, self_ty) {
-                    if !ignore_bindings {
-                        assoc_bounds = ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
+                if let Some((trait_ref, mut ctx)) =
+                    self.lower_trait_ref_from_path(path, self_ty.clone())
+                {
+                    // FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
+                    // sized-hierarchy correctly.
+                    let meta_sized = LangItem::MetaSized
+                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
+                    let pointee_sized = LangItem::PointeeSized
+                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
+                    if meta_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
+                        // Ignore this bound
+                    } else if pointee_sized.is_some_and(|it| it == trait_ref.hir_trait_id()) {
+                        // Regard this as `?Sized` bound
+                        ctx.ty_ctx().unsized_types.insert(self_ty);
+                    } else {
+                        if !ignore_bindings {
+                            assoc_bounds =
+                                ctx.assoc_type_bindings_from_type_bound(trait_ref.clone());
+                        }
+                        clause =
+                            Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
                     }
-                    clause = Some(crate::wrap_empty_binders(WhereClause::Implemented(trait_ref)));
                 }
             }
             &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
@@ -883,7 +900,7 @@ pub(crate) fn field_types_with_diagnostics_query(
     db: &dyn HirDatabase,
     variant_id: VariantId,
 ) -> (Arc<ArenaMap<LocalFieldId, Binders<Ty>>>, Diagnostics) {
-    let var_data = db.variant_fields(variant_id);
+    let var_data = variant_id.fields(db);
     let fields = var_data.fields();
     if fields.is_empty() {
         return (Arc::new(ArenaMap::default()), None);
@@ -945,8 +962,32 @@ pub(crate) fn generic_predicates_for_param_query(
         | WherePredicate::TypeBound { target, bound, .. } => {
             let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
             if invalid_target {
-                // If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types`
-                if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound {
+                // FIXME(sized-hierarchy): Revisit and adjust this properly once we have implemented
+                // sized-hierarchy correctly.
+                // If this is filtered out without lowering, `?Sized` or `PointeeSized` is not gathered into
+                // `ctx.unsized_types`
+                let lower = || -> bool {
+                    match bound {
+                        TypeBound::Path(_, TraitBoundModifier::Maybe) => true,
+                        TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
+                            let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
+                                return false;
+                            };
+                            let Some(pointee_sized) =
+                                LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
+                            else {
+                                return false;
+                            };
+                            // Lower the path directly with `Resolver` instead of PathLoweringContext`
+                            // to prevent diagnostics duplications.
+                            ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path).is_some_and(
+                                |it| matches!(it, TypeNs::TraitId(tr) if tr == pointee_sized),
+                            )
+                        }
+                        _ => false,
+                    }
+                }();
+                if lower {
                     ctx.lower_where_predicate(pred, true).for_each(drop);
                 }
                 return false;
@@ -1435,7 +1476,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
 
 /// Build the type of a tuple struct constructor.
 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
-    let struct_data = db.variant_fields(def.into());
+    let struct_data = def.fields(db);
     match struct_data.shape {
         FieldsShape::Record => None,
         FieldsShape::Unit => Some(type_for_adt(db, def.into())),
@@ -1468,7 +1509,7 @@ fn type_for_enum_variant_constructor(
     def: EnumVariantId,
 ) -> Option<Binders<Ty>> {
     let e = def.lookup(db).parent;
-    match db.variant_fields(def.into()).shape {
+    match def.fields(db).shape {
         FieldsShape::Record => None,
         FieldsShape::Unit => Some(type_for_adt(db, e.into())),
         FieldsShape::Tuple => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
index 3b75d4cf122..9c2a9eb5c51 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval.rs
@@ -1749,8 +1749,7 @@ impl Evaluator<'_> {
                         AdtId::UnionId(_) => not_supported!("unsizing unions"),
                         AdtId::EnumId(_) => not_supported!("unsizing enums"),
                     };
-                    let Some((last_field, _)) =
-                        self.db.variant_fields(id.into()).fields().iter().next_back()
+                    let Some((last_field, _)) = id.fields(self.db).fields().iter().next_back()
                     else {
                         not_supported!("unsizing struct without field");
                     };
@@ -2232,7 +2231,7 @@ impl Evaluator<'_> {
                 }
                 chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
                     AdtId::StructId(s) => {
-                        let data = this.db.variant_fields(s.into());
+                        let data = s.fields(this.db);
                         let layout = this.layout(ty)?;
                         let field_types = this.db.field_types(s.into());
                         for (f, _) in data.fields().iter() {
@@ -2261,7 +2260,7 @@ impl Evaluator<'_> {
                             bytes,
                             e,
                         ) {
-                            let data = &this.db.variant_fields(v.into());
+                            let data = v.fields(this.db);
                             let field_types = this.db.field_types(v.into());
                             for (f, _) in data.fields().iter() {
                                 let offset =
@@ -2838,7 +2837,7 @@ impl Evaluator<'_> {
                             return Ok(());
                         }
                         let layout = self.layout_adt(id.0, subst.clone())?;
-                        let variant_fields = self.db.variant_fields(s.into());
+                        let variant_fields = s.fields(self.db);
                         match variant_fields.shape {
                             FieldsShape::Record | FieldsShape::Tuple => {
                                 let field_types = self.db.field_types(s.into());
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
index 984648cfec3..bc331a23d98 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim/simd.rs
@@ -31,7 +31,7 @@ impl Evaluator<'_> {
                     Some(len) => len,
                     _ => {
                         if let AdtId::StructId(id) = id.0 {
-                            let struct_data = self.db.variant_fields(id.into());
+                            let struct_data = id.fields(self.db);
                             let fields = struct_data.fields();
                             let Some((first_field, _)) = fields.iter().next() else {
                                 not_supported!("simd type with no field");
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
index 71e038b92f0..845d6b8eae1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs
@@ -503,7 +503,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                         Ok(Some(current))
                     }
                     ValueNs::EnumVariantId(variant_id) => {
-                        let variant_fields = &self.db.variant_fields(variant_id.into());
+                        let variant_fields = variant_id.fields(self.db);
                         if variant_fields.shape == FieldsShape::Unit {
                             let ty = self.infer.type_of_expr[expr_id].clone();
                             current = self.lower_enum_variant(
@@ -856,7 +856,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     TyKind::Adt(_, s) => s.clone(),
                     _ => not_supported!("Non ADT record literal"),
                 };
-                let variant_fields = self.db.variant_fields(variant_id);
+                let variant_fields = variant_id.fields(self.db);
                 match variant_id {
                     VariantId::EnumVariantId(_) | VariantId::StructId(_) => {
                         let mut operands = vec![None; variant_fields.fields().len()];
@@ -1176,8 +1176,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     place,
                     Rvalue::Aggregate(
                         AggregateKind::Adt(st.into(), subst.clone()),
-                        self.db
-                            .variant_fields(st.into())
+                        st.fields(self.db)
                             .fields()
                             .iter()
                             .map(|it| {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
index b3c1f6f387f..61c0685c48a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -609,7 +609,7 @@ impl MirLowerCtx<'_> {
                 }
                 self.pattern_matching_variant_fields(
                     shape,
-                    &self.db.variant_fields(v.into()),
+                    v.fields(self.db),
                     variant,
                     current,
                     current_else,
@@ -619,7 +619,7 @@ impl MirLowerCtx<'_> {
             }
             VariantId::StructId(s) => self.pattern_matching_variant_fields(
                 shape,
-                &self.db.variant_fields(s.into()),
+                s.fields(self.db),
                 variant,
                 current,
                 current_else,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
index 8764e48b538..78a69cf4509 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/pretty.rs
@@ -326,7 +326,7 @@ impl<'a> MirPrettyCtx<'a> {
                     w!(this, ")");
                 }
                 ProjectionElem::Field(Either::Left(field)) => {
-                    let variant_fields = this.db.variant_fields(field.parent);
+                    let variant_fields = field.parent.fields(this.db);
                     let name = &variant_fields.fields()[field.local_id].name;
                     match field.parent {
                         hir_def::VariantId::EnumVariantId(e) => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
index 903b1fb6abe..0377ce95f19 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs
@@ -596,8 +596,8 @@ fn main() {
                 "struct_signature_with_source_map_shim",
                 "generic_predicates_shim",
                 "value_ty_shim",
-                "variant_fields_shim",
-                "variant_fields_with_source_map_shim",
+                "firewall_",
+                "query_",
                 "lang_item",
                 "inherent_impls_in_crate_shim",
                 "impl_signature_shim",
@@ -697,7 +697,7 @@ fn main() {
                 "function_signature_with_source_map_shim",
                 "expr_scopes_shim",
                 "struct_signature_with_source_map_shim",
-                "variant_fields_with_source_map_shim",
+                "query_",
                 "inherent_impls_in_crate_shim",
                 "impl_signature_with_source_map_shim",
                 "impl_signature_shim",
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index 074bde91fb6..aba2e032b32 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -490,7 +490,7 @@ impl<'db> AnyDiagnostic<'db> {
     ) -> Option<AnyDiagnostic<'db>> {
         match diagnostic {
             BodyValidationDiagnostic::RecordMissingFields { record, variant, missed_fields } => {
-                let variant_data = variant.variant_data(db);
+                let variant_data = variant.fields(db);
                 let missed_fields = missed_fields
                     .into_iter()
                     .map(|idx| variant_data.fields()[idx].name.clone())
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 18bab7cbf99..2960ebedf38 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -404,7 +404,7 @@ impl HirDisplay for TupleField {
 impl HirDisplay for Variant {
     fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
         write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
-        let data = f.db.variant_fields(self.id.into());
+        let data = self.id.fields(f.db);
         match data.shape {
             FieldsShape::Unit => {}
             FieldsShape::Tuple => {
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 6ba2b313537..e8a18169712 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -668,25 +668,25 @@ impl Module {
                         Adt::Struct(s) => {
                             let source_map = db.struct_signature_with_source_map(s.id).1;
                             expr_store_diagnostics(db, acc, &source_map);
-                            let source_map = db.variant_fields_with_source_map(s.id.into()).1;
-                            expr_store_diagnostics(db, acc, &source_map);
+                            let source_map = &s.id.fields_with_source_map(db).1;
+                            expr_store_diagnostics(db, acc, source_map);
                             push_ty_diagnostics(
                                 db,
                                 acc,
                                 db.field_types_with_diagnostics(s.id.into()).1,
-                                &source_map,
+                                source_map,
                             );
                         }
                         Adt::Union(u) => {
                             let source_map = db.union_signature_with_source_map(u.id).1;
                             expr_store_diagnostics(db, acc, &source_map);
-                            let source_map = db.variant_fields_with_source_map(u.id.into()).1;
-                            expr_store_diagnostics(db, acc, &source_map);
+                            let source_map = &u.id.fields_with_source_map(db).1;
+                            expr_store_diagnostics(db, acc, source_map);
                             push_ty_diagnostics(
                                 db,
                                 acc,
                                 db.field_types_with_diagnostics(u.id.into()).1,
-                                &source_map,
+                                source_map,
                             );
                         }
                         Adt::Enum(e) => {
@@ -711,14 +711,14 @@ impl Module {
                                 }
                             }
                             for &(v, _, _) in &variants.variants {
-                                let source_map = db.variant_fields_with_source_map(v.into()).1;
+                                let source_map = &v.fields_with_source_map(db).1;
                                 push_ty_diagnostics(
                                     db,
                                     acc,
                                     db.field_types_with_diagnostics(v.into()).1,
-                                    &source_map,
+                                    source_map,
                                 );
-                                expr_store_diagnostics(db, acc, &source_map);
+                                expr_store_diagnostics(db, acc, source_map);
                             }
                         }
                     }
@@ -1311,7 +1311,7 @@ impl AstNode for FieldSource {
 
 impl Field {
     pub fn name(&self, db: &dyn HirDatabase) -> Name {
-        db.variant_fields(self.parent.into()).fields()[self.id].name.clone()
+        VariantId::from(self.parent).fields(db).fields()[self.id].name.clone()
     }
 
     pub fn index(&self) -> usize {
@@ -1380,7 +1380,7 @@ impl Field {
 
 impl HasVisibility for Field {
     fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
-        let variant_data = db.variant_fields(self.parent.into());
+        let variant_data = VariantId::from(self.parent).fields(db);
         let visibility = &variant_data.fields()[self.id].visibility;
         let parent_id: hir_def::VariantId = self.parent.into();
         // FIXME: RawVisibility::Public doesn't need to construct a resolver
@@ -1403,7 +1403,8 @@ impl Struct {
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
-        db.variant_fields(self.id.into())
+        self.id
+            .fields(db)
             .fields()
             .iter()
             .map(|(id, _)| Field { parent: self.into(), id })
@@ -1434,8 +1435,8 @@ impl Struct {
         }
     }
 
-    fn variant_fields(self, db: &dyn HirDatabase) -> Arc<VariantFields> {
-        db.variant_fields(self.id.into())
+    fn variant_fields(self, db: &dyn HirDatabase) -> &VariantFields {
+        self.id.fields(db)
     }
 
     pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
@@ -1478,7 +1479,7 @@ impl Union {
     }
 
     pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
-        match db.variant_fields(self.id.into()).shape {
+        match self.id.fields(db).shape {
             hir_def::item_tree::FieldsShape::Record => StructKind::Record,
             hir_def::item_tree::FieldsShape::Tuple => StructKind::Tuple,
             hir_def::item_tree::FieldsShape::Unit => StructKind::Unit,
@@ -1486,7 +1487,8 @@ impl Union {
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
-        db.variant_fields(self.id.into())
+        self.id
+            .fields(db)
             .fields()
             .iter()
             .map(|(id, _)| Field { parent: self.into(), id })
@@ -1626,7 +1628,8 @@ impl Variant {
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
-        db.variant_fields(self.id.into())
+        self.id
+            .fields(db)
             .fields()
             .iter()
             .map(|(id, _)| Field { parent: self.into(), id })
@@ -1634,7 +1637,7 @@ impl Variant {
     }
 
     pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
-        match db.variant_fields(self.id.into()).shape {
+        match self.id.fields(db).shape {
             hir_def::item_tree::FieldsShape::Record => StructKind::Record,
             hir_def::item_tree::FieldsShape::Tuple => StructKind::Tuple,
             hir_def::item_tree::FieldsShape::Unit => StructKind::Unit,
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
index 188d0b9273d..e7db93d375d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs
@@ -191,7 +191,7 @@ impl ChildBySource for VariantId {
                 Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id),
             }
         }
-        let (_, sm) = db.variant_fields_with_source_map(*self);
+        let (_, sm) = self.fields_with_source_map(db);
         sm.expansions().for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id));
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index ae72cc6f5a2..f18ca7cb201 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -156,14 +156,14 @@ impl<'db> SourceAnalyzer<'db> {
         InFile { file_id, .. }: InFile<&SyntaxNode>,
         _offset: Option<TextSize>,
     ) -> SourceAnalyzer<'db> {
-        let (fields, source_map) = db.variant_fields_with_source_map(def);
+        let (fields, source_map) = def.fields_with_source_map(db);
         let resolver = def.resolver(db);
         SourceAnalyzer {
             resolver,
             body_or_sig: Some(BodyOrSig::VariantFields {
                 def,
                 store: fields.store.clone(),
-                source_map,
+                source_map: source_map.clone(),
             }),
             file_id,
         }
@@ -713,7 +713,7 @@ impl<'db> SourceAnalyzer<'db> {
         };
         let (adt, subst) = self.infer()?.type_of_expr_or_pat(expr_id)?.as_adt()?;
         let variant = self.infer()?.variant_resolution_for_expr_or_pat(expr_id)?;
-        let variant_data = variant.variant_data(db);
+        let variant_data = variant.fields(db);
         let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
         let field_ty =
             db.field_types(variant).get(field.local_id)?.clone().substitute(Interner, subst);
@@ -734,7 +734,7 @@ impl<'db> SourceAnalyzer<'db> {
         let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
         let pat_id = self.pat_id(&record_pat.into())?;
         let variant = self.infer()?.variant_resolution_for_pat(pat_id.as_pat()?)?;
-        let variant_data = variant.variant_data(db);
+        let variant_data = variant.fields(db);
         let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
         let (adt, subst) = self.infer()?.type_of_pat.get(pat_id.as_pat()?)?.as_adt()?;
         let field_ty =
@@ -803,8 +803,8 @@ impl<'db> SourceAnalyzer<'db> {
                 };
                 container = Either::Right(db.normalize_projection(projection, trait_env.clone()));
             }
-            let handle_variants = |variant, subst: &Substitution, container: &mut _| {
-                let fields = db.variant_fields(variant);
+            let handle_variants = |variant: VariantId, subst: &Substitution, container: &mut _| {
+                let fields = variant.fields(db);
                 let field = fields.field(&field_name.as_name())?;
                 let field_types = db.field_types(variant);
                 *container = Either::Right(field_types[field].clone().substitute(Interner, subst));
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs
index 3e6d0bec68a..517906b429a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_is_method.rs
@@ -1,3 +1,5 @@
+use std::slice;
+
 use ide_db::assists::GroupLabel;
 use stdx::to_lower_snake_case;
 use syntax::ast::HasVisibility;
@@ -52,7 +54,7 @@ pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext<'_>
     let fn_name = format!("is_{}", &to_lower_snake_case(&variant_name.text()));
 
     // Return early if we've found an existing new fn
-    let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?;
+    let impl_def = find_struct_impl(ctx, &parent_enum, slice::from_ref(&fn_name))?;
 
     let target = variant.syntax().text_range();
     acc.add_group(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
index 3974bcf6187..e4b0f830497 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
@@ -1,3 +1,5 @@
+use std::slice;
+
 use ide_db::assists::GroupLabel;
 use itertools::Itertools;
 use stdx::to_lower_snake_case;
@@ -148,7 +150,7 @@ fn generate_enum_projection_method(
     let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text()));
 
     // Return early if we've found an existing new fn
-    let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?;
+    let impl_def = find_struct_impl(ctx, &parent_enum, slice::from_ref(&fn_name))?;
 
     let target = variant.syntax().text_range();
     acc.add_group(
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
index b9a98f88be7..f0003dae3f3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs
@@ -143,7 +143,7 @@ fn foo<T>() {}
                                             file_id: FileId(
                                                 1,
                                             ),
-                                            range: 135..140,
+                                            range: 446..451,
                                         },
                                     ),
                                 ),
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index adc581309d1..1ccd20c25e9 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -438,6 +438,8 @@ define_symbols! {
     shr,
     simd,
     sized,
+    meta_sized,
+    pointee_sized,
     skip,
     slice_len_fn,
     Some,
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
index a9794347e19..d48063fb86f 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -26,7 +26,7 @@
 //!     deref: sized
 //!     derive:
 //!     discriminant:
-//!     drop:
+//!     drop: sized
 //!     env: option
 //!     eq: sized
 //!     error: fmt
@@ -37,7 +37,7 @@
 //!     future: pin
 //!     coroutine: pin
 //!     dispatch_from_dyn: unsize, pin
-//!     hash:
+//!     hash: sized
 //!     include:
 //!     index: sized
 //!     infallible:
@@ -77,33 +77,46 @@
 
 pub mod marker {
     // region:sized
+    #[lang = "pointee_sized"]
+    #[fundamental]
+    #[rustc_specialization_trait]
+    #[rustc_coinductive]
+    pub trait PointeeSized {}
+
+    #[lang = "meta_sized"]
+    #[fundamental]
+    #[rustc_specialization_trait]
+    #[rustc_coinductive]
+    pub trait MetaSized: PointeeSized {}
+
     #[lang = "sized"]
     #[fundamental]
     #[rustc_specialization_trait]
-    pub trait Sized {}
+    #[rustc_coinductive]
+    pub trait Sized: MetaSized {}
     // endregion:sized
 
     // region:send
     pub unsafe auto trait Send {}
 
-    impl<T: ?Sized> !Send for *const T {}
-    impl<T: ?Sized> !Send for *mut T {}
+    impl<T: PointeeSized> !Send for *const T {}
+    impl<T: PointeeSized> !Send for *mut T {}
     // region:sync
-    unsafe impl<T: Sync + ?Sized> Send for &T {}
-    unsafe impl<T: Send + ?Sized> Send for &mut T {}
+    unsafe impl<T: Sync + PointeeSized> Send for &T {}
+    unsafe impl<T: Send + PointeeSized> Send for &mut T {}
     // endregion:sync
     // endregion:send
 
     // region:sync
     pub unsafe auto trait Sync {}
 
-    impl<T: ?Sized> !Sync for *const T {}
-    impl<T: ?Sized> !Sync for *mut T {}
+    impl<T: PointeeSized> !Sync for *const T {}
+    impl<T: PointeeSized> !Sync for *mut T {}
     // endregion:sync
 
     // region:unsize
     #[lang = "unsize"]
-    pub trait Unsize<T: ?Sized> {}
+    pub trait Unsize<T: PointeeSized>: PointeeSized {}
     // endregion:unsize
 
     // region:unpin
@@ -120,7 +133,7 @@ pub mod marker {
     // endregion:derive
 
     mod copy_impls {
-        use super::Copy;
+        use super::{Copy, PointeeSized};
 
         macro_rules! impl_copy {
             ($($t:ty)*) => {
@@ -137,9 +150,9 @@ pub mod marker {
             bool char
         }
 
-        impl<T: ?Sized> Copy for *const T {}
-        impl<T: ?Sized> Copy for *mut T {}
-        impl<T: ?Sized> Copy for &T {}
+        impl<T: PointeeSized> Copy for *const T {}
+        impl<T: PointeeSized> Copy for *mut T {}
+        impl<T: PointeeSized> Copy for &T {}
         impl Copy for ! {}
     }
     // endregion:copy
@@ -151,7 +164,7 @@ pub mod marker {
 
     // region:phantom_data
     #[lang = "phantom_data"]
-    pub struct PhantomData<T: ?Sized>;
+    pub struct PhantomData<T: PointeeSized>;
     // endregion:phantom_data
 
     // region:discriminant
@@ -206,9 +219,11 @@ pub mod default {
 
 // region:hash
 pub mod hash {
+    use crate::marker::PointeeSized;
+
     pub trait Hasher {}
 
-    pub trait Hash {
+    pub trait Hash: PointeeSized {
         fn hash<H: Hasher>(&self, state: &mut H);
     }
 
@@ -221,10 +236,11 @@ pub mod hash {
 
 // region:cell
 pub mod cell {
+    use crate::marker::PointeeSized;
     use crate::mem;
 
     #[lang = "unsafe_cell"]
-    pub struct UnsafeCell<T: ?Sized> {
+    pub struct UnsafeCell<T: PointeeSized> {
         value: T,
     }
 
@@ -238,7 +254,7 @@ pub mod cell {
         }
     }
 
-    pub struct Cell<T: ?Sized> {
+    pub struct Cell<T: PointeeSized> {
         value: UnsafeCell<T>,
     }
 
@@ -357,7 +373,7 @@ pub mod convert {
     // endregion:from
 
     // region:as_ref
-    pub trait AsRef<T: ?Sized> {
+    pub trait AsRef<T: crate::marker::PointeeSized>: crate::marker::PointeeSized {
         fn as_ref(&self) -> &T;
     }
     // endregion:as_ref
@@ -368,9 +384,11 @@ pub mod convert {
 
 pub mod mem {
     // region:manually_drop
+    use crate::marker::PointeeSized;
+
     #[lang = "manually_drop"]
     #[repr(transparent)]
-    pub struct ManuallyDrop<T: ?Sized> {
+    pub struct ManuallyDrop<T: PointeeSized> {
         value: T,
     }
 
@@ -381,7 +399,7 @@ pub mod mem {
     }
 
     // region:deref
-    impl<T: ?Sized> crate::ops::Deref for ManuallyDrop<T> {
+    impl<T: PointeeSized> crate::ops::Deref for ManuallyDrop<T> {
         type Target = T;
         fn deref(&self) -> &T {
             &self.value
@@ -428,7 +446,7 @@ pub mod mem {
 pub mod ptr {
     // region:drop
     #[lang = "drop_in_place"]
-    pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    pub unsafe fn drop_in_place<T: crate::marker::PointeeSized>(to_drop: *mut T) {
         unsafe { drop_in_place(to_drop) }
     }
     pub const unsafe fn read<T>(src: *const T) -> T {
@@ -444,7 +462,7 @@ pub mod ptr {
     // region:pointee
     #[lang = "pointee_trait"]
     #[rustc_deny_explicit_impl(implement_via_object = false)]
-    pub trait Pointee {
+    pub trait Pointee: crate::marker::PointeeSized {
         #[lang = "metadata_type"]
         type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
     }
@@ -452,12 +470,14 @@ pub mod ptr {
     // region:non_null
     #[rustc_layout_scalar_valid_range_start(1)]
     #[rustc_nonnull_optimization_guaranteed]
-    pub struct NonNull<T: ?Sized> {
+    pub struct NonNull<T: crate::marker::PointeeSized> {
         pointer: *const T,
     }
     // region:coerce_unsized
-    impl<T: ?Sized, U: ?Sized> crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T> where
-        T: crate::marker::Unsize<U>
+    impl<T: crate::marker::PointeeSized, U: crate::marker::PointeeSized>
+        crate::ops::CoerceUnsized<NonNull<U>> for NonNull<T>
+    where
+        T: crate::marker::Unsize<U>,
     {
     }
     // endregion:coerce_unsized
@@ -478,42 +498,44 @@ pub mod ptr {
 pub mod ops {
     // region:coerce_unsized
     mod unsize {
-        use crate::marker::Unsize;
+        use crate::marker::{PointeeSized, Unsize};
 
         #[lang = "coerce_unsized"]
-        pub trait CoerceUnsized<T: ?Sized> {}
+        pub trait CoerceUnsized<T> {}
 
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
-        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {}
+        impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {}
 
-        impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
+        impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
 
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
+        impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
+        impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
+        impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {}
     }
     pub use self::unsize::CoerceUnsized;
     // endregion:coerce_unsized
 
     // region:deref
     mod deref {
+        use crate::marker::PointeeSized;
+
         #[lang = "deref"]
-        pub trait Deref {
+        pub trait Deref: PointeeSized {
             #[lang = "deref_target"]
             type Target: ?Sized;
             fn deref(&self) -> &Self::Target;
         }
 
-        impl<T: ?Sized> Deref for &T {
+        impl<T: PointeeSized> Deref for &T {
             type Target = T;
             fn deref(&self) -> &T {
                 loop {}
             }
         }
-        impl<T: ?Sized> Deref for &mut T {
+        impl<T: PointeeSized> Deref for &mut T {
             type Target = T;
             fn deref(&self) -> &T {
                 loop {}
@@ -521,19 +543,19 @@ pub mod ops {
         }
         // region:deref_mut
         #[lang = "deref_mut"]
-        pub trait DerefMut: Deref {
+        pub trait DerefMut: Deref + PointeeSized {
             fn deref_mut(&mut self) -> &mut Self::Target;
         }
         // endregion:deref_mut
 
         // region:receiver
         #[lang = "receiver"]
-        pub trait Receiver {
+        pub trait Receiver: PointeeSized {
             #[lang = "receiver_target"]
             type Target: ?Sized;
         }
 
-        impl<P: ?Sized, T: ?Sized> Receiver for P
+        impl<P: PointeeSized, T: PointeeSized> Receiver for P
         where
             P: Deref<Target = T>,
         {
@@ -1006,18 +1028,18 @@ pub mod ops {
 
     // region:dispatch_from_dyn
     mod dispatch_from_dyn {
-        use crate::marker::Unsize;
+        use crate::marker::{PointeeSized, Unsize};
 
         #[lang = "dispatch_from_dyn"]
         pub trait DispatchFromDyn<T> {}
 
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {}
 
-        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+        impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {}
 
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+        impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {}
 
-        impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
+        impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {}
     }
     pub use self::dispatch_from_dyn::DispatchFromDyn;
     // endregion:dispatch_from_dyn
@@ -1025,15 +1047,17 @@ pub mod ops {
 
 // region:eq
 pub mod cmp {
+    use crate::marker::PointeeSized;
+
     #[lang = "eq"]
-    pub trait PartialEq<Rhs: ?Sized = Self> {
+    pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
         fn eq(&self, other: &Rhs) -> bool;
         fn ne(&self, other: &Rhs) -> bool {
             !self.eq(other)
         }
     }
 
-    pub trait Eq: PartialEq<Self> {}
+    pub trait Eq: PartialEq<Self> + PointeeSized {}
 
     // region:derive
     #[rustc_builtin_macro]
@@ -1044,11 +1068,11 @@ pub mod cmp {
 
     // region:ord
     #[lang = "partial_ord"]
-    pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+    pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
         fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
     }
 
-    pub trait Ord: Eq + PartialOrd<Self> {
+    pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
         fn cmp(&self, other: &Self) -> Ordering;
     }
 
@@ -1071,6 +1095,8 @@ pub mod cmp {
 
 // region:fmt
 pub mod fmt {
+    use crate::marker::PointeeSized;
+
     pub struct Error;
     pub type Result = crate::result::Result<(), Error>;
     pub struct Formatter<'a>;
@@ -1106,10 +1132,10 @@ pub mod fmt {
         }
     }
 
-    pub trait Debug {
+    pub trait Debug: PointeeSized {
         fn fmt(&self, f: &mut Formatter<'_>) -> Result;
     }
-    pub trait Display {
+    pub trait Display: PointeeSized {
         fn fmt(&self, f: &mut Formatter<'_>) -> Result;
     }
 
@@ -1268,7 +1294,7 @@ pub mod fmt {
         }
     }
 
-    impl<T: Debug + ?Sized> Debug for &T {
+    impl<T: Debug + PointeeSized> Debug for &T {
         fn fmt(&self, f: &mut Formatter<'_>) -> Result {
             (&**self).fmt(f)
         }
@@ -1512,6 +1538,8 @@ pub mod iter {
 
     mod traits {
         mod iterator {
+            use crate::marker::PointeeSized;
+
             #[doc(notable_trait)]
             #[lang = "iterator"]
             pub trait Iterator {
@@ -1543,7 +1571,7 @@ pub mod iter {
                 }
                 // endregion:iterators
             }
-            impl<I: Iterator + ?Sized> Iterator for &mut I {
+            impl<I: Iterator + PointeeSized> Iterator for &mut I {
                 type Item = I::Item;
                 fn next(&mut self) -> Option<I::Item> {
                     (**self).next()