@@ -2121,10 +2121,17 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
21212121 if (decl->preconcurrency ())
21222122 options |= TypeResolutionFlags::Preconcurrency;
21232123
2124+ // Placeholders are only currently allowed for FuncDecls with bodies, which
2125+ // we diagnose in ReturnTypePlaceholderReplacer.
2126+ HandlePlaceholderTypeReprFn placeholderOpener;
2127+ if (auto *FD = dyn_cast<FuncDecl>(decl)) {
2128+ if (FD->hasBody () && !FD->isBodySkipped ())
2129+ placeholderOpener = PlaceholderType::get;
2130+ }
21242131 auto *const dc = decl->getInnermostDeclContext ();
21252132 return TypeResolution::forInterface (dc, options,
21262133 /* unboundTyOpener*/ nullptr ,
2127- PlaceholderType::get ,
2134+ placeholderOpener ,
21282135 /* packElementOpener*/ nullptr )
21292136 .resolveType (resultTyRepr);
21302137}
@@ -2310,9 +2317,17 @@ static Type validateParameterType(ParamDecl *decl) {
23102317 : TypeResolverContext::FunctionInput);
23112318 options |= TypeResolutionFlags::Direct;
23122319
2320+ // We allow placeholders in parameter types to improve recovery since if a
2321+ // default argument is present we can suggest the inferred type. Avoid doing
2322+ // this for protocol requirements though since those can't ever have default
2323+ // arguments anyway.
2324+ HandlePlaceholderTypeReprFn placeholderOpener;
2325+ if (!isa<ProtocolDecl>(dc->getParent ()))
2326+ placeholderOpener = PlaceholderType::get;
2327+
23132328 const auto resolution =
23142329 TypeResolution::forInterface (dc, options, unboundTyOpener,
2315- PlaceholderType::get ,
2330+ placeholderOpener ,
23162331 /* packElementOpener*/ nullptr );
23172332
23182333 if (isa<VarargTypeRepr>(nestedRepr)) {
@@ -3026,9 +3041,11 @@ bool TypeChecker::isPassThroughTypealias(TypeAliasDecl *typealias,
30263041
30273042Type
30283043ExtendedTypeRequest::evaluate (Evaluator &eval, ExtensionDecl *ext) const {
3029- auto error = [&ext]() {
3044+ auto &ctx = ext->getASTContext ();
3045+
3046+ auto error = [&]() {
30303047 ext->setInvalid ();
3031- return ErrorType::get (ext-> getASTContext () );
3048+ return ErrorType::get (ctx );
30323049 };
30333050
30343051 // If we didn't parse a type, fill in an error type and bail out.
@@ -3052,6 +3069,15 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
30523069 if (extendedType->hasError ())
30533070 return error ();
30543071
3072+ auto &diags = ctx.Diags ;
3073+
3074+ // Cannot extend types who contain placeholders.
3075+ if (extendedType->hasPlaceholder ()) {
3076+ diags.diagnose (ext->getLoc (), diag::extension_placeholder)
3077+ .highlight (extendedRepr->getSourceRange ());
3078+ return error ();
3079+ }
3080+
30553081 // Hack to allow extending a generic typealias.
30563082 if (auto *unboundGeneric = extendedType->getAs <UnboundGenericType>()) {
30573083 if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl ())) {
@@ -3069,8 +3095,6 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
30693095 }
30703096 }
30713097
3072- auto &diags = ext->getASTContext ().Diags ;
3073-
30743098 // Cannot extend a metatype.
30753099 if (extendedType->is <AnyMetatypeType>()) {
30763100 diags.diagnose (ext->getLoc (), diag::extension_metatype, extendedType)
@@ -3087,13 +3111,6 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
30873111 return error ();
30883112 }
30893113
3090- // Cannot extend types who contain placeholders.
3091- if (extendedType->hasPlaceholder ()) {
3092- diags.diagnose (ext->getLoc (), diag::extension_placeholder)
3093- .highlight (extendedRepr->getSourceRange ());
3094- return error ();
3095- }
3096-
30973114 return extendedType;
30983115}
30993116
0 commit comments