@@ -1217,6 +1217,77 @@ bool TypeVarBindingProducer::computeNext() {
1217
1217
return true ;
1218
1218
}
1219
1219
1220
+ Optional<std::pair<ConstraintFix *, unsigned >>
1221
+ TypeVariableBinding::fixForHole (ConstraintSystem &cs) const {
1222
+ auto *dstLocator = TypeVar->getImpl ().getLocator ();
1223
+ auto *srcLocator = Binding.getLocator ();
1224
+
1225
+ unsigned defaultImpact = 1 ;
1226
+
1227
+ if (auto *GP = TypeVar->getImpl ().getGenericParameter ()) {
1228
+ // If it is represetative for a key path root, let's emit a more
1229
+ // specific diagnostic.
1230
+ auto *keyPathRoot =
1231
+ cs.isRepresentativeFor (TypeVar, ConstraintLocator::KeyPathRoot);
1232
+ if (keyPathRoot) {
1233
+ ConstraintFix *fix = SpecifyKeyPathRootType::create (
1234
+ cs, keyPathRoot->getImpl ().getLocator ());
1235
+ return std::make_pair (fix, defaultImpact);
1236
+ } else {
1237
+ auto path = dstLocator->getPath ();
1238
+ // Drop `generic parameter` locator element so that all missing
1239
+ // generic parameters related to the same path can be coalesced later.
1240
+ ConstraintFix *fix = DefaultGenericArgument::create (
1241
+ cs, GP,
1242
+ cs.getConstraintLocator (dstLocator->getAnchor (), path.drop_back ()));
1243
+ return std::make_pair (fix, defaultImpact);
1244
+ }
1245
+ }
1246
+
1247
+ if (TypeVar->getImpl ().isClosureParameterType ()) {
1248
+ ConstraintFix *fix = SpecifyClosureParameterType::create (cs, dstLocator);
1249
+ return std::make_pair (fix, defaultImpact);
1250
+ }
1251
+
1252
+ if (TypeVar->getImpl ().isClosureResultType ()) {
1253
+ auto *closure = castToExpr<ClosureExpr>(dstLocator->getAnchor ());
1254
+ // If the whole body is being ignored due to a pre-check failure,
1255
+ // let's not record a fix about result type since there is
1256
+ // just not enough context to infer it without a body.
1257
+ if (cs.hasFixFor (cs.getConstraintLocator (closure->getBody ()),
1258
+ FixKind::IgnoreInvalidFunctionBuilderBody))
1259
+ return None;
1260
+
1261
+ ConstraintFix *fix = SpecifyClosureReturnType::create (cs, dstLocator);
1262
+ return std::make_pair (fix, defaultImpact);
1263
+ }
1264
+
1265
+ if (srcLocator->directlyAt <ObjectLiteralExpr>()) {
1266
+ ConstraintFix *fix = SpecifyObjectLiteralTypeImport::create (cs, dstLocator);
1267
+ return std::make_pair (fix, defaultImpact);
1268
+ }
1269
+
1270
+ if (srcLocator->isKeyPathRoot ()) {
1271
+ // If we recorded an invalid key path fix, let's skip this specify root
1272
+ // type fix because it wouldn't produce a useful diagnostic.
1273
+ auto *kpLocator = cs.getConstraintLocator (srcLocator->getAnchor ());
1274
+ if (cs.hasFixFor (kpLocator, FixKind::AllowKeyPathWithoutComponents))
1275
+ return None;
1276
+
1277
+ ConstraintFix *fix = SpecifyKeyPathRootType::create (cs, dstLocator);
1278
+ return std::make_pair (fix, defaultImpact);
1279
+ }
1280
+
1281
+ if (dstLocator->directlyAt <NilLiteralExpr>()) {
1282
+ // This is a dramatic event, it means that there is absolutely
1283
+ // no contextual information to resolve type of `nil`.
1284
+ ConstraintFix *fix = SpecifyContextualTypeForNil::create (cs, dstLocator);
1285
+ return std::make_pair (fix, /* impact=*/ (unsigned )10 );
1286
+ }
1287
+
1288
+ return None;
1289
+ }
1290
+
1220
1291
bool TypeVariableBinding::attempt (ConstraintSystem &cs) const {
1221
1292
auto type = Binding.BindingType ;
1222
1293
auto *srcLocator = Binding.getLocator ();
@@ -1238,56 +1309,10 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
1238
1309
// resolved and had to be bound to a placeholder "hole" type.
1239
1310
cs.increaseScore (SK_Hole);
1240
1311
1241
- ConstraintFix *fix = nullptr ;
1242
- unsigned fixImpact = 1 ;
1243
-
1244
- if (auto *GP = TypeVar->getImpl ().getGenericParameter ()) {
1245
- // If it is represetative for a key path root, let's emit a more
1246
- // specific diagnostic.
1247
- auto *keyPathRoot =
1248
- cs.isRepresentativeFor (TypeVar, ConstraintLocator::KeyPathRoot);
1249
- if (keyPathRoot) {
1250
- fix = SpecifyKeyPathRootType::create (
1251
- cs, keyPathRoot->getImpl ().getLocator ());
1252
- } else {
1253
- auto path = dstLocator->getPath ();
1254
- // Drop `generic parameter` locator element so that all missing
1255
- // generic parameters related to the same path can be coalesced later.
1256
- fix = DefaultGenericArgument::create (
1257
- cs, GP,
1258
- cs.getConstraintLocator (dstLocator->getAnchor (),
1259
- path.drop_back ()));
1260
- }
1261
- } else if (TypeVar->getImpl ().isClosureParameterType ()) {
1262
- fix = SpecifyClosureParameterType::create (cs, dstLocator);
1263
- } else if (TypeVar->getImpl ().isClosureResultType ()) {
1264
- auto *locator = TypeVar->getImpl ().getLocator ();
1265
- auto *closure = castToExpr<ClosureExpr>(locator->getAnchor ());
1266
- // If the whole body is being ignored due to a pre-check failure,
1267
- // let's not record a fix about result type since there is
1268
- // just not enough context to infer it without a body.
1269
- if (!cs.hasFixFor (cs.getConstraintLocator (closure->getBody ()),
1270
- FixKind::IgnoreInvalidFunctionBuilderBody))
1271
- fix = SpecifyClosureReturnType::create (cs, dstLocator);
1272
- } else if (srcLocator->directlyAt <ObjectLiteralExpr>()) {
1273
- fix = SpecifyObjectLiteralTypeImport::create (cs, dstLocator);
1274
- } else if (srcLocator->isKeyPathRoot ()) {
1275
- // If we recorded an invalid key path fix, let's skip this specify root
1276
- // type fix because it wouldn't produce a useful diagnostic.
1277
- auto *kpLocator = cs.getConstraintLocator (srcLocator->getAnchor ());
1278
- if (cs.hasFixFor (kpLocator, FixKind::AllowKeyPathWithoutComponents))
1312
+ if (auto fix = fixForHole (cs)) {
1313
+ if (cs.recordFix (/* fix=*/ fix->first , /* impact=*/ fix->second ))
1279
1314
return true ;
1280
-
1281
- fix = SpecifyKeyPathRootType::create (cs, dstLocator);
1282
- } else if (dstLocator->directlyAt <NilLiteralExpr>()) {
1283
- fix = SpecifyContextualTypeForNil::create (cs, dstLocator);
1284
- // This is a dramatic event, it means that there is absolutely
1285
- // no contextual information to resolve type of `nil`.
1286
- fixImpact = 10 ;
1287
1315
}
1288
-
1289
- if (fix && cs.recordFix (fix, fixImpact))
1290
- return true ;
1291
1316
}
1292
1317
}
1293
1318
0 commit comments