@@ -896,6 +896,48 @@ namespace {
896
896
return closedAny;
897
897
}
898
898
899
+ // / When we have a reference to a declaration whose type in context is
900
+ // / different from its normal interface type, introduce the appropriate
901
+ // / conversions. This can happen due to `@preconcurrency`.
902
+ Expr *adjustTypeForDeclReference (
903
+ Expr *expr, Type openedType, Type adjustedOpenedType,
904
+ llvm::function_ref<Type(Type)> getNewType = [](Type type) {
905
+ return type;
906
+ }) {
907
+ // If the types are the same, do nothing.
908
+ if (openedType->isEqual (adjustedOpenedType))
909
+ return expr;
910
+
911
+ auto &context = cs.getASTContext ();
912
+
913
+ // If we have an optional type, wrap it up in a monadic '?' and recurse.
914
+ if (Type objectType = openedType->getOptionalObjectType ()) {
915
+ Type adjustedRefType = getNewType (adjustedOpenedType);
916
+ Type adjustedObjectType = adjustedRefType->getOptionalObjectType ();
917
+ assert (adjustedObjectType && " Not an optional?" );
918
+
919
+ expr = new (context) BindOptionalExpr (expr, SourceLoc (), 0 , objectType);
920
+ cs.cacheType (expr);
921
+ expr = adjustTypeForDeclReference (expr, objectType, adjustedObjectType);
922
+ expr = new (context) InjectIntoOptionalExpr (expr, adjustedRefType);
923
+ cs.cacheType (expr);
924
+ expr = new (context) OptionalEvaluationExpr (expr, adjustedRefType);
925
+ cs.cacheType (expr);
926
+ return expr;
927
+ }
928
+
929
+ // For a function type, perform a function conversion.
930
+ if (openedType->is <AnyFunctionType>()) {
931
+ expr = new (context) FunctionConversionExpr (
932
+ expr, getNewType (adjustedOpenedType));
933
+ cs.cacheType (expr);
934
+ return expr;
935
+ }
936
+
937
+ assert (false && " Unhandled adjustment" );
938
+ return expr;
939
+ }
940
+
899
941
// / Determines if a partially-applied member reference should be
900
942
// / converted into a fully-applied member reference with a pair of
901
943
// / closures.
@@ -1388,6 +1430,7 @@ namespace {
1388
1430
ConstraintLocatorBuilder memberLocator, bool Implicit,
1389
1431
AccessSemantics semantics) {
1390
1432
const auto &choice = overload.choice ;
1433
+ const auto openedType = overload.openedType ;
1391
1434
const auto adjustedOpenedType = overload.adjustedOpenedType ;
1392
1435
1393
1436
ValueDecl *member = choice.getDecl ();
@@ -1597,7 +1640,7 @@ namespace {
1597
1640
1598
1641
auto computeRefType = [&](Type openedType) {
1599
1642
// Compute the type of the reference.
1600
- Type refType = simplifyType (adjustedOpenedType );
1643
+ Type refType = simplifyType (openedType );
1601
1644
1602
1645
// If the base was an opened existential, erase the opened
1603
1646
// existential.
@@ -1609,9 +1652,13 @@ namespace {
1609
1652
return refType;
1610
1653
};
1611
1654
1612
- Type refType = computeRefType (adjustedOpenedType );
1655
+ Type refType = computeRefType (openedType );
1613
1656
cs.setType (ref, refType);
1614
1657
1658
+ // Adjust the declaration reference type, if required.
1659
+ ref = adjustTypeForDeclReference (
1660
+ ref, openedType, adjustedOpenedType, computeRefType);
1661
+
1615
1662
closeExistentials (ref, locator, /* force=*/ openedExistential);
1616
1663
1617
1664
// We also need to handle the implicitly unwrap of the result
0 commit comments