@@ -10,6 +10,8 @@ use std::ops::Deref;
1010use std:: ops:: DerefMut ;
1111use std:: panic;
1212
13+ use crate :: translate:: translate_generics:: BindingLevel ;
14+
1315use super :: translate_crate:: * ;
1416use super :: translate_ctx:: * ;
1517use charon_lib:: ast:: ullbc_ast:: StatementKind ;
@@ -508,6 +510,7 @@ impl BodyTransCtx<'_, '_, '_> {
508510 let tgt_ty = self . translate_ty ( span, tgt_ty) ?;
509511
510512 // Translate the operand
513+ let src_hax_ty = hax_operand. ty ( ) ;
511514 let mut operand = self . translate_operand ( span, hax_operand) ?;
512515 let src_ty = operand. ty ( ) . clone ( ) ;
513516
@@ -566,28 +569,118 @@ impl BodyTransCtx<'_, '_, '_> {
566569 self . translate_constant_expr_to_const_generic ( span, len) ?;
567570 UnsizingMetadata :: Length ( len)
568571 }
569- hax:: UnsizingMetadata :: VTablePtr ( impl_expr) => {
572+ hax:: UnsizingMetadata :: DirectVTable ( impl_expr) => {
570573 let tref = self . translate_trait_impl_expr ( span, impl_expr) ?;
571- match & impl_expr. r#impl {
574+ let vtable = match & impl_expr. r#impl {
572575 hax:: ImplExprAtom :: Concrete ( tref) => {
573576 // Ensure the vtable type is translated.
574- let _ : GlobalDeclId = self . register_item (
577+ Some ( self . translate_item (
575578 span,
576579 tref,
577580 TransItemSourceKind :: VTableInstance (
578581 TraitImplSource :: Normal ,
579582 ) ,
580- ) ;
583+ ) ? )
581584 }
582585 // TODO(dyn): more ways of registering vtable instance?
583586 _ => {
584587 trace ! (
585588 "impl_expr not triggering registering vtable: {:?}" ,
586589 impl_expr
587- )
590+ ) ;
591+ None
592+ }
593+ } ;
594+ UnsizingMetadata :: VTableDirect ( tref, vtable)
595+ }
596+ hax:: UnsizingMetadata :: NestedVTable ( impl_expr) => {
597+ let ( hax:: TyKind :: Ref ( _, src_hax_ty, _)
598+ | hax:: TyKind :: RawPtr ( src_hax_ty, _) ) = src_hax_ty. kind ( )
599+ else {
600+ raise_error ! (
601+ self ,
602+ span,
603+ "Nested vtable unsizing only supported for ref types, got {:?}" ,
604+ src_hax_ty
605+ ) ;
606+ } ;
607+ let hax:: TyKind :: Dynamic ( self_ty, preds, region) =
608+ src_hax_ty. kind ( )
609+ else {
610+ raise_error ! (
611+ self ,
612+ span,
613+ "Nested vtable unsizing only supported for dyn traits, got {:?}" ,
614+ src_hax_ty
615+ ) ;
616+ } ;
617+
618+ // Add a binder that contains the existentially quantified type.
619+ self . binding_levels . push ( BindingLevel :: new ( true ) ) ;
620+
621+ // Add the existentially quantified type.
622+ let ty_id = self
623+ . innermost_binder_mut ( )
624+ . push_type_var ( self_ty. index , self_ty. name . clone ( ) ) ;
625+ let ty = TyKind :: TypeVar ( DeBruijnVar :: new_at_zero ( ty_id) ) . into_ty ( ) ;
626+
627+ let region = self . translate_region ( span, region) ?;
628+ self . innermost_binder_mut ( ) . params . types_outlive . push (
629+ RegionBinder :: empty ( OutlivesPred ( ty. clone ( ) , region. clone ( ) ) ) ,
630+ ) ;
631+ self . register_predicates ( preds, PredicateOrigin :: Dyn ) ?;
632+
633+ let tref = self . translate_trait_impl_expr ( span, impl_expr) ?;
634+ let params = self . binding_levels . pop ( ) . unwrap ( ) . params ;
635+ let binder = Binder {
636+ params : params,
637+ skip_binder : tref,
638+ kind : BinderKind :: Dyn ,
639+ } ;
640+
641+ let hax:: ImplExprAtom :: LocalBound { index, path, .. } =
642+ & impl_expr. r#impl
643+ else {
644+ raise_error ! (
645+ self ,
646+ span,
647+ "Unexpected impl expr in NestedVTable unsizing metadata"
648+ ) ;
649+ } ;
650+
651+ let fields = if * index != 0 {
652+ let mut fields = Vec :: new ( ) ;
653+ for segment in path {
654+ let hax:: ImplExprPathChunk :: Parent {
655+ predicate, index, ..
656+ } = segment
657+ else {
658+ raise_error ! (
659+ self ,
660+ span,
661+ "Unexpected path segment in NestedVTable unsizing metadata"
662+ ) ;
663+ } ;
664+ let vtable =
665+ self . vtable_for_itemref ( & predicate. value . trait_ref ) ?;
666+ let index = TraitClauseId :: new ( * index) ;
667+ let Some ( Some ( field) ) = vtable. clauses . get ( index) else {
668+ raise_error ! (
669+ self ,
670+ span,
671+ "VTable missing field {} for predicate {:?}" ,
672+ index,
673+ predicate. value. trait_ref
674+ ) ;
675+ } ;
676+ fields. push ( * field) ;
588677 }
678+ fields
679+ } else {
680+ vec ! [ ]
589681 } ;
590- UnsizingMetadata :: VTablePtr ( tref)
682+
683+ UnsizingMetadata :: VTableNested ( binder, fields)
591684 }
592685 hax:: UnsizingMetadata :: Unknown => UnsizingMetadata :: Unknown ,
593686 } ;
0 commit comments