// #target: macos-x64
module test;
import std::io;

alias Callback1 = fn double(double x);
alias Callback2 = fn int(int y);

macro test2(y)
{
	var $Type = $typeof(y);
	return fn $Type($typeof(y) x) { return x * x; };
}

macro test($Type)
{
	$Type z = fn (x) { return x * x; };
	return z;
}

fn void main()
{
	io::printfn("val: %d", test(Callback2)(3));
	io::printfn("val: %s", test(Callback1)(3.3));
	io::printfn("val: %s", test(Callback1)(3.3));
	io::printfn("val: %d", test2(1)(3));
	io::printfn("val: %d", test2(1)(3));
	io::printfn("val: %s", test2(1.0)(3.3));
}

/* #expect: test.ll

  store ptr @"test.test$lambda1", ptr %z, align 8
  %1 = call i32 %0(i32 3)
  store ptr @"test.test$lambda2", ptr %z2, align 8
  %6 = call double %5(double 3.300000e+00)
  store ptr @"test.test$lambda2", ptr %z6, align 8
  %11 = call double %10(double 3.300000e+00)
  %15 = call i32 @"test.test2$lambda3"(i32 3)
 %19 = call i32 @"test.test2$lambda3"(i32 3)
   %23 = call double @"test.test2$lambda4"(double 3.300000e+00)

define internal i32 @"test.test$lambda1"(i32 %0) #0 {
define internal double @"test.test$lambda2"(double %0) #0 {
define internal i32 @"test.test2$lambda3"(i32 %0) #0 {
define internal double @"test.test2$lambda4"(double %0) #0 {
