Files
swift-mirror/validation-test/stdlib/FixedPointDiagnostics.swift.gyb
Joe Pamer 2912159776 Improve diagnostics for expression typecheck errors
These changes make the following improvements to how we generate diagnostics for expression typecheck failure:
- Customizing a diagnostic for a specific expression kind is as easy as adding a new method to the FailureDiagnosis class,
  and does not require intimate knowledge of the constraint solver’s inner workings.
    - As part of this patch, I’ve introduced specialized diagnostics for call, binop, unop, subscript, assignment and inout
      expressions, but we can go pretty far with this.
    - This also opens up the possibility to customize diagnostics not just for the expression kind, but for the specific types
      involved as well.
- For the purpose of presenting accurate type info, partially-specialized subexpressions are individually re-typechecked
  free of any contextual types. This allows us to:
    - Properly surface subexpression errors.
    - Almost completely avoid any type variables in our diagnostics. In cases where they could not be eliminated, we now
      substitute in "_".
    - More accurately indicate the sources of errors.
- We do a much better job of diagnosing disjunction failures. (So no more nonsensical ‘UInt8’ error messages.)
- We now present reasonable error messages for overload resolution failures, informing the user of partially-matching
  parameter lists when possible.

At the very least, these changes address the following bugs:

<rdar://problem/15863738> More information needed in type-checking error messages
<rdar://problem/16306600> QoI: passing a 'let' value as an inout results in an unfriendly diagnostic
<rdar://problem/16449805> Wrong error for struct-to-protocol downcast
<rdar://problem/16699932> improve type checker diagnostic when passing Double to function taking a Float
<rdar://problem/16707914> fatal error: Can't unwrap Optional.None…Optional.swift, line 75 running Master-Detail Swift app built from template
<rdar://problem/16785829> Inout parameter fixit
<rdar://problem/16900438> We shouldn't leak the internal type placeholder
<rdar://problem/16909379> confusing type check diagnostics
<rdar://problem/16951521> Extra arguments to functions result in an unhelpful error
<rdar://problem/16971025> Two Terrible Diagnostics
<rdar://problem/17007804> $T2 in compiler error string
<rdar://problem/17027483> Terrible diagnostic
<rdar://problem/17083239> Mysterious error using find() with Foundation types
<rdar://problem/17149771> Diagnostic for closure with no inferred return value leaks type variables
<rdar://problem/17212371> Swift poorly-worded error message when overload resolution fails on return type
<rdar://problem/17236976> QoI: Swift error for incorrectly typed parameter is confusing/misleading
<rdar://problem/17304200> Wrong error for non-self-conforming protocols
<rdar://problem/17321369> better error message for inout protocols
<rdar://problem/17539380> Swift error seems wrong
<rdar://problem/17559593> Bogus locationless "treating a forced downcast to 'NSData' as optional will never produce 'nil'" warning
<rdar://problem/17567973> 32-bit error message is really far from the mark: error: missing argument for parameter 'withFont' in call
<rdar://problem/17671058> Wrong error message: "Missing argument for parameter 'completion' in call"
<rdar://problem/17704609> Float is not convertible to UInt8
<rdar://problem/17705424> Poor error reporting for passing Doubles to NSColor: extra argument 'red' in call
<rdar://problem/17743603> Swift compiler gives misleading error message in "NSLayoutConstraint.constraintsWithVisualFormat("x", options: 123, metrics: nil, views: views)"
<rdar://problem/17784167> application of operator to generic type results in odd diagnostic
<rdar://problem/17801696> Awful diagnostic trying to construct an Int when .Int is around
<rdar://problem/17863882> cannot convert the expression's type '()' to type 'Seq'
<rdar://problem/17865869> "has different argument names" diagnostic when parameter defaulted-ness differs
<rdar://problem/17937593> Unclear error message for empty array literal without type context
<rdar://problem/17943023> QoI: compiler displays wrong error when a float is provided to a Int16 parameter in init method
<rdar://problem/17951148> Improve error messages for expressions inside if statements by pre-evaluating outside the 'if'
<rdar://problem/18057815> Unhelpful Swift error message
<rdar://problem/18077468> Incorrect argument label for insertSubview(...)
<rdar://problem/18079213> 'T1' is not identical to 'T2' lacks directionality
<rdar://problem/18086470> Confusing Swift error message: error: 'T' is not convertible to 'MirrorDisposition'
<rdar://problem/18098995> QoI: Unhelpful compiler error when leaving off an & on an inout parameter
<rdar://problem/18104379> Terrible error message
<rdar://problem/18121897> unexpected low-level error on assignment to immutable value through array writeback
<rdar://problem/18123596> unexpected error on self. capture inside class method
<rdar://problem/18152074> QoI: Improve diagnostic for type mismatch in dictionary subscripting
<rdar://problem/18242160> There could be a better error message when using [] instead of [:]
<rdar://problem/18242812> 6A1021a : Type variable leaked
<rdar://problem/18331819> Unclear error message when trying to set an element of an array constant (Swift)
<rdar://problem/18414834> Bad diagnostics example
<rdar://problem/18422468> Calculation of constant value yields unexplainable error
<rdar://problem/18427217> Misleading error message makes debugging difficult
<rdar://problem/18439742> Misleading error: "cannot invoke" mentions completely unrelated types as arguments
<rdar://problem/18535804> Wrong compiler error from swift compiler
<rdar://problem/18567914> Xcode 6.1. GM, Swift, assignment from Int64 to NSNumber. Warning shown as problem with UInt8
<rdar://problem/18784027> Negating Int? Yields Float
<rdar://problem/17691565> attempt to modify a 'let' variable with ++ results in typecheck error about @lvalue Float
<rdar://problem/17164001> "++" on let value could give a better error message

Swift SVN r23782
2014-12-08 21:56:47 +00:00

131 lines
7.2 KiB
Plaintext

// RUN: rm -rf %t && mkdir -p %t && %S/../../utils/gyb %s -o %t/main.swift
// RUN: %S/../../utils/line-directive %t/main.swift -- %swift -verify -parse %t/main.swift
func testUnaryMinusInUnsigned() {
var a: UInt8 = -(1) // expected-error {{unary operator '-' cannot be applied to an operand of type '(Int)'}}
var b: UInt16 = -(1) // expected-error {{unary operator '-' cannot be applied to an operand of type '(Int)'}}
var c: UInt32 = -(1) // expected-error {{unary operator '-' cannot be applied to an operand of type '(Int)'}}
var d: UInt64 = -(1) // expected-error {{unary operator '-' cannot be applied to an operand of type '(Int)'}}
}
// Int and UInt are not identical to any fixed-size integer type
var i : Int = 0
var w : Word = i
var i64 : Int64 = i // expected-error {{'Int' is not convertible to 'Int64'}}
var i32 : Int32 = i // expected-error {{'Int' is not convertible to 'Int32'}}
var i16 : Int16 = i // expected-error {{'Int' is not convertible to 'Int16'}}
var i8 : Int8 = i // expected-error {{'Int' is not convertible to 'Int8'}}
var u : UInt = 0
var uw : UWord = u
var u64 : UInt64 = u // expected-error {{'UInt' is not convertible to 'UInt64'}}
var u32 : UInt32 = u // expected-error {{'UInt' is not convertible to 'UInt32'}}
var u16 : UInt16 = u // expected-error {{'UInt' is not convertible to 'UInt16'}}
var u8 : UInt8 = u // expected-error {{'UInt' is not convertible to 'UInt8'}}
func expectSameType<T>(_: T.Type, _: T.Type) {}
func test_truncatingBitPatternAPIIsStableAcrossPlatforms() {
// Audit and update this test when adding new integer types.
expectSameType(Int64.self, IntMax.self)
expectSameType(UInt64.self, UIntMax.self)
UInt8(truncatingBitPattern: UInt(0))
UInt16(truncatingBitPattern: UInt(0))
UInt32(truncatingBitPattern: UInt(0))
UInt64(truncatingBitPattern: UInt(0)) // expected-error {{extraneous argument label 'truncatingBitPattern:' in call}}
UInt(truncatingBitPattern: UInt(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
Int8(truncatingBitPattern: UInt(0))
Int16(truncatingBitPattern: UInt(0))
Int32(truncatingBitPattern: UInt(0))
Int64(truncatingBitPattern: UInt(0)) // expected-error {{extraneous argument label 'truncatingBitPattern:' in call}}
Int(truncatingBitPattern: UInt(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
UInt8(truncatingBitPattern: Int(0))
UInt16(truncatingBitPattern: Int(0))
UInt32(truncatingBitPattern: Int(0))
UInt64(truncatingBitPattern: Int(0)) // expected-error {{extraneous argument label 'truncatingBitPattern:' in call}}
UInt(truncatingBitPattern: Int(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
Int8(truncatingBitPattern: Int(0))
Int16(truncatingBitPattern: Int(0))
Int32(truncatingBitPattern: Int(0))
Int64(truncatingBitPattern: Int(0)) // expected-error {{extraneous argument label 'truncatingBitPattern:' in call}}
Int(truncatingBitPattern: Int(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
UInt(truncatingBitPattern: UInt8(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: UInt16(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: UInt32(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: UInt64(0))
Int(truncatingBitPattern: UInt8(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: UInt16(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: UInt32(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: UInt64(0))
UInt(truncatingBitPattern: Int8(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: Int16(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: Int32(0)) // expected-error {{cannot invoke initializer for type 'UInt' with an argument list of type}}
UInt(truncatingBitPattern: Int64(0))
Int(truncatingBitPattern: Int8(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: Int16(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: Int32(0)) // expected-error {{cannot invoke initializer for type 'Int' with an argument list of type}}
Int(truncatingBitPattern: Int64(0))
}
func testMixedSignArithmetic() {
// Ensure that the generic arithmetic operators for Strideable don't
// allow mixed-sign arithmetic to compile. We create a deliberate
// ambiguity in these cases.
% for T in "UInt UWord UInt64 UInt32 UInt16 UInt8".split():
if true {
typealias Stride = ${T}.Stride
${T}(1) + 0 // OK
0 + ${T}(1) // OK
${T}(1) + Stride(0) // expected-error {{ambiguous use of operator '+'}}
Stride(1) + ${T}(0) // expected-error {{ambiguous use of operator '+'}}
${T}(1) - Stride(0) // expected-error {{ambiguous use of operator '-'}}
var x: ${T} = 0
x += 1 // OK
x += Stride(1) // expected-error {{ambiguous use of operator '+='}}
x -= Stride(1) // expected-error {{ambiguous use of operator '-='}}
(x - x) as Stride // expected-error {{ambiguous use of operator '-'}}
//===------------------------------------------------------------------===//
// The following errors are different because they're not being
// disabled by the ambiguity trick.
//===------------------------------------------------------------------===//
Stride(1) - ${T}(0) // expected-error {{binary operator '-' cannot be applied to an Stride operand and a}} expected-note {{Overloads for '-' exist with these partially matching parameter lists:}}
// These tests are expected to start failing when we get improved diagnostics.
var y: Stride = 0
y += ${T}(1) // expected-error {{binary operator '+=' cannot be applied to an Stride operand and a}} expected-note {{Overloads for '+=' exist with these partially matching parameter lists:}}
y -= ${T}(1) // expected-error {{binary operator '-=' cannot be applied to an Stride operand and a}} expected-note {{Overloads for '-=' exist with these partially matching parameter lists:}}
}
% end
}
func testOps<T : IntegerArithmeticType>(x: T, y: T) -> T {
let a = x + y
let s = x - y
let m = x * y
let d = x / y
let r = x % y
return a + s + m + d + r
}
let s_ops: Int = testOps(5, 2)
let u_ops: UInt = testOps(5, 2)
let s8_ops: Int8 = testOps(5, 2)
let u8_ops: UInt8 = testOps(5, 2)
let s16_ops: Int16 = testOps(5, 2)
let u16_ops: UInt16 = testOps(5, 2)
let s32_ops: Int32 = testOps(5, 2)
let u32_ops: UInt32 = testOps(5, 2)
let s64_ops: Int64 = testOps(5, 2)
let u64_ops: UInt64 = testOps(5, 2)