checker/cgen: fix calling struct field with fn type
							parent
							
								
									da28bc7026
								
							
						
					
					
						commit
						fde83aff0b
					
				| 
						 | 
					@ -346,6 +346,17 @@ pub fn (c mut Checker) call_method(call_expr mut ast.CallExpr) table.Type {
 | 
				
			||||||
		call_expr.return_type = table.string_type
 | 
							call_expr.return_type = table.string_type
 | 
				
			||||||
		return table.string_type
 | 
							return table.string_type
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// call struct field fn type
 | 
				
			||||||
 | 
						// TODO: can we use SelectorExpr for all?
 | 
				
			||||||
 | 
						if field := c.table.struct_find_field(left_type_sym, method_name) {
 | 
				
			||||||
 | 
							field_type_sym := c.table.get_type_symbol(field.typ)
 | 
				
			||||||
 | 
							if field_type_sym.kind == .function {
 | 
				
			||||||
 | 
								call_expr.is_method = false
 | 
				
			||||||
 | 
								info := field_type_sym.info as table.FnType
 | 
				
			||||||
 | 
								call_expr.return_type = info.func.return_type
 | 
				
			||||||
 | 
								return info.func.return_type
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	c.error('unknown method: ${left_type_sym.name}.$method_name', call_expr.pos)
 | 
						c.error('unknown method: ${left_type_sym.name}.$method_name', call_expr.pos)
 | 
				
			||||||
	return table.void_type
 | 
						return table.void_type
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,6 +242,19 @@ fn (g mut Gen) method_call(node ast.CallExpr) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn (g mut Gen) fn_call(node ast.CallExpr) {
 | 
					fn (g mut Gen) fn_call(node ast.CallExpr) {
 | 
				
			||||||
 | 
						// call struct field with fn type
 | 
				
			||||||
 | 
						// TODO: test node.left instead
 | 
				
			||||||
 | 
						// left & left_type will be `x` and `x type` in `x.fieldfn()`
 | 
				
			||||||
 | 
						// will be `0` for `foo()`
 | 
				
			||||||
 | 
						if node.left_type != 0 {
 | 
				
			||||||
 | 
							g.expr(node.left)
 | 
				
			||||||
 | 
							if table.type_is_ptr(node.left_type) {
 | 
				
			||||||
 | 
								g.write('->')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								g.write('.')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	mut name := node.name
 | 
						mut name := node.name
 | 
				
			||||||
	is_print := name == 'println' || name == 'print'
 | 
						is_print := name == 'println' || name == 'print'
 | 
				
			||||||
	print_method := if name == 'println' { 'println' } else { 'print' }
 | 
						print_method := if name == 'println' { 'println' } else { 'print' }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,7 +153,11 @@ struct MySt {
 | 
				
			||||||
fn test_fn_type_call() {
 | 
					fn test_fn_type_call() {
 | 
				
			||||||
    mut arr := []MyFn
 | 
					    mut arr := []MyFn
 | 
				
			||||||
    arr << MyFn(test)
 | 
					    arr << MyFn(test)
 | 
				
			||||||
    assert arr[0](10) == 1010
 | 
						// TODO: `arr[0](10)`
 | 
				
			||||||
 | 
						// assert arr[0](10) == 1010
 | 
				
			||||||
 | 
						x1 := arr[0]
 | 
				
			||||||
 | 
						x2 := x1(10)
 | 
				
			||||||
 | 
						assert x2 == 1010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    st := MySt{f:test}
 | 
					    st := MySt{f:test}
 | 
				
			||||||
    assert st.f(10) == 1010
 | 
					    assert st.f(10) == 1010
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue