Skip to content

Commit 69f3b28

Browse files
Merge pull request #39191 from LucianoPAlmeida/SR15161-warn-opt-bridge
[Sema][SR-15161] Be more conservative when emit warning for bridge downcast
2 parents 8817de5 + 57ce024 commit 69f3b28

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6663,6 +6663,13 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
66636663
return fix;
66646664
}
66656665
if (extraOptionals > 0) {
6666+
// Conditional cast in this case can be an attempt to just unwrap a nil
6667+
// value.
6668+
if (isExpr<ConditionalCheckedCastExpr>(anchor) &&
6669+
castKind == CheckedCastKind::BridgingCoercion) {
6670+
return nullptr;
6671+
}
6672+
66666673
return AllowCheckedCastCoercibleOptionalType::create(
66676674
cs, origFromType, origToType, castKind,
66686675
cs.getConstraintLocator(locator));

test/Constraints/bridging.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,3 +394,16 @@ func rdar60501780() {
394394
foo(["": "", "": v as NSString])
395395
}
396396
}
397+
398+
// SR-15161
399+
func SR15161_as(e: Error?) {
400+
let _ = e as? NSError // Ok
401+
}
402+
403+
func SR15161_is(e: Error?) {
404+
_ = e is NSError // expected-warning{{checking a value with optional type 'Error?' against dynamic type 'NSError' succeeds whenever the value is non-nil; did you mean to use '!= nil'?}}
405+
}
406+
407+
func SR15161_as_1(e: Error?) {
408+
let _ = e as! NSError // expected-warning{{forced cast from 'Error?' to 'NSError' only unwraps and bridges; did you mean to use '!' with 'as'?}}
409+
}

test/Constraints/casts_objc.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func alwaysSucceedingConditionalCasts(f: CGFloat, n: NSNumber) {
5555
}
5656

5757
func optionalityReducingCasts(f: CGFloat?, n: NSNumber?) {
58-
let _ = f as? NSNumber // expected-warning{{conditional downcast from 'CGFloat?' to 'NSNumber' is a bridging conversion; did you mean to use 'as'?}}
58+
let _ = f as? NSNumber
5959
let _ = f as! NSNumber // expected-warning{{forced cast from 'CGFloat?' to 'NSNumber' only unwraps and bridges; did you mean to use '!' with 'as'?}}
6060
let _ = n as? CGFloat
6161
let _ = n as! CGFloat
@@ -71,7 +71,7 @@ func optionalityMatchingCasts(f: CGFloat?, n: NSNumber?) {
7171

7272
func optionalityMatchingCastsIUO(f: CGFloat?!, n: NSNumber?!) {
7373
let _ = f as NSNumber?
74-
let _ = f as? NSNumber? // expected-warning{{conditional downcast from 'CGFloat??' to 'NSNumber?' is a bridging conversion; did you mean to use 'as'?}}
74+
let _ = f as? NSNumber?
7575
let _ = f as! NSNumber? // expected-warning{{forced cast from 'CGFloat??' to 'NSNumber?' only unwraps and bridges; did you mean to use '!' with 'as'?}}
7676
let _ = n as? CGFloat?
7777
let _ = n as! CGFloat?

test/expr/cast/bridged.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ func testBridgeDowncastSuperclass(_ obj: NSObject, objOpt: NSObject?,
7777
func testBridgeDowncastExact(_ obj: BridgedClass, objOpt: BridgedClass?,
7878
objImplicitOpt: BridgedClass!) -> BridgedStruct? {
7979
_ = obj as? BridgedStruct // expected-warning{{conditional cast from 'BridgedClass' to 'BridgedStruct' always succeeds}}
80-
_ = objOpt as? BridgedStruct // expected-warning{{conditional downcast from 'BridgedClass?' to 'BridgedStruct' is a bridging conversion; did you mean to use 'as'?}}{{14-17=as}}{{31-31=?}}
81-
_ = objImplicitOpt as? BridgedStruct // expected-warning{{conditional downcast from 'BridgedClass?' to 'BridgedStruct' is a bridging conversion; did you mean to use 'as'?}}{{22-25=as}}{{39-39=?}}
80+
_ = objOpt as? BridgedStruct
81+
_ = objImplicitOpt as? BridgedStruct
8282

8383
_ = obj as! BridgedStruct // expected-warning{{forced cast from 'BridgedClass' to 'BridgedStruct' always succeeds; did you mean to use 'as'?}}{{11-14=as}}
8484
_ = objOpt as! BridgedStruct // expected-warning{{forced cast from 'BridgedClass?' to 'BridgedStruct' only unwraps and bridges; did you mean to use '!' with 'as'?}}{{13-13=!}}{{14-17=as}}

0 commit comments

Comments
 (0)