@@ -372,55 +372,60 @@ impl<'a, 'ctx> Ctx<'a> {
372372 if let ( PLType :: Trait ( t) , PLType :: Struct ( st) ) =
373373 ( & * target_pltype. borrow ( ) , & * st_pltype. borrow ( ) )
374374 {
375- if !st. implements_trait ( t, & self . get_root_ctx ( ) . plmod ) {
376- return Err ( mismatch_err ! (
377- self ,
378- ori_range,
379- target_range,
380- target_pltype. borrow( ) ,
381- st_pltype. borrow( )
382- ) ) ;
383- }
384- let trait_handle = builder. alloc ( "tmp_traitv" , & target_pltype. borrow ( ) , self , None ) ;
385- for f in t. list_trait_fields ( ) . iter ( ) {
386- let mthd = find_mthd ( st, f, t) . unwrap_or_else ( || {
387- for t in & t. derives {
388- match & * t. borrow ( ) {
389- PLType :: Trait ( t) => {
390- if let Some ( mthd) = find_mthd ( st, f, t) {
391- return mthd;
375+ return self . run_in_type_mod ( t, |ctx, t| {
376+ ctx. protect_generic_context ( & t. generic_map , |ctx| {
377+ if !st. implements_trait ( t, & ctx. get_root_ctx ( ) . plmod ) {
378+ return Err ( mismatch_err ! (
379+ ctx,
380+ ori_range,
381+ target_range,
382+ target_pltype. borrow( ) ,
383+ st_pltype. borrow( )
384+ ) ) ;
385+ }
386+ let trait_handle =
387+ builder. alloc ( "tmp_traitv" , & target_pltype. borrow ( ) , ctx, None ) ;
388+ for f in t. list_trait_fields ( ) . iter ( ) {
389+ let mthd = find_mthd ( st, f, t) . unwrap_or_else ( || {
390+ for t in & t. derives {
391+ match & * t. borrow ( ) {
392+ PLType :: Trait ( t) => {
393+ if let Some ( mthd) = find_mthd ( st, f, t) {
394+ return mthd;
395+ }
396+ }
397+ _ => unreachable ! ( ) ,
392398 }
393399 }
394- _ => unreachable ! ( ) ,
395- }
396- }
397- unreachable ! ( )
398- } ) ;
400+ unreachable ! ( )
401+ } ) ;
399402
400- // TODO: let a:trait = B<i64>{} panic
401- let fnhandle = builder. get_or_insert_fn_handle ( & mthd. borrow ( ) , self ) ;
402- let targetftp = f. typenode . get_type ( self , builder, true ) . unwrap ( ) ;
403- let casted = builder. bitcast ( self , fnhandle, & targetftp. borrow ( ) , "fncast_tmp" ) ;
404- let f_ptr = builder
405- . build_struct_gep ( trait_handle, f. index , "field_tmp" )
406- . unwrap ( ) ;
407- builder. build_store ( f_ptr, casted) ;
408- }
409- let st_value = builder. bitcast (
410- self ,
411- st_value,
412- & PLType :: Pointer ( Arc :: new ( RefCell :: new ( PLType :: Primitive ( PriType :: I64 ) ) ) ) ,
413- "traitcast_tmp" ,
414- ) ;
415- let v_ptr = builder. build_struct_gep ( trait_handle, 1 , "v_tmp" ) . unwrap ( ) ;
416- builder. build_store ( v_ptr, st_value) ;
417- let type_hash = builder
418- . build_struct_gep ( trait_handle, 0 , "tp_hash" )
419- . unwrap ( ) ;
420- let hash = st. get_type_code ( ) ;
421- let hash = builder. int_value ( & PriType :: U64 , hash, false ) ;
422- builder. build_store ( type_hash, hash) ;
423- return Ok ( trait_handle) ;
403+ let fnhandle = builder. get_or_insert_fn_handle ( & mthd. borrow ( ) , ctx) ;
404+ let targetftp = f. typenode . get_type ( ctx, builder, true ) . unwrap ( ) ;
405+ let casted =
406+ builder. bitcast ( ctx, fnhandle, & targetftp. borrow ( ) , "fncast_tmp" ) ;
407+ let f_ptr = builder
408+ . build_struct_gep ( trait_handle, f. index , "field_tmp" )
409+ . unwrap ( ) ;
410+ builder. build_store ( f_ptr, casted) ;
411+ }
412+ let st_value = builder. bitcast (
413+ ctx,
414+ st_value,
415+ & PLType :: Pointer ( Arc :: new ( RefCell :: new ( PLType :: Primitive ( PriType :: I64 ) ) ) ) ,
416+ "traitcast_tmp" ,
417+ ) ;
418+ let v_ptr = builder. build_struct_gep ( trait_handle, 1 , "v_tmp" ) . unwrap ( ) ;
419+ builder. build_store ( v_ptr, st_value) ;
420+ let type_hash = builder
421+ . build_struct_gep ( trait_handle, 0 , "tp_hash" )
422+ . unwrap ( ) ;
423+ let hash = st. get_type_code ( ) ;
424+ let hash = builder. int_value ( & PriType :: U64 , hash, false ) ;
425+ builder. build_store ( type_hash, hash) ;
426+ Ok ( trait_handle)
427+ } )
428+ } ) ;
424429 }
425430 #[ allow( clippy:: needless_return) ]
426431 return Err ( mismatch_err ! (
0 commit comments