Skip to content

[DO NOT MERGE] Make Swift 3 / 4 consistent with SE-0054. #12682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -3103,12 +3103,6 @@ ERROR(tuple_single_element,none,
ERROR(tuple_ellipsis,none,
"cannot create a variadic tuple", ())

WARNING(implicitly_unwrapped_optional_spelling_deprecated,none,
"the spelling 'ImplicitlyUnwrappedOptional' is deprecated", ())

WARNING(implicitly_unwrapped_optional_spelling_deprecated_with_fixit,none,
"the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name", ())

ERROR(implicitly_unwrapped_optional_spelling_error,none,
"the spelling 'ImplicitlyUnwrappedOptional' in unsupported; use an explicit type followed by '!'", ())

Expand Down
95 changes: 9 additions & 86 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1191,11 +1191,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
assert(genericTyR->getGenericArgs().size() == 1);
auto *genericArgTyR = genericTyR->getGenericArgs()[0];

Diagnostic diag = diag::implicitly_unwrapped_optional_spelling_deprecated_with_fixit;

// For Swift 5 and later, spelling the full name is an error.
if (TC.Context.isSwiftVersionAtLeast(5))
diag = diag::implicitly_unwrapped_optional_spelling_error_with_fixit;
Diagnostic diag = diag::implicitly_unwrapped_optional_spelling_error_with_fixit;

TC.diagnose(comp->getStartLoc(), diag)
.fixItRemoveChars(
Expand All @@ -1206,15 +1202,11 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
genericTyR->getAngleBrackets().End,
genericTyR->getAngleBrackets().End.getAdvancedLoc(1));
} else {
Diagnostic diag = diag::implicitly_unwrapped_optional_spelling_deprecated;

// For Swift 5 and later, spelling the full name is an error.
if (TC.Context.isSwiftVersionAtLeast(5))
diag = diag::implicitly_unwrapped_optional_spelling_error;
Diagnostic diag = diag::implicitly_unwrapped_optional_spelling_error;

TC.diagnose(comp->getStartLoc(), diag);
}
} else if (TC.Context.isSwiftVersionAtLeast(5)) {
} else {
if (isa<GenericIdentTypeRepr>(comp)) {
auto *genericTyR = cast<GenericIdentTypeRepr>(comp);
assert(genericTyR->getGenericArgs().size() == 1);
Expand All @@ -1231,10 +1223,6 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
} else {
TC.diagnose(comp->getStartLoc(), diag::iuo_in_illegal_position);
}
} else {
// Pre-Swift-5 warning for spelling ImplicitlyUnwrappedOptional
// in places we shouldn't even allow it.
TC.diagnose(comp->getStartLoc(), diag::implicitly_unwrapped_optional_spelling_deprecated);
}
}

Expand Down Expand Up @@ -1565,65 +1553,6 @@ Type TypeChecker::resolveIdentifierType(
return result;
}

/// Returns true if any illegal IUOs were found. If inference of IUO type is
/// disabled, IUOs may only be specified in the following positions:
/// * outermost type
/// * function param
/// * function return type
static bool checkForIllegalIUOs(TypeChecker &TC, TypeRepr *Repr,
TypeResolutionOptions Options) {
class IllegalIUOWalker : public ASTWalker {
TypeChecker &TC;
SmallVector<bool, 4> IUOsAllowed;
bool FoundIllegalIUO = false;

public:
IllegalIUOWalker(TypeChecker &TC, bool IsGenericParameter)
: TC(TC)
, IUOsAllowed{!IsGenericParameter} {}

bool walkToTypeReprPre(TypeRepr *T) override {
bool iuoAllowedHere = IUOsAllowed.back();

// Raise a diagnostic if we run into a prohibited IUO.
if (!iuoAllowedHere) {
if (auto *iuoTypeRepr =
dyn_cast<ImplicitlyUnwrappedOptionalTypeRepr>(T)) {
TC.diagnose(iuoTypeRepr->getStartLoc(), diag::iuo_in_illegal_position)
.fixItReplace(iuoTypeRepr->getExclamationLoc(), "?");
FoundIllegalIUO = true;
}
}

bool childIUOsAllowed = false;
if (iuoAllowedHere) {
if (auto *tupleTypeRepr = dyn_cast<TupleTypeRepr>(T)) {
if (tupleTypeRepr->isParenType()) {
childIUOsAllowed = true;
}
} else if (isa<FunctionTypeRepr>(T)) {
childIUOsAllowed = true;
} else if (isa<AttributedTypeRepr>(T) || isa<InOutTypeRepr>(T)) {
childIUOsAllowed = true;
}
}
IUOsAllowed.push_back(childIUOsAllowed);
return true;
}

bool walkToTypeReprPost(TypeRepr *T) override {
IUOsAllowed.pop_back();
return true;
}

bool getFoundIllegalIUO() const { return FoundIllegalIUO; }
};

IllegalIUOWalker Walker(TC, Options.contains(TR_GenericSignature));
Repr->walk(Walker);
return Walker.getFoundIllegalIUO();
}

bool TypeChecker::validateType(TypeLoc &Loc, DeclContext *DC,
TypeResolutionOptions options,
GenericTypeResolver *resolver,
Expand All @@ -1640,13 +1569,6 @@ bool TypeChecker::validateType(TypeLoc &Loc, DeclContext *DC,
Context.Stats->getFrontendCounters().NumTypesValidated++;

if (Loc.getType().isNull()) {
// Swift version < 5? Use the old "illegal IUO" check for
// backwards compatibiliy.
if (!Context.isSwiftVersionAtLeast(5)) {
// Raise error if we parse an IUO type in an illegal position.
checkForIllegalIUOs(*this, Loc.getTypeRepr(), options);
}

auto type = resolveType(Loc.getTypeRepr(), DC, options, resolver,
unsatisfiedDependency);
if (!type) {
Expand Down Expand Up @@ -2815,10 +2737,7 @@ Type TypeResolver::resolveOptionalType(OptionalTypeRepr *repr,
Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
ImplicitlyUnwrappedOptionalTypeRepr *repr,
TypeResolutionOptions options) {

// Swift version >= 5? Use the newer check for IUOs appearing in
// illegal positions.
if (TC.Context.isSwiftVersionAtLeast(5) && !options.contains(TR_AllowIUO)) {
if (!options.contains(TR_AllowIUO)) {
TC.diagnose(repr->getStartLoc(), diag::iuo_in_illegal_position)
.fixItReplace(repr->getExclamationLoc(), "?");
return ErrorType::get(Context);
Expand Down Expand Up @@ -2851,7 +2770,11 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
auto elementOptions = options;
if (repr->isParenType()) {
// We also want to disallow IUO within even a paren.
elementOptions -= TR_AllowIUO;
// FIXME: Until we remove the IUO type from the type system, we
// need to continue to parse IUOs in SIL tests so that we can
// match the types we generate from the importer.
if (!options.contains(TR_SILMode))
elementOptions -= TR_AllowIUO;

// If we have a single ParenType, don't clear the context bits; we
// still want to parse the type contained therein as if it were in
Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/blocks_parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ someNSString.enumerateLines({ useString($0) })
accepts_block(/*not a block=*/()) // expected-error{{cannot convert value of type '()' to expected argument type 'my_block_t' (aka '() -> ()'}}

func testNoEscape(f: @convention(block) () -> Void, nsStr: NSString,
fStr: (String!) -> Void) {
fStr: (String?) -> Void) {
accepts_noescape_block(f)
accepts_noescape_block(f)

Expand Down
8 changes: 4 additions & 4 deletions test/ClangImporter/objc_bridging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ extension Set {
}

func foo() {
_ = NSStringToNSString as (String!) -> String?
_ = NSStringToNSString as (String?) -> String?
_ = DummyClass().nsstringProperty.onlyOnString() as String

_ = BOOLtoBOOL as (Bool) -> Bool
_ = DummyClass().boolProperty.onlyOnBool() as Bool

_ = arrayToArray as (Array<Any>!) -> (Array<Any>!)
_ = arrayToArray as (Array<Any>?) -> (Array<Any>?)
DummyClass().arrayProperty.onlyOnArray()

_ = dictToDict as (Dictionary<AnyHashable, Any>!) -> Dictionary<AnyHashable, Any>!
_ = dictToDict as (Dictionary<AnyHashable, Any>?) -> Dictionary<AnyHashable, Any>?

DummyClass().dictProperty.onlyOnDictionary()

_ = setToSet as (Set<AnyHashable>!) -> Set<AnyHashable>!
_ = setToSet as (Set<AnyHashable>?) -> Set<AnyHashable>?
DummyClass().setProperty.onlyOnSet()
}

Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/objc_parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ func testPreferClassMethodToCurriedInstanceMethod(_ obj: NSObject) {
// FIXME: We shouldn't need the ": Bool" type annotation here.
// <rdar://problem/18006008>
let _: Bool = NSObject.isEqual(obj)
_ = NSObject.isEqual(obj) as (NSObject!) -> Bool // no-warning
_ = NSObject.isEqual(obj) as (NSObject?) -> Bool // no-warning
}


Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/keyword_arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ trailingclosure1(1) { return 5 } // expected-error{{missing argument label 'x:'

trailingclosure1(x: 1, { return 5 }) // expected-error{{missing argument label 'f:' in call}} {{24-24=f: }}

func trailingclosure2(x: Int, f: (() -> Int)!...) {}
func trailingclosure2(x: Int, f: (() -> Int)...) {}
trailingclosure2(x: 5) { return 5 }

func trailingclosure3(x: Int, f: (() -> Int)!) {
Expand Down
10 changes: 5 additions & 5 deletions test/Constraints/protocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,11 @@ func testClonableArchetype<T : Clonable>(_ t: T) {
let _: (Bool) -> T? = id(t.extMaybeClone)
let _: T? = id(t.extMaybeClone(true))

let _: (T) -> (Bool) -> T! = id(T.extProbablyClone)
let _: (Bool) -> T! = id(T.extProbablyClone(t))
let _: (T) -> (Bool) -> T! = id(T.extProbablyClone) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
let _: (Bool) -> T! = id(T.extProbablyClone(t)) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
let _: T! = id(T.extProbablyClone(t)(true))

let _: (Bool) -> T! = id(t.extProbablyClone)
let _: (Bool) -> T! = id(t.extProbablyClone) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
let _: T! = id(t.extProbablyClone(true))

// Static member of extension returning Self)
Expand All @@ -332,7 +332,7 @@ func testClonableArchetype<T : Clonable>(_ t: T) {
let _: (Bool) -> T? = id(T.returnSelfOptionalStatic)
let _: T? = id(T.returnSelfOptionalStatic(false))

let _: (Bool) -> T! = id(T.returnSelfIUOStatic)
let _: (Bool) -> T! = id(T.returnSelfIUOStatic) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
let _: T! = id(T.returnSelfIUOStatic(true))
}

Expand All @@ -358,7 +358,7 @@ func testClonableExistential(_ v: Clonable, _ vv: Clonable.Type) {
let _: (Bool) -> Clonable? = id(vv.returnSelfOptionalStatic)
let _: Clonable? = id(vv.returnSelfOptionalStatic(false))

let _: (Bool) -> Clonable! = id(vv.returnSelfIUOStatic)
let _: (Bool) -> Clonable! = id(vv.returnSelfIUOStatic) // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
let _: Clonable! = id(vv.returnSelfIUOStatic(true))

let _ = v.badClonerFn() // expected-error {{member 'badClonerFn' cannot be used on value of protocol type 'Clonable'; use a generic constraint instead}}
Expand Down
8 changes: 3 additions & 5 deletions test/Interpreter/FunctionConversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,20 @@ func a1(s: AddrOnly?) -> AddrOnly {

FunctionConversionTestSuite.test("Optional") {
let g11: (Trivial) -> Trivial? = t1
let g12: (Trivial!) -> Trivial? = t1
let g12: (Trivial?) -> Trivial? = t1

expectEqual(22, g11(Trivial(n: 11))?.n)
expectEqual(24, g12(Trivial(n: 12))?.n)

let g21: (Loadable?) -> Loadable? = l1
let g22: (Loadable!) -> Loadable? = l1
let g22: (Loadable?) -> Loadable? = l1

expectEqual(42, g21(Loadable(n: 21))?.n)
expectEqual(44, g22(Loadable(n: 22))?.n)

let g31: (AddrOnly?) -> AddrOnly? = a1
let g32: (AddrOnly!) -> AddrOnly? = a1
let g32: (AddrOnly?) -> AddrOnly? = a1

expectEqual(62, g31(AddrOnly(n: 31))?.n)
expectEqual(64, g32(AddrOnly(n: 32))?.n)
}

func t2(s: Quilt) -> Trivial {
Expand Down
2 changes: 1 addition & 1 deletion test/Migrator/Inputs/Cities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ open class Cities {

public protocol ExtraCities {
func coolum(x: [String : [Int : [(((String))?)]]])
func blibli(x: (String?, String) -> String!)
func blibli(x: (String?, String) -> String?)
func currimundi(x: (Int, (Int, Int))!)
}

Expand Down
12 changes: 4 additions & 8 deletions test/Migrator/wrap_optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,20 @@ extension ExtraCities {
}

class MyExtraCities : ExtraCities {
func blibli(x: (String?, String) -> String!) {}
func blibli(x: (String?, String) -> String?) {}
func currimundi(x: (Int, (Int, Int))!) {}
}

typealias IntAnd<T> = (Int, T)
class Outer {
typealias Inner = (String?, String) -> String!
}

class MyExtraCitiesWithAliases : ExtraCities {
func blibli(x: Outer.Inner) {}
func blibli(x: (String?, String) -> String?) {}
func currimundi(x: (Int, IntAnd<Int>)!) {}
}

typealias OptString = String?
typealias ImplicitlyUnwrapped<T> = T!

class MyExtraCitiesWithMoreAliases : ExtraCities {
func blibli(x: (OptString, String) -> String!) {}
func currimundi(x: ImplicitlyUnwrapped<(Int, (Int, Int))>) {}
func blibli(x: (OptString, String) -> String?) {}
func currimundi(x: (Int, (Int, Int))!) {}
}
12 changes: 4 additions & 8 deletions test/Migrator/wrap_optional.swift.expected
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,20 @@ extension ExtraCities {
}

class MyExtraCities : ExtraCities {
func blibli(x: ((String, String) -> String?)?) {}
func blibli(x: (String?, String) -> String?) {}
func currimundi(x: (Int, (Int?, Int))?) {}
}

typealias IntAnd<T> = (Int, T)
class Outer {
typealias Inner = (String?, String) -> String!
}

class MyExtraCitiesWithAliases : ExtraCities {
func blibli(x: Outer.Inner?) {}
func blibli(x: (String?, String) -> String?) {}
func currimundi(x: (Int, IntAnd<Int>)?) {}
}

typealias OptString = String?
typealias ImplicitlyUnwrapped<T> = T!

class MyExtraCitiesWithMoreAliases : ExtraCities {
func blibli(x: ((OptString, String) -> String?)?) {}
func currimundi(x: ImplicitlyUnwrapped<(Int, (Int, Int))>) {}
func blibli(x: (OptString, String) -> String?) {}
func currimundi(x: (Int, (Int?, Int))?) {}
}
2 changes: 1 addition & 1 deletion test/Parse/optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ var e : (() -> A)?
var f = e?()

struct B<T> {}
var g = B<A!>()
var g = B<A?>()
8 changes: 2 additions & 6 deletions test/SILGen/function_conversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func convOptionalTrivial(_ t1: @escaping (Trivial?) -> Trivial) {

// CHECK: function_ref @_T019function_conversion7TrivialVSgACIexyd_A2DIexyd_TR
// CHECK: partial_apply
let _: (Trivial!) -> Trivial? = t1
let _: (Trivial?) -> Trivial? = t1
}

// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T019function_conversion7TrivialVSgACIexyd_AcDIexyd_TR : $@convention(thin) (Trivial, @owned @callee_owned (Optional<Trivial>) -> Trivial) -> Optional<Trivial>
Expand All @@ -151,7 +151,7 @@ func convOptionalLoadable(_ l1: @escaping (Loadable?) -> Loadable) {

// CHECK: function_ref @_T019function_conversion8LoadableVSgACIexxo_A2DIexxo_TR
// CHECK: partial_apply
let _: (Loadable!) -> Loadable? = l1
let _: (Loadable?) -> Loadable? = l1
}

// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T019function_conversion8LoadableVSgACIexxo_A2DIexxo_TR : $@convention(thin) (@owned Optional<Loadable>, @owned @callee_owned (@owned Optional<Loadable>) -> @owned Loadable) -> @owned Optional<Loadable>
Expand All @@ -164,10 +164,6 @@ func convOptionalAddrOnly(_ a1: @escaping (AddrOnly?) -> AddrOnly) {
// CHECK: function_ref @_T019function_conversion8AddrOnlyVSgACIexir_A2DIexir_TR
// CHECK: partial_apply
let _: (AddrOnly?) -> AddrOnly? = a1

// CHECK: function_ref @_T019function_conversion8AddrOnlyVSgACIexir_A2DIexir_TR
// CHECK: partial_apply
let _: (AddrOnly!) -> AddrOnly? = a1
}

// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T019function_conversion8AddrOnlyVSgACIexir_A2DIexir_TR : $@convention(thin) (@in Optional<AddrOnly>, @owned @callee_owned (@in Optional<AddrOnly>) -> @out AddrOnly) -> @out Optional<AddrOnly>
Expand Down
2 changes: 1 addition & 1 deletion test/SILGen/objc_bridging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ func applyStringBlock(_ f: @convention(block) (String) -> String, x: String) ->
// CHECK: } // end sil function '_T013objc_bridging16applyStringBlockS3SXB_SS1xtF'

// CHECK-LABEL: sil hidden @_T013objc_bridging15bridgeCFunction{{.*}}F
func bridgeCFunction() -> (String!) -> (String!) {
func bridgeCFunction() -> (String?) -> (String?) {
// CHECK: [[THUNK:%.*]] = function_ref @_T0SC18NSStringFromStringSQySSGABFTO : $@convention(thin) (@owned Optional<String>) -> @owned Optional<String>
// CHECK: [[THICK:%.*]] = thin_to_thick_function [[THUNK]]
// CHECK: return [[THICK]]
Expand Down
Loading