authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-11-22 02:22:16+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-11-22 03:04:55+01:00
log41b37712ea0af660365b1638b9b7f742990c175a
treeb31f96284ec3059fc4b27e307b03ac91fe910995
parent96e5f661bd34d98bba89bcb70c9db059aaf38641

sema: function (pointer) in-memory coercion


1 files changed, 55 insertions(+), 1 deletions(-)

src/Sema.zig+55-1
......@@ -12435,16 +12435,70 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target:
1243512435 return coerceInMemoryAllowedPtrs(dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target);
1243612436 }
1243712437
12438 // Functions
12439 if (dest_ty.zigTypeTag() == .Fn and src_ty.zigTypeTag() == .Fn) {
12440 return coerceInMemoryAllowedFns(dest_ty, src_ty, target);
12441 }
12442
1243812443 // TODO: arrays
1243912444 // TODO: non-pointer-like optionals
1244012445 // TODO: error unions
1244112446 // TODO: error sets
12442 // TODO: functions
1244312447 // TODO: vectors
1244412448
1244512449 return .no_match;
1244612450}
1244712451
12452fn coerceInMemoryAllowedFns(
12453 dest_ty: Type,
12454 src_ty: Type,
12455 target: std.Target,
12456) InMemoryCoercionResult {
12457 const dest_info = dest_ty.fnInfo();
12458 const src_info = src_ty.fnInfo();
12459
12460 if (dest_info.is_var_args != src_info.is_var_args) {
12461 return .no_match;
12462 }
12463
12464 if (dest_info.is_generic != src_info.is_generic) {
12465 return .no_match;
12466 }
12467
12468 if (!src_info.return_type.isNoReturn()) {
12469 const rt = coerceInMemoryAllowed(dest_info.return_type, src_info.return_type, false, target);
12470 if (rt == .no_match) {
12471 return rt;
12472 }
12473 }
12474
12475 if (dest_info.param_types.len != src_info.param_types.len) {
12476 return .no_match;
12477 }
12478
12479 for (dest_info.param_types) |dest_param_ty, i| {
12480 const src_param_ty = src_info.param_types[i];
12481
12482 if (dest_info.comptime_params[i] != src_info.comptime_params[i]) {
12483 return .no_match;
12484 }
12485
12486 // TODO: nolias
12487
12488 // Note: Cast direction is reversed here.
12489 const param = coerceInMemoryAllowed(src_param_ty, dest_param_ty, false, target);
12490 if (param == .no_match) {
12491 return param;
12492 }
12493 }
12494
12495 if (dest_info.cc != src_info.cc) {
12496 return .no_match;
12497 }
12498
12499 return .ok;
12500}
12501
1244812502fn coerceInMemoryAllowedPtrs(
1244912503 dest_ty: Type,
1245012504 src_ty: Type,