Skip to content

Commit be5babf

Browse files
authored
Add experimental flag to turn on just opaque type erasure (#60172)
This was already enabled as part of `-enable-implicit-dynamic` but this new flag allows turning on opaque type erasure all by itself whether or not `dynamic` is added explicitly. rdar://97375478
1 parent 539c670 commit be5babf

File tree

7 files changed

+35
-2
lines changed

7 files changed

+35
-2
lines changed

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ EXPERIMENTAL_FEATURE(AdditiveArithmeticDerivedConformances)
117117
/// @Sendable.
118118
EXPERIMENTAL_FEATURE(SendableCompletionHandlers)
119119

120+
/// Enables opaque type erasure without also enabling implict dynamic
121+
EXPERIMENTAL_FEATURE(OpaqueTypeErasure)
122+
120123
#undef EXPERIMENTAL_FEATURE
121124
#undef UPCOMING_FEATURE
122125
#undef SUPPRESSIBLE_LANGUAGE_FEATURE

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,10 @@ def disable_swift3_objc_inference :
618618
def enable_implicit_dynamic : Flag<["-"], "enable-implicit-dynamic">,
619619
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
620620
HelpText<"Add 'dynamic' to all declarations">;
621+
622+
def enable_experimental_opaque_type_erasure : Flag<["-"], "enable-experimental-opaque-type-erasure">,
623+
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
624+
HelpText<"Type-erases opaque types that conform to @_typeEraser protocols">;
621625

622626
def enable_llvm_vfe : Flag<["-"], "enable-llvm-vfe">,
623627
Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5096,7 +5096,8 @@ class ConstraintSystem {
50965096
///
50975097
/// An expression needs type erasure if:
50985098
/// 1. The expression is a return value.
5099-
/// 2. The enclosing function is dynamic or a dynamic replacement.
5099+
/// 2. The enclosing function is dynamic, a dynamic replacement, or
5100+
/// `-enable-experimental-opaque-type-erasure` is used.
51005101
/// 3. The enclosing function returns an opaque type.
51015102
/// 4. The opaque type conforms to (exactly) one protocol, and the protocol
51025103
/// has a declared type eraser.

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,10 @@ static bool usesFeatureTypeWitnessSystemInference(Decl *decl) {
30413041
return false;
30423042
}
30433043

3044+
static bool usesFeatureOpaqueTypeErasure(Decl *decl) {
3045+
return false;
3046+
}
3047+
30443048
static bool usesFeatureDifferentiableProgramming(Decl *decl) {
30453049
return false;
30463050
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
678678
Opts.Features.insert(Feature::ForwardModeDifferentiation);
679679
if (Args.hasArg(OPT_enable_experimental_additive_arithmetic_derivation))
680680
Opts.Features.insert(Feature::AdditiveArithmeticDerivedConformances);
681+
682+
if (Args.hasArg(OPT_enable_experimental_opaque_type_erasure))
683+
Opts.Features.insert(Feature::OpaqueTypeErasure);
681684

682685
Opts.EnableAppExtensionRestrictions |= Args.hasArg(OPT_enable_app_extension);
683686

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6039,7 +6039,8 @@ Expr *ConstraintSystem::buildTypeErasedExpr(Expr *expr, DeclContext *dc,
60396039

60406040
auto *decl = dyn_cast_or_null<ValueDecl>(dc->getAsDecl());
60416041
if (!decl ||
6042-
!(decl->isDynamic() || decl->getDynamicallyReplacedDecl()))
6042+
(!Context.LangOpts.hasFeature(Feature::OpaqueTypeErasure) &&
6043+
!(decl->isDynamic() || decl->getDynamicallyReplacedDecl())))
60436044
return expr;
60446045

60456046
auto *opaque = contextualType->getAs<OpaqueTypeArchetypeType>();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -typecheck -disable-availability-checking -dump-ast -enable-experimental-opaque-type-erasure %s | %FileCheck %s
2+
3+
class AnyP: P {
4+
init<T: P>(erasing: T) {}
5+
}
6+
7+
@_typeEraser(AnyP)
8+
protocol P {}
9+
10+
struct ConcreteP: P, Hashable {}
11+
12+
// CHECK-LABEL: testTypeErased
13+
func testTypeErased() -> some P {
14+
// CHECK: underlying_to_opaque_expr{{.*}}'some P'
15+
// CHECK-NEXT: call_expr implicit type='AnyP'
16+
ConcreteP()
17+
}

0 commit comments

Comments
 (0)