mt-lang 0.3.24 → 0.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
- data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
- data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
- data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
- data/lib/milk_tea/core/bindings.rb +4 -9
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
- data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
- data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
- data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
- data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
- data/lib/milk_tea/core/c_backend/statements.rb +20 -20
- data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
- data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
- data/lib/milk_tea/core/c_backend.rb +3 -3
- data/lib/milk_tea/core/compile_time.rb +41 -70
- data/lib/milk_tea/core/control_flow/builder.rb +3 -3
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
- data/lib/milk_tea/core/control_flow/graph.rb +1 -1
- data/lib/milk_tea/core/control_flow/termination.rb +1 -1
- data/lib/milk_tea/core/cst.rb +16 -0
- data/lib/milk_tea/core/flow_scope.rb +13 -0
- data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
- data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
- data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
- data/lib/milk_tea/core/lexer/indentation.rb +4 -4
- data/lib/milk_tea/core/lexer/numbers.rb +1 -1
- data/lib/milk_tea/core/lexer/strings.rb +4 -4
- data/lib/milk_tea/core/lexer/symbols.rb +3 -3
- data/lib/milk_tea/core/lexer/trivia.rb +4 -4
- data/lib/milk_tea/core/lexer.rb +17 -17
- data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
- data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
- data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
- data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
- data/lib/milk_tea/core/lowering/block.rb +982 -980
- data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
- data/lib/milk_tea/core/lowering/declarations.rb +175 -173
- data/lib/milk_tea/core/lowering/dyn.rb +171 -169
- data/lib/milk_tea/core/lowering/events.rb +946 -944
- data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
- data/lib/milk_tea/core/lowering/functions.rb +186 -184
- data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
- data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
- data/lib/milk_tea/core/lowering/proc.rb +355 -353
- data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
- data/lib/milk_tea/core/lowering/scans.rb +162 -168
- data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
- data/lib/milk_tea/core/lowering/utils.rb +964 -963
- data/lib/milk_tea/core/lowering.rb +22 -22
- data/lib/milk_tea/core/module_binder.rb +1 -1
- data/lib/milk_tea/core/module_loader.rb +2 -2
- data/lib/milk_tea/core/parser/attributes.rb +1 -1
- data/lib/milk_tea/core/parser/blocks.rb +2 -2
- data/lib/milk_tea/core/parser/declarations.rb +15 -15
- data/lib/milk_tea/core/parser/expressions.rb +20 -20
- data/lib/milk_tea/core/parser/recovery.rb +1 -1
- data/lib/milk_tea/core/parser/statements.rb +3 -3
- data/lib/milk_tea/core/parser/types.rb +4 -4
- data/lib/milk_tea/core/parser.rb +39 -21
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
- data/lib/milk_tea/core/types/layout.rb +3 -1
- data/lib/milk_tea/core/types/visitor.rb +351 -349
- data/lib/milk_tea/core.rb +0 -2
- data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
- data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
- data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
- data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
- data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
- data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
- data/lib/milk_tea/tooling/cli.rb +22 -34
- data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
- metadata +4 -5
- data/lib/milk_tea/core/cst_builder.rb +0 -19
- data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
- data/lib/milk_tea/core/token_stream.rb +0 -30
|
@@ -3,438 +3,440 @@
|
|
|
3
3
|
require_relative "predicates"
|
|
4
4
|
|
|
5
5
|
module MilkTea
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
module Types
|
|
7
|
+
class Visitor
|
|
8
|
+
def initialize
|
|
9
|
+
@visited = {}
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def visit(type)
|
|
13
|
+
return if type.nil?
|
|
14
|
+
return if @visited[type.object_id]
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def dispatch(type)
|
|
20
|
-
case type
|
|
21
|
-
when Types::Nullable then visit_nullable(type)
|
|
22
|
-
when Types::GenericInstance then visit_generic_instance(type)
|
|
23
|
-
when Types::Span then visit_span(type)
|
|
24
|
-
when Types::Task then visit_task(type)
|
|
25
|
-
when Types::GenericStructDefinition then visit_generic_struct_definition(type)
|
|
26
|
-
when Types::GenericVariantDefinition then visit_generic_variant_definition(type)
|
|
27
|
-
when Types::Struct then visit_struct(type)
|
|
28
|
-
when Types::Union then visit_union(type)
|
|
29
|
-
when Types::StructInstance then visit_struct_instance(type)
|
|
30
|
-
when Types::Variant then visit_variant(type)
|
|
31
|
-
when Types::VariantInstance then visit_variant_instance(type)
|
|
32
|
-
when Types::VariantArmPayload then visit_variant_arm_payload(type)
|
|
33
|
-
when Types::Proc then visit_proc(type)
|
|
34
|
-
when Types::Function then visit_function(type)
|
|
35
|
-
when Types::Parameter then visit_parameter(type)
|
|
36
|
-
when Types::TypeVar then visit_type_var(type)
|
|
37
|
-
when Types::Null then visit_null(type)
|
|
38
|
-
when Types::Tuple then visit_tuple(type)
|
|
39
|
-
when Types::Dyn then visit_dyn(type)
|
|
40
|
-
when Types::SoA then visit_soa(type)
|
|
41
|
-
when Types::Simd then visit_simd(type)
|
|
42
|
-
when Types::Event then visit_event(type)
|
|
43
|
-
when Types::LifetimeRef then visit_lifetime_ref(type)
|
|
44
|
-
else visit_default(type)
|
|
16
|
+
@visited[type.object_id] = true
|
|
17
|
+
dispatch(type)
|
|
45
18
|
end
|
|
46
|
-
end
|
|
47
19
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
20
|
+
def dispatch(type)
|
|
21
|
+
case type
|
|
22
|
+
when Types::Nullable then visit_nullable(type)
|
|
23
|
+
when Types::GenericInstance then visit_generic_instance(type)
|
|
24
|
+
when Types::Span then visit_span(type)
|
|
25
|
+
when Types::Task then visit_task(type)
|
|
26
|
+
when Types::GenericStructDefinition then visit_generic_struct_definition(type)
|
|
27
|
+
when Types::GenericVariantDefinition then visit_generic_variant_definition(type)
|
|
28
|
+
when Types::Struct then visit_struct(type)
|
|
29
|
+
when Types::Union then visit_union(type)
|
|
30
|
+
when Types::StructInstance then visit_struct_instance(type)
|
|
31
|
+
when Types::Variant then visit_variant(type)
|
|
32
|
+
when Types::VariantInstance then visit_variant_instance(type)
|
|
33
|
+
when Types::VariantArmPayload then visit_variant_arm_payload(type)
|
|
34
|
+
when Types::Proc then visit_proc(type)
|
|
35
|
+
when Types::Function then visit_function(type)
|
|
36
|
+
when Types::Parameter then visit_parameter(type)
|
|
37
|
+
when Types::TypeVar then visit_type_var(type)
|
|
38
|
+
when Types::Null then visit_null(type)
|
|
39
|
+
when Types::Tuple then visit_tuple(type)
|
|
40
|
+
when Types::Dyn then visit_dyn(type)
|
|
41
|
+
when Types::SoA then visit_soa(type)
|
|
42
|
+
when Types::Simd then visit_simd(type)
|
|
43
|
+
when Types::Event then visit_event(type)
|
|
44
|
+
when Types::LifetimeRef then visit_lifetime_ref(type)
|
|
45
|
+
else visit_default(type)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def visit_task(type); visit_children(type); end
|
|
56
|
-
def visit_generic_struct_definition(type); visit_children(type); end
|
|
57
|
-
def visit_generic_variant_definition(type); visit_children(type); end
|
|
58
|
-
def visit_struct(type); visit_children(type); end
|
|
59
|
-
def visit_union(type); visit_children(type); end
|
|
60
|
-
def visit_struct_instance(type); visit_children(type); end
|
|
61
|
-
def visit_variant(type); visit_children(type); end
|
|
62
|
-
def visit_variant_instance(type); visit_children(type); end
|
|
63
|
-
def visit_variant_arm_payload(type); visit_children(type); end
|
|
64
|
-
def visit_proc(type); visit_children(type); end
|
|
65
|
-
def visit_function(type); visit_children(type); end
|
|
66
|
-
def visit_parameter(type); visit_children(type); end
|
|
67
|
-
def visit_tuple(type); visit_children(type); end
|
|
68
|
-
def visit_dyn(type); visit_children(type); end
|
|
69
|
-
def visit_soa(type); visit_children(type); end
|
|
70
|
-
def visit_simd(type); visit_children(type); end
|
|
71
|
-
def visit_event(type); visit_children(type); end
|
|
72
|
-
|
|
73
|
-
def visit_type_var(type); end
|
|
74
|
-
def visit_null(type); end
|
|
75
|
-
def visit_lifetime_ref(type); end
|
|
76
|
-
def visit_default(type); end
|
|
77
|
-
end
|
|
49
|
+
def visit_children(type)
|
|
50
|
+
type.children.each { |child| visit(child) }
|
|
51
|
+
end
|
|
78
52
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
53
|
+
def visit_nullable(type); visit_children(type); end
|
|
54
|
+
def visit_generic_instance(type); visit_children(type); end
|
|
55
|
+
def visit_span(type); visit_children(type); end
|
|
56
|
+
def visit_task(type); visit_children(type); end
|
|
57
|
+
def visit_generic_struct_definition(type); visit_children(type); end
|
|
58
|
+
def visit_generic_variant_definition(type); visit_children(type); end
|
|
59
|
+
def visit_struct(type); visit_children(type); end
|
|
60
|
+
def visit_union(type); visit_children(type); end
|
|
61
|
+
def visit_struct_instance(type); visit_children(type); end
|
|
62
|
+
def visit_variant(type); visit_children(type); end
|
|
63
|
+
def visit_variant_instance(type); visit_children(type); end
|
|
64
|
+
def visit_variant_arm_payload(type); visit_children(type); end
|
|
65
|
+
def visit_proc(type); visit_children(type); end
|
|
66
|
+
def visit_function(type); visit_children(type); end
|
|
67
|
+
def visit_parameter(type); visit_children(type); end
|
|
68
|
+
def visit_tuple(type); visit_children(type); end
|
|
69
|
+
def visit_dyn(type); visit_children(type); end
|
|
70
|
+
def visit_soa(type); visit_children(type); end
|
|
71
|
+
def visit_simd(type); visit_children(type); end
|
|
72
|
+
def visit_event(type); visit_children(type); end
|
|
73
|
+
|
|
74
|
+
def visit_type_var(type); end
|
|
75
|
+
def visit_null(type); end
|
|
76
|
+
def visit_lifetime_ref(type); end
|
|
77
|
+
def visit_default(type); end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class ContainsTypeVarVisitor < Visitor
|
|
81
|
+
def initialize
|
|
82
|
+
super
|
|
83
|
+
@found = false
|
|
84
|
+
end
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
def found?
|
|
87
|
+
@found
|
|
88
|
+
end
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
def visit_type_var(type)
|
|
91
|
+
@found = true
|
|
92
|
+
end
|
|
91
93
|
end
|
|
92
|
-
end
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
class ContainsRefTypeVisitor < Visitor
|
|
96
|
+
def initialize(allow_lifetimes: [])
|
|
97
|
+
super()
|
|
98
|
+
@found = false
|
|
99
|
+
@allow_lifetimes = allow_lifetimes
|
|
100
|
+
end
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
def found?
|
|
103
|
+
@found
|
|
104
|
+
end
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
def visit_generic_instance(type)
|
|
107
|
+
if type.name == "ref" && [1, 2].include?(type.arguments.length)
|
|
108
|
+
if type.arguments.length == 2
|
|
109
|
+
lt = type.arguments.first
|
|
110
|
+
if lt.is_a?(String) && @allow_lifetimes.include?(lt)
|
|
111
|
+
visit_children(type)
|
|
112
|
+
return
|
|
113
|
+
end
|
|
112
114
|
end
|
|
115
|
+
@found = true
|
|
116
|
+
return
|
|
113
117
|
end
|
|
114
|
-
|
|
115
|
-
return
|
|
118
|
+
visit_children(type)
|
|
116
119
|
end
|
|
117
|
-
visit_children(type)
|
|
118
120
|
end
|
|
119
|
-
end
|
|
120
121
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
class ContainsProcTypeVisitor < Visitor
|
|
123
|
+
def initialize
|
|
124
|
+
super
|
|
125
|
+
@found = false
|
|
126
|
+
end
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
def found?
|
|
129
|
+
@found
|
|
130
|
+
end
|
|
130
131
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
def visit_proc(type)
|
|
133
|
+
@found = true
|
|
134
|
+
end
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
def visit_generic_instance(type)
|
|
137
|
+
if type.name == "array" && type.arguments.first && !type.arguments.first.is_a?(Types::LiteralTypeArg)
|
|
138
|
+
visit(type.arguments.first)
|
|
139
|
+
end
|
|
138
140
|
end
|
|
139
141
|
end
|
|
140
|
-
end
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
class ContainsCallableRefTypeVisitor < Visitor
|
|
144
|
+
def initialize
|
|
145
|
+
super
|
|
146
|
+
@found = false
|
|
147
|
+
end
|
|
147
148
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
def found?
|
|
150
|
+
@found
|
|
151
|
+
end
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
def visit_proc(type)
|
|
154
|
+
checker = ContainsRefTypeVisitor.new
|
|
155
|
+
checker.visit(type)
|
|
156
|
+
@found = true if checker.found?
|
|
157
|
+
end
|
|
158
|
+
alias visit_function visit_proc
|
|
156
159
|
end
|
|
157
|
-
alias visit_function visit_proc
|
|
158
|
-
end
|
|
159
160
|
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
class StoredRefSupportedVisitor < Visitor
|
|
162
|
+
include Types::Predicates
|
|
162
163
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
def initialize(allow_lifetimes: [])
|
|
165
|
+
super()
|
|
166
|
+
@supported = true
|
|
167
|
+
@allow_lifetimes = allow_lifetimes
|
|
168
|
+
end
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
def result?
|
|
171
|
+
@supported
|
|
172
|
+
end
|
|
172
173
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
174
|
+
def visit_generic_instance(type)
|
|
175
|
+
if ref_type?(type)
|
|
176
|
+
lt = ref_lifetime(type)
|
|
177
|
+
if lt && @allow_lifetimes.include?(lt)
|
|
178
|
+
visit_children(type)
|
|
179
|
+
return
|
|
180
|
+
end
|
|
181
|
+
@supported = false
|
|
178
182
|
return
|
|
179
183
|
end
|
|
180
|
-
|
|
181
|
-
return
|
|
184
|
+
visit_children(type)
|
|
182
185
|
end
|
|
183
|
-
visit_children(type)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def visit_proc(type)
|
|
187
|
-
@supported = false unless callable_param_ref_supported?(type)
|
|
188
|
-
end
|
|
189
|
-
alias visit_function visit_proc
|
|
190
186
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
visit(child)
|
|
194
|
-
return unless @supported
|
|
187
|
+
def visit_proc(type)
|
|
188
|
+
@supported = false unless callable_param_ref_supported?(type)
|
|
195
189
|
end
|
|
196
|
-
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
class SendableCheckVisitor < TypeVisitor
|
|
200
|
-
def initialize
|
|
201
|
-
super
|
|
202
|
-
@sendable = true
|
|
203
|
-
end
|
|
190
|
+
alias visit_function visit_proc
|
|
204
191
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
type.children.each do |child|
|
|
211
|
-
visit(child)
|
|
212
|
-
return unless @sendable
|
|
192
|
+
def visit_children(type)
|
|
193
|
+
type.children.each do |child|
|
|
194
|
+
visit(child)
|
|
195
|
+
return unless @supported
|
|
196
|
+
end
|
|
213
197
|
end
|
|
214
198
|
end
|
|
215
199
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
@sendable = false
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def visit_span(type)
|
|
225
|
-
@sendable = false
|
|
226
|
-
end
|
|
200
|
+
class SendableCheckVisitor < Visitor
|
|
201
|
+
def initialize
|
|
202
|
+
super
|
|
203
|
+
@sendable = true
|
|
204
|
+
end
|
|
227
205
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
206
|
+
def sendable?
|
|
207
|
+
@sendable
|
|
208
|
+
end
|
|
231
209
|
|
|
232
|
-
|
|
210
|
+
def visit_children(type)
|
|
211
|
+
type.children.each do |child|
|
|
212
|
+
visit(child)
|
|
213
|
+
return unless @sendable
|
|
214
|
+
end
|
|
215
|
+
end
|
|
233
216
|
|
|
234
|
-
|
|
235
|
-
case type.name
|
|
236
|
-
when "ptr", "const_ptr", "own", "ref"
|
|
237
|
-
@sendable = false
|
|
238
|
-
when "array"
|
|
239
|
-
el = type.arguments.first
|
|
240
|
-
visit(el) unless el.is_a?(Types::LiteralTypeArg)
|
|
241
|
-
when "str_buffer", "atomic"
|
|
242
|
-
# sendable
|
|
243
|
-
else
|
|
217
|
+
def visit_event(type)
|
|
244
218
|
@sendable = false
|
|
245
219
|
end
|
|
246
|
-
end
|
|
247
220
|
|
|
248
|
-
|
|
249
|
-
if type.respond_to?(:has_events?) && type.has_events?
|
|
221
|
+
def visit_dyn(type)
|
|
250
222
|
@sendable = false
|
|
251
|
-
return
|
|
252
223
|
end
|
|
253
|
-
visit_children(type)
|
|
254
|
-
end
|
|
255
|
-
alias visit_struct_instance visit_struct
|
|
256
224
|
|
|
257
|
-
|
|
258
|
-
case type
|
|
259
|
-
when Types::Primitive
|
|
260
|
-
@sendable = false if type.name == "str"
|
|
261
|
-
when Types::Error, Types::Opaque, Types::StringView
|
|
225
|
+
def visit_span(type)
|
|
262
226
|
@sendable = false
|
|
263
227
|
end
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
228
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
end
|
|
229
|
+
def visit_proc(type)
|
|
230
|
+
@sendable = false
|
|
231
|
+
end
|
|
271
232
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
arg.is_a?(Types::LiteralTypeArg) ? arg : apply(arg)
|
|
284
|
-
end
|
|
285
|
-
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : Types::Registry.generic_instance(type.name, new_args)
|
|
286
|
-
when Types::Span
|
|
287
|
-
substituted = apply(type.element_type)
|
|
288
|
-
substituted.equal?(type.element_type) ? type : Types::Registry.span(substituted)
|
|
289
|
-
when Types::Task
|
|
290
|
-
substituted = apply(type.result_type)
|
|
291
|
-
substituted.equal?(type.result_type) ? type : Types::Registry.task(substituted)
|
|
292
|
-
when Types::Event
|
|
293
|
-
new_payload = type.payload_type ? apply(type.payload_type) : nil
|
|
294
|
-
if new_payload.equal?(type.payload_type)
|
|
295
|
-
type
|
|
233
|
+
def visit_function(type); end
|
|
234
|
+
|
|
235
|
+
def visit_generic_instance(type)
|
|
236
|
+
case type.name
|
|
237
|
+
when "ptr", "const_ptr", "own", "ref"
|
|
238
|
+
@sendable = false
|
|
239
|
+
when "array"
|
|
240
|
+
el = type.arguments.first
|
|
241
|
+
visit(el) unless el.is_a?(Types::LiteralTypeArg)
|
|
242
|
+
when "str_buffer", "atomic"
|
|
243
|
+
# sendable
|
|
296
244
|
else
|
|
297
|
-
|
|
245
|
+
@sendable = false
|
|
298
246
|
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def visit_struct(type)
|
|
250
|
+
if type.respond_to?(:has_events?) && type.has_events?
|
|
251
|
+
@sendable = false
|
|
252
|
+
return
|
|
306
253
|
end
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
254
|
+
visit_children(type)
|
|
255
|
+
end
|
|
256
|
+
alias visit_struct_instance visit_struct
|
|
257
|
+
|
|
258
|
+
def visit_default(type)
|
|
259
|
+
case type
|
|
260
|
+
when Types::Primitive
|
|
261
|
+
@sendable = false if type.name == "str"
|
|
262
|
+
when Types::Error, Types::Opaque, Types::StringView
|
|
263
|
+
@sendable = false
|
|
317
264
|
end
|
|
318
|
-
new_return = apply(type.return_type)
|
|
319
|
-
changed = true unless new_return.equal?(type.return_type)
|
|
320
|
-
new_receiver = type.receiver_type ? apply(type.receiver_type) : nil
|
|
321
|
-
changed = true unless new_receiver.equal?(type.receiver_type)
|
|
322
|
-
changed ? Types::Registry.function(type.name, params: new_params, return_type: new_return, receiver_type: new_receiver, receiver_editable: type.receiver_editable, variadic: type.variadic, external: type.external) : type
|
|
323
|
-
when Types::StructInstance
|
|
324
|
-
new_args = type.arguments.map { |arg| apply(arg) }
|
|
325
|
-
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
|
|
326
|
-
when Types::VariantInstance
|
|
327
|
-
new_args = type.arguments.map { |arg| apply(arg) }
|
|
328
|
-
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
|
|
329
|
-
else
|
|
330
|
-
type
|
|
331
265
|
end
|
|
332
266
|
end
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
class ContainsArrayStorageVisitor < TypeVisitor
|
|
336
|
-
def initialize
|
|
337
|
-
super
|
|
338
|
-
@found = false
|
|
339
|
-
end
|
|
340
267
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
268
|
+
class SubstituteTypeVisitor
|
|
269
|
+
def initialize(substitutions)
|
|
270
|
+
@substitutions = substitutions
|
|
271
|
+
end
|
|
344
272
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
273
|
+
def apply(type)
|
|
274
|
+
case type
|
|
275
|
+
when Types::TypeVar
|
|
276
|
+
@substitutions.fetch(type.name, type)
|
|
277
|
+
when Types::LifetimeRef
|
|
278
|
+
@substitutions.fetch(type.name, type)
|
|
279
|
+
when Types::Nullable
|
|
280
|
+
substituted = apply(type.base)
|
|
281
|
+
substituted.equal?(type.base) ? type : Types::Registry.nullable(substituted)
|
|
282
|
+
when Types::GenericInstance
|
|
283
|
+
new_args = type.arguments.map do |arg|
|
|
284
|
+
arg.is_a?(Types::LiteralTypeArg) ? arg : apply(arg)
|
|
285
|
+
end
|
|
286
|
+
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : Types::Registry.generic_instance(type.name, new_args)
|
|
287
|
+
when Types::Span
|
|
288
|
+
substituted = apply(type.element_type)
|
|
289
|
+
substituted.equal?(type.element_type) ? type : Types::Registry.span(substituted)
|
|
290
|
+
when Types::Task
|
|
291
|
+
substituted = apply(type.result_type)
|
|
292
|
+
substituted.equal?(type.result_type) ? type : Types::Registry.task(substituted)
|
|
293
|
+
when Types::Event
|
|
294
|
+
new_payload = type.payload_type ? apply(type.payload_type) : nil
|
|
295
|
+
if new_payload.equal?(type.payload_type)
|
|
296
|
+
type
|
|
297
|
+
else
|
|
298
|
+
Types::Event.new(type.name, capacity: type.capacity, payload_type: new_payload, module_name: type.module_name, visibility: type.visibility, owner_type_name: type.owner_type_name)
|
|
299
|
+
end
|
|
300
|
+
when Types::Proc
|
|
301
|
+
changed = false
|
|
302
|
+
new_params = type.params.map do |param|
|
|
303
|
+
new_param_type = apply(param.type)
|
|
304
|
+
new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
|
|
305
|
+
changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
|
|
306
|
+
Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
|
|
307
|
+
end
|
|
308
|
+
new_return = apply(type.return_type)
|
|
309
|
+
changed = true unless new_return.equal?(type.return_type)
|
|
310
|
+
changed ? Types::Registry.proc(params: new_params, return_type: new_return) : type
|
|
311
|
+
when Types::Function
|
|
312
|
+
changed = false
|
|
313
|
+
new_params = type.params.map do |param|
|
|
314
|
+
new_param_type = apply(param.type)
|
|
315
|
+
new_boundary = param.boundary_type ? apply(param.boundary_type) : nil
|
|
316
|
+
changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type)
|
|
317
|
+
Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary)
|
|
318
|
+
end
|
|
319
|
+
new_return = apply(type.return_type)
|
|
320
|
+
changed = true unless new_return.equal?(type.return_type)
|
|
321
|
+
new_receiver = type.receiver_type ? apply(type.receiver_type) : nil
|
|
322
|
+
changed = true unless new_receiver.equal?(type.receiver_type)
|
|
323
|
+
changed ? Types::Registry.function(type.name, params: new_params, return_type: new_return, receiver_type: new_receiver, receiver_editable: type.receiver_editable, variadic: type.variadic, external: type.external) : type
|
|
324
|
+
when Types::StructInstance
|
|
325
|
+
new_args = type.arguments.map { |arg| apply(arg) }
|
|
326
|
+
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
|
|
327
|
+
when Types::VariantInstance
|
|
328
|
+
new_args = type.arguments.map { |arg| apply(arg) }
|
|
329
|
+
type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args)
|
|
330
|
+
else
|
|
331
|
+
type
|
|
352
332
|
end
|
|
353
333
|
end
|
|
354
334
|
end
|
|
355
335
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
336
|
+
class ContainsArrayStorageVisitor < Visitor
|
|
337
|
+
def initialize
|
|
338
|
+
super
|
|
339
|
+
@found = false
|
|
360
340
|
end
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
341
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
@supported = true
|
|
368
|
-
end
|
|
342
|
+
def found?
|
|
343
|
+
@found
|
|
344
|
+
end
|
|
369
345
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
346
|
+
def dispatch(type)
|
|
347
|
+
case type
|
|
348
|
+
when Types::Nullable, Types::Struct, Types::StructInstance
|
|
349
|
+
visit_children(type)
|
|
350
|
+
when Types::GenericInstance
|
|
351
|
+
if type.name == "array"
|
|
352
|
+
@found = true
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
373
356
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
visit_children(type)
|
|
380
|
-
when Types::Proc
|
|
381
|
-
when Types::Task, Types::Function, Types::Dyn, Types::SoA
|
|
382
|
-
@supported = false
|
|
357
|
+
def visit_children(type)
|
|
358
|
+
type.children.each do |child|
|
|
359
|
+
visit(child)
|
|
360
|
+
return if @found
|
|
361
|
+
end
|
|
383
362
|
end
|
|
384
363
|
end
|
|
385
364
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
365
|
+
class ProcStorageSupportedVisitor < Visitor
|
|
366
|
+
def initialize
|
|
367
|
+
super
|
|
368
|
+
@supported = true
|
|
390
369
|
end
|
|
391
|
-
end
|
|
392
|
-
end
|
|
393
370
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
@function_name = function_name
|
|
398
|
-
@context = context
|
|
399
|
-
@on_error = on_error
|
|
400
|
-
@on_generic_instance = on_generic_instance
|
|
401
|
-
end
|
|
371
|
+
def result?
|
|
372
|
+
@supported
|
|
373
|
+
end
|
|
402
374
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
375
|
+
def dispatch(type)
|
|
376
|
+
case type
|
|
377
|
+
when Types::Nullable, Types::GenericInstance, Types::Struct, Types::Union,
|
|
378
|
+
Types::StructInstance, Types::Variant, Types::VariantInstance, Types::VariantArmPayload,
|
|
379
|
+
Types::Tuple, Types::Span
|
|
380
|
+
visit_children(type)
|
|
381
|
+
when Types::Proc
|
|
382
|
+
when Types::Task, Types::Function, Types::Dyn, Types::SoA
|
|
383
|
+
@supported = false
|
|
384
|
+
end
|
|
385
|
+
end
|
|
406
386
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
387
|
+
def visit_children(type)
|
|
388
|
+
type.children.each do |child|
|
|
389
|
+
visit(child)
|
|
390
|
+
return unless @supported
|
|
391
|
+
end
|
|
392
|
+
end
|
|
410
393
|
end
|
|
411
394
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
395
|
+
class ValidateSpecializedTypeVisitor < Visitor
|
|
396
|
+
def initialize(function_name:, context:, on_error:, on_generic_instance: nil)
|
|
397
|
+
super()
|
|
398
|
+
@function_name = function_name
|
|
399
|
+
@context = context
|
|
400
|
+
@on_error = on_error
|
|
401
|
+
@on_generic_instance = on_generic_instance
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def visit_type_var(type)
|
|
405
|
+
@on_error.call("cannot infer type argument #{type.name} for function #{@function_name}")
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def visit_generic_instance(type)
|
|
409
|
+
@on_generic_instance&.call(type.name, type.arguments)
|
|
410
|
+
visit_children(type)
|
|
415
411
|
end
|
|
416
|
-
with_context("#{@context} return type") { visit(type.return_type) }
|
|
417
|
-
end
|
|
418
412
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if param.boundary_type
|
|
423
|
-
with_context("#{@context} boundary parameter #{param.name}") { visit(param.boundary_type) }
|
|
413
|
+
def visit_proc(type)
|
|
414
|
+
type.params.each do |param|
|
|
415
|
+
with_context("#{@context} parameter #{param.name}") { visit(param.type) }
|
|
424
416
|
end
|
|
417
|
+
with_context("#{@context} return type") { visit(type.return_type) }
|
|
425
418
|
end
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
419
|
+
|
|
420
|
+
def visit_function(type)
|
|
421
|
+
type.params.each do |param|
|
|
422
|
+
with_context("#{@context} parameter #{param.name}") { visit(param.type) }
|
|
423
|
+
if param.boundary_type
|
|
424
|
+
with_context("#{@context} boundary parameter #{param.name}") { visit(param.boundary_type) }
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
with_context("#{@context} return type") { visit(type.return_type) }
|
|
428
|
+
if type.receiver_type
|
|
429
|
+
with_context("#{@context} receiver type") { visit(type.receiver_type) }
|
|
430
|
+
end
|
|
429
431
|
end
|
|
430
|
-
end
|
|
431
432
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
433
|
+
def with_context(new_context)
|
|
434
|
+
old = @context
|
|
435
|
+
@context = new_context
|
|
436
|
+
yield
|
|
437
|
+
ensure
|
|
438
|
+
@context = old
|
|
439
|
+
end
|
|
438
440
|
end
|
|
439
441
|
end
|
|
440
442
|
end
|