Sema: Fix substMemberTypeWithBase() for non-generic typealias with 'where' clause

getContextSubstitutionMap() builds a substitution map for the generic signature of
the parent context, which is wrong if the typealias has its own 'where' clause.
This commit is contained in:
Slava Pestov
2022-11-18 13:36:57 -05:00
parent 1457f8d2d1
commit 3dc7a2decd
3 changed files with 15 additions and 4 deletions

View File

@@ -4623,7 +4623,7 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
auto *aliasDecl = dyn_cast<TypeAliasDecl>(member);
if (aliasDecl) {
if (aliasDecl->getGenericParams()) {
if (aliasDecl->isGeneric()) {
return UnboundGenericType::get(
aliasDecl, baseTy,
aliasDecl->getASTContext());
@@ -4647,7 +4647,7 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
if (baseTy->is<ErrorType>())
return ErrorType::get(memberType);
subs = baseTy->getContextSubstitutionMap(module, member->getDeclContext());
subs = baseTy->getMemberSubstitutionMap(module, member);
resultType = memberType.subst(subs);
} else {
resultType = memberType;

View File

@@ -127,6 +127,8 @@ struct Container<T> {
// expected-error@-1 {{invalid redeclaration of 'NestedAlias}}
typealias NestedAlias2 = T.Magnitude where T: FixedWidthInteger
typealias NestedAlias3 = T.Element where T: Sequence
class NestedClass where T: Equatable {}
}
@@ -154,3 +156,12 @@ _ = Container<Bool>.NestedClass.self
_ = Container<String>.NestedStruct.self
_ = Container<Array<UInt8>>.NestedStruct2.self
_ = Container<Array<Double>>.NestedStruct2.NestedEnum.self
// Make sure the substitution here actually succeeds instead of producing an ErrorType
func sameType<T>(_: T.Type, _: T.Type) {}
sameType(Container<Array<Int>>.NestedAlias3.self, Int.self)
sameType(Container<Array<Bool>>.NestedAlias3.self, Int.self)
// expected-error@-1 {{cannot convert value of type 'Int.Type' to expected argument type 'Container<Array<Bool>>.NestedAlias3.Type' (aka 'Bool.Type')}}
sameType(Container<Array<Int>>.NestedAlias3.self, Bool.self)
// expected-error@-1 {{cannot convert value of type 'Bool.Type' to expected argument type 'Container<Array<Int>>.NestedAlias3.Type' (aka 'Int.Type')}}

View File

@@ -8,8 +8,8 @@ protocol P {
struct Type<Param> {}
extension Type: P where Param: P, Param.A == Type<Param> {
// expected-error@-1 6{{extension of generic struct 'Type' has self-referential generic requirements}}
// expected-note@-2 6{{through reference here}}
// expected-error@-1 5{{extension of generic struct 'Type' has self-referential generic requirements}}
// expected-note@-2 5{{through reference here}}
// expected-error@-3 {{type 'Type<Param>' does not conform to protocol 'P'}}
typealias A = Param
// expected-note@-1 2{{through reference here}}