Skip to content

Make ImplicitlyUnwrappedOptional<T> an unavailable typealias. #14364

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

Merged
merged 1 commit into from
Feb 3, 2018
Merged
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
8 changes: 1 addition & 7 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ class ASTContext {
DECL_CLASS *get##NAME##Decl() const;
#include "swift/AST/KnownStdlibTypes.def"

/// Retrieve the declaration of Swift.Optional or ImplicitlyUnwrappedOptional.
/// Retrieve the declaration of Swift.Optional.
EnumDecl *getOptionalDecl(OptionalTypeKind kind) const;

/// Retrieve the declaration of Swift.Optional<T>.Some.
Expand All @@ -419,12 +419,6 @@ class ASTContext {
/// Retrieve the declaration of Swift.Optional<T>.None.
EnumElementDecl *getOptionalNoneDecl() const;

/// Retrieve the declaration of Swift.ImplicitlyUnwrappedOptional<T>.Some.
EnumElementDecl *getImplicitlyUnwrappedOptionalSomeDecl() const;

/// Retrieve the declaration of Swift.ImplicitlyUnwrappedOptional<T>.None.
EnumElementDecl *getImplicitlyUnwrappedOptionalNoneDecl() const;

EnumElementDecl *getOptionalSomeDecl(OptionalTypeKind kind) const;
EnumElementDecl *getOptionalNoneDecl(OptionalTypeKind kind) const;

Expand Down
29 changes: 4 additions & 25 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ ERROR(iboutlet_non_optional,none,
NOTE(note_make_optional,none,
"add '?' to form the optional type %0", (Type))
NOTE(note_make_implicitly_unwrapped_optional,none,
"add '!' to form the implicitly unwrapped optional type %0", (Type))
"add '!' to form an implicitly unwrapped optional", ())

ERROR(invalid_ibdesignable_extension,none,
"@IBDesignable can only be applied to classes and extensions "
Expand Down Expand Up @@ -3129,32 +3129,11 @@ 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; use an explicit type followed by '!'", ())

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

WARNING(implicitly_unwrapped_optional_spelling_suggest_optional,none,
"using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead", ())

WARNING(implicitly_unwrapped_optional_in_illegal_position_suggest_optional,none,
"using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead", ())

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

ERROR(implicitly_unwrapped_optional_spelling_error_with_bang_fixit,none,
"the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name", ())

ERROR(implicitly_unwrapped_optional_spelling_error_with_optional_fixit,none,
"the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use 'Optional' instead", ())

ERROR(implicitly_unwrapped_optional_spelling_in_illegal_position,none,
"'ImplicitlyUnwrappedOptional' is not allowed here; perhaps 'Optional' was intended?", ())
WARNING(implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional,none,
"using '!' is not allowed here; treating this as '?' instead", ())

ERROR(implicitly_unwrapped_optional_in_illegal_position,none,
"'!' is not allowed here; perhaps '?' was intended?", ())
"using '!' is not allowed here; perhaps '?' was intended?", ())

// Ownership
ERROR(invalid_ownership_type,none,
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ IDENTIFIER(forKey)
IDENTIFIER(from)
IDENTIFIER(fromRaw)
IDENTIFIER(hashValue)
IDENTIFIER(ImplicitlyUnwrappedOptional)
IDENTIFIER(init)
IDENTIFIER(initialize)
IDENTIFIER(initStorage)
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/KnownStdlibTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ KNOWN_STDLIB_TYPE_DECL(WritableKeyPath, NominalTypeDecl, 2)
KNOWN_STDLIB_TYPE_DECL(ReferenceWritableKeyPath, NominalTypeDecl, 2)

KNOWN_STDLIB_TYPE_DECL(Optional, EnumDecl, 1)
KNOWN_STDLIB_TYPE_DECL(ImplicitlyUnwrappedOptional, EnumDecl, 1)

KNOWN_STDLIB_TYPE_DECL(OptionSet, NominalTypeDecl, 1)

Expand Down
3 changes: 2 additions & 1 deletion include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -4115,7 +4115,8 @@ class ImplicitlyUnwrappedOptionalType : public UnarySyntaxSugarType {
RecursiveTypeProperties properties)
: UnarySyntaxSugarType(TypeKind::ImplicitlyUnwrappedOptional, ctx, base,
properties) {
//llvm_unreachable("ImplicitlyUnwrappedOptionalType::ImplicitlyUnwrappedOptionalType");
llvm_unreachable(
"ImplicitlyUnwrappedOptionalType::ImplicitlyUnwrappedOptionalType");
}

public:
Expand Down
4 changes: 1 addition & 3 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 393; // SILLinkage::PublicNonABI
const uint16_t VERSION_MINOR = 394; // Remove IUO serialization and decl

using DeclIDField = BCFixed<31>;

Expand Down Expand Up @@ -790,8 +790,6 @@ namespace decls_block {

using ArraySliceTypeLayout = SyntaxSugarTypeLayout<ARRAY_SLICE_TYPE>;
using OptionalTypeLayout = SyntaxSugarTypeLayout<OPTIONAL_TYPE>;
using ImplicitlyUnwrappedOptionalTypeLayout =
SyntaxSugarTypeLayout<UNCHECKED_OPTIONAL_TYPE>;

using DictionaryTypeLayout = BCRecordLayout<
DICTIONARY_TYPE,
Expand Down
20 changes: 3 additions & 17 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ EnumDecl *ASTContext::getOptionalDecl(OptionalTypeKind kind) const {
case OTK_None:
llvm_unreachable("not optional");
case OTK_ImplicitlyUnwrappedOptional:
return getImplicitlyUnwrappedOptionalDecl();
llvm_unreachable("Should no longer have IUOs");
case OTK_Optional:
return getOptionalDecl();
}
Expand All @@ -663,7 +663,7 @@ EnumElementDecl *ASTContext::getOptionalSomeDecl(OptionalTypeKind kind) const {
case OTK_Optional:
return getOptionalSomeDecl();
case OTK_ImplicitlyUnwrappedOptional:
return getImplicitlyUnwrappedOptionalSomeDecl();
llvm_unreachable("Should not have IUOs.");
case OTK_None:
llvm_unreachable("getting Some decl for non-optional type?");
}
Expand All @@ -675,7 +675,7 @@ EnumElementDecl *ASTContext::getOptionalNoneDecl(OptionalTypeKind kind) const {
case OTK_Optional:
return getOptionalNoneDecl();
case OTK_ImplicitlyUnwrappedOptional:
return getImplicitlyUnwrappedOptionalNoneDecl();
llvm_unreachable("Should not have IUOs.");
case OTK_None:
llvm_unreachable("getting None decl for non-optional type?");
}
Expand All @@ -694,20 +694,6 @@ EnumElementDecl *ASTContext::getOptionalNoneDecl() const {
return Impl.OptionalNoneDecl;
}

EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalSomeDecl() const {
if (!Impl.ImplicitlyUnwrappedOptionalSomeDecl)
Impl.ImplicitlyUnwrappedOptionalSomeDecl =
getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/true);
return Impl.ImplicitlyUnwrappedOptionalSomeDecl;
}

EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalNoneDecl() const {
if (!Impl.ImplicitlyUnwrappedOptionalNoneDecl)
Impl.ImplicitlyUnwrappedOptionalNoneDecl =
getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/false);
return Impl.ImplicitlyUnwrappedOptionalNoneDecl;
}

static VarDecl *getPointeeProperty(VarDecl *&cache,
NominalTypeDecl *(ASTContext::*getNominal)() const,
const ASTContext &ctx) {
Expand Down
6 changes: 1 addition & 5 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,11 +756,7 @@ void ASTMangler::appendType(Type type) {
return appendSugaredType<SyntaxSugarType>(type);

case TypeKind::ImplicitlyUnwrappedOptional: {
assert(DWARFMangling && "sugared types are only legal for the debugger");
auto *IUO = cast<ImplicitlyUnwrappedOptionalType>(tybase);
auto implDecl = tybase->getASTContext().getImplicitlyUnwrappedOptionalDecl();
auto GenTy = BoundGenericType::get(implDecl, Type(), IUO->getBaseType());
return appendType(GenTy);
llvm_unreachable("Should no longer have IUOs");
}

case TypeKind::ExistentialMetatype: {
Expand Down
5 changes: 0 additions & 5 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3337,11 +3337,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
Printer << "?";
return;
}
if (NT == Ctx.getImplicitlyUnwrappedOptionalDecl()) {
printWithParensIfNotSimple(T->getGenericArgs()[0]);
Printer << "!";
return;
}
}
if (auto ParentType = T->getParent()) {
visit(ParentType);
Expand Down
8 changes: 3 additions & 5 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2684,11 +2684,9 @@ class Verifier : public ASTWalker {

// Verify that the optionality of the result type of the
// initializer matches the failability of the initializer.
if (!CD->isInvalid() &&
CD->getDeclContext()->getDeclaredInterfaceType()->getAnyNominal()
!= Ctx.getOptionalDecl() &&
CD->getDeclContext()->getDeclaredInterfaceType()->getAnyNominal()
!= Ctx.getImplicitlyUnwrappedOptionalDecl()) {
if (!CD->isInvalid() &&
CD->getDeclContext()->getDeclaredInterfaceType()->getAnyNominal() !=
Ctx.getOptionalDecl()) {
OptionalTypeKind resultOptionality = OTK_None;
CD->getResultInterfaceType()->getAnyOptionalObjectType(resultOptionality);
auto declOptionality = CD->getFailability();
Expand Down
2 changes: 0 additions & 2 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2489,8 +2489,6 @@ OptionalTypeKind NominalTypeDecl::classifyAsOptionalType() const {
const ASTContext &ctx = getASTContext();
if (this == ctx.getOptionalDecl()) {
return OTK_Optional;
} else if (this == ctx.getImplicitlyUnwrappedOptionalDecl()) {
return OTK_ImplicitlyUnwrappedOptional;
} else {
return OTK_None;
}
Expand Down
5 changes: 1 addition & 4 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,9 +1235,6 @@ TypeBase *TypeBase::reconstituteSugar(bool Recursive) {
boundGeneric->getGenericArgs()[1]);
if (boundGeneric->getDecl() == ctx.getOptionalDecl())
return OptionalType::get(boundGeneric->getGenericArgs()[0]);
if (boundGeneric->getDecl() == ctx.getImplicitlyUnwrappedOptionalDecl())
return ImplicitlyUnwrappedOptionalType::
get(boundGeneric->getGenericArgs()[0]);
}
return Ty;
};
Expand Down Expand Up @@ -1294,7 +1291,7 @@ Type SugarType::getSinglyDesugaredTypeSlow() {
implDecl = Context->getOptionalDecl();
break;
case TypeKind::ImplicitlyUnwrappedOptional:
implDecl = Context->getImplicitlyUnwrappedOptionalDecl();
llvm_unreachable("Should no longer have IUOs");
break;
case TypeKind::Dictionary:
implDecl = Context->getDictionaryDecl();
Expand Down
8 changes: 1 addition & 7 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2773,13 +2773,7 @@ namespace {
// aren't mapped correctly because the EnumImplStrategy ends up
// using the lowered cases, i.e. the cases for Optional<>.
if (type->classifyAsOptionalType() == OTK_ImplicitlyUnwrappedOptional) {
assert(enumElements.size() == 1);
auto decl = IGM.Context.getImplicitlyUnwrappedOptionalSomeDecl();
auto caseType = decl->getParentEnum()->mapTypeIntoContext(
decl->getArgumentInterfaceType())
->getCanonicalType();
types.push_back(FieldTypeInfo(caseType, false, false));
return getFieldTypeAccessorFn(IGM, type, types);
llvm_unreachable("Should not have IUOs.");
}

for (auto &elt : enumElements) {
Expand Down
13 changes: 3 additions & 10 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,9 @@ SILGenModule::~SILGenModule() {

EnumElementDecl *SILGenModule::getLoweredEnumElementDecl(EnumElementDecl *elt) {
auto &ctx = getASTContext();
if (elt->getParentEnum()->classifyAsOptionalType()
!= OTK_ImplicitlyUnwrappedOptional)
return elt;

if (elt == ctx.getImplicitlyUnwrappedOptionalSomeDecl()) {
return ctx.getOptionalSomeDecl();
} else {
assert(elt == ctx.getImplicitlyUnwrappedOptionalNoneDecl());
return ctx.getOptionalNoneDecl();
}
assert(elt->getParentEnum()->classifyAsOptionalType() !=
OTK_ImplicitlyUnwrappedOptional);
return elt;
}

static SILDeclRef
Expand Down
12 changes: 0 additions & 12 deletions lib/SILGen/SILGenPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1762,12 +1762,6 @@ void PatternMatchEmission::emitEnumElementDispatchWithOwnership(
bool exhaustive = false;
auto enumDecl = sourceType.getEnumOrBoundGenericEnum();

// The SIL values will range over Optional, so count against
// Optional's cases.
if (enumDecl == SGF.getASTContext().getImplicitlyUnwrappedOptionalDecl()) {
enumDecl = SGF.getASTContext().getOptionalDecl();
}

if (!enumDecl->isResilient(SGF.SGM.M.getSwiftModule(),
SGF.F.getResilienceExpansion())) {
exhaustive = true;
Expand Down Expand Up @@ -1990,12 +1984,6 @@ void PatternMatchEmission::emitEnumElementDispatch(
bool exhaustive = false;
auto enumDecl = sourceType.getEnumOrBoundGenericEnum();

// The SIL values will range over Optional, so count against
// Optional's cases.
if (enumDecl == SGF.getASTContext().getImplicitlyUnwrappedOptionalDecl()) {
enumDecl = SGF.getASTContext().getOptionalDecl();
}

if (!enumDecl->isResilient(SGF.SGM.M.getSwiftModule(),
SGF.F.getResilienceExpansion())) {
exhaustive = true;
Expand Down
6 changes: 1 addition & 5 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3560,8 +3560,6 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,

// Explicit bridging from a value type to an Objective-C class type.
if (unwrappedFromType->isPotentiallyBridgedValueType() &&
unwrappedFromType->getAnyNominal()
!= TC.Context.getImplicitlyUnwrappedOptionalDecl() &&
!flags.contains(TMF_ApplyingOperatorParameter) &&
(unwrappedToType->isBridgeableObjectType() ||
(unwrappedToType->isExistentialType() &&
Expand All @@ -3577,9 +3575,7 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
// Note that specifically require a class or class-constrained archetype
// here, because archetypes cannot be bridged.
if (unwrappedFromType->mayHaveSuperclass() &&
unwrappedToType->isPotentiallyBridgedValueType() &&
unwrappedToType->getAnyNominal()
!= TC.Context.getImplicitlyUnwrappedOptionalDecl()) {
unwrappedToType->isPotentiallyBridgedValueType()) {
Type bridgedValueType;
if (auto objcClass = TC.Context.getBridgedToObjC(DC, unwrappedToType,
&bridgedValueType)) {
Expand Down
35 changes: 0 additions & 35 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1786,42 +1786,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
}
}

/// Given that we're accessing a member of an ImplicitlyUnwrappedOptional<T>, is
/// the DC one of the special cases where we should not instead look at T?
static bool isPrivilegedAccessToImplicitlyUnwrappedOptional(DeclContext *DC,
NominalTypeDecl *D) {
assert(D == DC->getASTContext().getImplicitlyUnwrappedOptionalDecl());

// Walk up through the chain of current contexts.
for (; ; DC = DC->getParent()) {
assert(DC && "ran out of contexts before finding a module scope?");

// Look through local contexts.
if (DC->isLocalContext()) {
continue;

// If we're in a type context that's defining or extending
// ImplicitlyUnwrappedOptional<T>, we're privileged.
} else if (DC->isTypeContext()) {
if (DC->getAsNominalTypeOrNominalTypeExtensionContext() == D)
return true;

// Otherwise, we're privileged if we're within the same file that
// defines ImplicitlyUnwrappedOptional<T>.
} else {
assert(DC->isModuleScopeContext());
return (DC == D->getModuleScopeContext());
}
}
}

Type ConstraintSystem::lookThroughImplicitlyUnwrappedOptionalType(Type type) {
if (auto boundTy = type->getAs<BoundGenericEnumType>()) {
auto boundDecl = boundTy->getDecl();
if (boundDecl == TC.Context.getImplicitlyUnwrappedOptionalDecl() &&
!isPrivilegedAccessToImplicitlyUnwrappedOptional(DC, boundDecl))
return boundTy->getGenericArgs()[0];
}
return Type();
}

Expand Down
Loading