Skip to content

Commit cef6c94

Browse files
committed
Fix more places where were allowing IUOs but shouldn't.
My previous commit, f9b82bc, failed to ensure that IUOs could not be nested inside of other types in all positions.
1 parent dded839 commit cef6c94

File tree

6 files changed

+99
-17
lines changed

6 files changed

+99
-17
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4252,7 +4252,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
42524252
&resolver);
42534253
TypeResolutionOptions options;
42544254
options |= TR_SubscriptParameters;
4255-
options |= TR_AllowIUO;
42564255

42574256
isInvalid |= TC.typeCheckParameterList(SD->getIndices(), SD,
42584257
options,
@@ -4792,8 +4791,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
47924791
GenericTypeResolver &resolver) {
47934792
bool hadError = false;
47944793
for (auto paramList : fd->getParameterLists()) {
4795-
hadError |=
4796-
TC.typeCheckParameterList(paramList, fd, TR_AllowIUO, resolver);
4794+
hadError |= TC.typeCheckParameterList(paramList, fd,
4795+
TypeResolutionOptions(), resolver);
47974796
}
47984797

47994798
return hadError;

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ static bool checkGenericFuncSignature(TypeChecker &tc,
457457
// Check the parameter patterns.
458458
for (auto params : func->getParameterLists()) {
459459
// Check the pattern.
460-
if (tc.typeCheckParameterList(params, func, TR_AllowIUO,
460+
if (tc.typeCheckParameterList(params, func, TypeResolutionOptions(),
461461
resolver))
462462
badType = true;
463463

@@ -932,8 +932,7 @@ static bool checkGenericSubscriptSignature(TypeChecker &tc,
932932

933933
// Check the element type.
934934
badType |= tc.validateType(subscript->getElementTypeLoc(), subscript,
935-
TypeResolutionOptions(),
936-
&resolver);
935+
TR_AllowIUO, &resolver);
937936

938937
// Infer requirements from it.
939938
if (genericParams && builder) {
@@ -951,7 +950,6 @@ static bool checkGenericSubscriptSignature(TypeChecker &tc,
951950

952951
TypeResolutionOptions options;
953952
options |= TR_SubscriptParameters;
954-
options |= TR_AllowIUO;
955953

956954
badType |= tc.typeCheckParameterList(params, subscript,
957955
options,

lib/Sema/TypeCheckPattern.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
691691
auto elementOptions = (options |
692692
(decl->isVariadic() ? TR_VariadicFunctionInput
693693
: TR_FunctionInput));
694+
if (!decl->isVariadic())
695+
elementOptions |= TR_AllowIUO;
696+
694697
bool hadError = false;
695698

696699
// We might have a null typeLoc if this is a closure parameter list,

lib/Sema/TypeCheckType.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ Type TypeChecker::applyUnboundGenericArguments(
501501
options -= TR_FunctionInput;
502502
options -= TR_TypeAliasUnderlyingType;
503503
options -= TR_AllowUnavailableProtocol;
504+
options -= TR_AllowIUO;
504505

505506
assert(genericArgs.size() == decl->getGenericParams()->size() &&
506507
"invalid arguments, use applyGenericArguments for diagnostic emitting");
@@ -2774,17 +2775,18 @@ Type TypeResolver::resolveOptionalType(OptionalTypeRepr *repr,
27742775
Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
27752776
ImplicitlyUnwrappedOptionalTypeRepr *repr,
27762777
TypeResolutionOptions options) {
2777-
auto elementOptions = withoutContext(options, true);
2778-
elementOptions |= TR_ImmediateOptionalTypeArgument;
27792778

27802779
// Swift version >= 5? Use the newer check for IUOs appearing in
27812780
// illegal positions.
2782-
if (TC.Context.isSwiftVersionAtLeast(5) &&
2783-
!elementOptions.contains(TR_AllowIUO)) {
2781+
if (TC.Context.isSwiftVersionAtLeast(5) && !options.contains(TR_AllowIUO)) {
27842782
TC.diagnose(repr->getStartLoc(), diag::iuo_in_illegal_position)
27852783
.fixItReplace(repr->getExclamationLoc(), "?");
2784+
return ErrorType::get(Context);
27862785
}
27872786

2787+
auto elementOptions = withoutContext(options, true);
2788+
elementOptions |= TR_ImmediateOptionalTypeArgument;
2789+
27882790
// The T in T! is a generic type argument and therefore always an AST type.
27892791
// FIXME: diagnose non-materializability of element type!
27902792
Type baseTy = resolveType(repr->getBase(), elementOptions);

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ withoutContext(TypeResolutionOptions options, bool preserveSIL = false) {
557557
options -= TR_VariadicFunctionInput;
558558
options -= TR_EnumCase;
559559
options -= TR_ImmediateOptionalTypeArgument;
560+
options -= TR_AllowIUO;
560561
if (!preserveSIL) options -= TR_SILType;
561562
return options;
562563
}

test/Sema/diag_erroneous_iuo.swift

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,72 @@
11
// RUN: %target-typecheck-verify-swift -swift-version 5
22

3+
// These are all legal uses of '!'.
4+
struct Fine {
5+
var value: Int!
6+
7+
func m(_ unnamed: Int!, named: Int!) -> Int! { return unnamed }
8+
static func s(_ unnamed: Int!, named: Int!) -> Int! { return named }
9+
10+
init(_ value: Int) { self.value = value }
11+
init!() { return nil }
12+
13+
subscript (
14+
index: Int!
15+
) -> Int! {
16+
return index
17+
}
18+
19+
subscript<T> (
20+
index: T!
21+
) -> T! {
22+
return index
23+
}
24+
}
25+
326
let _: ImplicitlyUnwrappedOptional<Int> = 1 // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{8-36=}}{{39-39=!}}{{39-40=}}
427
let _: ImplicitlyUnwrappedOptional = 1 // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' in unsupported; use an explicit type followed by '!'}}
528

629
extension ImplicitlyUnwrappedOptional {} // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
730

8-
func function(
31+
func functionSpelling(
932
_: ImplicitlyUnwrappedOptional<Int> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{37-37=!}}{{37-38=}}
1033
) -> ImplicitlyUnwrappedOptional<Int> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{37-37=!}}{{37-38=}}
1134
return 1
1235
}
1336

37+
// Okay, like in the method case.
38+
func functionSigil(
39+
_: Int!
40+
) -> Int! {
41+
return 1
42+
}
43+
44+
// Not okay because '!' is not at the top level of the type.
45+
func functionSigilArray(
46+
_: [Int!] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
47+
) -> [Int!] { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
48+
return [1]
49+
}
50+
1451
func genericFunction<T>(
1552
iuo: ImplicitlyUnwrappedOptional<T> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{8-36=}}{{37-37=!}}{{37-38=}}
1653
) -> ImplicitlyUnwrappedOptional<T> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{6-34=}}{{35-35=!}}{{35-36=}}
1754
return iuo
1855
}
1956

57+
// Okay, like in the non-generic case.
58+
func genericFunctionSigil<T>(
59+
iuo: T!
60+
) -> T! {
61+
return iuo
62+
}
63+
64+
func genericFunctionSigilArray<T>(
65+
iuo: [T!] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
66+
) -> [T!] { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
67+
return iuo
68+
}
69+
2070
protocol P {
2171
associatedtype T
2272
associatedtype U
@@ -26,11 +76,23 @@ struct S : P {
2676
typealias T = ImplicitlyUnwrappedOptional<Int> // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
2777
typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
2878

79+
typealias V = Int! // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
80+
typealias W = Int!? // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
81+
82+
var x: V
83+
var y: W
84+
2985
subscript (
3086
index: ImplicitlyUnwrappedOptional<Int> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{43-43=!}}{{43-44=}}
3187
) -> ImplicitlyUnwrappedOptional<Int> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{43-43=!}}{{43-44=}}
3288
return index
3389
}
90+
91+
subscript<T> (
92+
index: ImplicitlyUnwrappedOptional<T> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{41-41=!}}{{41-42=}}
93+
) -> ImplicitlyUnwrappedOptional<T> { // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{41-41=!}}{{41-42=}}
94+
return index
95+
}
3496
}
3597

3698
func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
@@ -45,16 +107,33 @@ func testClosure() -> Int {
45107
}
46108

47109
_ = Array<Int!>() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
110+
let _: Array<Int!> = [1] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
48111
_ = [Int!]() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
112+
let _: [Int!] = [1] // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
49113
_ = Optional<Int!>(nil) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
114+
let _: Optional<Int!> = nil // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
50115
_ = Int!?(0) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
116+
let _: Int!? = 0 // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
51117
_ = (
52118
Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
53-
Float!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
54-
String! // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
119+
Float!,
120+
String!
55121
)(1, 2.0, "3")
122+
let _: (
123+
Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
124+
Float!,
125+
String!
126+
) = (1, 2.0, "3")
56127

57-
struct Generic<T, U, C> {}
128+
struct Generic<T, U, C> {
129+
init(_ t: T, _ u: U, _ c: C) {}
130+
}
58131
_ = Generic<Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
59-
Float!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
60-
String!>() // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
132+
Float!,
133+
String!>(1, 2.0, "3")
134+
let _: Generic<Int!, // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
135+
Float!,
136+
String!> = Generic(1, 2.0, "3")
137+
138+
func vararg(_ first: Int, more: Int!...) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
139+
}

0 commit comments

Comments
 (0)