File tree 5 files changed +16
-9
lines changed
5 files changed +16
-9
lines changed Original file line number Diff line number Diff line change @@ -407,4 +407,15 @@ describe "Restrictions" do
407
407
) ,
408
408
" no overload matches"
409
409
end
410
+
411
+ it " errors if using free var without forall" do
412
+ assert_error %(
413
+ def foo(x : T)
414
+ T
415
+ end
416
+
417
+ foo(1)
418
+ ) ,
419
+ " undefined constant T"
420
+ end
410
421
end
Original file line number Diff line number Diff line change @@ -128,7 +128,7 @@ class Crystal::Def
128
128
# a temporary variable (tmp_var) and then replace all ocurrences of that free var with typeof(tmp_var)
129
129
# to achieve the same effect, since we can't define a type alias inside a method.
130
130
restriction = arg.restriction
131
- if restriction.is_a?(Path ) && restriction.names.size == 1 && ( Parser .free_var_name?(restriction.names.first) || free_vars.try(& .includes?(restriction.names.first) ))
131
+ if restriction.is_a?(Path ) && restriction.names.size == 1 && free_vars.try(& .includes?(restriction.names.first))
132
132
restriction_name = program.new_temp_var_name
133
133
new_body << Assign .new(Var .new(restriction_name), Var .new(arg.name))
134
134
body = body.transform(ReplaceFreeVarTransformer .new(restriction.names.first, restriction_name))
Original file line number Diff line number Diff line change @@ -377,7 +377,7 @@ module Crystal
377
377
378
378
if single_name
379
379
first_name = other.names.first
380
- if context.defining_type.type_var?(first_name) || Parser .free_var_name?(first_name)
380
+ if context.defining_type.type_var?(first_name)
381
381
return context.set_free_var(first_name, self )
382
382
end
383
383
end
@@ -856,7 +856,7 @@ module Crystal
856
856
single_name = other.names.size == 1
857
857
if single_name
858
858
first_name = other.names.first
859
- if context.defining_type.type_var?(first_name) || Parser .free_var_name?(first_name)
859
+ if context.defining_type.type_var?(first_name)
860
860
return context.set_free_var(first_name, self )
861
861
else
862
862
other.raise_undefined_constant(context.defining_type)
Original file line number Diff line number Diff line change @@ -5359,9 +5359,5 @@ module Crystal
5359
5359
@visibility = old_visibility
5360
5360
value
5361
5361
end
5362
-
5363
- def self.free_var_name ?(name)
5364
- name.size == 1 || (name.size == 2 && name[1 ].ascii_number?)
5365
- end
5366
5362
end
5367
5363
end
Original file line number Diff line number Diff line change @@ -91,7 +91,7 @@ module Enumerable(T)
91
91
# * `Enumerable::Chunk::Alone` specifies that the element should be chunked by itself
92
92
#
93
93
# See also: `Iterator#chunk`
94
- def chunks (& block : T - > U )
94
+ def chunks (& block : T - > U ) forall U
95
95
res = [] of Tuple (U , Array (T ))
96
96
chunks_internal(block) { |k , v | res << {k, v} }
97
97
res
@@ -160,7 +160,7 @@ module Enumerable(T)
160
160
end
161
161
end
162
162
163
- private def chunks_internal (original_block : T - > U )
163
+ private def chunks_internal (original_block : T - > U ) forall U
164
164
acc = Chunk ::Accumulator (T , U ).new
165
165
each do |val |
166
166
key = original_block.call(val)
You can’t perform that action at this time.
0 commit comments