Changeset 2162c2c for src/ResolvExpr


Ignore:
Timestamp:
Jan 11, 2017, 4:11:02 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
075734f
Parents:
bb82c03 (diff), d3a85240 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AdjustExprType.cc

    rbb82c03 r2162c2c  
    2222        class AdjustExprType : public Mutator {
    2323                typedef Mutator Parent;
     24                using Parent::mutate;
    2425          public:
    2526                AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
  • src/ResolvExpr/AlternativeFinder.cc

    rbb82c03 r2162c2c  
    267267                std::list< Expression* >& actuals = appExpr->get_args();
    268268
    269                 std::list< Type * > formalTypes;
    270                 std::list< Type * >::iterator formalType = formalTypes.end();
    271 
    272269                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    273 
     270                        Type * actualType = (*actualExpr)->get_result();
    274271                        PRINT(
    275272                                std::cerr << "actual expression:" << std::endl;
    276273                                (*actualExpr)->print( std::cerr, 8 );
    277274                                std::cerr << "--- results are" << std::endl;
    278                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
    279                         )
    280                         std::list< DeclarationWithType* >::iterator startFormal = formal;
     275                                actualType->print( std::cerr, 8 );
     276                        )
    281277                        Cost actualCost;
    282                         std::list< Type * > flatActualTypes;
    283                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    284                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    285 
    286 
    287                                 // tuple handling code
    288                                 if ( formalType == formalTypes.end() ) {
    289                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    290                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    291                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    292                                         // been exhausted load the next formal parameter's type.
    293                                         if ( formal == formals.end() ) {
    294                                                 if ( function->get_isVarArgs() ) {
    295                                                         convCost += Cost( 1, 0, 0 );
    296                                                         break;
    297                                                 } else {
    298                                                         return Cost::infinity;
    299                                                 }
    300                                         }
    301                                         formalTypes.clear();
    302                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    303                                         formalType = formalTypes.begin();
    304                                         ++formal;
     278                        if ( formal == formals.end() ) {
     279                                if ( function->get_isVarArgs() ) {
     280                                        convCost += Cost( 1, 0, 0 );
     281                                        continue;
     282                                } else {
     283                                        return Cost::infinity;
    305284                                }
    306 
    307                                 PRINT(
    308                                         std::cerr << std::endl << "converting ";
    309                                         (*actualType)->print( std::cerr, 8 );
    310                                         std::cerr << std::endl << " to ";
    311                                         (*formalType)->print( std::cerr, 8 );
    312                                 )
    313                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    314                                 PRINT(
    315                                         std::cerr << std::endl << "cost is" << newCost << std::endl;
    316                                 )
    317 
    318                                 if ( newCost == Cost::infinity ) {
    319                                         return newCost;
    320                                 }
    321                                 convCost += newCost;
    322                                 actualCost += newCost;
    323 
    324                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    325 
    326                                 formalType++;
    327                         }
     285                        }
     286                        Type * formalType = (*formal)->get_type();
     287                        PRINT(
     288                                std::cerr << std::endl << "converting ";
     289                                actualType->print( std::cerr, 8 );
     290                                std::cerr << std::endl << " to ";
     291                                formalType->print( std::cerr, 8 );
     292                        )
     293                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     294                        PRINT(
     295                                std::cerr << std::endl << "cost is" << newCost << std::endl;
     296                        )
     297
     298                        if ( newCost == Cost::infinity ) {
     299                                return newCost;
     300                        }
     301                        convCost += newCost;
     302                        actualCost += newCost;
    328303                        if ( actualCost != Cost( 0, 0, 0 ) ) {
    329                                 std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
    330                                 startFormalPlusOne++;
    331                                 if ( formal == startFormalPlusOne ) {
    332                                         // not a tuple type
    333                                         Type *newType = (*startFormal)->get_type()->clone();
    334                                         alt.env.apply( newType );
    335                                         *actualExpr = new CastExpr( *actualExpr, newType );
    336                                 } else {
    337                                         TupleType *newType = new TupleType( Type::Qualifiers() );
    338                                         for ( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
    339                                                 newType->get_types().push_back( (*i)->get_type()->clone() );
    340                                         }
    341                                         alt.env.apply( newType );
    342                                         *actualExpr = new CastExpr( *actualExpr, newType );
    343                                 }
    344                         }
    345 
     304                                Type *newType = formalType->clone();
     305                                alt.env.apply( newType );
     306                                *actualExpr = new CastExpr( *actualExpr, newType );
     307                        }
     308                        convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
     309                        ++formal; // can't be in for-loop update because of the continue
    346310                }
    347311                if ( formal != formals.end() ) {
     
    364328                        }
    365329                        convCost += newCost;
    366 
    367330                        convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
    368331                }
     
    376339                        unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar };
    377340                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    378                                 needAssertions[ *assert ] = true;
     341                                needAssertions[ *assert ].isUsed = true;
    379342                        }
    380343///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
     
    388351                if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    389352                        // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    390                         TupleExpr * tupleExpr = new TupleExpr();
     353                        std::list< Expression * > exprs;
    391354                        for ( Type * type : *tupleType ) {
    392                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
    393                                         delete tupleExpr;
     355                                if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {
     356                                        deleteAll( exprs );
    394357                                        return false;
    395358                                }
    396359                        }
    397                         tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
    398                         *out++ = tupleExpr;
     360                        *out++ = new TupleExpr( exprs );
     361                } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
     362                        // xxx - mixing default arguments with variadic??
     363                        std::list< Expression * > exprs;
     364                        for ( ; actualIt != actualEnd; ++actualIt ) {
     365                                exprs.push_back( actualIt->expr->clone() );
     366                                cost += actualIt->cost;
     367                        }
     368                        Expression * arg = nullptr;
     369                        if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {
     370                                // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes
     371                                // xxx - what if passing multiple arguments, last of which is ttype?
     372                                // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.
     373                                arg = exprs.front();
     374                        } else {
     375                                arg = new TupleExpr( exprs );
     376                        }
     377                        assert( arg && arg->get_result() );
     378                        if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     379                                return false;
     380                        }
     381                        *out++ = arg;
    399382                } else if ( actualIt != actualEnd ) {
    400383                        // both actualType and formalType are atomic (non-tuple) types - if they unify
     
    483466        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    484467                for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    485                         if ( i->second == true ) {
     468                        if ( i->second.isUsed ) {
    486469                                i->first->accept( indexer );
    487470                        }
     
    494477                if ( begin == end ) {
    495478                        if ( newNeed.empty() ) {
     479                                PRINT(
     480                                        std::cerr << "all assertions satisfied, output alternative: ";
     481                                        newAlt.print( std::cerr );
     482                                        std::cerr << std::endl;
     483                                );
    496484                                *out++ = newAlt;
    497485                                return;
     
    510498
    511499                ForwardIterator cur = begin++;
    512                 if ( ! cur->second ) {
     500                if ( ! cur->second.isUsed ) {
    513501                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    514502                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
     
    554542                                assert( (*candidate)->get_uniqueId() );
    555543                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
     544
     545                                // everything with an empty idChain was pulled in by the current assertion.
     546                                // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
     547                                for ( auto & a : newerNeed ) {
     548                                        if ( a.second.idChain.empty() ) {
     549                                                a.second.idChain = cur->second.idChain;
     550                                                a.second.idChain.push_back( curDecl->get_uniqueId() );
     551                                        }
     552                                }
     553
    556554                                //AssertionParentSet newNeedParents( needParents );
    557555                                // skip repeatingly-self-recursive assertion satisfaction
     
    569567                                )
    570568                                ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
     569                                // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
     570                                InferredParams * inferParameters = &appExpr->get_inferParams();
     571                                for ( UniqueId id : cur->second.idChain ) {
     572                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
     573                                }
    571574                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    572                                 appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     575                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    573576                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    574577                        } else {
     
    609612                makeUnifiableVars( funcType, openVars, resultNeed );
    610613                AltList instantiatedActuals; // filled by instantiate function
    611                 if ( targetType && ! targetType->isVoid() ) {
     614                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    612615                        // attempt to narrow based on expected target type
    613616                        Type * returnType = funcType->get_returnVals().front()->get_type();
     
    10751078        }
    10761079
    1077         void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     1080        void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
    10781081                std::list< AlternativeFinder > subExprAlternatives;
    10791082                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
     
    10811084                combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    10821085                for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
    1083                         TupleExpr *newExpr = new TupleExpr;
    1084                         makeExprList( *i, newExpr->get_exprs() );
    1085                         newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
     1086                        std::list< Expression * > exprs;
     1087                        makeExprList( *i, exprs );
    10861088
    10871089                        TypeEnvironment compositeEnv;
    10881090                        simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
    1089                         alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
     1091                        alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) );
    10901092                } // for
     1093        }
     1094
     1095        void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     1096                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    10911097        }
    10921098
  • src/ResolvExpr/AlternativeFinder.h

    rbb82c03 r2162c2c  
    6464                virtual void visit( ConditionalExpr *conditionalExpr );
    6565                virtual void visit( CommaExpr *commaExpr );
    66                 virtual void visit( TupleExpr *tupleExpr );
    6766                virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
    6867                virtual void visit( ConstructorExpr * ctorExpr );
     68                virtual void visit( UntypedTupleExpr *tupleExpr );
     69                virtual void visit( TupleExpr *tupleExpr );
    6970                virtual void visit( TupleIndexExpr *tupleExpr );
    7071                virtual void visit( TupleAssignExpr *tupleExpr );
  • src/ResolvExpr/FindOpenVars.cc

    rbb82c03 r2162c2c  
    5050                                openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    5151                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    52                                         needAssertions[ *assert ] = false;
     52                                        needAssertions[ *assert ].isUsed = false;
    5353                                }
    5454///       cloneAll( (*i)->get_assertions(), needAssertions );
     
    5959                                closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    6060                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    61                                         haveAssertions[ *assert ] = false;
     61                                        haveAssertions[ *assert ].isUsed = false;
    6262                                }
    6363///       cloneAll( (*i)->get_assertions(), haveAssertions );
  • src/ResolvExpr/TypeEnvironment.cc

    rbb82c03 r2162c2c  
    7575                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
    7676                        i->first->print( os, indent );
    77                         if ( i->second ) {
     77                        if ( i->second.isUsed ) {
    7878                                os << "(used)";
    7979                        } else {
  • src/ResolvExpr/TypeEnvironment.h

    rbb82c03 r2162c2c  
    3131                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const;
    3232        };
    33         typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
     33        struct AssertionSetValue {
     34                bool isUsed;
     35                // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID of an assertion on the current type,
     36                // with each successive ID being the ID of an assertion pulled in by the previous ID. The last ID in the chain is
     37                // the ID of the assertion that pulled in the current assertion.
     38                std::list< UniqueId > idChain;
     39        };
     40        typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet;
    3441        typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
    3542
  • src/ResolvExpr/Unify.cc

    rbb82c03 r2162c2c  
    2626#include "SymTab/Indexer.h"
    2727#include "Common/utility.h"
    28 
     28#include "Tuples/Tuples.h"
    2929
    3030// #define DEBUG
     
    157157                        // if the type variable is specified to be a complete type then the incoming
    158158                        // type must also be complete
     159                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    159160                        return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
    160161                  case TypeDecl::Ftype:
    161162                        return isFtype( type, indexer );
     163                        case TypeDecl::Ttype:
     164                        // ttype unifies with any tuple type
     165                        return dynamic_cast< TupleType * >( type );
    162166                } // switch
    163                 assert( false );
    164167                return false;
    165168        }
     
    431434                if ( i != assertions.end() ) {
    432435///     std::cerr << "found it!" << std::endl;
    433                         i->second = true;
     436                        i->second.isUsed = true;
    434437                } // if
    435438        }
     
    485488        }
    486489
     490        template< typename Iterator >
     491        std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {
     492                std::list< Type * > types;
     493                for ( ; begin != end; ++begin ) {
     494                        // it's guaranteed that a ttype variable will be bound to a flat tuple, so ensure that this results in a flat tuple
     495                        flatten( (*begin)->get_type(), back_inserter( types ) );
     496                }
     497                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
     498        }
     499
    487500        template< typename Iterator1, typename Iterator2 >
    488501        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    489502                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    490                         // Type * commonType;
    491                         // if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
    492                         if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
     503                        Type * t1 = (*list1Begin)->get_type();
     504                        Type * t2 = (*list2Begin)->get_type();
     505                        bool isTtype1 = Tuples::isTtype( t1 );
     506                        bool isTtype2 = Tuples::isTtype( t2 );
     507                        // xxx - assumes ttype must be last parameter
     508                        // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases.
     509                        if ( isTtype1 && ! isTtype2 ) {
     510                                // combine all of the things in list2, then unify
     511                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     512                        } else if ( isTtype2 && ! isTtype1 ) {
     513                                // combine all of the things in list1, then unify
     514                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     515                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    493516                                return false;
    494517                        } // if
    495518                } // for
    496                 if ( list1Begin != list1End || list2Begin != list2End ) {
    497                         return false;
     519                // may get to the end of one argument list before the end of the other. This is only okay when the other is a ttype
     520                if ( list1Begin != list1End ) {
     521                        // try unifying empty tuple type with ttype
     522                        Type * t1 = (*list1Begin)->get_type();
     523                        if ( Tuples::isTtype( t1 ) ) {
     524                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     525                        } else return false;
     526                } else if ( list2Begin != list2End ) {
     527                        // try unifying empty tuple type with ttype
     528                        Type * t2 = (*list2Begin)->get_type();
     529                        if ( Tuples::isTtype( t2 ) ) {
     530                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     531                        } else return false;
    498532                } else {
    499533                        return true;
    500534                } // if
     535        }
     536
     537        /// Finds ttypes and replaces them with their expansion, if known.
     538        /// This needs to be done so that satisfying ttype assertions is easier.
     539        /// If this isn't done then argument lists can have wildly different
     540        /// size and structure, when they should be compatible.
     541        struct TtypeExpander : public Mutator {
     542                TypeEnvironment & env;
     543                TtypeExpander( TypeEnvironment & env ) : env( env ) {}
     544                Type * mutate( TypeInstType * typeInst ) {
     545                        EqvClass eqvClass;
     546                        if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     547                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
     548                                        // expand ttype parameter into its actual type
     549                                        if ( eqvClass.type ) {
     550                                                delete typeInst;
     551                                                return eqvClass.type->clone();
     552                                        }
     553                                }
     554                        }
     555                        return typeInst;
     556                }
     557        };
     558
     559        /// flattens a list of declarations, so that each tuple type has a single declaration.
     560        /// makes use of TtypeExpander to ensure ttypes are flat as well.
     561        void flattenList( std::list< DeclarationWithType * > src, std::list< DeclarationWithType * > & dst, TypeEnvironment & env ) {
     562                dst.clear();
     563                for ( DeclarationWithType * dcl : src ) {
     564                        TtypeExpander expander( env );
     565                        dcl->acceptMutator( expander );
     566                        std::list< Type * > types;
     567                        flatten( dcl->get_type(), back_inserter( types ) );
     568                        for ( Type * t : types ) {
     569                                dst.push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t, nullptr ) );
     570                        }
     571                        delete dcl;
     572                }
    501573        }
    502574
     
    504576                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    505577                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
    506                         if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) {
    507                                 if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    508                                         if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    509 
     578                        // flatten the parameter lists for both functions so that tuple structure
     579                        // doesn't affect unification. Must be a clone so that the types don't change.
     580                        std::unique_ptr<FunctionType> flatFunc( functionType->clone() );
     581                        std::unique_ptr<FunctionType> flatOther( otherFunction->clone() );
     582                        flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env );
     583                        flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env );
     584
     585                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
     586                        if ( (flatFunc->get_parameters().size() == flatOther->get_parameters().size() && flatFunc->get_returnVals().size() == flatOther->get_returnVals().size()) || flatFunc->isTtype() || flatOther->isTtype() ) {
     587                                if ( unifyDeclList( flatFunc->get_parameters().begin(), flatFunc->get_parameters().end(), flatOther->get_parameters().begin(), flatOther->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     588                                        if ( unifyDeclList( flatFunc->get_returnVals().begin(), flatFunc->get_returnVals().end(), flatOther->get_returnVals().begin(), flatOther->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     589
     590                                                // the original types must be used in mark assertions, since pointer comparisons are used
    510591                                                markAssertions( haveAssertions, needAssertions, functionType );
    511592                                                markAssertions( haveAssertions, needAssertions, otherFunction );
  • src/ResolvExpr/typeops.h

    rbb82c03 r2162c2c  
    164164                        }
    165165                } else {
    166                         *out++ = type;
     166                        *out++ = type->clone();
    167167                }
    168168        }
Note: See TracChangeset for help on using the changeset viewer.