Skip to content

Commit 5d2c829

Browse files
committed
LifetimeDependence: implement strict type checking
Rework the type checker to support completely checking lifetime dependence requirements. Don't let anything through without the feature being enabled and complete annotation or inference. First, prevent lifetime dependencies from sneaking into source that does not enable LifetimeDependence. This is essential for controlling the scope of the feature. Fixing this is disruptive because, ever since `~Escapable` was introduced we have been declaring empty non-Escapable types without enabling LifetimeDependence. Such as: struct Implicit_Init_Nonescapable : ~Escapable {} Fixes: rdar://145979187 ([nonescapable] diagnose implicit non-Escapable initializers as an error unless LifetimeDependence is enabled) Various forms of unsupported 'inout' dependencies are now also caught by the type checker. Second, disable lifetime dependency inferrence except in unambiguous cases and some implicitly generated cases. Fixes: rdar://131176898 ([nonescapable] missing diagnostic for incorrectly inferred inherited dependence) This is important to avoid source compatibility problems as inference rules change. They will change as the proposal goes through review. This fixes various latent missing dependency bugs. Disable experimental lifetime dependence inference. Unambiguous lifetime dependency candidates will still be inferred by default, without any frontend options. Ambiguous candidates will, however, no longer be inferred unless -Xfrontend -enable_experimental_lifetime_dependence_inference is enabled. This all has to be done without breaking existing .swiftinterface files. So backward compatibility logic is maintained. Examples of inference rules that are no longer enabled by default: 1. do not infer a dependency on non-Escapable 'self' for methods with more than zero parameters: extension NE: ~Escapable { /*@Lifetime(self)*/ // ERROR: 'self' not inferred func method<Arg>(arg: Arg) -> NE { ... } } 2. Never infer a 'copy' dependency kind for explicit functions extension NE: ~Escapable { @Lifetime(self) // ERROR: 'copy' not inferred func method() -> NE { ... } @Lifetime(self) // ERROR: 'copy' not inferred var property : NE { /*@Lifetime(self: newValue)*/ set { ... } } }
1 parent 97612ad commit 5d2c829

File tree

4 files changed

+907
-510
lines changed

4 files changed

+907
-510
lines changed

include/swift/AST/LifetimeDependence.h

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -227,32 +227,6 @@ class LifetimeDependenceInfo {
227227

228228
unsigned targetIndex;
229229

230-
static LifetimeDependenceInfo getForIndex(AbstractFunctionDecl *afd,
231-
unsigned targetIndex,
232-
unsigned sourceIndex,
233-
LifetimeDependenceKind kind);
234-
235-
/// Builds LifetimeDependenceInfo from @lifetime attribute
236-
static std::optional<ArrayRef<LifetimeDependenceInfo>>
237-
fromLifetimeAttribute(AbstractFunctionDecl *afd);
238-
239-
/// Infer LifetimeDependenceInfo on result
240-
static std::optional<LifetimeDependenceInfo> infer(AbstractFunctionDecl *afd);
241-
242-
/// Infer LifetimeDependenceInfo on setter
243-
static std::optional<LifetimeDependenceInfo>
244-
inferSetter(AbstractFunctionDecl *afd);
245-
246-
/// Infer LifetimeDependenceInfo on mutating self
247-
static std::optional<LifetimeDependenceInfo>
248-
inferMutatingSelf(AbstractFunctionDecl *afd);
249-
250-
/// Builds LifetimeDependenceInfo from SIL function type
251-
static std::optional<LifetimeDependenceInfo>
252-
fromDependsOn(LifetimeDependentTypeRepr *lifetimeDependentRepr,
253-
unsigned targetIndex, ArrayRef<SILParameterInfo> params,
254-
DeclContext *dc);
255-
256230
public:
257231
LifetimeDependenceInfo(IndexSubset *inheritLifetimeParamIndices,
258232
IndexSubset *scopeLifetimeParamIndices,
@@ -350,8 +324,8 @@ class LifetimeDependenceInfo {
350324

351325
/// Builds LifetimeDependenceInfo from SIL
352326
static std::optional<llvm::ArrayRef<LifetimeDependenceInfo>>
353-
get(FunctionTypeRepr *funcRepr, ArrayRef<SILParameterInfo> params,
354-
ArrayRef<SILResultInfo> results, DeclContext *dc);
327+
getFromSIL(FunctionTypeRepr *funcRepr, ArrayRef<SILParameterInfo> params,
328+
ArrayRef<SILResultInfo> results, DeclContext *dc);
355329

356330
bool operator==(const LifetimeDependenceInfo &other) const {
357331
return this->isImmortal() == other.isImmortal() &&

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ namespace swift {
598598
bool EnableRequirementMachineOpaqueArchetypes = false;
599599

600600
/// Enable implicit lifetime dependence for ~Escapable return types.
601-
bool EnableExperimentalLifetimeDependenceInference = true;
601+
bool EnableExperimentalLifetimeDependenceInference = false;
602602

603603
/// Skips decls that cannot be referenced externally.
604604
bool SkipNonExportableDecls = false;

0 commit comments

Comments
 (0)