lib/rbs/variance_calculator.rb in rbs-1.7.1 vs lib/rbs/variance_calculator.rb in rbs-1.8.0
- old
+ new
@@ -52,10 +52,25 @@
true
else
false
end
end
+
+ def incompatible?(params)
+ # @type set: Hash[Symbol]
+ set = Set[]
+
+ params.each do |param|
+ unless compatible?(param.name, with_annotation: param.variance)
+ set << param.name
+ end
+ end
+
+ unless set.empty?
+ set
+ end
+ end
end
attr_reader :builder
def initialize(builder:)
@@ -67,23 +82,16 @@
end
def in_method_type(method_type:, variables:)
result = Result.new(variables: variables)
- method_type.type.each_param do |param|
- type(param.type, result: result, context: :contravariant)
- end
+ function(method_type.type, result: result, context: :covariant)
if block = method_type.block
- block.type.each_param do |param|
- type(param.type, result: result, context: :covariant)
- end
- type(block.type.return_type, result: result, context: :contravariant)
+ function(block.type, result: result, context: :contravariant)
end
- type(method_type.type.return_type, result: result, context: :covariant)
-
result
end
def in_inherit(name:, args:, variables:)
type = if name.class?
@@ -95,10 +103,18 @@
Result.new(variables: variables).tap do |result|
type(type, result: result, context: :covariant)
end
end
+ def in_type_alias(name:)
+ decl = env.alias_decls[name].decl or raise
+ variables = decl.type_params.each.map(&:name)
+ Result.new(variables: variables).tap do |result|
+ type(decl.type, result: result, context: :covariant)
+ end
+ end
+
def type(type, result:, context:)
case type
when Types::Variable
if result.include?(type.name)
case context
@@ -108,48 +124,60 @@
result.contravariant(type.name)
when :invariant
result.invariant(type.name)
end
end
- when Types::ClassInstance, Types::Interface
+ when Types::ClassInstance, Types::Interface, Types::Alias
NoTypeFoundError.check!(type.name,
env: env,
location: type.location)
type_params = case type
when Types::ClassInstance
env.class_decls[type.name].type_params
when Types::Interface
env.interface_decls[type.name].decl.type_params
+ when Types::Alias
+ env.alias_decls[type.name].decl.type_params
end
type.args.each.with_index do |ty, i|
var = type_params.params[i]
case var&.variance
when :invariant
type(ty, result: result, context: :invariant)
when :covariant
type(ty, result: result, context: context)
when :contravariant
- # @type var con: variance
- con = case context
- when :invariant
- :invariant
- when :covariant
- :contravariant
- when :contravariant
- :covariant
- else
- raise
- end
- type(ty, result: result, context: con)
+ type(ty, result: result, context: negate(context))
end
end
- when Types::Tuple, Types::Record, Types::Union, Types::Intersection
- # Covariant types
+ when Types::Proc
+ function(type.type, result: result, context: context)
+ else
type.each_type do |ty|
type(ty, result: result, context: context)
end
+ end
+ end
+
+ def function(type, result:, context:)
+ type.each_param do |param|
+ type(param.type, result: result, context: negate(context))
+ end
+ type(type.return_type, result: result, context: context)
+ end
+
+ def negate(variance)
+ case variance
+ when :invariant
+ :invariant
+ when :covariant
+ :contravariant
+ when :contravariant
+ :covariant
+ else
+ raise
end
end
end
end