@@ -2422,74 +2422,180 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
2422
2422
}
2423
2423
2424
2424
#ifndef NDEBUG
2425
- verifyLowering (*lowering, origType, origSubstType , forExpansion);
2425
+ verifyLowering (*lowering, origType, loweredSubstType , forExpansion);
2426
2426
#endif
2427
2427
2428
2428
return *lowering;
2429
2429
}
2430
2430
2431
2431
#ifndef NDEBUG
2432
+ bool TypeConverter::visitAggregateLeaves (
2433
+ Lowering::AbstractionPattern origType, Type substType,
2434
+ TypeExpansionContext context,
2435
+ std::function<bool (Type, Lowering::AbstractionPattern,
2436
+ Optional<TaggedUnion<ValueDecl *, unsigned >>)>
2437
+ isLeafAggregate,
2438
+ std::function<bool(Type, Lowering::AbstractionPattern,
2439
+ Optional<TaggedUnion<ValueDecl *, unsigned >>)>
2440
+ visit) {
2441
+ llvm::SmallSet<std::tuple<TypeBase *, ValueDecl *, unsigned >, 16 > visited;
2442
+ llvm::SmallVector<
2443
+ std::tuple<TypeBase *, AbstractionPattern, ValueDecl *, unsigned >, 16 >
2444
+ worklist;
2445
+ auto insertIntoWorklist =
2446
+ [&visited,
2447
+ &worklist](Type substTy, AbstractionPattern origTy,
2448
+ Optional<TaggedUnion<ValueDecl *, unsigned >> either) -> bool {
2449
+ ValueDecl *field;
2450
+ unsigned index;
2451
+ if (either) {
2452
+ if (either->isa <ValueDecl *>()) {
2453
+ field = either->get <ValueDecl *>();
2454
+ index = UINT_MAX;
2455
+ } else {
2456
+ field = nullptr ;
2457
+ index = either->get <unsigned >();
2458
+ }
2459
+ } else {
2460
+ field = nullptr ;
2461
+ index = UINT_MAX;
2462
+ }
2463
+ if (!visited.insert ({substTy.getPointer (), field, index}).second )
2464
+ return false ;
2465
+ worklist.push_back ({substTy.getPointer (), origTy, field, index});
2466
+ return true ;
2467
+ };
2468
+ auto popFromWorklist = [&worklist]()
2469
+ -> std::tuple<Type, AbstractionPattern,
2470
+ Optional<TaggedUnion<ValueDecl *, unsigned >>> {
2471
+ TypeBase *ty;
2472
+ AbstractionPattern origTy = AbstractionPattern::getOpaque ();
2473
+ Optional<TaggedUnion<ValueDecl *, unsigned >> either;
2474
+ ValueDecl *field;
2475
+ unsigned index = 0 ;
2476
+ std::tie (ty, origTy, field, index) = worklist.pop_back_val ();
2477
+ if (field) {
2478
+ either = TaggedUnion<ValueDecl *, unsigned >(field);
2479
+ } else if (index != UINT_MAX) {
2480
+ either = TaggedUnion<ValueDecl *, unsigned >(index);
2481
+ } else {
2482
+ either = llvm::None;
2483
+ }
2484
+ return {ty->getCanonicalType (), origTy, either};
2485
+ };
2486
+ auto isAggregate = [](Type ty) {
2487
+ return ty->is <TupleType>() || ty->getEnumOrBoundGenericEnum () ||
2488
+ ty->getStructOrBoundGenericStruct ();
2489
+ };
2490
+ insertIntoWorklist (substType, origType, llvm::None);
2491
+ while (!worklist.empty ()) {
2492
+ Type ty;
2493
+ AbstractionPattern origTy = AbstractionPattern::getOpaque ();
2494
+ Optional<TaggedUnion<ValueDecl *, unsigned >> path;
2495
+ std::tie (ty, origTy, path) = popFromWorklist ();
2496
+ if (isAggregate (ty) && !isLeafAggregate (ty, origTy, path)) {
2497
+ if (auto tupleTy = ty->getAs <TupleType>()) {
2498
+ for (unsigned index = 0 , num = tupleTy->getNumElements (); index < num;
2499
+ ++index) {
2500
+ auto origElementTy = origTy.getTupleElementType (index);
2501
+ auto substElementTy =
2502
+ tupleTy->getElementType (index)->getCanonicalType ();
2503
+ substElementTy =
2504
+ computeLoweredRValueType (context, origElementTy, substElementTy);
2505
+ insertIntoWorklist (substElementTy, origElementTy,
2506
+ TaggedUnion<ValueDecl *, unsigned >(index));
2507
+ }
2508
+ } else if (auto *decl = ty->getStructOrBoundGenericStruct ()) {
2509
+ for (auto *field : decl->getStoredProperties ()) {
2510
+ auto subMap = ty->getContextSubstitutionMap (&M, decl);
2511
+ auto substFieldTy =
2512
+ field->getInterfaceType ().subst (subMap)->getCanonicalType ();
2513
+ auto sig = field->getDeclContext ()->getGenericSignatureOfContext ();
2514
+ auto interfaceTy = field->getInterfaceType ()->getReducedType (sig);
2515
+ auto origFieldType =
2516
+ origTy.unsafeGetSubstFieldType (field, interfaceTy);
2517
+ insertIntoWorklist (substFieldTy, origFieldType,
2518
+ TaggedUnion<ValueDecl *, unsigned >(
2519
+ static_cast <ValueDecl *>(field)));
2520
+ }
2521
+ } else if (auto *decl = ty->getEnumOrBoundGenericEnum ()) {
2522
+ auto subMap = ty->getContextSubstitutionMap (&M, decl);
2523
+ for (auto *element : decl->getAllElements ()) {
2524
+ if (!element->hasAssociatedValues ())
2525
+ continue ;
2526
+ // TODO: Callback for indirect elements.
2527
+ if (element->isIndirect ())
2528
+ continue ;
2529
+ auto substElementType = element->getArgumentInterfaceType ()
2530
+ .subst (subMap)
2531
+ ->getCanonicalType ();
2532
+ auto origElementTy = origTy.unsafeGetSubstFieldType (
2533
+ element, element->getArgumentInterfaceType ()->getReducedType (
2534
+ decl->getGenericSignature ()));
2535
+
2536
+ insertIntoWorklist (substElementType, origElementTy,
2537
+ TaggedUnion<ValueDecl *, unsigned >(
2538
+ static_cast <ValueDecl *>(element)));
2539
+ }
2540
+ } else {
2541
+ llvm_unreachable (" unknown aggregate kind!" );
2542
+ }
2543
+ continue ;
2544
+ }
2545
+
2546
+ // This type is a leaf. Visit it.
2547
+ auto success = visit (ty, origTy, path);
2548
+ if (!success)
2549
+ return false ;
2550
+ }
2551
+ return true ;
2552
+ }
2553
+
2432
2554
void TypeConverter::verifyLowering (const TypeLowering &lowering,
2433
- AbstractionPattern origType,
2434
- Type origSubstType,
2555
+ AbstractionPattern origType, Type substType,
2435
2556
TypeExpansionContext forExpansion) {
2436
2557
// Non-trivial lowerings should always be lexical unless all non-trivial
2437
2558
// fields are eager move.
2438
2559
if (!lowering.isTrivial () && !lowering.isLexical ()) {
2439
- auto getLifetimeAnnotation = [](SILType ty) -> LifetimeAnnotation {
2560
+ if (lowering.getRecursiveProperties ().isInfinite ())
2561
+ return ;
2562
+ auto getLifetimeAnnotation = [](Type ty) -> LifetimeAnnotation {
2440
2563
NominalTypeDecl *nominal;
2441
- if (!(nominal = ty. getASTType (). getAnyNominal ()))
2564
+ if (!(nominal = ty-> getAnyNominal ()))
2442
2565
return LifetimeAnnotation::None;
2443
2566
return nominal->getLifetimeAnnotation ();
2444
2567
};
2445
- auto loweredType = lowering.getLoweredType ();
2446
- bool hasNoNontrivialLexicalLeaf = loweredType.visitAggregateLeaves (
2447
- *this , forExpansion,
2568
+ bool hasNoNontrivialLexicalLeaf = visitAggregateLeaves (
2569
+ origType, substType, forExpansion,
2448
2570
/* isLeaf=*/
2449
- [&](auto parent , auto ty , auto *fieldDecl ) -> bool {
2571
+ [&](auto ty , auto origTy , auto either ) -> bool {
2450
2572
// The field's type is an aggregate. Treat it as a leaf if it
2451
2573
// has a lifetime annotation.
2452
2574
2453
- // If we don't have a field decl, it's either a field of a tuple
2454
- // or the top-level type. Either way, there's no var decl on
2455
- // which to look for an attribute.
2456
- //
2457
- // It's a leaf if the type has a lifetime annotation.
2458
- if (!fieldDecl)
2575
+ // If it's the top-level type or a field of a tuple, there's no var
2576
+ // decl on which to look for an attribute. It's a leaf iff the type
2577
+ // has a lifetime annotation.
2578
+ if (!either || either->template isa <unsigned >())
2459
2579
return getLifetimeAnnotation (ty).isSome ();
2460
2580
2461
2581
// It's a field of a struct or an enum. It's a leaf if the type
2462
2582
// or the var decl has a lifetime annotation.
2463
- return fieldDecl->getLifetimeAnnotation ().isSome () ||
2583
+ return either->template get <ValueDecl *>()
2584
+ ->getLifetimeAnnotation ()
2585
+ .isSome () ||
2464
2586
getLifetimeAnnotation (ty);
2465
2587
},
2466
2588
/* visit=*/
2467
- [&](auto parent , auto ty , auto *fieldDecl ) -> bool {
2589
+ [&](auto ty , auto origTy , auto either ) -> bool {
2468
2590
// Look at each leaf: if it is non-trivial, verify that it is
2469
2591
// attributed @_eagerMove.
2470
2592
2471
2593
// If the leaf is the whole type, verify that it is annotated
2472
2594
// @_eagerMove.
2473
- if (ty == loweredType )
2595
+ if (ty-> getCanonicalType () == substType-> getCanonicalType () )
2474
2596
return getLifetimeAnnotation (ty) == LifetimeAnnotation::EagerMove;
2475
2597
2476
- // Get ty's lowering.
2477
- CanGenericSignature sig;
2478
- if (fieldDecl) {
2479
- AbstractionPattern origFieldTy = getAbstractionPattern (fieldDecl);
2480
- CanType substFieldTy;
2481
- if (fieldDecl->hasClangNode ()) {
2482
- substFieldTy = origFieldTy.getType ();
2483
- } else {
2484
- substFieldTy = parent.getASTType ()
2485
- ->getTypeOfMember (&M, fieldDecl)
2486
- ->getCanonicalType ();
2487
- }
2488
- sig = getAbstractionPattern (fieldDecl).getGenericSignatureOrNull ();
2489
- } else {
2490
- sig = CanGenericSignature ();
2491
- }
2492
- auto &tyLowering = getTypeLowering (ty, forExpansion, sig);
2598
+ auto &tyLowering = getTypeLowering (origTy, ty, forExpansion);
2493
2599
2494
2600
// Leaves which are trivial aren't of interest.
2495
2601
if (tyLowering.isTrivial ())
@@ -2499,7 +2605,7 @@ void TypeConverter::verifyLowering(const TypeLowering &lowering,
2499
2605
// not lexical. The leaf must be annotated @_eagerMove.
2500
2606
// Otherwise, the whole type would be lexical.
2501
2607
2502
- if (!fieldDecl ) {
2608
+ if (!either || either-> template isa < unsigned >() ) {
2503
2609
// There is no field decl that might be annotated @_eagerMove. The
2504
2610
// field is @_eagerMove iff its type is annotated @_eagerMove.
2505
2611
return getLifetimeAnnotation (ty) == LifetimeAnnotation::EagerMove;
@@ -2508,7 +2614,7 @@ void TypeConverter::verifyLowering(const TypeLowering &lowering,
2508
2614
// The field is non-trivial and the whole type is non-lexical.
2509
2615
// That's fine as long as the field or its type is annotated
2510
2616
// @_eagerMove.
2511
- return fieldDecl ->getLifetimeAnnotation () ==
2617
+ return either-> template get <ValueDecl *>() ->getLifetimeAnnotation () ==
2512
2618
LifetimeAnnotation::EagerMove ||
2513
2619
getLifetimeAnnotation (ty) == LifetimeAnnotation::EagerMove;
2514
2620
});
0 commit comments