swift: Compiler error when extending a typealias of a partially specialized generic type

Description When creating a typealias that partially specializes a generic type, the compiler generates an error when attempting to extend that type via the typealias.

Steps to reproduce Create a Generic type with two type parameters.

struct Field<Tag,Value> {
  let tag: Tag
  let value: Value
}

Define a typealias which specializes one of the type parameters as such :

typealias IntField<Tag> = Field<Tag,Int>

Define an extension based on the typealias:

extension IntField {
  func adding(_ value: Int) -> Self {
    Field(tag: tag, value: self.value + value)
  }
}

Expected behavior I would expect this code to compile.

Instead the compiler complained: “Binary operator ‘+’ cannot be applied to operands of type ‘Value’ and ‘Int’”

If instead of extending the typealias, I extend the type directly it compiles fine as such:

extension Field where Value == Int {
  func adding(_ value: Int) -> Self {
    Field(tag: tag, value: self.value + value)
  }
}

Environment

  • Swift compiler version info swift-driver version: 1.75.2 Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
  • Xcode version info: Xcode 14.3.1 Build version 14E300c
  • Deployment target: macOS Playground

About this issue

  • Original URL
  • State: open
  • Created 10 months ago
  • Comments: 54 (27 by maintainers)

Most upvoted comments

@dochoi-bot Does the following command make any difference in the terminal?

ninja -C /Users/dochoi/swift-project/build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64 bin/swift-frontend && bin/swift-frontend /Users/dochoi/file.swift -typecheck

If not, you may have interrupted the build script before it finished building the standard library. You can build it by rerunning your build script invocation, or by running ninja swift-stdlib-macosx-x86_64 from within the swift-macosx-x86_64 directory. Targets can be listed with ninja -t targets.

I would like to work on this if you don’t mind. @saehejkang @AnthonyLatsis

I was able to reproduce this issue and see the signature with the -debug-generic-signatures flag. I commented the isPassThroughTypealias in order to get rid of the fall back Field: https://github.com/apple/swift/pull/73169/commits/7025a0d231b2b47987c691afdff52f721071d2ee

Why is the check isPassThroughTypealias check needed here after all? After commenting the complete “Hack to allow extending a generic typealias”, extending the generic typealias throws an error in the code as expected.

I believe when the hack is resolved to a reasonable check, we can also fix this issue with ease.

In order to tackle this better I am required to debug the code using LLDB. I have not yet figured out how to run my example swift file and start the LLDB. If you could refer me to any tuturial, would be appreciated.

This is how I ran my swift file: …/withDebugSwift/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/bin/swift-frontend -debug-generic-signa tures issue.swift

I am going to take a pause on this. If anyone else comes along and wants to work on this please unassign me and give it to them.

Why would static_cast<bool>(nominalSig) != static_cast<bool>(typealiasSig) evaluate to true?

It would not evaluate to true because nominalSig has a GenericSignature of X and typeAlias has a GenericSignature of T. It exists for both so the cast succeeds and they are both true thus the whole if evaluates to false.

I would like to solve this problem, It will be my first open source contribution. Do you mind if I start?

Sounds good. Thanks.

I would like to solve this problem, It will be my first open source contribution. Do you mind if I start?