@@ -6516,52 +6516,74 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
65166516 }
65176517 }
65186518
6519+ // Handle "from specific" coercions before "catch all" coercions.
6520+ auto desugaredFromType = fromType->getDesugaredType ();
6521+ switch (desugaredFromType->getKind ()) {
65196522 // Coercions from an lvalue: load or perform implicit address-of. We perform
65206523 // these coercions first because they are often the first step in a multi-step
65216524 // coercion.
6522- if ( auto fromLValue = fromType-> getAs <LValueType>()) {
6523- if ( auto *toIO = toType-> getAs <InOutType>()) {
6524- // In an 'inout' operator like "i += 1", the operand is converted from
6525- // an implicit lvalue to an inout argument.
6526- assert (toIO-> getObjectType ()-> isEqual (fromLValue-> getObjectType ()) );
6527- return cs. cacheType ( new (tc. Context )
6528- InOutExpr (expr-> getStartLoc (), expr,
6529- toIO-> getObjectType (),
6530- /* isImplicit */ true ));
6531- }
6532-
6533- return coerceToType ( addImplicitLoadExpr (cs, expr), toType, locator );
6525+ case TypeKind::LValue: {
6526+ auto fromLValue = cast<LValueType>(desugaredFromType);
6527+ auto toIO = toType-> getAs <InOutType>();
6528+ if (!toIO)
6529+ return coerceToType ( addImplicitLoadExpr (cs, expr), toType, locator );
6530+
6531+ // In an 'inout' operator like "i += 1", the operand is converted from
6532+ // an implicit lvalue to an inout argument.
6533+ assert (toIO-> getObjectType ()-> isEqual (fromLValue-> getObjectType () ));
6534+ return cs. cacheType ( new (tc. Context ) InOutExpr (expr-> getStartLoc (), expr,
6535+ toIO-> getObjectType (),
6536+ /* isImplicit */ true ) );
65346537 }
65356538
6536- // Coercions to tuple type.
6537- if (auto toTuple = toType->getAs <TupleType>()) {
6538- // Coerce from a tuple to a tuple.
6539- if (auto fromTuple = fromType->getAs <TupleType>()) {
6540- SmallVector<unsigned , 4 > sources;
6541- if (!computeTupleShuffle (fromTuple, toTuple, sources)) {
6542- return coerceTupleToTuple (expr, fromTuple, toTuple,
6543- locator, sources);
6544- }
6539+ // Coerce from a tuple to a tuple.
6540+ case TypeKind::Tuple: {
6541+ auto fromTuple = cast<TupleType>(desugaredFromType);
6542+ auto toTuple = toType->getAs <TupleType>();
6543+ if (!toTuple)
6544+ break ;
6545+ SmallVector<unsigned , 4 > sources;
6546+ if (!computeTupleShuffle (fromTuple, toTuple, sources)) {
6547+ return coerceTupleToTuple (expr, fromTuple, toTuple,
6548+ locator, sources);
65456549 }
6550+ break ;
65466551 }
65476552
6553+ case TypeKind::PrimaryArchetype:
6554+ case TypeKind::OpenedArchetype:
6555+ case TypeKind::NestedArchetype:
6556+ if (!cast<ArchetypeType>(desugaredFromType)->requiresClass ())
6557+ break ;
6558+ LLVM_FALLTHROUGH;
6559+
65486560 // Coercion from a subclass to a superclass.
65496561 //
65506562 // FIXME: Can we rig things up so that we always have a Superclass
65516563 // conversion restriction in this case?
6552- if (fromType->mayHaveSuperclass () &&
6553- toType->getClassOrBoundGenericClass ()) {
6564+ case TypeKind::DynamicSelf:
6565+ case TypeKind::BoundGenericClass:
6566+ case TypeKind::Class: {
6567+ if (!toType->getClassOrBoundGenericClass ())
6568+ break ;
65546569 for (auto fromSuperClass = fromType->getSuperclass ();
65556570 fromSuperClass;
65566571 fromSuperClass = fromSuperClass->getSuperclass ()) {
65576572 if (fromSuperClass->isEqual (toType)) {
65586573 return coerceSuperclass (expr, toType, locator);
65596574 }
65606575 }
6576+ break ;
65616577 }
65626578
6563- // Coercions to function type.
6564- if (auto toFunc = toType->getAs <FunctionType>()) {
6579+ // Coercion from one function type to another, this produces a
6580+ // FunctionConversionExpr in its full generality.
6581+ case TypeKind::Function: {
6582+ auto fromFunc = cast<FunctionType>(desugaredFromType);
6583+ auto toFunc = toType->getAs <FunctionType>();
6584+ if (!toFunc)
6585+ break ;
6586+
65656587 // Default argument generator must return escaping functions. Therefore, we
65666588 // leave an explicit escape to noescape cast here such that SILGen can skip
65676589 // the cast and emit a code for the escaping function.
@@ -6570,49 +6592,52 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
65706592 isInDefaultArgumentContext = (initalizerCtx->getInitializerKind () ==
65716593 InitializerKind::DefaultArgument);
65726594 auto toEI = toFunc->getExtInfo ();
6573- // Coercion from one function type to another, this produces a
6574- // FunctionConversionExpr in its full generality.
6575- if (auto fromFunc = fromType->getAs <FunctionType>()) {
6576- assert (toType->is <FunctionType>());
6577- // If we have a ClosureExpr, then we can safely propagate the 'no escape'
6578- // bit to the closure without invalidating prior analysis.
6579- auto fromEI = fromFunc->getExtInfo ();
6580- if (toEI.isNoEscape () && !fromEI.isNoEscape ()) {
6581- auto newFromFuncType = fromFunc->withExtInfo (fromEI.withNoEscape ());
6582- if (!isInDefaultArgumentContext &&
6583- applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
6584- fromFunc = newFromFuncType->castTo <FunctionType>();
6585- // Propagating the 'no escape' bit might have satisfied the entire
6586- // conversion. If so, we're done, otherwise keep converting.
6587- if (fromFunc->isEqual (toType))
6588- return expr;
6589- } else if (isInDefaultArgumentContext) {
6590- // First apply the conversion *without* noescape attribute.
6591- if (!newFromFuncType->isEqual (toType)) {
6592- auto escapingToFuncTy =
6593- toFunc->withExtInfo (toEI.withNoEscape (false ));
6594- maybeDiagnoseUnsupportedFunctionConversion (cs, expr, toFunc);
6595- expr = cs.cacheType (new (tc.Context ) FunctionConversionExpr (
6596- expr, escapingToFuncTy));
6597- }
6598- // Apply an explict function conversion *only* for the escape to
6599- // noescape conversion. This conversion will be stripped by the
6600- // default argument generator. (We can't return a @noescape function)
6601- auto newExpr = cs.cacheType (new (tc.Context )
6602- FunctionConversionExpr (expr, toFunc));
6603- return newExpr;
6595+ assert (toType->is <FunctionType>());
6596+ // If we have a ClosureExpr, then we can safely propagate the 'no escape'
6597+ // bit to the closure without invalidating prior analysis.
6598+ auto fromEI = fromFunc->getExtInfo ();
6599+ if (toEI.isNoEscape () && !fromEI.isNoEscape ()) {
6600+ auto newFromFuncType = fromFunc->withExtInfo (fromEI.withNoEscape ());
6601+ if (!isInDefaultArgumentContext &&
6602+ applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
6603+ fromFunc = newFromFuncType->castTo <FunctionType>();
6604+ // Propagating the 'no escape' bit might have satisfied the entire
6605+ // conversion. If so, we're done, otherwise keep converting.
6606+ if (fromFunc->isEqual (toType))
6607+ return expr;
6608+ } else if (isInDefaultArgumentContext) {
6609+ // First apply the conversion *without* noescape attribute.
6610+ if (!newFromFuncType->isEqual (toType)) {
6611+ auto escapingToFuncTy =
6612+ toFunc->withExtInfo (toEI.withNoEscape (false ));
6613+ maybeDiagnoseUnsupportedFunctionConversion (cs, expr, toFunc);
6614+ expr = cs.cacheType (new (tc.Context ) FunctionConversionExpr (
6615+ expr, escapingToFuncTy));
66046616 }
6617+ // Apply an explict function conversion *only* for the escape to
6618+ // noescape conversion. This conversion will be stripped by the
6619+ // default argument generator. (We can't return a @noescape function)
6620+ auto newExpr = cs.cacheType (new (tc.Context )
6621+ FunctionConversionExpr (expr, toFunc));
6622+ return newExpr;
66056623 }
6624+ }
66066625
6607- maybeDiagnoseUnsupportedFunctionConversion (cs, expr, toFunc);
6626+ maybeDiagnoseUnsupportedFunctionConversion (cs, expr, toFunc);
66086627
6609- return cs.cacheType (new (tc.Context )
6610- FunctionConversionExpr (expr, toType));
6611- }
6628+ return cs.cacheType (new (tc.Context )
6629+ FunctionConversionExpr (expr, toType));
66126630 }
66136631
6614- // Coercions from metadata to objects.
6615- if (auto fromMeta = fromType->getAs <AnyMetatypeType>()) {
6632+ // Coercions from one metatype to another.
6633+ case TypeKind::Metatype: {
6634+ if (auto toMeta = toType->getAs <MetatypeType>())
6635+ return cs.cacheType (new (tc.Context ) MetatypeConversionExpr (expr, toMeta));
6636+ LLVM_FALLTHROUGH;
6637+ }
6638+ // Coercions from metatype to objects.
6639+ case TypeKind::ExistentialMetatype: {
6640+ auto fromMeta = cast<AnyMetatypeType>(desugaredFromType);
66166641 if (toType->isAnyObject ()) {
66176642 assert (cs.getASTContext ().LangOpts .EnableObjCInterop
66186643 && " metatype-to-object conversion requires objc interop" );
@@ -6648,39 +6673,46 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
66486673 new (tc.Context ) ProtocolMetatypeToObjectExpr (expr, toType));
66496674 }
66506675 }
6651- }
66526676
6653- // Coercions from a type to an existential type.
6654- if (toType->isAnyExistentialType ()) {
6655- return coerceExistential (expr, toType, locator);
6677+ break ;
66566678 }
66576679
6658- if (toType->getOptionalObjectType () &&
6659- cs.getType (expr)->getOptionalObjectType ()) {
6660- return coerceOptionalToOptional (expr, toType, locator, typeFromPattern);
6680+ default :
6681+ break ;
66616682 }
66626683
6684+ // "Catch all" coercions.
6685+ auto desugaredToType = toType->getDesugaredType ();
6686+ switch (desugaredToType->getKind ()) {
6687+ // Coercions from a type to an existential type.
6688+ case TypeKind::ExistentialMetatype:
6689+ case TypeKind::ProtocolComposition:
6690+ case TypeKind::Protocol: {
6691+ return coerceExistential (expr, toType, locator);
6692+
66636693 // Coercion to Optional<T>.
6664- if (auto toGenericType = toType->getAs <BoundGenericType>()) {
6665- if (toGenericType->getDecl ()->isOptionalDecl ()) {
6666- tc.requireOptionalIntrinsics (expr->getLoc ());
6694+ case TypeKind::BoundGenericEnum: {
6695+ auto toGenericType = cast<BoundGenericEnumType>(desugaredToType);
6696+ if (!toGenericType->getDecl ()->isOptionalDecl ())
6697+ break ;
6698+ tc.requireOptionalIntrinsics (expr->getLoc ());
66676699
6668- Type valueType = toGenericType->getGenericArgs ()[0 ];
6669- expr = coerceToType (expr, valueType, locator);
6670- if (!expr) return nullptr ;
6700+ if (cs.getType (expr)->getOptionalObjectType ())
6701+ return coerceOptionalToOptional (expr, toType, locator, typeFromPattern);
66716702
6672- auto *result =
6673- cs.cacheType (new (tc.Context ) InjectIntoOptionalExpr (expr, toType));
6674- diagnoseOptionalInjection (result);
6675- return result;
6676- }
6703+ Type valueType = toGenericType->getGenericArgs ()[0 ];
6704+ expr = coerceToType (expr, valueType, locator);
6705+ if (!expr) return nullptr ;
6706+
6707+ auto *result =
6708+ cs.cacheType (new (tc.Context ) InjectIntoOptionalExpr (expr, toType));
6709+ diagnoseOptionalInjection (result);
6710+ return result;
6711+ }
66776712 }
66786713
6679- // Coercion from one metatype to another.
6680- if (fromType->is <MetatypeType>() &&
6681- toType->is <MetatypeType>()) {
6682- auto toMeta = toType->castTo <MetatypeType>();
6683- return cs.cacheType (new (tc.Context ) MetatypeConversionExpr (expr, toMeta));
6714+ default :
6715+ break ;
66846716 }
66856717
66866718 // Unresolved types come up in diagnostics for lvalue and inout types.
0 commit comments