parent
05f0f3e180
commit
2298063129
|
@ -1993,9 +1993,9 @@ fn (t Tree) array_node_attr(nodes []ast.Attr) &Node {
|
||||||
return arr
|
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()
|
mut arr := new_array()
|
||||||
for node in nodes {
|
for _, node in nodes {
|
||||||
arr.add_item(t.scope_struct_field(node))
|
arr.add_item(t.scope_struct_field(node))
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Scope {
|
||||||
pub mut:
|
pub mut:
|
||||||
// mut:
|
// mut:
|
||||||
objects map[string]ScopeObject
|
objects map[string]ScopeObject
|
||||||
struct_fields []ScopeStructField
|
struct_fields map[string]ScopeStructField
|
||||||
parent &Scope
|
parent &Scope
|
||||||
detached_from_parent bool
|
detached_from_parent bool
|
||||||
children []&Scope
|
children []&Scope
|
||||||
|
@ -65,9 +65,10 @@ pub fn (s &Scope) find(name string) ?ScopeObject {
|
||||||
return none
|
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 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 {
|
if field.struct_type == struct_type && field.name == field_name {
|
||||||
return field
|
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) {
|
// selector_expr: name.field_name
|
||||||
for f in s.struct_fields {
|
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 {
|
if f.struct_type == field.struct_type && f.name == field.name {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.struct_fields << field
|
s.struct_fields[name] = field
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut s Scope) register(obj ScopeObject) {
|
pub fn (mut s Scope) register(obj ScopeObject) {
|
||||||
|
@ -211,7 +213,7 @@ pub fn (sc Scope) show(depth int, max_depth int) string {
|
||||||
else {}
|
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'
|
out += '$indent * struct_field: $field.struct_type $field.name - $field.typ\n'
|
||||||
}
|
}
|
||||||
if max_depth == 0 || depth < max_depth - 1 {
|
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)
|
iface.pos)
|
||||||
continue
|
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] {
|
if !efnames_ds_info[f.name] {
|
||||||
efnames_ds_info[f.name] = true
|
efnames_ds_info[f.name] = true
|
||||||
decl_sym.info.fields << f
|
decl_sym.info.fields << f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for m in isym.info.methods {
|
for m in isym_info.methods {
|
||||||
if !emnames_ds_info[m.name] {
|
if !emnames_ds_info[m.name] {
|
||||||
emnames_ds_info[m.name] = true
|
emnames_ds_info[m.name] = true
|
||||||
decl_sym.info.methods << m.new_method_with_receiver_type(decl.typ)
|
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)
|
field_sym := c.table.get_type_symbol(field.typ)
|
||||||
if field_sym.kind in [.sum_type, .interface_] {
|
if field_sym.kind in [.sum_type, .interface_] {
|
||||||
if !prevent_sum_type_unwrapping_once {
|
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()
|
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
|
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
|
smartcasts << field.smartcasts
|
||||||
}
|
}
|
||||||
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
||||||
if !is_mut || expr.is_mut {
|
if !is_mut || expr.is_mut {
|
||||||
smartcasts << to_type
|
smartcasts << to_type
|
||||||
scope.register_struct_field(ast.ScopeStructField{
|
scope.register_struct_field(expr.expr.str(), ast.ScopeStructField{
|
||||||
struct_type: expr.expr_type
|
struct_type: expr.expr_type
|
||||||
name: expr.field_name
|
name: expr.field_name
|
||||||
typ: cur_type
|
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 {
|
} 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
|
is_already_sum_type = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3457,7 +3457,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
if !prevent_sum_type_unwrapping_once {
|
if !prevent_sum_type_unwrapping_once {
|
||||||
// check first if field is sum type because scope searching is expensive
|
// check first if field is sum type because scope searching is expensive
|
||||||
scope := g.file.scope.innermost(node.pos.pos)
|
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() {
|
if field.orig_type.is_ptr() {
|
||||||
sum_type_dot = '->'
|
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()
|
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 {
|
&& mapping_b.source_position is SourcePosition {
|
||||||
if mapping_a.source_position.source_line != mapping_b.source_position.source_line
|
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 {
|
|| 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