Skip to content

Commit 0874ea4

Browse files
authored
Merge pull request #15624 from rudkx/rdar37121121
Emit a different diagnostic for Swift 3/4 for 'as T!'.
2 parents 99dcfae + f47218c commit 0874ea4

File tree

5 files changed

+36
-14
lines changed

5 files changed

+36
-14
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3166,6 +3166,9 @@ ERROR(tuple_ellipsis,none,
31663166
WARNING(implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional,none,
31673167
"using '!' is not allowed here; treating this as '?' instead", ())
31683168

3169+
WARNING(implicitly_unwrapped_optional_deprecated_in_this_position,none,
3170+
"using '!' here is deprecated and will be removed in a future release", ())
3171+
31693172
ERROR(implicitly_unwrapped_optional_in_illegal_position,none,
31703173
"using '!' is not allowed here; perhaps '?' was intended?", ())
31713174

lib/Sema/CSGen.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,6 +2525,9 @@ namespace {
25252525
// Validate the resulting type.
25262526
TypeResolutionOptions options = TypeResolutionFlags::AllowUnboundGenerics;
25272527
options |= TypeResolutionFlags::InExpression;
2528+
// Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
2529+
if (!CS.getASTContext().isSwiftVersionAtLeast(5))
2530+
options |= TypeResolutionFlags::AllowIUODeprecated;
25282531
if (tc.validateType(expr->getCastTypeLoc(), CS.DC, options))
25292532
return nullptr;
25302533

@@ -2554,6 +2557,9 @@ namespace {
25542557
// Validate the resulting type.
25552558
TypeResolutionOptions options = TypeResolutionFlags::AllowUnboundGenerics;
25562559
options |= TypeResolutionFlags::InExpression;
2560+
// Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
2561+
if (!CS.getASTContext().isSwiftVersionAtLeast(5))
2562+
options |= TypeResolutionFlags::AllowIUODeprecated;
25572563
if (tc.validateType(expr->getCastTypeLoc(), CS.DC, options))
25582564
return nullptr;
25592565

@@ -2588,6 +2594,9 @@ namespace {
25882594
// Validate the resulting type.
25892595
TypeResolutionOptions options = TypeResolutionFlags::AllowUnboundGenerics;
25902596
options |= TypeResolutionFlags::InExpression;
2597+
// Prior to Swift 5, we allow 'as T!' and turn it into a disjunction.
2598+
if (!CS.getASTContext().isSwiftVersionAtLeast(5))
2599+
options |= TypeResolutionFlags::AllowIUODeprecated;
25912600
if (tc.validateType(expr->getCastTypeLoc(), CS.DC, options))
25922601
return nullptr;
25932602

lib/Sema/TypeCheckType.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,14 +2777,21 @@ Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
27772777
ImplicitlyUnwrappedOptionalTypeRepr *repr,
27782778
TypeResolutionOptions options) {
27792779
if (!options.contains(TypeResolutionFlags::AllowIUO)) {
2780-
Diagnostic diag = diag::
2781-
implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional;
2782-
2783-
if (TC.Context.isSwiftVersionAtLeast(5))
2784-
diag = diag::implicitly_unwrapped_optional_in_illegal_position;
2785-
2786-
TC.diagnose(repr->getStartLoc(), diag)
2787-
.fixItReplace(repr->getExclamationLoc(), "?");
2780+
if (options.contains(TypeResolutionFlags::AllowIUODeprecated)) {
2781+
TC.diagnose(
2782+
repr->getStartLoc(),
2783+
diag::implicitly_unwrapped_optional_deprecated_in_this_position);
2784+
} else if (!TC.Context.isSwiftVersionAtLeast(5)) {
2785+
TC.diagnose(
2786+
repr->getStartLoc(),
2787+
diag::
2788+
implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional)
2789+
.fixItReplace(repr->getExclamationLoc(), "?");
2790+
} else {
2791+
TC.diagnose(repr->getStartLoc(),
2792+
diag::implicitly_unwrapped_optional_in_illegal_position)
2793+
.fixItReplace(repr->getExclamationLoc(), "?");
2794+
}
27882795
}
27892796

27902797
auto elementOptions = withoutContext(options, true);

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ enum class TypeResolutionFlags : unsigned {
539539

540540
/// Is it okay to resolve an IUO sigil ("!") here?
541541
AllowIUO = 0x4000000,
542+
543+
/// Is it okay to resolve an IUO sigil ("!") here with a deprecation warning?
544+
AllowIUODeprecated = 0x8000000,
542545
};
543546

544547
/// Option set describing how type resolution should work.

test/Sema/diag_deprecated_iuo.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { //
201201
let x0 = 1 as ImplicitlyUnwrappedOptional // expected-error {{'ImplicitlyUnwrappedOptional' has been renamed to 'Optional'}}{{15-42=Optional}}
202202

203203
let x: Int? = 1
204-
let y0: Int = x as Int! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{23-24=?}}
205-
let y1: Int = (x as Int!)! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{24-25=?}}
206-
let z0: Int = x as! Int! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{24-25=?}}
204+
let y0: Int = x as Int! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
205+
let y1: Int = (x as Int!)! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
206+
let z0: Int = x as! Int! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
207207
// expected-warning@-1 {{forced cast of 'Int?' to same type has no effect}}
208-
let z1: Int = (x as! Int!)! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{25-26=?}}
208+
let z1: Int = (x as! Int!)! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
209209
// expected-warning@-1 {{forced cast of 'Int?' to same type has no effect}}
210-
let w0: Int = (x as? Int!)! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{25-26=?}}
210+
let w0: Int = (x as? Int!)! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
211211
// expected-warning@-1 {{conditional cast from 'Int?' to 'Int?' always succeeds}}
212-
let w1: Int = (x as? Int!)!! // expected-warning {{using '!' is not allowed here; treating this as '?' instead}}{{25-26=?}}
212+
let w1: Int = (x as? Int!)!! // expected-warning {{using '!' here is deprecated and will be removed in a future release}}
213213
// expected-warning@-1 {{conditional cast from 'Int?' to 'Int?' always succeeds}}
214214

215215
func overloadedByOptionality(_ a: inout Int!) {}

0 commit comments

Comments
 (0)