Skip to content

Commit 9a9a6a3

Browse files
authored
Merge pull request #84694 from hamishknight/tuple-trouble
[Sema] Reject tuple extensions early when feature is disabled
2 parents 0cfb11b + 8ec8902 commit 9a9a6a3

16 files changed

+44
-17
lines changed

lib/AST/NameLookup.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3630,7 +3630,17 @@ NominalTypeDecl *ExtensionDecl::computeExtendedNominal(
36303630
if (nominalTypes.empty())
36313631
return nullptr;
36323632

3633-
return nominalTypes[0];
3633+
auto *result = nominalTypes[0];
3634+
3635+
// Tuple extensions are experimental, if the feature isn't enabled let's not
3636+
// bind this extension at all. This fixes a bunch of crashers that we don't
3637+
// yet properly handle with the feature enabled.
3638+
if (isa<BuiltinTupleDecl>(result) &&
3639+
!ctx.LangOpts.hasFeature(Feature::TupleConformances)) {
3640+
return nullptr;
3641+
}
3642+
3643+
return result;
36343644
}
36353645

36363646
NominalTypeDecl *

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,6 +3089,13 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
30893089
return error();
30903090
}
30913091

3092+
// Tuple extensions are experimental.
3093+
if (extendedType->is<TupleType>() &&
3094+
!ctx.LangOpts.hasFeature(Feature::TupleConformances)) {
3095+
diags.diagnose(ext, diag::experimental_tuple_extension);
3096+
return error();
3097+
}
3098+
30923099
// Cannot extend function types, metatypes, existentials, etc.
30933100
if (!extendedType->is<TupleType>() &&
30943101
!extendedType->getAnyNominal() &&

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3652,10 +3652,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
36523652
return;
36533653

36543654
auto &ctx = ED->getASTContext();
3655-
3656-
if (!ctx.LangOpts.hasFeature(Feature::TupleConformances)) {
3657-
ED->diagnose(diag::experimental_tuple_extension);
3658-
}
3655+
ASSERT(ctx.LangOpts.hasFeature(Feature::TupleConformances) &&
3656+
"Extension binding should not have permitted this");
36593657

36603658
if (!isValidExtendedTypeForTupleExtension(ED)) {
36613659
ED->diagnose(diag::tuple_extension_wrong_type,

validation-test/IDE/crashers/38a36bbe0fc496da.swift renamed to validation-test/IDE/crashers_fixed/38a36bbe0fc496da.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"complete","original":"61e9155a","signature":"swift::ide::CodeCompletionResultBuilder::takeResult()"}
2-
// RUN: not --crash %target-swift-ide-test -code-completion -batch-code-completion -skip-filecheck -code-completion-diagnostics -source-filename %s
2+
// RUN: %target-swift-ide-test -code-completion -batch-code-completion -skip-filecheck -code-completion-diagnostics -source-filename %s
33
extension ()
44
where
55
#^^# == <#type#>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"typecheck","original":"679d3d53","signature":"(anonymous namespace)::PrintAST::visit(swift::Decl*)"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
extension () {
44
class let a
55
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// {"kind":"typecheck","signature":"swift::ConditionalRequirementsRequest::evaluate(swift::Evaluator&, swift::NormalProtocolConformance*) const","signatureAssert":"Assertion failed: (typeSig.getCanonicalSignature().getGenericParams() == extensionSig.getCanonicalSignature().getGenericParams()), function evaluate"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
protocol a typealias b<c> = () extension b : a
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// {"kind":"typecheck","signature":"swift::NominalType::get(swift::NominalTypeDecl*, swift::Type, swift::ASTContext const&)","signatureAssert":"Assertion failed: ((!Parent || Parent->is<NominalType>() || Parent->is<BoundGenericType>() || Parent->is<UnboundGenericType>()) && \"parent must be a nominal type\"), function get"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
extension() {
44
struct a extension a
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"typecheck","original":"2e2249a5","signature":"swift::TypeBase::computeCanonicalType()","signatureAssert":"Assertion failed: (Result->isCanonical()), function computeCanonicalType"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
typealias a<b> = (
44
>extension a where b == {
55
c
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// {"kind":"typecheck","signature":"(anonymous namespace)::DeclChecker::visit(swift::Decl*)","signatureAssert":"Assertion failed: (false && \"Huh?\"), function isValidExtendedTypeForTupleExtension"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
extension repeat (
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// {"kind":"typecheck","original":"71a26232","signature":"swift::Decl::getDescriptiveKind() const"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
typealias a = ()
4+
extension a {
5+
func
6+
< (b: Self, c: Self)
7+
{
8+
for (d, e) in repeat (each b each c) {
9+
d < &e
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)