Changeset 7f6a7c9 for src/ResolvExpr/Unify.cc
- Timestamp:
- Sep 21, 2022, 11:02:15 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 95dab9e
- Parents:
- 428adbc (diff), 0bd46fd (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. - File:
-
- 1 edited
-
src/ResolvExpr/Unify.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r428adbc r7f6a7c9 165 165 ast::Type * newFirst = shallowCopy( first ); 166 166 ast::Type * newSecond = shallowCopy( second ); 167 if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) { 168 if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) { 169 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 170 if ( auto t = baseEnum->base.get() ) { 171 newFirst = ast::shallowCopy( t ); 172 } 173 } 174 } else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) { 175 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 176 if ( auto t = baseEnum->base.get() ) { 177 newSecond = ast::shallowCopy( t ); 178 } 179 } 180 167 181 newFirst ->qualifiers = {}; 168 182 newSecond->qualifiers = {}; … … 693 707 } 694 708 709 namespace { 710 /// Replaces ttype variables with their bound types. 711 /// If this isn't done when satifying ttype assertions, then argument lists can have 712 /// different size and structure when they should be compatible. 713 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor { 714 ast::TypeEnvironment & tenv; 715 716 TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {} 717 718 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 719 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) { 720 // expand ttype parameter into its actual type 721 if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) { 722 return clz->bound; 723 } 724 } 725 return typeInst; 726 } 727 }; 728 } 729 730 std::vector< ast::ptr< ast::Type > > flattenList( 731 const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env 732 ) { 733 std::vector< ast::ptr< ast::Type > > dst; 734 dst.reserve( src.size() ); 735 for ( const auto & d : src ) { 736 ast::Pass<TtypeExpander_new> expander{ env }; 737 // TtypeExpander pass is impure (may mutate nodes in place) 738 // need to make nodes shared to prevent accidental mutation 739 ast::ptr<ast::Type> dc = d->accept(expander); 740 auto types = flatten( dc ); 741 for ( ast::ptr< ast::Type > & t : types ) { 742 // outermost const, volatile, _Atomic qualifiers in parameters should not play 743 // a role in the unification of function types, since they do not determine 744 // whether a function is callable. 745 // NOTE: **must** consider at least mutex qualifier, since functions can be 746 // overloaded on outermost mutex and a mutex function has different 747 // requirements than a non-mutex function 748 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 749 dst.emplace_back( t ); 750 } 751 } 752 return dst; 753 } 754 695 755 class Unify_new final : public ast::WithShortCircuiting { 696 756 const ast::Type * type2; … … 764 824 765 825 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 826 826 827 template< typename Iter > … … 1034 1035 private: 1035 1036 /// 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 } 1037 1048 1038 1049 1039 static bool unifyList( … … 1217 1207 } 1218 1208 1219 } else if (( common = commonType( t1, t2, widen, symtab, env, open ))) {1209 } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) { 1220 1210 // no exact unification, but common type 1221 1211 auto c = shallowCopy(common.get());
Note:
See TracChangeset
for help on using the changeset viewer.