@@ -2001,55 +2001,54 @@ bool GenericRequirementsCheckListener::diagnoseUnsatisfiedRequirement(
2001
2001
return false ;
2002
2002
}
2003
2003
2004
- // / Whether the contextual type provided for the given purpose is only a
2005
- // / hint, and not a requirement.
2006
- static bool contextualTypeIsOnlyAHint (ContextualTypePurpose ctp,
2007
- TypeCheckExprOptions options) {
2008
- switch (ctp) {
2009
- case CTP_Initialization:
2010
- return !options.contains (
2011
- TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType);
2012
- case CTP_ForEachStmt:
2013
- return true ;
2014
- case CTP_Unused:
2015
- case CTP_ReturnStmt:
2016
- case CTP_ReturnSingleExpr:
2017
- case CTP_YieldByValue:
2018
- case CTP_YieldByReference:
2019
- case CTP_ThrowStmt:
2020
- case CTP_EnumCaseRawValue:
2021
- case CTP_DefaultParameter:
2022
- case CTP_AutoclosureDefaultParameter:
2023
- case CTP_CalleeResult:
2024
- case CTP_CallArgument:
2025
- case CTP_ClosureResult:
2026
- case CTP_ArrayElement:
2027
- case CTP_DictionaryKey:
2028
- case CTP_DictionaryValue:
2029
- case CTP_CoerceOperand:
2030
- case CTP_AssignSource:
2031
- case CTP_SubscriptAssignSource:
2032
- case CTP_Condition:
2033
- case CTP_CannotFail:
2034
- return false ;
2035
- }
2036
- }
2037
-
2038
2004
#pragma mark High-level entry points
2039
2005
Type TypeChecker::typeCheckExpression (Expr *&expr, DeclContext *dc,
2040
2006
TypeLoc convertType,
2041
2007
ContextualTypePurpose convertTypePurpose,
2042
2008
TypeCheckExprOptions options,
2043
2009
ExprTypeCheckListener *listener,
2044
2010
ConstraintSystem *baseCS) {
2011
+ SolutionApplicationTarget target (
2012
+ expr, convertTypePurpose, convertType,
2013
+ options.contains (TypeCheckExprFlags::IsDiscarded));
2014
+ bool unresolvedTypeExprs = false ;
2015
+ auto resultTarget = typeCheckExpression (
2016
+ target, dc, unresolvedTypeExprs, options, listener, baseCS);
2017
+ if (!resultTarget) {
2018
+ expr = target.getAsExpr ();
2019
+ return Type ();
2020
+ }
2021
+
2022
+ expr = resultTarget->getAsExpr ();
2023
+
2024
+ // HACK for clients that want unresolved types.
2025
+ if (unresolvedTypeExprs) {
2026
+ return ErrorType::get (dc->getASTContext ());
2027
+ }
2028
+
2029
+
2030
+ return expr->getType ();
2031
+ }
2032
+
2033
+ Optional<SolutionApplicationTarget>
2034
+ TypeChecker::typeCheckExpression (
2035
+ SolutionApplicationTarget &target,
2036
+ DeclContext *dc,
2037
+ bool &unresolvedTypeExprs,
2038
+ TypeCheckExprOptions options,
2039
+ ExprTypeCheckListener *listener,
2040
+ ConstraintSystem *baseCS) {
2041
+ unresolvedTypeExprs = false ;
2045
2042
auto &Context = dc->getASTContext ();
2043
+ Expr *expr = target.getAsExpr ();
2046
2044
FrontendStatsTracer StatsTracer (Context.Stats , " typecheck-expr" , expr);
2047
2045
PrettyStackTraceExpr stackTrace (Context, " type-checking" , expr);
2048
2046
2049
2047
// First, pre-check the expression, validating any types that occur in the
2050
2048
// expression and folding sequence expressions.
2051
2049
if (ConstraintSystem::preCheckExpression (expr, dc, baseCS)) {
2052
- return Type ();
2050
+ target.setExpr (expr);
2051
+ return None;
2053
2052
}
2054
2053
2055
2054
// Construct a constraint system from this expression.
@@ -2067,45 +2066,23 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2067
2066
ConstraintSystem cs (dc, csOptions);
2068
2067
cs.baseCS = baseCS;
2069
2068
2070
- // Verify that a purpose was specified if a convertType was. Note that it is
2071
- // ok to have a purpose without a convertType (which is used for call
2072
- // return types).
2073
- assert ((!convertType.getType () || convertTypePurpose != CTP_Unused) &&
2074
- " Purpose for conversion type was not specified" );
2075
-
2076
- // Take a look at the conversion type to check to make sure it is sensible.
2077
- if (auto type = convertType.getType ()) {
2078
- // If we're asked to convert to an UnresolvedType, then ignore the request.
2079
- // This happens when CSDiags nukes a type.
2080
- if (type->is <UnresolvedType>() ||
2081
- (type->is <MetatypeType>() && type->hasUnresolvedType ())) {
2082
- convertType = TypeLoc ();
2083
- convertTypePurpose = CTP_Unused;
2084
- }
2085
- }
2086
-
2087
- // For an @autoclosure default parameter, we want to convert to the result
2088
- // type. Stash the autoclosure default parameter type.
2089
- FunctionType *autoclosureDefaultParamType = nullptr ;
2090
- if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2091
- autoclosureDefaultParamType = convertType.getType ()->castTo <FunctionType>();
2092
- convertType.setType (autoclosureDefaultParamType->getResult ());
2093
- }
2094
-
2095
2069
// Tell the constraint system what the contextual type is. This informs
2096
2070
// diagnostics and is a hint for various performance optimizations.
2097
2071
// FIXME: Look through LoadExpr. This is an egregious hack due to the
2098
2072
// way typeCheckExprIndependently works.
2073
+ TypeLoc convertType = target.getExprConversionTypeLoc ();
2099
2074
Expr *contextualTypeExpr = expr;
2100
2075
if (auto loadExpr = dyn_cast_or_null<LoadExpr>(contextualTypeExpr))
2101
2076
contextualTypeExpr = loadExpr->getSubExpr ();
2102
2077
cs.setContextualType (
2103
- contextualTypeExpr, convertType, convertTypePurpose,
2078
+ contextualTypeExpr, convertType,
2079
+ target.getExprContextualTypePurpose (),
2104
2080
options.contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType));
2105
2081
2106
2082
// If the convertType is *only* provided for that hint, then null it out so
2107
2083
// that we don't later treat it as an actual conversion constraint.
2108
- if (contextualTypeIsOnlyAHint (convertTypePurpose, options))
2084
+ if (target.contextualTypeIsOnlyAHint (
2085
+ options.contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType)))
2109
2086
convertType = TypeLoc ();
2110
2087
2111
2088
// If the client can handle unresolved type variables, leave them in the
@@ -2122,56 +2099,59 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2122
2099
cs.getConstraintLocator (expr, LocatorPathElt::ContextualType ());
2123
2100
Type var = cs.createTypeVariable (convertTypeLocator, TVO_CanBindToNoEscape);
2124
2101
convertTo = getOptionalType (expr->getLoc (), var);
2102
+ } else if (target.getExprContextualTypePurpose ()
2103
+ == CTP_AutoclosureDefaultParameter) {
2104
+ // FIXME: Hack around the convertTo adjustment below, which we want to
2105
+ // eliminate.
2106
+ convertTo = Type (target.getAsAutoclosureParamType ());
2125
2107
}
2126
2108
2127
2109
// Attempt to solve the constraint system.
2128
- SolutionApplicationTarget target (
2129
- expr, convertTypePurpose, convertTo,
2130
- options.contains (TypeCheckExprFlags::IsDiscarded));
2131
- auto viable = cs.solve (target, listener, allowFreeTypeVariables);
2132
- if (!viable)
2133
- return Type ();
2110
+ SolutionApplicationTarget innerTarget (
2111
+ expr, target.getExprContextualTypePurpose (), convertTo,
2112
+ target.isDiscardedExpr ());
2113
+ auto viable = cs.solve (innerTarget, listener, allowFreeTypeVariables);
2114
+ if (!viable) {
2115
+ target.setExpr (expr);
2116
+ return None;
2117
+ }
2134
2118
2135
2119
// If the client allows the solution to have unresolved type expressions,
2136
2120
// check for them now. We cannot apply the solution with unresolved TypeVars,
2137
2121
// because they will leak out into arbitrary places in the resultant AST.
2138
2122
if (options.contains (TypeCheckExprFlags::AllowUnresolvedTypeVariables) &&
2139
2123
(viable->size () != 1 ||
2140
2124
(convertType.getType () && convertType.getType ()->hasUnresolvedType ()))) {
2141
- return ErrorType::get (Context);
2125
+ // FIXME: This hack should only be needed for CSDiag.
2126
+ unresolvedTypeExprs = true ;
2127
+ return target;
2142
2128
}
2143
2129
2144
- auto result = target.getAsExpr ();
2145
- auto &solution = (*viable)[0 ];
2146
- if (!result)
2147
- return Type ();
2148
-
2149
2130
// Apply this solution to the constraint system.
2131
+ // FIXME: This shouldn't be necessary.
2132
+ auto &solution = (*viable)[0 ];
2150
2133
cs.applySolution (solution);
2151
2134
2152
2135
// Apply the solution to the expression.
2153
2136
bool performingDiagnostics =
2154
2137
options.contains (TypeCheckExprFlags::SubExpressionDiagnostics);
2155
- // FIXME: HACK!
2156
- target.setExprConversionType (convertType.getType ());
2138
+ // FIXME: HACK! Copy over the inner target's expression info.
2139
+ target.setExpr (innerTarget.getAsExpr ());
2140
+ if (convertTo.isNull ())
2141
+ target.setExprConversionType (convertTo);
2157
2142
auto resultTarget = cs.applySolution (solution, target, performingDiagnostics);
2158
2143
if (!resultTarget) {
2159
2144
// Failure already diagnosed, above, as part of applying the solution.
2160
- return Type ();
2161
- }
2162
- result = resultTarget->getAsExpr ();
2163
-
2164
- // For an @autoclosure default parameter type, add the autoclosure
2165
- // conversion.
2166
- if (convertTypePurpose == CTP_AutoclosureDefaultParameter) {
2167
- result = cs.buildAutoClosureExpr (result, autoclosureDefaultParamType);
2145
+ return None;
2168
2146
}
2147
+ Expr *result = resultTarget->getAsExpr ();
2169
2148
2170
2149
// Notify listener that we've applied the solution.
2171
- if (listener)
2150
+ if (listener) {
2172
2151
result = listener->appliedSolution (solution, result);
2173
- if (!result)
2174
- return Type ();
2152
+ if (!result)
2153
+ return None;
2154
+ }
2175
2155
2176
2156
if (Context.TypeCheckerOpts .DebugConstraintSolver ) {
2177
2157
auto &log = Context.TypeCheckerDebug ->getStream ();
@@ -2188,8 +2168,8 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2188
2168
performSyntacticExprDiagnostics (result, dc, isExprStmt);
2189
2169
}
2190
2170
2191
- expr = result;
2192
- return cs. getType (expr) ;
2171
+ target. setExpr ( result) ;
2172
+ return target ;
2193
2173
}
2194
2174
2195
2175
Type TypeChecker::typeCheckParameterDefault (Expr *&defaultValue,
0 commit comments