@@ -3903,6 +3903,38 @@ static bool generateInitPatternConstraints(
3903
3903
return false ;
3904
3904
}
3905
3905
3906
+ static Expr *eraseTypeForDynamicReplacement (SolutionApplicationTarget target,
3907
+ Expr *expr) {
3908
+ auto purpose = target.getExprContextualTypePurpose ();
3909
+ auto *dc = target.getDeclContext ();
3910
+ auto *decl = dyn_cast_or_null<ValueDecl>(dc->getAsDecl ());
3911
+ if (!decl)
3912
+ return expr;
3913
+
3914
+ if (!(purpose == CTP_ReturnStmt || purpose == CTP_ReturnSingleExpr) ||
3915
+ !(decl->isDynamic () || decl->getDynamicallyReplacedDecl ()))
3916
+ return expr;
3917
+
3918
+ auto *opaque =
3919
+ target.getExprContextualType ()->getAs <OpaqueTypeArchetypeType>();
3920
+ if (!opaque)
3921
+ return expr;
3922
+
3923
+ auto protocols = opaque->getConformsTo ();
3924
+ if (protocols.size () != 1 )
3925
+ return expr;
3926
+
3927
+ auto *attr = protocols.front ()->getAttrs ().getAttribute <TypeEraserAttr>();
3928
+ if (!attr)
3929
+ return expr;
3930
+
3931
+ auto typeEraser = attr->getTypeEraserLoc ().getType ();
3932
+ auto &ctx = dc->getASTContext ();
3933
+ return CallExpr::createImplicit (ctx,
3934
+ TypeExpr::createImplicit (typeEraser, ctx),
3935
+ {expr}, {ctx.Id_erasing });
3936
+ }
3937
+
3906
3938
bool ConstraintSystem::generateConstraints (
3907
3939
SolutionApplicationTarget &target,
3908
3940
FreeTypeVariableBinding allowFreeTypeVariables) {
@@ -3919,6 +3951,8 @@ bool ConstraintSystem::generateConstraints(
3919
3951
target.setExprConversionType (TypeChecker::getOptionalType (expr->getLoc (), var));
3920
3952
}
3921
3953
3954
+ expr = eraseTypeForDynamicReplacement (target, expr);
3955
+
3922
3956
// Generate constraints for the main system.
3923
3957
expr = generateConstraints (expr, target.getDeclContext ());
3924
3958
if (!expr)
0 commit comments