mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
AST: Add TypeBase::isNoEscape()
This commit is contained in:
@@ -1641,12 +1641,12 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
|
||||
return getTypeMatchFailure(locator);
|
||||
|
||||
// FIXME; Feels like a hack...nothing actually "conforms" here, and
|
||||
// we need to disallow conversions from @noescape functions to Any.
|
||||
// we need to disallow conversions from types containing @noescape
|
||||
// functions to Any.
|
||||
|
||||
// Conformance to 'Any' always holds.
|
||||
if (type2->isAny()) {
|
||||
auto *fnTy = type1->getAs<FunctionType>();
|
||||
if (!fnTy || !fnTy->isNoEscape())
|
||||
if (!type1->isNoEscape())
|
||||
return getTypeMatchSuccess();
|
||||
|
||||
if (shouldAttemptFixes()) {
|
||||
@@ -1835,21 +1835,19 @@ ConstraintSystem::matchTypesBindTypeVar(
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
|
||||
// Disallow bindings of noescape functions to type variables that
|
||||
// represent an opened archetype. If we allowed this it would allow
|
||||
// the noescape function to potentially escape.
|
||||
if (auto *fnTy = type->getAs<FunctionType>()) {
|
||||
if (fnTy->isNoEscape() && typeVar->getImpl().getGenericParameter()) {
|
||||
if (shouldAttemptFixes()) {
|
||||
auto *fix = MarkExplicitlyEscaping::create(
|
||||
*this, getConstraintLocator(locator));
|
||||
if (recordFix(fix))
|
||||
return getTypeMatchFailure(locator);
|
||||
|
||||
// Allow no-escape function to be bound with recorded fix.
|
||||
} else {
|
||||
// Disallow bindings of types containing noescape functions to type
|
||||
// variables that represent an opened generic parameter. If we allowed
|
||||
// this it would allow noescape functions to potentially escape.
|
||||
if (type->isNoEscape() && typeVar->getImpl().getGenericParameter()) {
|
||||
if (shouldAttemptFixes()) {
|
||||
auto *fix = MarkExplicitlyEscaping::create(
|
||||
*this, getConstraintLocator(locator));
|
||||
if (recordFix(fix))
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
|
||||
// Allow no-escape function to be bound with recorded fix.
|
||||
} else {
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2413,23 +2411,21 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
|
||||
type2->isExistentialType()) {
|
||||
|
||||
// Penalize conversions to Any, and disallow conversions of
|
||||
// noescape functions to Any.
|
||||
// types containing noescape functions to Any.
|
||||
if (kind >= ConstraintKind::Conversion && type2->isAny()) {
|
||||
if (auto *fnTy = type1->getAs<FunctionType>()) {
|
||||
if (fnTy->isNoEscape()) {
|
||||
if (shouldAttemptFixes()) {
|
||||
auto &ctx = getASTContext();
|
||||
auto *fix = MarkExplicitlyEscaping::create(
|
||||
*this, getConstraintLocator(locator), ctx.TheAnyType);
|
||||
if (recordFix(fix))
|
||||
return getTypeMatchFailure(locator);
|
||||
|
||||
// Allow 'no-escape' functions to be converted to 'Any'
|
||||
// with a recorded fix that helps us to properly diagnose
|
||||
// such situations.
|
||||
} else {
|
||||
if (type1->isNoEscape()) {
|
||||
if (shouldAttemptFixes()) {
|
||||
auto &ctx = getASTContext();
|
||||
auto *fix = MarkExplicitlyEscaping::create(
|
||||
*this, getConstraintLocator(locator), ctx.TheAnyType);
|
||||
if (recordFix(fix))
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
|
||||
// Allow 'no-escape' functions to be converted to 'Any'
|
||||
// with a recorded fix that helps us to properly diagnose
|
||||
// such situations.
|
||||
} else {
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user