Sema: Fix for archetypes leaking through when resolving generic type alias

Also make the existing assertion for this stricter. Previously,
we were calling hasArchetype() on a GenericFunctionType, which
is always false (along with hasTypeParameter()) since generic
function types don't have any free type parameters in them.

Fixes <rdar://problem/27405113>.
This commit is contained in:
Slava Pestov
2016-07-24 02:01:40 -07:00
parent 825ee70f05
commit c55e0eecea
3 changed files with 13 additions and 6 deletions

View File

@@ -638,6 +638,11 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func) {
if (i == 0 && func->hasThrows()) if (i == 0 && func->hasThrows())
info = info.withThrows(); info = info.withThrows();
assert(!argTy->hasArchetype());
assert(!funcTy->hasArchetype());
if (initFuncTy)
assert(!initFuncTy->hasArchetype());
if (sig && i == e-1) { if (sig && i == e-1) {
funcTy = GenericFunctionType::get(sig, argTy, funcTy, info); funcTy = GenericFunctionType::get(sig, argTy, funcTy, info);
if (initFuncTy) if (initFuncTy)
@@ -650,12 +655,9 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func) {
} }
// Record the interface type. // Record the interface type.
assert(!funcTy->hasArchetype());
func->setInterfaceType(funcTy); func->setInterfaceType(funcTy);
if (initFuncTy) { if (initFuncTy)
assert(!initFuncTy->hasArchetype());
cast<ConstructorDecl>(func)->setInitializerInterfaceType(initFuncTy); cast<ConstructorDecl>(func)->setInitializerInterfaceType(initFuncTy);
}
if (func->getGenericParams()) { if (func->getGenericParams()) {
// Collect all generic params referenced in parameter types, // Collect all generic params referenced in parameter types,

View File

@@ -519,8 +519,7 @@ Type TypeChecker::applyUnboundGenericArguments(
if (auto outerSig = TAD->getDeclContext()->getGenericSignatureOfContext()) { if (auto outerSig = TAD->getDeclContext()->getGenericSignatureOfContext()) {
for (auto outerParam : outerSig->getGenericParams()) { for (auto outerParam : outerSig->getGenericParams()) {
subs[outerParam->getCanonicalType().getPointer()] = subs[outerParam->getCanonicalType().getPointer()] =
ArchetypeBuilder::mapTypeIntoContext(TAD->getDeclContext(), resolver->resolveGenericTypeParamType(outerParam);
outerParam);
} }
} }

View File

@@ -164,6 +164,12 @@ class GenericClass<T> {
} }
} }
let gc = GenericClass<Double>()
let fn: MyType<Double, Int> = gc.testCapture(s: 1, t: 1.0)
func use<T>(_ t: T) {}
use(fn)
// Make sure we apply base substitutions to the interface type of the typealias // Make sure we apply base substitutions to the interface type of the typealias
class ConcreteClass : GenericClass<String> { class ConcreteClass : GenericClass<String> {
func testSubstitutedCapture1<S>(s: S, t: String) -> TA<S> { func testSubstitutedCapture1<S>(s: S, t: String) -> TA<S> {