@@ -499,15 +499,12 @@ checkEffects(AbstractStorageDecl *witness, AbstractStorageDecl *req) {
499
499
return std::nullopt ; // OK
500
500
}
501
501
502
- RequirementMatch swift::matchWitness (
503
- DeclContext *dc, ValueDecl *req, ValueDecl *witness,
504
- llvm::function_ref<
505
- std::tuple<std::optional<RequirementMatch>, Type, Type>(void )>
506
- setup,
507
- llvm::function_ref<std::optional<RequirementMatch>(Type, Type)> matchTypes,
508
- llvm::function_ref<RequirementMatch(bool , ArrayRef<OptionalAdjustment>)>
509
- finalize) {
510
-
502
+ // / Implementation of `matchWitnessStructure` that also sets a few out paramters
503
+ // / to be used by `matchWitness`.
504
+ static std::optional<RequirementMatch>
505
+ matchWitnessStructureImpl (ValueDecl *req, ValueDecl *witness,
506
+ bool &decomposeFunctionType, bool &ignoreReturnType,
507
+ Type &reqThrownError, Type &witnessThrownError) {
511
508
assert (!req->isInvalid () && " Cannot have an invalid requirement here" );
512
509
513
510
// / Make sure the witness is of the same kind as the requirement.
@@ -530,7 +527,7 @@ RequirementMatch swift::matchWitness(
530
527
if (witness->isRecursiveValidation ()) {
531
528
return RequirementMatch (witness, MatchKind::Circularity);
532
529
}
533
-
530
+
534
531
// If the witness is invalid, record that and stop now.
535
532
if (witness->isInvalid ()) {
536
533
return RequirementMatch (witness, MatchKind::WitnessInvalid);
@@ -541,10 +538,6 @@ RequirementMatch swift::matchWitness(
541
538
const auto &witnessAttrs = witness->getAttrs ();
542
539
543
540
// Perform basic matching of the requirement and witness.
544
- bool decomposeFunctionType = false ;
545
- bool ignoreReturnType = false ;
546
- Type reqThrownError;
547
- Type witnessThrownError;
548
541
if (isa<FuncDecl>(req) && isa<FuncDecl>(witness)) {
549
542
auto funcReq = cast<FuncDecl>(req);
550
543
auto funcWitness = cast<FuncDecl>(witness);
@@ -617,7 +610,7 @@ RequirementMatch swift::matchWitness(
617
610
decomposeFunctionType = true ;
618
611
} else if (auto *witnessASD = dyn_cast<AbstractStorageDecl>(witness)) {
619
612
auto *reqASD = cast<AbstractStorageDecl>(req);
620
-
613
+
621
614
// Check that the static-ness matches.
622
615
if (reqASD->isStatic () != witnessASD->isStatic ())
623
616
return RequirementMatch (witness, MatchKind::StaticNonStaticConflict);
@@ -701,8 +694,42 @@ RequirementMatch swift::matchWitness(
701
694
// If the requirement is @objc, the witness must not be marked with @nonobjc.
702
695
// @objc-ness will be inferred (separately) and the selector will be checked
703
696
// later.
704
- if (req->isObjC () && witness->getAttrs ().hasAttribute <NonObjCAttr>())
697
+ if (req->isObjC () && witness->getAttrs ().hasAttribute <NonObjCAttr>()) {
705
698
return RequirementMatch (witness, MatchKind::NonObjC);
699
+ }
700
+ return std::nullopt ;
701
+ }
702
+
703
+ bool swift::TypeChecker::witnessStructureMatches (ValueDecl *req,
704
+ const ValueDecl *witness) {
705
+ bool decomposeFunctionType = false ;
706
+ bool ignoreReturnType = false ;
707
+ Type reqThrownError;
708
+ Type witnessThrownError;
709
+ return matchWitnessStructureImpl (req, const_cast <ValueDecl *>(witness),
710
+ decomposeFunctionType, ignoreReturnType,
711
+ reqThrownError,
712
+ witnessThrownError) == std::nullopt ;
713
+ }
714
+
715
+ RequirementMatch swift::matchWitness (
716
+ DeclContext *dc, ValueDecl *req, ValueDecl *witness,
717
+ llvm::function_ref<
718
+ std::tuple<std::optional<RequirementMatch>, Type, Type>(void )>
719
+ setup,
720
+ llvm::function_ref<std::optional<RequirementMatch>(Type, Type)> matchTypes,
721
+ llvm::function_ref<RequirementMatch(bool , ArrayRef<OptionalAdjustment>)>
722
+ finalize) {
723
+ bool decomposeFunctionType = false ;
724
+ bool ignoreReturnType = false ;
725
+ Type reqThrownError;
726
+ Type witnessThrownError;
727
+
728
+ if (auto StructuralMismatch = matchWitnessStructureImpl (
729
+ req, witness, decomposeFunctionType, ignoreReturnType, reqThrownError,
730
+ witnessThrownError)) {
731
+ return *StructuralMismatch;
732
+ }
706
733
707
734
// Set up the match, determining the requirement and witness types
708
735
// in the process.
0 commit comments