Skip to content

Commit 3c17d35

Browse files
committed
CS: Use TypeResolutionStage::Interface for applying generic arguments in 'openUnboundGenericType'
1 parent e48f483 commit 3c17d35

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,9 +4037,12 @@ class ConstraintSystem {
40374037
/// parent type by introducing fresh type variables for generic parameters
40384038
/// and constructing a bound generic type from these type variables.
40394039
///
4040+
/// \param isTypeResolution Whether we are in the process of resolving a type.
4041+
///
40404042
/// \returns The opened type.
40414043
Type openUnboundGenericType(GenericTypeDecl *decl, Type parentTy,
4042-
ConstraintLocatorBuilder locator);
4044+
ConstraintLocatorBuilder locator,
4045+
bool isTypeResolution);
40434046

40444047
/// Replace placeholder types with fresh type variables, and unbound generic
40454048
/// types with bound generic types whose generic args are fresh type
@@ -5275,7 +5278,8 @@ class OpenUnboundGenericType {
52755278

52765279
Type operator()(UnboundGenericType *unboundTy) const {
52775280
return cs.openUnboundGenericType(unboundTy->getDecl(),
5278-
unboundTy->getParent(), locator);
5281+
unboundTy->getParent(), locator,
5282+
/*isTypeResolution=*/true);
52795283
}
52805284
};
52815285

lib/Sema/CSBindings.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,9 +1818,10 @@ bool TypeVarBindingProducer::computeNext() {
18181818
// always preserved.
18191819
auto *BGT = type->castTo<BoundGenericType>();
18201820
auto dstLocator = TypeVar->getImpl().getLocator();
1821-
auto newType = CS.openUnboundGenericType(BGT->getDecl(), BGT->getParent(),
1822-
dstLocator)
1823-
->reconstituteSugar(/*recursive=*/false);
1821+
auto newType =
1822+
CS.openUnboundGenericType(BGT->getDecl(), BGT->getParent(),
1823+
dstLocator, /*isTypeResolution=*/false)
1824+
->reconstituteSugar(/*recursive=*/false);
18241825
addNewBinding(binding.withType(newType));
18251826
}
18261827

lib/Sema/ConstraintSystem.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,10 @@ Optional<std::pair<unsigned, Expr *>> ConstraintSystem::getExprDepthAndParent(
628628
return None;
629629
}
630630

631-
Type ConstraintSystem::openUnboundGenericType(
632-
GenericTypeDecl *decl, Type parentTy, ConstraintLocatorBuilder locator) {
631+
Type ConstraintSystem::openUnboundGenericType(GenericTypeDecl *decl,
632+
Type parentTy,
633+
ConstraintLocatorBuilder locator,
634+
bool isTypeResolution) {
633635
if (parentTy) {
634636
parentTy = replaceInferableTypesWithTypeVars(parentTy, locator);
635637
}
@@ -642,7 +644,15 @@ Type ConstraintSystem::openUnboundGenericType(
642644
recordOpenedTypes(locator, replacements);
643645

644646
if (parentTy) {
645-
auto subs = parentTy->getContextSubstitutions(decl->getDeclContext());
647+
const auto parentTyInContext =
648+
isTypeResolution
649+
// Type resolution produces interface types, so we have to map
650+
// the parent type into context before binding type variables.
651+
? DC->mapTypeIntoContext(parentTy)
652+
: parentTy;
653+
654+
const auto subs =
655+
parentTyInContext->getContextSubstitutions(decl->getDeclContext());
646656
for (auto pair : subs) {
647657
auto found = replacements.find(
648658
cast<GenericTypeParamType>(pair.first));
@@ -670,9 +680,17 @@ Type ConstraintSystem::openUnboundGenericType(
670680
// pointing at a generic TypeAliasDecl here. If we find a way to
671681
// handle generic TypeAliases elsewhere, this can just become a
672682
// call to BoundGenericType::get().
673-
return TypeResolution::forContextual(DC, None, /*unboundTyOpener*/ nullptr,
674-
/*placeholderHandler*/ nullptr)
675-
.applyUnboundGenericArguments(decl, parentTy, SourceLoc(), arguments);
683+
auto result =
684+
TypeResolution::forInterface(
685+
DC, None,
686+
[](auto) -> Type { llvm_unreachable("should not be used"); },
687+
[](auto &, auto) -> Type { llvm_unreachable("should not be used"); })
688+
.applyUnboundGenericArguments(decl, parentTy, SourceLoc(), arguments);
689+
if (!parentTy && !isTypeResolution) {
690+
result = DC->mapTypeIntoContext(result);
691+
}
692+
693+
return result;
676694
}
677695

678696
static void checkNestedTypeConstraints(ConstraintSystem &cs, Type type,
@@ -756,15 +774,13 @@ static void checkNestedTypeConstraints(ConstraintSystem &cs, Type type,
756774

757775
Type ConstraintSystem::replaceInferableTypesWithTypeVars(
758776
Type type, ConstraintLocatorBuilder locator) {
759-
assert(!type->getCanonicalType()->hasTypeParameter());
760-
761777
if (!type->hasUnboundGenericType() && !type->hasPlaceholder())
762778
return type;
763779

764780
type = type.transform([&](Type type) -> Type {
765781
if (auto unbound = type->getAs<UnboundGenericType>()) {
766782
return openUnboundGenericType(unbound->getDecl(), unbound->getParent(),
767-
locator);
783+
locator, /*isTypeResolution=*/false);
768784
} else if (auto *placeholderTy = type->getAs<PlaceholderType>()) {
769785
if (auto *placeholderRepr = placeholderTy->getOriginator()
770786
.dyn_cast<PlaceholderTypeRepr *>()) {

test/Constraints/generics.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,14 @@ func rdar79757320() {
930930
// expected-error@-1 {{cannot infer contextual base in reference to member 'a'}}
931931
// expected-error@-2 {{cannot infer contextual base in reference to member 'b'}}
932932
}
933+
934+
protocol P_eaf0300ff7a {}
935+
do {
936+
struct Outer<T: P_eaf0300ff7a> {
937+
struct Inner<U> {}
938+
939+
func container<T>() -> Inner<T> {
940+
return Inner()
941+
}
942+
}
943+
}

test/decl/typealias/generic.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ class GenericClass<T> {
132132
typealias TA<U> = MyType<T, U>
133133
typealias TAI<U> = MyType<Int, U>
134134

135+
func testNestedUnbound(t: T) {
136+
typealias Nested<X, Y> = MyType<X, Y>
137+
_ = Nested(a: t, b: t)
138+
}
139+
135140
func testCapture<S>(s: S, t: T) -> TA<S> {
136141
return TA<S>(a: t, b: s)
137142
}

0 commit comments

Comments
 (0)