Skip to content

Commit 52b9107

Browse files
authored
Merge pull request #3143 from ruby/type-params-validation
Validate the type params of an entry once
2 parents 40e7fc2 + a5458a8 commit 52b9107

6 files changed

Lines changed: 27 additions & 3 deletions

File tree

lib/rbs/definition_builder.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,11 @@ def source_location(source, decl)
504504
def validate_type_params(definition, ancestors:, methods:)
505505
type_params = definition.type_params_decl
506506

507+
# Without type params nothing can violate the variance: the ancestor validation
508+
# iterates the (empty) params, and the type params of the methods themselves are
509+
# invariant, which `Result#compatible?` always accepts
510+
return if type_params.empty?
511+
507512
calculator = VarianceCalculator.new(builder: self)
508513
param_names = type_params.each.map(&:name)
509514

@@ -1048,9 +1053,10 @@ def validate_type_presence(type)
10481053
end
10491054

10501055
def validate_type_name(name, location)
1051-
name = name.absolute! unless name.absolute?
1052-
return if env.type_name?(env.normalize_type_name(name))
1056+
absolute = name.absolute? ? name : name.absolute!
1057+
return if env.type_name?(env.normalize_type_name(absolute))
10531058

1059+
# Report the name as it is written in the signature
10541060
raise NoTypeFoundError.new(type_name: name, location: location)
10551061
end
10561062
end

lib/rbs/environment/class_entry.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def initialize(name)
1515
def <<(context_decl)
1616
context_decls << context_decl
1717
@primary_decl = nil
18+
@type_params_validated = nil
1819
self
1920
end
2021

@@ -50,6 +51,10 @@ def type_params
5051
end
5152

5253
def validate_type_params
54+
# The entry only changes with `<<`, which resets the memo -- a failed
55+
# validation is not recorded and raises again
56+
return if @type_params_validated
57+
5358
unless context_decls.empty?
5459
first_decl, *rest_decls = each_decl.to_a
5560
first_decl or raise
@@ -63,6 +68,8 @@ def validate_type_params
6368
end
6469
end
6570
end
71+
72+
@type_params_validated = true
6673
end
6774

6875
def align_params(decl)

lib/rbs/environment/module_entry.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def initialize(name)
1414

1515
def <<(context_decl)
1616
context_decls << context_decl
17+
@type_params_validated = nil
1718
self
1819
end
1920

@@ -72,6 +73,10 @@ def align_params(decl)
7273
end
7374

7475
def validate_type_params
76+
# The entry only changes with `<<`, which resets the memo -- a failed
77+
# validation is not recorded and raises again
78+
return if @type_params_validated
79+
7580
unless context_decls.empty?
7681
first_decl, *rest_decls = each_decl.to_a
7782
first_decl or raise
@@ -85,6 +90,8 @@ def validate_type_params
8590
end
8691
end
8792
end
93+
94+
@type_params_validated = true
8895
end
8996
end
9097
end

sig/environment/class_entry.rbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module RBS
1818

1919
@primary_decl: declaration?
2020

21+
@type_params_validated: bool?
22+
2123
def initialize: (TypeName) -> void
2224

2325
def <<: (context_decl) -> self

sig/environment/module_entry.rbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ module RBS
1717

1818
attr_reader context_decls: Array[context_decl]
1919

20+
@type_params_validated: bool?
21+
2022
def initialize: (TypeName) -> void
2123

2224
def <<: (context_decl) -> self

test/rbs/cli_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ module Bar[B]
402402
cli.run(["-I", dir, "validate"])
403403
end
404404

405-
assert_include stdout.string, "a.rbs:2:13...2:14: Could not find ::A (RBS::NoTypeFoundError)"
405+
assert_include stdout.string, "a.rbs:2:13...2:14: Could not find A (RBS::NoTypeFoundError)"
406406
end
407407
end
408408
end

0 commit comments

Comments
 (0)