@@ -1402,6 +1402,38 @@ static bool diagnoseAvailability(Type ty, IdentTypeRepr *IdType, SourceLoc Loc,
1402
1402
return false ;
1403
1403
}
1404
1404
1405
+ // / Whether the given DC is a noescape-by-default context, i.e. not a property
1406
+ // / setter
1407
+ static bool isDefaultNoEscapeContext (const DeclContext *DC) {
1408
+ auto funcDecl = dyn_cast<FuncDecl>(DC);
1409
+ return !funcDecl || !funcDecl->isSetter ();
1410
+ }
1411
+
1412
+ // Hack to apply context-specific @escaping to an AST function type.
1413
+ static Type adjustFunctionExtInfo (DeclContext *DC,
1414
+ Type ty,
1415
+ TypeResolutionOptions options) {
1416
+ // Remember whether this is a function parameter.
1417
+ bool isFunctionParam =
1418
+ options.contains (TR_FunctionInput) ||
1419
+ options.contains (TR_ImmediateFunctionInput);
1420
+
1421
+ bool defaultNoEscape = isFunctionParam && isDefaultNoEscapeContext (DC);
1422
+
1423
+ // Desugar here
1424
+ auto *funcTy = ty->castTo <FunctionType>();
1425
+ auto extInfo = funcTy->getExtInfo ();
1426
+ if (defaultNoEscape && !extInfo.isNoEscape ()) {
1427
+ extInfo = extInfo.withNoEscape ();
1428
+
1429
+ // We lost the sugar to flip the isNoEscape bit
1430
+ return FunctionType::get (funcTy->getInput (), funcTy->getResult (), extInfo);
1431
+ }
1432
+
1433
+ // Note: original sugared type
1434
+ return ty;
1435
+ }
1436
+
1405
1437
// / \brief Returns a valid type or ErrorType in case of an error.
1406
1438
Type TypeChecker::resolveIdentifierType (
1407
1439
DeclContext *DC,
@@ -1432,6 +1464,11 @@ Type TypeChecker::resolveIdentifierType(
1432
1464
return ErrorType::get (Context);
1433
1465
}
1434
1466
1467
+ // Hack to apply context-specific @escaping to a typealias with an underlying
1468
+ // function type.
1469
+ if (result->is <FunctionType>())
1470
+ result = adjustFunctionExtInfo (DC, result, options);
1471
+
1435
1472
// We allow a type to conform to a protocol that is less available than
1436
1473
// the type itself. This enables a type to retroactively model or directly
1437
1474
// conform to a protocol only available on newer OSes and yet still be used on
@@ -1637,29 +1674,20 @@ Type TypeChecker::resolveType(TypeRepr *TyR, DeclContext *DC,
1637
1674
return result;
1638
1675
}
1639
1676
1640
- // / Whether the given DC is a noescape-by-default context, i.e. not a property
1641
- // / setter
1642
- static bool isDefaultNoEscapeContext (const DeclContext *DC) {
1643
- auto funcDecl = dyn_cast<FuncDecl>(DC);
1644
- return !funcDecl || !funcDecl->isSetter ();
1645
- }
1646
-
1647
1677
Type TypeResolver::resolveType (TypeRepr *repr, TypeResolutionOptions options) {
1648
1678
assert (repr && " Cannot validate null TypeReprs!" );
1649
1679
1650
1680
// If we know the type representation is invalid, just return an
1651
1681
// error type.
1652
1682
if (repr->isInvalid ()) return ErrorType::get (TC.Context );
1653
1683
1654
- // Remember whether this is a function parameter.
1655
- bool isFunctionParam =
1656
- options.contains (TR_FunctionInput) ||
1657
- options.contains (TR_ImmediateFunctionInput);
1658
-
1659
1684
// Strip the "is function input" bits unless this is a type that knows about
1660
1685
// them.
1661
- if (!isa<InOutTypeRepr>(repr) && !isa<TupleTypeRepr>(repr) &&
1662
- !isa<AttributedTypeRepr>(repr)) {
1686
+ if (!isa<InOutTypeRepr>(repr) &&
1687
+ !isa<TupleTypeRepr>(repr) &&
1688
+ !isa<AttributedTypeRepr>(repr) &&
1689
+ !isa<FunctionTypeRepr>(repr) &&
1690
+ !isa<IdentTypeRepr>(repr)) {
1663
1691
options -= TR_ImmediateFunctionInput;
1664
1692
options -= TR_FunctionInput;
1665
1693
}
@@ -1686,11 +1714,10 @@ Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) {
1686
1714
case TypeReprKind::Function:
1687
1715
if (!(options & TR_SILType)) {
1688
1716
// Default non-escaping for closure parameters
1689
- auto info = AnyFunctionType::ExtInfo ().withNoEscape (
1690
- isFunctionParam &&
1691
- isDefaultNoEscapeContext (DC));
1692
- return resolveASTFunctionType (cast<FunctionTypeRepr>(repr), options,
1693
- info);
1717
+ auto result = resolveASTFunctionType (cast<FunctionTypeRepr>(repr), options);
1718
+ if (result->is <FunctionType>())
1719
+ return adjustFunctionExtInfo (DC, result, options);
1720
+ return result;
1694
1721
}
1695
1722
return resolveSILFunctionType (cast<FunctionTypeRepr>(repr), options);
1696
1723
@@ -1761,8 +1788,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
1761
1788
bool isFunctionParam =
1762
1789
options.contains (TR_FunctionInput) ||
1763
1790
options.contains (TR_ImmediateFunctionInput);
1764
- options -= TR_ImmediateFunctionInput;
1765
- options -= TR_FunctionInput;
1766
1791
1767
1792
// The type we're working with, in case we want to build it differently
1768
1793
// based on the attributes we see.
@@ -1786,7 +1811,11 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
1786
1811
if (base) {
1787
1812
Optional<MetatypeRepresentation> storedRepr;
1788
1813
// The instance type is not a SIL type.
1789
- auto instanceOptions = options - TR_SILType;
1814
+ auto instanceOptions = options;
1815
+ instanceOptions -= TR_SILType;
1816
+ instanceOptions -= TR_ImmediateFunctionInput;
1817
+ instanceOptions -= TR_FunctionInput;
1818
+
1790
1819
auto instanceTy = resolveType (base, instanceOptions);
1791
1820
if (!instanceTy || instanceTy->is <ErrorType>())
1792
1821
return instanceTy;
@@ -1915,10 +1944,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
1915
1944
1916
1945
ty = resolveSILFunctionType (fnRepr, options, extInfo, calleeConvention);
1917
1946
if (!ty || ty->is <ErrorType>()) return ty;
1918
-
1919
- for (auto i : FunctionAttrs)
1920
- attrs.clearAttribute (i);
1921
- attrs.convention = None;
1922
1947
} else if (hasFunctionAttr && fnRepr) {
1923
1948
1924
1949
FunctionType::Representation rep = FunctionType::Representation::Swift;
@@ -1962,29 +1987,54 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
1962
1987
.fixItReplace (resultRange, " Never" );
1963
1988
}
1964
1989
1965
- bool defaultNoEscape = false ;
1966
- if (isFunctionParam && !attrs.has (TAK_escaping)) {
1967
- defaultNoEscape = isDefaultNoEscapeContext (DC);
1968
- }
1969
-
1970
- if (isFunctionParam && attrs.has (TAK_noescape) &&
1971
- isDefaultNoEscapeContext (DC)) {
1990
+ if (attrs.has (TAK_noescape)) {
1972
1991
// FIXME: diagnostic to tell user this is redundant and drop it
1973
1992
}
1974
1993
1975
1994
// Resolve the function type directly with these attributes.
1976
1995
FunctionType::ExtInfo extInfo (rep,
1977
1996
attrs.has (TAK_autoclosure),
1978
- defaultNoEscape | attrs.has (TAK_noescape),
1997
+ attrs.has (TAK_noescape),
1979
1998
fnRepr->throws ());
1980
1999
1981
2000
ty = resolveASTFunctionType (fnRepr, options, extInfo);
1982
2001
if (!ty || ty->is <ErrorType>()) return ty;
2002
+ }
1983
2003
1984
- for (auto i : FunctionAttrs)
1985
- attrs.clearAttribute (i);
1986
- attrs.convention = None;
1987
- } else if (hasFunctionAttr) {
2004
+ auto instanceOptions = options;
2005
+ instanceOptions -= TR_ImmediateFunctionInput;
2006
+ instanceOptions -= TR_FunctionInput;
2007
+
2008
+ // If we didn't build the type differently above, we might have
2009
+ // a typealias pointing at a function type with the @escaping
2010
+ // attribute. Resolve the type as if it were in non-parameter
2011
+ // context, and then set isNoEscape if @escaping is not present.
2012
+ if (!ty) ty = resolveType (repr, instanceOptions);
2013
+ if (!ty || ty->is <ErrorType>()) return ty;
2014
+
2015
+ // Handle @escaping
2016
+ if (hasFunctionAttr && ty->is <FunctionType>()) {
2017
+ if (attrs.has (TAK_escaping)) {
2018
+ // The attribute is meaningless except on parameter types.
2019
+ if (!isFunctionParam) {
2020
+ auto &SM = TC.Context .SourceMgr ;
2021
+ auto loc = attrs.getLoc (TAK_escaping);
2022
+ auto attrRange = SourceRange (
2023
+ loc.getAdvancedLoc (-1 ),
2024
+ Lexer::getLocForEndOfToken (SM, loc));
2025
+
2026
+ TC.diagnose (loc, diag::escaping_function_type)
2027
+ .fixItRemove (attrRange);
2028
+ }
2029
+
2030
+ attrs.clearAttribute (TAK_escaping);
2031
+ } else {
2032
+ // No attribute; set the isNoEscape bit if we're in parameter context.
2033
+ ty = adjustFunctionExtInfo (DC, ty, options);
2034
+ }
2035
+ }
2036
+
2037
+ if (hasFunctionAttr && !fnRepr) {
1988
2038
// @autoclosure usually auto-implies @noescape, don't complain about both
1989
2039
// of them.
1990
2040
if (attrs.has (TAK_autoclosure))
@@ -1997,11 +2047,11 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
1997
2047
attrs.clearAttribute (i);
1998
2048
}
1999
2049
}
2000
- }
2001
-
2002
- // If we didn't build the type differently above, build it normally now.
2003
- if (!ty) ty = resolveType (repr, options) ;
2004
- if (!ty || ty-> is <ErrorType>()) return ty;
2050
+ } else if (hasFunctionAttr && fnRepr) {
2051
+ for ( auto i : FunctionAttrs)
2052
+ attrs. clearAttribute (i);
2053
+ attrs. convention = None ;
2054
+ }
2005
2055
2006
2056
// In SIL, handle @opened (n), which creates an existential archetype.
2007
2057
if (attrs.has (TAK_opened)) {
@@ -2056,6 +2106,9 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
2056
2106
Type TypeResolver::resolveASTFunctionType (FunctionTypeRepr *repr,
2057
2107
TypeResolutionOptions options,
2058
2108
FunctionType::ExtInfo extInfo) {
2109
+ options -= TR_ImmediateFunctionInput;
2110
+ options -= TR_FunctionInput;
2111
+
2059
2112
Type inputTy = resolveType (repr->getArgsTypeRepr (),
2060
2113
options | TR_ImmediateFunctionInput);
2061
2114
if (!inputTy || inputTy->is <ErrorType>()) return inputTy;
@@ -2120,6 +2173,9 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
2120
2173
TypeResolutionOptions options,
2121
2174
SILFunctionType::ExtInfo extInfo,
2122
2175
ParameterConvention callee) {
2176
+ options -= TR_ImmediateFunctionInput;
2177
+ options -= TR_FunctionInput;
2178
+
2123
2179
bool hasError = false ;
2124
2180
2125
2181
SmallVector<SILParameterInfo, 4 > params;
@@ -2448,9 +2504,12 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
2448
2504
2449
2505
// If this is the top level of a function input list, peel off the
2450
2506
// ImmediateFunctionInput marker and install a FunctionInput one instead.
2451
- auto elementOptions = withoutContext (options);
2452
- if (options & TR_ImmediateFunctionInput)
2453
- elementOptions |= TR_FunctionInput;
2507
+ auto elementOptions = options;
2508
+ if (!repr->isParenType ()) {
2509
+ elementOptions = withoutContext (elementOptions);
2510
+ if (options & TR_ImmediateFunctionInput)
2511
+ elementOptions |= TR_FunctionInput;
2512
+ }
2454
2513
2455
2514
for (auto tyR : repr->getElements ()) {
2456
2515
NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
0 commit comments