Skip to content

Commit 46a6500

Browse files
committed
[Constraint system] Eliminate global flag UnderlyingTypeForOpaqueReturnType
Make this information contextual (per type) rather than global (per constraint system) so we don’t misapply it.
1 parent cc44f22 commit 46a6500

File tree

5 files changed

+22
-19
lines changed

5 files changed

+22
-19
lines changed

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3831,7 +3831,8 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
38313831

38323832
case StmtConditionElement::CK_Boolean: {
38333833
Expr *condExpr = condElement.getBoolean();
3834-
setContextualType(condExpr, TypeLoc::withoutLoc(boolTy), CTP_Condition);
3834+
setContextualType(condExpr, TypeLoc::withoutLoc(boolTy), CTP_Condition,
3835+
/*isOpaqueReturnType=*/false);
38353836

38363837
condExpr = generateConstraints(condExpr, dc);
38373838
if (!condExpr) {

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9076,9 +9076,7 @@ void ConstraintSystem::addContextualConversionConstraint(
90769076
case CTP_ReturnStmt:
90779077
case CTP_ReturnSingleExpr:
90789078
case CTP_Initialization:
9079-
// FIXME: This option should not be global!
9080-
if (Options.contains(
9081-
ConstraintSystemFlags::UnderlyingTypeForOpaqueReturnType))
9079+
if (contextualType.isOpaqueReturnType)
90829080
constraintKind = ConstraintKind::OpaqueUnderlyingType;
90839081
break;
90849082

lib/Sema/CSSolver.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ void ConstraintSystem::applySolution(const Solution &solution) {
240240
for (const auto &contextualType : solution.contextualTypes) {
241241
if (!getContextualTypeInfo(contextualType.first)) {
242242
setContextualType(contextualType.first, contextualType.second.typeLoc,
243-
contextualType.second.purpose);
243+
contextualType.second.purpose,
244+
contextualType.second.isOpaqueReturnType);
244245
}
245246
}
246247

@@ -1239,7 +1240,13 @@ ConstraintSystem::solveImpl(Expr *&expr,
12391240
// If there is a type that we're expected to convert to, add the conversion
12401241
// constraint.
12411242
if (convertType) {
1242-
auto ctp = getContextualTypePurpose(origExpr);
1243+
// Determine whether we know more about the contextual type.
1244+
ContextualTypePurpose ctp = CTP_Unused;
1245+
bool isOpaqueReturnType = false;
1246+
if (auto contextualInfo = getContextualTypeInfo(origExpr)) {
1247+
ctp = contextualInfo->purpose;
1248+
isOpaqueReturnType = contextualInfo->isOpaqueReturnType;
1249+
}
12431250

12441251
// Substitute type variables in for unresolved types.
12451252
if (allowFreeTypeVariables == FreeTypeVariableBinding::UnresolvedType) {
@@ -1254,7 +1261,8 @@ ConstraintSystem::solveImpl(Expr *&expr,
12541261
});
12551262
}
12561263

1257-
ContextualTypeInfo info{TypeLoc::withoutLoc(convertType), ctp};
1264+
ContextualTypeInfo info{
1265+
TypeLoc::withoutLoc(convertType), ctp, isOpaqueReturnType};
12581266
addContextualConversionConstraint(expr, info);
12591267
}
12601268

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ using OpenedTypeMap =
792792
struct ContextualTypeInfo {
793793
TypeLoc typeLoc;
794794
ContextualTypePurpose purpose;
795+
bool isOpaqueReturnType = false;
795796

796797
Type getType() const { return typeLoc.getType(); }
797798
};
@@ -1012,10 +1013,6 @@ enum class ConstraintSystemFlags {
10121013
/// expression, and doesn't dig into its subexpressions.
10131014
ReusePrecheckedType = 0x20,
10141015

1015-
/// If set, the top-level expression may be able to provide an underlying
1016-
/// type for the contextual opaque archetype.
1017-
UnderlyingTypeForOpaqueReturnType = 0x40,
1018-
10191016
/// FIXME(diagnostics): Once diagnostics are completely switched to new
10201017
/// framework, this flag could be removed as obsolete.
10211018
///
@@ -2180,11 +2177,12 @@ class ConstraintSystem {
21802177
}
21812178

21822179
void setContextualType(
2183-
const Expr *expr, TypeLoc T, ContextualTypePurpose purpose) {
2180+
const Expr *expr, TypeLoc T, ContextualTypePurpose purpose,
2181+
bool isOpaqueReturnType) {
21842182
assert(expr != nullptr && "Expected non-null expression!");
21852183
assert(contextualTypes.count(expr) == 0 &&
21862184
"Already set this contextual type");
2187-
contextualTypes[expr] = { T, purpose };
2185+
contextualTypes[expr] = { T, purpose, isOpaqueReturnType };
21882186
}
21892187

21902188
Optional<ContextualTypeInfo> getContextualTypeInfo(const Expr *expr) const {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,9 +2189,6 @@ Type TypeChecker::typeCheckExpressionImpl(Expr *&expr, DeclContext *dc,
21892189
if (options.contains(TypeCheckExprFlags::AllowUnresolvedTypeVariables))
21902190
csOptions |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;
21912191

2192-
if (options.contains(TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType))
2193-
csOptions |= ConstraintSystemFlags::UnderlyingTypeForOpaqueReturnType;
2194-
21952192
if (options.contains(TypeCheckExprFlags::SubExpressionDiagnostics))
21962193
csOptions |= ConstraintSystemFlags::SubExpressionDiagnostics;
21972194

@@ -2222,7 +2219,9 @@ Type TypeChecker::typeCheckExpressionImpl(Expr *&expr, DeclContext *dc,
22222219
Expr *contextualTypeExpr = expr;
22232220
if (auto loadExpr = dyn_cast_or_null<LoadExpr>(contextualTypeExpr))
22242221
contextualTypeExpr = loadExpr->getSubExpr();
2225-
cs.setContextualType(contextualTypeExpr, convertType, convertTypePurpose);
2222+
cs.setContextualType(
2223+
contextualTypeExpr, convertType, convertTypePurpose,
2224+
options.contains(TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType));
22262225

22272226
// If the convertType is *only* provided for that hint, then null it out so
22282227
// that we don't later treat it as an actual conversion constraint.
@@ -2666,8 +2665,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
26662665
initType = patternType;
26672666

26682667
// Add a conversion constraint between the types.
2669-
if (!cs.Options.contains(
2670-
ConstraintSystemFlags::UnderlyingTypeForOpaqueReturnType)) {
2668+
if (!initType->is<OpaqueTypeArchetypeType>()) {
26712669
cs.addConstraint(ConstraintKind::Conversion, cs.getType(expr),
26722670
patternType, Locator, /*isFavored*/true);
26732671
}

0 commit comments

Comments
 (0)