cgen: fix `x.interface_field = value_implementing_interface` (closes #7620)
parent
8872b0a23b
commit
df61cf246b
|
@ -1720,7 +1720,8 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok
|
|||
}
|
||||
continue
|
||||
}
|
||||
c.error("`$styp` doesn't implement method `$imethod.name`", pos)
|
||||
c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`",
|
||||
pos)
|
||||
}
|
||||
if mut inter_sym.info is table.Interface {
|
||||
if typ !in inter_sym.info.types && typ_sym.kind != .interface_ {
|
||||
|
@ -2370,6 +2371,9 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
c.error('cannot assign to `$left`: $err', right.position())
|
||||
}
|
||||
}
|
||||
if left_sym.kind == .interface_ {
|
||||
c.type_implements(right_type, left_type, right.position())
|
||||
}
|
||||
}
|
||||
// this needs to run after the assign stmt left exprs have been run through checker so that ident.obj is set
|
||||
// Check `x := &y` and `mut x := <-ch`
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
vlib/v/checker/tests/is_type_invalid.vv:14:12: error: `IoS` has no variant `byte`
|
||||
12 |
|
||||
12 |
|
||||
13 | fn main() {
|
||||
14 | if IoS(1) is byte {
|
||||
| ~~
|
||||
15 | println('not cool')
|
||||
16 | }
|
||||
vlib/v/checker/tests/is_type_invalid.vv:18:2: error: `Cat` doesn't implement method `speak`
|
||||
vlib/v/checker/tests/is_type_invalid.vv:18:2: error: `Cat` doesn't implement method `speak` of interface `Animal`
|
||||
16 | }
|
||||
17 | a := Animal(Dog{})
|
||||
18 | if a is Cat {
|
||||
| ~~~~~~~~~~~
|
||||
19 | println('not cool either')
|
||||
20 | }
|
||||
20 | }
|
||||
|
|
|
@ -6,16 +6,16 @@ vlib/v/checker/tests/match_invalid_type.vv:5:3: error: `IoS` has no variant `byt
|
|||
6 | println('not cool')
|
||||
7 | }
|
||||
vlib/v/checker/tests/match_invalid_type.vv:4:2: error: match must be exhaustive (add match branches for: `int`, `string` or `else {}` at the end)
|
||||
2 |
|
||||
2 |
|
||||
3 | fn sum() {
|
||||
4 | match IoS(1) {
|
||||
| ~~~~~~~~~~~~~~
|
||||
5 | byte {
|
||||
6 | println('not cool')
|
||||
vlib/v/checker/tests/match_invalid_type.vv:24:3: error: `Cat` doesn't implement method `speak`
|
||||
vlib/v/checker/tests/match_invalid_type.vv:24:3: error: `Cat` doesn't implement method `speak` of interface `Animal`
|
||||
22 | a := Animal(Dog{})
|
||||
23 | match a {
|
||||
24 | Cat {
|
||||
| ~~~
|
||||
25 | println('not cool either')
|
||||
26 | }
|
||||
26 | }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
vlib/v/checker/tests/unimplemented_interface_a.vv:10:6: error: `Cat` doesn't implement method `name`
|
||||
8 |
|
||||
vlib/v/checker/tests/unimplemented_interface_a.vv:10:6: error: `Cat` doesn't implement method `name` of interface `Animal`
|
||||
8 |
|
||||
9 | fn main() {
|
||||
10 | foo(Cat{})
|
||||
| ~~~~~
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
interface Planet {
|
||||
name() string
|
||||
}
|
||||
|
||||
struct Moon {}
|
||||
|
||||
fn (moon Moon) name() string {
|
||||
return 'moon'
|
||||
}
|
||||
|
||||
struct Mars {}
|
||||
|
||||
fn (moon Mars) name() string {
|
||||
return 'mars'
|
||||
}
|
||||
|
||||
struct AnyPlanet {
|
||||
mut:
|
||||
planet Planet
|
||||
}
|
||||
|
||||
fn test_a_struct_implementing_an_interface_can_be_assigned_without_explicit_casts() {
|
||||
mut anyplanet := AnyPlanet{}
|
||||
anyplanet.planet = Moon{}
|
||||
assert anyplanet.planet.name() == 'moon'
|
||||
anyplanet.planet = Mars{}
|
||||
assert anyplanet.planet.name() == 'mars'
|
||||
}
|
Loading…
Reference in New Issue