Skip to content

Commit 19bc18f

Browse files
authored
Merge pull request #82152 from hamishknight/fix-nested-arenas-6.2
2 parents 9bf1d28 + bd4c3ad commit 19bc18f

File tree

10 files changed

+54
-13
lines changed

10 files changed

+54
-13
lines changed

include/swift/AST/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,12 @@ class alignas(1 << TypeAlignInBits) TypeBase
720720
return getRecursiveProperties().hasTypeVariable();
721721
}
722722

723+
// Convenience for checking whether the given type either has a type
724+
// variable or placeholder.
725+
bool hasTypeVariableOrPlaceholder() const {
726+
return hasTypeVariable() || hasPlaceholder();
727+
}
728+
723729
/// Determine where this type is a type variable or a dependent
724730
/// member root in a type variable.
725731
bool isTypeVariableOrMember();

lib/Sema/CSFix.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,12 @@ CoerceToCheckedCast *CoerceToCheckedCast::attempt(ConstraintSystem &cs,
185185
Type fromType, Type toType,
186186
bool useConditionalCast,
187187
ConstraintLocator *locator) {
188-
// If any of the types has a type variable, don't add the fix.
189-
if (fromType->hasTypeVariable() || toType->hasTypeVariable())
188+
// If any of the types have type variables or placeholders, don't add the fix.
189+
// `typeCheckCheckedCast` doesn't support checking such types.
190+
if (fromType->hasTypeVariableOrPlaceholder() ||
191+
toType->hasTypeVariableOrPlaceholder()) {
190192
return nullptr;
193+
}
191194

192195
auto anchor = locator->getAnchor();
193196
if (auto *assignExpr = getAsExpr<AssignExpr>(anchor))

lib/Sema/CSRanking.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,11 +1413,9 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
14131413
auto type1 = types.Type1;
14141414
auto type2 = types.Type2;
14151415

1416-
// If either of the types still contains type variables, we can't
1417-
// compare them.
1418-
// FIXME: This is really unfortunate. More type variable sharing
1419-
// (when it's sound) would help us do much better here.
1420-
if (type1->hasTypeVariable() || type2->hasTypeVariable()) {
1416+
// `isSubtypeOf` cannot be used with solver-allocated types.
1417+
if (type1->getRecursiveProperties().isSolverAllocated() ||
1418+
type2->getRecursiveProperties().isSolverAllocated()) {
14211419
identical = false;
14221420
continue;
14231421
}

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4910,8 +4910,12 @@ static bool
49104910
repairViaBridgingCast(ConstraintSystem &cs, Type fromType, Type toType,
49114911
SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
49124912
ConstraintLocatorBuilder locator) {
4913-
if (fromType->hasTypeVariable() || toType->hasTypeVariable())
4913+
// Don't check if any of the types have type variables or placeholders,
4914+
// `typeCheckCheckedCast` doesn't support checking solver-allocated types.
4915+
if (fromType->hasTypeVariableOrPlaceholder() ||
4916+
toType->hasTypeVariableOrPlaceholder()) {
49144917
return false;
4918+
}
49154919

49164920
auto objectType1 = fromType->getOptionalObjectType();
49174921
auto objectType2 = toType->getOptionalObjectType();
@@ -9373,10 +9377,12 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
93739377
if (locator.endsWith<LocatorPathElt::GenericArgument>())
93749378
return nullptr;
93759379

9376-
// Both types have to be fixed.
9377-
if (fromType->hasTypeVariable() || toType->hasTypeVariable() ||
9378-
fromType->hasPlaceholder() || toType->hasPlaceholder())
9380+
// Both types have to be resolved, `typeCheckCheckedCast` doesn't support
9381+
// checking solver-allocated types.
9382+
if (fromType->hasTypeVariableOrPlaceholder() ||
9383+
toType->hasTypeVariableOrPlaceholder()) {
93799384
return nullptr;
9385+
}
93809386

93819387
SmallVector<LocatorPathElt, 4> path;
93829388
auto anchor = locator.getLocatorParts(path);

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,8 +1055,15 @@ bool TypeChecker::typesSatisfyConstraint(Type type1, Type type2,
10551055
bool openArchetypes,
10561056
ConstraintKind kind, DeclContext *dc,
10571057
bool *unwrappedIUO) {
1058-
assert(!type1->hasTypeVariable() && !type2->hasTypeVariable() &&
1059-
"Unexpected type variable in constraint satisfaction testing");
1058+
// Don't allow any type variables to leak into the nested ConstraintSystem
1059+
// (including as originator types for placeholders). This also ensure that we
1060+
// avoid lifetime issues for e.g cases where we lazily populate the
1061+
// `ContextSubMap` on `NominalOrBoundGenericNominalType` in the nested arena,
1062+
// since it will be destroyed on leaving.
1063+
CONDITIONAL_ASSERT(
1064+
!type1->getRecursiveProperties().isSolverAllocated() &&
1065+
!type2->getRecursiveProperties().isSolverAllocated() &&
1066+
"Cannot escape solver-allocated types into a nested ConstraintSystem");
10601067

10611068
ConstraintSystem cs(dc, ConstraintSystemOptions());
10621069
if (openArchetypes) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// {"signature":"bool llvm::function_ref<bool (swift::ProtocolConformanceRef)>::callback_fn<(anonymous namespace)::MismatchedIsolatedConformances>(long, swift::ProtocolConformanceRef)"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
func a {
4+
{ print("\(\ " ")\n"
5+
}
6+
"\()\n"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// {"signature":"swift::ProtocolConformanceRef::forEachMissingConformance(llvm::function_ref<bool (swift::BuiltinProtocolConformance*)>) const"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
.a == .! == b / c
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// {"signature":"swift::GenericParamKey::findIndexIn(llvm::ArrayRef<swift::GenericTypeParamType*>) const"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
a[[[[ a a?[[a a?
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// {"signature":"swift::ProtocolConformanceRef::forAbstract(swift::Type, swift::ProtocolDecl*)"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
@resultBuilder struct a {
4+
static buildBlock<b, c, d, e>(b, c, d, e) func f<h>(_ : Bool @a Bool->h) { f(true {
5+
cond in var g : Int g 2 30\ g
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// {"signature":"(anonymous namespace)::ApplyClassifier::classifyApply(swift::ApplyExpr*, llvm::DenseSet<swift::Expr const*, llvm::DenseMapInfo<swift::Expr const*, void>>*)"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
let a = switch \0 {
4+
case 0.0

0 commit comments

Comments
 (0)