Changeset ef1da0e2 for src/ResolvExpr/Unify.cc
- Timestamp:
- Sep 20, 2022, 6:34:55 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 79ae13d, a065f1f
- Parents:
- 8f1e035
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r8f1e035 ref1da0e2 693 693 } 694 694 695 namespace { 696 /// Replaces ttype variables with their bound types. 697 /// If this isn't done when satifying ttype assertions, then argument lists can have 698 /// different size and structure when they should be compatible. 699 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor { 700 ast::TypeEnvironment & tenv; 701 702 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {} 703 704 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 705 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) { 706 // expand ttype parameter into its actual type 707 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) { 708 return clz->bound; 709 } 710 } 711 return typeInst; 712 } 713 }; 714 } 715 716 std::vector< ast::ptr< ast::Type > > flattenList( 717 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 718 ) { 719 std::vector< ast::ptr< ast::Type > > dst; 720 dst.reserve( src.size() ); 721 for ( const auto & d : src ) { 722 ast::Pass<TtypeExpander_new> expander{ env }; 723 // TtypeExpander pass is impure (may mutate nodes in place) 724 // need to make nodes shared to prevent accidental mutation 725 ast::ptr<ast::Type> dc = d->accept(expander); 726 auto types = flatten( dc ); 727 for ( ast::ptr< ast::Type > & t : types ) { 728 // outermost const, volatile, _Atomic qualifiers in parameters should not play 729 // a role in the unification of function types, since they do not determine 730 // whether a function is callable. 731 // NOTE: **must** consider at least mutex qualifier, since functions can be 732 // overloaded on outermost mutex and a mutex function has different 733 // requirements than a non-mutex function 734 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 735 dst.emplace_back( t ); 736 } 737 } 738 return dst; 739 } 740 695 741 class Unify_new final : public ast::WithShortCircuiting { 696 742 const ast::Type * type2; … … 764 810 765 811 private: 766 /// Replaces ttype variables with their bound types.767 /// If this isn't done when satifying ttype assertions, then argument lists can have768 /// different size and structure when they should be compatible.769 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor {770 ast::TypeEnvironment & tenv;771 772 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}773 774 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {775 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) {776 // expand ttype parameter into its actual type777 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {778 return clz->bound;779 }780 }781 return typeInst;782 }783 };784 785 /// returns flattened version of `src`786 static std::vector< ast::ptr< ast::Type > > flattenList(787 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env788 ) {789 std::vector< ast::ptr< ast::Type > > dst;790 dst.reserve( src.size() );791 for ( const auto & d : src ) {792 ast::Pass<TtypeExpander_new> expander{ env };793 // TtypeExpander pass is impure (may mutate nodes in place)794 // need to make nodes shared to prevent accidental mutation795 ast::ptr<ast::Type> dc = d->accept(expander);796 auto types = flatten( dc );797 for ( ast::ptr< ast::Type > & t : types ) {798 // outermost const, volatile, _Atomic qualifiers in parameters should not play799 // a role in the unification of function types, since they do not determine800 // whether a function is callable.801 // NOTE: **must** consider at least mutex qualifier, since functions can be802 // overloaded on outermost mutex and a mutex function has different803 // requirements than a non-mutex function804 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );805 dst.emplace_back( t );806 }807 }808 return dst;809 }810 811 /// Creates a tuple type based on a list of DeclWithType812 template< typename Iter >813 static const ast::Type * tupleFromTypes( Iter crnt, Iter end ) {814 std::vector< ast::ptr< ast::Type > > types;815 while ( crnt != end ) {816 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure817 // that this results in a flat tuple818 flatten( *crnt, types );819 820 ++crnt;821 }822 823 return new ast::TupleType{ std::move(types) };824 }825 812 826 813 template< typename Iter > … … 1034 1021 private: 1035 1022 /// Creates a tuple type based on a list of Type 1036 static const ast::Type * tupleFromTypes( 1037 const std::vector< ast::ptr< ast::Type > > & tys 1038 ) { 1039 std::vector< ast::ptr< ast::Type > > out; 1040 for ( const ast::Type * ty : tys ) { 1041 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1042 // that this results in a flat tuple 1043 flatten( ty, out ); 1044 } 1045 1046 return new ast::TupleType{ std::move(out) }; 1047 } 1023 1048 1024 1049 1025 static bool unifyList( … … 1217 1193 } 1218 1194 1219 } else if ( ( common = commonType( t1, t2, widen, symtab, env, open ))) {1195 } else if ( common = commonType( t1, t2, env, need, have, open, widen, symtab )) { 1220 1196 // no exact unification, but common type 1221 1197 auto c = shallowCopy(common.get());
Note: See TracChangeset
for help on using the changeset viewer.