Skip to content

Commit c773493

Browse files
committed
Revert "IUO: Update protocol conformance checking to check IUO attr on decl."
This reverts commit ec5cebd. The way it's implemented is problematic when we still have IUOs in the type system and library. We end up thinking there are mismatches between requirements and potential witnesses when there are not.
1 parent be6d83c commit c773493

File tree

1 file changed

+21
-83
lines changed

1 file changed

+21
-83
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,11 @@ namespace {
133133
};
134134
} // end anonymous namespace
135135

136-
static std::tuple<Type, Type, OptionalAdjustmentKind>
137-
getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
138-
Type witnessType, bool witnessTypeIsIUO,
139-
VarianceKind variance) {
136+
static std::tuple<Type,Type, OptionalAdjustmentKind>
137+
getTypesToCompare(ValueDecl *reqt,
138+
Type reqtType,
139+
Type witnessType,
140+
VarianceKind variance) {
140141
// For @objc protocols, deal with differences in the optionality.
141142
// FIXME: It probably makes sense to extend this to non-@objc
142143
// protocols as well, but this requires more testing.
@@ -159,11 +160,6 @@ getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
159160
break;
160161

161162
case OTK_Optional:
162-
if (witnessTypeIsIUO) {
163-
optAdjustment = OptionalAdjustmentKind::RemoveIUO;
164-
break;
165-
}
166-
167163
switch (variance) {
168164
case VarianceKind::None:
169165
case VarianceKind::Covariant:
@@ -183,17 +179,6 @@ getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
183179
break;
184180

185181
case OTK_Optional:
186-
// When the requirement is an IUO, all is permitted, because we
187-
// assume that the user knows more about the signature than we
188-
// have information in the protocol.
189-
if (reqtTypeIsIUO)
190-
break;
191-
192-
if (witnessTypeIsIUO) {
193-
optAdjustment = OptionalAdjustmentKind::IUOToOptional;
194-
break;
195-
}
196-
197182
switch (witnessOptKind) {
198183
case OTK_None:
199184
switch (variance) {
@@ -224,15 +209,6 @@ getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
224209
// have information in the protocol.
225210
break;
226211
}
227-
} else {
228-
// FIXME: Until IUOs are removed from the type system, make
229-
// sure we turn these both into optionals for the purpose of
230-
// comparing types since we could be producing IUOs in some
231-
// places and optionals in others.
232-
if (auto objTy = reqtType->getImplicitlyUnwrappedOptionalObjectType())
233-
reqtType = OptionalType::get(objTy);
234-
if (auto objTy = witnessType->getImplicitlyUnwrappedOptionalObjectType())
235-
witnessType = OptionalType::get(objTy);
236212
}
237213

238214
return std::make_tuple(reqtType, witnessType, optAdjustment);
@@ -367,14 +343,6 @@ static bool checkObjCWitnessSelector(TypeChecker &tc, ValueDecl *req,
367343
return false;
368344
}
369345

370-
static ParameterList *getParameterList(ValueDecl *value) {
371-
if (auto func = dyn_cast<AbstractFunctionDecl>(value))
372-
return func->getParameterList(func->getDeclContext()->isTypeContext());
373-
374-
auto subscript = cast<SubscriptDecl>(value);
375-
return subscript->getIndices();
376-
}
377-
378346
RequirementMatch
379347
swift::matchWitness(
380348
TypeChecker &tc,
@@ -522,24 +490,18 @@ swift::matchWitness(
522490
// Result types must match.
523491
// FIXME: Could allow (trivial?) subtyping here.
524492
if (!ignoreReturnType) {
525-
auto reqTypeIsIUO =
526-
req->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
527-
auto witnessTypeIsIUO =
528-
witness->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
529-
auto types =
530-
getTypesToCompare(req, reqResultType, reqTypeIsIUO, witnessResultType,
531-
witnessTypeIsIUO, VarianceKind::Covariant);
493+
auto types = getTypesToCompare(req, reqResultType,
494+
witnessResultType,
495+
VarianceKind::Covariant);
532496

533497
// Record optional adjustment, if any.
534498
if (std::get<2>(types) != OptionalAdjustmentKind::None) {
535499
optionalAdjustments.push_back(
536500
OptionalAdjustment(std::get<2>(types)));
537501
}
538502

539-
if (!req->isObjC() && reqTypeIsIUO != witnessTypeIsIUO)
540-
return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
541-
542-
if (auto result = matchTypes(std::get<0>(types), std::get<1>(types))) {
503+
if (auto result = matchTypes(std::get<0>(types),
504+
std::get<1>(types))) {
543505
return std::move(result.getValue());
544506
}
545507
}
@@ -555,12 +517,6 @@ swift::matchWitness(
555517
return RequirementMatch(witness, MatchKind::TypeConflict,
556518
witnessType);
557519

558-
ParameterList *witnessParamList = getParameterList(witness);
559-
assert(witnessParamList->size() == witnessParams.size());
560-
561-
ParameterList *reqParamList = getParameterList(req);
562-
assert(reqParamList->size() == reqParams.size());
563-
564520
// Match each of the parameters.
565521
for (unsigned i = 0, n = reqParams.size(); i != n; ++i) {
566522
// Variadic bits must match.
@@ -574,33 +530,21 @@ swift::matchWitness(
574530
if (reqParams[i].isInOut() != witnessParams[i].isInOut())
575531
return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
576532

577-
auto reqParamDecl = reqParamList->get(i);
578-
auto witnessParamDecl = witnessParamList->get(i);
579-
580-
auto reqParamTypeIsIUO =
581-
reqParamDecl->getAttrs()
582-
.hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
583-
auto witnessParamTypeIsIUO =
584-
witnessParamDecl->getAttrs()
585-
.hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
586-
587533
// Gross hack: strip a level of unchecked-optionality off both
588534
// sides when matching against a protocol imported from Objective-C.
589-
auto types =
590-
getTypesToCompare(req, reqParams[i].getType(), reqParamTypeIsIUO,
591-
witnessParams[i].getType(), witnessParamTypeIsIUO,
592-
VarianceKind::Contravariant);
535+
auto types = getTypesToCompare(req, reqParams[i].getType(),
536+
witnessParams[i].getType(),
537+
VarianceKind::Contravariant);
593538

594539
// Record any optional adjustment that occurred.
595540
if (std::get<2>(types) != OptionalAdjustmentKind::None) {
596541
optionalAdjustments.push_back(
597542
OptionalAdjustment(std::get<2>(types), i));
598543
}
599544

600-
if (!req->isObjC() && reqParamTypeIsIUO != witnessParamTypeIsIUO)
601-
return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
602-
603-
if (auto result = matchTypes(std::get<0>(types), std::get<1>(types))) {
545+
// Check whether the parameter types match.
546+
if (auto result = matchTypes(std::get<0>(types),
547+
std::get<1>(types))) {
604548
return std::move(result.getValue());
605549
}
606550
}
@@ -612,22 +556,16 @@ swift::matchWitness(
612556
}
613557

614558
} else {
615-
auto reqTypeIsIUO =
616-
req->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
617-
auto witnessTypeIsIUO =
618-
witness->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
619-
auto types = getTypesToCompare(req, reqType, reqTypeIsIUO, witnessType,
620-
witnessTypeIsIUO, VarianceKind::None);
559+
// Simple case: add the constraint.
560+
auto types = getTypesToCompare(req, reqType, witnessType,
561+
VarianceKind::None);
621562

622563
// Record optional adjustment, if any.
623564
if (std::get<2>(types) != OptionalAdjustmentKind::None) {
624565
optionalAdjustments.push_back(
625566
OptionalAdjustment(std::get<2>(types)));
626567
}
627568

628-
if (!req->isObjC() && reqTypeIsIUO != witnessTypeIsIUO)
629-
return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
630-
631569
if (auto result = matchTypes(std::get<0>(types), std::get<1>(types))) {
632570
return std::move(result.getValue());
633571
}
@@ -785,8 +723,8 @@ RequirementMatch swift::matchWitness(TypeChecker &tc,
785723
};
786724

787725
// Match a type in the requirement to a type in the witness.
788-
auto matchTypes = [&](Type reqType,
789-
Type witnessType) -> Optional<RequirementMatch> {
726+
auto matchTypes = [&](Type reqType, Type witnessType)
727+
-> Optional<RequirementMatch> {
790728
cs->addConstraint(ConstraintKind::Equal, reqType, witnessType, locator);
791729
// FIXME: Check whether this has already failed.
792730
return None;

0 commit comments

Comments
 (0)