Skip to content

Commit 699977f

Browse files
committed
AST: Tweak getContextSubstitutions() for types inside generic functions
1 parent 8199e8d commit 699977f

File tree

2 files changed

+22
-23
lines changed

2 files changed

+22
-23
lines changed

lib/AST/Type.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,31 +3273,33 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
32733273
assert(ownerNominal == baseTy->getAnyNominal());
32743274

32753275
// Gather all of the substitutions for all levels of generic arguments.
3276-
GenericParamList *curGenericParams = dc->getGenericParamsOfContext();
3277-
if (!curGenericParams)
3276+
auto *genericSig = dc->getGenericSignatureOfContext();
3277+
if (!genericSig)
32783278
return substitutions;
32793279

3280-
while (baseTy && curGenericParams) {
3280+
auto params = genericSig->getGenericParams();
3281+
unsigned n = params.size();
3282+
3283+
while (baseTy && n > 0) {
32813284
// For a bound generic type, gather the generic parameter -> generic
32823285
// argument substitutions.
32833286
if (auto boundGeneric = baseTy->getAs<BoundGenericType>()) {
3284-
auto params = curGenericParams->getParams();
32853287
auto args = boundGeneric->getGenericArgs();
3286-
for (unsigned i = 0, n = args.size(); i != n; ++i) {
3287-
substitutions[params[i]->getDeclaredInterfaceType()->getCanonicalType()
3288+
for (unsigned i = 0, e = args.size(); i < e; ++i) {
3289+
substitutions[params[n - e + i]->getCanonicalType()
32883290
->castTo<GenericTypeParamType>()] = args[i];
32893291
}
32903292

32913293
// Continue looking into the parent.
32923294
baseTy = boundGeneric->getParent();
3293-
curGenericParams = curGenericParams->getOuterParameters();
3295+
n -= args.size();
32943296
continue;
32953297
}
32963298

32973299
// Continue looking into the parent.
32983300
if (auto protocolTy = baseTy->getAs<ProtocolType>()) {
32993301
baseTy = protocolTy->getParent();
3300-
curGenericParams = curGenericParams->getOuterParameters();
3302+
n--;
33013303
continue;
33023304
}
33033305

@@ -3310,19 +3312,16 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
33103312
llvm_unreachable("Bad base type");
33113313
}
33123314

3313-
if (genericEnv) {
3314-
auto *parentDC = dc;
3315-
while (parentDC->isTypeContext())
3316-
parentDC = parentDC->getParent();
3317-
if (auto *outerSig = parentDC->getGenericSignatureOfContext()) {
3318-
for (auto gp : outerSig->getGenericParams()) {
3319-
auto result = substitutions.insert(
3320-
{gp->getCanonicalType()->castTo<GenericTypeParamType>(),
3321-
genericEnv->mapTypeIntoContext(gp)});
3322-
assert(result.second);
3323-
(void) result;
3324-
}
3325-
}
3315+
while (n > 0) {
3316+
auto *gp = params[--n];
3317+
auto substTy = (genericEnv
3318+
? genericEnv->mapTypeIntoContext(gp)
3319+
: gp);
3320+
auto result = substitutions.insert(
3321+
{gp->getCanonicalType()->castTo<GenericTypeParamType>(),
3322+
substTy});
3323+
assert(result.second);
3324+
(void) result;
33263325
}
33273326

33283327
return substitutions;

test/decl/nested/type_in_function.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func hasAClosure() {
2323
}
2424

2525
protocol Racoon {
26-
associatedtype Stripes // expected-note{{protocol requires nested type 'Stripes'; do you want to add it?}}
26+
associatedtype Stripes
2727
}
2828

2929
// Types inside generic functions -- not supported yet
@@ -117,7 +117,7 @@ struct OuterGenericStruct<A> {
117117
}
118118

119119
func middleFunction() {
120-
struct ConformingType : Racoon { // expected-error{{type 'ConformingType' does not conform to protocol 'Racoon'}}
120+
struct ConformingType : Racoon {
121121
// expected-error@-1 {{type 'ConformingType' cannot be nested in generic function 'middleFunction()'}}
122122
typealias Stripes = A
123123
}

0 commit comments

Comments
 (0)