Skip to content

Commit 626e8fe

Browse files
authored
fix(printer.rs): include ZeroSized FnDef consts in functions (#112)
- Problem: stable-mir-json misses function items (FnDef) that appear as ConstantKind::ZeroSized when passed as values (e.g. Option::map(u64::from_le_bytes)), so the emitted functions list is incomplete. - Fix: In InternedValueCollector::visit_mir_const, detect ZeroSized constants whose type is FnDef, resolve an Instance (prefer resolve_for_fn_ptr, fallback to resolve), and add it to the link map with ItemSource(FPTR) so it is emitted in functions. - Robustness: Avoid panicking on inconsistent symbol mappings by skipping insertion when the existing LinkMapKey already maps to a different symbol (direct-call vs reify shim cases). - Related: #55 (and downstream runtimeverification/mir-semantics#891 runtimeverification/mir-semantics#488).
1 parent 20a1bbd commit 626e8fe

31 files changed

+9581
-4090
lines changed

src/printer.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ struct InternedValueCollector<'tcx, 'local> {
600600

601601
type InternedValues<'tcx> = (LinkMap<'tcx>, AllocMap, TyMap, SpanMap);
602602

603+
fn is_reify_shim(kind: &middle::ty::InstanceKind<'_>) -> bool {
604+
matches!(kind, middle::ty::InstanceKind::ReifyShim(..))
605+
}
606+
603607
fn update_link_map<'tcx>(
604608
link_map: &mut LinkMap<'tcx>,
605609
fn_sym: Option<FnSymInfo<'tcx>>,
@@ -609,14 +613,26 @@ fn update_link_map<'tcx>(
609613
return;
610614
}
611615
let (ty, kind, name) = fn_sym.unwrap();
612-
let new_val = (source, name);
616+
let new_val = (source, name.clone());
613617
let key = if link_instance_enabled() {
614618
LinkMapKey(ty, Some(kind))
615619
} else {
616620
LinkMapKey(ty, None)
617621
};
618622
if let Some(curr_val) = link_map.get_mut(&key.clone()) {
619623
if curr_val.1 != new_val.1 {
624+
if !link_instance_enabled() {
625+
// When LINK_INST is disabled, prefer Item over ReifyShim.
626+
// ReifyShim has no body in items, so Item is more useful.
627+
if is_reify_shim(&kind) {
628+
// New entry is ReifyShim, existing is Item → skip
629+
return;
630+
}
631+
// New entry is Item, existing is ReifyShim → replace
632+
curr_val.1 = name;
633+
curr_val.0 .0 |= new_val.0 .0;
634+
return;
635+
}
620636
panic!(
621637
"Added inconsistent entries into link map! {:?} -> {:?}, {:?}",
622638
(ty, ty.kind().fn_def(), &kind),
@@ -898,7 +914,27 @@ impl MirVisitor for InternedValueCollector<'_, '_> {
898914
panic!("TyConstKind::Value");
899915
}
900916
}
901-
ConstantKind::Unevaluated(_) | ConstantKind::Param(_) | ConstantKind::ZeroSized => {}
917+
ConstantKind::ZeroSized => {
918+
// Zero-sized constants can represent function items (FnDef) used as values,
919+
// e.g. when passing a function pointer to a higher-order function.
920+
// Ensure such functions are included in the link map so they appear in the
921+
// `functions` array of the SMIR JSON.
922+
if constant.ty().kind().fn_def().is_some() {
923+
if let Some(inst) = fn_inst_for_ty(constant.ty(), false)
924+
.or_else(|| fn_inst_for_ty(constant.ty(), true))
925+
{
926+
let fn_sym = fn_inst_sym(self.tcx, Some(constant.ty()), Some(&inst));
927+
if let Some((ty, kind, name)) = fn_sym {
928+
update_link_map(
929+
self.link_map,
930+
Some((ty, kind, name)),
931+
ItemSource(FPTR),
932+
);
933+
}
934+
}
935+
}
936+
}
937+
ConstantKind::Unevaluated(_) | ConstantKind::Param(_) => {}
902938
}
903939
self.super_mir_const(constant, loc);
904940
}

tests/integration/normalise-filter.jq

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# Apply the normalisation filter
1212
{ allocs: ( .allocs | sort ),
1313
functions: (.functions | sort ),
14-
items: (.items | sort ),
14+
items: (.items | map(walk(if type == "object" then del(.ty) else . end)) | sort ),
1515
types: ( [
1616
# sort by constructors and remove unstable IDs within each
1717
( .types | map(select(.[0].PrimitiveType)) | sort ),
@@ -20,7 +20,7 @@
2020
( .types | map(select(.[0].StructType) | del(.[0].StructType.adt_def) | .[0].StructType.fields = "elided" ) | sort_by(.[0].StructType.name) ),
2121
( .types | map(select(.[0].UnionType) | del(.[0].UnionType.adt_def)) | sort_by(.[0].UnionType.name) ),
2222
# delete unstable Ty IDs for arrays and tuples
23-
( .types | map(select(.[0].ArrayType) | del(.[0].ArrayType.elem_type) | del(.[0].ArrayType.size.id)) | sort ),
23+
( .types | map(select(.[0].ArrayType) | del(.[0].ArrayType.elem_type) | del(.[0].ArrayType.size.id) | del(.[0].ArrayType.size.kind.Value[0])) | sort ),
2424
( .types | map(select(.[0].TupleType) | .[0].TupleType.types = "elided") ),
2525
# replace unstable Ty IDs for references by zero
2626
( .types | map(select(.[0].PtrType) | .[0].PtrType.pointee_type = "elided") | sort ),

0 commit comments

Comments
 (0)