@@ -467,26 +467,31 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
467
467
if (!ExprToIdentTypeRepr (components, Context).visit (ude->getBase ()))
468
468
return nullptr ;
469
469
470
- auto *const repr = IdentTypeRepr::create (Context, components);
470
+ const auto options =
471
+ TypeResolutionOptions (None) | TypeResolutionFlags::SilenceErrors;
471
472
472
- // See first if the repr unambiguously references an enum declaration.
473
- bool anyObject = false ;
474
- const auto &referencedDecls =
475
- getDirectlyReferencedNominalTypeDecls (Context, repr, DC, anyObject);
476
- if (referencedDecls.size () != 1 )
477
- return nullptr ;
473
+ auto *repr = IdentTypeRepr::create (Context, components);
478
474
479
- auto *const enumDecl = dyn_cast<EnumDecl>(referencedDecls.front ());
475
+ // See if the repr resolves to a type.
476
+ const auto resolution =
477
+ TypeResolution::forContextual (DC, options, [](auto unboundTy) {
478
+ // FIXME: Don't let unbound generic types escape type resolution.
479
+ // For now, just return the unbound generic type.
480
+ return unboundTy;
481
+ });
482
+ const auto ty = resolution.resolveType (repr);
483
+ auto *enumDecl = dyn_cast_or_null<EnumDecl>(ty->getAnyNominal ());
480
484
if (!enumDecl)
481
485
return nullptr ;
482
486
483
- EnumElementDecl *referencedElement =
484
- lookupEnumMemberElement (DC, enumDecl->getDeclaredInterfaceType (),
485
- ude->getName (), ude->getLoc ());
487
+ EnumElementDecl *referencedElement
488
+ = lookupEnumMemberElement (DC, ty, ude->getName (), ude->getLoc ());
486
489
if (!referencedElement)
487
490
return nullptr ;
488
491
489
- auto *const base = new (Context) TypeExpr (repr);
492
+ auto *base =
493
+ TypeExpr::createForMemberDecl (repr, ude->getNameLoc (), enumDecl);
494
+ base->setType (MetatypeType::get (ty));
490
495
return new (Context)
491
496
EnumElementPattern (base, ude->getDotLoc (), ude->getNameLoc (),
492
497
ude->getName (), referencedElement, nullptr );
@@ -564,31 +569,37 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
564
569
baseTE = TypeExpr::createImplicit (enumDecl->getDeclaredTypeInContext (),
565
570
Context);
566
571
} else {
572
+ const auto options =
573
+ TypeResolutionOptions (None) | TypeResolutionFlags::SilenceErrors;
574
+
567
575
// Otherwise, see whether we had an enum type as the penultimate
568
576
// component, and look up an element inside it.
569
- auto *const prefixRepr = IdentTypeRepr::create (Context, components);
570
-
571
- // See first if the repr unambiguously references an enum declaration .
572
- bool anyObject = false ;
573
- const auto &referencedDecls = getDirectlyReferencedNominalTypeDecls (
574
- Context, prefixRepr, DC, anyObject);
575
- if (referencedDecls. size () != 1 )
576
- return nullptr ;
577
-
578
- auto *const enumDecl = dyn_cast <EnumDecl>(referencedDecls. front ());
577
+ auto *prefixRepr = IdentTypeRepr::create (Context, components);
578
+
579
+ // See first if the entire repr resolves to a type .
580
+ const Type enumTy =
581
+ TypeResolution::forContextual (DC, options, []( auto unboundTy) {
582
+ // FIXME: Don't let unbound generic types escape type resolution.
583
+ // For now, just return the unbound generic type.
584
+ return unboundTy ;
585
+ }). resolveType (prefixRepr);
586
+ auto *enumDecl = dyn_cast_or_null <EnumDecl>(enumTy-> getAnyNominal ());
579
587
if (!enumDecl)
580
588
return nullptr ;
581
589
582
- referencedElement = lookupEnumMemberElement (
583
- DC, enumDecl->getDeclaredInterfaceType (), tailComponent->getNameRef (),
584
- tailComponent->getLoc ());
590
+ referencedElement
591
+ = lookupEnumMemberElement (DC, enumTy,
592
+ tailComponent->getNameRef (),
593
+ tailComponent->getLoc ());
585
594
if (!referencedElement)
586
595
return nullptr ;
587
596
588
- baseTE = new (Context) TypeExpr (prefixRepr);
597
+ baseTE = TypeExpr::createForMemberDecl (
598
+ prefixRepr, tailComponent->getNameLoc (), enumDecl);
599
+ baseTE->setType (MetatypeType::get (enumTy));
589
600
}
590
601
591
- assert (baseTE && " Didn't initialize base expression?" );
602
+ assert (baseTE && baseTE-> getType () && " Didn't initialize base expression?" );
592
603
assert (!isa<GenericIdentTypeRepr>(tailComponent) &&
593
604
" should be handled above" );
594
605
@@ -1426,25 +1437,11 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1426
1437
1427
1438
enumTy = type;
1428
1439
} else {
1429
- // Validate the parent type if we haven't done so yet.
1430
- if (EEP->getParentType ().isNull ()) {
1431
- const auto resolution =
1432
- TypeResolution::forContextual (dc, options, [](auto unboundTy) {
1433
- // FIXME: Don't let unbound generic types escape type resolution.
1434
- // For now, just return the unbound generic type.
1435
- return unboundTy;
1436
- });
1437
- const auto ty = resolution.resolveType (EEP->getParentTypeRepr ());
1438
- EEP->setParentType (ty);
1439
-
1440
- if (ty->hasError ()) {
1441
- return nullptr ;
1442
- }
1443
- }
1444
-
1445
1440
// Check if the explicitly-written enum type matches the type we're
1446
1441
// coercing to.
1447
- const Type parentTy = EEP->getParentType ();
1442
+ assert (!EEP->getParentType ().isNull ()
1443
+ && " enum with resolved element doesn't specify parent type?!" );
1444
+ auto parentTy = EEP->getParentType ();
1448
1445
// If the type matches exactly, use it.
1449
1446
if (parentTy->isEqual (type)) {
1450
1447
enumTy = type;
0 commit comments