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`
 | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ vlib/v/checker/tests/is_type_invalid.vv:14:12: error: `IoS` has no variant `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 { | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ vlib/v/checker/tests/match_invalid_type.vv:4:2: error: match must be exhaustive | |||
|       |     ~~~~~~~~~~~~~~ | ||||
|     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 { | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| vlib/v/checker/tests/unimplemented_interface_a.vv:10:6: error: `Cat` doesn't implement method `name` | ||||
| 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