@@ -456,6 +456,7 @@ Type ConstraintSystem::getCaughtErrorType(CatchNode catchNode) {
456
456
457
457
case PotentialThrowSite::ExplicitThrow:
458
458
case PotentialThrowSite::NonExhaustiveDoCatch:
459
+ case PotentialThrowSite::PropertyAccess:
459
460
thrownErrorType = type;
460
461
break ;
461
462
}
@@ -1809,7 +1810,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
1809
1810
1810
1811
// The reference implicitly binds 'self'.
1811
1812
return {origOpenedType, openedType,
1812
- origOpenedType->getResult (), openedType->getResult ()};
1813
+ origOpenedType->getResult (), openedType->getResult (), Type () };
1813
1814
}
1814
1815
1815
1816
// Unqualified reference to a local or global function.
@@ -1854,7 +1855,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
1854
1855
// If we opened up any type variables, record the replacements.
1855
1856
recordOpenedTypes (locator, replacements);
1856
1857
1857
- return { origOpenedType, openedType, origOpenedType, openedType };
1858
+ return { origOpenedType, openedType, origOpenedType, openedType, Type () };
1858
1859
}
1859
1860
1860
1861
// Unqualified reference to a type.
@@ -1876,11 +1877,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
1876
1877
1877
1878
// Module types are not wrapped in metatypes.
1878
1879
if (type->is <ModuleType>())
1879
- return { type, type, type, type };
1880
+ return { type, type, type, type, Type () };
1880
1881
1881
1882
// If it's a value reference, refer to the metatype.
1882
1883
type = MetatypeType::get (type);
1883
- return { type, type, type, type };
1884
+ return { type, type, type, type, Type () };
1884
1885
}
1885
1886
1886
1887
// Unqualified reference to a macro.
@@ -1898,7 +1899,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
1898
1899
1899
1900
// FIXME: Should we use replaceParamErrorTypeByPlaceholder() here?
1900
1901
1901
- return { openedType, openedType, openedType, openedType };
1902
+ return { openedType, openedType, openedType, openedType, Type () };
1902
1903
}
1903
1904
1904
1905
// Only remaining case: unqualified reference to a property.
@@ -1911,9 +1912,15 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
1911
1912
getUnopenedTypeOfReference (varDecl, Type (), useDC, /* base=*/ nullptr ,
1912
1913
wantInterfaceType);
1913
1914
1915
+ Type thrownErrorType;
1916
+ if (auto accessor = varDecl->getEffectfulGetAccessor ()) {
1917
+ thrownErrorType =
1918
+ accessor->getEffectiveThrownErrorType ().value_or (Type ());
1919
+ }
1920
+
1914
1921
assert (!valueType->hasUnboundGenericType () &&
1915
1922
!valueType->hasTypeParameter ());
1916
- return { valueType, valueType, valueType, valueType };
1923
+ return { valueType, valueType, valueType, valueType, thrownErrorType };
1917
1924
}
1918
1925
1919
1926
// / Bind type variables for archetypes that are determined from
@@ -2640,13 +2647,13 @@ ConstraintSystem::getTypeOfMemberReference(
2640
2647
memberTy = MetatypeType::get (memberTy);
2641
2648
2642
2649
auto openedType = FunctionType::get ({baseObjParam}, memberTy);
2643
- return { openedType, openedType, memberTy, memberTy };
2650
+ return { openedType, openedType, memberTy, memberTy, Type () };
2644
2651
}
2645
2652
2646
2653
if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
2647
2654
if (value->getInterfaceType ()->is <ErrorType>()) {
2648
2655
auto genericErrorTy = ErrorType::get (getASTContext ());
2649
- return { genericErrorTy, genericErrorTy, genericErrorTy, genericErrorTy };
2656
+ return { genericErrorTy, genericErrorTy, genericErrorTy, genericErrorTy, Type () };
2650
2657
}
2651
2658
}
2652
2659
@@ -2665,6 +2672,7 @@ ConstraintSystem::getTypeOfMemberReference(
2665
2672
if (genericSig)
2666
2673
openGenericParameters (outerDC, genericSig, replacements, locator);
2667
2674
2675
+ Type thrownErrorType;
2668
2676
if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
2669
2677
// This is the easy case.
2670
2678
openedType = value->getInterfaceType ()->castTo <AnyFunctionType>();
@@ -2674,20 +2682,14 @@ ConstraintSystem::getTypeOfMemberReference(
2674
2682
[&](Type type) { return openType (type, replacements, locator); });
2675
2683
}
2676
2684
} else {
2677
- // Figure out the effect information for the reference.
2678
- FunctionType::ExtInfo info;
2685
+ // If the storage has a throwing getter, save the thrown error type..
2679
2686
auto storage = cast<AbstractStorageDecl>(value);
2680
-
2681
- // If the storage has a throwing getter, record that in the type.
2682
- if (auto effectfulGetter = storage->getEffectfulGetAccessor ()) {
2683
- if (effectfulGetter->hasThrows ()) {
2684
- Type thrownErrorType = effectfulGetter->getThrownInterfaceType ();
2685
- info = info.withThrows (true , thrownErrorType);
2686
- }
2687
+ if (auto accessor = storage->getEffectfulGetAccessor ()) {
2688
+ thrownErrorType = accessor->getEffectiveThrownErrorType ().value_or (Type ());
2687
2689
}
2688
2690
2689
2691
// For a property, build a type (Self) -> PropType.
2690
- // For a subscript, build a type (Self) -> (Indices...) -> ElementType.
2692
+ // For a subscript, build a type (Self) -> (Indices...) throws(?) -> ElementType.
2691
2693
//
2692
2694
// If the access is mutating, wrap the storage type in an lvalue type.
2693
2695
Type refType;
@@ -2700,6 +2702,14 @@ ConstraintSystem::getTypeOfMemberReference(
2700
2702
auto indices = subscript->getInterfaceType ()
2701
2703
->castTo <AnyFunctionType>()->getParams ();
2702
2704
2705
+ // Transfer the thrown error type into the subscript reference type,
2706
+ // which will be used in the application.
2707
+ FunctionType::ExtInfo info;
2708
+ if (thrownErrorType) {
2709
+ info = info.withThrows (true , thrownErrorType);
2710
+ thrownErrorType = Type ();
2711
+ }
2712
+
2703
2713
refType = FunctionType::get (indices, elementTy, info);
2704
2714
} else {
2705
2715
// Delay the adjustment for preconcurrency until after we've formed
@@ -2728,9 +2738,13 @@ ConstraintSystem::getTypeOfMemberReference(
2728
2738
if (genericSig) {
2729
2739
selfTy = openType (selfTy, replacements, locator);
2730
2740
refType = openType (refType, replacements, locator);
2741
+
2742
+ if (thrownErrorType)
2743
+ thrownErrorType = openType (thrownErrorType, replacements, locator);
2731
2744
}
2732
2745
FunctionType::Param selfParam (selfTy, Identifier (), selfFlags);
2733
2746
2747
+ FunctionType::ExtInfo info;
2734
2748
openedType = FunctionType::get ({selfParam}, refType, info);
2735
2749
}
2736
2750
assert (!openedType->hasTypeParameter ());
@@ -2863,7 +2877,7 @@ ConstraintSystem::getTypeOfMemberReference(
2863
2877
// If we opened up any type variables, record the replacements.
2864
2878
recordOpenedTypes (locator, replacements);
2865
2879
2866
- return { origOpenedType, openedType, origType, type };
2880
+ return { origOpenedType, openedType, origType, type, thrownErrorType };
2867
2881
}
2868
2882
2869
2883
Type ConstraintSystem::getEffectiveOverloadType (ConstraintLocator *locator,
@@ -3090,7 +3104,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
3090
3104
// FIXME: Verify ExtInfo state is correct, not working by accident.
3091
3105
FunctionType::ExtInfo info;
3092
3106
auto refType = FunctionType::get ({inputArg}, output, info);
3093
- return {refType, refType, refType, refType};
3107
+ return {refType, refType, refType, refType, Type () };
3094
3108
}
3095
3109
case DeclTypeCheckingSemantics::WithoutActuallyEscaping: {
3096
3110
// Proceed with a "WithoutActuallyEscaping" operation. The body closure
@@ -3125,7 +3139,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
3125
3139
.withAsync (true )
3126
3140
.withThrows (true , /* FIXME:*/ Type ())
3127
3141
.build ());
3128
- return {refType, refType, refType, refType};
3142
+ return {refType, refType, refType, refType, Type () };
3129
3143
}
3130
3144
case DeclTypeCheckingSemantics::OpenExistential: {
3131
3145
// The body closure receives a freshly-opened archetype constrained by the
@@ -3158,7 +3172,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
3158
3172
.withThrows (true , /* FIXME:*/ Type ())
3159
3173
.withAsync (true )
3160
3174
.build ());
3161
- return {refType, refType, refType, refType};
3175
+ return {refType, refType, refType, refType, Type () };
3162
3176
}
3163
3177
}
3164
3178
@@ -3751,6 +3765,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
3751
3765
Type adjustedOpenedType;
3752
3766
Type refType;
3753
3767
Type adjustedRefType;
3768
+ Type thrownErrorTypeOnAccess;
3754
3769
3755
3770
switch (auto kind = choice.getKind ()) {
3756
3771
case OverloadChoiceKind::Decl:
@@ -3784,7 +3799,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
3784
3799
adjustedOpenedType = declRefType.adjustedOpenedType ;
3785
3800
refType = declRefType.referenceType ;
3786
3801
adjustedRefType = declRefType.adjustedReferenceType ;
3787
-
3802
+ thrownErrorTypeOnAccess = declRefType. thrownErrorTypeOnAccess ;
3788
3803
break ;
3789
3804
}
3790
3805
@@ -3951,6 +3966,13 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
3951
3966
}
3952
3967
}
3953
3968
3969
+ // If accessing this declaration could throw an error, record this as a
3970
+ // potential throw site.
3971
+ if (thrownErrorTypeOnAccess) {
3972
+ recordPotentialThrowSite (
3973
+ PotentialThrowSite::PropertyAccess, thrownErrorTypeOnAccess, locator);
3974
+ }
3975
+
3954
3976
// Note that we have resolved this overload.
3955
3977
auto overload = SelectedOverload{
3956
3978
choice, openedType, adjustedOpenedType, refType, adjustedRefType,
0 commit comments