@@ -2643,11 +2643,13 @@ class VarDeclUsageChecker : public ASTWalker {
2643
2643
// / An AST walker that determines the underlying type of an opaque return decl
2644
2644
// / from its associated function body.
2645
2645
class OpaqueUnderlyingTypeChecker : public ASTWalker {
2646
+ using Candidate = std::pair<Expr *, Type>;
2647
+
2646
2648
ASTContext &Ctx;
2647
2649
AbstractFunctionDecl *Implementation;
2648
2650
OpaqueTypeDecl *OpaqueDecl;
2649
2651
BraceStmt *Body;
2650
- SmallVector<std::pair<Expr*, Type> , 4 > Candidates;
2652
+ SmallVector<Candidate , 4 > Candidates;
2651
2653
2652
2654
bool HasInvalidReturn = false ;
2653
2655
@@ -2680,23 +2682,13 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
2680
2682
}
2681
2683
2682
2684
// Check whether all of the underlying type candidates match up.
2683
- auto opaqueTypeInContext =
2684
- Implementation->mapTypeIntoContext (OpaqueDecl->getDeclaredInterfaceType ());
2685
- Type underlyingType = Candidates.front ().second ;
2686
-
2687
2685
// TODO [OPAQUE SUPPORT]: multiple opaque types
2688
- bool mismatch = false ;
2689
- for (auto otherCandidate : llvm::makeArrayRef (Candidates).slice (1 )) {
2690
- // Disregard tautological candidates.
2691
- if (otherCandidate.second ->isEqual (opaqueTypeInContext))
2692
- continue ;
2693
-
2694
- if (!underlyingType->isEqual (otherCandidate.second )) {
2695
- mismatch = true ;
2696
- break ;
2697
- }
2698
- }
2699
-
2686
+ Type underlyingType = Candidates.front ().second ;
2687
+ bool mismatch =
2688
+ std::any_of (Candidates.begin () + 1 , Candidates.end (),
2689
+ [&](Candidate &otherCandidate) {
2690
+ return !underlyingType->isEqual (otherCandidate.second );
2691
+ });
2700
2692
if (mismatch) {
2701
2693
Implementation->diagnose (
2702
2694
diag::opaque_type_mismatched_underlying_type_candidates);
@@ -2710,6 +2702,8 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
2710
2702
2711
2703
// The underlying type can't be defined recursively
2712
2704
// in terms of the opaque type itself.
2705
+ auto opaqueTypeInContext = Implementation->mapTypeIntoContext (
2706
+ OpaqueDecl->getDeclaredInterfaceType ());
2713
2707
auto isSelfReferencing = underlyingType.findIf ([&](Type t) -> bool {
2714
2708
return t->isEqual (opaqueTypeInContext);
2715
2709
});
@@ -2741,15 +2735,11 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
2741
2735
2742
2736
std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
2743
2737
if (auto underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(E)) {
2744
- assert (E->getType ()->isEqual (
2745
- Implementation->mapTypeIntoContext (OpaqueDecl->getDeclaredInterfaceType ()))
2746
- && " unexpected opaque type in function body" );
2747
-
2748
2738
Candidates.push_back (std::make_pair (underlyingToOpaque->getSubExpr (),
2749
2739
underlyingToOpaque->getSubExpr ()->getType ()));
2740
+ return {false , E};
2750
2741
}
2751
- // return std::make_pair(true, E);
2752
- return std::make_pair (false , E);
2742
+ return {true , E};
2753
2743
}
2754
2744
2755
2745
std::pair<bool , Stmt *> walkToStmtPre (Stmt *S) override {
0 commit comments