Skip to content

Commit aac0a9a

Browse files
[doc] Document function representation conversions inline.
1 parent 3301ae9 commit aac0a9a

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,10 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
15901590
// C function pointers cannot capture anything from their context.
15911591
auto captures = SGF.SGM.Types.getLoweredLocalCaptures(constant);
15921592

1593+
// Catch cases like:
1594+
// func g(_ : @convention(c) () -> ()) {}
1595+
// func q() { let z = 0; func r() { print(z) }; g(r); } // error
1596+
// (See also: [NOTE: diagnose-swift-to-c-convention-change])
15931597
if (!captures.getCaptures().empty() ||
15941598
captures.hasGenericParamCaptures() ||
15951599
captures.hasDynamicSelfCapture() ||

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6013,6 +6013,11 @@ maybeDiagnoseUnsupportedFunctionConversion(ConstraintSystem &cs, Expr *expr,
60136013
if (auto closure = dyn_cast<ClosureExpr>(semanticExpr))
60146014
return;
60156015

6016+
// Diagnose cases like:
6017+
// func f() { print(w) }; func g(_ : @convention(c) () -> ()) {}
6018+
// let k = f; g(k) // error
6019+
// func m() { let x = 0; g({ print(x) }) } // error
6020+
// (See also: [NOTE: diagnose-swift-to-c-convention-change])
60166021
de.diagnose(expr->getLoc(),
60176022
diag::invalid_c_function_pointer_conversion_expr);
60186023
}

lib/Sema/CSSimplify.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,11 +1577,27 @@ static bool matchFunctionRepresentations(FunctionTypeRepresentation rep1,
15771577
return isSubtypeOf(rep1, rep2);
15781578
}
15791579

1580-
case ConstraintKind::OpaqueUnderlyingType:
1580+
1581+
// [NOTE: diagnose-swift-to-c-convention-change]: @convention(swift) ->
1582+
// @convention(c) conversions are permitted only in certain cases.
1583+
//
1584+
// var w = 3; func f() { print(w) }; func g(_ : @convention(c) () -> ()) {}
1585+
// g(f); // OK
1586+
// let h = f as @convention(c) () -> (); g(h) // OK
1587+
// let k = f; g(k) // error
1588+
// func m() { let x = 0; g({ print(x) }) } // error
1589+
// func n() { let y = 0; func p() { }; g(p); } // OK
1590+
// func q() { let z = 0; func r() { print(z) }; g(r); } // error
1591+
//
1592+
// Since checking for disallowed cases requires access to captures,
1593+
// it is simpler to defer diagnosing (to CSApply/SILGen) and return true here.
15811594
case ConstraintKind::Conversion:
1582-
case ConstraintKind::BridgingConversion:
15831595
case ConstraintKind::ArgumentConversion:
15841596
case ConstraintKind::OperatorArgumentConversion:
1597+
return true;
1598+
1599+
case ConstraintKind::OpaqueUnderlyingType:
1600+
case ConstraintKind::BridgingConversion:
15851601
case ConstraintKind::ApplicableFunction:
15861602
case ConstraintKind::DynamicCallableApplicableFunction:
15871603
case ConstraintKind::BindOverload:

0 commit comments

Comments
 (0)