Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-5440] Typealias in constrained extension misinterprets the where clause #48014

Closed
jepers opened this issue Jul 12, 2017 · 7 comments
Closed

Comments

@jepers
Copy link

jepers commented Jul 12, 2017

Previous ID SR-5440
Radar rdar://problem/33268536
Original Reporter @jepers
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, AcceptsInvalid
Assignee @slavapestov
Priority Medium

md5: 64a011da616f479d8c228dd46791be39

relates to:

  • SR-5392 Inconsistent "invalid redeclaration of typealias"
  • SR-7217 Protocol composition with conflicting typealiases does not diagnose
  • SR-7605 Overly-exuberant associatedtype deduction?
  • SR-3793 Protocol extension cannot implement associated type
  • SR-10466 Accepts invalid because where clause seems to be ignored.
  • SR-7516 Compiler accepts ambiguous and/or invalid use of associated types
  • SR-7976 Unexpected behavior from conditional conformances
  • SR-10158 Associated type inference resolution ignores conditionality of extensions

Issue Description:

The following seemingly invalid program compiles ( ! ), and the result is the same as if the where-clauses had been removed, so it seems like typealiases added in constrained extensions ignores the constraint:

struct S<T> {
    var v: (A, B, C)
}
extension S where T == Int {
    typealias A = Int
}
extension S where T == Bool {
    typealias B = Bool
}
extension S where T == Float {
    typealias C = Float
}
print(S<String>.A.self) // Int
print(S<String>.B.self) // Bool
print(S<String>.C.self) // Float
print(S<Double>.A.self) // Int
print(S<Double>.B.self) // Bool
print(S<Double>.C.self) // Float

The same is true when using a protocol instead of a struct:

protocol P {
    associatedtype Q
    var v: (D, E, F) { get }
}
extension P where Q == Int {
    typealias D = Int
}
extension P where Q == Bool {
    typealias E = Bool
}
extension P where Q == Float {
    typealias F = Float
}
struct R<T> : P {
    typealias Q = T
    var v: (D, E, F)
}
print(R<String>.D.self) // Int
print(R<String>.E.self) // Bool
print(R<String>.F.self) // Float
print(R<Double>.D.self) // Int
print(R<Double>.E.self) // Bool
print(R<Double>.F.self) // Float

UPDATE:
As the following program shows, it seems like the where-clause is actually misinterpreted rather than ignored:

// typealias misinterprets where clause of extension

struct S<A> {
    var hmm: (A, B, C)
}
extension S where A == Bool {
    typealias B = A
    static func printB() { print(B.self) }
}
extension S where A == Float {
    typealias C = A
    static func printC() { print(C.self) }
}
let a = S(hmm: ("strange", true, Float(42.1)))
dump(a)
// Will print:
▿ TestXc9b3.S<Swift.String>
  ▿ hmm: (3 elements)
    - .0: "strange"
    - .1: true
    - .2: 42.0999985

Note: I have only used (a single) same-type constraint (eg A == Float) in the where-clause here, but there are similar problems when constraining to protocol types (eg A: FloatingPoint).

Tested in Xcode 9 beta 3, same behavior in default toolchain and dev snapshot 2017-07-12.

@huonw
Copy link
Mannequin

huonw mannequin commented Jul 12, 2017

@swift-ci create

@huonw
Copy link
Mannequin

huonw mannequin commented Jun 13, 2018

The first two cases are fixed by d57330975a39187e4129d91f566024c9f8923530, but the last case is very curly.

@huonw
Copy link
Mannequin

huonw mannequin commented Jun 13, 2018

Ah, and that patch only addressed {{typealias}}s specifically: there's still fundamental issues with nested types. The following compiles without error:

struct Generic<Foo> {}
extension Generic where Foo == Int {
    struct X {}
}

print(Generic<String>.X.self)

@huonw
Copy link
Mannequin

huonw mannequin commented Jun 13, 2018

#17168 for that specific example, but still no handling of decls (checking the types used in the decls of v and hmm).

@jepers
Copy link
Author

jepers commented Mar 23, 2019

This issue is still not resolved (in Swift 4.2, haven't tried 5.0) and has been in progress for a very long time.

@jepers
Copy link
Author

jepers commented Apr 12, 2019

The following (afaics invalid) program still compiles with Swift 5 / Xcode 10.2 and the latest dev snapshot (2019-04-10):

struct S<T> {
    var a : A
}
extension S where T == Never {
    typealias A = Int
}
let v = S<Int>(a: 123)
print(v)

even though it required Int == Never.

I filed this as a separate (more specific) bug:
https://bugs.swift.org/browse/SR-10466

@slavapestov
Copy link
Member

slavapestov commented Nov 15, 2019

#28275

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants