diff --git a/lib/steep/signature/validator.rb b/lib/steep/signature/validator.rb index 6f1a69323..6056590d5 100644 --- a/lib/steep/signature/validator.rb +++ b/lib/steep/signature/validator.rb @@ -214,7 +214,17 @@ def mixin_constraints(definition, mixin_ancestors, immediate_self_types:) ancestor_ancestors.self_types or raise ancestor_ancestors.params or raise self_constraints = ancestor_ancestors.self_types.map do |self_ancestor| - s = Interface::Substitution.build(ancestor_ancestors.params, args) + params = ancestor_ancestors.params + + if source = self_ancestor.source + if entry = env.class_decls[ancestor.name] + if decl = entry.each_decl.find { _1.is_a?(RBS::AST::Declarations::Module) && _1.self_types.include?(source) } + params = decl.type_params.map(&:name) + end + end + end + + s = Interface::Substitution.build(params, args) ancestor_to_type(self_ancestor).subst(s) end diff --git a/test/validation_test.rb b/test/validation_test.rb index bcfe10dd6..37cf222c8 100644 --- a/test/validation_test.rb +++ b/test/validation_test.rb @@ -485,6 +485,33 @@ class E end end + def test_validate_mixin_with_renamed_type_params + with_checker <<~RBS do |checker| + interface _Each[A] + def each: () { (A) -> void } -> void + end + + module Enum[E] : _Each[E] + end + + module Enum[Elem] : _Each[Elem] + end + + class Collection + include Enum[String] + + def each: () { (String) -> void } -> void + end + RBS + + Validator.new(checker: checker).tap do |validator| + validator.validate_one_class(RBS::TypeName.parse("::Collection")) + + assert_predicate validator, :no_error? + end + end + end + def test_validate_mixin_module with_checker <<-EOF do |checker| interface _FooEach[A]