@@ -467,31 +467,26 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
467
467
if (!ExprToIdentTypeRepr (components, Context).visit (ude->getBase ()))
468
468
return nullptr ;
469
469
470
- const auto options =
471
- TypeResolutionOptions (None) | TypeResolutionFlags::SilenceErrors;
470
+ auto *const repr = IdentTypeRepr::create (Context, components);
472
471
473
- auto *repr = IdentTypeRepr::create (Context, components);
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 ;
474
478
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 ());
479
+ auto *const enumDecl = dyn_cast<EnumDecl>(referencedDecls.front ());
484
480
if (!enumDecl)
485
481
return nullptr ;
486
482
487
- EnumElementDecl *referencedElement
488
- = lookupEnumMemberElement (DC, ty, ude->getName (), ude->getLoc ());
483
+ EnumElementDecl *referencedElement =
484
+ lookupEnumMemberElement (DC, enumDecl->getDeclaredInterfaceType (),
485
+ ude->getName (), ude->getLoc ());
489
486
if (!referencedElement)
490
487
return nullptr ;
491
488
492
- auto *base =
493
- TypeExpr::createForMemberDecl (repr, ude->getNameLoc (), enumDecl);
494
- base->setType (MetatypeType::get (ty));
489
+ auto *const base = new (Context) TypeExpr (repr);
495
490
return new (Context)
496
491
EnumElementPattern (base, ude->getDotLoc (), ude->getNameLoc (),
497
492
ude->getName (), referencedElement, nullptr );
@@ -569,37 +564,31 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
569
564
baseTE = TypeExpr::createImplicit (enumDecl->getDeclaredTypeInContext (),
570
565
Context);
571
566
} else {
572
- const auto options =
573
- TypeResolutionOptions (None) | TypeResolutionFlags::SilenceErrors;
574
-
575
567
// Otherwise, see whether we had an enum type as the penultimate
576
568
// component, and look up an element inside it.
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 ());
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 ());
587
579
if (!enumDecl)
588
580
return nullptr ;
589
581
590
- referencedElement
591
- = lookupEnumMemberElement (DC, enumTy,
592
- tailComponent->getNameRef (),
593
- tailComponent->getLoc ());
582
+ referencedElement = lookupEnumMemberElement (
583
+ DC, enumDecl->getDeclaredInterfaceType (), tailComponent->getNameRef (),
584
+ tailComponent->getLoc ());
594
585
if (!referencedElement)
595
586
return nullptr ;
596
587
597
- baseTE = TypeExpr::createForMemberDecl (
598
- prefixRepr, tailComponent->getNameLoc (), enumDecl);
599
- baseTE->setType (MetatypeType::get (enumTy));
588
+ baseTE = new (Context) TypeExpr (prefixRepr);
600
589
}
601
590
602
- assert (baseTE && baseTE-> getType () && " Didn't initialize base expression?" );
591
+ assert (baseTE && " Didn't initialize base expression?" );
603
592
assert (!isa<GenericIdentTypeRepr>(tailComponent) &&
604
593
" should be handled above" );
605
594
@@ -1437,11 +1426,25 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
1437
1426
1438
1427
enumTy = type;
1439
1428
} 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
+
1440
1445
// Check if the explicitly-written enum type matches the type we're
1441
1446
// coercing to.
1442
- assert (!EEP->getParentType ().isNull ()
1443
- && " enum with resolved element doesn't specify parent type?!" );
1444
- auto parentTy = EEP->getParentType ();
1447
+ const Type parentTy = EEP->getParentType ();
1445
1448
// If the type matches exactly, use it.
1446
1449
if (parentTy->isEqual (type)) {
1447
1450
enumTy = type;
0 commit comments