Skip to content

Commit 1275adc

Browse files
committed
Don't leak rustc Layout in hir layer
1 parent 3514f2f commit 1275adc

File tree

2 files changed

+54
-44
lines changed

2 files changed

+54
-44
lines changed

crates/hir/src/lib.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ use hir_ty::{
6262
consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
6363
diagnostics::BodyValidationDiagnostic,
6464
display::HexifiedConst,
65-
layout::{LayoutError, RustcEnumVariantIdx, TagEncoding},
65+
layout::{Layout as TyLayout, LayoutError, RustcEnumVariantIdx, TagEncoding},
6666
method_resolution::{self, TyFingerprint},
6767
mir::{self, interpret_mir},
6868
primitive::UintTy,
@@ -133,11 +133,8 @@ pub use {
133133
},
134134
hir_ty::{
135135
display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite},
136-
// FIXME: This just needs a HIR wrapper
137-
layout::Layout,
138136
mir::MirEvalError,
139-
PointerCast,
140-
Safety,
137+
PointerCast, Safety,
141138
},
142139
};
143140

@@ -964,8 +961,8 @@ impl Field {
964961
Type::new(db, var_id, ty)
965962
}
966963

967-
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
968-
db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into())
964+
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
965+
db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into()).map(Layout)
969966
}
970967

971968
pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
@@ -1138,10 +1135,10 @@ impl Enum {
11381135
self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
11391136
}
11401137

1141-
pub fn layout(self, db: &dyn HirDatabase) -> Result<(Arc<Layout>, usize), LayoutError> {
1138+
pub fn layout(self, db: &dyn HirDatabase) -> Result<(Layout, usize), LayoutError> {
11421139
let layout = Adt::from(self).layout(db)?;
11431140
let tag_size =
1144-
if let layout::Variants::Multiple { tag, tag_encoding, .. } = &layout.variants {
1141+
if let layout::Variants::Multiple { tag, tag_encoding, .. } = &layout.0.variants {
11451142
match tag_encoding {
11461143
TagEncoding::Direct => {
11471144
let target_data_layout = db
@@ -1222,11 +1219,11 @@ impl Variant {
12221219
let parent_enum = self.parent_enum(db);
12231220
let (parent_layout, tag_size) = parent_enum.layout(db)?;
12241221
Ok((
1225-
match &parent_layout.variants {
1222+
match &parent_layout.0.variants {
12261223
layout::Variants::Multiple { variants, .. } => {
1227-
variants[RustcEnumVariantIdx(self.id)].clone()
1224+
Layout(Arc::new(variants[RustcEnumVariantIdx(self.id)].clone()))
12281225
}
1229-
_ => (*parent_layout).clone(),
1226+
_ => parent_layout,
12301227
},
12311228
tag_size,
12321229
))
@@ -1258,11 +1255,11 @@ impl Adt {
12581255
})
12591256
}
12601257

1261-
pub fn layout(self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
1258+
pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
12621259
if db.generic_params(self.into()).iter().count() != 0 {
12631260
return Err(LayoutError::HasPlaceholder);
12641261
}
1265-
db.layout_of_adt(self.into(), Substitution::empty(Interner), self.krate(db).id)
1262+
db.layout_of_adt(self.into(), Substitution::empty(Interner), self.krate(db).id).map(Layout)
12661263
}
12671264

12681265
/// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -4246,8 +4243,8 @@ impl Type {
42464243
.collect()
42474244
}
42484245

4249-
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
4250-
db.layout_of_ty(self.ty.clone(), self.env.krate)
4246+
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
4247+
db.layout_of_ty(self.ty.clone(), self.env.krate).map(Layout)
42514248
}
42524249
}
42534250

@@ -4358,6 +4355,35 @@ fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::Closu
43584355
}
43594356
}
43604357

4358+
#[derive(Clone, Debug, Eq, PartialEq)]
4359+
pub struct Layout(Arc<TyLayout>);
4360+
4361+
impl Layout {
4362+
pub fn size(&self) -> u64 {
4363+
self.0.size.bytes()
4364+
}
4365+
4366+
pub fn align(&self) -> u64 {
4367+
self.0.align.abi.bytes()
4368+
}
4369+
4370+
pub fn niches(&self, db: &dyn HirDatabase, krate: Crate) -> Option<u128> {
4371+
Some(self.0.largest_niche?.available(&*db.target_data_layout(krate.id)?))
4372+
}
4373+
4374+
pub fn field_offset(&self, idx: usize) -> Option<u64> {
4375+
match self.0.fields {
4376+
layout::FieldsShape::Primitive => None,
4377+
layout::FieldsShape::Union(_) => Some(0),
4378+
layout::FieldsShape::Array { stride, count } => {
4379+
let i = u64::try_from(idx).ok()?;
4380+
(i < count).then_some((stride * i).bytes())
4381+
}
4382+
layout::FieldsShape::Arbitrary { ref offsets, .. } => Some(offsets.get(idx)?.bytes()),
4383+
}
4384+
}
4385+
}
4386+
43614387
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
43624388
pub enum BindingMode {
43634389
Move,

crates/ide/src/hover/render.rs

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::fmt::Display;
33

44
use either::Either;
55
use hir::{
6-
db::HirDatabase, Adt, AsAssocItem, AttributeTemplate, CaptureKind, HasAttrs, HasCrate,
7-
HasSource, HirDisplay, Layout, Semantics, TypeInfo,
6+
Adt, AsAssocItem, AttributeTemplate, CaptureKind, HasAttrs, HasCrate, HasSource, HirDisplay,
7+
Layout, Semantics, TypeInfo,
88
};
99
use ide_db::{
1010
base_db::SourceDatabase,
@@ -401,14 +401,14 @@ pub(super) fn definition(
401401
hir::VariantDef::Struct(s) => Adt::from(s)
402402
.layout(db)
403403
.ok()
404-
.map(|layout| format!(", offset = {:#X}", layout.fields.offset(id).bytes())),
404+
.and_then(|layout| Some(format!(", offset = {:#X}", layout.field_offset(id)?))),
405405
_ => None,
406406
};
407407
let niches = niches(db, it, &layout).unwrap_or_default();
408408
Some(format!(
409409
"size = {:#X}, align = {:#X}{}{niches}",
410-
layout.size.bytes(),
411-
layout.align.abi.bytes(),
410+
layout.size(),
411+
layout.align(),
412412
offset.as_deref().unwrap_or_default()
413413
))
414414
}),
@@ -417,11 +417,7 @@ pub(super) fn definition(
417417
Definition::Adt(it) => label_and_layout_info_and_docs(db, it, config, |&it| {
418418
let layout = it.layout(db).ok()?;
419419
let niches = niches(db, it, &layout).unwrap_or_default();
420-
Some(format!(
421-
"size = {:#X}, align = {:#X}{niches}",
422-
layout.size.bytes(),
423-
layout.align.abi.bytes()
424-
))
420+
Some(format!("size = {:#X}, align = {:#X}{niches}", layout.size(), layout.align()))
425421
}),
426422
Definition::Variant(it) => label_value_and_layout_info_and_docs(
427423
db,
@@ -441,13 +437,13 @@ pub(super) fn definition(
441437
},
442438
|&it| {
443439
let (layout, tag_size) = it.layout(db).ok()?;
444-
let size = layout.size.bytes_usize() - tag_size;
440+
let size = layout.size() as usize - tag_size;
445441
if size == 0 {
446442
// There is no value in showing layout info for fieldless variants
447443
return None;
448444
}
449445
let niches = niches(db, it, &layout).unwrap_or_default();
450-
Some(format!("size = {:#X}{niches}", layout.size.bytes()))
446+
Some(format!("size = {:#X}{niches}", layout.size()))
451447
},
452448
),
453449
Definition::Const(it) => label_value_and_docs(db, it, |it| {
@@ -477,11 +473,7 @@ pub(super) fn definition(
477473
Definition::TypeAlias(it) => label_and_layout_info_and_docs(db, it, config, |&it| {
478474
let layout = it.ty(db).layout(db).ok()?;
479475
let niches = niches(db, it, &layout).unwrap_or_default();
480-
Some(format!(
481-
"size = {:#X}, align = {:#X}{niches}",
482-
layout.size.bytes(),
483-
layout.align.abi.bytes(),
484-
))
476+
Some(format!("size = {:#X}, align = {:#X}{niches}", layout.size(), layout.align(),))
485477
}),
486478
Definition::BuiltinType(it) => {
487479
return famous_defs
@@ -518,10 +510,7 @@ pub(super) fn definition(
518510
}
519511

520512
fn niches(db: &RootDatabase, it: impl HasCrate, layout: &Layout) -> Option<String> {
521-
Some(format!(
522-
", niches = {}",
523-
layout.largest_niche?.available(&*db.target_data_layout(it.krate(db).into())?)
524-
))
513+
Some(format!(", niches = {}", layout.niches(db, it.krate(db).into())?))
525514
}
526515

527516
fn type_info(
@@ -571,7 +560,7 @@ fn closure_ty(
571560
let layout = if config.memory_layout {
572561
original
573562
.layout(sema.db)
574-
.map(|x| format!(" // size = {}, align = {}", x.size.bytes(), x.align.abi.bytes()))
563+
.map(|x| format!(" // size = {}, align = {}", x.size(), x.align()))
575564
.unwrap_or_default()
576565
} else {
577566
String::default()
@@ -782,12 +771,7 @@ fn local(db: &RootDatabase, it: hir::Local, config: &HoverConfig) -> Option<Mark
782771
};
783772
if config.memory_layout {
784773
if let Ok(layout) = it.ty(db).layout(db) {
785-
format_to!(
786-
desc,
787-
" // size = {}, align = {}",
788-
layout.size.bytes(),
789-
layout.align.abi.bytes()
790-
);
774+
format_to!(desc, " // size = {}, align = {}", layout.size(), layout.align());
791775
}
792776
}
793777
markup(None, desc, None)

0 commit comments

Comments
 (0)