@@ -2058,55 +2058,41 @@ bool GenericRequirementsCheckListener::diagnoseUnsatisfiedRequirement(
2058
2058
return false ;
2059
2059
}
2060
2060
2061
- // / Whether the contextual type provided for the given purpose is only a
2062
- // / hint, and not a requirement.
2063
- static bool contextualTypeIsOnlyAHint (ContextualTypePurpose ctp,
2064
- TypeCheckExprOptions options) {
2065
- switch (ctp) {
2066
- case CTP_Initialization:
2067
- return !options.contains (
2068
- TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType);
2069
- case CTP_ForEachStmt:
2070
- return true ;
2071
- case CTP_Unused:
2072
- case CTP_ReturnStmt:
2073
- case CTP_ReturnSingleExpr:
2074
- case CTP_YieldByValue:
2075
- case CTP_YieldByReference:
2076
- case CTP_ThrowStmt:
2077
- case CTP_EnumCaseRawValue:
2078
- case CTP_DefaultParameter:
2079
- case CTP_AutoclosureDefaultParameter:
2080
- case CTP_CalleeResult:
2081
- case CTP_CallArgument:
2082
- case CTP_ClosureResult:
2083
- case CTP_ArrayElement:
2084
- case CTP_DictionaryKey:
2085
- case CTP_DictionaryValue:
2086
- case CTP_CoerceOperand:
2087
- case CTP_AssignSource:
2088
- case CTP_SubscriptAssignSource:
2089
- case CTP_Condition:
2090
- case CTP_CannotFail:
2091
- return false ;
2092
- }
2093
- }
2094
-
2095
2061
#pragma mark High-level entry points
2096
2062
Type TypeChecker::typeCheckExpression (Expr *&expr, DeclContext *dc,
2097
2063
TypeLoc convertType,
2098
2064
ContextualTypePurpose convertTypePurpose,
2099
2065
TypeCheckExprOptions options,
2100
2066
ExprTypeCheckListener *listener,
2101
2067
ConstraintSystem *baseCS) {
2068
+ SolutionApplicationTarget target (
2069
+ expr, convertTypePurpose, convertType,
2070
+ options.contains (TypeCheckExprFlags::IsDiscarded));
2071
+ auto resultType = typeCheckExpression (target, dc, options, listener, baseCS);
2072
+ if (!resultType) {
2073
+ return Type ();
2074
+ }
2075
+
2076
+ expr = resultType->getAsExpr ();
2077
+ return expr->getType ();
2078
+ }
2079
+
2080
+ Optional<SolutionApplicationTarget>
2081
+ TypeChecker::typeCheckExpression (
2082
+ SolutionApplicationTarget target,
2083
+ DeclContext *dc,
2084
+ TypeCheckExprOptions options,
2085
+ ExprTypeCheckListener *listener,
2086
+ ConstraintSystem *baseCS) {
2102
2087
auto &Context = dc->getASTContext ();
2088
+ Expr *expr = target.getAsExpr ();
2103
2089
FrontendStatsTracer StatsTracer (Context.Stats , " typecheck-expr" , expr);
2104
2090
PrettyStackTraceExpr stackTrace (Context, " type-checking" , expr);
2105
2091
2106
2092
// First, pre-check the expression, validating any types that occur in the
2107
2093
// expression and folding sequence expressions.
2108
2094
if (ConstraintSystem::preCheckExpression (expr, dc, baseCS)) {
2109
- return Type () ;
2095
+ return None ;
2110
2096
}
2111
2097
2112
2098
// Construct a constraint system from this expression.
@@ -2124,45 +2110,23 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2124
2110
ConstraintSystem cs (dc, csOptions);
2125
2111
cs.baseCS = baseCS;
2126
2112
2127
- // Verify that a purpose was specified if a convertType was. Note that it is
2128
- // ok to have a purpose without a convertType (which is used for call
2129
- // return types).
2130
- assert ((!convertType.getType () || convertTypePurpose != CTP_Unused) &&
2131
- " Purpose for conversion type was not specified" );
2132
-
2133
- // Take a look at the conversion type to check to make sure it is sensible.
2134
- if (auto type = convertType.getType ()) {
2135
- // If we're asked to convert to an UnresolvedType, then ignore the request.
2136
- // This happens when CSDiags nukes a type.
2137
- if (type->is <UnresolvedType>() ||
2138
- (type->is <MetatypeType>() && type->hasUnresolvedType ())) {
2139
- convertType = TypeLoc ();
2140
- convertTypePurpose = CTP_Unused;
2141
- }
2142
- }
2143
-
2144
- // For an @autoclosure default parameter, we want to convert to the result
2145
- // type. Stash the autoclosure default parameter type.
2146
- FunctionType *autoclosureDefaultParamType = nullptr ;
2147
- if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2148
- autoclosureDefaultParamType = convertType.getType ()->castTo <FunctionType>();
2149
- convertType.setType (autoclosureDefaultParamType->getResult ());
2150
- }
2151
-
2152
2113
// Tell the constraint system what the contextual type is. This informs
2153
2114
// diagnostics and is a hint for various performance optimizations.
2154
2115
// FIXME: Look through LoadExpr. This is an egregious hack due to the
2155
2116
// way typeCheckExprIndependently works.
2117
+ TypeLoc convertType = target.getExprConversionTypeLoc ();
2156
2118
Expr *contextualTypeExpr = expr;
2157
2119
if (auto loadExpr = dyn_cast_or_null<LoadExpr>(contextualTypeExpr))
2158
2120
contextualTypeExpr = loadExpr->getSubExpr ();
2159
2121
cs.setContextualType (
2160
- contextualTypeExpr, convertType, convertTypePurpose,
2122
+ contextualTypeExpr, convertType,
2123
+ target.getExprContextualTypePurpose (),
2161
2124
options.contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType));
2162
2125
2163
2126
// If the convertType is *only* provided for that hint, then null it out so
2164
2127
// that we don't later treat it as an actual conversion constraint.
2165
- if (contextualTypeIsOnlyAHint (convertTypePurpose, options))
2128
+ if (target.contextualTypeIsOnlyAHint (
2129
+ options.contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType)))
2166
2130
convertType = TypeLoc ();
2167
2131
2168
2132
// If the client can handle unresolved type variables, leave them in the
@@ -2179,56 +2143,57 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2179
2143
cs.getConstraintLocator (expr, LocatorPathElt::ContextualType ());
2180
2144
Type var = cs.createTypeVariable (convertTypeLocator, TVO_CanBindToNoEscape);
2181
2145
convertTo = getOptionalType (expr->getLoc (), var);
2146
+ } else if (target.getExprContextualTypePurpose ()
2147
+ == CTP_AutoclosureDefaultParameter) {
2148
+ // FIXME: Hack around the convertTo adjustment below, which we want to
2149
+ // eliminate.
2150
+ convertTo = Type (target.getAsAutoclosureParamType ());
2182
2151
}
2183
2152
2184
2153
// Attempt to solve the constraint system.
2185
- SolutionApplicationTarget target (
2186
- expr, convertTypePurpose , convertTo,
2187
- options. contains (TypeCheckExprFlags::IsDiscarded ));
2188
- auto viable = cs.solve (target , listener, allowFreeTypeVariables);
2154
+ SolutionApplicationTarget innerTarget (
2155
+ expr, target. getExprContextualTypePurpose () , convertTo,
2156
+ target. isDiscardedExpr ( ));
2157
+ auto viable = cs.solve (innerTarget , listener, allowFreeTypeVariables);
2189
2158
if (!viable)
2190
- return Type () ;
2159
+ return None ;
2191
2160
2192
2161
// If the client allows the solution to have unresolved type expressions,
2193
2162
// check for them now. We cannot apply the solution with unresolved TypeVars,
2194
2163
// because they will leak out into arbitrary places in the resultant AST.
2195
2164
if (options.contains (TypeCheckExprFlags::AllowUnresolvedTypeVariables) &&
2196
2165
(viable->size () != 1 ||
2197
2166
(convertType.getType () && convertType.getType ()->hasUnresolvedType ()))) {
2198
- return ErrorType::get (Context);
2167
+ // FIXME: This hack should only be needed for CSDiag.
2168
+ target.getAsExpr ()->setType (ErrorType::get (Context));
2169
+ return target;
2199
2170
}
2200
2171
2201
- auto result = target.getAsExpr ();
2202
- auto &solution = (*viable)[0 ];
2203
- if (!result)
2204
- return Type ();
2205
-
2206
2172
// Apply this solution to the constraint system.
2173
+ // FIXME: This shouldn't be necessary.
2174
+ auto &solution = (*viable)[0 ];
2207
2175
cs.applySolution (solution);
2208
2176
2209
2177
// Apply the solution to the expression.
2210
2178
bool performingDiagnostics =
2211
2179
options.contains (TypeCheckExprFlags::SubExpressionDiagnostics);
2212
- // FIXME: HACK!
2213
- target.setExprConversionType (convertType.getType ());
2180
+ // FIXME: HACK! Copy over the inner target's expression info.
2181
+ target.setExpr (innerTarget.getAsExpr ());
2182
+ if (convertTo.isNull ())
2183
+ target.setExprConversionType (convertTo);
2214
2184
auto resultTarget = cs.applySolution (solution, target, performingDiagnostics);
2215
2185
if (!resultTarget) {
2216
2186
// Failure already diagnosed, above, as part of applying the solution.
2217
- return Type ();
2218
- }
2219
- result = resultTarget->getAsExpr ();
2220
-
2221
- // For an @autoclosure default parameter type, add the autoclosure
2222
- // conversion.
2223
- if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2224
- result = cs.buildAutoClosureExpr (result, autoclosureDefaultParamType);
2187
+ return None;
2225
2188
}
2189
+ Expr *result = resultTarget->getAsExpr ();
2226
2190
2227
2191
// Notify listener that we've applied the solution.
2228
- if (listener)
2192
+ if (listener) {
2229
2193
result = listener->appliedSolution (solution, result);
2230
- if (!result)
2231
- return Type ();
2194
+ if (!result)
2195
+ return None;
2196
+ }
2232
2197
2233
2198
if (Context.TypeCheckerOpts .DebugConstraintSolver ) {
2234
2199
auto &log = Context.TypeCheckerDebug ->getStream ();
@@ -2245,8 +2210,8 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2245
2210
performSyntacticExprDiagnostics (result, dc, isExprStmt);
2246
2211
}
2247
2212
2248
- expr = result;
2249
- return cs. getType (expr) ;
2213
+ target. setExpr ( result) ;
2214
+ return target ;
2250
2215
}
2251
2216
2252
2217
Type TypeChecker::typeCheckParameterDefault (Expr *&defaultValue,
0 commit comments