@@ -58,12 +58,15 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
58
58
CanSILFunctionType fnTy;
59
59
ArrayRef<SILParameterInfo> ¶meters;
60
60
bool isNoImplicitCopy;
61
+ LifetimeAnnotation lifetimeAnnotation;
61
62
62
63
EmitBBArguments (SILGenFunction &sgf, SILBasicBlock *parent, SILLocation l,
63
64
CanSILFunctionType fnTy,
64
- ArrayRef<SILParameterInfo> ¶meters, bool isNoImplicitCopy)
65
+ ArrayRef<SILParameterInfo> ¶meters, bool isNoImplicitCopy,
66
+ LifetimeAnnotation lifetimeAnnotation)
65
67
: SGF(sgf), parent(parent), loc(l), fnTy(fnTy), parameters(parameters),
66
- isNoImplicitCopy (isNoImplicitCopy) {}
68
+ isNoImplicitCopy (isNoImplicitCopy),
69
+ lifetimeAnnotation(lifetimeAnnotation) {}
67
70
68
71
ManagedValue visitType (CanType t, AbstractionPattern orig) {
69
72
return visitType (t, orig, /* isInOut=*/ false );
@@ -90,7 +93,8 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
90
93
auto paramType =
91
94
SGF.F .mapTypeIntoContext (SGF.getSILType (parameterInfo, fnTy));
92
95
ManagedValue mv = SGF.B .createInputFunctionArgument (
93
- paramType, loc.getAsASTNode <ValueDecl>(), isNoImplicitCopy);
96
+ paramType, loc.getAsASTNode <ValueDecl>(), isNoImplicitCopy,
97
+ lifetimeAnnotation);
94
98
95
99
// This is a hack to deal with the fact that Self.Type comes in as a static
96
100
// metatype, but we have to downcast it to a dynamic Self metatype to get
@@ -239,13 +243,14 @@ struct ArgumentInitHelper {
239
243
unsigned getNumArgs () const { return ArgNo; }
240
244
241
245
ManagedValue makeArgument (Type ty, bool isInOut, bool isNoImplicitCopy,
242
- SILBasicBlock *parent, SILLocation l) {
246
+ LifetimeAnnotation lifetime, SILBasicBlock *parent,
247
+ SILLocation l) {
243
248
assert (ty && " no type?!" );
244
249
245
250
// Create an RValue by emitting destructured arguments into a basic block.
246
251
CanType canTy = ty->getCanonicalType ();
247
252
EmitBBArguments argEmitter (SGF, parent, l, f.getLoweredFunctionType (),
248
- parameters, isNoImplicitCopy);
253
+ parameters, isNoImplicitCopy, lifetime );
249
254
250
255
// Note: inouts of tuples are not exploded, so we bypass visit().
251
256
AbstractionPattern origTy = OrigFnType
@@ -266,17 +271,24 @@ struct ArgumentInitHelper {
266
271
267
272
// Look for the following annotations on the function argument:
268
273
// - @noImplicitCopy
274
+ // - @_eagerMove
275
+ // - @_lexical
269
276
auto isNoImplicitCopy = pd->isNoImplicitCopy ();
277
+ auto lifetime = SGF.F .getLifetime (pd, value->getType ());
270
278
271
279
// If we have a no implicit copy argument and the argument is trivial,
272
280
// we need to use copyable to move only to convert it to its move only
273
281
// form.
274
282
if (!isNoImplicitCopy) {
275
283
if (!value->getType ().isMoveOnly ()) {
284
+ // Follow the "normal path": perform a lexical borrow if the lifetime is
285
+ // lexical.
276
286
if (value->getOwnershipKind () == OwnershipKind::Owned) {
277
- value =
278
- SILValue (SGF.B .createBeginBorrow (loc, value, /* isLexical*/ true ));
279
- SGF.Cleanups .pushCleanup <EndBorrowCleanup>(value);
287
+ if (lifetime.isLexical ()) {
288
+ value = SILValue (
289
+ SGF.B .createBeginBorrow (loc, value, /* isLexical*/ true ));
290
+ SGF.Cleanups .pushCleanup <EndBorrowCleanup>(value);
291
+ }
280
292
}
281
293
return value;
282
294
}
@@ -343,8 +355,8 @@ struct ArgumentInitHelper {
343
355
SILLocation loc (pd);
344
356
loc.markAsPrologue ();
345
357
346
- ManagedValue argrv =
347
- makeArgument (ty, pd-> isInOut (), pd->isNoImplicitCopy (), parent, loc);
358
+ ManagedValue argrv = makeArgument (ty, pd-> isInOut (), pd-> isNoImplicitCopy (),
359
+ pd->getLifetimeAnnotation (), parent, loc);
348
360
349
361
if (pd->isInOut ()) {
350
362
assert (argrv.getType ().isAddress () && " expected inout to be address" );
@@ -362,7 +374,10 @@ struct ArgumentInitHelper {
362
374
} else {
363
375
if (auto *allocStack = dyn_cast<AllocStackInst>(value)) {
364
376
allocStack->setArgNo (ArgNo);
365
- allocStack->setIsLexical ();
377
+ if (SGF.getASTContext ().SILOpts .supportsLexicalLifetimes (
378
+ SGF.getModule ()) &&
379
+ SGF.F .getLifetime (pd, value->getType ()).isLexical ())
380
+ allocStack->setIsLexical ();
366
381
} else {
367
382
SGF.B .createDebugValueAddr (loc, value, varinfo);
368
383
}
@@ -397,8 +412,9 @@ struct ArgumentInitHelper {
397
412
Scope discardScope (SGF.Cleanups , CleanupLocation (PD));
398
413
399
414
// Manage the parameter.
400
- auto argrv = makeArgument (type, PD->isInOut (), PD->isNoImplicitCopy (),
401
- &*f.begin (), paramLoc);
415
+ auto argrv =
416
+ makeArgument (type, PD->isInOut (), PD->isNoImplicitCopy (),
417
+ PD->getLifetimeAnnotation (), &*f.begin (), paramLoc);
402
418
403
419
// Emit debug information for the argument.
404
420
SILLocation loc (PD);
0 commit comments