Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3713c4b

Browse files
committed
Auto merge of rust-lang#14904 - Veykril:hover-hex, r=Veykril
Render size, align and offset hover values in hex Arguably, these values are usually almost always viewed in hex format so I think we should do the same here
2 parents eee6872 + be9cc0b commit 3713c4b

File tree

6 files changed

+165
-110
lines changed

6 files changed

+165
-110
lines changed

crates/hir-ty/src/layout.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Compute the binary representation of a type
22
33
use base_db::CrateId;
4-
use chalk_ir::{AdtId, TyKind};
4+
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
55
use hir_def::{
66
layout::{
77
Abi, FieldsShape, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions, Scalar, Size,
@@ -83,7 +83,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
8383
let dl = &*cx.current_data_layout();
8484
let trait_env = Arc::new(TraitEnvironment::empty(krate));
8585
let ty = normalize(db, trait_env, ty.clone());
86-
Ok(match ty.kind(Interner) {
86+
let layout = match ty.kind(Interner) {
8787
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone(), krate)?,
8888
TyKind::Scalar(s) => match s {
8989
chalk_ir::Scalar::Bool => Layout::scalar(
@@ -104,12 +104,12 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
104104
dl,
105105
Primitive::Int(
106106
match i {
107-
chalk_ir::IntTy::Isize => dl.ptr_sized_integer(),
108-
chalk_ir::IntTy::I8 => Integer::I8,
109-
chalk_ir::IntTy::I16 => Integer::I16,
110-
chalk_ir::IntTy::I32 => Integer::I32,
111-
chalk_ir::IntTy::I64 => Integer::I64,
112-
chalk_ir::IntTy::I128 => Integer::I128,
107+
IntTy::Isize => dl.ptr_sized_integer(),
108+
IntTy::I8 => Integer::I8,
109+
IntTy::I16 => Integer::I16,
110+
IntTy::I32 => Integer::I32,
111+
IntTy::I64 => Integer::I64,
112+
IntTy::I128 => Integer::I128,
113113
},
114114
true,
115115
),
@@ -118,21 +118,21 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
118118
dl,
119119
Primitive::Int(
120120
match i {
121-
chalk_ir::UintTy::Usize => dl.ptr_sized_integer(),
122-
chalk_ir::UintTy::U8 => Integer::I8,
123-
chalk_ir::UintTy::U16 => Integer::I16,
124-
chalk_ir::UintTy::U32 => Integer::I32,
125-
chalk_ir::UintTy::U64 => Integer::I64,
126-
chalk_ir::UintTy::U128 => Integer::I128,
121+
UintTy::Usize => dl.ptr_sized_integer(),
122+
UintTy::U8 => Integer::I8,
123+
UintTy::U16 => Integer::I16,
124+
UintTy::U32 => Integer::I32,
125+
UintTy::U64 => Integer::I64,
126+
UintTy::U128 => Integer::I128,
127127
},
128128
false,
129129
),
130130
),
131131
chalk_ir::Scalar::Float(f) => scalar(
132132
dl,
133133
match f {
134-
chalk_ir::FloatTy::F32 => Primitive::F32,
135-
chalk_ir::FloatTy::F64 => Primitive::F64,
134+
FloatTy::F32 => Primitive::F32,
135+
FloatTy::F64 => Primitive::F64,
136136
},
137137
),
138138
},
@@ -283,7 +283,8 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
283283
| TyKind::Placeholder(_)
284284
| TyKind::BoundVar(_)
285285
| TyKind::InferenceVar(_, _) => return Err(LayoutError::HasPlaceholder),
286-
})
286+
};
287+
Ok(layout)
287288
}
288289

289290
fn layout_of_unit(cx: &LayoutCx<'_>, dl: &TargetDataLayout) -> Result<Layout, LayoutError> {

crates/hir/src/lib.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,25 @@ impl Enum {
11251125
pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
11261126
self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
11271127
}
1128+
1129+
pub fn layout(self, db: &dyn HirDatabase) -> Result<(Layout, usize), LayoutError> {
1130+
let layout = Adt::from(self).layout(db)?;
1131+
let tag_size =
1132+
if let layout::Variants::Multiple { tag, tag_encoding, .. } = &layout.variants {
1133+
match tag_encoding {
1134+
TagEncoding::Direct => {
1135+
let target_data_layout = db
1136+
.target_data_layout(self.module(db).krate().id)
1137+
.ok_or(LayoutError::TargetLayoutNotAvailable)?;
1138+
tag.size(&*target_data_layout).bytes_usize()
1139+
}
1140+
TagEncoding::Niche { .. } => 0,
1141+
}
1142+
} else {
1143+
0
1144+
};
1145+
Ok((layout, tag_size))
1146+
}
11281147
}
11291148

11301149
impl HasVisibility for Enum {
@@ -1185,23 +1204,16 @@ impl Variant {
11851204
/// Return layout of the variant and tag size of the parent enum.
11861205
pub fn layout(&self, db: &dyn HirDatabase) -> Result<(Layout, usize), LayoutError> {
11871206
let parent_enum = self.parent_enum(db);
1188-
let parent_layout = Adt::from(parent_enum).layout(db)?;
1189-
if let layout::Variants::Multiple { variants, tag, tag_encoding, tag_field: _ } =
1190-
parent_layout.variants
1191-
{
1192-
let tag_size = match tag_encoding {
1193-
TagEncoding::Direct => {
1194-
let target_data_layout = db
1195-
.target_data_layout(parent_enum.module(db).krate().id)
1196-
.ok_or(LayoutError::TargetLayoutNotAvailable)?;
1197-
tag.size(&*target_data_layout).bytes_usize()
1207+
let (parent_layout, tag_size) = parent_enum.layout(db)?;
1208+
Ok((
1209+
match parent_layout.variants {
1210+
layout::Variants::Multiple { variants, .. } => {
1211+
variants[RustcEnumVariantIdx(self.id)].clone()
11981212
}
1199-
TagEncoding::Niche { .. } => 0,
1200-
};
1201-
Ok((variants[RustcEnumVariantIdx(self.id)].clone(), tag_size))
1202-
} else {
1203-
Ok((parent_layout, 0))
1204-
}
1213+
_ => parent_layout,
1214+
},
1215+
tag_size,
1216+
))
12051217
}
12061218
}
12071219

crates/ide/src/hover/render.rs

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ pub(super) fn definition(
401401
hir::VariantDef::Struct(s) => Adt::from(s)
402402
.layout(db)
403403
.ok()
404-
.map(|layout| format!(", offset = {}", layout.fields.offset(id).bytes())),
404+
.map(|layout| format!(", offset = {:#X}", layout.fields.offset(id).bytes())),
405405
_ => None,
406406
};
407407
Some(format!(
408-
"size = {}, align = {}{}",
408+
"size = {:#X}, align = {:#X}{}",
409409
layout.size.bytes(),
410410
layout.align.abi.bytes(),
411411
offset.as_deref().unwrap_or_default()
@@ -415,28 +415,38 @@ pub(super) fn definition(
415415
Definition::Function(it) => label_and_docs(db, it),
416416
Definition::Adt(it) => label_and_layout_info_and_docs(db, it, config, |&it| {
417417
let layout = it.layout(db).ok()?;
418-
Some(format!("size = {}, align = {}", layout.size.bytes(), layout.align.abi.bytes()))
418+
Some(format!(
419+
"size = {:#X}, align = {:#X}",
420+
layout.size.bytes(),
421+
layout.align.abi.bytes()
422+
))
419423
}),
420-
Definition::Variant(it) => label_value_and_layout_info_and_docs(db, it, config, |&it| {
421-
let layout = (|| {
424+
Definition::Variant(it) => label_value_and_layout_info_and_docs(
425+
db,
426+
it,
427+
config,
428+
|&it| {
429+
if !it.parent_enum(db).is_data_carrying(db) {
430+
match it.eval(db) {
431+
Ok(x) => {
432+
Some(if x >= 10 { format!("{x} ({x:#X})") } else { format!("{x}") })
433+
}
434+
Err(_) => it.value(db).map(|x| format!("{x:?}")),
435+
}
436+
} else {
437+
None
438+
}
439+
},
440+
|it| {
422441
let (layout, tag_size) = it.layout(db).ok()?;
423442
let size = layout.size.bytes_usize() - tag_size;
424443
if size == 0 {
425444
// There is no value in showing layout info for fieldless variants
426445
return None;
427446
}
428-
Some(format!("size = {}", layout.size.bytes()))
429-
})();
430-
let value = if !it.parent_enum(db).is_data_carrying(db) {
431-
match it.eval(db) {
432-
Ok(x) => Some(if x >= 10 { format!("{x} ({x:#X})") } else { format!("{x}") }),
433-
Err(_) => it.value(db).map(|x| format!("{x:?}")),
434-
}
435-
} else {
436-
None
437-
};
438-
(value, layout)
439-
}),
447+
Some(format!("size = {:#X}", layout.size.bytes()))
448+
},
449+
),
440450
Definition::Const(it) => label_value_and_docs(db, it, |it| {
441451
let body = it.render_eval(db);
442452
match body {
@@ -463,7 +473,11 @@ pub(super) fn definition(
463473
Definition::TraitAlias(it) => label_and_docs(db, it),
464474
Definition::TypeAlias(it) => label_and_layout_info_and_docs(db, it, config, |&it| {
465475
let layout = it.ty(db).layout(db).ok()?;
466-
Some(format!("size = {}, align = {}", layout.size.bytes(), layout.align.abi.bytes()))
476+
Some(format!(
477+
"size = {:#X}, align = {:#X}",
478+
layout.size.bytes(),
479+
layout.align.abi.bytes()
480+
))
467481
}),
468482
Definition::BuiltinType(it) => {
469483
return famous_defs
@@ -634,41 +648,42 @@ fn label_and_layout_info_and_docs<D, E, V>(
634648
db: &RootDatabase,
635649
def: D,
636650
config: &HoverConfig,
637-
value_extractor: E,
651+
layout_extractor: E,
638652
) -> (String, Option<hir::Documentation>)
639653
where
640654
D: HasAttrs + HirDisplay,
641655
E: Fn(&D) -> Option<V>,
642656
V: Display,
643657
{
644-
let label = match value_extractor(&def) {
645-
Some(value) if config.memory_layout => format!("{} // {value}", def.display(db)),
658+
let label = match config.memory_layout.then(|| layout_extractor(&def)).flatten() {
659+
Some(layout) => format!("{} // {layout}", def.display(db)),
646660
_ => def.display(db).to_string(),
647661
};
648662
let docs = def.attrs(db).docs();
649663
(label, docs)
650664
}
651665

652-
fn label_value_and_layout_info_and_docs<D, E, V, L>(
666+
fn label_value_and_layout_info_and_docs<D, E, E2, V, L>(
653667
db: &RootDatabase,
654668
def: D,
655669
config: &HoverConfig,
656670
value_extractor: E,
671+
layout_extractor: E2,
657672
) -> (String, Option<hir::Documentation>)
658673
where
659674
D: HasAttrs + HirDisplay,
660-
E: Fn(&D) -> (Option<V>, Option<L>),
675+
E: Fn(&D) -> Option<V>,
676+
E2: Fn(&D) -> Option<L>,
661677
V: Display,
662678
L: Display,
663679
{
664-
let (value, layout) = value_extractor(&def);
665-
let label = if let Some(value) = value {
666-
format!("{} = {value}", def.display(db))
667-
} else {
668-
def.display(db).to_string()
680+
let value = value_extractor(&def);
681+
let label = match value {
682+
Some(value) => format!("{} = {value}", def.display(db)),
683+
None => def.display(db).to_string(),
669684
};
670-
let label = match layout {
671-
Some(layout) if config.memory_layout => format!("{} // {layout}", label),
685+
let label = match config.memory_layout.then(|| layout_extractor(&def)).flatten() {
686+
Some(layout) => format!("{} // {layout}", label),
672687
_ => label,
673688
};
674689
let docs = def.attrs(db).docs();

0 commit comments

Comments
 (0)