@@ -2121,10 +2121,17 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
2121
2121
if (decl->preconcurrency ())
2122
2122
options |= TypeResolutionFlags::Preconcurrency;
2123
2123
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
+ }
2124
2131
auto *const dc = decl->getInnermostDeclContext ();
2125
2132
return TypeResolution::forInterface (dc, options,
2126
2133
/* unboundTyOpener*/ nullptr ,
2127
- PlaceholderType::get ,
2134
+ placeholderOpener ,
2128
2135
/* packElementOpener*/ nullptr )
2129
2136
.resolveType (resultTyRepr);
2130
2137
}
@@ -2310,9 +2317,17 @@ static Type validateParameterType(ParamDecl *decl) {
2310
2317
: TypeResolverContext::FunctionInput);
2311
2318
options |= TypeResolutionFlags::Direct;
2312
2319
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
+
2313
2328
const auto resolution =
2314
2329
TypeResolution::forInterface (dc, options, unboundTyOpener,
2315
- PlaceholderType::get ,
2330
+ placeholderOpener ,
2316
2331
/* packElementOpener*/ nullptr );
2317
2332
2318
2333
if (isa<VarargTypeRepr>(nestedRepr)) {
@@ -3026,9 +3041,11 @@ bool TypeChecker::isPassThroughTypealias(TypeAliasDecl *typealias,
3026
3041
3027
3042
Type
3028
3043
ExtendedTypeRequest::evaluate (Evaluator &eval, ExtensionDecl *ext) const {
3029
- auto error = [&ext]() {
3044
+ auto &ctx = ext->getASTContext ();
3045
+
3046
+ auto error = [&]() {
3030
3047
ext->setInvalid ();
3031
- return ErrorType::get (ext-> getASTContext () );
3048
+ return ErrorType::get (ctx );
3032
3049
};
3033
3050
3034
3051
// 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 {
3052
3069
if (extendedType->hasError ())
3053
3070
return error ();
3054
3071
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
+
3055
3081
// Hack to allow extending a generic typealias.
3056
3082
if (auto *unboundGeneric = extendedType->getAs <UnboundGenericType>()) {
3057
3083
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl ())) {
@@ -3069,8 +3095,6 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
3069
3095
}
3070
3096
}
3071
3097
3072
- auto &diags = ext->getASTContext ().Diags ;
3073
-
3074
3098
// Cannot extend a metatype.
3075
3099
if (extendedType->is <AnyMetatypeType>()) {
3076
3100
diags.diagnose (ext->getLoc (), diag::extension_metatype, extendedType)
@@ -3087,13 +3111,6 @@ ExtendedTypeRequest::evaluate(Evaluator &eval, ExtensionDecl *ext) const {
3087
3111
return error ();
3088
3112
}
3089
3113
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
-
3097
3114
return extendedType;
3098
3115
}
3099
3116
0 commit comments