checker: fix multi types generic struct init (#10201)

pull/10204/head
yuyi 2021-05-26 00:51:55 +08:00 committed by GitHub
parent 39c376bb5b
commit cf07375d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 1 deletions

View File

@ -3241,7 +3241,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
}
return
}
//
is_decl := assign_stmt.op == .decl_assign
for i, left in assign_stmt.left {
if left is ast.CallExpr {
@ -3283,6 +3283,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
right := if i < assign_stmt.right.len { assign_stmt.right[i] } else { assign_stmt.right[0] }
mut right_type := assign_stmt.right_types[i]
if is_decl {
// check generic struct init and return unwrap generic struct type
if right is ast.StructInit {
if right.typ.has_flag(.generic) {
c.expr(right)
right_type = right.typ
}
}
if right.is_auto_deref_var() {
left_type = c.table.mktyp(right_type.deref())
} else {

View File

@ -0,0 +1,41 @@
struct Response<T> {
result T
}
pub fn send<T>(res T) string {
msg := Response<T>{
result: res
}
return '$msg'
}
struct Foo {}
struct Bar {}
fn test_generics_multi_types_struct_init() {
mut ret := send(Foo{})
println(ret)
assert ret.contains('Response<Foo>{')
assert ret.contains('result: Foo{}')
ret = send(Bar{})
println(ret)
assert ret.contains('Response<Bar>{')
assert ret.contains('result: Bar{}')
ret = send(123)
println(ret)
assert ret.contains('Response<int>{')
assert ret.contains('result: 123')
ret = send('abc')
println(ret)
assert ret.contains('Response<string>{')
assert ret.contains("result: 'abc'")
ret = send(2.22)
println(ret)
assert ret.contains('Response<f64>{')
assert ret.contains('result: 2.22')
}