Skip to content

Commit fef5257

Browse files
committed
Sema: Ensure archetypes don't leak through when a local generic function uses a typealias defined in function scope
When resolving a typealias, we need to feed it through the resolver even if it is not defined in type context. For example, func outer<T>(t: T) { typealias TT = T // We want 'TT' to resolve to the interface type and not the // archetype while we are building inner()'s generic signature func inner<U>(t: TT, u: U) {} }
1 parent 98a0e73 commit fef5257

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

lib/Sema/GenericTypeResolver.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ArchetypeBuilder;
2727
class AssociatedTypeDecl;
2828
class Identifier;
2929
class TypeChecker;
30+
class TypeDecl;
3031

3132
/// Abstract class that resolves references into generic types during
3233
/// type resolution.
@@ -77,6 +78,14 @@ class GenericTypeResolver {
7778
///
7879
/// \returns the type of context.
7980
virtual Type resolveTypeOfContext(DeclContext *dc) = 0;
81+
82+
/// Retrieve the type when referring to the given type declaration within
83+
/// its context.
84+
///
85+
/// \param decl A type declaration.
86+
///
87+
/// \returns the type of the declaration in context..
88+
virtual Type resolveTypeOfDecl(TypeDecl *decl) = 0;
8089
};
8190

8291
/// Generic type resolver that leaves all generic types dependent.
@@ -102,6 +111,8 @@ class DependentGenericTypeResolver : public GenericTypeResolver {
102111
AssociatedTypeDecl *assocType);
103112

104113
virtual Type resolveTypeOfContext(DeclContext *dc);
114+
115+
virtual Type resolveTypeOfDecl(TypeDecl *decl);
105116
};
106117

107118
/// Generic type resolver that maps a generic type parameter type to its
@@ -123,6 +134,7 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
123134

124135
virtual Type resolveTypeOfContext(DeclContext *dc);
125136

137+
virtual Type resolveTypeOfDecl(TypeDecl *decl);
126138
};
127139

128140
/// Generic type resolver that maps any generic type parameter type that
@@ -152,6 +164,8 @@ class PartialGenericTypeToArchetypeResolver : public GenericTypeResolver {
152164
AssociatedTypeDecl *assocType);
153165

154166
virtual Type resolveTypeOfContext(DeclContext *dc);
167+
168+
virtual Type resolveTypeOfDecl(TypeDecl *decl);
155169
};
156170

157171
/// Generic type resolver that performs complete resolution of dependent
@@ -181,6 +195,8 @@ class CompleteGenericTypeResolver : public GenericTypeResolver {
181195
AssociatedTypeDecl *assocType);
182196

183197
virtual Type resolveTypeOfContext(DeclContext *dc);
198+
199+
virtual Type resolveTypeOfDecl(TypeDecl *decl);
184200
};
185201

186202
} // end namespace swift

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ Type DependentGenericTypeResolver::resolveTypeOfContext(DeclContext *dc) {
5959
return ext->getExtendedType()->getAnyNominal()->getDeclaredInterfaceType();
6060
}
6161

62+
Type DependentGenericTypeResolver::resolveTypeOfDecl(TypeDecl *decl) {
63+
return decl->getDeclaredInterfaceType();
64+
}
65+
6266
Type GenericTypeToArchetypeResolver::resolveGenericTypeParamType(
6367
GenericTypeParamType *gp) {
6468
auto gpDecl = gp->getDecl();
@@ -90,6 +94,10 @@ Type GenericTypeToArchetypeResolver::resolveTypeOfContext(DeclContext *dc) {
9094
return dc->getDeclaredTypeInContext();
9195
}
9296

97+
Type GenericTypeToArchetypeResolver::resolveTypeOfDecl(TypeDecl *decl) {
98+
return decl->getDeclaredType();
99+
}
100+
93101
Type PartialGenericTypeToArchetypeResolver::resolveGenericTypeParamType(
94102
GenericTypeParamType *gp) {
95103
auto gpDecl = gp->getDecl();
@@ -129,6 +137,11 @@ PartialGenericTypeToArchetypeResolver::resolveTypeOfContext(DeclContext *dc) {
129137
return dc->getDeclaredTypeInContext();
130138
}
131139

140+
Type
141+
PartialGenericTypeToArchetypeResolver::resolveTypeOfDecl(TypeDecl *decl) {
142+
return decl->getDeclaredType();
143+
}
144+
132145
Type CompleteGenericTypeResolver::resolveGenericTypeParamType(
133146
GenericTypeParamType *gp) {
134147
// Retrieve the potential archetype corresponding to this generic type
@@ -223,6 +236,10 @@ Type CompleteGenericTypeResolver::resolveTypeOfContext(DeclContext *dc) {
223236
return ext->getExtendedType()->getAnyNominal()->getDeclaredInterfaceType();
224237
}
225238

239+
Type CompleteGenericTypeResolver::resolveTypeOfDecl(TypeDecl *decl) {
240+
return decl->getDeclaredInterfaceType();
241+
}
242+
226243
/// Check the generic parameters in the given generic parameter list (and its
227244
/// parent generic parameter lists) according to the given resolver.
228245
bool TypeChecker::checkGenericParamList(ArchetypeBuilder *builder,

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,18 @@ Type TypeChecker::resolveTypeInContext(
249249
nominalType = nullptr;
250250
}
251251

252-
if (nonTypeOwner)
252+
if (nonTypeOwner) {
253+
// If this is a typealias not in type context, we still need the
254+
// interface type; the typealias might be in a function context, and
255+
// its underlying type might reference outer generic parameters.
256+
if (isa<TypeAliasDecl>(typeDecl))
257+
return resolver->resolveTypeOfDecl(typeDecl);
258+
259+
// When a nominal type used outside its context, return the unbound
260+
// generic form of the type.
261+
assert(isa<NominalTypeDecl>(typeDecl) || isa<ModuleDecl>(typeDecl));
253262
return typeDecl->getDeclaredType();
263+
}
254264

255265
// For the next steps we need our parentDC to be a type context
256266
if (!parentDC->isTypeContext())

0 commit comments

Comments
 (0)