Compiler crashes while resolving generics constraints


(Игорь Никитин) #1

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?


(Slava Pestov) #2

Hi Igor,

Your example is not self-contained, so I added the following definitions:

struct URI {}

struct App {
  class Remote {
    struct Credentials {}
  }
}

struct RemoteUser {}

protocol ResponseRepresentable {}

protocol RemoteCredentials {}

Unfortunately, this makes the code compile in both Swift 3.0 and the latest code built from GitHub, even with the ‘where’ part uncommented, so I suspect we’ll need a larger testcase to reproduce the original issue.

However from looking at the code, what you’re doing is adding a requirement to an associated type of the ‘Self’ generic parameter, which Swift 3.0 did not model properly, but it is one of the things we addressed in some recent refactoring work.

Could you try the latest development snapshot from swift.org <http://swift.org/> and let us know if it solves your problem?

Slava

···

On Dec 25, 2016, at 1:05 PM, Игорь Никитин via swift-users <swift-users@swift.org> wrote:

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Игорь Никитин) #3

Hello!

Here is a class that uses all of this protocols: https://gist.github.com/rabbitinspace/a88410d778e5ac955ee88bdfede6e00b
Line 19

Latest Xcode gives me this log: https://gist.github.com/rabbitinspace/6cb5ebd536a81b0b1cc6b0fadbabbe77
It’s a compiler crash, I think

While the latest dev swift snapshot produces a build error: https://gist.github.com/rabbitinspace/944a62efc18432baf781e368a1023b87
Shortly:
  cannot invoke 'authenticationService' with an argument list of type '(for: Remote.Type)’
  expected an argument list of type '(for: Remote.Type)’

I can build it with the latest dev snapshot (Xcode still can't) if I will constraint generic types in AuthController class:
Can’t compile:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>

This is compiles successfully:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>
       where Builder.Service.Remote == Remote

···

25 дек. 2016 г., в 23:50, Slava Pestov via swift-users <swift-users@swift.org> написал(а):

Hi Igor,

Your example is not self-contained, so I added the following definitions:

struct URI {}

struct App {
  class Remote {
    struct Credentials {}
  }
}

struct RemoteUser {}

protocol ResponseRepresentable {}

protocol RemoteCredentials {}

Unfortunately, this makes the code compile in both Swift 3.0 and the latest code built from GitHub, even with the ‘where’ part uncommented, so I suspect we’ll need a larger testcase to reproduce the original issue.

However from looking at the code, what you’re doing is adding a requirement to an associated type of the ‘Self’ generic parameter, which Swift 3.0 did not model properly, but it is one of the things we addressed in some recent refactoring work.

Could you try the latest development snapshot from swift.org <http://swift.org/> and let us know if it solves your problem?

Slava

On Dec 25, 2016, at 1:05 PM, Игорь Никитин via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Slava Pestov) #4

Hello!

Here is a class that uses all of this protocols: https://gist.github.com/rabbitinspace/a88410d778e5ac955ee88bdfede6e00b
Line 19

Latest Xcode gives me this log: https://gist.github.com/rabbitinspace/6cb5ebd536a81b0b1cc6b0fadbabbe77
It’s a compiler crash, I think

While the latest dev swift snapshot produces a build error: https://gist.github.com/rabbitinspace/944a62efc18432baf781e368a1023b87
Shortly:
  cannot invoke 'authenticationService' with an argument list of type '(for: Remote.Type)’
  expected an argument list of type '(for: Remote.Type)’

I can build it with the latest dev snapshot (Xcode still can't) if I will constraint generic types in AuthController class:
Can’t compile:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>

This is compiles successfully:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>
       where Builder.Service.Remote == Remote

It seems this is the correct fix — the compile error is obtuse, but it sounds like it’s talking about the two different types (both named ‘Remote’).

If you feel this behavior is in error, do you mind filing a JIRA bug?

Slava

···

On Dec 26, 2016, at 2:30 PM, Игорь Никитин <devnikor@icloud.com> wrote:

25 дек. 2016 г., в 23:50, Slava Pestov via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> написал(а):

Hi Igor,

Your example is not self-contained, so I added the following definitions:

struct URI {}

struct App {
  class Remote {
    struct Credentials {}
  }
}

struct RemoteUser {}

protocol ResponseRepresentable {}

protocol RemoteCredentials {}

Unfortunately, this makes the code compile in both Swift 3.0 and the latest code built from GitHub, even with the ‘where’ part uncommented, so I suspect we’ll need a larger testcase to reproduce the original issue.

However from looking at the code, what you’re doing is adding a requirement to an associated type of the ‘Self’ generic parameter, which Swift 3.0 did not model properly, but it is one of the things we addressed in some recent refactoring work.

Could you try the latest development snapshot from swift.org <http://swift.org/> and let us know if it solves your problem?

Slava

On Dec 25, 2016, at 1:05 PM, Игорь Никитин via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Игорь Никитин) #5

Now I’m not sure that it’s a compiler bug.
Maybe I not provide enough info of the type system or whatever else

Thanks for the help!

···

26 дек. 2016 г., в 22:49, Slava Pestov via swift-users <swift-users@swift.org> написал(а):

On Dec 26, 2016, at 2:30 PM, Игорь Никитин <devnikor@icloud.com <mailto:devnikor@icloud.com>> wrote:

Hello!

Here is a class that uses all of this protocols: https://gist.github.com/rabbitinspace/a88410d778e5ac955ee88bdfede6e00b
Line 19

Latest Xcode gives me this log: https://gist.github.com/rabbitinspace/6cb5ebd536a81b0b1cc6b0fadbabbe77
It’s a compiler crash, I think

While the latest dev swift snapshot produces a build error: https://gist.github.com/rabbitinspace/944a62efc18432baf781e368a1023b87
Shortly:
  cannot invoke 'authenticationService' with an argument list of type '(for: Remote.Type)’
  expected an argument list of type '(for: Remote.Type)’

I can build it with the latest dev snapshot (Xcode still can't) if I will constraint generic types in AuthController class:
Can’t compile:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>

This is compiles successfully:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>
       where Builder.Service.Remote == Remote

It seems this is the correct fix — the compile error is obtuse, but it sounds like it’s talking about the two different types (both named ‘Remote’).

If you feel this behavior is in error, do you mind filing a JIRA bug?

Slava

25 дек. 2016 г., в 23:50, Slava Pestov via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> написал(а):

Hi Igor,

Your example is not self-contained, so I added the following definitions:

struct URI {}

struct App {
  class Remote {
    struct Credentials {}
  }
}

struct RemoteUser {}

protocol ResponseRepresentable {}

protocol RemoteCredentials {}

Unfortunately, this makes the code compile in both Swift 3.0 and the latest code built from GitHub, even with the ‘where’ part uncommented, so I suspect we’ll need a larger testcase to reproduce the original issue.

However from looking at the code, what you’re doing is adding a requirement to an associated type of the ‘Self’ generic parameter, which Swift 3.0 did not model properly, but it is one of the things we addressed in some recent refactoring work.

Could you try the latest development snapshot from swift.org <http://swift.org/> and let us know if it solves your problem?

Slava

On Dec 25, 2016, at 1:05 PM, Игорь Никитин via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Slava Pestov) #6

The Swift 3 crash is definitely a compiler bug — the compiler should never crash, even with invalid code. However it looks like we fixed it already, and the latest snapshot produces a compile error instead. Let us know if you need any more help!

Slava

···

On Dec 26, 2016, at 2:56 PM, Игорь Никитин <devnikor@icloud.com> wrote:

Now I’m not sure that it’s a compiler bug.
Maybe I not provide enough info of the type system or whatever else

Thanks for the help!

26 дек. 2016 г., в 22:49, Slava Pestov via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> написал(а):

On Dec 26, 2016, at 2:30 PM, Игорь Никитин <devnikor@icloud.com <mailto:devnikor@icloud.com>> wrote:

Hello!

Here is a class that uses all of this protocols: https://gist.github.com/rabbitinspace/a88410d778e5ac955ee88bdfede6e00b
Line 19

Latest Xcode gives me this log: https://gist.github.com/rabbitinspace/6cb5ebd536a81b0b1cc6b0fadbabbe77
It’s a compiler crash, I think

While the latest dev swift snapshot produces a build error: https://gist.github.com/rabbitinspace/944a62efc18432baf781e368a1023b87
Shortly:
  cannot invoke 'authenticationService' with an argument list of type '(for: Remote.Type)’
  expected an argument list of type '(for: Remote.Type)’

I can build it with the latest dev snapshot (Xcode still can't) if I will constraint generic types in AuthController class:
Can’t compile:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>

This is compiles successfully:
   final class AuthController<Remote: App.Remote, Builder: RemoteAuthenticationServiceBuilder>
       where Builder.Service.Remote == Remote

It seems this is the correct fix — the compile error is obtuse, but it sounds like it’s talking about the two different types (both named ‘Remote’).

If you feel this behavior is in error, do you mind filing a JIRA bug?

Slava

25 дек. 2016 г., в 23:50, Slava Pestov via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> написал(а):

Hi Igor,

Your example is not self-contained, so I added the following definitions:

struct URI {}

struct App {
  class Remote {
    struct Credentials {}
  }
}

struct RemoteUser {}

protocol ResponseRepresentable {}

protocol RemoteCredentials {}

Unfortunately, this makes the code compile in both Swift 3.0 and the latest code built from GitHub, even with the ‘where’ part uncommented, so I suspect we’ll need a larger testcase to reproduce the original issue.

However from looking at the code, what you’re doing is adding a requirement to an associated type of the ‘Self’ generic parameter, which Swift 3.0 did not model properly, but it is one of the things we addressed in some recent refactoring work.

Could you try the latest development snapshot from swift.org <http://swift.org/> and let us know if it solves your problem?

Slava

On Dec 25, 2016, at 1:05 PM, Игорь Никитин via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hello!

I have few protocols with associated types:
protocol Remote {
    associatedtype Credentials: RemoteCredentials

    static var url: URI { get }
    static var name: String { get }
    static var credentials: Credentials.Type { get }
}
protocol RemoteAuthenticating {
    associatedtype Remote: App.Remote

    func authenticate(with credentials: Remote.Credentials) throws -> (RemoteUser, ResponseRepresentable?)
}
protocol RemoteAuthenticationServiceBuilder {
    associatedtype Service: RemoteAuthenticating

    // TODO: `Service.Remote` should be constrained to `Remote` but compiler crashes
    func authenticationService<Remote: App.Remote>(for: Remote.Type) -> Service? // where Service.Remote == Remote
}
It works fine until I uncomment the last where statement
If I trying to constraint Service.Remote type compiler will crash with segfault 11
I can guess that it's a compiler bug, but maybe I’m using generics in wrong way?

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users