Skip to content

Commit 945c09b

Browse files
committed
[Type checker] Improve diagnostics when an optional value is not unwrapped.
When we determine that an optional value needs to be unwrapped to make an expression type check, use notes to provide several different Fix-It options (with descriptions) rather than always pushing users toward '!'. Specifically, the errors + Fix-Its now looks like this: error: value of optional type 'X?' must be unwrapped to a value of type 'X' f(x) ^ note: coalesce using '??' to provide a default when the optional value contains 'nil' f(x) ^ ?? <#default value#> note: force-unwrap using '!' to abort execution if the optional value contains 'nil' f(x) ^ ! Fixes rdar://problem/42081852.
1 parent 520c645 commit 945c09b

22 files changed

+194
-46
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,15 @@ ERROR(missing_unwrap_optional,none,
906906
"value of optional type %0 not unwrapped; did you mean to use '!' "
907907
"or '?'?",
908908
(Type))
909+
ERROR(optional_not_unwrapped,none,
910+
"value of optional type %0 must be unwrapped to a value of type %1",
911+
(Type, Type))
912+
NOTE(unwrap_with_default_value,none,
913+
"coalesce using '?" "?' to provide a default when the optional value "
914+
"contains 'nil'", ())
915+
NOTE(unwrap_with_force_value,none,
916+
"force-unwrap using '!' to abort execution if the optional value contains "
917+
"'nil'", ())
909918
ERROR(missing_unwrap_optional_try,none,
910919
"value of optional type %0 not unwrapped; did you mean to use 'try!' "
911920
"or chain with '?'?",

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ IDENTIFIER(AssignmentPrecedence)
135135
IDENTIFIER(CastingPrecedence)
136136
IDENTIFIER(DefaultPrecedence)
137137
IDENTIFIER(FunctionArrowPrecedence)
138+
IDENTIFIER(NilCoalescingPrecedence)
138139
IDENTIFIER(TernaryPrecedence)
139140

140141
// Builtins and literals

lib/Sema/CSApply.cpp

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7794,6 +7794,32 @@ static bool exprNeedsParensAfterAddingAs(TypeChecker &TC, DeclContext *DC,
77947794
return exprNeedsParensOutsideFollowingOperator(TC, DC, expr, rootExpr, asPG);
77957795
}
77967796

7797+
// Return true if, when replacing "<expr>" with "<expr> ?? T", parentheses need
7798+
// to be added around <expr> first in order to maintain the correct precedence.
7799+
static bool exprNeedsParensBeforeAddingNilCoalescing(TypeChecker &TC,
7800+
DeclContext *DC,
7801+
Expr *expr) {
7802+
auto asPG =
7803+
TC.lookupPrecedenceGroup(DC, DC->getASTContext().Id_NilCoalescingPrecedence,
7804+
SourceLoc());
7805+
if (!asPG) return true;
7806+
return exprNeedsParensInsideFollowingOperator(TC, DC, expr, asPG);
7807+
}
7808+
7809+
// Return true if, when replacing "<expr>" with "<expr> as T", parentheses need
7810+
// to be added around the new expression in order to maintain the correct
7811+
// precedence.
7812+
static bool exprNeedsParensAfterAddingNilCoalescing(TypeChecker &TC,
7813+
DeclContext *DC,
7814+
Expr *expr,
7815+
Expr *rootExpr) {
7816+
auto asPG =
7817+
TC.lookupPrecedenceGroup(DC, DC->getASTContext().Id_NilCoalescingPrecedence,
7818+
SourceLoc());
7819+
if (!asPG) return true;
7820+
return exprNeedsParensOutsideFollowingOperator(TC, DC, expr, rootExpr, asPG);
7821+
}
7822+
77977823
namespace {
77987824
class ExprWalker : public ASTWalker {
77997825
ExprRewriter &Rewriter;
@@ -7966,13 +7992,53 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
79667992
"try!");
79677993

79687994
} else {
7969-
auto diag = TC.diagnose(affected->getLoc(),
7970-
diag::missing_unwrap_optional, type);
7971-
if (affected->canAppendPostfixExpression(true)) {
7972-
diag.fixItInsertAfter(affected->getEndLoc(), "!");
7973-
} else {
7974-
diag.fixItInsert(affected->getStartLoc(), "(")
7975-
.fixItInsertAfter(affected->getEndLoc(), ")!");
7995+
Type unwrappedType = type->getOptionalObjectType();
7996+
if (!unwrappedType)
7997+
return false;
7998+
7999+
TC.diagnose(affected->getLoc(), diag::optional_not_unwrapped, type,
8000+
unwrappedType);
8001+
8002+
// Suggest a default value via ?? <default value>
8003+
{
8004+
auto diag =
8005+
TC.diagnose(affected->getLoc(), diag::unwrap_with_default_value);
8006+
8007+
// Figure out what we need to parenthesize.
8008+
bool needsParensInside =
8009+
exprNeedsParensBeforeAddingNilCoalescing(TC, DC, affected);
8010+
bool needsParensOutside =
8011+
exprNeedsParensAfterAddingNilCoalescing(TC, DC, affected, expr);
8012+
8013+
llvm::SmallString<2> insertBefore;
8014+
llvm::SmallString<32> insertAfter;
8015+
if (needsParensOutside) {
8016+
insertBefore += "(";
8017+
}
8018+
if (needsParensInside) {
8019+
insertBefore += "(";
8020+
insertAfter += ")";
8021+
}
8022+
insertAfter += " ?? <" "#default value#" ">";
8023+
if (needsParensOutside)
8024+
insertAfter += ")";
8025+
8026+
if (!insertBefore.empty()) {
8027+
diag.fixItInsert(affected->getStartLoc(), insertBefore);
8028+
}
8029+
diag.fixItInsertAfter(affected->getEndLoc(), insertAfter);
8030+
}
8031+
8032+
// Suggest a force-unwrap.
8033+
{
8034+
auto diag =
8035+
TC.diagnose(affected->getLoc(), diag::unwrap_with_force_value);
8036+
if (affected->canAppendPostfixExpression(true)) {
8037+
diag.fixItInsertAfter(affected->getEndLoc(), "!");
8038+
} else {
8039+
diag.fixItInsert(affected->getStartLoc(), "(")
8040+
.fixItInsertAfter(affected->getEndLoc(), ")!");
8041+
}
79768042
}
79778043
}
79788044
return true;

test/ClangImporter/cfuncs_parse.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,27 @@ func test_cfunc2(_ i: Int) {
1616

1717
func test_cfunc3_a() {
1818
let b = cfunc3( { (a : Double, b : Double) -> Double in a + b } )
19-
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
19+
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
20+
// expected-note@-1{{coalesce}}
21+
// expected-note@-2{{force-unwrap}}
2022
_ = b!(1.5, 2.5) as Double
2123
_ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
2224
}
2325

2426
func test_cfunc3_b() {
2527
let b = cfunc3( { a, b in a + b } )
26-
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
28+
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
29+
// expected-note@-1{{coalesce}}
30+
// expected-note@-2{{force-unwrap}}
2731
_ = b!(1.5, 2.5) as Double
2832
_ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
2933
}
3034

3135
func test_cfunc3_c() {
3236
let b = cfunc3({ $0 + $1 })
33-
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') not unwrapped; did you mean to use '!' or '?'?}}
37+
_ = b(1.5, 2.5) as Double // expected-error{{value of optional type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') must be unwrapped}}
38+
// expected-note@-1{{coalesce}}
39+
// expected-note@-2{{force-unwrap}}
3440
_ = b!(1.5, 2.5) as Double
3541
_ = b as Double// expected-error{{cannot convert value of type 'double_bin_op_block?' (aka 'Optional<(Double, Double) -> Double>') to type 'Double' in coercion}}
3642
}

test/ClangImporter/nullability.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,22 @@ func testSomeClass(_ sc: SomeClass, osc: SomeClass?) {
2121
if sc.methodD() == nil { } // expected-warning {{comparing non-optional value of type 'Any' to 'nil' always returns false}}
2222

2323
sc.methodE(sc)
24-
sc.methodE(osc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
24+
sc.methodE(osc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
25+
// expected-note@-1{{coalesce}}
26+
// expected-note@-2{{force-unwrap}}
2527

2628
sc.methodF(sc, second: sc)
27-
sc.methodF(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
28-
sc.methodF(sc, second: osc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{29-29=!}}
29+
sc.methodF(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
30+
// expected-note@-1{{coalesce}}
31+
// expected-note@-2{{force-unwrap}}
32+
sc.methodF(sc, second: osc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
33+
// expected-note@-1{{coalesce}}
34+
// expected-note@-2{{force-unwrap}}
2935

3036
sc.methodG(sc, second: sc)
31-
sc.methodG(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' not unwrapped; did you mean to use '!' or '?'?}} {{17-17=!}}
37+
sc.methodG(osc, second: sc) // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
38+
// expected-note@-1{{coalesce}}
39+
// expected-note@-2{{force-unwrap}}
3240
sc.methodG(sc, second: osc)
3341

3442
let ci: CInt = 1
@@ -39,7 +47,9 @@ func testSomeClass(_ sc: SomeClass, osc: SomeClass?) {
3947

4048
let sc3 = SomeClass(double: 1.5)
4149
if sc3 == nil { } // okay
42-
let sc3a: SomeClass = sc3 // expected-error{{value of optional type 'SomeClass?' not unwrapped}} {{28-28=!}}
50+
let sc3a: SomeClass = sc3 // expected-error{{value of optional type 'SomeClass?' must be unwrapped}}
51+
// expected-note@-1{{coalesce}}
52+
// expected-note@-2{{force-unwrap}}
4353
_ = sc3a
4454

4555
let sc4 = sc.returnMe()

test/ClangImporter/objc_parse.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ func properties(_ b: B) {
130130
var obj : AnyObject = b
131131
var optStr = obj.nsstringProperty // optStr has type String??
132132
if optStr != nil {
133-
var s : String = optStr! // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}}
133+
var s : String = optStr! // expected-error{{value of optional type 'String?' must be unwrapped}}
134+
// expected-note@-1{{coalesce}}
135+
// expected-note@-2{{force-unwrap}}
134136
var t : String = optStr!!
135137
}
136138

@@ -288,7 +290,9 @@ extension Wobbler2 : NSMaybeInitWobble { // expected-error{{type 'Wobbler2' does
288290

289291
func optionalMemberAccess(_ w: NSWobbling) {
290292
w.wobble()
291-
w.wibble() // expected-error{{value of optional type '(() -> Void)?' not unwrapped; did you mean to use '!' or '?'?}} {{11-11=!}}
293+
w.wibble() // expected-error{{value of optional type '(() -> Void)?' must be unwrapped}}
294+
// expected-note@-1{{coalesce}}
295+
// expected-note@-2{{force-unwrap}}
292296
let x = w[5]!!
293297
_ = x
294298
}

test/Constraints/diagnostics.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,9 @@ _ = (i = 6) ? 42 : 57 // expected-error {{use of '=' in a boolean context, did y
577577
// <rdar://problem/22263468> QoI: Not producing specific argument conversion diagnostic for tuple init
578578
func r22263468(_ a : String?) {
579579
typealias MyTuple = (Int, String)
580-
_ = MyTuple(42, a) // expected-error {{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}} {{20-20=!}}
580+
_ = MyTuple(42, a) // expected-error {{value of optional type 'String?' must be unwrapped to a value of type 'String'}}
581+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
582+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
581583
}
582584

583585

test/Constraints/fixes.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,38 @@ func forgotCall() {
4747
/// Forgot the '!' to unwrap an optional.
4848
func parseInt() -> Int? { }
4949

50+
func <(lhs: A, rhs: A) -> A? { return nil }
51+
5052
func forgotOptionalBang(_ a: A, obj: AnyObject) {
51-
var i: Int = parseInt() // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}{{26-26=!}}
53+
var i: Int = parseInt() // expected-error{{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
54+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{26-26= ?? <#default value#>}}
55+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{26-26=!}}
5256

5357
var a = A(), b = B()
54-
b = a as? B // expected-error{{value of optional type 'B?' not unwrapped; did you mean to use '!' or '?'?}}{{7-7=(}}{{14-14=)!}}
55-
58+
b = a as? B // expected-error{{value of optional type 'B?' must be unwrapped to a value of type 'B'}}
59+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{14-14= ?? <#default value#>}}
60+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{7-7=(}}{{14-14=)!}}
61+
62+
a = a < a // expected-error{{value of optional type 'A?' must be unwrapped to a value of type 'A'}}
63+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}{{7-7=(}}{{12-12=) ?? <#default value#>}}
64+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}{{7-7=(}}{{12-12=)!}}
65+
5666
// rdar://problem/20377684 -- take care that the '!' doesn't fall into an
5767
// optional evaluation context
5868
let bo: B? = b
59-
let b2: B = bo?.createB() // expected-error{{value of optional type 'B?' not unwrapped; did you mean to use '!' or '?'?}}{{15-15=(}}{{28-28=)!}}
69+
let b2: B = bo?.createB() // expected-error{{value of optional type 'B?' must be unwrapped to a value of type 'B'}}
70+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
71+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
6072
}
6173

6274
// Crash with one-element tuple with labeled element
6375
class Dinner {}
6476

6577
func microwave() -> Dinner {
6678
let d: Dinner? = nil
67-
return (n: d) // expected-error{{value of optional type 'Dinner?' not unwrapped; did you mean to use '!' or '?'?}} {{16-16=!}}
79+
return (n: d) // expected-error{{value of optional type 'Dinner?' must be unwrapped to a value of type 'Dinner'}}
80+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
81+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
6882
}
6983

7084
func forgotAnyObjectBang(_ obj: AnyObject) {
@@ -89,7 +103,9 @@ func extraCall() {
89103
var i = 7
90104
i = i() // expected-error{{cannot call value of non-function type 'Int'}}{{8-10=}}
91105

92-
maybeFn()(5) // expected-error{{value of optional type '((Int) -> Int)?' not unwrapped; did you mean to use '!' or '?'?}}{{12-12=!}}
106+
maybeFn()(5) // expected-error{{value of optional type '((Int) -> Int)?' must be unwrapped to a value of type '(Int) -> Int'}}
107+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
108+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
93109
}
94110

95111
class U {

test/Constraints/if_expr.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ _ = (x: 1) ? true : false // expected-error {{'(x: Int)' is not convertible to '
6262
let ib: Bool! = false
6363
let eb: Bool? = .some(false)
6464
let conditional = ib ? "Broken" : "Heart" // should infer Bool!
65-
let conditional = eb ? "Broken" : "Heart" // expected-error {{value of optional type 'Bool?' not unwrapped; did you mean to use '!' or '?'?}}
65+
let conditional = eb ? "Broken" : "Heart" // expected-error {{value of optional type 'Bool?' must be unwrapped}}
66+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
67+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
6668

6769
// <rdar://problem/39586166> - crash when IfExpr has UnresolvedType in condition
6870
struct Delegate {

test/Constraints/iuo.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,10 @@ func conditionalDowncastToOptional(b: B?) -> D? {
210210
}
211211

212212
func conditionalDowncastToObject(b: B?) -> D {
213-
return b as? D! // expected-error {{value of optional type 'D?' not unwrapped; did you mean to use '!' or '?'?}}
214-
// expected-warning@-1 {{using '!' here is deprecated and will be removed in a future release}}
213+
return b as? D! // expected-error {{value of optional type 'D?' must be unwrapped}}
214+
// expected-note@-1{{coalesce}}
215+
// expected-note@-2{{force-unwrap}}
216+
// expected-warning@-3 {{using '!' here is deprecated and will be removed in a future release}}
215217
}
216218

217219
// Ensure that we select the overload that does *not* involve forcing an IUO.

test/Constraints/iuo_objc.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,34 @@ import Foundation
55

66
func iuo_error(prop: IUOProperty) {
77
let _: Coat? = prop.iuo.optional()
8-
// expected-error@-1 {{value of optional type '(() -> Coat?)?' not unwrapped; did you mean to use '!' or '?'?}}
8+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
9+
// expected-note@-2{{coalesce}}
10+
// expected-note@-3{{force-unwrap}}
911
let _: Coat? = prop.iuo.optional()!
1012
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
1113
let _: Coat? = prop.iuo.optional!()
1214
let _: Coat? = prop.iuo.optional!()!
1315
let _: Coat? = prop.iuo!.optional()
14-
// expected-error@-1 {{value of optional type '(() -> Coat?)?' not unwrapped; did you mean to use '!' or '?'?}}
16+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
17+
// expected-note@-2{{coalesce}}
18+
// expected-note@-3{{force-unwrap}}
1519
let _: Coat? = prop.iuo!.optional()!
1620
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
1721
let _: Coat? = prop.iuo!.optional!()
1822
let _: Coat? = prop.iuo!.optional!()!
1923
let _: Coat = prop.iuo.optional()
20-
// expected-error@-1 {{value of optional type '(() -> Coat)?' not unwrapped; did you mean to use '!' or '?'?}}
24+
// expected-error@-1 {{value of optional type '(() -> Coat)?' must be unwrapped}}
25+
// expected-note@-2{{coalesce}}
26+
// expected-note@-3{{force-unwrap}}
2127
let _: Coat = prop.iuo.optional()!
2228
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
2329
let _: Coat = prop.iuo.optional!()
2430
let _: Coat = prop.iuo.optional!()!
2531
let _: Coat = prop.iuo!.optional()
26-
// expected-error@-1 {{value of optional type '(() -> Coat)?' not unwrapped; did you mean to use '!' or '?'?}}
32+
// expected-error@-1 {{value of optional type '(() -> Coat)?' must be unwrapped}}
33+
// expected-note@-2{{coalesce}}
34+
// expected-note@-3{{force-unwrap}}
35+
2736
let _: Coat = prop.iuo!.optional()!
2837
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
2938
let _: Coat = prop.iuo!.optional!()

test/Constraints/overload.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ struct X1 {
153153
}
154154

155155
let x1 = X1(Int.self)
156-
let x1check: X1 = x1 // expected-error{{value of optional type 'X1?' not unwrapped; did you mean to use '!' or '?'?}}
156+
let x1check: X1 = x1 // expected-error{{value of optional type 'X1?' must be unwrapped}}
157+
// expected-note@-1{{coalesce}}
158+
// expected-note@-2{{force-unwrap}}
157159

158160

159161
struct X2 {
@@ -164,7 +166,9 @@ struct X2 {
164166
}
165167

166168
let x2 = X2(Int.self)
167-
let x2check: X2 = x2 // expected-error{{value of optional type 'X2?' not unwrapped; did you mean to use '!' or '?'?}}
169+
let x2check: X2 = x2 // expected-error{{value of optional type 'X2?' must be unwrapped}}
170+
// expected-note@-1{{coalesce}}
171+
// expected-note@-2{{force-unwrap}}
168172

169173
// rdar://problem/28051973
170174
struct R_28051973 {

test/Constraints/patterns.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ switch staticMembers {
292292
case .init(0): break
293293
case .init(_): break // expected-error{{'_' can only appear in a pattern}}
294294
case .init(let x): break // expected-error{{cannot appear in an expression}}
295-
case .init(opt: 0): break // expected-error{{not unwrapped}}
295+
case .init(opt: 0): break // expected-error{{pattern cannot match values of type 'StaticMembers'}}
296296

297297
case .prop: break
298298
// TODO: repeated error message
@@ -309,7 +309,7 @@ switch staticMembers {
309309
case .method(withLabel: let x): break // expected-error{{cannot appear in an expression}}
310310

311311
case .optMethod: break // expected-error{{cannot match}}
312-
case .optMethod(0): break // expected-error{{not unwrapped}}
312+
case .optMethod(0): break // expected-error{{pattern cannot match values of type 'StaticMembers'}}
313313
}
314314

315315
_ = 0

test/Generics/deduction.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,9 @@ func foo() {
318318
let j = min(Int(3), Float(2.5)) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}}
319319
let k = min(A(), A()) // expected-error{{argument type 'A' does not conform to expected type 'Comparable'}}
320320
let oi : Int? = 5
321-
let l = min(3, oi) // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}
321+
let l = min(3, oi) // expected-error{{value of optional type 'Int?' must be unwrapped}}
322+
// expected-note@-1{{coalesce}}
323+
// expected-note@-2{{force-unwrap}}
322324
}
323325

324326
infix operator +&

test/Migrator/rdar31892850.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ func foo() {
2121
// CHECK: {
2222
// CHECK: "file": "{{.*}}rdar31892850.swift",
2323
// CHECK: "offset": 327,
24-
// CHECK: "text": ")!"
24+
// CHECK: "text": ")"
2525
// CHECK: }
2626
// CHECK:]

0 commit comments

Comments
 (0)