@@ -2566,7 +2566,8 @@ TypeChecker::getTypeOfCompletionOperator(DeclContext *DC, Expr *LHS,
2566
2566
}
2567
2567
2568
2568
bool TypeChecker::typeCheckBinding (Pattern *&pattern, Expr *&initializer,
2569
- DeclContext *DC) {
2569
+ DeclContext *DC,
2570
+ Type patternType) {
2570
2571
2571
2572
// / Type checking listener for pattern binding initializers.
2572
2573
class BindingListener : public ExprTypeCheckListener {
@@ -2763,28 +2764,31 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2763
2764
// if there's an error we can use that information to inform diagnostics.
2764
2765
contextualPurpose = CTP_Initialization;
2765
2766
2766
- if (pattern->hasType ()) {
2767
- contextualType = TypeLoc::withoutLoc (pattern->getType ());
2767
+ if (isa<OptionalSomePattern>(pattern)) {
2768
+ flags |= TypeCheckExprFlags::ExpressionTypeMustBeOptional;
2769
+ } else if (patternType && !patternType->isEqual (Context.TheUnresolvedType )) {
2770
+ contextualType = TypeLoc::withoutLoc (patternType);
2768
2771
2769
2772
// If we already had an error, don't repeat the problem.
2770
2773
if (contextualType.getType ()->hasError ())
2771
2774
return true ;
2772
2775
2773
2776
// Allow the initializer expression to establish the underlying type of an
2774
2777
// opaque type.
2775
- if (auto opaqueType = pattern-> getType () ->getAs <OpaqueTypeArchetypeType>()){
2778
+ if (auto opaqueType = patternType ->getAs <OpaqueTypeArchetypeType>()){
2776
2779
flags |= TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType;
2777
2780
flags -= TypeCheckExprFlags::ConvertTypeIsOnlyAHint;
2778
2781
}
2779
2782
2780
2783
// Only provide a TypeLoc if it makes sense to allow diagnostics.
2781
2784
if (auto *typedPattern = dyn_cast<TypedPattern>(pattern)) {
2782
2785
const Pattern *inner = typedPattern->getSemanticsProvidingPattern ();
2783
- if (isa<NamedPattern>(inner) || isa<AnyPattern>(inner))
2786
+ if (isa<NamedPattern>(inner) || isa<AnyPattern>(inner)) {
2784
2787
contextualType = typedPattern->getTypeLoc ();
2788
+ if (!contextualType.getType ())
2789
+ contextualType.setType (patternType);
2790
+ }
2785
2791
}
2786
- } else if (isa<OptionalSomePattern>(pattern)) {
2787
- flags |= TypeCheckExprFlags::ExpressionTypeMustBeOptional;
2788
2792
}
2789
2793
2790
2794
// Type-check the initializer.
@@ -2797,6 +2801,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2797
2801
? TypeResolverContext::EditorPlaceholderExpr
2798
2802
: TypeResolverContext::InExpression;
2799
2803
options |= TypeResolutionFlags::OverrideType;
2804
+ options |= TypeResolutionFlags::AllowUnspecifiedTypes;
2805
+ options |= TypeResolutionFlags::AllowUnboundGenerics;
2800
2806
2801
2807
// FIXME: initTy should be the same as resultTy; now that typeCheckExpression()
2802
2808
// returns a Type and not bool, we should be able to simplify the listener
@@ -2819,7 +2825,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2819
2825
// and its variables, to prevent it from being referenced by the constraint
2820
2826
// system.
2821
2827
if (!resultTy &&
2822
- (!pattern->hasType () || pattern->getType ()->hasUnboundGenericType ())) {
2828
+ (patternType->hasUnresolvedType () ||
2829
+ patternType->hasUnboundGenericType ())) {
2823
2830
pattern->setType (ErrorType::get (Context));
2824
2831
pattern->forEachVariable ([&](VarDecl *var) {
2825
2832
// Don't change the type of a variable that we've been able to
@@ -2837,7 +2844,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2837
2844
}
2838
2845
2839
2846
bool TypeChecker::typeCheckPatternBinding (PatternBindingDecl *PBD,
2840
- unsigned patternNumber) {
2847
+ unsigned patternNumber,
2848
+ Type patternType) {
2841
2849
Pattern *pattern = PBD->getPattern (patternNumber);
2842
2850
Expr *init = PBD->getInit (patternNumber);
2843
2851
@@ -2851,7 +2859,24 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
2851
2859
DC = initContext;
2852
2860
}
2853
2861
2854
- bool hadError = TypeChecker::typeCheckBinding (pattern, init, DC);
2862
+ // If we weren't given a pattern type, compute one now.
2863
+ if (!patternType) {
2864
+ if (pattern->hasType ())
2865
+ patternType = pattern->getType ();
2866
+ else {
2867
+ TypeResolutionOptions options (TypeResolverContext::InExpression);
2868
+ options |= TypeResolutionFlags::AllowUnspecifiedTypes;
2869
+ options |= TypeResolutionFlags::AllowUnboundGenerics;
2870
+ patternType = typeCheckPattern (pattern, DC, options);
2871
+ }
2872
+
2873
+ if (patternType->hasError ()) {
2874
+ PBD->setInvalid ();
2875
+ return true ;
2876
+ }
2877
+ }
2878
+
2879
+ bool hadError = TypeChecker::typeCheckBinding (pattern, init, DC, patternType);
2855
2880
if (!init) {
2856
2881
PBD->setInvalid ();
2857
2882
return true ;
@@ -2973,7 +2998,9 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2973
2998
TypeResolutionOptions options (TypeResolverContext::InExpression);
2974
2999
options |= TypeResolutionFlags::AllowUnspecifiedTypes;
2975
3000
options |= TypeResolutionFlags::AllowUnboundGenerics;
2976
- if (TypeChecker::typeCheckPattern (Stmt->getPattern (), DC, options)) {
3001
+ Type patternType = TypeChecker::typeCheckPattern (
3002
+ Stmt->getPattern (), DC, options);
3003
+ if (patternType->hasError ()) {
2977
3004
// FIXME: Handle errors better.
2978
3005
Stmt->getPattern ()->setType (ErrorType::get (ctx));
2979
3006
return true ;
@@ -3040,6 +3067,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3040
3067
Pattern *pattern = Stmt->getPattern ();
3041
3068
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
3042
3069
options |= TypeResolutionFlags::OverrideType;
3070
+ options |= TypeResolutionFlags::AllowUnboundGenerics;
3071
+ options |= TypeResolutionFlags::AllowUnspecifiedTypes;
3043
3072
if (TypeChecker::coercePatternToType (pattern,
3044
3073
TypeResolution::forContextual (DC),
3045
3074
InitType, options)) {
@@ -3195,15 +3224,16 @@ bool TypeChecker::typeCheckStmtCondition(StmtCondition &cond, DeclContext *dc,
3195
3224
TypeResolutionOptions options (TypeResolverContext::InExpression);
3196
3225
options |= TypeResolutionFlags::AllowUnspecifiedTypes;
3197
3226
options |= TypeResolutionFlags::AllowUnboundGenerics;
3198
- if (TypeChecker::typeCheckPattern (pattern, dc, options)) {
3227
+ Type patternType = TypeChecker::typeCheckPattern (pattern, dc, options);
3228
+ if (patternType->hasError ()) {
3199
3229
typeCheckPatternFailed ();
3200
3230
continue ;
3201
3231
}
3202
3232
3203
3233
// If the pattern didn't get a type, it's because we ran into some
3204
3234
// unknown types along the way. We'll need to check the initializer.
3205
3235
auto init = elt.getInitializer ();
3206
- hadError |= TypeChecker::typeCheckBinding (pattern, init, dc);
3236
+ hadError |= TypeChecker::typeCheckBinding (pattern, init, dc, patternType );
3207
3237
elt.setPattern (pattern);
3208
3238
elt.setInitializer (init);
3209
3239
hadAnyFalsable |= pattern->isRefutablePattern ();
0 commit comments