Skip to content

Commit e6ad3f7

Browse files
authored
Merge pull request #788 from Nadrieril/vtables
Generate explicit structs and values for trait vtables
2 parents 5807dea + 8f3ffaa commit e6ad3f7

30 files changed

+2291
-69
lines changed

charon-ml/src/CharonVersion.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
(* This is an automatically generated file, generated from `charon/Cargo.toml`. *)
22
(* To re-generate this file, rune `make` in the root directory *)
3-
let supported_charon_version = "0.1.121"
3+
let supported_charon_version = "0.1.122"

charon-ml/src/generated/Generated_GAst.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ type trait_decl = {
209209
The binder contains the type parameters specific to the method. The
210210
[FunDeclRef] then provides a full list of arguments to the pointed-to
211211
function. *)
212+
vtable : type_decl_ref option;
213+
(** The virtual table struct for this trait, if it has one. It is
214+
guaranteed that the trait has a vtable iff it is dyn-compatible. *)
212215
}
213216
[@@deriving
214217
show,
@@ -256,6 +259,9 @@ type trait_impl = {
256259
(** The associated types declared in the trait. *)
257260
methods : (trait_item_name * fun_decl_ref binder) list;
258261
(** The implemented methods *)
262+
vtable : global_decl_ref option;
263+
(** The virtual table instance for this trait implementation. This is
264+
[Some] iff the trait is dyn-compatible. *)
259265
}
260266
[@@deriving
261267
show,

charon-ml/src/generated/Generated_GAstOfJson.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,12 @@ and item_kind_of_json (ctx : of_json_ctx) (js : json) :
10411041
let* item_name = trait_item_name_of_json ctx item_name in
10421042
let* reuses_default = bool_of_json ctx reuses_default in
10431043
Ok (TraitImplItem (impl_ref, trait_ref, item_name, reuses_default))
1044+
| `Assoc [ ("VTableTy", `Assoc [ ("dyn_predicate", dyn_predicate) ]) ] ->
1045+
let* dyn_predicate = dyn_predicate_of_json ctx dyn_predicate in
1046+
Ok (VTableTyItem dyn_predicate)
1047+
| `Assoc [ ("VTableInstance", `Assoc [ ("impl_ref", impl_ref) ]) ] ->
1048+
let* impl_ref = trait_impl_ref_of_json ctx impl_ref in
1049+
Ok (VTableInstanceItem impl_ref)
10441050
| _ -> Error "")
10451051

10461052
and item_meta_of_json (ctx : of_json_ctx) (js : json) :
@@ -1569,6 +1575,7 @@ and trait_decl_of_json (ctx : of_json_ctx) (js : json) :
15691575
("type_defaults", _);
15701576
("type_clauses", _);
15711577
("methods", methods);
1578+
("vtable", vtable);
15721579
] ->
15731580
let* def_id = trait_decl_id_of_json ctx def_id in
15741581
let* item_meta = item_meta_of_json ctx item_meta in
@@ -1589,6 +1596,7 @@ and trait_decl_of_json (ctx : of_json_ctx) (js : json) :
15891596
(binder_of_json fun_decl_ref_of_json))
15901597
ctx methods
15911598
in
1599+
let* vtable = option_of_json type_decl_ref_of_json ctx vtable in
15921600
Ok
15931601
({
15941602
def_id;
@@ -1598,6 +1606,7 @@ and trait_decl_of_json (ctx : of_json_ctx) (js : json) :
15981606
consts;
15991607
types;
16001608
methods;
1609+
vtable;
16011610
}
16021611
: trait_decl)
16031612
| _ -> Error "")
@@ -1634,6 +1643,7 @@ and trait_impl_of_json (ctx : of_json_ctx) (js : json) :
16341643
("types", types);
16351644
("type_clauses", _);
16361645
("methods", methods);
1646+
("vtable", vtable);
16371647
] ->
16381648
let* def_id = trait_impl_id_of_json ctx def_id in
16391649
let* item_meta = item_meta_of_json ctx item_meta in
@@ -1659,6 +1669,7 @@ and trait_impl_of_json (ctx : of_json_ctx) (js : json) :
16591669
(binder_of_json fun_decl_ref_of_json))
16601670
ctx methods
16611671
in
1672+
let* vtable = option_of_json global_decl_ref_of_json ctx vtable in
16621673
Ok
16631674
({
16641675
def_id;
@@ -1669,6 +1680,7 @@ and trait_impl_of_json (ctx : of_json_ctx) (js : json) :
16691680
consts;
16701681
types;
16711682
methods;
1683+
vtable;
16721684
}
16731685
: trait_impl)
16741686
| _ -> Error "")

charon-ml/src/generated/Generated_Types.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,17 @@ and item_kind =
717717
- [reuses_default]: True if the trait decl had a default
718718
implementation for this function/const and this item is a copy of
719719
the default item. *)
720+
| VTableTyItem of dyn_predicate
721+
(** This is a vtable struct for a trait.
722+
723+
Fields:
724+
- [dyn_predicate]: The [dyn Trait] predicate implemented by this
725+
vtable. *)
726+
| VTableInstanceItem of trait_impl_ref
727+
(** This is a vtable value for an impl.
728+
729+
Fields:
730+
- [impl_ref] *)
720731

721732
(** Meta information about an item (function, trait decl, trait impl, type decl,
722733
global). *)

charon/Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charon/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "charon"
3-
version = "0.1.121"
3+
version = "0.1.122"
44
authors = [
55
"Son Ho <[email protected]>",
66
"Guillaume Boisseau <[email protected]>",

charon/src/ast/expressions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ impl From<FunDeclRef> for FnPtr {
471471
/// reading the constant `a.b` is translated to `{ _1 = const a; _2 = (_1.0) }`.
472472
#[derive(
473473
Debug,
474+
Hash,
474475
PartialEq,
475476
Eq,
476477
Clone,
@@ -485,7 +486,6 @@ impl From<FunDeclRef> for FnPtr {
485486
#[charon::variants_prefix("C")]
486487
pub enum RawConstantExpr {
487488
Literal(Literal),
488-
///
489489
/// In most situations:
490490
/// Enumeration with one variant with no fields, structure with
491491
/// no fields, unit (encoded as a 0-tuple).
@@ -553,7 +553,7 @@ pub enum RawConstantExpr {
553553
Opaque(String),
554554
}
555555

556-
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Drive, DriveMut)]
556+
#[derive(Debug, Hash, PartialEq, Eq, Clone, Serialize, Deserialize, Drive, DriveMut)]
557557
pub struct ConstantExpr {
558558
pub value: RawConstantExpr,
559559
pub ty: Ty,

charon/src/ast/gast.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ pub enum ItemKind {
127127
#[drive(skip)]
128128
reuses_default: bool,
129129
},
130+
/// This is a vtable struct for a trait.
131+
VTableTy {
132+
/// The `dyn Trait` predicate implemented by this vtable.
133+
dyn_predicate: DynPredicate,
134+
},
135+
/// This is a vtable value for an impl.
136+
VTableInstance { impl_ref: TraitImplRef },
130137
}
131138

132139
/// A function definition
@@ -279,6 +286,9 @@ pub struct TraitDecl {
279286
/// The binder contains the type parameters specific to the method. The `FunDeclRef` then
280287
/// provides a full list of arguments to the pointed-to function.
281288
pub methods: Vec<(TraitItemName, Binder<FunDeclRef>)>,
289+
/// The virtual table struct for this trait, if it has one.
290+
/// It is guaranteed that the trait has a vtable iff it is dyn-compatible.
291+
pub vtable: Option<TypeDeclRef>,
282292
}
283293

284294
/// A trait **implementation**.
@@ -313,6 +323,9 @@ pub struct TraitImpl {
313323
pub type_clauses: Vec<(TraitItemName, Vector<TraitClauseId, TraitRef>)>,
314324
/// The implemented methods
315325
pub methods: Vec<(TraitItemName, Binder<FunDeclRef>)>,
326+
/// The virtual table instance for this trait implementation. This is `Some` iff the trait is
327+
/// dyn-compatible.
328+
pub vtable: Option<GlobalDeclRef>,
316329
}
317330

318331
/// A function operand is used in function calls.

charon/src/ast/types_utils.rs

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,47 @@ impl GenericArgs {
412412
}
413413
}
414414

415+
impl IntTy {
416+
/// Important: this returns the target byte count for the types.
417+
/// Must not be used for host types from rustc.
418+
pub fn target_size(&self, ptr_size: ByteCount) -> usize {
419+
match self {
420+
IntTy::Isize => ptr_size as usize,
421+
IntTy::I8 => size_of::<i8>(),
422+
IntTy::I16 => size_of::<i16>(),
423+
IntTy::I32 => size_of::<i32>(),
424+
IntTy::I64 => size_of::<i64>(),
425+
IntTy::I128 => size_of::<i128>(),
426+
}
427+
}
428+
}
429+
impl UIntTy {
430+
/// Important: this returns the target byte count for the types.
431+
/// Must not be used for host types from rustc.
432+
pub fn target_size(&self, ptr_size: ByteCount) -> usize {
433+
match self {
434+
UIntTy::Usize => ptr_size as usize,
435+
UIntTy::U8 => size_of::<u8>(),
436+
UIntTy::U16 => size_of::<u16>(),
437+
UIntTy::U32 => size_of::<u32>(),
438+
UIntTy::U64 => size_of::<u64>(),
439+
UIntTy::U128 => size_of::<u128>(),
440+
}
441+
}
442+
}
443+
impl FloatTy {
444+
/// Important: this returns the target byte count for the types.
445+
/// Must not be used for host types from rustc.
446+
pub fn target_size(&self) -> usize {
447+
match self {
448+
FloatTy::F16 => size_of::<u16>(),
449+
FloatTy::F32 => size_of::<u32>(),
450+
FloatTy::F64 => size_of::<u64>(),
451+
FloatTy::F128 => size_of::<u128>(),
452+
}
453+
}
454+
}
455+
415456
impl IntegerTy {
416457
pub fn to_unsigned(&self) -> Self {
417458
match self {
@@ -429,18 +470,8 @@ impl IntegerTy {
429470
/// Must not be used for host types from rustc.
430471
pub fn target_size(&self, ptr_size: ByteCount) -> usize {
431472
match self {
432-
IntegerTy::Signed(IntTy::Isize) => ptr_size as usize,
433-
IntegerTy::Signed(IntTy::I8) => size_of::<i8>(),
434-
IntegerTy::Signed(IntTy::I16) => size_of::<i16>(),
435-
IntegerTy::Signed(IntTy::I32) => size_of::<i32>(),
436-
IntegerTy::Signed(IntTy::I64) => size_of::<i64>(),
437-
IntegerTy::Signed(IntTy::I128) => size_of::<i128>(),
438-
IntegerTy::Unsigned(UIntTy::Usize) => ptr_size as usize,
439-
IntegerTy::Unsigned(UIntTy::U8) => size_of::<u8>(),
440-
IntegerTy::Unsigned(UIntTy::U16) => size_of::<u16>(),
441-
IntegerTy::Unsigned(UIntTy::U32) => size_of::<u32>(),
442-
IntegerTy::Unsigned(UIntTy::U64) => size_of::<u64>(),
443-
IntegerTy::Unsigned(UIntTy::U128) => size_of::<u128>(),
473+
IntegerTy::Signed(ty) => ty.target_size(ptr_size),
474+
IntegerTy::Unsigned(ty) => ty.target_size(ptr_size),
444475
}
445476
}
446477
}
@@ -453,6 +484,18 @@ impl LiteralTy {
453484
_ => None,
454485
}
455486
}
487+
488+
/// Important: this returns the target byte count for the types.
489+
/// Must not be used for host types from rustc.
490+
pub fn target_size(&self, ptr_size: ByteCount) -> usize {
491+
match self {
492+
LiteralTy::Int(int_ty) => int_ty.target_size(ptr_size),
493+
LiteralTy::UInt(uint_ty) => uint_ty.target_size(ptr_size),
494+
LiteralTy::Float(float_ty) => float_ty.target_size(),
495+
LiteralTy::Char => 4,
496+
LiteralTy::Bool => 1,
497+
}
498+
}
456499
}
457500

458501
/// A value of type `T` bound by the generic parameters of item

charon/src/bin/charon-driver/translate/translate_bodies.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,25 @@ impl BodyTransCtx<'_, '_, '_> {
501501
}
502502
hax::UnsizingMetadata::VTablePtr(impl_expr) => {
503503
let tref = self.translate_trait_impl_expr(span, impl_expr)?;
504+
match &impl_expr.r#impl {
505+
hax::ImplExprAtom::Concrete(tref) => {
506+
// Ensure the vtable type is translated.
507+
let _: GlobalDeclId = self.register_item(
508+
span,
509+
tref,
510+
TransItemSourceKind::VTableInstance(
511+
TraitImplSource::Normal,
512+
),
513+
);
514+
}
515+
// TODO(dyn): more ways of registering vtable instance?
516+
_ => {
517+
trace!(
518+
"impl_expr not triggering registering vtable: {:?}",
519+
impl_expr
520+
)
521+
}
522+
};
504523
UnsizingMetadata::VTablePtr(tref)
505524
}
506525
hax::UnsizingMetadata::Unknown => UnsizingMetadata::Unknown,

0 commit comments

Comments
 (0)