cgen: interface fix + add more interface tests (#7776)
							parent
							
								
									d5b510df80
								
							
						
					
					
						commit
						82162b8ff8
					
				|  | @ -4196,6 +4196,10 @@ fn (mut g Gen) return_statement(node ast.Return) { | |||
| 			if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() { | ||||
| 				// Automatic Dereference for optional
 | ||||
| 				g.write('*') | ||||
| 				// Fixes returning a mutable receiver with interface as return type
 | ||||
| 				if node.exprs[0] is ast.Ident && !g.is_amp { | ||||
| 					g.write('&') | ||||
| 				} | ||||
| 			} | ||||
| 			for i, expr in node.exprs { | ||||
| 				g.expr(expr) | ||||
|  |  | |||
|  | @ -788,7 +788,9 @@ fn (mut g Gen) call_args(node ast.CallExpr) { | |||
| 				exp_sym := g.table.get_type_symbol(expected_types[i]) | ||||
| 				// exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no])
 | ||||
| 				// styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ)
 | ||||
| 				if exp_sym.kind == .interface_ { | ||||
| 				// NB: the second check avoids casting the interface into itself
 | ||||
| 				// aka avoid 'I__Speaker_to_Interface_Speaker' thing for example
 | ||||
| 				if exp_sym.kind == .interface_ && expected_types[i] != arg.typ { | ||||
| 					g.interface_call(arg.typ, expected_types[i]) | ||||
| 					is_interface = true | ||||
| 				} | ||||
|  |  | |||
|  | @ -188,6 +188,52 @@ fn test_register() { | |||
| interface Speaker2 { | ||||
| 	name() string | ||||
| 	speak() | ||||
| 	return_speaker() Speaker2 | ||||
| 	return_speaker2() ?Speaker2 | ||||
| } | ||||
| 
 | ||||
| struct Boss { | ||||
| mut: | ||||
| 	name string | ||||
| } | ||||
| 
 | ||||
| fn (b Boss) name() string { | ||||
| 	return b.name | ||||
| } | ||||
| 
 | ||||
| fn (b Boss) speak() { | ||||
| 	println("i'm $b.name") | ||||
| } | ||||
| 
 | ||||
| fn (b &Boss) return_speaker() Speaker2 { | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| fn (mut b Boss) return_speaker2() ?Speaker2 { | ||||
| 	if b.name == 'richard' { | ||||
| 		return none | ||||
| 	} | ||||
| 	b.name = 'boss' | ||||
| 	return b | ||||
| } | ||||
| 
 | ||||
| fn return_speaker2(sp Speaker2) Speaker2 { | ||||
| 	s := sp.return_speaker() | ||||
| 	s2 := sp.return_speaker2() or { | ||||
| 		return sp | ||||
| 	} | ||||
| 	s.speak() | ||||
| 	s2.speak() | ||||
| 	return s2 | ||||
| } | ||||
| 
 | ||||
| fn test_interface_returning_interface() { | ||||
| 	mut b := Boss{'bob'} | ||||
| 	assert b.name == 'bob' | ||||
| 	s2 := return_speaker2(b) | ||||
| 	if s2 is Boss { | ||||
| 		assert s2.name == 'boss' | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct Foo { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue