Merge pull request #30423 from AnthonyLatsis/se-0267-additions

[SE-0267] Improvements (Ep. 1)
This commit is contained in:
Anthony Latsis
2020-03-21 08:59:13 +03:00
committed by GitHub
11 changed files with 103 additions and 45 deletions

View File

@@ -1658,9 +1658,6 @@ ERROR(redundant_class_requirement,none,
"redundant 'class' requirement", ())
ERROR(late_class_requirement,none,
"'class' must come first in the requirement list", ())
ERROR(where_toplevel_nongeneric,none,
"'where' clause cannot be attached to non-generic "
"top-level declaration", ())
ERROR(where_inside_brackets,none,
"'where' clause next to generic parameters is obsolete, "
"must be written following the declaration's type", ())

View File

@@ -1575,7 +1575,7 @@ NOTE(unstable_mangled_name_add_objc,none,
"for compatibility with existing archives, use '@objc' "
"to record the Swift 3 runtime name", ())
// Generic types
// Generic declarations
ERROR(unsupported_type_nested_in_generic_function,none,
"type %0 cannot be nested in generic function %1",
(Identifier, DeclName))
@@ -1591,6 +1591,12 @@ ERROR(unsupported_type_nested_in_protocol_extension,none,
ERROR(unsupported_nested_protocol,none,
"protocol %0 cannot be nested inside another declaration",
(Identifier))
ERROR(where_nongeneric_ctx,none,
"'where' clause on non-generic member declaration requires a "
"generic context", ())
ERROR(where_nongeneric_toplevel,none,
"'where' clause cannot be applied to a non-generic top-level "
"declaration", ())
// Type aliases
ERROR(type_alias_underlying_type_access,none,
@@ -2755,10 +2761,6 @@ ERROR(dynamic_self_stored_property_init,none,
ERROR(dynamic_self_default_arg,none,
"covariant 'Self' type cannot be referenced from a default argument expression", ())
ERROR(where_nongeneric_ctx,none,
"'where' clause on non-generic member declaration requires a "
"generic context", ())
//------------------------------------------------------------------------------
// MARK: Type Check Attributes
//------------------------------------------------------------------------------

View File

@@ -418,12 +418,10 @@ parseFreestandingGenericWhereClause(GenericContext *genCtx,
genericParams->addTrailingWhereClause(Context, WhereLoc, Requirements);
// A where clause that references only outer generic parameters?
} else if (flags.contains(PD_HasContainerType)) {
} else {
// A where clause against outer generic parameters.
genCtx->setTrailingWhereClause(
TrailingWhereClause::create(Context, WhereLoc, Requirements));
} else {
diagnose(WhereLoc, diag::where_toplevel_nongeneric);
}
return ParserStatus();

View File

@@ -620,11 +620,15 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
return cast<SubscriptDecl>(accessor->getStorage())->getGenericSignature();
}
// ...or we may have a where clause dependent on outer generic parameters.
// ...or we may only have a contextual where clause.
} else if (const auto *where = GC->getTrailingWhereClause()) {
// If there is no generic context for the where clause to
// rely on, diagnose that now and bail out.
if (!GC->isGenericContext()) {
if (GC->getParent()->isModuleScopeContext()) {
GC->getASTContext().Diags.diagnose(where->getWhereLoc(),
diag::where_nongeneric_toplevel);
return nullptr;
} else if (!GC->isGenericContext()) {
GC->getASTContext().Diags.diagnose(where->getWhereLoc(),
diag::where_nongeneric_ctx);
return nullptr;

View File

@@ -651,30 +651,25 @@ static Type checkContextualRequirements(Type type,
return type;
}
// We are interested in either a contextual where clause or
// a constrained extension context.
TypeSubstitutionMap subMap;
GenericSignature genericSig;
SourceLoc noteLoc;
if (decl->getTrailingWhereClause()) {
subMap = parentTy->getContextSubstitutions(decl->getDeclContext());
genericSig = decl->getGenericSignature();
noteLoc = decl->getLoc();
} else {
{
// We are interested in either a contextual where clause or
// a constrained extension context.
const auto ext = dyn_cast<ExtensionDecl>(decl->getDeclContext());
if (ext && ext->isConstrainedExtension()) {
subMap = parentTy->getContextSubstitutions(ext);
genericSig = ext->getGenericSignature();
if (decl->getTrailingWhereClause())
noteLoc = decl->getLoc();
else if (ext && ext->isConstrainedExtension())
noteLoc = ext->getLoc();
} else {
else
return type;
}
if (noteLoc.isInvalid())
noteLoc = loc;
}
if (noteLoc.isInvalid())
noteLoc = loc;
auto result =
const auto subMap = parentTy->getContextSubstitutions(decl->getDeclContext());
const auto genericSig = decl->getGenericSignature();
const auto result =
TypeChecker::checkGenericArguments(
dc, loc, noteLoc, type,
genericSig->getGenericParams(),

View File

@@ -1,17 +1,5 @@
// RUN: %target-typecheck-verify-swift
func bet() where A : B {} // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
typealias gimel = Int where A : B // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
class dalet where A : B {} // expected-error {{'where' clause cannot be attached to non-generic top-level declaration}}
struct Where {
func bet() where A == B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
typealias gimel = Int where A : B // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
class dalet where A : B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
}
protocol he where A : B { // expected-error {{use of undeclared type 'A'}}
// expected-error@-1 {{use of undeclared type 'B'}}

View File

@@ -1,5 +1,17 @@
// RUN: %target-typecheck-verify-swift -typecheck %s -verify -swift-version 4
func bet() where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
typealias gimel = Int where A : B // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
class dalet where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}
struct Where {
func bet() where A == B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
typealias gimel = Int where A : B // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
class dalet where A : B {} // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
}
// Make sure Self: ... is correctly diagnosed in classes
class SelfInGenericClass<T> {

View File

@@ -557,3 +557,32 @@ class MoreGenericSub2<TT, T> : GenericBase<T> {
// CHECK-NEXT: #GenericBase.init!allocator: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$s27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufC [override]
// CHECK-NEXT: #MoreGenericSub2.deinit!deallocator: @$s27vtable_thunks_reabstraction15MoreGenericSub2CfD // MoreGenericSub2.__deallocating_deinit
// CHECK-NEXT: }
protocol SE_0267_P1 {}
class SE_0267_Base1<T> {
func foo() where T: SE_0267_P1 {}
}
class SE_0267_Derived1<T>: SE_0267_Base1<T> {
override func foo() {}
}
// CHECK-LABEL: sil_vtable SE_0267_Derived1 {
// 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]
// CHECK-NEXT: #SE_0267_Base1.init
// CHECK-NEXT: #SE_0267_Derived1.foo: <T> (SE_0267_Derived1<T>) -> () -> () : @$s27vtable_thunks_reabstraction16SE_0267_Derived1C3fooyyF
// CHECK-NEXT: #SE_0267_Derived1.deinit
// CHECK-NEXT: }
class SE_0267_Base2<T> {
func foo() -> T where T: FixedWidthInteger { fatalError() }
}
class SE_0267_Derived2: SE_0267_Base2<Int> {
override func foo() -> Int { return .zero }
}
// CHECK-LABEL: sil_vtable SE_0267_Derived2 {
// CHECK-NEXT: #SE_0267_Base2.foo: <T where T : FixedWidthInteger> (SE_0267_Base2<T>) -> () -> T : @$s27vtable_thunks_reabstraction16SE_0267_Derived2C3fooSiyFAA0D11_0267_Base2CADxys17FixedWidthIntegerRzlFTV [override]
// CHECK-NEXT: #SE_0267_Base2.init
// CHECK-NEXT: #SE_0267_Derived2.deinit
// CHECK-NEXT: }

View File

@@ -20,9 +20,11 @@ struct Outer {
struct GenericOuter<T> {
typealias Alias<T> = Int
typealias AliasWhere = Int where T == GenericOuter<Never>
struct Inner {
typealias Alias<T> = Int
typealias AliasWhere = Int where T: Equatable
}
}
@@ -32,6 +34,7 @@ protocol Proto {
extension Proto {
typealias OtherAlias<T> = Int
typealias OtherAliasWhere = Int where Self == Conforms
}
extension GenericOuter where T : Proto {
@@ -90,16 +93,22 @@ do {
// CHECK-TYPE: Outer.Inner.Alias<String>
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5AliasaySi_SSGD
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV10AliasWhereayACys5NeverOG_GD
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5InnerV5AliasaySi__SSGD
// DEMANGLE-TYPE: $s17generic_typealias12GenericOuterV5InnerV10AliasWhereaySi__GD
// CHECK-TYPE: GenericOuter<Int>.Alias<String>
// CHECK-TYPE: GenericOuter<GenericOuter<Never>>.AliasWhere
// CHECK-TYPE: GenericOuter<Int>.Inner.Alias<String>
// CHECK-TYPE: GenericOuter<Int>.Inner.AliasWhere
// DEMANGLE-TYPE: $s17generic_typealias5ProtoP5AliasayAA8ConformsV_SSGD
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE10OtherAliasayAA8ConformsV_SSGD
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE15OtherAliasWhereayAA8ConformsV_GD
// CHECK-TYPE: Conforms.Alias<String>
// CHECK-TYPE: Conforms.OtherAlias<String>
// CHECK-TYPE: Conforms.OtherAliasWhere
// DEMANGLE-TYPE: $s17generic_typealias5ProtoP5Aliasayx_SSGD
// DEMANGLE-TYPE: $s17generic_typealias5ProtoPAAE10OtherAliasayx_SSGD
@@ -116,16 +125,22 @@ do {
// DEMANGLE-DECL: $s17generic_typealias5OuterV5Aliasa
// DEMANGLE-DECL: $s17generic_typealias5OuterV5InnerV5Aliasa
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5Aliasa
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV10AliasWherea
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5InnerV5Aliasa
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterV5InnerV10AliasWherea
// DEMANGLE-DECL: $s17generic_typealias5ProtoP5Aliasa
// DEMANGLE-DECL: $s17generic_typealias5ProtoPAAE10OtherAliasa
// DEMANGLE-DECL: $s17generic_typealias5ProtoPAAE15OtherAliasWherea
// DEMANGLE-DECL: $s17generic_typealias12GenericOuterVA2A5ProtoRzlE16ConditionalAliasa
// CHECK-DECL: generic_typealias.(file).Alias
// CHECK-DECL: generic_typealias.(file).Outer.Alias
// CHECK-DECL: generic_typealias.(file).Outer.Inner.Alias
// CHECK-DECL: generic_typealias.(file).GenericOuter.Alias
// CHECK-DECL: generic_typealias.(file).GenericOuter.AliasWhere
// CHECK-DECL: generic_typealias.(file).GenericOuter.Inner.Alias
// CHECK-DECL: generic_typealias.(file).GenericOuter.Inner.AliasWhere
// CHECK-DECL: generic_typealias.(file).Proto.Alias
// CHECK-DECL: generic_typealias.(file).Proto extension.OtherAlias
// CHECK-DECL: generic_typealias.(file).Proto extension.OtherAliasWhere
// CHECK-DECL: generic_typealias.(file).GenericOuter extension.ConditionalAlias

View File

@@ -25,6 +25,7 @@ enum GenericOuter<T, U> {
struct Inner {}
struct GenericInner<T, U> {}
struct InnerWhere where T == GenericOuter<U, U> {}
}
func blackHole(_: Any...) {}
@@ -59,6 +60,7 @@ enum STSContainer<T : STSTagProtocol> {
class Superclass {}
class Subclass<U>: Superclass where T == STSOuter {
class ExtraNested: Superclass {}
class ExtraNestedWhere: Superclass where U: Subclass<T> {}
}
class GenericSuperclass<U> {}
@@ -122,13 +124,17 @@ extension STSContainer℠ where T == STSOuter {
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO5InnerVyxq__GD
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO0C5InnerVyxq__qd__qd_0_GD
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO10InnerWhereVyACyq_q_Gq__GD
// CHECK-TYPE: GenericOuter<τ_0_0, τ_0_1>.Inner
// CHECK-TYPE: GenericOuter<τ_0_0, τ_0_1>.GenericInner<τ_1_0, τ_1_1>
// CHECK-TYPE: GenericOuter<GenericOuter<τ_0_1, τ_0_1>, τ_0_1>.InnerWhere
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO5InnerVySiSS_GD
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO0C5InnerVySiSS_SfSdGD
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterO10InnerWhereVyACyS2bGSb_GD
// CHECK-TYPE: GenericOuter<Int, String>.Inner
// CHECK-TYPE: GenericOuter<Int, String>.GenericInner<Float, Double>
// CHECK-TYPE: GenericOuter<GenericOuter<Bool, Bool>, Bool>.InnerWhere
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterOyxq_GD
// DEMANGLE-TYPE: $s13nominal_types12GenericOuterOySiSSGD
@@ -153,6 +159,8 @@ extension STSContainer℠ where T == STSOuter {
// DEMANGLE-TYPE: $s13nominal_types12STSContainerO8SubclassC11ExtraNestedCyAA8STSOuterV_Si_G
// CHECK-TYPE: STSContainer<STSOuter>.Subclass<Int>.ExtraNested
// DEMANGLE-TYPE: $s13nominal_types12STSContainerO8SubclassC16ExtraNestedWhereCyAA8STSOuterV_AEyAI_AIG_G
// CHECK-TYPE: STSContainer<STSOuter>.Subclass<STSContainer<STSOuter>.Subclass<STSOuter>>.ExtraNestedWhere
// DEMANGLE-TYPE: $s13nominal_types0017STSContainer_swCgOA2A8STSOuterVRszrlE8SubclassC11ExtraNestedCyAE_Si_G
// CHECK-TYPE: STSContainer<STSOuter>.Subclass<Int>.ExtraNested
@@ -177,6 +185,7 @@ extension STSContainer℠ where T == STSOuter {
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO5InnerV
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO0C5InnerV
// DEMANGLE-DECL: $s13nominal_types12GenericOuterO10InnerWhereV
// DEMANGLE-DECL: $s13nominal_types1PP
// DEMANGLE-DECL: $s13nominal_types11ConstrainedV
@@ -186,5 +195,6 @@ extension STSContainer℠ where T == STSOuter {
// CHECK-DECL: nominal_types.(file).GenericOuter
// CHECK-DECL: nominal_types.(file).GenericOuter.Inner
// CHECK-DECL: nominal_types.(file).GenericOuter.GenericInner
// CHECK-DECL: nominal_types.(file).GenericOuter.InnerWhere
// CHECK-DECL: nominal_types.(file).P
// CHECK-DECL: nominal_types.(file).Constrained

View File

@@ -579,7 +579,7 @@ class SR_4206_DerivedGeneric_6<T>: SR_4206_BaseConcrete_6 {
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>}}
}
// Where clauses on contextually generic declarations
// Contextual where clauses on non-generic members
class SR_4206_Base_7<T> {
func foo1() where T: SR_4206_Protocol_1 {} // expected-note {{overridden declaration is here}}
@@ -598,6 +598,14 @@ class SR_4206_Base_8<T> {
func foo() where T: SR_4206_Protocol_1 {}
}
class SR_4206_Derived_8<T: SR_4206_Protocol_2, U>: SR_4206_Base_8<T> {
// Because the generic signature of foo() is the same either way,
// it may seem confusing that placing an additional constraint on the
// generic parameter declaration directly has a different effect on
// overridability in contrast to placing the constraint on foo().
// The former (unlike the latter) is accepted because the constraint
// in question only affects the ability to initialize an instance of the
// subclass not the visibility of the override itself relative to an
// existing instance.
override func foo() where T: SR_4206_Protocol_1 {} // OK
}