Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    ref9988b r18e683b  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed Jun 5 14:30:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Oct  1 14:55:00 2019
    13 // Update Count     : 2
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Wed Jun 5 14:30:00 2019
     13// Update Count     : 1
    1414//
    1515
     
    5454                return new ast::CastExpr{ expr, expr->result->stripReferences() };
    5555        }
    56 
     56       
    5757        return expr;
    5858}
     
    6161UniqueId globalResnSlot = 0;
    6262
    63 Cost computeConversionCost(
    64         const ast::Type * argType, const ast::Type * paramType, bool argIsLvalue,
    65         const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     63Cost computeConversionCost( 
     64        const ast::Type * argType, const ast::Type * paramType, const ast::SymbolTable & symtab,
     65        const ast::TypeEnvironment & env
    6666) {
    6767        PRINT(
     
    7474                std::cerr << std::endl;
    7575        )
    76         Cost convCost = conversionCost( argType, paramType, argIsLvalue, symtab, env );
     76        Cost convCost = conversionCost( argType, paramType, symtab, env );
    7777        PRINT(
    7878                std::cerr << std::endl << "cost is " << convCost << std::endl;
     
    107107
    108108        /// Computes conversion cost for a given expression to a given type
    109         const ast::Expr * computeExpressionConversionCost(
    110                 const ast::Expr * arg, const ast::Type * paramType, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env, Cost & outCost
     109        const ast::Expr * computeExpressionConversionCost( 
     110                const ast::Expr * arg, const ast::Type * paramType, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env, Cost & outCost 
    111111        ) {
    112                 Cost convCost = computeConversionCost(
    113                                 arg->result, paramType, arg->get_lvalue(), symtab, env );
     112                Cost convCost = computeConversionCost( arg->result, paramType, symtab, env );
    114113                outCost += convCost;
    115114
    116                 // If there is a non-zero conversion cost, ignoring poly cost, then the expression requires
    117                 // conversion. Ignore poly cost for now, since this requires resolution of the cast to
     115                // If there is a non-zero conversion cost, ignoring poly cost, then the expression requires 
     116                // conversion. Ignore poly cost for now, since this requires resolution of the cast to 
    118117                // infer parameters and this does not currently work for the reason stated below
    119118                Cost tmpCost = convCost;
     
    124123                        return new ast::CastExpr{ arg, newType };
    125124
    126                         // xxx - *should* be able to resolve this cast, but at the moment pointers are not
    127                         // castable to zero_t, but are implicitly convertible. This is clearly inconsistent,
     125                        // xxx - *should* be able to resolve this cast, but at the moment pointers are not 
     126                        // castable to zero_t, but are implicitly convertible. This is clearly inconsistent, 
    128127                        // once this is fixed it should be possible to resolve the cast.
    129                         // xxx - this isn't working, it appears because type1 (parameter) is seen as widenable,
    130                         // but it shouldn't be because this makes the conversion from DT* to DT* since
     128                        // xxx - this isn't working, it appears because type1 (parameter) is seen as widenable, 
     129                        // but it shouldn't be because this makes the conversion from DT* to DT* since 
    131130                        // commontype(zero_t, DT*) is DT*, rather than nothing
    132131
    133132                        // CandidateFinder finder{ symtab, env };
    134133                        // finder.find( arg, ResolvMode::withAdjustment() );
    135                         // assertf( finder.candidates.size() > 0,
     134                        // assertf( finder.candidates.size() > 0, 
    136135                        //      "Somehow castable expression failed to find alternatives." );
    137                         // assertf( finder.candidates.size() == 1,
     136                        // assertf( finder.candidates.size() == 1, 
    138137                        //      "Somehow got multiple alternatives for known cast expression." );
    139138                        // return finder.candidates.front()->expr;
     
    144143
    145144        /// Computes conversion cost for a given candidate
    146         Cost computeApplicationConversionCost(
    147                 CandidateRef cand, const ast::SymbolTable & symtab
     145        Cost computeApplicationConversionCost( 
     146                CandidateRef cand, const ast::SymbolTable & symtab 
    148147        ) {
    149148                auto appExpr = cand->expr.strict_as< ast::ApplicationExpr >();
     
    168167                                if ( function->isVarArgs ) {
    169168                                        convCost.incUnsafe();
    170                                         PRINT( std::cerr << "end of params with varargs function: inc unsafe: "
     169                                        PRINT( std::cerr << "end of params with varargs function: inc unsafe: " 
    171170                                                << convCost << std::endl; ; )
    172171                                        // convert reference-typed expressions into value-typed expressions
    173                                         cand->expr = ast::mutate_field_index(
    174                                                 appExpr, &ast::ApplicationExpr::args, i,
     172                                        cand->expr = ast::mutate_field_index( 
     173                                                appExpr, &ast::ApplicationExpr::args, i, 
    175174                                                referenceToRvalueConversion( args[i], convCost ) );
    176175                                        continue;
     
    181180                                // Default arguments should be free - don't include conversion cost.
    182181                                // Unwrap them here because they are not relevant to the rest of the system
    183                                 cand->expr = ast::mutate_field_index(
     182                                cand->expr = ast::mutate_field_index( 
    184183                                        appExpr, &ast::ApplicationExpr::args, i, def->expr );
    185184                                ++param;
     
    189188                        // mark conversion cost and also specialization cost of param type
    190189                        const ast::Type * paramType = (*param)->get_type();
    191                         cand->expr = ast::mutate_field_index(
    192                                 appExpr, &ast::ApplicationExpr::args, i,
    193                                 computeExpressionConversionCost(
     190                        cand->expr = ast::mutate_field_index( 
     191                                appExpr, &ast::ApplicationExpr::args, i, 
     192                                computeExpressionConversionCost( 
    194193                                        args[i], paramType, symtab, cand->env, convCost ) );
    195194                        convCost.decSpec( specCost( paramType ) );
     
    199198                if ( param != params.end() ) return Cost::infinity;
    200199
    201                 // specialization cost of return types can't be accounted for directly, it disables
     200                // specialization cost of return types can't be accounted for directly, it disables 
    202201                // otherwise-identical calls, like this example based on auto-newline in the I/O lib:
    203202                //
     
    216215        }
    217216
    218         void makeUnifiableVars(
    219                 const ast::ParameterizedType * type, ast::OpenVarSet & unifiableVars,
    220                 ast::AssertionSet & need
     217        void makeUnifiableVars( 
     218                const ast::ParameterizedType * type, ast::OpenVarSet & unifiableVars, 
     219                ast::AssertionSet & need 
    221220        ) {
    222221                for ( const ast::TypeDecl * tyvar : type->forall ) {
     
    255254
    256255                ArgPack()
    257                 : parent( 0 ), expr(), cost( Cost::zero ), env(), need(), have(), open(), nextArg( 0 ),
     256                : parent( 0 ), expr(), cost( Cost::zero ), env(), need(), have(), open(), nextArg( 0 ), 
    258257                  tupleStart( 0 ), nextExpl( 0 ), explAlt( 0 ) {}
    259 
     258               
     259                ArgPack(
     260                        const ast::TypeEnvironment & env, const ast::AssertionSet & need,
     261                        const ast::AssertionSet & have, const ast::OpenVarSet & open )
     262                : parent( 0 ), expr(), cost( Cost::zero ), env( env ), need( need ), have( have ),
     263                  open( open ), nextArg( 0 ), tupleStart( 0 ), nextExpl( 0 ), explAlt( 0 ) {}
     264               
    260265                ArgPack(
    261                         const ast::TypeEnvironment & env, const ast::AssertionSet & need,
    262                         const ast::AssertionSet & have, const ast::OpenVarSet & open )
    263                 : parent( 0 ), expr(), cost( Cost::zero ), env( env ), need( need ), have( have ),
    264                   open( open ), nextArg( 0 ), tupleStart( 0 ), nextExpl( 0 ), explAlt( 0 ) {}
    265 
    266                 ArgPack(
    267                         std::size_t parent, const ast::Expr * expr, ast::TypeEnvironment && env,
    268                         ast::AssertionSet && need, ast::AssertionSet && have, ast::OpenVarSet && open,
    269                         unsigned nextArg, unsigned tupleStart = 0, Cost cost = Cost::zero,
     266                        std::size_t parent, const ast::Expr * expr, ast::TypeEnvironment && env,
     267                        ast::AssertionSet && need, ast::AssertionSet && have, ast::OpenVarSet && open,
     268                        unsigned nextArg, unsigned tupleStart = 0, Cost cost = Cost::zero,
    270269                        unsigned nextExpl = 0, unsigned explAlt = 0 )
    271270                : parent(parent), expr( expr ), cost( cost ), env( move( env ) ), need( move( need ) ),
    272271                  have( move( have ) ), open( move( open ) ), nextArg( nextArg ), tupleStart( tupleStart ),
    273272                  nextExpl( nextExpl ), explAlt( explAlt ) {}
    274 
     273               
    275274                ArgPack(
    276                         const ArgPack & o, ast::TypeEnvironment && env, ast::AssertionSet && need,
     275                        const ArgPack & o, ast::TypeEnvironment && env, ast::AssertionSet && need, 
    277276                        ast::AssertionSet && have, ast::OpenVarSet && open, unsigned nextArg, Cost added )
    278                 : parent( o.parent ), expr( o.expr ), cost( o.cost + added ), env( move( env ) ),
    279                   need( move( need ) ), have( move( have ) ), open( move( open ) ), nextArg( nextArg ),
     277                : parent( o.parent ), expr( o.expr ), cost( o.cost + added ), env( move( env ) ), 
     278                  need( move( need ) ), have( move( have ) ), open( move( open ) ), nextArg( nextArg ), 
    280279                  tupleStart( o.tupleStart ), nextExpl( 0 ), explAlt( 0 ) {}
    281 
     280               
    282281                /// true if this pack is in the middle of an exploded argument
    283282                bool hasExpl() const { return nextExpl > 0; }
     
    287286                        return args[ nextArg-1 ][ explAlt ];
    288287                }
    289 
     288               
    290289                /// Ends a tuple expression, consolidating the appropriate args
    291290                void endTuple( const std::vector< ArgPack > & packs ) {
     
    308307
    309308        /// Instantiates an argument to match a parameter, returns false if no matching results left
    310         bool instantiateArgument(
    311                 const ast::Type * paramType, const ast::Init * init, const ExplodedArgs_new & args,
    312                 std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab,
    313                 unsigned nTuples = 0
     309        bool instantiateArgument( 
     310                const ast::Type * paramType, const ast::Init * init, const ExplodedArgs_new & args, 
     311                std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab, 
     312                unsigned nTuples = 0 
    314313        ) {
    315314                if ( auto tupleType = dynamic_cast< const ast::TupleType * >( paramType ) ) {
     
    319318                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    320319                                // ^^^ need to handle the case where a tuple has a default argument
    321                                 if ( ! instantiateArgument(
     320                                if ( ! instantiateArgument( 
    322321                                        type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;
    323322                                nTuples = 0;
     
    330329                } else if ( const ast::TypeInstType * ttype = Tuples::isTtype( paramType ) ) {
    331330                        // paramType is a ttype, consumes all remaining arguments
    332 
     331                       
    333332                        // completed tuples; will be spliced to end of results to finish
    334333                        std::vector< ArgPack > finalResults{};
     
    343342                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    344343                                        unsigned nextArg = results[i].nextArg;
    345 
     344                                       
    346345                                        // use next element of exploded tuple if present
    347346                                        if ( results[i].hasExpl() ) {
     
    353352                                                results.emplace_back(
    354353                                                        i, expl.exprs[ results[i].nextExpl ], copy( results[i].env ),
    355                                                         copy( results[i].need ), copy( results[i].have ),
     354                                                        copy( results[i].need ), copy( results[i].have ), 
    356355                                                        copy( results[i].open ), nextArg, nTuples, Cost::zero, nextExpl,
    357356                                                        results[i].explAlt );
     
    371370                                                        // push empty tuple expression
    372371                                                        newResult.parent = i;
    373                                                         newResult.expr = new ast::TupleExpr{ CodeLocation{}, {} };
     372                                                        std::vector< ast::ptr< ast::Expr > > emptyList;
     373                                                        newResult.expr =
     374                                                                new ast::TupleExpr{ CodeLocation{}, move( emptyList ) };
    374375                                                        argType = newResult.expr->result;
    375376                                                } else {
     
    399400
    400401                                                // check unification for ttype before adding to final
    401                                                 if (
    402                                                         unify(
     402                                                if ( 
     403                                                        unify( 
    403404                                                                ttype, argType, newResult.env, newResult.need, newResult.have,
    404                                                                 newResult.open, symtab )
     405                                                                newResult.open, symtab ) 
    405406                                                ) {
    406407                                                        finalResults.emplace_back( move( newResult ) );
     
    423424                                                if ( expl.exprs.empty() ) {
    424425                                                        results.emplace_back(
    425                                                                 results[i], move( env ), copy( results[i].need ),
     426                                                                results[i], move( env ), copy( results[i].need ), 
    426427                                                                copy( results[i].have ), move( open ), nextArg + 1, expl.cost );
    427 
     428                                                       
    428429                                                        continue;
    429430                                                }
     
    431432                                                // add new result
    432433                                                results.emplace_back(
    433                                                         i, expl.exprs.front(), move( env ), copy( results[i].need ),
    434                                                         copy( results[i].have ), move( open ), nextArg + 1, nTuples,
     434                                                        i, expl.exprs.front(), move( env ), copy( results[i].need ), 
     435                                                        copy( results[i].have ), move( open ), nextArg + 1, nTuples, 
    435436                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    436437                                        }
     
    478479
    479480                                        results.emplace_back(
    480                                                 i, expr, move( env ), move( need ), move( have ), move( open ), nextArg,
     481                                                i, expr, move( env ), move( need ), move( have ), move( open ), nextArg, 
    481482                                                nTuples, Cost::zero, nextExpl, results[i].explAlt );
    482483                                }
     
    494495                                        if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) {
    495496                                                results.emplace_back(
    496                                                         i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ),
     497                                                        i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ), 
    497498                                                        move( need ), move( have ), move( open ), nextArg, nTuples );
    498499                                        }
     
    516517                                if ( expl.exprs.empty() ) {
    517518                                        results.emplace_back(
    518                                                 results[i], move( env ), move( need ), move( have ), move( open ),
     519                                                results[i], move( env ), move( need ), move( have ), move( open ), 
    519520                                                nextArg + 1, expl.cost );
    520 
     521                                       
    521522                                        continue;
    522523                                }
     
    538539                                        // add new result
    539540                                        results.emplace_back(
    540                                                 i, expr, move( env ), move( need ), move( have ), move( open ),
     541                                                i, expr, move( env ), move( need ), move( have ), move( open ), 
    541542                                                nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    542543                                }
     
    547548                genStart = genEnd;
    548549
    549                 return genEnd != results.size();  // were any new results added?
     550                return genEnd != results.size();
    550551        }
    551552
    552553        /// Generate a cast expression from `arg` to `toType`
    553         const ast::Expr * restructureCast(
     554        const ast::Expr * restructureCast( 
    554555                ast::ptr< ast::Expr > & arg, const ast::Type * toType, ast::GeneratedFlag isGenerated = ast::GeneratedCast
    555556        ) {
    556                 if (
    557                         arg->result->size() > 1
    558                         && ! toType->isVoid()
    559                         && ! dynamic_cast< const ast::ReferenceType * >( toType )
     557                if ( 
     558                        arg->result->size() > 1 
     559                        && ! toType->isVoid() 
     560                        && ! dynamic_cast< const ast::ReferenceType * >( toType ) 
    560561                ) {
    561                         // Argument is a tuple and the target type is neither void nor a reference. Cast each
    562                         // member of the tuple to its corresponding target type, producing the tuple of those
    563                         // cast expressions. If there are more components of the tuple than components in the
    564                         // target type, then excess components do not come out in the result expression (but
     562                        // Argument is a tuple and the target type is neither void nor a reference. Cast each 
     563                        // member of the tuple to its corresponding target type, producing the tuple of those 
     564                        // cast expressions. If there are more components of the tuple than components in the 
     565                        // target type, then excess components do not come out in the result expression (but 
    565566                        // UniqueExpr ensures that the side effects will still be produced)
    566567                        if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    567                                 // expressions which may contain side effects require a single unique instance of
     568                                // expressions which may contain side effects require a single unique instance of 
    568569                                // the expression
    569570                                arg = new ast::UniqueExpr{ arg->location, arg };
     
    573574                                // cast each component
    574575                                ast::ptr< ast::Expr > idx = new ast::TupleIndexExpr{ arg->location, arg, i };
    575                                 components.emplace_back(
     576                                components.emplace_back( 
    576577                                        restructureCast( idx, toType->getComponent( i ), isGenerated ) );
    577578                        }
     
    593594
    594595        /// Actually visits expressions to find their candidate interpretations
    595         class Finder final : public ast::WithShortCircuiting {
     596        struct Finder final : public ast::WithShortCircuiting {
     597                CandidateFinder & selfFinder;
    596598                const ast::SymbolTable & symtab;
    597         public:
    598                 static size_t traceId;
    599                 CandidateFinder & selfFinder;
    600599                CandidateList & candidates;
    601600                const ast::TypeEnvironment & tenv;
    602601                ast::ptr< ast::Type > & targetType;
    603602
    604                 enum Errors {
    605                         NotFound,
    606                         NoMatch,
    607                         ArgsToFew,
    608                         ArgsToMany,
    609                         RetsToFew,
    610                         RetsToMany,
    611                         NoReason
    612                 };
    613 
    614                 struct {
    615                         Errors code = NotFound;
    616                 } reason;
    617 
    618603                Finder( CandidateFinder & f )
    619                 : symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ),
     604                : selfFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),
    620605                  targetType( f.targetType ) {}
    621 
     606               
    622607                void previsit( const ast::Node * ) { visit_children = false; }
    623608
     
    626611                void addCandidate( Args &&... args ) {
    627612                        candidates.emplace_back( new Candidate{ std::forward<Args>( args )... } );
    628                         reason.code = NoReason;
    629613                }
    630614
     
    655639
    656640                /// Completes a function candidate with arguments located
    657                 void validateFunctionCandidate(
    658                         const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results,
    659                         CandidateList & out
     641                void validateFunctionCandidate( 
     642                        const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results, 
     643                        CandidateList & out 
    660644                ) {
    661                         ast::ApplicationExpr * appExpr =
     645                        ast::ApplicationExpr * appExpr = 
    662646                                new ast::ApplicationExpr{ func->expr->location, func->expr };
    663647                        // sum cost and accumulate arguments
     
    673657                        appExpr->args = move( vargs );
    674658                        // build and validate new candidate
    675                         auto newCand =
     659                        auto newCand = 
    676660                                std::make_shared<Candidate>( appExpr, result.env, result.open, result.need, cost );
    677661                        PRINT(
     
    685669                /// Builds a list of candidates for a function, storing them in out
    686670                void makeFunctionCandidates(
    687                         const CandidateRef & func, const ast::FunctionType * funcType,
     671                        const CandidateRef & func, const ast::FunctionType * funcType, 
    688672                        const ExplodedArgs_new & args, CandidateList & out
    689673                ) {
     
    692676                        ast::TypeEnvironment funcEnv{ func->env };
    693677                        makeUnifiableVars( funcType, funcOpen, funcNeed );
    694                         // add all type variables as open variables now so that those not used in the
    695                         // parameter list are still considered open
     678                        // add all type variables as open variables now so that those not used in the parameter
     679                        // list are still considered open
    696680                        funcEnv.add( funcType->forall );
    697681
     
    699683                                // attempt to narrow based on expected target type
    700684                                const ast::Type * returnType = funcType->returns.front()->get_type();
    701                                 if ( ! unify(
    702                                         returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
     685                                if ( ! unify( 
     686                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) 
    703687                                ) {
    704688                                        // unification failed, do not pursue this candidate
     
    714698                        for ( const ast::DeclWithType * param : funcType->params ) {
    715699                                auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
    716                                 // Try adding the arguments corresponding to the current parameter to the existing
     700                                // Try adding the arguments corresponding to the current parameter to the existing 
    717701                                // matches
    718                                 if ( ! instantiateArgument(
     702                                if ( ! instantiateArgument( 
    719703                                        obj->type, obj->init, args, results, genStart, symtab ) ) return;
    720704                        }
     
    766750                                                        if ( expl.exprs.empty() ) {
    767751                                                                results.emplace_back(
    768                                                                         results[i], move( env ), copy( results[i].need ),
    769                                                                         copy( results[i].have ), move( open ), nextArg + 1,
     752                                                                        results[i], move( env ), copy( results[i].need ), 
     753                                                                        copy( results[i].have ), move( open ), nextArg + 1, 
    770754                                                                        expl.cost );
    771755
     
    776760                                                        results.emplace_back(
    777761                                                                i, expl.exprs.front(), move( env ), copy( results[i].need ),
    778                                                                 copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost,
     762                                                                copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost, 
    779763                                                                expl.exprs.size() == 1 ? 0 : 1, j );
    780764                                                }
     
    796780                /// Adds implicit struct-conversions to the alternative list
    797781                void addAnonConversions( const CandidateRef & cand ) {
    798                         // adds anonymous member interpretations whenever an aggregate value type is seen.
    799                         // it's okay for the aggregate expression to have reference type -- cast it to the
     782                        // adds anonymous member interpretations whenever an aggregate value type is seen. 
     783                        // it's okay for the aggregate expression to have reference type -- cast it to the 
    800784                        // base type to treat the aggregate as the referenced value
    801785                        ast::ptr< ast::Expr > aggrExpr( cand->expr );
    802786                        ast::ptr< ast::Type > & aggrType = aggrExpr.get_and_mutate()->result;
    803787                        cand->env.apply( aggrType );
    804 
     788                       
    805789                        if ( aggrType.as< ast::ReferenceType >() ) {
    806790                                aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() };
     
    815799
    816800                /// Adds aggregate member interpretations
    817                 void addAggMembers(
    818                         const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
    819                         const Candidate & cand, const Cost & addedCost, const std::string & name
     801                void addAggMembers( 
     802                        const ast::ReferenceToType * aggrInst, const ast::Expr * expr, 
     803                        const Candidate & cand, const Cost & addedCost, const std::string & name 
    820804                ) {
    821805                        for ( const ast::Decl * decl : aggrInst->lookup( name ) ) {
    822806                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( decl );
    823                                 CandidateRef newCand = std::make_shared<Candidate>(
     807                                CandidateRef newCand = std::make_shared<Candidate>( 
    824808                                        cand, new ast::MemberExpr{ expr->location, dwt, expr }, addedCost );
    825                                 // add anonymous member interpretations whenever an aggregate value type is seen
     809                                // add anonymous member interpretations whenever an aggregate value type is seen 
    826810                                // as a member expression
    827811                                addAnonConversions( newCand );
     
    831815
    832816                /// Adds tuple member interpretations
    833                 void addTupleMembers(
    834                         const ast::TupleType * tupleType, const ast::Expr * expr, const Candidate & cand,
    835                         const Cost & addedCost, const ast::Expr * member
     817                void addTupleMembers( 
     818                        const ast::TupleType * tupleType, const ast::Expr * expr, const Candidate & cand, 
     819                        const Cost & addedCost, const ast::Expr * member 
    836820                ) {
    837821                        if ( auto constantExpr = dynamic_cast< const ast::ConstantExpr * >( member ) ) {
    838                                 // get the value of the constant expression as an int, must be between 0 and the
     822                                // get the value of the constant expression as an int, must be between 0 and the 
    839823                                // length of the tuple to have meaning
    840824                                long long val = constantExpr->intValue();
    841825                                if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    842826                                        addCandidate(
    843                                                 cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val },
     827                                                cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val }, 
    844828                                                addedCost );
    845829                                }
     
    853837                        if ( funcFinder.candidates.empty() ) return;
    854838
    855                         reason.code = NoMatch;
    856 
    857                         std::vector< CandidateFinder > argCandidates =
     839                        std::vector< CandidateFinder > argCandidates =
    858840                                selfFinder.findSubExprs( untypedExpr->args );
    859 
     841                       
    860842                        // take care of possible tuple assignments
    861843                        // if not tuple assignment, handled as normal function call
     
    895877                                                if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    896878                                                        CandidateRef newFunc{ new Candidate{ *func } };
    897                                                         newFunc->expr =
     879                                                        newFunc->expr = 
    898880                                                                referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    899881                                                        makeFunctionCandidates( newFunc, function, argExpansions, found );
    900882                                                }
    901                                         } else if (
    902                                                 auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult )
     883                                        } else if ( 
     884                                                auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult ) 
    903885                                        ) {
    904886                                                if ( const ast::EqvClass * clz = func->env.lookup( inst->name ) ) {
    905887                                                        if ( auto function = clz->bound.as< ast::FunctionType >() ) {
    906888                                                                CandidateRef newFunc{ new Candidate{ *func } };
    907                                                                 newFunc->expr =
     889                                                                newFunc->expr = 
    908890                                                                        referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    909891                                                                makeFunctionCandidates( newFunc, function, argExpansions, found );
     
    919901                                std::vector< ExplodedArg > funcE;
    920902                                funcE.reserve( funcFinder.candidates.size() );
    921                                 for ( const CandidateRef & func : funcFinder ) {
     903                                for ( const CandidateRef & func : funcFinder ) { 
    922904                                        funcE.emplace_back( *func, symtab );
    923905                                }
     
    931913                                                        if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    932914                                                                CandidateRef newOp{ new Candidate{ *op} };
    933                                                                 newOp->expr =
     915                                                                newOp->expr = 
    934916                                                                        referenceToRvalueConversion( newOp->expr, newOp->cost );
    935917                                                                makeFunctionCandidates( newOp, function, argExpansions, found );
     
    940922                        }
    941923
    942                         // Implement SFINAE; resolution errors are only errors if there aren't any non-error
     924                        // Implement SFINAE; resolution errors are only errors if there aren't any non-error 
    943925                        // candidates
    944926                        if ( found.empty() && ! errors.isEmpty() ) { throw errors; }
     
    952934                                        auto pointer = appExpr->func->result.strict_as< ast::PointerType >();
    953935                                        auto function = pointer->base.strict_as< ast::FunctionType >();
    954 
     936                                       
    955937                                        std::cerr << "Case +++++++++++++ " << appExpr->func << std::endl;
    956938                                        std::cerr << "parameters are:" << std::endl;
     
    975957                        promoteCvtCost( winners );
    976958
    977                         // function may return a struct/union value, in which case we need to add candidates
    978                         // for implicit conversions to each of the anonymous members, which must happen after
     959                        // function may return a struct/union value, in which case we need to add candidates 
     960                        // for implicit conversions to each of the anonymous members, which must happen after 
    979961                        // `findMinCost`, since anon conversions are never the cheapest
    980962                        for ( const CandidateRef & c : winners ) {
     
    984966
    985967                        if ( candidates.empty() && targetType && ! targetType->isVoid() ) {
    986                                 // If resolution is unsuccessful with a target type, try again without, since it
     968                                // If resolution is unsuccessful with a target type, try again without, since it 
    987969                                // will sometimes succeed when it wouldn't with a target type binding.
    988970                                // For example:
     
    1001983                /// true if expression is an lvalue
    1002984                static bool isLvalue( const ast::Expr * x ) {
    1003                         return x->result && ( x->get_lvalue() || x->result.as< ast::ReferenceType >() );
     985                        return x->result && ( x->result->is_lvalue() || x->result.as< ast::ReferenceType >() );
    1004986                }
    1005987
     
    1007989                        CandidateFinder finder{ symtab, tenv };
    1008990                        finder.find( addressExpr->arg );
    1009 
    1010                         if( finder.candidates.empty() ) return;
    1011 
    1012                         reason.code = NoMatch;
    1013 
    1014991                        for ( CandidateRef & r : finder.candidates ) {
    1015992                                if ( ! isLvalue( r->expr ) ) continue;
     
    10321009                        finder.find( castExpr->arg, ResolvMode::withAdjustment() );
    10331010
    1034                         if( !finder.candidates.empty() ) reason.code = NoMatch;
    1035 
    10361011                        CandidateList matches;
    10371012                        for ( CandidateRef & cand : finder.candidates ) {
     
    10411016                                cand->env.extractOpenVars( open );
    10421017
    1043                                 // It is possible that a cast can throw away some values in a multiply-valued
    1044                                 // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of the
    1045                                 // subexpression results that are cast directly. The candidate is invalid if it
     1018                                // It is possible that a cast can throw away some values in a multiply-valued 
     1019                                // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of the 
     1020                                // subexpression results that are cast directly. The candidate is invalid if it 
    10461021                                // has fewer results than there are types to cast to.
    10471022                                int discardedValues = cand->expr->result->size() - toType->size();
     
    10501025                                // unification run for side-effects
    10511026                                unify( toType, cand->expr->result, cand->env, need, have, open, symtab );
    1052                                 Cost thisCost = castCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    1053                                                 symtab, cand->env );
     1027                                Cost thisCost = castCost( cand->expr->result, toType, symtab, cand->env );
    10541028                                PRINT(
    10551029                                        std::cerr << "working on cast with result: " << toType << std::endl;
     
    10631037                                        // count one safe conversion for each value that is thrown away
    10641038                                        thisCost.incSafe( discardedValues );
    1065                                         CandidateRef newCand = std::make_shared<Candidate>(
    1066                                                 restructureCast( cand->expr, toType, castExpr->isGenerated ),
    1067                                                 copy( cand->env ), move( open ), move( need ), cand->cost,
     1039                                        CandidateRef newCand = std::make_shared<Candidate>( 
     1040                                                restructureCast( cand->expr, toType, castExpr->isGenerated ), 
     1041                                                copy( cand->env ), move( open ), move( need ), cand->cost, 
    10681042                                                cand->cost + thisCost );
    10691043                                        inferParameters( newCand, matches );
     
    10831057                        finder.find( castExpr->arg, ResolvMode::withoutPrune() );
    10841058                        for ( CandidateRef & r : finder.candidates ) {
    1085                                 addCandidate(
    1086                                         *r,
     1059                                addCandidate( 
     1060                                        *r, 
    10871061                                        new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } );
    10881062                        }
     
    10931067                        aggFinder.find( memberExpr->aggregate, ResolvMode::withAdjustment() );
    10941068                        for ( CandidateRef & agg : aggFinder.candidates ) {
    1095                                 // it's okay for the aggregate expression to have reference type -- cast it to the
     1069                                // it's okay for the aggregate expression to have reference type -- cast it to the 
    10961070                                // base type to treat the aggregate as the referenced value
    10971071                                Cost addedCost = Cost::zero;
     
    11001074                                // find member of the given type
    11011075                                if ( auto structInst = agg->expr->result.as< ast::StructInstType >() ) {
    1102                                         addAggMembers(
     1076                                        addAggMembers( 
    11031077                                                structInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    11041078                                } else if ( auto unionInst = agg->expr->result.as< ast::UnionInstType >() ) {
    1105                                         addAggMembers(
     1079                                        addAggMembers( 
    11061080                                                unionInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    11071081                                } else if ( auto tupleType = agg->expr->result.as< ast::TupleType >() ) {
     
    11181092                        std::vector< ast::SymbolTable::IdData > declList = symtab.lookupId( nameExpr->name );
    11191093                        PRINT( std::cerr << "nameExpr is " << nameExpr->name << std::endl; )
    1120                         if( declList.empty() ) return;
    1121 
    1122                         reason.code = NoMatch;
    1123 
    11241094                        for ( auto & data : declList ) {
    11251095                                Cost cost = Cost::zero;
     
    11271097
    11281098                                CandidateRef newCand = std::make_shared<Candidate>(
    1129                                         newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
     1099                                        newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero, 
    11301100                                        cost );
    11311101                                PRINT(
     
    11371107                                        std::cerr << std::endl;
    11381108                                )
    1139                                 newCand->expr = ast::mutate_field(
    1140                                         newCand->expr.get(), &ast::Expr::result,
     1109                                newCand->expr = ast::mutate_field( 
     1110                                        newCand->expr.get(), &ast::Expr::result, 
    11411111                                        renameTyVars( newCand->expr->result ) );
    1142                                 // add anonymous member interpretations whenever an aggregate value type is seen
     1112                                // add anonymous member interpretations whenever an aggregate value type is seen 
    11431113                                // as a name expression
    11441114                                addAnonConversions( newCand );
     
    11501120                        // not sufficient to just pass `variableExpr` here, type might have changed since
    11511121                        // creation
    1152                         addCandidate(
     1122                        addCandidate( 
    11531123                                new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv );
    11541124                }
     
    11601130                void postvisit( const ast::SizeofExpr * sizeofExpr ) {
    11611131                        if ( sizeofExpr->type ) {
    1162                                 addCandidate(
    1163                                         new ast::SizeofExpr{
    1164                                                 sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) },
     1132                                addCandidate( 
     1133                                        new ast::SizeofExpr{ 
     1134                                                sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) }, 
    11651135                                        tenv );
    11661136                        } else {
     
    11711141                                CandidateList winners = findMinCost( finder.candidates );
    11721142                                if ( winners.size() != 1 ) {
    1173                                         SemanticError(
     1143                                        SemanticError( 
    11741144                                                sizeofExpr->expr.get(), "Ambiguous expression in sizeof operand: " );
    11751145                                }
     
    11841154                void postvisit( const ast::AlignofExpr * alignofExpr ) {
    11851155                        if ( alignofExpr->type ) {
    1186                                 addCandidate(
    1187                                         new ast::AlignofExpr{
    1188                                                 alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) },
     1156                                addCandidate( 
     1157                                        new ast::AlignofExpr{ 
     1158                                                alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) }, 
    11891159                                        tenv );
    11901160                        } else {
     
    11951165                                CandidateList winners = findMinCost( finder.candidates );
    11961166                                if ( winners.size() != 1 ) {
    1197                                         SemanticError(
     1167                                        SemanticError( 
    11981168                                                alignofExpr->expr.get(), "Ambiguous expression in alignof operand: " );
    11991169                                }
     
    12021172                                choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    12031173                                choice->cost = Cost::zero;
    1204                                 addCandidate(
     1174                                addCandidate( 
    12051175                                        *choice, new ast::AlignofExpr{ alignofExpr->location, choice->expr } );
    12061176                        }
     
    12151185                        for ( const ast::Decl * member : aggInst->lookup( offsetofExpr->member ) ) {
    12161186                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( member );
    1217                                 addCandidate(
     1187                                addCandidate( 
    12181188                                        new ast::OffsetofExpr{ offsetofExpr->location, aggInst, dwt }, tenv );
    12191189                        }
     
    12361206                        finder2.find( logicalExpr->arg2, ResolvMode::withAdjustment() );
    12371207                        if ( finder2.candidates.empty() ) return;
    1238 
    1239                         reason.code = NoMatch;
    12401208
    12411209                        for ( const CandidateRef & r1 : finder1.candidates ) {
     
    12501218
    12511219                                        addCandidate(
    1252                                                 new ast::LogicalExpr{
     1220                                                new ast::LogicalExpr{ 
    12531221                                                        logicalExpr->location, r1->expr, r2->expr, logicalExpr->isAnd },
    12541222                                                move( env ), move( open ), move( need ), r1->cost + r2->cost );
     
    12721240                        finder3.find( conditionalExpr->arg3, ResolvMode::withAdjustment() );
    12731241                        if ( finder3.candidates.empty() ) return;
    1274 
    1275                         reason.code = NoMatch;
    12761242
    12771243                        for ( const CandidateRef & r1 : finder1.candidates ) {
     
    12901256                                                ast::AssertionSet have;
    12911257
    1292                                                 // unify true and false results, then infer parameters to produce new
     1258                                                // unify true and false results, then infer parameters to produce new 
    12931259                                                // candidates
    12941260                                                ast::ptr< ast::Type > common;
    1295                                                 if (
    1296                                                         unify(
    1297                                                                 r2->expr->result, r3->expr->result, env, need, have, open, symtab,
    1298                                                                 common )
     1261                                                if ( 
     1262                                                        unify( 
     1263                                                                r2->expr->result, r3->expr->result, env, need, have, open, symtab, 
     1264                                                                common ) 
    12991265                                                ) {
    13001266                                                        // generate typed expression
    1301                                                         ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{
     1267                                                        ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{ 
    13021268                                                                conditionalExpr->location, r1->expr, r2->expr, r3->expr };
    13031269                                                        newExpr->result = common ? common : r2->expr->result;
    13041270                                                        // convert both options to result type
    13051271                                                        Cost cost = r1->cost + r2->cost + r3->cost;
    1306                                                         newExpr->arg2 = computeExpressionConversionCost(
     1272                                                        newExpr->arg2 = computeExpressionConversionCost( 
    13071273                                                                newExpr->arg2, newExpr->result, symtab, env, cost );
    13081274                                                        newExpr->arg3 = computeExpressionConversionCost(
     
    13211287                        ast::TypeEnvironment env{ tenv };
    13221288                        ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, symtab, env );
    1323 
     1289                       
    13241290                        CandidateFinder finder2{ symtab, env };
    13251291                        finder2.find( commaExpr->arg2, ResolvMode::withAdjustment() );
     
    13511317                        finder2.find( rangeExpr->high, ResolvMode::withAdjustment() );
    13521318                        if ( finder2.candidates.empty() ) return;
    1353 
    1354                         reason.code = NoMatch;
    13551319
    13561320                        for ( const CandidateRef & r1 : finder1.candidates ) {
     
    13661330
    13671331                                        ast::ptr< ast::Type > common;
    1368                                         if (
    1369                                                 unify(
    1370                                                         r1->expr->result, r2->expr->result, env, need, have, open, symtab,
    1371                                                         common )
     1332                                        if ( 
     1333                                                unify( 
     1334                                                        r1->expr->result, r2->expr->result, env, need, have, open, symtab, 
     1335                                                        common ) 
    13721336                                        ) {
    13731337                                                // generate new expression
    1374                                                 ast::RangeExpr * newExpr =
     1338                                                ast::RangeExpr * newExpr = 
    13751339                                                        new ast::RangeExpr{ rangeExpr->location, r1->expr, r2->expr };
    13761340                                                newExpr->result = common ? common : r1->expr->result;
    13771341                                                // add candidate
    13781342                                                CandidateRef newCand = std::make_shared<Candidate>(
    1379                                                         newExpr, move( env ), move( open ), move( need ),
     1343                                                        newExpr, move( env ), move( open ), move( need ), 
    13801344                                                        r1->cost + r2->cost );
    13811345                                                inferParameters( newCand, candidates );
     
    13861350
    13871351                void postvisit( const ast::UntypedTupleExpr * tupleExpr ) {
    1388                         std::vector< CandidateFinder > subCandidates =
     1352                        std::vector< CandidateFinder > subCandidates = 
    13891353                                selfFinder.findSubExprs( tupleExpr->exprs );
    13901354                        std::vector< CandidateList > possibilities;
     
    14061370
    14071371                                addCandidate(
    1408                                         new ast::TupleExpr{ tupleExpr->location, move( exprs ) },
     1372                                        new ast::TupleExpr{ tupleExpr->location, move( exprs ) }, 
    14091373                                        move( env ), move( open ), move( need ), sumCost( subs ) );
    14101374                        }
     
    14481412                                toType = SymTab::validateType( initExpr->location, toType, symtab );
    14491413                                toType = adjustExprType( toType, tenv, symtab );
    1450                                 // The call to find must occur inside this loop, otherwise polymorphic return
    1451                                 // types are not bound to the initialization type, since return type variables are
    1452                                 // only open for the duration of resolving the UntypedExpr.
     1414                                // The call to find must occur inside this loop, otherwise polymorphic return 
     1415                                // types are not bound to the initialization type, since return type variables are 
     1416                                // only open for the duration of resolving the UntypedExpr. 
    14531417                                CandidateFinder finder{ symtab, tenv, toType };
    14541418                                finder.find( initExpr->expr, ResolvMode::withAdjustment() );
    14551419                                for ( CandidateRef & cand : finder.candidates ) {
    1456                                         if(reason.code == NotFound) reason.code = NoMatch;
    1457 
    14581420                                        ast::TypeEnvironment env{ cand->env };
    14591421                                        ast::AssertionSet need( cand->need.begin(), cand->need.end() ), have;
     
    14641426                                        )
    14651427
    1466                                         // It is possible that a cast can throw away some values in a multiply-valued
    1467                                         // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of
    1468                                         // the subexpression results that are cast directly. The candidate is invalid
     1428                                        // It is possible that a cast can throw away some values in a multiply-valued 
     1429                                        // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of 
     1430                                        // the subexpression results that are cast directly. The candidate is invalid 
    14691431                                        // if it has fewer results than there are types to cast to.
    14701432                                        int discardedValues = cand->expr->result->size() - toType->size();
     
    14731435                                        // unification run for side-effects
    14741436                                        unify( toType, cand->expr->result, env, need, have, open, symtab );
    1475                                         Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
    1476                                                         symtab, env );
    1477 
     1437                                        Cost thisCost = castCost( cand->expr->result, toType, symtab, env );
     1438                                       
    14781439                                        if ( thisCost != Cost::infinity ) {
    14791440                                                // count one safe conversion for each value that is thrown away
    14801441                                                thisCost.incSafe( discardedValues );
    1481                                                 CandidateRef newCand = std::make_shared<Candidate>(
    1482                                                         new ast::InitExpr{
    1483                                                                 initExpr->location, restructureCast( cand->expr, toType ),
    1484                                                                 initAlt.designation },
    1485                                                         move(env), move( open ), move( need ), cand->cost, thisCost );
     1442                                                CandidateRef newCand = std::make_shared<Candidate>( 
     1443                                                        new ast::InitExpr{ 
     1444                                                                initExpr->location, restructureCast( cand->expr, toType ), 
     1445                                                                initAlt.designation }, 
     1446                                                        copy( cand->env ), move( open ), move( need ), cand->cost, thisCost );
    14861447                                                inferParameters( newCand, matches );
    14871448                                        }
     
    15081469        };
    15091470
    1510         // size_t Finder::traceId = Stats::Heap::new_stacktrace_id("Finder");
    1511         /// Prunes a list of candidates down to those that have the minimum conversion cost for a given
     1471        /// Prunes a list of candidates down to those that have the minimum conversion cost for a given
    15121472        /// return type. Skips ambiguous candidates.
    15131473        CandidateList pruneCandidates( CandidateList & candidates ) {
     
    15261486                        {
    15271487                                ast::ptr< ast::Type > newType = candidate->expr->result;
    1528                                 assertf(candidate->expr->result, "Result of expression %p for candidate is null", candidate->expr.get());
    15291488                                candidate->env.apply( newType );
    15301489                                mangleName = Mangle::mangle( newType );
     
    15351494                                if ( candidate->cost < found->second.candidate->cost ) {
    15361495                                        PRINT(
    1537                                                 std::cerr << "cost " << candidate->cost << " beats "
     1496                                                std::cerr << "cost " << candidate->cost << " beats " 
    15381497                                                        << found->second.candidate->cost << std::endl;
    15391498                                        )
     
    15411500                                        found->second = PruneStruct{ candidate };
    15421501                                } else if ( candidate->cost == found->second.candidate->cost ) {
    1543                                         // if one of the candidates contains a deleted identifier, can pick the other,
    1544                                         // since deleted expressions should not be ambiguous if there is another option
     1502                                        // if one of the candidates contains a deleted identifier, can pick the other, 
     1503                                        // since deleted expressions should not be ambiguous if there is another option 
    15451504                                        // that is at least as good
    15461505                                        if ( findDeletedExpr( candidate->expr ) ) {
     
    15561515                                } else {
    15571516                                        PRINT(
    1558                                                 std::cerr << "cost " << candidate->cost << " loses to "
     1517                                                std::cerr << "cost " << candidate->cost << " loses to " 
    15591518                                                        << found->second.candidate->cost << std::endl;
    15601519                                        )
     
    15711530
    15721531                        CandidateRef cand = target.second.candidate;
    1573 
     1532                       
    15741533                        ast::ptr< ast::Type > newResult = cand->expr->result;
    15751534                        cand->env.applyFree( newResult );
    15761535                        cand->expr = ast::mutate_field(
    15771536                                cand->expr.get(), &ast::Expr::result, move( newResult ) );
    1578 
     1537                       
    15791538                        out.emplace_back( cand );
    15801539                }
     
    15901549
    15911550        if ( mode.failFast && candidates.empty() ) {
    1592                 switch(finder.core.reason.code) {
    1593                 case Finder::NotFound:
    1594                         { SemanticError( expr, "No alternatives for expression " ); break; }
    1595                 case Finder::NoMatch:
    1596                         { SemanticError( expr, "Invalid application of existing declaration(s) in expression " ); break; }
    1597                 case Finder::ArgsToFew:
    1598                 case Finder::ArgsToMany:
    1599                 case Finder::RetsToFew:
    1600                 case Finder::RetsToMany:
    1601                 case Finder::NoReason:
    1602                 default:
    1603                         { SemanticError( expr->location, "No reasonable alternatives for expression : reasons unkown" ); }
    1604                 }
     1551                SemanticError( expr, "No reasonable alternatives for expression " );
    16051552        }
    16061553
     
    16111558                std::vector< std::string > errors;
    16121559                for ( CandidateRef & candidate : candidates ) {
    1613                         satisfyAssertions( candidate, localSyms, satisfied, errors );
     1560                        satisfyAssertions( candidate, symtab, satisfied, errors );
    16141561                }
    16151562
     
    16361583
    16371584                CandidateList pruned = pruneCandidates( candidates );
    1638 
     1585               
    16391586                if ( mode.failFast && pruned.empty() ) {
    16401587                        std::ostringstream stream;
     
    16551602                )
    16561603                PRINT(
    1657                         std::cerr << "there are " << candidates.size() << " alternatives after elimination"
     1604                        std::cerr << "there are " << candidates.size() << " alternatives after elimination" 
    16581605                                << std::endl;
    16591606                )
    16601607        }
    16611608
    1662         // adjust types after pruning so that types substituted by pruneAlternatives are correctly
     1609        // adjust types after pruning so that types substituted by pruneAlternatives are correctly 
    16631610        // adjusted
    16641611        if ( mode.adjust ) {
    16651612                for ( CandidateRef & r : candidates ) {
    1666                         r->expr = ast::mutate_field(
    1667                                 r->expr.get(), &ast::Expr::result,
    1668                                 adjustExprType( r->expr->result, r->env, localSyms ) );
     1613                        r->expr = ast::mutate_field( 
     1614                                r->expr.get(), &ast::Expr::result, 
     1615                                adjustExprType( r->expr->result, r->env, symtab ) );
    16691616                }
    16701617        }
     
    16781625}
    16791626
    1680 std::vector< CandidateFinder > CandidateFinder::findSubExprs(
    1681         const std::vector< ast::ptr< ast::Expr > > & xs
     1627std::vector< CandidateFinder > CandidateFinder::findSubExprs( 
     1628        const std::vector< ast::ptr< ast::Expr > > & xs 
    16821629) {
    16831630        std::vector< CandidateFinder > out;
    16841631
    16851632        for ( const auto & x : xs ) {
    1686                 out.emplace_back( localSyms, env );
     1633                out.emplace_back( symtab, env );
    16871634                out.back().find( x, ResolvMode::withAdjustment() );
    1688 
     1635               
    16891636                PRINT(
    16901637                        std::cerr << "findSubExprs" << std::endl;
Note: See TracChangeset for help on using the changeset viewer.