Ignore:
Timestamp:
Jul 27, 2018, 2:41:34 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env
Children:
6fa409e
Parents:
5a3e1f1
Message:

Fix open var handling in BF assn resolution; memory usage reasonable again

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r5a3e1f1 r1a59641  
    687687                /// as appropriate.
    688688                void bindAssertion( const DeclarationWithType* curDecl, const AssertionSetValue& assnInfo,
    689                                 AssertionResnState& resn, AssertionPack&& match ) {
    690                         addToIndexer( match.have, resn.indexer );
    691                         resn.newNeed.insert( match.need.begin(), match.need.end() );
    692                         resn.openVars = std::move(match.openVars);
    693                         resn.alt.env = std::move(match.env);
     689                                Alternative& alt, AssertionPack& match ) {
    694690
    695691                        DeclarationWithType* candidate = match.cdata.id;
     
    702698                        }
    703699
    704                         Expression* varExpr = match.cdata.combine( resn.alt.cvtCost );
     700                        Expression* varExpr = match.cdata.combine( alt.cvtCost );
    705701                        varExpr->result = match.adjType;
    706702
     
    708704                        // parameters to add the candidate o (i.e. the set of inferred parameters belonging
    709705                        // to the entity which requested the assertion parameter)
    710                         InferredParams* inferParams = &resn.alt.expr->inferParams;
     706                        InferredParams* inferParams = &alt.expr->inferParams;
    711707                        for ( UniqueId id : assnInfo.idChain ) {
    712708                                inferParams = (*inferParams)[ id ].inferParams.get();
     
    759755
    760756                        // otherwise bind current match in ongoing scope
    761                         bindAssertion( curDecl, assnInfo, resn, std::move(matches.front()) );
     757                        AssertionPack& match = matches.front();
     758                        addToIndexer( match.have, resn.indexer );
     759                        resn.newNeed.insert( match.need.begin(), match.need.end() );
     760                        resn.openVars = std::move(match.openVars);
     761                        resn.alt.env = std::move(match.env);
     762
     763                        bindAssertion( curDecl, assnInfo, resn.alt, match );
    762764                        return true;
    763765                }
     
    771773                        /// Stack of environments, to support backtracking
    772774                        std::vector<TypeEnvironment> envs;
     775                        /// Open variables for environment combination
     776                        std::vector<OpenVarSet> varSets;
    773777                        /// Indexer to use for environment merges
    774778                        const SymTab::Indexer& indexer;
    775779                public:
    776                         /// Outputs a pair consisting of the merged environment and the list of interpretations
    777                         using OutType = std::pair<TypeEnvironment, std::vector<DeferElement>>;
    778 
    779                         InterpretationEnvMerger( const TypeEnvironment& env, const SymTab::Indexer& indexer )
    780                                 : crnt{}, envs{}, indexer{indexer} { envs.push_back( env ); }
     780                        /// The merged environment/open variables and the list of interpretations
     781                        struct OutType {
     782                                TypeEnvironment env;
     783                                OpenVarSet openVars;
     784                                std::vector<DeferElement> assns;
     785
     786                                OutType( const TypeEnvironment& env, const OpenVarSet& openVars,
     787                                        const std::vector<DeferElement>& assns )
     788                                        : env(env), openVars(openVars), assns(assns) {}
     789                        };
     790
     791                        InterpretationEnvMerger( const TypeEnvironment& env, const OpenVarSet& openVars,
     792                                const SymTab::Indexer& indexer ) : crnt{}, envs{}, varSets{}, indexer{indexer} {
     793                                envs.push_back( env );
     794                                varSets.push_back( openVars );
     795                        }
    781796
    782797                        ComboResult append( DeferElement i ) {
    783798                                TypeEnvironment env = envs.back();
    784                                 if ( ! env.combine( i.match.env, indexer ) ) return ComboResult::REJECT_THIS;
     799                                OpenVarSet openVars = varSets.back();
     800                                mergeOpenVars( openVars, i.match.openVars );
     801
     802                                if ( ! env.combine( i.match.env, openVars, indexer ) )
     803                                        return ComboResult::REJECT_THIS;
     804                               
    785805                                crnt.push_back( i );
    786806                                envs.push_back( env );
     807                                varSets.push_back( openVars );
    787808                                return ComboResult::ACCEPT;
    788809                        }
     
    791812                                crnt.pop_back();
    792813                                envs.pop_back();
    793                         }
    794 
    795                         OutType finalize() { return { envs.back(), crnt }; }
     814                                varSets.pop_back();
     815                        }
     816
     817                        OutType finalize() { return { envs.back(), varSets.back(), crnt }; }
    796818                };
    797819        }
     
    833855
    834856                                        std::vector<InterpretationEnvMerger::OutType> compatible = filterCombos(
    835                                                 resn.deferred, InterpretationEnvMerger{ resn.alt.env, resn.indexer });
     857                                                resn.deferred,
     858                                                InterpretationEnvMerger{ resn.alt.env, resn.openVars, resn.indexer } );
    836859                                       
    837860                                        for ( auto& compat : compatible ) {
     
    839862
    840863                                                // add compatible assertions to new resolution state
    841                                                 for ( DeferElement el : compat.second ) {
    842                                                         bindAssertion(
    843                                                                 el.curDecl, el.assnInfo, new_resn, AssertionPack{el.match} );
     864                                                for ( DeferElement el : compat.assns ) {
     865                                                        AssertionPack match = el.match;
     866                                                        addToIndexer( match.have, new_resn.indexer );
     867                                                        resn.newNeed.insert( match.need.begin(), match.need.end() );
     868                                                       
     869                                                        bindAssertion( el.curDecl, el.assnInfo, new_resn.alt, match );
    844870                                                }
    845871
    846872                                                // set mutual environment into resolution state
    847                                                 new_resn.alt.env = std::move(compat.first);
     873                                                new_resn.alt.env = std::move(compat.env);
     874                                                new_resn.openVars = std::move(compat.openVars);
    848875
    849876                                                // add successful match or push back next state
Note: See TracChangeset for help on using the changeset viewer.