mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Better cope with UnboundGenericType in TypeBase::getSuperclass()
Returning the unsubstituted superclass type is not correct, because it may contain type parameters. Let's form a new UnboundGenericType instead. - Fixes https://github.com/swiftlang/swift/issues/82160. - Fixes rdar://152989888.
This commit is contained in:
@@ -2249,10 +2249,24 @@ Type TypeBase::getSuperclass(bool useArchetypes) {
|
||||
Type superclassTy = classDecl->getSuperclass();
|
||||
|
||||
// If there's no superclass, or it is fully concrete, we're done.
|
||||
if (!superclassTy || !superclassTy->hasTypeParameter() ||
|
||||
hasUnboundGenericType())
|
||||
if (!superclassTy || !superclassTy->hasTypeParameter())
|
||||
return superclassTy;
|
||||
|
||||
auto hasUnboundGenericType = [&]() {
|
||||
Type t(this);
|
||||
while (t) {
|
||||
if (t->is<UnboundGenericType>())
|
||||
return true;
|
||||
t = t->getNominalParent();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// If we started with an UnboundGenericType, we cannot apply the
|
||||
// context substitution map. Return the unbound form of the superclass.
|
||||
if (hasUnboundGenericType())
|
||||
return superclassTy->getAnyNominal()->getDeclaredType();
|
||||
|
||||
// Gather substitutions from the self type, and apply them to the original
|
||||
// superclass type to form the substituted superclass type.
|
||||
auto subMap = getContextSubstitutionMap(classDecl,
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements validation for Swift types, emitting semantic errors as
|
||||
// appropriate and checking default initializer values.
|
||||
// This file implements type resolution, which converts syntactic type
|
||||
// representations into semantic types, emitting diagnostics as appropriate.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -6344,14 +6344,23 @@ Type TypeChecker::substMemberTypeWithBase(TypeDecl *member,
|
||||
: member->getDeclaredInterfaceType();
|
||||
SubstitutionMap subs;
|
||||
if (baseTy) {
|
||||
// Cope with the presence of unbound generic types, which are ill-formed
|
||||
// at this point but break the invariants of getContextSubstitutionMap().
|
||||
// If the base type contains an unbound generic type, we cannot
|
||||
// proceed to the getContextSubstitutionMap() call below.
|
||||
//
|
||||
// In general, this means the user program is ill-formed, but we
|
||||
// do allow type aliases to be referenced with an unbound generic
|
||||
// type as the base, if the underlying type of the type alias
|
||||
// does not contain type parameters.
|
||||
if (baseTy->hasUnboundGenericType()) {
|
||||
memberType = memberType->getReducedType(aliasDecl->getGenericSignature());
|
||||
|
||||
// This is the error case. The diagnostic is emitted elsewhere,
|
||||
// in TypeChecker::isUnsupportedMemberTypeAccess().
|
||||
if (memberType->hasTypeParameter())
|
||||
return ErrorType::get(memberType);
|
||||
|
||||
// Otherwise, there's no substitution to be performed, so we
|
||||
// just drop the base type.
|
||||
return memberType;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ let _: GenericStruct.ReferencesConcrete = foo()
|
||||
|
||||
class SuperG<T, U> {
|
||||
typealias Composed = (T, U)
|
||||
typealias Concrete = Int
|
||||
}
|
||||
|
||||
class SubG<T> : SuperG<T, T> { }
|
||||
@@ -74,3 +75,16 @@ typealias SubGX<T> = SubG<T?>
|
||||
func checkSugar(gs: SubGX<Int>.Composed) {
|
||||
let i4: Int = gs // expected-error{{cannot convert value of type 'SubGX<Int>.Composed' (aka '(Optional<Int>, Optional<Int>)') to specified type 'Int'}}
|
||||
}
|
||||
|
||||
// https://github.com/swiftlang/swift/issues/82160
|
||||
|
||||
let x1: SuperG.Concrete = 123
|
||||
let x2: SubG.Concrete = 123
|
||||
|
||||
func f1() -> SuperG.Concrete {
|
||||
return 123
|
||||
}
|
||||
|
||||
func f2() -> SubG.Concrete {
|
||||
return 123
|
||||
}
|
||||
Reference in New Issue
Block a user