@@ -336,3 +336,62 @@ TEST_F(SemaTest, TestTransitiveProtocolInferenceThroughEquivalenceChains) {
336336 verifyProtocolInferenceResults (*bindings.TransitiveProtocols ,
337337 {protocolTy0, protocolTy1});
338338}
339+
340+ TEST_F (SemaTest, TestNoDoubleVoidClosureResultInference) {
341+ ConstraintSystemOptions options;
342+ ConstraintSystem cs (DC, options);
343+
344+ auto verifyInference = [&](TypeVariableType *typeVar, unsigned numExpected) {
345+ auto bindings = cs.getBindingsFor (typeVar);
346+ TypeVarBindingProducer producer (bindings);
347+
348+ llvm::SmallPtrSet<Type, 2 > inferredTypes;
349+
350+ while (auto binding = producer ()) {
351+ ASSERT_TRUE (binding.hasValue ());
352+ ASSERT_EQ (binding->getTypeVariable (), typeVar);
353+ ASSERT_TRUE (inferredTypes.insert (binding->getType ()).second );
354+ }
355+
356+ ASSERT_EQ (inferredTypes.size (), numExpected);
357+ };
358+
359+ auto *closureResultLoc =
360+ cs.getConstraintLocator ({}, ConstraintLocator::ClosureResult);
361+
362+ auto *closureResult = cs.createTypeVariable (closureResultLoc, /* options=*/ 0 );
363+
364+ cs.addConstraint (ConstraintKind::Subtype, getStdlibType (" Int" ), closureResult,
365+ closureResultLoc);
366+ cs.addConstraint (ConstraintKind::Subtype, closureResult, getStdlibType (" Void" ),
367+ closureResultLoc);
368+
369+ verifyInference (closureResult, 2 );
370+
371+ auto closureResultWithTransitiveVoid = cs.createTypeVariable (closureResultLoc,
372+ /* options=*/ 0 );
373+
374+ auto contextualVar = cs.createTypeVariable ({}, /* options=*/ 0 );
375+
376+ cs.addConstraint (ConstraintKind::Subtype, getStdlibType (" Void" ),
377+ contextualVar, cs.getConstraintLocator ({}));
378+
379+ cs.addConstraint (ConstraintKind::Subtype, contextualVar,
380+ closureResultWithTransitiveVoid, closureResultLoc);
381+
382+ cs.addConstraint (ConstraintKind::Subtype, getStdlibType (" Int" ),
383+ closureResultWithTransitiveVoid, closureResultLoc);
384+
385+ verifyInference (closureResultWithTransitiveVoid, 2 );
386+
387+ auto closureResultWithoutVoid =
388+ cs.createTypeVariable (closureResultLoc, /* options=*/ 0 );
389+
390+ // Supertype triggers `Void` inference
391+ cs.addConstraint (ConstraintKind::Subtype, getStdlibType (" Int" ),
392+ closureResultWithoutVoid, closureResultLoc);
393+ cs.addConstraint (ConstraintKind::Subtype, closureResultWithoutVoid,
394+ getStdlibType (" String" ), closureResultLoc);
395+
396+ verifyInference (closureResultWithoutVoid, 3 );
397+ }
0 commit comments