@@ -135,7 +135,8 @@ struct Crystal::TypeDeclarationProcessor
135
135
# Process class variables
136
136
type_guess_visitor.class_vars.each do |owner , vars |
137
137
vars.each do |name , info |
138
- declare_meta_type_var(owner.class_vars, owner, name, info)
138
+ # No need to freeze its type because it is frozen by check_class_var_errors
139
+ declare_meta_type_var(owner.class_vars, owner, name, info, freeze_type: false )
139
140
end
140
141
end
141
142
@@ -155,7 +156,7 @@ struct Crystal::TypeDeclarationProcessor
155
156
{node, self }
156
157
end
157
158
158
- private def declare_meta_type_var (vars , owner , name , type : Type , location : Location ? = nil , instance_var = false )
159
+ private def declare_meta_type_var (vars , owner , name , type : Type , location : Location ? = nil , instance_var = false , freeze_type = true )
159
160
if instance_var && location && ! owner.allows_instance_vars?
160
161
raise_cant_declare_instance_var(owner, location)
161
162
end
@@ -174,24 +175,24 @@ struct Crystal::TypeDeclarationProcessor
174
175
var.owner = owner
175
176
var.type = type
176
177
var.bind_to(var)
177
- var.freeze_type = type
178
+ var.freeze_type = type if freeze_type
178
179
var.location = location
179
180
vars[name] = var
180
181
var
181
182
end
182
183
183
- private def declare_meta_type_var (vars , owner , name , info : TypeGuessVisitor ::TypeInfo )
184
+ private def declare_meta_type_var (vars , owner , name , info : TypeGuessVisitor ::TypeInfo , freeze_type = true )
184
185
type = info.type
185
186
type = Type .merge!(type , @program .nil ) unless info.outside_def
186
- declare_meta_type_var(vars, owner, name, type )
187
+ declare_meta_type_var(vars, owner, name, type , freeze_type: freeze_type )
187
188
end
188
189
189
- private def declare_meta_type_var (vars , owner , name , info : TypeDeclarationWithLocation , instance_var = false , check_nilable = true )
190
+ private def declare_meta_type_var (vars , owner , name , info : TypeDeclarationWithLocation , instance_var = false , check_nilable = true , freeze_type = true )
190
191
if instance_var && ! owner.allows_instance_vars?
191
192
raise_cant_declare_instance_var(owner, info.location)
192
193
end
193
194
194
- var = declare_meta_type_var(vars, owner, name, info.type.as(Type ), info.location)
195
+ var = declare_meta_type_var(vars, owner, name, info.type.as(Type ), info.location, freeze_type: freeze_type )
195
196
var.location = info.location
196
197
197
198
# Check if var is uninitialized
@@ -646,10 +647,16 @@ struct Crystal::TypeDeclarationProcessor
646
647
ancestor_class_var = ancestor.lookup_class_var?(name)
647
648
next unless ancestor_class_var
648
649
650
+ if owner_class_var.type.implements?(ancestor_class_var.type)
651
+ owner_class_var.type = ancestor_class_var.type
652
+ end
653
+
649
654
if owner_class_var.type != ancestor_class_var.type
650
655
raise TypeException .new(" class variable '#{ name } ' of #{ owner } is already defined as #{ ancestor_class_var.type } in #{ ancestor } " , info.location)
651
656
end
652
657
end
658
+
659
+ owner_class_var.freeze_type = owner_class_var.type
653
660
end
654
661
end
655
662
end
0 commit comments