Skip to content

Commit 8c8f5b1

Browse files
authored
Merge pull request #29588 from DougGregor/silence-the-listeners
2 parents 7cabef8 + 4b0e7b2 commit 8c8f5b1

File tree

4 files changed

+27
-50
lines changed

4 files changed

+27
-50
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ Optional<Diag<Type, Type>> GenericArgumentsMismatchFailure::getDiagnosticFor(
560560
case CTP_ReturnSingleExpr:
561561
return diag::cannot_convert_to_return_type;
562562
case CTP_DefaultParameter:
563+
case CTP_AutoclosureDefaultParameter:
563564
return diag::cannot_convert_default_arg_value;
564565
case CTP_YieldByValue:
565566
return diag::cannot_convert_yield_value;
@@ -2085,6 +2086,7 @@ getContextualNilDiagnostic(ContextualTypePurpose CTP) {
20852086
case CTP_EnumCaseRawValue:
20862087
return diag::cannot_convert_raw_initializer_value_nil;
20872088
case CTP_DefaultParameter:
2089+
case CTP_AutoclosureDefaultParameter:
20882090
return diag::cannot_convert_default_arg_value_nil;
20892091
case CTP_YieldByValue:
20902092
return diag::cannot_convert_yield_value_nil;
@@ -2863,6 +2865,7 @@ ContextualFailure::getDiagnosticFor(ContextualTypePurpose context,
28632865
case CTP_EnumCaseRawValue:
28642866
return diag::cannot_convert_raw_initializer_value;
28652867
case CTP_DefaultParameter:
2868+
case CTP_AutoclosureDefaultParameter:
28662869
return forProtocol ? diag::cannot_convert_default_arg_value_protocol
28672870
: diag::cannot_convert_default_arg_value;
28682871
case CTP_YieldByValue:

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9174,6 +9174,7 @@ void ConstraintSystem::addContextualConversionConstraint(
91749174
case CTP_ThrowStmt:
91759175
case CTP_EnumCaseRawValue:
91769176
case CTP_DefaultParameter:
9177+
case CTP_AutoclosureDefaultParameter:
91779178
case CTP_ClosureResult:
91789179
case CTP_DictionaryKey:
91799180
case CTP_DictionaryValue:

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,14 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
20502050
}
20512051
}
20522052

2053+
// For an @autoclosure default parameter, we want to convert to the result
2054+
// type. Stash the autoclosure default parameter type.
2055+
FunctionType *autoclosureDefaultParamType = nullptr;
2056+
if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2057+
autoclosureDefaultParamType = convertType.getType()->castTo<FunctionType>();
2058+
convertType.setType(autoclosureDefaultParamType->getResult());
2059+
}
2060+
20532061
// Tell the constraint system what the contextual type is. This informs
20542062
// diagnostics and is a hint for various performance optimizations.
20552063
// FIXME: Look through LoadExpr. This is an egregious hack due to the
@@ -2073,6 +2081,7 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
20732081
allowFreeTypeVariables = FreeTypeVariableBinding::UnresolvedType;
20742082

20752083
Type convertTo = convertType.getType();
2084+
20762085
if (options.contains(TypeCheckExprFlags::ExpressionTypeMustBeOptional)) {
20772086
assert(!convertTo && "convertType and type check options conflict");
20782087
auto *convertTypeLocator =
@@ -2118,6 +2127,12 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
21182127
}
21192128
result = resultTarget->getAsExpr();
21202129

2130+
// For an @autoclosure default parameter type, add the autoclosure
2131+
// conversion.
2132+
if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2133+
result = cs.buildAutoClosureExpr(result, autoclosureDefaultParamType);
2134+
}
2135+
21212136
// Notify listener that we've applied the solution.
21222137
if (listener)
21232138
result = listener->appliedSolution(solution, result);
@@ -2147,32 +2162,9 @@ Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
21472162
DeclContext *DC, Type paramType,
21482163
bool isAutoClosure) {
21492164
assert(paramType && !paramType->hasError());
2150-
2151-
if (isAutoClosure) {
2152-
class AutoClosureListener : public ExprTypeCheckListener {
2153-
FunctionType *ParamType;
2154-
2155-
public:
2156-
AutoClosureListener(FunctionType *paramType)
2157-
: ParamType(paramType) {}
2158-
2159-
Expr *appliedSolution(constraints::Solution &solution,
2160-
Expr *expr) override {
2161-
auto &cs = solution.getConstraintSystem();
2162-
return cs.buildAutoClosureExpr(expr, ParamType);
2163-
}
2164-
};
2165-
2166-
auto *fnType = paramType->castTo<FunctionType>();
2167-
AutoClosureListener listener(fnType);
2168-
return typeCheckExpression(defaultValue, DC,
2169-
TypeLoc::withoutLoc(fnType->getResult()),
2170-
CTP_DefaultParameter, TypeCheckExprOptions(),
2171-
&listener);
2172-
}
2173-
2174-
return typeCheckExpression(defaultValue, DC, TypeLoc::withoutLoc(paramType),
2175-
CTP_DefaultParameter);
2165+
return typeCheckExpression(
2166+
defaultValue, DC, TypeLoc::withoutLoc(paramType),
2167+
isAutoClosure ? CTP_AutoclosureDefaultParameter : CTP_DefaultParameter);
21762168
}
21772169

21782170
Type TypeChecker::
@@ -3152,30 +3144,7 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
31523144
/*Implicit=*/true);
31533145

31543146
// Check the expression as a condition.
3155-
//
3156-
// TODO: Type-check of `~=` operator can't (yet) use `typeCheckCondition`
3157-
// because that utilizes contextual type which interferes with diagnostics.
3158-
// We don't yet have a full access to pattern-matching context in
3159-
// constraint system, which is required to enable these situations
3160-
// to be properly diagnosed.
3161-
struct ConditionListener : public ExprTypeCheckListener {
3162-
// Add the appropriate Boolean constraint.
3163-
bool builtConstraints(ConstraintSystem &cs, Expr *expr) override {
3164-
// Otherwise, the result must be convertible to Bool.
3165-
auto boolDecl = cs.getASTContext().getBoolDecl();
3166-
if (!boolDecl)
3167-
return true;
3168-
3169-
// Condition must convert to Bool.
3170-
cs.addConstraint(ConstraintKind::Conversion, cs.getType(expr),
3171-
boolDecl->getDeclaredType(),
3172-
cs.getConstraintLocator(expr));
3173-
return false;
3174-
}
3175-
};
3176-
3177-
ConditionListener listener;
3178-
bool hadError = !typeCheckExpression(matchCall, DC, &listener);
3147+
bool hadError = typeCheckCondition(matchCall, DC);
31793148
// Save the type-checked expression in the pattern.
31803149
EP->setMatchExpr(matchCall);
31813150
// Set the type on the pattern.

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ enum ContextualTypePurpose {
133133
CTP_EnumCaseRawValue, ///< Raw value specified for "case X = 42" in enum.
134134
CTP_DefaultParameter, ///< Default value in parameter 'foo(a : Int = 42)'.
135135

136+
/// Default value in @autoclosure parameter
137+
/// 'foo(a : @autoclosure () -> Int = 42)'.
138+
CTP_AutoclosureDefaultParameter,
139+
136140
CTP_CalleeResult, ///< Constraint is placed on the result of a callee.
137141
CTP_CallArgument, ///< Call to function or operator requires type.
138142
CTP_ClosureResult, ///< Closure result expects a specific type.

0 commit comments

Comments
 (0)