cgen: fix `x.interface_field = value_implementing_interface` (closes #7620)

pull/7622/head
Delyan Angelov 2020-12-27 19:12:39 +02:00
parent 8872b0a23b
commit df61cf246b
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
5 changed files with 41 additions and 9 deletions

View File

@ -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`

View File

@ -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 | }

View File

@ -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 | }

View File

@ -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{})
| ~~~~~

View File

@ -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'
}