parent
05f0f3e180
commit
2298063129
|
@ -1993,9 +1993,9 @@ fn (t Tree) array_node_attr(nodes []ast.Attr) &Node {
|
|||
return arr
|
||||
}
|
||||
|
||||
fn (t Tree) array_node_scope_struct_field(nodes []ast.ScopeStructField) &Node {
|
||||
fn (t Tree) array_node_scope_struct_field(nodes map[string]ast.ScopeStructField) &Node {
|
||||
mut arr := new_array()
|
||||
for node in nodes {
|
||||
for _, node in nodes {
|
||||
arr.add_item(t.scope_struct_field(node))
|
||||
}
|
||||
return arr
|
||||
|
|
|
@ -8,7 +8,7 @@ pub struct Scope {
|
|||
pub mut:
|
||||
// mut:
|
||||
objects map[string]ScopeObject
|
||||
struct_fields []ScopeStructField
|
||||
struct_fields map[string]ScopeStructField
|
||||
parent &Scope
|
||||
detached_from_parent bool
|
||||
children []&Scope
|
||||
|
@ -65,9 +65,10 @@ pub fn (s &Scope) find(name string) ?ScopeObject {
|
|||
return none
|
||||
}
|
||||
|
||||
pub fn (s &Scope) find_struct_field(struct_type Type, field_name string) ?ScopeStructField {
|
||||
// selector_expr: name.field_name
|
||||
pub fn (s &Scope) find_struct_field(name string, struct_type Type, field_name string) ?ScopeStructField {
|
||||
for sc := s; true; sc = sc.parent {
|
||||
for field in sc.struct_fields {
|
||||
if field := sc.struct_fields[name] {
|
||||
if field.struct_type == struct_type && field.name == field_name {
|
||||
return field
|
||||
}
|
||||
|
@ -128,13 +129,14 @@ pub fn (mut s Scope) update_var_type(name string, typ Type) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn (mut s Scope) register_struct_field(field ScopeStructField) {
|
||||
for f in s.struct_fields {
|
||||
// selector_expr: name.field_name
|
||||
pub fn (mut s Scope) register_struct_field(name string, field ScopeStructField) {
|
||||
if f := s.struct_fields[name] {
|
||||
if f.struct_type == field.struct_type && f.name == field.name {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.struct_fields << field
|
||||
s.struct_fields[name] = field
|
||||
}
|
||||
|
||||
pub fn (mut s Scope) register(obj ScopeObject) {
|
||||
|
@ -211,7 +213,7 @@ pub fn (sc Scope) show(depth int, max_depth int) string {
|
|||
else {}
|
||||
}
|
||||
}
|
||||
for field in sc.struct_fields {
|
||||
for _, field in sc.struct_fields {
|
||||
out += '$indent * struct_field: $field.struct_type $field.name - $field.typ\n'
|
||||
}
|
||||
if max_depth == 0 || depth < max_depth - 1 {
|
||||
|
|
|
@ -442,13 +442,14 @@ pub fn (mut c Checker) interface_decl(mut decl ast.InterfaceDecl) {
|
|||
iface.pos)
|
||||
continue
|
||||
}
|
||||
for f in isym.info.fields {
|
||||
isym_info := isym.info as ast.Interface
|
||||
for f in isym_info.fields {
|
||||
if !efnames_ds_info[f.name] {
|
||||
efnames_ds_info[f.name] = true
|
||||
decl_sym.info.fields << f
|
||||
}
|
||||
}
|
||||
for m in isym.info.methods {
|
||||
for m in isym_info.methods {
|
||||
if !emnames_ds_info[m.name] {
|
||||
emnames_ds_info[m.name] = true
|
||||
decl_sym.info.methods << m.new_method_with_receiver_type(decl.typ)
|
||||
|
@ -2983,7 +2984,9 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||
field_sym := c.table.get_type_symbol(field.typ)
|
||||
if field_sym.kind in [.sum_type, .interface_] {
|
||||
if !prevent_sum_type_unwrapping_once {
|
||||
if scope_field := node.scope.find_struct_field(utyp, field_name) {
|
||||
if scope_field := node.scope.find_struct_field(node.expr.str(), utyp,
|
||||
field_name)
|
||||
{
|
||||
return scope_field.smartcasts.last()
|
||||
}
|
||||
}
|
||||
|
@ -5764,13 +5767,13 @@ fn (c Checker) smartcast(expr ast.Expr, cur_type ast.Type, to_type_ ast.Type, mu
|
|||
orig_type = field.typ
|
||||
}
|
||||
}
|
||||
if field := scope.find_struct_field(expr.expr_type, expr.field_name) {
|
||||
if field := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name) {
|
||||
smartcasts << field.smartcasts
|
||||
}
|
||||
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
||||
if !is_mut || expr.is_mut {
|
||||
smartcasts << to_type
|
||||
scope.register_struct_field(ast.ScopeStructField{
|
||||
scope.register_struct_field(expr.expr.str(), ast.ScopeStructField{
|
||||
struct_type: expr.expr_type
|
||||
name: expr.field_name
|
||||
typ: cur_type
|
||||
|
|
|
@ -1842,7 +1842,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
|||
}
|
||||
}
|
||||
} else if expr is ast.SelectorExpr {
|
||||
if _ := scope.find_struct_field(expr.expr_type, expr.field_name) {
|
||||
if _ := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name) {
|
||||
is_already_sum_type = true
|
||||
}
|
||||
}
|
||||
|
@ -3457,7 +3457,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
|||
if !prevent_sum_type_unwrapping_once {
|
||||
// check first if field is sum type because scope searching is expensive
|
||||
scope := g.file.scope.innermost(node.pos.pos)
|
||||
if field := scope.find_struct_field(node.expr_type, node.field_name) {
|
||||
if field := scope.find_struct_field(node.expr.str(), node.expr_type, node.field_name) {
|
||||
if field.orig_type.is_ptr() {
|
||||
sum_type_dot = '->'
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ fn compare_by_generated_positions_inflated(mapping_a Mapping, mapping_b Mapping)
|
|||
}
|
||||
|
||||
if mapping_a.source_position.type_name() == mapping_b.source_position.type_name()
|
||||
&& mapping_a.source_position is SourcePosition
|
||||
&& mapping_b.source_position is SourcePosition {
|
||||
if mapping_a.source_position.source_line != mapping_b.source_position.source_line
|
||||
|| mapping_a.source_position.source_column != mapping_b.source_position.source_column {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
struct Empty {}
|
||||
|
||||
type Text = string
|
||||
|
||||
type SumTypeB = Empty | Text
|
||||
|
||||
struct DataStruct {
|
||||
y SumTypeB
|
||||
}
|
||||
|
||||
fn isok(a DataStruct, b DataStruct) bool {
|
||||
if a.y is Text {
|
||||
if b.y is Text {
|
||||
return a.y == b.y
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fn test_nested_if_smartcast_selector_exprs() {
|
||||
a := DataStruct{
|
||||
y: Text('da')
|
||||
}
|
||||
b := DataStruct{
|
||||
y: Text('da')
|
||||
}
|
||||
assert isok(a, b)
|
||||
}
|
Loading…
Reference in New Issue