Skip to content

Commit 1940626

Browse files
authored
Merge pull request #2590 from ruby/type-syntax-error
Update parser so that `void` type is rejected depending on the context
2 parents 0f3ceb6 + 98b1911 commit 1940626

File tree

16 files changed

+223
-173
lines changed

16 files changed

+223
-173
lines changed

ext/rbs_extension/main.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ struct parse_type_arg {
8585
rb_encoding *encoding;
8686
rbs_parser_t *parser;
8787
VALUE require_eof;
88+
VALUE void_allowed;
89+
};
90+
91+
struct parse_method_type_arg {
92+
VALUE buffer;
93+
rb_encoding *encoding;
94+
rbs_parser_t *parser;
95+
VALUE require_eof;
96+
};
97+
98+
struct parse_signature_arg {
99+
VALUE buffer;
100+
rb_encoding *encoding;
101+
rbs_parser_t *parser;
102+
VALUE require_eof;
88103
};
89104

90105
static VALUE ensure_free_parser(VALUE parser) {
@@ -100,8 +115,10 @@ static VALUE parse_type_try(VALUE a) {
100115
return Qnil;
101116
}
102117

118+
bool void_allowed = RTEST(arg->void_allowed);
119+
103120
rbs_node_t *type;
104-
rbs_parse_type(parser, &type);
121+
rbs_parse_type(parser, &type, void_allowed);
105122

106123
raise_error_if_any(parser, arg->buffer);
107124

@@ -157,7 +174,7 @@ static rbs_parser_t *alloc_parser_from_buffer(VALUE buffer, int start_pos, int e
157174
);
158175
}
159176

160-
static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) {
177+
static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed) {
161178
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
162179
StringValue(string);
163180
rb_encoding *encoding = rb_enc_get(string);
@@ -168,7 +185,8 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL
168185
.buffer = buffer,
169186
.encoding = encoding,
170187
.parser = parser,
171-
.require_eof = require_eof
188+
.require_eof = require_eof,
189+
.void_allowed = void_allowed
172190
};
173191

174192
VALUE result = rb_ensure(parse_type_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
@@ -179,7 +197,7 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL
179197
}
180198

181199
static VALUE parse_method_type_try(VALUE a) {
182-
struct parse_type_arg *arg = (struct parse_type_arg *) a;
200+
struct parse_method_type_arg *arg = (struct parse_method_type_arg *) a;
183201
rbs_parser_t *parser = arg->parser;
184202

185203
if (parser->next_token.type == pEOF) {
@@ -215,7 +233,7 @@ static VALUE rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_p
215233

216234
rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
217235
declare_type_variables(parser, variables, buffer);
218-
struct parse_type_arg arg = {
236+
struct parse_method_type_arg arg = {
219237
.buffer = buffer,
220238
.encoding = encoding,
221239
.parser = parser,
@@ -230,7 +248,7 @@ static VALUE rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_p
230248
}
231249

232250
static VALUE parse_signature_try(VALUE a) {
233-
struct parse_type_arg *arg = (struct parse_type_arg *) a;
251+
struct parse_signature_arg *arg = (struct parse_signature_arg *) a;
234252
rbs_parser_t *parser = arg->parser;
235253

236254
rbs_signature_t *signature = NULL;
@@ -253,7 +271,7 @@ static VALUE rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE start_pos
253271
rb_encoding *encoding = rb_enc_get(string);
254272

255273
rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
256-
struct parse_type_arg arg = {
274+
struct parse_signature_arg arg = {
257275
.buffer = buffer,
258276
.encoding = encoding,
259277
.parser = parser,
@@ -432,7 +450,7 @@ void rbs__init_parser(void) {
432450
VALUE empty_array = rb_obj_freeze(rb_ary_new());
433451
rb_gc_register_mark_object(empty_array);
434452

435-
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5);
453+
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 6);
436454
rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
437455
rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
438456
rb_define_singleton_method(RBS_Parser, "_parse_type_params", rbsparser_parse_type_params, 4);

include/rbs/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ rbs_ast_comment_t *rbs_parser_get_comment(rbs_parser_t *parser, int subject_line
126126

127127
void rbs_parser_set_error(rbs_parser_t *parser, rbs_token_t tok, bool syntax_error, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(4, 5);
128128

129-
bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type);
129+
bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed);
130130
bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type);
131131
bool rbs_parse_signature(rbs_parser_t *parser, rbs_signature_t **signature);
132132

lib/rbs/cli/validate.rb

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ def validate_class_module_definition
122122
entry.each_decl do |decl|
123123
if super_class = decl.super_class
124124
super_class.args.each do |arg|
125-
void_type_context_validator(arg, true)
126125
no_self_type_validator(arg)
127126
no_classish_type_validator(arg)
128127
@validator.validate_type(arg, context: nil)
@@ -133,7 +132,6 @@ def validate_class_module_definition
133132
entry.each_decl do |decl|
134133
decl.self_types.each do |self_type|
135134
self_type.args.each do |arg|
136-
void_type_context_validator(arg, true)
137135
no_self_type_validator(arg)
138136
no_classish_type_validator(arg)
139137
@validator.validate_type(arg, context: nil)
@@ -163,21 +161,18 @@ def validate_class_module_definition
163161

164162
d.type_params.each do |param|
165163
if ub = param.upper_bound_type
166-
void_type_context_validator(ub)
167164
no_self_type_validator(ub)
168165
no_classish_type_validator(ub)
169166
@validator.validate_type(ub, context: nil)
170167
end
171168

172169
if lb = param.lower_bound_type
173-
void_type_context_validator(lb)
174170
no_self_type_validator(lb)
175171
no_classish_type_validator(lb)
176172
@validator.validate_type(lb, context: nil)
177173
end
178174

179175
if dt = param.default_type
180-
void_type_context_validator(dt, true)
181176
no_self_type_validator(dt)
182177
no_classish_type_validator(dt)
183178
@validator.validate_type(dt, context: nil)
@@ -193,17 +188,9 @@ def validate_class_module_definition
193188
case member
194189
when AST::Members::MethodDefinition
195190
@validator.validate_method_definition(member, type_name: name)
196-
member.overloads.each do |ov|
197-
void_type_context_validator(ov.method_type)
198-
end
199-
when AST::Members::Attribute
200-
void_type_context_validator(member.type)
201191
when AST::Members::Mixin
202192
member.args.each do |arg|
203193
no_self_type_validator(arg)
204-
unless arg.is_a?(Types::Bases::Void)
205-
void_type_context_validator(arg, true)
206-
end
207194
end
208195
params =
209196
if member.name.class?
@@ -216,7 +203,6 @@ def validate_class_module_definition
216203
InvalidTypeApplicationError.check!(type_name: member.name, params: params, args: member.args, location: member.location)
217204
when AST::Members::Var
218205
@validator.validate_variable(member)
219-
void_type_context_validator(member.type)
220206
if member.is_a?(AST::Members::ClassVariable)
221207
no_self_type_validator(member.type)
222208
end
@@ -255,21 +241,18 @@ def validate_interface
255241

256242
decl.decl.type_params.each do |param|
257243
if ub = param.upper_bound_type
258-
void_type_context_validator(ub)
259244
no_self_type_validator(ub)
260245
no_classish_type_validator(ub)
261246
@validator.validate_type(ub, context: nil)
262247
end
263248

264249
if lb = param.lower_bound_type
265-
void_type_context_validator(lb)
266250
no_self_type_validator(lb)
267251
no_classish_type_validator(lb)
268252
@validator.validate_type(lb, context: nil)
269253
end
270254

271255
if dt = param.default_type
272-
void_type_context_validator(dt, true)
273256
no_self_type_validator(dt)
274257
no_classish_type_validator(dt)
275258
@validator.validate_type(dt, context: nil)
@@ -283,7 +266,6 @@ def validate_interface
283266
when AST::Members::MethodDefinition
284267
@validator.validate_method_definition(member, type_name: name)
285268
member.overloads.each do |ov|
286-
void_type_context_validator(ov.method_type)
287269
no_classish_type_validator(ov.method_type)
288270
end
289271
end
@@ -300,7 +282,6 @@ def validate_constant
300282
@builder.ensure_namespace!(name.namespace, location: const.decl.location)
301283
no_self_type_validator(const.decl.type)
302284
no_classish_type_validator(const.decl.type)
303-
void_type_context_validator(const.decl.type)
304285
rescue BaseError => error
305286
@errors.add(error)
306287
end
@@ -312,7 +293,6 @@ def validate_global
312293
@validator.validate_type global.decl.type, context: nil
313294
no_self_type_validator(global.decl.type)
314295
no_classish_type_validator(global.decl.type)
315-
void_type_context_validator(global.decl.type)
316296
rescue BaseError => error
317297
@errors.add(error)
318298
end
@@ -335,21 +315,18 @@ def validate_type_alias
335315

336316
decl.decl.type_params.each do |param|
337317
if ub = param.upper_bound_type
338-
void_type_context_validator(ub)
339318
no_self_type_validator(ub)
340319
no_classish_type_validator(ub)
341320
@validator.validate_type(ub, context: nil)
342321
end
343322

344323
if lb = param.lower_bound_type
345-
void_type_context_validator(lb)
346324
no_self_type_validator(lb)
347325
no_classish_type_validator(lb)
348326
@validator.validate_type(lb, context: nil)
349327
end
350328

351329
if dt = param.default_type
352-
void_type_context_validator(dt, true)
353330
no_self_type_validator(dt)
354331
no_classish_type_validator(dt)
355332
@validator.validate_type(dt, context: nil)
@@ -360,7 +337,6 @@ def validate_type_alias
360337

361338
no_self_type_validator(decl.decl.type)
362339
no_classish_type_validator(decl.decl.type)
363-
void_type_context_validator(decl.decl.type)
364340
rescue BaseError => error
365341
@errors.add(error)
366342
end
@@ -384,7 +360,7 @@ def void_type_context_validator(type, allowed_here = false)
384360
if allowed_here
385361
return if type.is_a?(Types::Bases::Void)
386362
end
387-
if type.with_nonreturn_void?
363+
if type.with_nonreturn_void? # steep:ignore DeprecatedReference
388364
@errors.add WillSyntaxError.new("`void` type is only allowed in return type or generics parameter", location: type.location)
389365
end
390366
end

lib/rbs/method_type.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,13 @@ def has_classish_type?
129129
end
130130

131131
def with_nonreturn_void?
132-
if type.with_nonreturn_void?
132+
if type.with_nonreturn_void? # steep:ignore DeprecatedReference
133133
true
134134
else
135135
if block = block()
136-
block.type.with_nonreturn_void? || block.self_type&.with_nonreturn_void? || false
136+
block.type.with_nonreturn_void? || # steep:ignore DeprecatedReference
137+
block.self_type&.with_nonreturn_void? || # steep:ignore DeprecatedReference
138+
false
137139
else
138140
false
139141
end

lib/rbs/parser_aux.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
module RBS
77
class Parser
8-
def self.parse_type(source, range: 0..., variables: [], require_eof: false)
8+
def self.parse_type(source, range: 0..., variables: [], require_eof: false, void_allowed: true)
99
buf = buffer(source)
10-
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
10+
_parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof, void_allowed)
1111
end
1212

1313
def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)

lib/rbs/types.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ def with_nonreturn_void?
303303
# `void` in immediate generics parameter is allowed
304304
false
305305
else
306-
type.with_nonreturn_void?
306+
type.with_nonreturn_void? # steep:ignore DeprecatedReference
307307
end
308308
end
309309
end
@@ -520,7 +520,7 @@ def has_classish_type?
520520
end
521521

522522
def with_nonreturn_void?
523-
each_type.any? {|type| type.with_nonreturn_void? }
523+
each_type.any? {|type| type.with_nonreturn_void? } # steep:ignore DeprecatedReference
524524
end
525525
end
526526

@@ -638,7 +638,7 @@ def has_classish_type?
638638
end
639639

640640
def with_nonreturn_void?
641-
each_type.any? {|type| type.with_nonreturn_void? }
641+
each_type.any? {|type| type.with_nonreturn_void? } # steep:ignore DeprecatedReference
642642
end
643643
end
644644

@@ -724,7 +724,7 @@ def has_classish_type?
724724
end
725725

726726
def with_nonreturn_void?
727-
each_type.any? {|type| type.with_nonreturn_void? }
727+
each_type.any? {|type| type.with_nonreturn_void? } # steep:ignore DeprecatedReference
728728
end
729729
end
730730

@@ -815,7 +815,7 @@ def has_classish_type?
815815
end
816816

817817
def with_nonreturn_void?
818-
each_type.any? {|type| type.with_nonreturn_void? }
818+
each_type.any? {|type| type.with_nonreturn_void? } # steep:ignore DeprecatedReference
819819
end
820820
end
821821

@@ -898,7 +898,7 @@ def has_classish_type?
898898
end
899899

900900
def with_nonreturn_void?
901-
each_type.any? {|type| type.with_nonreturn_void? }
901+
each_type.any? {|type| type.with_nonreturn_void? } # steep:ignore DeprecatedReference
902902
end
903903
end
904904

@@ -1226,13 +1226,13 @@ def has_classish_type?
12261226
end
12271227

12281228
def with_nonreturn_void?
1229-
if each_param.any? {|param| param.type.with_nonreturn_void? }
1229+
if each_param.any? {|param| param.type.with_nonreturn_void? } # steep:ignore DeprecatedReference
12301230
true
12311231
else
12321232
if return_type.is_a?(Bases::Void)
12331233
false
12341234
else
1235-
return_type.with_nonreturn_void?
1235+
return_type.with_nonreturn_void? # steep:ignore DeprecatedReference
12361236
end
12371237
end
12381238
end
@@ -1505,11 +1505,11 @@ def has_classish_type?
15051505
end
15061506

15071507
def with_nonreturn_void?
1508-
if type.with_nonreturn_void? || self_type&.with_nonreturn_void?
1508+
if type.with_nonreturn_void? || self_type&.with_nonreturn_void? # steep:ignore DeprecatedReference
15091509
true
15101510
else
15111511
if block = block()
1512-
block.type.with_nonreturn_void? || block.self_type&.with_nonreturn_void? || false
1512+
block.type.with_nonreturn_void? || block.self_type&.with_nonreturn_void? || false # steep:ignore DeprecatedReference
15131513
else
15141514
false
15151515
end

sig/cli/validate.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ module RBS
4646
def validate_type_alias: () -> void
4747
def no_self_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void
4848
def no_classish_type_validator: (::RBS::Types::t | ::RBS::MethodType type) -> void
49-
def void_type_context_validator: (::RBS::Types::t | ::RBS::MethodType type, ?bool allowed_here) -> void
49+
%a{deprecated} def void_type_context_validator: (::RBS::Types::t | ::RBS::MethodType type, ?bool allowed_here) -> void
5050
end
5151
end
5252
end

sig/method_types.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ module RBS
5353

5454
def has_classish_type?: () -> bool
5555

56-
def with_nonreturn_void?: () -> bool
56+
%a{deprecated} def with_nonreturn_void?: () -> bool
5757
end
5858
end

0 commit comments

Comments
 (0)