Skip to content

Commit 7e21d7b

Browse files
Merge pull request #30423 from AnthonyLatsis/se-0267-additions
[SE-0267] Improvements (Ep. 1)
2 parents 076a247 + 3825656 commit 7e21d7b

11 files changed

+103
-45
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,9 +1658,6 @@ ERROR(redundant_class_requirement,none,
16581658
"redundant 'class' requirement", ())
16591659
ERROR(late_class_requirement,none,
16601660
"'class' must come first in the requirement list", ())
1661-
ERROR(where_toplevel_nongeneric,none,
1662-
"'where' clause cannot be attached to non-generic "
1663-
"top-level declaration", ())
16641661
ERROR(where_inside_brackets,none,
16651662
"'where' clause next to generic parameters is obsolete, "
16661663
"must be written following the declaration's type", ())

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ NOTE(unstable_mangled_name_add_objc,none,
15751575
"for compatibility with existing archives, use '@objc' "
15761576
"to record the Swift 3 runtime name", ())
15771577

1578-
// Generic types
1578+
// Generic declarations
15791579
ERROR(unsupported_type_nested_in_generic_function,none,
15801580
"type %0 cannot be nested in generic function %1",
15811581
(Identifier, DeclName))
@@ -1591,6 +1591,12 @@ ERROR(unsupported_type_nested_in_protocol_extension,none,
15911591
ERROR(unsupported_nested_protocol,none,
15921592
"protocol %0 cannot be nested inside another declaration",
15931593
(Identifier))
1594+
ERROR(where_nongeneric_ctx,none,
1595+
"'where' clause on non-generic member declaration requires a "
1596+
"generic context", ())
1597+
ERROR(where_nongeneric_toplevel,none,
1598+
"'where' clause cannot be applied to a non-generic top-level "
1599+
"declaration", ())
15941600

15951601
// Type aliases
15961602
ERROR(type_alias_underlying_type_access,none,
@@ -2755,10 +2761,6 @@ ERROR(dynamic_self_stored_property_init,none,
27552761
ERROR(dynamic_self_default_arg,none,
27562762
"covariant 'Self' type cannot be referenced from a default argument expression", ())
27572763

2758-
ERROR(where_nongeneric_ctx,none,
2759-
"'where' clause on non-generic member declaration requires a "
2760-
"generic context", ())
2761-
27622764
//------------------------------------------------------------------------------
27632765
// MARK: Type Check Attributes
27642766
//------------------------------------------------------------------------------

lib/Parse/ParseGeneric.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,10 @@ parseFreestandingGenericWhereClause(GenericContext *genCtx,
418418

419419
genericParams->addTrailingWhereClause(Context, WhereLoc, Requirements);
420420

421-
// A where clause that references only outer generic parameters?
422-
} else if (flags.contains(PD_HasContainerType)) {
421+
} else {
422+
// A where clause against outer generic parameters.
423423
genCtx->setTrailingWhereClause(
424424
TrailingWhereClause::create(Context, WhereLoc, Requirements));
425-
} else {
426-
diagnose(WhereLoc, diag::where_toplevel_nongeneric);
427425
}
428426

429427
return ParserStatus();

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,11 +620,15 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
620620
return cast<SubscriptDecl>(accessor->getStorage())->getGenericSignature();
621621
}
622622

623-
// ...or we may have a where clause dependent on outer generic parameters.
623+
// ...or we may only have a contextual where clause.
624624
} else if (const auto *where = GC->getTrailingWhereClause()) {
625625
// If there is no generic context for the where clause to
626626
// rely on, diagnose that now and bail out.
627-
if (!GC->isGenericContext()) {
627+
if (GC->getParent()->isModuleScopeContext()) {
628+
GC->getASTContext().Diags.diagnose(where->getWhereLoc(),
629+
diag::where_nongeneric_toplevel);
630+
return nullptr;
631+
} else if (!GC->isGenericContext()) {
628632
GC->getASTContext().Diags.diagnose(where->getWhereLoc(),
629633
diag::where_nongeneric_ctx);
630634
return nullptr;

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -651,30 +651,25 @@ static Type checkContextualRequirements(Type type,
651651
return type;
652652
}
653653

654-
// We are interested in either a contextual where clause or
655-
// a constrained extension context.
656-
TypeSubstitutionMap subMap;
657-
GenericSignature genericSig;
658654
SourceLoc noteLoc;
659-
if (decl->getTrailingWhereClause()) {
660-
subMap = parentTy->getContextSubstitutions(decl->getDeclContext());
661-
genericSig = decl->getGenericSignature();
662-
noteLoc = decl->getLoc();
663-
} else {
655+
{
656+
// We are interested in either a contextual where clause or
657+
// a constrained extension context.
664658
const auto ext = dyn_cast<ExtensionDecl>(decl->getDeclContext());
665-
if (ext && ext->isConstrainedExtension()) {
666-
subMap = parentTy->getContextSubstitutions(ext);
667-
genericSig = ext->getGenericSignature();
659+
if (decl->getTrailingWhereClause())
660+
noteLoc = decl->getLoc();
661+
else if (ext && ext->isConstrainedExtension())
668662
noteLoc = ext->getLoc();
669-
} else {
663+
else
670664
return type;
671-
}
672-
}
673665

674-
if (noteLoc.isInvalid())
675-
noteLoc = loc;
666+
if (noteLoc.isInvalid())
667+
noteLoc = loc;
668+
}
676669

677-
auto result =
670+
const auto subMap = parentTy->getContextSubstitutions(decl->getDeclContext());
671+
const auto genericSig = decl->getGenericSignature();
672+
const auto result =
678673
TypeChecker::checkGenericArguments(
679674
dc, loc, noteLoc, type,
680675
genericSig->getGenericParams(),

test/Generics/invalid.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
func bet() where A : B {} // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
4-
5-
typealias gimel = Int where A : B // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
6-
7-
class dalet where A : B {} // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
8-
9-
struct Where {
10-
func bet() where A == B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
11-
typealias gimel = Int where A : B // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
12-
class dalet where A : B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
13-
}
14-
153
protocol he where A : B { // expected-error {{use of undeclared type 'A'}}
164
// expected-error@-1 {{use of undeclared type 'B'}}
175

test/Generics/where_clause_contextually_generic_decls.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
// RUN: %target-typecheck-verify-swift -typecheck %s -verify -swift-version 4
22

3+
func bet() where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
4+
5+
typealias gimel = Int where A : B // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
6+
7+
class dalet where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
8+
9+
struct Where {
10+
func bet() where A == B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
11+
typealias gimel = Int where A : B // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
12+
class dalet where A : B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
13+
}
14+
315
// Make sure Self: ... is correctly diagnosed in classes
416

517
class SelfInGenericClass<T> {

test/SILGen/vtable_thunks_reabstraction.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,3 +557,32 @@ class MoreGenericSub2<TT, T> : GenericBase<T> {
557557
// CHECK-NEXT: #GenericBase.init!allocator: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$s27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufC [override]
558558
// CHECK-NEXT: #MoreGenericSub2.deinit!deallocator: @$s27vtable_thunks_reabstraction15MoreGenericSub2CfD // MoreGenericSub2.__deallocating_deinit
559559
// CHECK-NEXT: }
560+
561+
protocol SE_0267_P1 {}
562+
563+
class SE_0267_Base1<T> {
564+
func foo() where T: SE_0267_P1 {}
565+
}
566+
class SE_0267_Derived1<T>: SE_0267_Base1<T> {
567+
override func foo() {}
568+
}
569+
570+
// CHECK-LABEL: sil_vtable SE_0267_Derived1 {
571+
// CHECK-NEXT: #SE_0267_Base1.foo: <T where T : SE_0267_P1> (SE_0267_Base1<T>) -> () -> () : @$s27vtable_thunks_reabstraction16SE_0267_Derived1C3fooyyFAA0D11_0267_Base1CADyyAA0D8_0267_P1RzlFTV [override]
572+
// CHECK-NEXT: #SE_0267_Base1.init
573+
// CHECK-NEXT: #SE_0267_Derived1.foo: <T> (SE_0267_Derived1<T>) -> () -> () : @$s27vtable_thunks_reabstraction16SE_0267_Derived1C3fooyyF
574+
// CHECK-NEXT: #SE_0267_Derived1.deinit
575+
// CHECK-NEXT: }
576+
577+
class SE_0267_Base2<T> {
578+
func foo() -> T where T: FixedWidthInteger { fatalError() }
579+
}
580+
class SE_0267_Derived2: SE_0267_Base2<Int> {
581+
override func foo() -> Int { return .zero }
582+
}
583+
584+
// CHECK-LABEL: sil_vtable SE_0267_Derived2 {
585+
// CHECK-NEXT: #SE_0267_Base2.foo: <T where T : FixedWidthInteger> (SE_0267_Base2<T>) -> () -> T : @$s27vtable_thunks_reabstraction16SE_0267_Derived2C3fooSiyFAA0D11_0267_Base2CADxys17FixedWidthIntegerRzlFTV [override]
586+
// CHECK-NEXT: #SE_0267_Base2.init
587+
// CHECK-NEXT: #SE_0267_Derived2.deinit
588+
// CHECK-NEXT: }

test/TypeDecoder/generic_typealias.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ struct Outer {
2020

2121
struct GenericOuter<T> {
2222
typealias Alias<T> = Int
23+
typealias AliasWhere = Int where T == GenericOuter<Never>
2324

2425
struct Inner {
2526
typealias Alias<T> = Int
27+
typealias AliasWhere = Int where T: Equatable
2628
}
2729
}
2830

@@ -32,6 +34,7 @@ protocol Proto {
3234

3335
extension Proto {
3436
typealias OtherAlias<T> = Int
37+
typealias OtherAliasWhere = Int where Self == Conforms
3538
}
3639

3740
extension GenericOuter where T : Proto {
@@ -90,16 +93,22 @@ do {
9093
// CHECK-TYPE: Outer.Inner.Alias<String>
9194

9295
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5AliasaySi_SSGD
96+
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV10AliasWhereayACys5NeverOG_GD
9397
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5InnerV5AliasaySi__SSGD
98+
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5InnerV10AliasWhereaySi__GD
9499

95100
// CHECK-TYPE: GenericOuter<Int>.Alias<String>
101+
// CHECK-TYPE: GenericOuter<GenericOuter<Never>>.AliasWhere
96102
// CHECK-TYPE: GenericOuter<Int>.Inner.Alias<String>
103+
// CHECK-TYPE: GenericOuter<Int>.Inner.AliasWhere
97104

98105
// DEMANGLE-TYPE: $s17generic_typealias5ProtoP5AliasayAA8ConformsV_SSGD
99106
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE10OtherAliasayAA8ConformsV_SSGD
107+
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE15OtherAliasWhereayAA8ConformsV_GD
100108

101109
// CHECK-TYPE: Conforms.Alias<String>
102110
// CHECK-TYPE: Conforms.OtherAlias<String>
111+
// CHECK-TYPE: Conforms.OtherAliasWhere
103112

104113
// DEMANGLE-TYPE: $s17generic_typealias5ProtoP5Aliasayx_SSGD
105114
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE10OtherAliasayx_SSGD
@@ -116,16 +125,22 @@ do {
116125
// DEMANGLE-DECL: $s17generic_typealias5OuterV5Aliasa
117126
// DEMANGLE-DECL: $s17generic_typealias5OuterV5InnerV5Aliasa
118127
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5Aliasa
128+
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV10AliasWherea
119129
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5InnerV5Aliasa
130+
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5InnerV10AliasWherea
120131
// DEMANGLE-DECL: $s17generic_typealias5ProtoP5Aliasa
121132
// DEMANGLE-DECL: $s17generic_typealias5ProtoPAAE10OtherAliasa
133+
// DEMANGLE-DECL: $s17generic_typealias5ProtoPAAE15OtherAliasWherea
122134
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterVA2A5ProtoRzlE16ConditionalAliasa
123135

124136
// CHECK-DECL: generic_typealias.(file).Alias
125137
// CHECK-DECL: generic_typealias.(file).Outer.Alias
126138
// CHECK-DECL: generic_typealias.(file).Outer.Inner.Alias
127139
// CHECK-DECL: generic_typealias.(file).GenericOuter.Alias
140+
// CHECK-DECL: generic_typealias.(file).GenericOuter.AliasWhere
128141
// CHECK-DECL: generic_typealias.(file).GenericOuter.Inner.Alias
142+
// CHECK-DECL: generic_typealias.(file).GenericOuter.Inner.AliasWhere
129143
// CHECK-DECL: generic_typealias.(file).Proto.Alias
130144
// CHECK-DECL: generic_typealias.(file).Proto extension.OtherAlias
145+
// CHECK-DECL: generic_typealias.(file).Proto extension.OtherAliasWhere
131146
// CHECK-DECL: generic_typealias.(file).GenericOuter extension.ConditionalAlias

test/TypeDecoder/nominal_types.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ enum GenericOuter<T, U> {
2525

2626
struct Inner {}
2727
struct GenericInner<T, U> {}
28+
struct InnerWhere where T == GenericOuter<U, U> {}
2829
}
2930

3031
func blackHole(_: Any...) {}
@@ -59,6 +60,7 @@ enum STSContainer<T : STSTagProtocol> {
5960
class Superclass {}
6061
class Subclass<U>: Superclass where T == STSOuter {
6162
class ExtraNested: Superclass {}
63+
class ExtraNestedWhere: Superclass where U: Subclass<T> {}
6264
}
6365

6466
class GenericSuperclass<U> {}
@@ -122,13 +124,17 @@ extension STSContainer℠ where T == STSOuter {
122124

123125
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO5InnerVyxq__GD
124126
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO0C5InnerVyxq__qd__qd_0_GD
127+
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO10InnerWhereVyACyq_q_Gq__GD
125128
// CHECK-TYPE: GenericOuter<τ_0_0, τ_0_1>.Inner
126129
// CHECK-TYPE: GenericOuter<τ_0_0, τ_0_1>.GenericInner<τ_1_0, τ_1_1>
130+
// CHECK-TYPE: GenericOuter<GenericOuter<τ_0_1, τ_0_1>, τ_0_1>.InnerWhere
127131

128132
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO5InnerVySiSS_GD
129133
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO0C5InnerVySiSS_SfSdGD
134+
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO10InnerWhereVyACyS2bGSb_GD
130135
// CHECK-TYPE: GenericOuter<Int, String>.Inner
131136
// CHECK-TYPE: GenericOuter<Int, String>.GenericInner<Float, Double>
137+
// CHECK-TYPE: GenericOuter<GenericOuter<Bool, Bool>, Bool>.InnerWhere
132138

133139
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterOyxq_GD
134140
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterOySiSSGD
@@ -153,6 +159,8 @@ extension STSContainer℠ where T == STSOuter {
153159

154160
// DEMANGLE-TYPE: $s13nominal_types12STSContainerO8SubclassC11ExtraNestedCyAA8STSOuterV_Si_G
155161
// CHECK-TYPE: STSContainer<STSOuter>.Subclass<Int>.ExtraNested
162+
// DEMANGLE-TYPE: $s13nominal_types12STSContainerO8SubclassC16ExtraNestedWhereCyAA8STSOuterV_AEyAI_AIG_G
163+
// CHECK-TYPE: STSContainer<STSOuter>.Subclass<STSContainer<STSOuter>.Subclass<STSOuter>>.ExtraNestedWhere
156164
// DEMANGLE-TYPE: $s13nominal_types0017STSContainer_swCgOA2A8STSOuterVRszrlE8SubclassC11ExtraNestedCyAE_Si_G
157165
// CHECK-TYPE: STSContainer℠<STSOuter>.Subclass<Int>.ExtraNested
158166

@@ -177,6 +185,7 @@ extension STSContainer℠ where T == STSOuter {
177185
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO
178186
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO5InnerV
179187
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO0C5InnerV
188+
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO10InnerWhereV
180189
// DEMANGLE-DECL: $s13nominal_types1PP
181190
// DEMANGLE-DECL: $s13nominal_types11ConstrainedV
182191

@@ -186,5 +195,6 @@ extension STSContainer℠ where T == STSOuter {
186195
// CHECK-DECL: nominal_types.(file).GenericOuter
187196
// CHECK-DECL: nominal_types.(file).GenericOuter.Inner
188197
// CHECK-DECL: nominal_types.(file).GenericOuter.GenericInner
198+
// CHECK-DECL: nominal_types.(file).GenericOuter.InnerWhere
189199
// CHECK-DECL: nominal_types.(file).P
190200
// CHECK-DECL: nominal_types.(file).Constrained

test/attr/attr_override.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ class SR_4206_DerivedGeneric_6<T>: SR_4206_BaseConcrete_6 {
579579
override func foo<T: SR_4206_Protocol_1>(arg: T) {} // expected-error {{overridden method 'foo' has generic signature <T, T where T : SR_4206_Protocol_1> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_2>; expected generic signature to be <T, T where T : SR_4206_Protocol_2>}}
580580
}
581581

582-
// Where clauses on contextually generic declarations
582+
// Contextual where clauses on non-generic members
583583

584584
class SR_4206_Base_7<T> {
585585
func foo1() where T: SR_4206_Protocol_1 {} // expected-note {{overridden declaration is here}}
@@ -598,6 +598,14 @@ class SR_4206_Base_8<T> {
598598
func foo() where T: SR_4206_Protocol_1 {}
599599
}
600600
class SR_4206_Derived_8<T: SR_4206_Protocol_2, U>: SR_4206_Base_8<T> {
601+
// Because the generic signature of foo() is the same either way,
602+
// it may seem confusing that placing an additional constraint on the
603+
// generic parameter declaration directly has a different effect on
604+
// overridability in contrast to placing the constraint on foo().
605+
// The former (unlike the latter) is accepted because the constraint
606+
// in question only affects the ability to initialize an instance of the
607+
// subclass — not the visibility of the override itself relative to an
608+
// existing instance.
601609
override func foo() where T: SR_4206_Protocol_1 {} // OK
602610
}
603611

0 commit comments

Comments
 (0)