Skip to content

[SR-5480] CLONE - Compiler crash related to associatedtype with where clauses and recursive constraints #48052

@huonw

Description

@huonw
mannequin
Previous ID SR-5480
Radar rdar://problem/33356158
Original Reporter @huonw
Type Bug
Status Resolved
Resolution Done
Environment

Xcode 9 beta 3, both default toolchain and development snapshot 2017-07-13

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee @DougGregor
Priority Medium

md5: 40c0cce69238e741c8a7e64d9c8e41e5

cloned from:

  • SR-5473 Incorrect redundant same-type warnings related to associatedtype with where clauses and recursive constraints

Issue Description:

I realize that recursive constraints are not fully implemented but I report this anyway since I think it was interesting that the workaround works (but only with -wmo), and I have code that is very similar to this that I really want to work without workarounds.

My original project (in which I stumbled over these issues) could be reduced to this.
main.swift

//============================================================================
// main.swift - Compile together with Foo.swift to demonstrate compiler bugs:
//============================================================================
// › swiftc --version
// Apple Swift version 4.0 (swiftlang-900.0.52 clang-900.0.29)
// Target: x86_64-apple-macosx10.9 (<-- why is this 10.9? I'm on 10.12.5 ...)
//
//----------------------------------------------------------------------------
// Compiles successfully like this:
//----------------------------------------------------------------------------
// › swiftc -wmo -O -g -D WORKAROUND main.swift Foo.swift -o foobar && ./foobar
//     BarWithFoo1<Bool>.Foo is Foo1 and
//     BarWithFoo1<Bool>.Foo.StringBar is BarWithFoo1<String>
//
//----------------------------------------------------------------------------
// Compiler crashes if we remove whole module optimization:
//----------------------------------------------------------------------------
// › swiftc -O -g -D WORKAROUND main.swift Foo.swift -o foobar && ./foobar
// <unknown>:0: error: fatal error encountered while reading from module
// 'foobar'; please file a bug report with your project and the crash log
// *** DESERIALIZATION FAILURE (please include this section in any bug report) ***
// top-level value not found
// Cross-reference to module 'foobar'
// ... Barable
// 0  swift       0x00000001052b67fa PrintStackTraceSignalHandler(void*) + 42
// /.../
// 
//----------------------------------------------------------------------------
// Compiles without WORKAROUND, but compiler emits lots of nonsense warnings:
//----------------------------------------------------------------------------
// › swiftc -wmo -O -g main.swift Foo.swift -o foobar && ./foobar
// Foo.swift:12:88: warning: redundant same-type constraint 'Self' == 'Self.StringBar.Foo'
//         associatedtype StringBar: Barable where StringBar.Baz == String, StringBar.Foo == Self
//                                                                                        ^
// /.../ 
//     BarWithFoo1<Bool>.Foo is Foo1 and
//     BarWithFoo1<Bool>.Foo.StringBar is BarWithFoo1<String>
//
// See Foo.swift for more details.
//----------------------------------------------------------------------------

protocol Barable {
    associatedtype Foo: Fooable
    associatedtype Baz
    init(baz: Baz)
}
struct BarWithFoo1<Baz> : Barable {
    typealias Foo = Foo1
    var baz: Baz
}
struct BarWithFoo2<Baz> : Barable {
    typealias Foo = Foo2
    var baz: Baz
}

typealias A = BarWithFoo1<Bool>
print("""
    \(A.self).Foo is \(A.Foo.self) and
    \(A.self).Foo.StringBar is \(A.Foo.StringBar.self)
""")

Foo.swift

//============================================================================
// Foo.swift - See main.swift and then this.
//============================================================================

#if !WORKAROUND
    // (A)
    // Using this version of Fooable does compile, however the constraints are not
    // enforced (it is possible to set StringBar and DoubleBar in Foo1 and Foo2 to
    // any BarWithFooX<Y>), and the compiler emits nonsense warnings (as seen in
    // main.swift) for the two lines with associatedtype below:
    protocol Fooable {
        associatedtype StringBar: Barable where StringBar.Baz == String, StringBar.Foo == Self
        associatedtype DoubleBar: Barable where DoubleBar.Baz == Double, DoubleBar.Foo == Self
    }
#else
    // (B)
    // This will properly enforce the constraints on StringBar and DoubleBar.
    protocol Fooable where
        StringBar.Foo == Self,
        StringBar.Baz == String,
        DoubleBar.Foo == Self,
        DoubleBar.Baz == Double
    {
        associatedtype StringBar: Barable
        associatedtype DoubleBar: Barable
    }
#endif

struct Foo1 : Fooable {
    typealias StringBar = BarWithFoo1<String>
    typealias DoubleBar = BarWithFoo1<Double>
}
struct Foo2 : Fooable {
    typealias StringBar = BarWithFoo2<String>
    typealias DoubleBar = BarWithFoo2<Double>
}

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itself

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions