compiler/resolution/functionResolution.cpp
//
// returns true iff dispatching the actualType to the formalType
// results in a coercion.
//
// fn is the function being called usually but in resolveReturnType it
// is the function we're finding return types for.
returns true iff dispatching the actualType to the formalType
results in a coercion.

fn is the function being called usually but in resolveReturnType it
is the function we're finding return types for.
returns true iff dispatching the actualType to the formalType results in a coercion . fn is the function being called usually but in resolveReturnType it is the function we ' re finding return types for .
bool canCoerce(Type*     actualType,
               Symbol*   actualSym,
               Type*     formalType,
               FnSymbol* fn,
               bool*     promotes,
               bool*     paramNarrows) {
  bool tmpParamNarrows = false;
  if (canParamCoerce(actualType, actualSym, formalType, &tmpParamNarrows)) {
    if (paramNarrows) *paramNarrows = tmpParamNarrows;
    return true;
  }
  if (isSyncType(actualType) || isSingleType(actualType)) {
    Type* baseType = actualType->getField("valType")->type;
    return canDispatch(baseType, NULL, formalType, fn);
  }
  if (isManagedPtrType(actualType)) {
    Type* actualBaseType = getManagedPtrBorrowType(actualType);
    AggregateType* actualOwnedShared = toAggregateType(actualType);
    while (actualOwnedShared && actualOwnedShared->instantiatedFrom != NULL)
      actualOwnedShared = actualOwnedShared->instantiatedFrom;
    Type* formalBaseType = NULL;
    AggregateType* formalOwnedShared = toAggregateType(formalType);
    bool formalIsClass = false;
    if (isManagedPtrType(formalType)) {
      formalBaseType = getManagedPtrBorrowType(formalType);
      while (formalOwnedShared && formalOwnedShared->instantiatedFrom != NULL)
        formalOwnedShared = formalOwnedShared->instantiatedFrom;
    } else if (AggregateType* formalAt = toAggregateType(formalType)) {
      formalIsClass = formalAt->isClass();
    }
    if (isManagedPtrType(formalType) &&
        actualOwnedShared == formalOwnedShared) {
      return canDispatch(actualBaseType, NULL, formalBaseType, fn,
                         promotes, paramNarrows);
    } else if (formalIsClass) {
      return canDispatch(actualBaseType, NULL, formalType, fn,
                         promotes, paramNarrows);
    }
  }
  if (UnmanagedClassType* actualMt = toUnmanagedClassType(actualType)) {
    if (AggregateType* formalC = toAggregateType(formalType)) {
      if (isClass(formalC)) {
        AggregateType* actualC = actualMt->getCanonicalClass();
        if (canDispatch(actualC, NULL, formalC, fn, promotes, paramNarrows))
          return true;
      }
    }
  }
  if (actualType == dtNil && isManagedPtrType(formalType)) {
    return true;
  }
  if (canCoerceTuples(actualType, actualSym, formalType, fn)) {
    return true;
  }
  if (actualType->symbol->hasFlag(FLAG_REF))
    return canDispatch(actualType->getValType(),
                       NULL,
                       formalType,
                       fn,
                       promotes);
  if (actualType->symbol->hasFlag(FLAG_C_PTR_CLASS) &&
      (formalType == dtCVoidPtr))
    return true;
  return false;
}
bool canCoerce ( Type * actualType , Symbol * actualSym , Type * formalType , FnSymbol * fn , bool * promotes , bool * paramNarrows ) { bool tmpParamNarrows = false ; if ( canParamCoerce ( actualType , actualSym , formalType , & tmpParamNarrows ) ) { if ( paramNarrows ) * paramNarrows = tmpParamNarrows ; return true ; } if ( isSyncType ( actualType ) || isSingleType ( actualType ) ) { Type * baseType = actualType -> getField ( " " ) -> type ; return canDispatch ( baseType , NULL , formalType , fn ) ; } if ( isManagedPtrType ( actualType ) ) { Type * actualBaseType = getManagedPtrBorrowType ( actualType ) ; AggregateType * actualOwnedShared = toAggregateType ( actualType ) ; while ( actualOwnedShared && actualOwnedShared -> instantiatedFrom != NULL ) actualOwnedShared = actualOwnedShared -> instantiatedFrom ; Type * formalBaseType = NULL ; AggregateType * formalOwnedShared = toAggregateType ( formalType ) ; bool formalIsClass = false ; if ( isManagedPtrType ( formalType ) ) { formalBaseType = getManagedPtrBorrowType ( formalType ) ; while ( formalOwnedShared && formalOwnedShared -> instantiatedFrom != NULL ) formalOwnedShared = formalOwnedShared -> instantiatedFrom ; } else if ( AggregateType * formalAt = toAggregateType ( formalType ) ) { formalIsClass = formalAt -> isClass ( ) ; } if ( isManagedPtrType ( formalType ) && actualOwnedShared == formalOwnedShared ) { return canDispatch ( actualBaseType , NULL , formalBaseType , fn , promotes , paramNarrows ) ; } else if ( formalIsClass ) { return canDispatch ( actualBaseType , NULL , formalType , fn , promotes , paramNarrows ) ; } } if ( UnmanagedClassType * actualMt = toUnmanagedClassType ( actualType ) ) { if ( AggregateType * formalC = toAggregateType ( formalType ) ) { if ( isClass ( formalC ) ) { AggregateType * actualC = actualMt -> getCanonicalClass ( ) ; if ( canDispatch ( actualC , NULL , formalC , fn , promotes , paramNarrows ) ) return true ; } } } if ( actualType == dtNil && isManagedPtrType ( formalType ) ) { return true ; } if ( canCoerceTuples ( actualType , actualSym , formalType , fn ) ) { return true ; } if ( actualType -> symbol -> hasFlag ( FLAG_REF ) ) return canDispatch ( actualType -> getValType ( ) , NULL , formalType , fn , promotes ) ; if ( actualType -> symbol -> hasFlag ( FLAG_C_PTR_CLASS ) && ( formalType == dtCVoidPtr ) ) return true ; return false ; }
returns true iff dispatching the actualType to the formalType
results in a coercion.
returns true iff dispatching the actualType to the formalType results in a coercion .
// sync can't store an array or a param, so no need to // propagate promotes / paramNarrows // e.g. Owned(Child) coerces to Owned(Parent) // e.g. Owned(SomeClass) to SomeClass (borrow type) // Handle coercions from unmanaged -> borrow // Handle coercions nil -> owned/shared // ref can't store a param, so no need to propagate paramNarrows // MPF: Should this be formalType->getValType() ?