Changes in src/ResolvExpr/Unify.cc [6c3a988f:4a9ccc3]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r6c3a988f r4a9ccc3 123 123 } 124 124 125 struct CompleteTypeChecker : public Visitor {126 virtual void visit( VoidType *basicType ) { status = false; }127 virtual void visit( BasicType *basicType ) {}128 virtual void visit( PointerType *pointerType ) {}129 virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }130 virtual void visit( FunctionType *functionType ) {}131 virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }132 virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }133 // xxx - enum inst does not currently contain a pointer to base, this should be fixed.134 virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }135 virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }136 virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }137 virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness138 virtual void visit( TypeofType *typeofType ) { assert( false ); }139 virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here140 virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?141 virtual void visit( ZeroType *zeroType ) {}142 virtual void visit( OneType *oneType ) {}143 bool status = true;144 };145 bool isComplete( Type * type ) {146 CompleteTypeChecker checker;147 assert( type );148 type->accept( checker );149 return checker.status;150 }151 152 125 bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) { 153 126 switch ( data.kind ) { … … 158 131 // type must also be complete 159 132 // xxx - should this also check that type is not a tuple type and that it's not a ttype? 160 return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));133 return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() ); 161 134 case TypeDecl::Ftype: 162 135 return isFtype( type, indexer ); 163 136 case TypeDecl::Ttype: 164 137 // ttype unifies with any tuple type 165 return dynamic_cast< TupleType * >( type ) ;138 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type ); 166 139 } // switch 167 140 return false; … … 488 461 } 489 462 490 template< typename Iterator >491 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {463 template< typename Iterator, typename Func > 464 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) { 492 465 std::list< Type * > types; 493 466 for ( ; begin != end; ++begin ) { 494 467 // 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 ) );468 flatten( toType( *begin ), back_inserter( types ) ); 496 469 } 497 470 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) ); … … 500 473 template< typename Iterator1, typename Iterator2 > 501 474 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 475 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); }; 502 476 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 503 477 Type * t1 = (*list1Begin)->get_type(); … … 509 483 if ( isTtype1 && ! isTtype2 ) { 510 484 // 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 );485 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 512 486 } else if ( isTtype2 && ! isTtype1 ) { 513 487 // 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 );488 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 515 489 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 516 490 return false; … … 522 496 Type * t1 = (*list1Begin)->get_type(); 523 497 if ( Tuples::isTtype( t1 ) ) { 524 return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );498 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 525 499 } else return false; 526 500 } else if ( list2Begin != list2End ) { … … 528 502 Type * t2 = (*list2Begin)->get_type(); 529 503 if ( Tuples::isTtype( t2 ) ) { 530 return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );504 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 531 505 } else return false; 532 506 } else { … … 665 639 template< typename Iterator1, typename Iterator2 > 666 640 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 ) { 641 auto get_type = [](Type * t) { return t; }; 667 642 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 668 Type *commonType = 0; 669 if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) { 643 Type * t1 = *list1Begin; 644 Type * t2 = *list2Begin; 645 bool isTtype1 = Tuples::isTtype( t1 ); 646 bool isTtype2 = Tuples::isTtype( t2 ); 647 // xxx - assumes ttype must be last parameter 648 // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases. 649 if ( isTtype1 && ! isTtype2 ) { 650 // combine all of the things in list2, then unify 651 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 652 } else if ( isTtype2 && ! isTtype1 ) { 653 // combine all of the things in list1, then unify 654 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 655 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 670 656 return false; 671 } 672 delete commonType; 657 } // if 658 673 659 } // for 674 if ( list1Begin != list1End || list2Begin != list2End ) { 675 return false; 660 if ( list1Begin != list1End ) { 661 // try unifying empty tuple type with ttype 662 Type * t1 = *list1Begin; 663 if ( Tuples::isTtype( t1 ) ) { 664 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 665 } else return false; 666 } else if ( list2Begin != list2End ) { 667 // try unifying empty tuple type with ttype 668 Type * t2 = *list2Begin; 669 if ( Tuples::isTtype( t2 ) ) { 670 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 671 } else return false; 676 672 } else { 677 673 return true; 678 } // if674 } // if 679 675 } 680 676 681 677 void Unify::visit(TupleType *tupleType) { 682 678 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 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 ); 679 std::unique_ptr<TupleType> flat1( tupleType->clone() ); 680 std::unique_ptr<TupleType> flat2( otherTuple->clone() ); 681 std::list<Type *> types1, types2; 682 683 TtypeExpander expander( env ); 684 flat1->acceptMutator( expander ); 685 flat2->acceptMutator( expander ); 686 687 flatten( flat1.get(), back_inserter( types1 ) ); 688 flatten( flat2.get(), back_inserter( types2 ) ); 689 690 result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 684 691 } // if 685 692 }
Note:
See TracChangeset
for help on using the changeset viewer.