@@ -268,6 +268,42 @@ class Conventions {
268
268
getIndirectSelfParameter (const AbstractionPattern &type) const = 0 ;
269
269
virtual ParameterConvention
270
270
getDirectSelfParameter (const AbstractionPattern &type) const = 0 ;
271
+
272
+ // Helpers that branch based on a value ownership.
273
+ ParameterConvention getIndirect (ValueOwnership ownership, bool forSelf,
274
+ unsigned index,
275
+ const AbstractionPattern &type,
276
+ const TypeLowering &substTL) const {
277
+ switch (ownership) {
278
+ case ValueOwnership::Default:
279
+ if (forSelf)
280
+ return getIndirectSelfParameter (type);
281
+ return getIndirectParameter (index, type, substTL);
282
+ case ValueOwnership::InOut:
283
+ return ParameterConvention::Indirect_Inout;
284
+ case ValueOwnership::Shared:
285
+ return ParameterConvention::Indirect_In_Guaranteed;
286
+ case ValueOwnership::Owned:
287
+ return ParameterConvention::Indirect_In;
288
+ }
289
+ }
290
+
291
+ ParameterConvention getDirect (ValueOwnership ownership, bool forSelf,
292
+ unsigned index, const AbstractionPattern &type,
293
+ const TypeLowering &substTL) const {
294
+ switch (ownership) {
295
+ case ValueOwnership::Default:
296
+ if (forSelf)
297
+ return getDirectSelfParameter (type);
298
+ return getDirectParameter (index, type, substTL);
299
+ case ValueOwnership::InOut:
300
+ return ParameterConvention::Indirect_Inout;
301
+ case ValueOwnership::Shared:
302
+ return ParameterConvention::Direct_Guaranteed;
303
+ case ValueOwnership::Owned:
304
+ return ParameterConvention::Direct_Owned;
305
+ }
306
+ }
271
307
};
272
308
273
309
// / A visitor for breaking down formal result types into a SILResultInfo
@@ -523,40 +559,6 @@ class DestructureInputs {
523
559
}
524
560
}
525
561
526
- void visitSharedType (AbstractionPattern origType, CanType substType,
527
- SILFunctionTypeRepresentation rep) {
528
- NextOrigParamIndex++;
529
-
530
- auto &substTL =
531
- M.Types .getTypeLowering (origType, substType);
532
- ParameterConvention convention;
533
- if (origType.getAs <InOutType>()) {
534
- convention = ParameterConvention::Indirect_Inout;
535
- } else if (isa<TupleType>(substType) && !origType.isTypeParameter ()) {
536
- // Do not lower tuples @guaranteed. This can create conflicts with
537
- // substitutions for witness thunks e.g. we take $*(T, T)
538
- // @in_guaranteed and try to substitute it for $*T.
539
- return visit (origType, substType);
540
- } else if (isFormallyPassedIndirectly (origType, substType, substTL)) {
541
- if (rep == SILFunctionTypeRepresentation::WitnessMethod)
542
- convention = ParameterConvention::Indirect_In_Guaranteed;
543
- else
544
- convention = Convs.getIndirectSelfParameter (origType);
545
- assert (isIndirectFormalParameter (convention));
546
-
547
- } else if (substTL.isTrivial ()) {
548
- convention = ParameterConvention::Direct_Unowned;
549
- } else {
550
- convention = Convs.getDirectSelfParameter (origType);
551
- assert (!isIndirectFormalParameter (convention));
552
- }
553
-
554
- auto loweredType = substTL.getLoweredType ().getSwiftRValueType ();
555
- Inputs.push_back (SILParameterInfo (loweredType, convention));
556
-
557
- maybeAddForeignParameters ();
558
- }
559
-
560
562
// / This is a special entry point that allows destructure inputs to handle
561
563
// / self correctly.
562
564
void visitTopLevelParams (AbstractionPattern origType,
@@ -565,11 +567,15 @@ class DestructureInputs {
565
567
unsigned numEltTypes = params.size ();
566
568
unsigned numNonSelfParams = numEltTypes - 1 ;
567
569
570
+ auto silRepresentation = extInfo.getSILRepresentation ();
571
+
568
572
// We have to declare this out here so that the lambda scope lasts for
569
573
// the duration of the loop below.
570
574
auto handleForeignSelf = [&] {
571
- visit (origType.getTupleElementType (numNonSelfParams),
572
- params[numNonSelfParams].getType ());
575
+ // This is a "self", but it's not a Swift self, we handle it differently.
576
+ visit (ValueOwnership::Default,
577
+ /* forSelf=*/ false , origType.getTupleElementType (numNonSelfParams),
578
+ params[numNonSelfParams].getType (), silRepresentation);
573
579
};
574
580
575
581
// If we have a foreign-self, install handleSelf as the handler.
@@ -587,7 +593,8 @@ class DestructureInputs {
587
593
// to substitute.
588
594
if (params.empty ()) {
589
595
if (origType.isTypeParameter ())
590
- visit (origType, M.getASTContext ().TheEmptyTupleType );
596
+ visit (ValueOwnership::Default, /* forSelf=*/ false , origType,
597
+ M.getASTContext ().TheEmptyTupleType , silRepresentation);
591
598
return ;
592
599
}
593
600
@@ -599,25 +606,18 @@ class DestructureInputs {
599
606
// If the abstraction pattern is opaque, and the tuple type is
600
607
// materializable -- if it doesn't contain an l-value type -- then it's
601
608
// a valid target for substitution and we should not expand it.
602
- auto silExtInfo = extInfo.getSILRepresentation ();
603
609
if (!tty || (pattern.isTypeParameter () && !tty->hasInOutElement ())) {
604
- if (paramFlags.isShared ()) {
605
- visitSharedType (pattern, ty, silExtInfo);
606
- } else {
607
- visit (pattern, ty);
608
- }
610
+ visit (paramFlags.getValueOwnership (), /* forSelf=*/ false , pattern, ty,
611
+ silRepresentation);
609
612
return ;
610
613
}
611
614
612
615
for (auto i : indices (tty.getElementTypes ())) {
613
616
auto patternEltTy = pattern.getTupleElementType (i);
614
617
auto trueEltTy = tty.getElementType (i);
615
618
auto flags = tty->getElement (i).getParameterFlags ();
616
- if (flags.isShared ()) {
617
- visitSharedType (patternEltTy, trueEltTy, silExtInfo);
618
- } else {
619
- visit (patternEltTy, trueEltTy);
620
- }
619
+ visit (flags.getValueOwnership (), /* forSelf=*/ false , patternEltTy,
620
+ trueEltTy, silRepresentation);
621
621
}
622
622
};
623
623
@@ -647,25 +647,41 @@ class DestructureInputs {
647
647
// Process the self parameter. Note that we implicitly drop self
648
648
// if this is a static foreign-self import.
649
649
if (!Foreign.Self .isImportAsMember ()) {
650
- visitSharedType (origType. getTupleElementType (numNonSelfParams) ,
651
- params[numNonSelfParams]. getType ( ),
652
- extInfo. getSILRepresentation () );
650
+ visit (ValueOwnership::Default, /* forSelf= */ true ,
651
+ origType. getTupleElementType (numNonSelfParams ),
652
+ params[numNonSelfParams]. getType (), silRepresentation );
653
653
}
654
654
655
655
// Clear the foreign-self handler for safety.
656
656
HandleForeignSelf.reset ();
657
657
}
658
658
659
- void visit (AbstractionPattern origType, CanType substType) {
660
- // Expand tuples.
659
+ void visit (ValueOwnership ownership, bool forSelf,
660
+ AbstractionPattern origType, CanType substType,
661
+ SILFunctionTypeRepresentation rep) {
662
+ // Tuples get handled specially, in some cases:
661
663
CanTupleType substTupleTy = dyn_cast<TupleType>(substType);
662
664
if (substTupleTy && !origType.isTypeParameter ()) {
663
665
assert (origType.getNumTupleElements () == substTupleTy->getNumElements ());
664
- for (auto i : indices (substTupleTy.getElementTypes ())) {
665
- visit (origType.getTupleElementType (i),
666
- substTupleTy.getElementType (i));
666
+ switch (ownership) {
667
+ case ValueOwnership::Default:
668
+ case ValueOwnership::Owned:
669
+ // Expand the tuple.
670
+ for (auto i : indices (substTupleTy.getElementTypes ())) {
671
+ visit (ownership, forSelf, origType.getTupleElementType (i),
672
+ substTupleTy.getElementType (i), rep);
673
+ }
674
+ return ;
675
+ case ValueOwnership::Shared:
676
+ // Do not lower tuples @guaranteed. This can create conflicts with
677
+ // substitutions for witness thunks e.g. we take $*(T, T)
678
+ // @in_guaranteed and try to substitute it for $*T.
679
+ return visit (ValueOwnership::Default, forSelf, origType, substType,
680
+ rep);
681
+ case ValueOwnership::InOut:
682
+ // handled below
683
+ break ;
667
684
}
668
- return ;
669
685
}
670
686
671
687
unsigned origParamIndex = NextOrigParamIndex++;
@@ -676,14 +692,17 @@ class DestructureInputs {
676
692
assert (origType.isTypeParameter () || origType.getAs <InOutType>());
677
693
convention = ParameterConvention::Indirect_Inout;
678
694
} else if (isFormallyPassedIndirectly (origType, substType, substTL)) {
679
- convention = Convs.getIndirectParameter (origParamIndex,
680
- origType, substTL);
695
+ if (forSelf && rep == SILFunctionTypeRepresentation::WitnessMethod)
696
+ convention = ParameterConvention::Indirect_In_Guaranteed;
697
+ else
698
+ convention = Convs.getIndirect (ownership, forSelf, origParamIndex,
699
+ origType, substTL);
681
700
assert (isIndirectFormalParameter (convention));
682
701
} else if (substTL.isTrivial ()) {
683
702
convention = ParameterConvention::Direct_Unowned;
684
703
} else {
685
- convention = Convs.getDirectParameter ( origParamIndex, origType,
686
- substTL);
704
+ convention = Convs.getDirect (ownership, forSelf, origParamIndex, origType,
705
+ substTL);
687
706
assert (!isIndirectFormalParameter (convention));
688
707
}
689
708
auto loweredType = substTL.getLoweredType ().getSwiftRValueType ();
0 commit comments