Skip to content

Commit 995cfa0

Browse files
committed
Include method signatures in the trait decl
1 parent 45b6e8e commit 995cfa0

11 files changed

Lines changed: 70 additions & 56 deletions

File tree

charon-ml/src/GAstUtils.ml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,26 @@ let bound_fun_sig_of_decl (def : fun_decl) : bound_fun_sig =
5757
reflect that there are two binding levels: the trait generics and the method
5858
generics. *)
5959
let lookup_trait_decl_method (tdecl : trait_decl) (name : trait_item_name) :
60+
trait_method binder item_binder option =
61+
Option.map
62+
(fun m -> { item_binder_params = tdecl.generics; item_binder_value = m })
63+
(List.find_opt
64+
(fun (m : trait_method binder) -> m.binder_value.name = name)
65+
tdecl.methods)
66+
67+
let lookup_trait_decl_method_ref (tdecl : trait_decl) (name : trait_item_name) :
6068
fun_decl_ref binder item_binder option =
6169
Option.map
6270
(fun m ->
6371
{
64-
item_binder_params = tdecl.generics;
72+
item_binder_params = m.item_binder_params;
6573
item_binder_value =
6674
{
67-
binder_params = m.binder_params;
68-
binder_value = m.binder_value.item;
75+
binder_params = m.item_binder_value.binder_params;
76+
binder_value = m.item_binder_value.binder_value.item;
6977
};
7078
})
71-
(List.find_opt
72-
(fun (m : trait_method binder) -> m.binder_value.name = name)
73-
tdecl.methods)
79+
(lookup_trait_decl_method tdecl name)
7480

7581
(** Lookup a method in this trait impl. The two levels of binders in the output
7682
reflect that there are two binding levels: the impl generics and the method

charon-ml/src/Substitute.ml

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -562,12 +562,12 @@ let fuse_binders (substitutor : subst -> 'a -> 'a)
562562
(** Helper *)
563563
let instantiate_method (trait_self : trait_ref_kind)
564564
(item_generics : generic_args) (method_generics : generic_args)
565-
(bound_fn : fun_decl_ref binder item_binder) : fun_decl_ref =
565+
(bound_method : fun_decl_ref binder item_binder) : fun_decl_ref =
566566
let bound_fn =
567567
apply_args_to_item_binder trait_self item_generics
568568
(st_substitute_visitor#visit_binder
569569
st_substitute_visitor#visit_fun_decl_ref)
570-
bound_fn
570+
bound_method
571571
in
572572
apply_args_to_binder method_generics st_substitute_visitor#visit_fun_decl_ref
573573
bound_fn
@@ -585,7 +585,7 @@ let lookup_and_subst_trait_decl_method (tdecl : trait_decl)
585585
(method_generics : generic_args) : fun_decl_ref option =
586586
Option.map
587587
(instantiate_trait_method trait_ref method_generics)
588-
(lookup_trait_decl_method tdecl name)
588+
(lookup_trait_decl_method_ref tdecl name)
589589

590590
(** Like lookup_trait_impl_method, but also correctly substitutes the generics.
591591
*)
@@ -606,26 +606,17 @@ let lookup_method_sig (crate : crate) (trait_id : trait_decl_id)
606606
let* tdecl = TraitDeclId.Map.find_opt trait_id crate.trait_decls in
607607
let* {
608608
item_binder_params : generic_params = trait_params;
609-
item_binder_value : fun_decl_ref binder = bound_method;
609+
item_binder_value : trait_method binder =
610+
{ binder_params = method_params; binder_value = trait_method };
610611
} =
611612
lookup_trait_decl_method tdecl name
612613
in
613-
let method_decl_id = bound_method.binder_value.id in
614-
let* method_decl =
615-
LlbcAst.FunDeclId.Map.find_opt method_decl_id crate.fun_decls
616-
in
617-
(* Substitute the signature to be valid under the binder. *)
618-
let signature =
619-
st_substitute_visitor#visit_fun_sig
620-
(make_subst_from_generics method_decl.generics
621-
bound_method.binder_value.generics Self)
622-
method_decl.signature
623-
in
624-
(* Rebind everything *)
625-
let bound_sig =
626-
{ binder_params = bound_method.binder_params; binder_value = signature }
627-
in
628-
Some { item_binder_params = trait_params; item_binder_value = bound_sig }
614+
Some
615+
{
616+
item_binder_params = trait_params;
617+
item_binder_value =
618+
{ binder_params = method_params; binder_value = trait_method.signature };
619+
}
629620

630621
(* Like [lookup_method_sig], but with no binder shenanigans: the returned
631622
binder binds the concatenation of trait generics and method generics. *)

charon-ml/src/generated/Generated_GAst.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ and trait_decl = {
301301
and trait_method = {
302302
name : trait_item_name;
303303
attr_info : attr_info;
304+
signature : fun_sig;
304305
item : fun_decl_ref;
305306
(** Each method declaration is represented by a function item. That
306307
function contains the signature of the method as well as information

charon-ml/src/generated/Generated_OfJson.ml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,11 +2782,18 @@ and trait_method_of_json (ctx : of_json_ctx) (js : json) :
27822782
(trait_method, string) result =
27832783
combine_error_msgs js __FUNCTION__
27842784
(match js with
2785-
| `Assoc [ ("name", name); ("attr_info", attr_info); ("item", item) ] ->
2785+
| `Assoc
2786+
[
2787+
("name", name);
2788+
("attr_info", attr_info);
2789+
("signature", signature);
2790+
("item", item);
2791+
] ->
27862792
let* name = trait_item_name_of_json ctx name in
27872793
let* attr_info = attr_info_of_json ctx attr_info in
2794+
let* signature = fun_sig_of_json ctx signature in
27882795
let* item = fun_decl_ref_of_json ctx item in
2789-
Ok ({ name; attr_info; item } : trait_method)
2796+
Ok ({ name; attr_info; signature; item } : trait_method)
27902797
| _ -> Error "")
27912798

27922799
and translated_crate_of_json (ctx : of_json_ctx) (js : json) :

charon/src/ast/gast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ pub struct TraitMethod {
399399
#[drive(skip)]
400400
#[serde_state(stateless)]
401401
pub attr_info: AttrInfo,
402+
pub signature: FunSig,
402403
/// Each method declaration is represented by a function item. That function contains the
403404
/// signature of the method as well as information like attributes. It has a body iff the
404405
/// method declaration has a default implementation; otherwise it has an `Opaque` body.

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

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -672,13 +672,6 @@ impl ItemTransCtx<'_, '_> {
672672
TraitRefKind::SelfId,
673673
RegionBinder::empty(self.translate_trait_predicate(span, self_predicate)?),
674674
);
675-
let items: Vec<(TraitItemName, &hax::AssocItem)> = items
676-
.iter()
677-
.map(|item| -> Result<_, Error> {
678-
let name = self.t_ctx.translate_trait_item_name(&item.def_id)?;
679-
Ok((name, item))
680-
})
681-
.try_collect()?;
682675

683676
// Translate the associated items
684677
let mut consts = Vec::new();
@@ -701,8 +694,9 @@ impl ItemTransCtx<'_, '_> {
701694
});
702695
}
703696

704-
for &(item_name, hax_item) in &items {
697+
for hax_item in items {
705698
let item_def_id = &hax_item.def_id;
699+
let item_name = self.t_ctx.translate_trait_item_name(item_def_id)?;
706700
let item_span = self.def_span(item_def_id);
707701

708702
// In --mono mode, we keep only non-polymorphic items; in not-mono mode, we use the
@@ -718,7 +712,7 @@ impl ItemTransCtx<'_, '_> {
718712
let attr_info = self.translate_attr_info(&item_def);
719713

720714
match item_def.kind() {
721-
hax::FullDefKind::AssocFn { .. } => {
715+
hax::FullDefKind::AssocFn { sig, .. } => {
722716
let method_id = self.register_no_enqueue(item_span, &item_src);
723717
// Register this method.
724718
self.register_method_impl(def_id, item_name, method_id);
@@ -752,9 +746,14 @@ impl ItemTransCtx<'_, '_> {
752746
id: method_id,
753747
generics: Box::new(fun_generics),
754748
};
749+
// `skip_binder` is allowed because `translate_binder_for_def` puts the
750+
// late bound params in scope.
751+
let signature =
752+
bt_ctx.translate_fun_sig(span, sig.hax_skip_binder_ref())?;
755753
Ok(TraitMethod {
756754
name: item_name,
757755
attr_info,
756+
signature,
758757
item: fn_ref,
759758
})
760759
},
@@ -884,10 +883,21 @@ impl ItemTransCtx<'_, '_> {
884883
let (method_name, method_binder) =
885884
self.prepare_drop_in_place_method(def, span, def_id, None);
886885
self.mark_method_as_used(def_id, method_name);
887-
methods.push(method_binder.map(|fn_ref| TraitMethod {
888-
name: method_name,
889-
attr_info: AttrInfo::dummy_public(),
890-
item: fn_ref,
886+
methods.push(method_binder.map(|fn_ref| {
887+
let self_ty = if self.monomorphize() {
888+
// FIXME: put something real here
889+
Ty::mk_unit()
890+
} else {
891+
TyKind::TypeVar(DeBruijnVar::bound(DeBruijnId::one(), TypeVarId::ZERO))
892+
.into_ty()
893+
};
894+
let signature = self.drop_in_place_method_sig(self_ty);
895+
TraitMethod {
896+
name: method_name,
897+
item: fn_ref,
898+
attr_info: AttrInfo::dummy_public(),
899+
signature,
900+
}
891901
}));
892902
}
893903

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,7 @@ impl<'tcx, 'ctx> ItemTransCtx<'tcx, 'ctx> {
331331
..
332332
} => {
333333
let tref = &impl_source.r#trait;
334-
let trait_def =
335-
self.hax_def(&tref.hax_skip_binder_ref().erase(self.hax_state_with_id()))?;
334+
let trait_def = self.poly_hax_def(&tref.hax_skip_binder_ref().def_id)?;
336335
let kind = if let hax::FullDefKind::TraitAlias { .. } = trait_def.kind() {
337336
// We reuse the same `def_id` to generate a blanket impl for the trait.
338337
let mut impl_ref: TraitImplRef = self.translate_item(

charon/tests/ptr-metadata.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,6 @@
4646
"core::fmt::Formatter": "None",
4747
"core::fmt::Error": "None",
4848
"core::cmp::Ordering": "None",
49-
"core::option::Option": "None"
49+
"core::option::Option": "None",
50+
"core::ops::control_flow::ControlFlow": "None"
5051
}

charon/tests/ui/control-flow/loops.out

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,25 +321,24 @@ where
321321
[@TraitClause0]: Iterator<Self>,
322322
= <opaque>
323323

324-
// Full name: core::slice::index::private_slice_index::Sealed
325-
pub trait Sealed<Self>
324+
pub trait core::slice::index::private_slice_index::Sealed<Self>
326325
{
327326
parent_clause0 : [@TraitClause0]: MetaSized<Self>
328327
vtable: core::slice::index::private_slice_index::Sealed::{vtable}
329328
}
330329

331-
// Full name: core::slice::index::private_slice_index::{impl Sealed for usize}
332-
impl Sealed for usize {
330+
// Full name: core::slice::index::private_slice_index::{impl core::slice::index::private_slice_index::Sealed for usize}
331+
impl core::slice::index::private_slice_index::Sealed for usize {
333332
parent_clause0 = {built_in impl MetaSized for usize}
334-
vtable: {impl Sealed for usize}::{vtable}
333+
vtable: {impl core::slice::index::private_slice_index::Sealed for usize}::{vtable}
335334
}
336335

337336
// Full name: core::slice::index::SliceIndex
338337
#[lang_item("SliceIndex")]
339338
pub trait SliceIndex<Self, T>
340339
{
341340
parent_clause0 : [@TraitClause0]: MetaSized<Self>
342-
parent_clause1 : [@TraitClause1]: Sealed<Self>
341+
parent_clause1 : [@TraitClause1]: core::slice::index::private_slice_index::Sealed<Self>
343342
parent_clause2 : [@TraitClause2]: MetaSized<T>
344343
parent_clause3 : [@TraitClause3]: MetaSized<Self::Output>
345344
type Output
@@ -424,7 +423,7 @@ where
424423
[@TraitClause0]: Sized<T>,
425424
{
426425
parent_clause0 = {built_in impl MetaSized for usize}
427-
parent_clause1 = {impl Sealed for usize}
426+
parent_clause1 = {impl core::slice::index::private_slice_index::Sealed for usize}
428427
parent_clause2 = {built_in impl MetaSized for [T]}
429428
parent_clause3 = @TraitClause0::parent_clause0
430429
type Output = T

charon/tests/ui/monomorphization/dyn-trait.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
thread 'rustc' panicked at src/bin/charon-driver/translate/translate_trait_objects.rs:1696:13:
2+
thread 'rustc' panicked at src/bin/charon-driver/translate/translate_trait_objects.rs:1687:13:
33
Could not determine method index for drop in vtable
44
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
55
error: Thread panicked when extracting item `core::fmt::Display`.
@@ -11,7 +11,7 @@ note: the error occurred when translating `core::fmt::Display::{vtable_drop_pres
1111
12 | let _ = dyn_to_string(&str);
1212
| ----
1313

14-
thread 'rustc' panicked at src/bin/charon-driver/translate/translate_trait_objects.rs:1574:13:
14+
thread 'rustc' panicked at src/bin/charon-driver/translate/translate_trait_objects.rs:1565:13:
1515
Could not determine method index for method_fmt in vtable
1616
error: Thread panicked when extracting item `core::fmt::Display`.
1717
--> /rustc/library/core/src/fmt/mod.rs:1186:1

0 commit comments

Comments
 (0)