cgen: fix cast to generic interface (#14708)

master
yuyi 2022-06-07 13:32:25 +08:00 committed by GitHub
parent 73b59c7b16
commit 7780f56c31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 8 deletions

View File

@ -2126,8 +2126,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
g.expr(expr) g.expr(expr)
return return
} }
if exp_sym.info is ast.Interface && got_type.idx() != expected_type.idx() if got_sym.info !is ast.Interface && exp_sym.info is ast.Interface
&& !expected_type.has_flag(.optional) { && got_type.idx() != expected_type.idx() && !expected_type.has_flag(.optional) {
if expr is ast.StructInit && !got_type.is_ptr() { if expr is ast.StructInit && !got_type.is_ptr() {
g.inside_cast_in_heap++ g.inside_cast_in_heap++
got_styp := g.cc_type(got_type.ref(), true) got_styp := g.cc_type(got_type.ref(), true)

View File

@ -13,7 +13,7 @@ enum NodeType {
struct EnumTypeFactory {} struct EnumTypeFactory {}
fn (f EnumTypeFactory) get_type(type_name string) NodeType { fn (f &EnumTypeFactory) get_type(type_name string) NodeType {
return match type_name { return match type_name {
'expression' { NodeType.expression } 'expression' { NodeType.expression }
'statement' { NodeType.statement } 'statement' { NodeType.statement }
@ -22,24 +22,34 @@ fn (f EnumTypeFactory) get_type(type_name string) NodeType {
} }
} }
struct RawNode {
type_name string
}
struct Node<T> { struct Node<T> {
factory TypeFactory<T> factory TypeFactory<T>
type_name NodeType type_name NodeType
raw_node RawNode
} }
fn new_node<T>(type_name string, factory TypeFactory<T>) Node<T> { fn new_node<T>(factory TypeFactory<T>, raw_node RawNode) ?Node<T> {
return Node<T>{ return Node<T>{
factory: factory factory: factory
type_name: factory.get_type(type_name) type_name: factory.get_type(raw_node.type_name)
raw_node: raw_node
} }
} }
fn test_generic_interface_with_non_generic_method() { fn program<T>(factory TypeFactory<T>) ? {
root1 := new_node<NodeType>('literal', EnumTypeFactory{}) root1 := new_node<T>(factory, RawNode{'literal'})?
println(root1) println(root1)
assert root1.type_name == .literal assert root1.type_name == .literal
root2 := new_node<NodeType>('expression', root1.factory) root2 := new_node<T>(root1.factory, RawNode{'expression'})?
println(root2) println(root2)
assert root2.type_name == .expression assert root2.type_name == .expression
} }
fn test_generic_interface_with_non_generic_method() ? {
program<NodeType>(&EnumTypeFactory{})?
}