Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    rf3b0a07 r6c3a988f  
    163163                        case TypeDecl::Ttype:
    164164                        // ttype unifies with any tuple type
    165                         return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
     165                        return dynamic_cast< TupleType * >( type );
    166166                } // switch
    167167                return false;
     
    488488        }
    489489
    490         template< typename Iterator, typename Func >
    491         std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
     490        template< typename Iterator >
     491        std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {
    492492                std::list< Type * > types;
    493493                for ( ; begin != end; ++begin ) {
    494494                        // 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( toType( *begin ), back_inserter( types ) );
     495                        flatten( (*begin)->get_type(), back_inserter( types ) );
    496496                }
    497497                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
     
    500500        template< typename Iterator1, typename Iterator2 >
    501501        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    502                 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
    503502                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    504503                        Type * t1 = (*list1Begin)->get_type();
     
    510509                        if ( isTtype1 && ! isTtype2 ) {
    511510                                // combine all of the things in list2, then unify
    512                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     511                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    513512                        } else if ( isTtype2 && ! isTtype1 ) {
    514513                                // combine all of the things in list1, then unify
    515                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     514                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    516515                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    517516                                return false;
     
    523522                        Type * t1 = (*list1Begin)->get_type();
    524523                        if ( Tuples::isTtype( t1 ) ) {
    525                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     524                                return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    526525                        } else return false;
    527526                } else if ( list2Begin != list2End ) {
     
    529528                        Type * t2 = (*list2Begin)->get_type();
    530529                        if ( Tuples::isTtype( t2 ) ) {
    531                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     530                                return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    532531                        } else return false;
    533532                } else {
     
    666665        template< typename Iterator1, typename Iterator2 >
    667666        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    668                 auto get_type = [](Type * t) { return t; };
    669667                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    670                         Type * t1 = *list1Begin;
    671                         Type * t2 = *list2Begin;
    672                         bool isTtype1 = Tuples::isTtype( t1 );
    673                         bool isTtype2 = Tuples::isTtype( t2 );
    674                         // xxx - assumes ttype must be last parameter
    675                         // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases.
    676                         if ( isTtype1 && ! isTtype2 ) {
    677                                 // combine all of the things in list2, then unify
    678                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    679                         } else if ( isTtype2 && ! isTtype1 ) {
    680                                 // combine all of the things in list1, then unify
    681                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    682                         } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
     668                        Type *commonType = 0;
     669                        if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
    683670                                return false;
    684                         } // if
    685 
     671                        }
     672                        delete commonType;
    686673                } // for
    687                 if ( list1Begin != list1End ) {
    688                         // try unifying empty tuple type with ttype
    689                         Type * t1 = *list1Begin;
    690                         if ( Tuples::isTtype( t1 ) ) {
    691                                 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    692                         } else return false;
    693                 } else if ( list2Begin != list2End ) {
    694                         // try unifying empty tuple type with ttype
    695                         Type * t2 = *list2Begin;
    696                         if ( Tuples::isTtype( t2 ) ) {
    697                                 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    698                         } else return false;
     674                if ( list1Begin != list1End || list2Begin != list2End ) {
     675                        return false;
    699676                } else {
    700677                        return true;
    701                 } // if
     678                } //if
    702679        }
    703680
    704681        void Unify::visit(TupleType *tupleType) {
    705682                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    706                         std::unique_ptr<TupleType> flat1( tupleType->clone() );
    707                         std::unique_ptr<TupleType> flat2( otherTuple->clone() );
    708                         std::list<Type *> types1, types2;
    709 
    710                         TtypeExpander expander( env );
    711                         flat1->acceptMutator( expander );
    712                         flat2->acceptMutator( expander );
    713 
    714                         flatten( flat1.get(), back_inserter( types1 ) );
    715                         flatten( flat2.get(), back_inserter( types2 ) );
    716 
    717                         result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     683                        result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    718684                } // if
    719685        }
Note: See TracChangeset for help on using the changeset viewer.