OK, I've made some progress. Although I haven't fixed the problem in my custom stdlib, I have fixed the unit test you directed me to.
I haven't rebased on top of master yet as it will take a long time to do and I'm not sure it's the best use of time until I've eliminated all possible other routes to find out what's going wrong.
When I was debugging various runs through the compiler, I noticed that dumping typealias declarations often resulted in...
( **typealias** range=[stdlib.swift:14:1 - line:14:42] "XXX" type='<<<unresolved>>>')
...so I thought, maybe the error _MaxBuiltinFloatType is not properly defined
will show up if the typealias is somehow not fully resolved at the point when it is tested or needed.
Looking in the standard library that comes with swift, _ExpressibleByBuiltinFloatLiteral
and ExpressibleByFloatLiteral
are defined in CompilerProtocols.swift
... Float
and Double
and their conformances to those protocols are defined in FloatingPoint.swift
and FloatingPointTypes.swift.gyb
and all are declared before public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
, which is in Policy.swift
so is alphabetically last.
I rearranged the unit test in stdlib.swift
to match this order, then added a struct that conformed to the protocols and updated the protocols.
It looks like the unit test might have been written a fairly long time ago when the _ExpressibleByBuiltinFloatLiteral
for example needed a static factory function called _convertFromBuiltinFloatLiteral
, but that has been changed to a simple initialiser in modern versions of the protocol. And similar for ExpressibleByFloatLiteral
.
With all these changes, the script now runs without error when _MaxBuiltinFloatType
is defined...
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ cat stdlib.swift
// RUN: %target-typecheck-verify-swift -parse-stdlib -module-name Swift
enum Optional<T> {
case none
case some(T)
}
public protocol _ExpressibleByBuiltinFloatLiteral {
init(_builtinFloatLiteral value: _MaxBuiltinFloatType)
}
public protocol ExpressibleByFloatLiteral {
associatedtype FloatLiteralType : _ExpressibleByBuiltinFloatLiteral
init(floatLiteral value: FloatLiteralType)
}
public struct Y: ExpressibleByFloatLiteral, _ExpressibleByBuiltinFloatLiteral {
public init(_builtinFloatLiteral value: _MaxBuiltinFloatType) {
}
public init(floatLiteral value: FloatLiteralType) {
}
}
public typealias FloatLiteralType = Y
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
// <rdar://problem/15593704>
struct X {
// This is in parse-stdlib mode with no default literal type.
var _maxLoadFactorInverse = 1.0 // expected-error{{standard library error: _MaxBuiltinFloatType is not properly defined}}
}
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ swift-macosx-x86_64/bin/swift -frontend -typecheck -primary-file stdlib.swift -disable-objc-attr-requires-foundation-module -target avr-atmel-linux-gnueabihf -enable-objc-interop -parse-stdlib -color-diagnostics -module-name Swift
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ echo $?
0
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$
...and it produces the expected error when _MaxBuiltinFloatType
is not properly defined...
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ cat stdlib.swift
// RUN: %target-typecheck-verify-swift -parse-stdlib -module-name Swift
enum Optional<T> {
case none
case some(T)
}
public protocol _ExpressibleByBuiltinFloatLiteral {
init(_builtinFloatLiteral value: MaxBuiltinFloatType)
}
public protocol ExpressibleByFloatLiteral {
associatedtype FloatLiteralType : _ExpressibleByBuiltinFloatLiteral
init(floatLiteral value: FloatLiteralType)
}
public struct Y: ExpressibleByFloatLiteral, _ExpressibleByBuiltinFloatLiteral {
public init(_builtinFloatLiteral value: MaxBuiltinFloatType) {
}
public init(floatLiteral value: FloatLiteralType) {
}
}
public typealias FloatLiteralType = Y
public typealias MaxBuiltinFloatType = Builtin.FPIEEE64
// <rdar://problem/15593704>
struct X {
// This is in parse-stdlib mode with no default literal type.
var _maxLoadFactorInverse = 1.0 // expected-error{{standard library error: _MaxBuiltinFloatType is not properly defined}}
}
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ swift-macosx-x86_64/bin/swift -frontend -typecheck -primary-file stdlib.swift -disable-objc-attr-requires-foundation-module -target avr-atmel-linux-gnueabihf -enable-objc-interop -parse-stdlib -color-diagnostics -module-name Swift
stdlib.swift:31:31: error: standard library error: _MaxBuiltinFloatType is not properly defined
var _maxLoadFactorInverse = 1.0 // expected-error{{standard library error: _MaxBuiltinFloatType is not properly defined}}
^
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$ echo $?
1
Carls-MacBook-Air:Ninja-DebugAssert carlpeto$
So it looks like the order of things in the standard library by luck happens to avoid this problem, but it's fragile, reorder things a bit and float literals break. Like you say, this looks like a bug, although of course it won't affect 99.99% of swift users, who don't like to make their own standard libraries (everyone else in the world except me?)
Unfortunately my stdlib is still reporting the same error, even after I did the same reordering so I'm going to have to try more tricks. Within the file where ExpressibleByFloatLiteral
, _ExpressibleByBuiltinFloatLiteral
and _MaxBuiltinFloatType
are defined, float literals now work fine in my library. But in any other files in my library, they can refer to all these definitions but float literals do not work and produce the error described in this post.