Skip to content

Commit 49e6a59

Browse files
authored
Merge pull request swiftlang#10163 from slavapestov/fix-generic-typealiases-part-infinity
Sema: Fix a few problems with generic typealiases in protocols
2 parents 5c58327 + 443ba23 commit 49e6a59

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
379379

380380
if (parentTy) {
381381
auto subs = parentTy->getContextSubstitutions(
382-
parentTy->getAnyNominal());
382+
unboundDecl->getDeclContext());
383383
for (auto pair : subs) {
384384
auto found = replacements.find(
385385
cast<GenericTypeParamType>(pair.first));

lib/Sema/TypeCheckType.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -456,14 +456,11 @@ Type TypeChecker::resolveTypeInContext(
456456
->castTo<GenericTypeParamType>());
457457
}
458458

459-
bool hasDependentType = typeDecl->getDeclaredInterfaceType()
460-
->hasTypeParameter();
461-
462459
// Simple case -- the type is not nested inside of another type.
463460
// However, it might be nested inside another generic context, so
464461
// we do want to write the type in terms of interface types or
465462
// context archetypes, depending on the resolver given to us.
466-
if (!selfType || !hasDependentType) {
463+
if (!selfType) {
467464
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
468465
// For a generic typealias, return the unbound generic form of the type.
469466
if (aliasDecl->getGenericParams())
@@ -478,7 +475,7 @@ Type TypeChecker::resolveTypeInContext(
478475
if (auto *nominalDecl = dyn_cast<NominalTypeDecl>(typeDecl))
479476
return nominalDecl->getDeclaredType();
480477

481-
assert(!hasDependentType);
478+
assert(isa<ModuleDecl>(typeDecl));
482479
return typeDecl->getDeclaredInterfaceType();
483480
}
484481

@@ -662,20 +659,28 @@ Type TypeChecker::applyUnboundGenericArguments(
662659
// generic arguments.
663660
auto resultType = decl->getDeclaredInterfaceType();
664661

662+
bool hasTypeParameterOrVariable = false;
663+
665664
// Get the substitutions for outer generic parameters from the parent
666-
// type, but skip the step if the result type does not contain any
667-
// substitutable type parameters.
668-
if (resultType->hasTypeParameter())
669-
if (auto parentType = unboundType->getParent())
670-
subs = parentType->getContextSubstitutions(decl->getDeclContext());
665+
// type.
666+
if (auto parentType = unboundType->getParent()) {
667+
if (parentType->hasUnboundGenericType()) {
668+
assert(!resultType->hasTypeParameter());
669+
return resultType;
670+
}
671+
672+
subs = parentType->getContextSubstitutions(decl->getDeclContext());
673+
674+
hasTypeParameterOrVariable |=
675+
(parentType->hasTypeParameter() || parentType->hasTypeVariable());
676+
}
671677

672678
SourceLoc noteLoc = decl->getLoc();
673679
if (noteLoc.isInvalid())
674680
noteLoc = loc;
675681

676682
// Realize the types of the generic arguments and add them to the
677683
// substitution map.
678-
bool hasTypeParameterOrVariable = false;
679684
for (unsigned i = 0, e = genericArgs.size(); i < e; i++) {
680685
auto &genericArg = genericArgs[i];
681686

test/decl/typealias/generic.swift

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,64 @@ class AnotherGeneric<T> {}
338338

339339
protocol P {
340340
associatedtype A
341-
typealias G1<T> = MyType<Self, T>
342-
typealias G2<T> = MyType<T, A>
341+
typealias G1<T> = MyType<Self, T> // expected-note {{did you mean 'G1'?}}
342+
typealias G2<T> = MyType<T, A> // expected-note {{did you mean 'G2'?}}
343+
typealias G3<T> = () -> () // expected-note {{did you mean 'G3'?}}
344+
typealias G4<T> = (T) -> () // expected-note {{did you mean 'G4'?}}
345+
346+
func firstRequirement(_: G1<Int>)
347+
func secondRequirement(_: G2<Int>)
348+
func thirdRequirement(_: G3<Int>)
349+
func fourthRequirement(_: G4<Int>)
350+
351+
func firstRequirementGeneric<T>(_: G1<T>)
352+
func secondRequirementGeneric<T>(_: G2<T>)
353+
func thirdRequirementGeneric<T>(_: G3<T>, _: T)
354+
func fourthRequirementGeneric<T>(_: G4<T>)
343355
}
344356

345357
struct S : P {
346358
typealias A = Float
359+
360+
func shouldFail(fn: (Int) -> ()) {
361+
thirdRequirement(fn)
362+
// expected-error@-1 {{cannot convert value of type '(Int) -> ()' to expected argument type '() -> ()'}}
363+
}
364+
365+
func firstRequirement(_: G1<Int>) {}
366+
func secondRequirement(_: G2<Int>) {}
367+
func thirdRequirement(_: G3<Int>) {}
368+
func fourthRequirement(_: G4<Int>) {}
369+
370+
func firstRequirementGeneric<T>(_: G1<T>) {
371+
_ = G1<T>.self // FIXME // expected-error {{use of unresolved identifier 'G1'}}
372+
}
373+
374+
func secondRequirementGeneric<T>(_: G2<T>) {
375+
_ = G2<T>.self // FIXME // expected-error {{use of unresolved identifier 'G2'}}
376+
}
377+
378+
func thirdRequirementGeneric<T>(_: G3<T>, _: T) {
379+
_ = G3<T>.self // FIXME // expected-error {{use of unresolved identifier 'G3'}}
380+
}
381+
382+
func fourthRequirementGeneric<T>(_: G4<T>) {
383+
_ = G4<T>.self // FIXME // expected-error {{use of unresolved identifier 'G4'}}
384+
}
385+
386+
func expressionContext() {
387+
let _: G1 = MyType<S, Int>(a: S(), b: 3)
388+
let _: G1<Int> = MyType<S, Int>(a: S(), b: 3)
389+
390+
let _: S.G1 = MyType<S, Int>(a: S(), b: 3)
391+
let _: S.G1<Int> = MyType<S, Int>(a: S(), b: 3)
392+
393+
let _: G2 = MyType<Int, Float>(a: 3, b: 1.0)
394+
let _: G2<Int> = MyType<Int, Float>(a: 3, b: 1.0)
395+
396+
let _: S.G2 = MyType<Int, Float>(a: 3, b: 1.0)
397+
let _: S.G2<Int> = MyType<Int, Float>(a: 3, b: 1.0)
398+
}
347399
}
348400

349401
func takesMyType(x: MyType<S, Int>) {}

0 commit comments

Comments
 (0)