parent
							
								
									143c3d4bb4
								
							
						
					
					
						commit
						14b7ce0f04
					
				| 
						 | 
				
			
			@ -426,7 +426,7 @@ pub mut:
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
pub struct FnType {
 | 
			
		||||
pub:
 | 
			
		||||
pub mut:
 | 
			
		||||
	is_anon  bool
 | 
			
		||||
	has_decl bool
 | 
			
		||||
	func     Fn
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -508,6 +508,15 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
 | 
			
		|||
 | 
			
		||||
			if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
 | 
			
		||||
				to_set = c.table.mktyp(arg.typ)
 | 
			
		||||
				mut sym := c.table.get_type_symbol(arg.typ)
 | 
			
		||||
				if mut sym.info is ast.FnType {
 | 
			
		||||
					if !sym.info.is_anon {
 | 
			
		||||
						sym.info.func.name = ''
 | 
			
		||||
						idx := c.table.find_or_register_fn_type(c.mod, sym.info.func,
 | 
			
		||||
							true, false)
 | 
			
		||||
						to_set = ast.new_type(idx).derive(arg.typ)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if arg.expr.is_auto_deref_var() {
 | 
			
		||||
					to_set = to_set.deref()
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
fn neg(a int) int {
 | 
			
		||||
	return -a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn normal_v1(func fn (int) int) fn (int) int {
 | 
			
		||||
	assert typeof(func).name == typeof(neg).name
 | 
			
		||||
	return func
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn normal_v2(func fn (int) int) fn (int) int {
 | 
			
		||||
	f := func
 | 
			
		||||
	assert typeof(f).name == typeof(neg).name
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn generic_v1<T>(func T) T {
 | 
			
		||||
	assert T.name == typeof(neg).name
 | 
			
		||||
	assert typeof(func).name == typeof(neg).name
 | 
			
		||||
	return func
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn generic_v2<T>(func T) T {
 | 
			
		||||
	assert T.name == typeof(neg).name
 | 
			
		||||
	f := func
 | 
			
		||||
	assert typeof(f).name == typeof(neg).name
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn mixed_v1<T>(func T) fn (int) int {
 | 
			
		||||
	assert T.name == typeof(neg).name
 | 
			
		||||
	assert typeof(func).name == typeof(neg).name
 | 
			
		||||
	return func
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn mixed_v2<T>(func T) fn (int) int {
 | 
			
		||||
	assert T.name == typeof(neg).name
 | 
			
		||||
	f := func
 | 
			
		||||
	assert typeof(f).name == typeof(neg).name
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_generics_with_generics_fn_return_type() {
 | 
			
		||||
	mut f := neg
 | 
			
		||||
	assert f(1) == -1
 | 
			
		||||
 | 
			
		||||
	f = normal_v1(neg)
 | 
			
		||||
	assert f(2) == -2
 | 
			
		||||
	f = normal_v2(neg)
 | 
			
		||||
	assert f(3) == -3
 | 
			
		||||
 | 
			
		||||
	f = generic_v1(neg)
 | 
			
		||||
	assert f(4) == -4
 | 
			
		||||
	f = generic_v2(neg)
 | 
			
		||||
	assert f(5) == -5
 | 
			
		||||
 | 
			
		||||
	f = mixed_v1(neg)
 | 
			
		||||
	assert f(6) == -6
 | 
			
		||||
	f = mixed_v2(neg)
 | 
			
		||||
	assert f(7) == -7
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue