Skip to content

Commit 62a239d

Browse files
authored
HOTFIX normalise field types before emitting them (#95)
The `Ty`s found in field information can contain `AliasTy` as well as `ParamTy`, and potentially have unevaluated constants. Also now panicking if an unevaluated constant is found in array type metadata. In the discussion, it was pointed out that the variant fields can be obtained using `stable_mir` crate (interface) methods only, so I refactored the code to not use internals where possible. Related Zulip discussion:[#project-stable-mir > Visiting ADT field types, problem with unevaluated constants](https://rust-lang.zulipchat.com/#narrow/channel/320896-project-stable-mir/topic/Visiting.20ADT.20field.20types.2C.20problem.20with.20unevaluated.20constants)
1 parent 74a4261 commit 62a239d

File tree

2 files changed

+36
-87
lines changed

2 files changed

+36
-87
lines changed

src/printer.rs

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern crate serde;
2222
extern crate serde_json;
2323
use rustc_middle as middle;
2424
use rustc_middle::ty::{
25-
EarlyBinder, FnSig, GenericArgs, GenericArgsRef, List, Ty, TyCtxt, TypeFoldable, TypingEnv,
25+
EarlyBinder, FnSig, GenericArgs, List, Ty, TyCtxt, TypeFoldable, TypingEnv,
2626
};
2727
use rustc_session::config::{OutFileName, OutputType};
2828
use rustc_smir::rustc_internal::{self, internal};
@@ -557,15 +557,12 @@ impl Visitor for TyCollector<'_> {
557557
}
558558
// The visitor won't collect field types for ADTs, therefore doing it explicitly
559559
TyKind::RigidTy(RigidTy::Adt(adt_def, args)) => {
560-
let tcx = self.tcx;
561-
let adt = rustc_internal::internal(tcx, adt_def);
562-
563-
let args: GenericArgsRef = rustc_internal::internal(tcx, args);
564-
let fields: Vec<stable_mir::ty::Ty> = adt
565-
.all_fields()
566-
.map(move |field| field.ty(tcx, args))
567-
.map(rustc_internal::stable)
568-
.collect();
560+
let fields = adt_def
561+
.variants()
562+
.iter()
563+
.flat_map(|v| v.fields())
564+
.map(|f| f.ty_with_args(&args))
565+
.collect::<Vec<_>>();
569566

570567
let control = ty.super_visit(self);
571568
if matches!(control, ControlFlow::Continue(_)) {
@@ -1055,14 +1052,13 @@ fn mk_type_metadata(
10551052
.discriminants(tcx)
10561053
.map(|(_, discr)| discr.val)
10571054
.collect::<Vec<_>>();
1058-
let fields = adt_internal
1055+
let fields = adt_def
10591056
.variants()
1060-
.into_iter()
1061-
.map(|def| {
1062-
def.fields
1057+
.iter()
1058+
.map(|v| {
1059+
v.fields()
10631060
.iter()
1064-
.map(|f| f.ty(tcx, rustc_internal::internal(tcx, &args)))
1065-
.map(rustc_internal::stable)
1061+
.map(|f| f.ty_with_args(&args))
10661062
.collect::<Vec<stable_mir::ty::Ty>>()
10671063
})
10681064
.collect();
@@ -1078,10 +1074,13 @@ fn mk_type_metadata(
10781074
))
10791075
}
10801076
T(Adt(adt_def, args)) if t.is_struct() => {
1081-
let fields = rustc_internal::internal(tcx, adt_def)
1082-
.all_fields() // is_struct, so only one variant
1083-
.map(move |f| f.ty(tcx, rustc_internal::internal(tcx, &args)))
1084-
.map(rustc_internal::stable)
1077+
let fields = adt_def
1078+
.variants()
1079+
.pop() // NB struct, there should be a single variant
1080+
.unwrap()
1081+
.fields()
1082+
.iter()
1083+
.map(|f| f.ty_with_args(&args))
10851084
.collect();
10861085
Some((
10871086
k,
@@ -1104,14 +1103,23 @@ fn mk_type_metadata(
11041103
// encode str together with primitive types
11051104
T(Str) => Some((k, PrimitiveType(Str))),
11061105
// for arrays and slices, record element type and optional size
1107-
T(Array(elem_type, ty_const)) => Some((
1108-
k,
1109-
ArrayType {
1110-
elem_type,
1111-
size: Some(ty_const),
1112-
layout,
1113-
},
1114-
)),
1106+
T(Array(elem_type, ty_const)) => {
1107+
if matches!(
1108+
ty_const.kind(),
1109+
stable_mir::ty::TyConstKind::Unevaluated(_, _)
1110+
) {
1111+
panic!("Unevaluated constant {ty_const:?} in type {k}");
1112+
}
1113+
Some((
1114+
k,
1115+
ArrayType {
1116+
elem_type,
1117+
size: Some(ty_const),
1118+
layout,
1119+
},
1120+
))
1121+
}
1122+
11151123
T(Slice(elem_type)) => Some((
11161124
k,
11171125
ArrayType {

tests/integration/programs/assert_eq.smir.json.expected

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5653,65 +5653,6 @@
56535653
}
56545654
}
56555655
],
5656-
[
5657-
{
5658-
"RefType": {
5659-
"layout": {
5660-
"abi": {
5661-
"ScalarPair": [
5662-
{
5663-
"Initialized": {
5664-
"valid_range": {
5665-
"end": 18446744073709551615,
5666-
"start": 1
5667-
},
5668-
"value": {
5669-
"Pointer": 0
5670-
}
5671-
}
5672-
},
5673-
{
5674-
"Initialized": {
5675-
"valid_range": {
5676-
"end": 18446744073709551615,
5677-
"start": 0
5678-
},
5679-
"value": {
5680-
"Int": {
5681-
"length": "I64",
5682-
"signed": false
5683-
}
5684-
}
5685-
}
5686-
}
5687-
]
5688-
},
5689-
"abi_align": 8,
5690-
"fields": {
5691-
"Arbitrary": {
5692-
"offsets": [
5693-
{
5694-
"num_bits": 0
5695-
},
5696-
{
5697-
"num_bits": 64
5698-
}
5699-
]
5700-
}
5701-
},
5702-
"size": {
5703-
"num_bits": 128
5704-
},
5705-
"variants": {
5706-
"Single": {
5707-
"index": 0
5708-
}
5709-
}
5710-
},
5711-
"pointee_type": "elided"
5712-
}
5713-
}
5714-
],
57155656
[
57165657
{
57175658
"RefType": {

0 commit comments

Comments
 (0)