@@ -170,6 +170,7 @@ static unsigned getGenericRequirementKind(TypeResolutionOptions options) {
170170 case TypeResolverContext::ImmediateOptionalTypeArgument:
171171 case TypeResolverContext::AbstractFunctionDecl:
172172 case TypeResolverContext::CustomAttr:
173+ case TypeResolverContext::Inverted:
173174 break ;
174175 }
175176
@@ -5150,6 +5151,7 @@ NeverNullType TypeResolver::resolveImplicitlyUnwrappedOptionalType(
51505151 case TypeResolverContext::GenericParameterInherited:
51515152 case TypeResolverContext::AssociatedTypeInherited:
51525153 case TypeResolverContext::CustomAttr:
5154+ case TypeResolverContext::Inverted:
51535155 doDiag = true ;
51545156 break ;
51555157 }
@@ -5740,10 +5742,30 @@ NeverNullType TypeResolver::buildMetatypeType(
57405742
57415743NeverNullType TypeResolver::resolveInverseType (InverseTypeRepr *repr,
57425744 TypeResolutionOptions options) {
5743- auto ty = resolveType (repr->getConstraint (), options);
5745+ auto subOptions = options.withoutContext (true )
5746+ .withContext (TypeResolverContext::Inverted);
5747+ auto ty = resolveType (repr->getConstraint (), subOptions);
57445748 if (ty->hasError ())
57455749 return ErrorType::get (getASTContext ());
57465750
5751+ // If the inverted type is an existential metatype, unwrap the existential
5752+ // metatype so we can look at the instance type. We'll re-wrap at the end.
5753+ ExistentialMetatypeType *existentialTy =
5754+ dyn_cast<ExistentialMetatypeType>(ty.get ().getPointer ());
5755+ if (existentialTy) {
5756+ ty = existentialTy->getInstanceType ();
5757+ }
5758+
5759+ auto wrapInExistential = [existentialTy](Type type) -> Type {
5760+ if (!existentialTy)
5761+ return type;
5762+
5763+ std::optional<MetatypeRepresentation> repr;
5764+ if (existentialTy->hasRepresentation ())
5765+ repr = existentialTy->getRepresentation ();
5766+ return ExistentialMetatypeType::get (type, repr);
5767+ };
5768+
57475769 if (auto kp = ty->getKnownProtocol ()) {
57485770 if (auto kind = getInvertibleProtocolKind (*kp)) {
57495771
@@ -5752,13 +5774,16 @@ NeverNullType TypeResolver::resolveInverseType(InverseTypeRepr *repr,
57525774 !getASTContext ().LangOpts .hasFeature (Feature::NonescapableTypes)) {
57535775 diagnoseInvalid (repr, repr->getLoc (),
57545776 diag::escapable_requires_feature_flag);
5755- return ErrorType::get (getASTContext ());
5777+ return wrapInExistential ( ErrorType::get (getASTContext () ));
57565778 }
57575779
5758- return ProtocolCompositionType::getInverseOf (getASTContext (), *kind);
5780+ return wrapInExistential (
5781+ ProtocolCompositionType::getInverseOf (getASTContext (), *kind));
57595782 }
57605783 }
57615784
5785+ // Rewrap for diagnostic purposes.
5786+ ty = wrapInExistential (ty);
57625787 diagnoseInvalid (repr, repr->getLoc (), diag::inverse_type_not_invertible, ty);
57635788 return ErrorType::get (getASTContext ());
57645789}
@@ -5917,6 +5942,23 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
59175942 if (isa<ExistentialTypeRepr>(T))
59185943 return Action::SkipNode ();
59195944
5945+ // Suppressed conformance needs to be within any/some.
5946+ if (auto inverse = dyn_cast<InverseTypeRepr>(T)) {
5947+ // Find an enclosing protocol composition, if there is one, so we
5948+ // can insert 'any' before that.
5949+ SourceLoc anyLoc = inverse->getTildeLoc ();
5950+ if (!reprStack.empty ()) {
5951+ if (isa<CompositionTypeRepr>(reprStack.back ())) {
5952+ anyLoc = reprStack.back ()->getStartLoc ();
5953+ }
5954+ }
5955+
5956+ Ctx.Diags .diagnose (inverse->getTildeLoc (), diag::inverse_requires_any)
5957+ .highlight (inverse->getConstraint ()->getSourceRange ())
5958+ .fixItInsert (anyLoc, " any " );
5959+ return Action::SkipNode ();
5960+ }
5961+
59205962 reprStack.push_back (T);
59215963
59225964 auto *declRefTR = dyn_cast<DeclRefTypeRepr>(T);
0 commit comments