| 1 | // declare interface |
| 2 | interface MyInterface { |
| 3 | val() int |
| 4 | } |
| 5 | |
| 6 | // define struct type |
| 7 | struct St { |
| 8 | mut: |
| 9 | n int |
| 10 | } |
| 11 | |
| 12 | // make the struct type implement the interface |
| 13 | fn (x St) val() int { |
| 14 | return x.n |
| 15 | } |
| 16 | |
| 17 | fn overwrite_stack() f64 { |
| 18 | a := 12.5 |
| 19 | b := 3.5 |
| 20 | c := a + b |
| 21 | return c |
| 22 | } |
| 23 | |
| 24 | // nothing special so far, but now some functions that return an interfaces |
| 25 | // these used to cause memory corruptions, but work with this PR: |
| 26 | fn gen_interface() MyInterface { |
| 27 | x := St{ |
| 28 | n: -123 |
| 29 | } // `x`will be allocated on heap |
| 30 | return x // because an interface object is returned here that contains the address of x |
| 31 | } |
| 32 | |
| 33 | fn return_interface(x St) MyInterface { |
| 34 | // x will be copied to stack (requires #10528) |
| 35 | return x // because it's address is returned inside the interface |
| 36 | } |
| 37 | |
| 38 | fn test_gen_interface() { |
| 39 | i1 := gen_interface() |
| 40 | d := overwrite_stack() |
| 41 | assert i1.val() == -123 |
| 42 | assert d == 16.0 |
| 43 | } |
| 44 | |
| 45 | fn test_convert_to_interface() { |
| 46 | x := St{ |
| 47 | n: 5 |
| 48 | } |
| 49 | i2 := return_interface(x) |
| 50 | d := overwrite_stack() |
| 51 | assert i2.val() == 5 |
| 52 | assert d == 16.0 |
| 53 | } |
| 54 | |