@@ -1314,3 +1314,53 @@ fn gc_heap_oom() -> Result<()> {
1314
1314
}
1315
1315
Ok ( ( ) )
1316
1316
}
1317
+
1318
+ #[ test]
1319
+ #[ cfg_attr( miri, ignore) ]
1320
+ fn issue_10772 ( ) -> Result < ( ) > {
1321
+ let mut store = crate :: gc_store ( ) ?;
1322
+ let engine = store. engine ( ) . clone ( ) ;
1323
+
1324
+ let module = Module :: new (
1325
+ & engine,
1326
+ r#"
1327
+ (module
1328
+ (type $empty (struct))
1329
+ (type $tuple-concrete (struct (field (ref $empty))))
1330
+ (type $tuple-abstract (struct (field (ref struct))))
1331
+ (func (export "abstract") (param $t (ref $tuple-abstract))
1332
+ (drop (ref.cast (ref $tuple-concrete) (local.get $t)))
1333
+ )
1334
+ )
1335
+ "# ,
1336
+ ) ?;
1337
+
1338
+ let linker = Linker :: new ( & engine) ;
1339
+
1340
+ let instance = linker. instantiate ( & mut store, & module) ?;
1341
+ let abstract_ = instance. get_func ( & mut store, "abstract" ) . unwrap ( ) ;
1342
+ let empty_pre = StructRefPre :: new ( & mut store, StructType :: new ( & engine, [ ] ) ?) ;
1343
+ let empty_struct = StructRef :: new ( & mut store, & empty_pre, & [ ] ) ?;
1344
+ let tuple_pre = StructRefPre :: new (
1345
+ & mut store,
1346
+ StructType :: new (
1347
+ & engine,
1348
+ [ FieldType :: new (
1349
+ Mutability :: Const ,
1350
+ StorageType :: ValType ( ValType :: Ref ( RefType :: new ( false , HeapType :: Struct ) ) ) ,
1351
+ ) ] ,
1352
+ ) ?,
1353
+ ) ;
1354
+ let tuple_struct = StructRef :: new ( & mut store, & tuple_pre, & [ empty_struct. into ( ) ] ) ?;
1355
+ let tuple_any = Val :: from ( tuple_struct) ;
1356
+
1357
+ match abstract_. call ( store, & [ tuple_any] , & mut [ ] ) {
1358
+ Ok ( ( ) ) => panic ! ( "should have trapped on cast failure" ) ,
1359
+ Err ( e) => {
1360
+ let trap = e. downcast :: < Trap > ( ) . expect ( "should fail with a trap" ) ;
1361
+ assert_eq ! ( trap, Trap :: CastFailure ) ;
1362
+ }
1363
+ }
1364
+
1365
+ Ok ( ( ) )
1366
+ }
0 commit comments