Skip to content

Commit 973a506

Browse files
authored
Merge pull request #68282 from slavapestov/sema-tuple-conformances
(More) Declaration checker support for tuple conformances
2 parents b6764c3 + 7dacc5e commit 973a506

19 files changed

+659
-205
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5232,21 +5232,19 @@ class ProtocolDecl final : public NominalTypeDecl {
52325232
/// and conformances for tuple types.
52335233
///
52345234
/// - The declared interface type is the special TheTupleType singleton.
5235-
/// - The generic parameter list has one pack generic parameter, <Elements...>
5236-
/// - The generic signature has no requirements, <Elements...>
5235+
/// - The generic parameter list has one pack generic parameter, <each Element>
5236+
/// - The generic signature has no requirements, <each Element>
52375237
/// - The self interface type is the tuple type containing a single pack
5238-
/// expansion, (Elements...).
5238+
/// expansion, (repeat each Element).
52395239
class BuiltinTupleDecl final : public NominalTypeDecl {
5240-
TupleType *TupleSelfType = nullptr;
5241-
52425240
public:
52435241
BuiltinTupleDecl(Identifier Name, DeclContext *Parent);
52445242

52455243
SourceRange getSourceRange() const {
52465244
return SourceRange();
52475245
}
52485246

5249-
TupleType *getTupleSelfType() const;
5247+
TupleType *getTupleSelfType(const ExtensionDecl *owner) const;
52505248

52515249
// Implement isa/cast/dyncast/etc.
52525250
static bool classof(const Decl *D) {

include/swift/AST/DiagnosticsSema.def

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,18 @@ ERROR(extension_access_with_conformances,none,
23632363
ERROR(experimental_tuple_extension,none,
23642364
"tuple extensions are experimental",
23652365
())
2366+
ERROR(tuple_extension_wrong_type,none,
2367+
"tuple extension must be written as extension of %0", (Type))
2368+
ERROR(tuple_extension_one_conformance,none,
2369+
"tuple extension must declare conformance to exactly one protocol", ())
2370+
ERROR(tuple_extension_extra_requirement,none,
2371+
"tuple extension cannot require that %0 "
2372+
"%select{conforms to|subclasses|is the same type as|%error|%error}1 %2",
2373+
(Type, unsigned, Type))
2374+
ERROR(tuple_extension_missing_requirement,none,
2375+
"tuple extension must require that %0 conforms to %1", (Type, Type))
2376+
ERROR(tuple_extension_nested_type,none,
2377+
"type %0 cannot be nested in tuple extension", (const NominalTypeDecl *))
23662378
ERROR(extension_metatype,none,
23672379
"cannot extend a metatype %0", (Type))
23682380
ERROR(extension_placeholder,none,
@@ -2731,10 +2743,23 @@ NOTE(ambiguous_witnesses_wrong_name,none,
27312743
NOTE(no_witnesses_type,none,
27322744
"protocol requires nested type %0; add nested type %0 for conformance",
27332745
(const AssociatedTypeDecl *))
2734-
NOTE(default_associated_type_req_fail,none,
2746+
NOTE(no_witnesses_type_tuple,none,
2747+
"protocol requires nested type %0; add type alias %0 with underlying type %1 "
2748+
"for conformance",
2749+
(const AssociatedTypeDecl *, Type))
2750+
NOTE(default_associated_type_unsatisfied_conformance,none,
2751+
"default type %0 for associated type %1 (from protocol %2) "
2752+
"does not conform to %3",
2753+
(Type, const AssociatedTypeDecl *, Type, Type))
2754+
NOTE(default_associated_type_unsatisfied_superclass,none,
2755+
"default type %0 for associated type %1 (from protocol %2) "
2756+
"does not inherit from %3",
2757+
(Type, const AssociatedTypeDecl *, Type, Type))
2758+
NOTE(default_associated_type_tuple,none,
27352759
"default type %0 for associated type %1 (from protocol %2) "
2736-
"does not %select{inherit from|conform to}4 %3",
2737-
(Type, const AssociatedTypeDecl *, Type, Type, bool))
2760+
"is unsuitable for tuple conformance; the associated type requirement "
2761+
"must be fulfilled by a type alias with underlying type %3",
2762+
(Type, const AssociatedTypeDecl *, Type, Type))
27382763
ERROR(associated_type_access,none,
27392764
"associated type in "
27402765
"%select{a private|a fileprivate|an internal|a package|a public|%error}0 protocol "
@@ -2762,10 +2787,19 @@ WARNING(associated_type_not_usable_from_inline_warn,none,
27622787
NOTE(bad_associated_type_deduction,none,
27632788
"unable to infer associated type %0 for protocol %1",
27642789
(const AssociatedTypeDecl *, const ProtocolDecl *))
2765-
NOTE(associated_type_deduction_witness_failed,none,
2790+
NOTE(associated_type_deduction_unsatisfied_conformance,none,
2791+
"candidate would match and infer %0 = %1 if %1 "
2792+
"conformed to %2",
2793+
(const AssociatedTypeDecl *, Type, Type))
2794+
NOTE(associated_type_deduction_unsatisfied_superclass,none,
27662795
"candidate would match and infer %0 = %1 if %1 "
2767-
"%select{inherited from|conformed to}3 %2",
2768-
(const AssociatedTypeDecl *, Type, Type, bool))
2796+
"inherited from %2",
2797+
(const AssociatedTypeDecl *, Type, Type))
2798+
NOTE(associated_type_deduction_tuple,none,
2799+
"cannot infer %0 = %1 in tuple conformance because "
2800+
"the associated type requirement must be fulfilled by a type alias with "
2801+
"underlying type %2",
2802+
(const AssociatedTypeDecl *, Type, Type))
27692803
NOTE(associated_type_witness_conform_impossible,none,
27702804
"candidate can not infer %0 = %1 because %1 "
27712805
"is not a nominal type and so can't conform to %2",
@@ -2856,9 +2890,17 @@ NOTE(protocol_witness_enum_case_payload, none,
28562890

28572891
NOTE(protocol_witness_type,none,
28582892
"possibly intended match", ())
2859-
NOTE(protocol_witness_nonconform_type,none,
2893+
NOTE(protocol_type_witness_unsatisfied_conformance,none,
28602894
"possibly intended match %0 does not "
2861-
"%select{inherit from|conform to}2 %1", (Type, Type, bool))
2895+
"conform to %1", (Type, Type))
2896+
NOTE(protocol_type_witness_unsatisfied_superclass,none,
2897+
"possibly intended match %0 does not "
2898+
"inherit from %1", (Type, Type))
2899+
NOTE(protocol_type_witness_tuple,none,
2900+
"possibly intended match %0 is unsuitable for tuple conformance; "
2901+
"the associated type requirement must be fulfilled by a type alias "
2902+
"with underlying type %1",
2903+
(Type, Type))
28622904

28632905
NOTE(protocol_witness_circularity,none,
28642906
"candidate references itself", ())

lib/AST/Decl.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7902,27 +7902,30 @@ Type DeclContext::getSelfTypeInContext() const {
79027902
return mapTypeIntoContext(getSelfInterfaceType());
79037903
}
79047904

7905-
TupleType *BuiltinTupleDecl::getTupleSelfType() const {
7906-
if (TupleSelfType)
7907-
return TupleSelfType;
7908-
7905+
TupleType *BuiltinTupleDecl::getTupleSelfType(const ExtensionDecl *owner) const {
79097906
auto &ctx = getASTContext();
79107907

7911-
// Get the generic parameter type 'Elements'.
7912-
auto paramType = getGenericParams()->getParams()[0]
7913-
->getDeclaredInterfaceType();
7908+
// Get the generic parameter type 'each T'.
7909+
GenericParamList *genericParams;
7910+
if (owner != nullptr) {
7911+
genericParams = owner->getGenericParams();
7912+
} else {
7913+
genericParams = getGenericParams();
7914+
}
79147915

7915-
// Build the pack expansion type 'Elements...'.
7916+
assert(genericParams != nullptr);
7917+
assert(genericParams->getParams().size() == 1);
7918+
assert(genericParams->getOuterParameters() == nullptr);
7919+
auto paramType = genericParams->getParams()[0]->getDeclaredInterfaceType();
7920+
7921+
// Build the pack expansion type 'repeat each T'.
79167922
Type packExpansionType = PackExpansionType::get(paramType, paramType);
79177923

7918-
// Build the one-element tuple type '(Elements...)'.
7924+
// Build the one-element tuple type '(repeat each T)'.
79197925
SmallVector<TupleTypeElt, 1> elts;
79207926
elts.push_back(packExpansionType);
79217927

7922-
const_cast<BuiltinTupleDecl *>(this)->TupleSelfType =
7923-
TupleType::get(elts, ctx);
7924-
7925-
return TupleSelfType;
7928+
return TupleType::get(elts, ctx);
79267929
}
79277930

79287931
/// Retrieve the interface type of 'self' for the given context.
@@ -7931,7 +7934,7 @@ Type DeclContext::getSelfInterfaceType() const {
79317934

79327935
if (auto *nominalDecl = getSelfNominalTypeDecl()) {
79337936
if (auto *builtinTupleDecl = dyn_cast<BuiltinTupleDecl>(nominalDecl))
7934-
return builtinTupleDecl->getTupleSelfType();
7937+
return builtinTupleDecl->getTupleSelfType(dyn_cast<ExtensionDecl>(this));
79357938

79367939
if (isa<ProtocolDecl>(nominalDecl)) {
79377940
auto *genericParams = nominalDecl->getGenericParams();

0 commit comments

Comments
 (0)