@@ -2009,11 +2009,11 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2009
2009
ExprTypeCheckListener *listener,
2010
2010
ConstraintSystem *baseCS) {
2011
2011
SolutionApplicationTarget target (
2012
- expr, convertTypePurpose, convertType,
2012
+ expr, dc, convertTypePurpose, convertType,
2013
2013
options.contains (TypeCheckExprFlags::IsDiscarded));
2014
2014
bool unresolvedTypeExprs = false ;
2015
2015
auto resultTarget = typeCheckExpression (
2016
- target, dc, unresolvedTypeExprs, options, listener, baseCS);
2016
+ target, unresolvedTypeExprs, options, listener, baseCS);
2017
2017
if (!resultTarget) {
2018
2018
expr = target.getAsExpr ();
2019
2019
return Type ();
@@ -2033,14 +2033,14 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
2033
2033
Optional<SolutionApplicationTarget>
2034
2034
TypeChecker::typeCheckExpression (
2035
2035
SolutionApplicationTarget &target,
2036
- DeclContext *dc,
2037
2036
bool &unresolvedTypeExprs,
2038
2037
TypeCheckExprOptions options,
2039
2038
ExprTypeCheckListener *listener,
2040
2039
ConstraintSystem *baseCS) {
2041
2040
unresolvedTypeExprs = false ;
2042
- auto &Context = dc->getASTContext ();
2043
2041
Expr *expr = target.getAsExpr ();
2042
+ DeclContext *dc = target.getDeclContext ();
2043
+ auto &Context = dc->getASTContext ();
2044
2044
FrontendStatsTracer StatsTracer (Context.Stats , " typecheck-expr" , expr);
2045
2045
PrettyStackTraceExpr stackTrace (Context, " type-checking" , expr);
2046
2046
@@ -2077,12 +2077,11 @@ TypeChecker::typeCheckExpression(
2077
2077
cs.setContextualType (
2078
2078
contextualTypeExpr, convertType,
2079
2079
target.getExprContextualTypePurpose (),
2080
- options. contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType ));
2080
+ target. infersOpaqueReturnType ( ));
2081
2081
2082
2082
// If the convertType is *only* provided for that hint, then null it out so
2083
2083
// that we don't later treat it as an actual conversion constraint.
2084
- if (target.contextualTypeIsOnlyAHint (
2085
- options.contains (TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType)))
2084
+ if (target.contextualTypeIsOnlyAHint ())
2086
2085
convertType = TypeLoc ();
2087
2086
2088
2087
// If the client can handle unresolved type variables, leave them in the
@@ -2093,7 +2092,7 @@ TypeChecker::typeCheckExpression(
2093
2092
2094
2093
Type convertTo = convertType.getType ();
2095
2094
2096
- if (options. contains (TypeCheckExprFlags::ExpressionTypeMustBeOptional )) {
2095
+ if (target. isOptionalSomePatternInit ( )) {
2097
2096
assert (!convertTo && " convertType and type check options conflict" );
2098
2097
auto *convertTypeLocator =
2099
2098
cs.getConstraintLocator (expr, LocatorPathElt::ContextualType ());
@@ -2108,7 +2107,7 @@ TypeChecker::typeCheckExpression(
2108
2107
2109
2108
// Attempt to solve the constraint system.
2110
2109
SolutionApplicationTarget innerTarget (
2111
- expr, target.getExprContextualTypePurpose (), convertTo,
2110
+ expr, dc, target.getExprContextualTypePurpose (), convertTo,
2112
2111
target.isDiscardedExpr ());
2113
2112
auto viable = cs.solve (innerTarget, listener, allowFreeTypeVariables);
2114
2113
if (!viable) {
@@ -2207,7 +2206,7 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
2207
2206
if (needClearType)
2208
2207
expr->setType (Type ());
2209
2208
SolutionApplicationTarget target (
2210
- expr, CTP_Unused, Type (), /* isDiscarded=*/ false );
2209
+ expr, dc, CTP_Unused, Type (), /* isDiscarded=*/ false );
2211
2210
auto viable = cs.solve (target, listener, allowFreeTypeVariables);
2212
2211
if (!viable) {
2213
2212
recoverOriginalType ();
@@ -2288,7 +2287,7 @@ void TypeChecker::getPossibleTypesOfExpressionWithoutApplying(
2288
2287
expr->setType (Type ());
2289
2288
2290
2289
SolutionApplicationTarget target (
2291
- expr, CTP_Unused, Type (), /* isDiscarded=*/ false );
2290
+ expr, dc, CTP_Unused, Type (), /* isDiscarded=*/ false );
2292
2291
if (auto viable = cs.solve (target, listener, allowFreeTypeVariables)) {
2293
2292
expr = target.getAsExpr ();
2294
2293
for (auto &solution : *viable) {
@@ -2612,54 +2611,22 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2612
2611
if (!initializer)
2613
2612
return true ;
2614
2613
2615
- TypeLoc contextualType;
2616
- auto contextualPurpose = CTP_Unused;
2617
- TypeCheckExprOptions flags = None;
2618
-
2619
- // Set the contextual purpose even if the pattern doesn't have a type so
2620
- // if there's an error we can use that information to inform diagnostics.
2621
- contextualPurpose = CTP_Initialization;
2622
-
2623
- if (isa<OptionalSomePattern>(pattern)) {
2624
- flags |= TypeCheckExprFlags::ExpressionTypeMustBeOptional;
2625
- } else if (patternType && !patternType->isEqual (Context.TheUnresolvedType )) {
2626
- contextualType = TypeLoc::withoutLoc (patternType);
2627
-
2628
- // If we already had an error, don't repeat the problem.
2629
- if (contextualType.getType ()->hasError ())
2630
- return true ;
2631
-
2632
- // Allow the initializer expression to establish the underlying type of an
2633
- // opaque type.
2634
- if (auto opaqueType = patternType->getAs <OpaqueTypeArchetypeType>()){
2635
- flags |= TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType;
2636
- }
2637
-
2638
- // Only provide a TypeLoc if it makes sense to allow diagnostics.
2639
- if (auto *typedPattern = dyn_cast<TypedPattern>(pattern)) {
2640
- const Pattern *inner = typedPattern->getSemanticsProvidingPattern ();
2641
- if (isa<NamedPattern>(inner) || isa<AnyPattern>(inner)) {
2642
- contextualType = typedPattern->getTypeLoc ();
2643
- if (!contextualType.getType ())
2644
- contextualType.setType (patternType);
2645
- }
2646
- }
2647
- }
2648
-
2649
2614
// Type-check the initializer.
2650
- auto resultTy = typeCheckExpression (initializer, DC, contextualType,
2651
- contextualPurpose, flags, &listener);
2615
+ auto target = SolutionApplicationTarget::forInitialization (
2616
+ initializer, DC, patternType, pattern);
2617
+ bool unresolvedTypeExprs = false ;
2618
+ auto resultTarget = typeCheckExpression (target, unresolvedTypeExprs,
2619
+ None, &listener);
2620
+
2621
+ if (resultTarget) {
2622
+ initializer = resultTarget->getAsExpr ();
2652
2623
2653
- if (resultTy) {
2654
2624
TypeResolutionOptions options =
2655
2625
isa<EditorPlaceholderExpr>(initializer->getSemanticsProvidingExpr ())
2656
2626
? TypeResolverContext::EditorPlaceholderExpr
2657
2627
: TypeResolverContext::InExpression;
2658
2628
options |= TypeResolutionFlags::OverrideType;
2659
2629
2660
- // FIXME: initTy should be the same as resultTy; now that typeCheckExpression()
2661
- // returns a Type and not bool, we should be able to simplify the listener
2662
- // implementation here.
2663
2630
auto initTy = listener.getPatternInitType (nullptr );
2664
2631
if (initTy->hasDependentMember ())
2665
2632
return true ;
@@ -2673,15 +2640,17 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2673
2640
} else {
2674
2641
return true ;
2675
2642
}
2643
+ } else {
2644
+ initializer = target.getAsExpr ();
2676
2645
}
2677
2646
2678
- if (!resultTy && !initializer->getType ())
2647
+ if (!resultTarget && !initializer->getType ())
2679
2648
initializer->setType (ErrorType::get (Context));
2680
2649
2681
2650
// If the type of the pattern is inferred, assign error types to the pattern
2682
2651
// and its variables, to prevent it from being referenced by the constraint
2683
2652
// system.
2684
- if (!resultTy &&
2653
+ if (!resultTarget &&
2685
2654
(patternType->hasUnresolvedType () ||
2686
2655
patternType->hasUnboundGenericType ())) {
2687
2656
pattern->setType (ErrorType::get (Context));
@@ -2697,7 +2666,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2697
2666
});
2698
2667
}
2699
2668
2700
- return !resultTy ;
2669
+ return !resultTarget ;
2701
2670
}
2702
2671
2703
2672
bool TypeChecker::typeCheckPatternBinding (PatternBindingDecl *PBD,
0 commit comments