@@ -456,6 +456,7 @@ Type ConstraintSystem::getCaughtErrorType(CatchNode catchNode) {
456456
457457 case PotentialThrowSite::ExplicitThrow:
458458 case PotentialThrowSite::NonExhaustiveDoCatch:
459+ case PotentialThrowSite::PropertyAccess:
459460 thrownErrorType = type;
460461 break ;
461462 }
@@ -1809,7 +1810,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
18091810
18101811 // The reference implicitly binds 'self'.
18111812 return {origOpenedType, openedType,
1812- origOpenedType->getResult (), openedType->getResult ()};
1813+ origOpenedType->getResult (), openedType->getResult (), Type () };
18131814 }
18141815
18151816 // Unqualified reference to a local or global function.
@@ -1854,7 +1855,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
18541855 // If we opened up any type variables, record the replacements.
18551856 recordOpenedTypes (locator, replacements);
18561857
1857- return { origOpenedType, openedType, origOpenedType, openedType };
1858+ return { origOpenedType, openedType, origOpenedType, openedType, Type () };
18581859 }
18591860
18601861 // Unqualified reference to a type.
@@ -1876,11 +1877,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
18761877
18771878 // Module types are not wrapped in metatypes.
18781879 if (type->is <ModuleType>())
1879- return { type, type, type, type };
1880+ return { type, type, type, type, Type () };
18801881
18811882 // If it's a value reference, refer to the metatype.
18821883 type = MetatypeType::get (type);
1883- return { type, type, type, type };
1884+ return { type, type, type, type, Type () };
18841885 }
18851886
18861887 // Unqualified reference to a macro.
@@ -1898,7 +1899,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
18981899
18991900 // FIXME: Should we use replaceParamErrorTypeByPlaceholder() here?
19001901
1901- return { openedType, openedType, openedType, openedType };
1902+ return { openedType, openedType, openedType, openedType, Type () };
19021903 }
19031904
19041905 // Only remaining case: unqualified reference to a property.
@@ -1911,9 +1912,15 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
19111912 getUnopenedTypeOfReference (varDecl, Type (), useDC, /* base=*/ nullptr ,
19121913 wantInterfaceType);
19131914
1915+ Type thrownErrorType;
1916+ if (auto accessor = varDecl->getEffectfulGetAccessor ()) {
1917+ thrownErrorType =
1918+ accessor->getEffectiveThrownErrorType ().value_or (Type ());
1919+ }
1920+
19141921 assert (!valueType->hasUnboundGenericType () &&
19151922 !valueType->hasTypeParameter ());
1916- return { valueType, valueType, valueType, valueType };
1923+ return { valueType, valueType, valueType, valueType, thrownErrorType };
19171924}
19181925
19191926// / Bind type variables for archetypes that are determined from
@@ -2640,13 +2647,13 @@ ConstraintSystem::getTypeOfMemberReference(
26402647 memberTy = MetatypeType::get (memberTy);
26412648
26422649 auto openedType = FunctionType::get ({baseObjParam}, memberTy);
2643- return { openedType, openedType, memberTy, memberTy };
2650+ return { openedType, openedType, memberTy, memberTy, Type () };
26442651 }
26452652
26462653 if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
26472654 if (value->getInterfaceType ()->is <ErrorType>()) {
26482655 auto genericErrorTy = ErrorType::get (getASTContext ());
2649- return { genericErrorTy, genericErrorTy, genericErrorTy, genericErrorTy };
2656+ return { genericErrorTy, genericErrorTy, genericErrorTy, genericErrorTy, Type () };
26502657 }
26512658 }
26522659
@@ -2665,6 +2672,7 @@ ConstraintSystem::getTypeOfMemberReference(
26652672 if (genericSig)
26662673 openGenericParameters (outerDC, genericSig, replacements, locator);
26672674
2675+ Type thrownErrorType;
26682676 if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
26692677 // This is the easy case.
26702678 openedType = value->getInterfaceType ()->castTo <AnyFunctionType>();
@@ -2674,20 +2682,14 @@ ConstraintSystem::getTypeOfMemberReference(
26742682 [&](Type type) { return openType (type, replacements, locator); });
26752683 }
26762684 } 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..
26792686 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 ());
26872689 }
26882690
26892691 // 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.
26912693 //
26922694 // If the access is mutating, wrap the storage type in an lvalue type.
26932695 Type refType;
@@ -2700,6 +2702,14 @@ ConstraintSystem::getTypeOfMemberReference(
27002702 auto indices = subscript->getInterfaceType ()
27012703 ->castTo <AnyFunctionType>()->getParams ();
27022704
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+
27032713 refType = FunctionType::get (indices, elementTy, info);
27042714 } else {
27052715 // Delay the adjustment for preconcurrency until after we've formed
@@ -2728,9 +2738,13 @@ ConstraintSystem::getTypeOfMemberReference(
27282738 if (genericSig) {
27292739 selfTy = openType (selfTy, replacements, locator);
27302740 refType = openType (refType, replacements, locator);
2741+
2742+ if (thrownErrorType)
2743+ thrownErrorType = openType (thrownErrorType, replacements, locator);
27312744 }
27322745 FunctionType::Param selfParam (selfTy, Identifier (), selfFlags);
27332746
2747+ FunctionType::ExtInfo info;
27342748 openedType = FunctionType::get ({selfParam}, refType, info);
27352749 }
27362750 assert (!openedType->hasTypeParameter ());
@@ -2863,7 +2877,7 @@ ConstraintSystem::getTypeOfMemberReference(
28632877 // If we opened up any type variables, record the replacements.
28642878 recordOpenedTypes (locator, replacements);
28652879
2866- return { origOpenedType, openedType, origType, type };
2880+ return { origOpenedType, openedType, origType, type, thrownErrorType };
28672881}
28682882
28692883Type ConstraintSystem::getEffectiveOverloadType (ConstraintLocator *locator,
@@ -3090,7 +3104,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
30903104 // FIXME: Verify ExtInfo state is correct, not working by accident.
30913105 FunctionType::ExtInfo info;
30923106 auto refType = FunctionType::get ({inputArg}, output, info);
3093- return {refType, refType, refType, refType};
3107+ return {refType, refType, refType, refType, Type () };
30943108 }
30953109 case DeclTypeCheckingSemantics::WithoutActuallyEscaping: {
30963110 // Proceed with a "WithoutActuallyEscaping" operation. The body closure
@@ -3125,7 +3139,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
31253139 .withAsync (true )
31263140 .withThrows (true , /* FIXME:*/ Type ())
31273141 .build ());
3128- return {refType, refType, refType, refType};
3142+ return {refType, refType, refType, refType, Type () };
31293143 }
31303144 case DeclTypeCheckingSemantics::OpenExistential: {
31313145 // The body closure receives a freshly-opened archetype constrained by the
@@ -3158,7 +3172,7 @@ static DeclReferenceType getTypeOfReferenceWithSpecialTypeCheckingSemantics(
31583172 .withThrows (true , /* FIXME:*/ Type ())
31593173 .withAsync (true )
31603174 .build ());
3161- return {refType, refType, refType, refType};
3175+ return {refType, refType, refType, refType, Type () };
31623176 }
31633177 }
31643178
@@ -3751,6 +3765,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
37513765 Type adjustedOpenedType;
37523766 Type refType;
37533767 Type adjustedRefType;
3768+ Type thrownErrorTypeOnAccess;
37543769
37553770 switch (auto kind = choice.getKind ()) {
37563771 case OverloadChoiceKind::Decl:
@@ -3784,7 +3799,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
37843799 adjustedOpenedType = declRefType.adjustedOpenedType ;
37853800 refType = declRefType.referenceType ;
37863801 adjustedRefType = declRefType.adjustedReferenceType ;
3787-
3802+ thrownErrorTypeOnAccess = declRefType. thrownErrorTypeOnAccess ;
37883803 break ;
37893804 }
37903805
@@ -3951,6 +3966,13 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
39513966 }
39523967 }
39533968
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+
39543976 // Note that we have resolved this overload.
39553977 auto overload = SelectedOverload{
39563978 choice, openedType, adjustedOpenedType, refType, adjustedRefType,
0 commit comments