Skip to content

Commit b517ed3

Browse files
[Sema] Suggest for unwrap fix-it instead of coercion if a subtype relation exists with from and to types
1 parent 8c42438 commit b517ed3

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,6 +2953,20 @@ bool ContextualFailure::tryTypeCoercionFixIt(
29532953
if (!toType->hasTypeRepr())
29542954
return false;
29552955

2956+
// If optional unwrapped type is a subtype of the specified contextual type,
2957+
// let's suggest a force unwrap "!". Otherwise fallback to potential coercion
2958+
// or force cast.
2959+
if (!bothOptional && fromType->getOptionalObjectType()) {
2960+
if (TypeChecker::isSubtypeOf(fromType->lookThroughAllOptionalTypes(),
2961+
toType, getDC())) {
2962+
diagnostic.fixItInsert(
2963+
Lexer::getLocForEndOfToken(getASTContext().SourceMgr,
2964+
getSourceRange().End),
2965+
"!");
2966+
return true;
2967+
}
2968+
}
2969+
29562970
CheckedCastKind Kind =
29572971
TypeChecker::typeCheckCheckedCast(fromType, toType,
29582972
CheckedCastContextKind::None, getDC(),

test/Constraints/casts.swift

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -614,22 +614,40 @@ func decodeStringOrIntDictionary<T: FixedWidthInteger>() -> [Int: T] {
614614
}
615615
}
616616

617+
617618
// SR-15281
618619
struct SR15281_A { }
619-
620620
struct SR15281_B {
621621
init(a: SR15281_A) { }
622622
}
623623

624624
struct SR15281_S {
625625
var a: SR15281_A? = SR15281_A()
626626

627+
var b: SR15281_B {
628+
a.flatMap(SR15281_B.init(a:)) // expected-error{{cannot convert return expression of type 'SR15281_B?' to return type 'SR15281_B'}} {{34-34=!}}
629+
}
630+
627631
var b1: SR15281_B {
628632
a.flatMap(SR15281_B.init(a:)) as! SR15281_B
629633
// expected-warning@-1 {{forced cast from 'SR15281_B?' to 'SR15281_B' only unwraps optionals; did you mean to use '!'?}} {{34-34=!}} {{34-48=}}
630634
}
635+
}
636+
637+
class SR15281_AC {}
638+
class SR15281_BC {
639+
init(a: SR15281_AC) { }
640+
}
641+
class SR15281_CC: SR15281_BC {}
642+
643+
struct SR15281_SC {
644+
var a: SR15281_AC? = SR15281_AC()
645+
646+
var b: SR15281_BC {
647+
a.flatMap(SR15281_BC.init(a:)) // expected-error{{cannot convert return expression of type 'SR15281_BC?' to return type 'SR15281_BC'}} {{35-35=!}}
648+
}
631649

632-
var b: SR15281_B {
633-
a.flatMap(SR15281_B.init(a:)) // expected-error{{cannot convert return expression of type 'SR15281_B?' to return type 'SR15281_B'}} {{34-34= as! SR15281_B}}
650+
var c: SR15281_BC {
651+
a.flatMap(SR15281_CC.init(a:)) // expected-error{{cannot convert return expression of type 'SR15281_CC?' to return type 'SR15281_BC'}} {{35-35=!}}
634652
}
635653
}

0 commit comments

Comments
 (0)