Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r18e683b r4e13e2a  
    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, const ast::SymbolTable & symtab, 
    65         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(
     
    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        ) {
    112112                Cost convCost = computeConversionCost( arg->result, paramType, symtab, env );
    113113                outCost += convCost;
    114114
    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 
     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
    117117                // infer parameters and this does not currently work for the reason stated below
    118118                Cost tmpCost = convCost;
     
    123123                        return new ast::CastExpr{ arg, newType };
    124124
    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, 
     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,
    127127                        // once this is fixed it should be possible to resolve the cast.
    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 
     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
    130130                        // commontype(zero_t, DT*) is DT*, rather than nothing
    131131
    132132                        // CandidateFinder finder{ symtab, env };
    133133                        // finder.find( arg, ResolvMode::withAdjustment() );
    134                         // assertf( finder.candidates.size() > 0, 
     134                        // assertf( finder.candidates.size() > 0,
    135135                        //      "Somehow castable expression failed to find alternatives." );
    136                         // assertf( finder.candidates.size() == 1, 
     136                        // assertf( finder.candidates.size() == 1,
    137137                        //      "Somehow got multiple alternatives for known cast expression." );
    138138                        // return finder.candidates.front()->expr;
     
    143143
    144144        /// Computes conversion cost for a given candidate
    145         Cost computeApplicationConversionCost( 
    146                 CandidateRef cand, const ast::SymbolTable & symtab 
     145        Cost computeApplicationConversionCost(
     146                CandidateRef cand, const ast::SymbolTable & symtab
    147147        ) {
    148148                auto appExpr = cand->expr.strict_as< ast::ApplicationExpr >();
     
    167167                                if ( function->isVarArgs ) {
    168168                                        convCost.incUnsafe();
    169                                         PRINT( std::cerr << "end of params with varargs function: inc unsafe: " 
     169                                        PRINT( std::cerr << "end of params with varargs function: inc unsafe: "
    170170                                                << convCost << std::endl; ; )
    171171                                        // convert reference-typed expressions into value-typed expressions
    172                                         cand->expr = ast::mutate_field_index( 
    173                                                 appExpr, &ast::ApplicationExpr::args, i, 
     172                                        cand->expr = ast::mutate_field_index(
     173                                                appExpr, &ast::ApplicationExpr::args, i,
    174174                                                referenceToRvalueConversion( args[i], convCost ) );
    175175                                        continue;
     
    180180                                // Default arguments should be free - don't include conversion cost.
    181181                                // Unwrap them here because they are not relevant to the rest of the system
    182                                 cand->expr = ast::mutate_field_index( 
     182                                cand->expr = ast::mutate_field_index(
    183183                                        appExpr, &ast::ApplicationExpr::args, i, def->expr );
    184184                                ++param;
     
    188188                        // mark conversion cost and also specialization cost of param type
    189189                        const ast::Type * paramType = (*param)->get_type();
    190                         cand->expr = ast::mutate_field_index( 
    191                                 appExpr, &ast::ApplicationExpr::args, i, 
    192                                 computeExpressionConversionCost( 
     190                        cand->expr = ast::mutate_field_index(
     191                                appExpr, &ast::ApplicationExpr::args, i,
     192                                computeExpressionConversionCost(
    193193                                        args[i], paramType, symtab, cand->env, convCost ) );
    194194                        convCost.decSpec( specCost( paramType ) );
     
    198198                if ( param != params.end() ) return Cost::infinity;
    199199
    200                 // 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
    201201                // otherwise-identical calls, like this example based on auto-newline in the I/O lib:
    202202                //
     
    215215        }
    216216
    217         void makeUnifiableVars( 
    218                 const ast::ParameterizedType * type, ast::OpenVarSet & unifiableVars, 
    219                 ast::AssertionSet & need 
     217        void makeUnifiableVars(
     218                const ast::ParameterizedType * type, ast::OpenVarSet & unifiableVars,
     219                ast::AssertionSet & need
    220220        ) {
    221221                for ( const ast::TypeDecl * tyvar : type->forall ) {
     
    254254
    255255                ArgPack()
    256                 : 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 ),
    257257                  tupleStart( 0 ), nextExpl( 0 ), explAlt( 0 ) {}
    258                
    259                 ArgPack( 
    260                         const ast::TypeEnvironment & env, const ast::AssertionSet & need, 
     258
     259                ArgPack(
     260                        const ast::TypeEnvironment & env, const ast::AssertionSet & need,
    261261                        const ast::AssertionSet & have, const ast::OpenVarSet & open )
    262                 : parent( 0 ), expr(), cost( Cost::zero ), env( env ), need( need ), have( have ), 
     262                : parent( 0 ), expr(), cost( Cost::zero ), env( env ), need( need ), have( have ),
    263263                  open( open ), nextArg( 0 ), tupleStart( 0 ), nextExpl( 0 ), explAlt( 0 ) {}
    264                
     264
    265265                ArgPack(
    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, 
     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,
    269269                        unsigned nextExpl = 0, unsigned explAlt = 0 )
    270270                : parent(parent), expr( expr ), cost( cost ), env( move( env ) ), need( move( need ) ),
    271271                  have( move( have ) ), open( move( open ) ), nextArg( nextArg ), tupleStart( tupleStart ),
    272272                  nextExpl( nextExpl ), explAlt( explAlt ) {}
    273                
     273
    274274                ArgPack(
    275                         const ArgPack & o, ast::TypeEnvironment && env, ast::AssertionSet && need, 
     275                        const ArgPack & o, ast::TypeEnvironment && env, ast::AssertionSet && need,
    276276                        ast::AssertionSet && have, ast::OpenVarSet && open, unsigned nextArg, Cost added )
    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 ), 
     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 ),
    279279                  tupleStart( o.tupleStart ), nextExpl( 0 ), explAlt( 0 ) {}
    280                
     280
    281281                /// true if this pack is in the middle of an exploded argument
    282282                bool hasExpl() const { return nextExpl > 0; }
     
    286286                        return args[ nextArg-1 ][ explAlt ];
    287287                }
    288                
     288
    289289                /// Ends a tuple expression, consolidating the appropriate args
    290290                void endTuple( const std::vector< ArgPack > & packs ) {
     
    307307
    308308        /// Instantiates an argument to match a parameter, returns false if no matching results left
    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 
     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
    313313        ) {
    314314                if ( auto tupleType = dynamic_cast< const ast::TupleType * >( paramType ) ) {
     
    318318                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    319319                                // ^^^ need to handle the case where a tuple has a default argument
    320                                 if ( ! instantiateArgument( 
     320                                if ( ! instantiateArgument(
    321321                                        type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;
    322322                                nTuples = 0;
     
    329329                } else if ( const ast::TypeInstType * ttype = Tuples::isTtype( paramType ) ) {
    330330                        // paramType is a ttype, consumes all remaining arguments
    331                        
     331
    332332                        // completed tuples; will be spliced to end of results to finish
    333333                        std::vector< ArgPack > finalResults{};
     
    342342                                for ( std::size_t i = genStart; i < genEnd; ++i ) {
    343343                                        unsigned nextArg = results[i].nextArg;
    344                                        
     344
    345345                                        // use next element of exploded tuple if present
    346346                                        if ( results[i].hasExpl() ) {
     
    352352                                                results.emplace_back(
    353353                                                        i, expl.exprs[ results[i].nextExpl ], copy( results[i].env ),
    354                                                         copy( results[i].need ), copy( results[i].have ), 
     354                                                        copy( results[i].need ), copy( results[i].have ),
    355355                                                        copy( results[i].open ), nextArg, nTuples, Cost::zero, nextExpl,
    356356                                                        results[i].explAlt );
     
    370370                                                        // push empty tuple expression
    371371                                                        newResult.parent = i;
    372                                                         std::vector< ast::ptr< ast::Expr > > emptyList;
    373                                                         newResult.expr =
    374                                                                 new ast::TupleExpr{ CodeLocation{}, move( emptyList ) };
     372                                                        newResult.expr = new ast::TupleExpr{ CodeLocation{}, {} };
    375373                                                        argType = newResult.expr->result;
    376374                                                } else {
     
    400398
    401399                                                // check unification for ttype before adding to final
    402                                                 if ( 
    403                                                         unify( 
     400                                                if (
     401                                                        unify(
    404402                                                                ttype, argType, newResult.env, newResult.need, newResult.have,
    405                                                                 newResult.open, symtab ) 
     403                                                                newResult.open, symtab )
    406404                                                ) {
    407405                                                        finalResults.emplace_back( move( newResult ) );
     
    424422                                                if ( expl.exprs.empty() ) {
    425423                                                        results.emplace_back(
    426                                                                 results[i], move( env ), copy( results[i].need ), 
     424                                                                results[i], move( env ), copy( results[i].need ),
    427425                                                                copy( results[i].have ), move( open ), nextArg + 1, expl.cost );
    428                                                        
     426
    429427                                                        continue;
    430428                                                }
     
    432430                                                // add new result
    433431                                                results.emplace_back(
    434                                                         i, expl.exprs.front(), move( env ), copy( results[i].need ), 
    435                                                         copy( results[i].have ), move( open ), nextArg + 1, nTuples, 
     432                                                        i, expl.exprs.front(), move( env ), copy( results[i].need ),
     433                                                        copy( results[i].have ), move( open ), nextArg + 1, nTuples,
    436434                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    437435                                        }
     
    479477
    480478                                        results.emplace_back(
    481                                                 i, expr, move( env ), move( need ), move( have ), move( open ), nextArg, 
     479                                                i, expr, move( env ), move( need ), move( have ), move( open ), nextArg,
    482480                                                nTuples, Cost::zero, nextExpl, results[i].explAlt );
    483481                                }
     
    495493                                        if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) {
    496494                                                results.emplace_back(
    497                                                         i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ), 
     495                                                        i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ),
    498496                                                        move( need ), move( have ), move( open ), nextArg, nTuples );
    499497                                        }
     
    517515                                if ( expl.exprs.empty() ) {
    518516                                        results.emplace_back(
    519                                                 results[i], move( env ), move( need ), move( have ), move( open ), 
     517                                                results[i], move( env ), move( need ), move( have ), move( open ),
    520518                                                nextArg + 1, expl.cost );
    521                                        
     519
    522520                                        continue;
    523521                                }
     
    539537                                        // add new result
    540538                                        results.emplace_back(
    541                                                 i, expr, move( env ), move( need ), move( have ), move( open ), 
     539                                                i, expr, move( env ), move( need ), move( have ), move( open ),
    542540                                                nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    543541                                }
     
    548546                genStart = genEnd;
    549547
    550                 return genEnd != results.size();
     548                return genEnd != results.size();  // were any new results added?
    551549        }
    552550
    553551        /// Generate a cast expression from `arg` to `toType`
    554         const ast::Expr * restructureCast( 
     552        const ast::Expr * restructureCast(
    555553                ast::ptr< ast::Expr > & arg, const ast::Type * toType, ast::GeneratedFlag isGenerated = ast::GeneratedCast
    556554        ) {
    557                 if ( 
    558                         arg->result->size() > 1 
    559                         && ! toType->isVoid() 
    560                         && ! dynamic_cast< const ast::ReferenceType * >( toType ) 
     555                if (
     556                        arg->result->size() > 1
     557                        && ! toType->isVoid()
     558                        && ! dynamic_cast< const ast::ReferenceType * >( toType )
    561559                ) {
    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 
     560                        // Argument is a tuple and the target type is neither void nor a reference. Cast each
     561                        // member of the tuple to its corresponding target type, producing the tuple of those
     562                        // cast expressions. If there are more components of the tuple than components in the
     563                        // target type, then excess components do not come out in the result expression (but
    566564                        // UniqueExpr ensures that the side effects will still be produced)
    567565                        if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    568                                 // expressions which may contain side effects require a single unique instance of 
     566                                // expressions which may contain side effects require a single unique instance of
    569567                                // the expression
    570568                                arg = new ast::UniqueExpr{ arg->location, arg };
     
    574572                                // cast each component
    575573                                ast::ptr< ast::Expr > idx = new ast::TupleIndexExpr{ arg->location, arg, i };
    576                                 components.emplace_back( 
     574                                components.emplace_back(
    577575                                        restructureCast( idx, toType->getComponent( i ), isGenerated ) );
    578576                        }
     
    594592
    595593        /// Actually visits expressions to find their candidate interpretations
    596         struct Finder final : public ast::WithShortCircuiting {
     594        class Finder final : public ast::WithShortCircuiting {
     595                const ast::SymbolTable & symtab;
     596        public:
    597597                CandidateFinder & selfFinder;
    598                 const ast::SymbolTable & symtab;
    599598                CandidateList & candidates;
    600599                const ast::TypeEnvironment & tenv;
     
    602601
    603602                Finder( CandidateFinder & f )
    604                 : selfFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),
     603                : symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ),
    605604                  targetType( f.targetType ) {}
    606                
     605
    607606                void previsit( const ast::Node * ) { visit_children = false; }
    608607
     
    639638
    640639                /// Completes a function candidate with arguments located
    641                 void validateFunctionCandidate( 
    642                         const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results, 
    643                         CandidateList & out 
     640                void validateFunctionCandidate(
     641                        const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results,
     642                        CandidateList & out
    644643                ) {
    645                         ast::ApplicationExpr * appExpr = 
     644                        ast::ApplicationExpr * appExpr =
    646645                                new ast::ApplicationExpr{ func->expr->location, func->expr };
    647646                        // sum cost and accumulate arguments
     
    657656                        appExpr->args = move( vargs );
    658657                        // build and validate new candidate
    659                         auto newCand = 
     658                        auto newCand =
    660659                                std::make_shared<Candidate>( appExpr, result.env, result.open, result.need, cost );
    661660                        PRINT(
     
    669668                /// Builds a list of candidates for a function, storing them in out
    670669                void makeFunctionCandidates(
    671                         const CandidateRef & func, const ast::FunctionType * funcType, 
     670                        const CandidateRef & func, const ast::FunctionType * funcType,
    672671                        const ExplodedArgs_new & args, CandidateList & out
    673672                ) {
     
    676675                        ast::TypeEnvironment funcEnv{ func->env };
    677676                        makeUnifiableVars( funcType, funcOpen, funcNeed );
    678                         // add all type variables as open variables now so that those not used in the parameter
    679                         // list are still considered open
     677                        // add all type variables as open variables now so that those not used in the
     678                        // parameter list are still considered open
    680679                        funcEnv.add( funcType->forall );
    681680
     
    683682                                // attempt to narrow based on expected target type
    684683                                const ast::Type * returnType = funcType->returns.front()->get_type();
    685                                 if ( ! unify( 
    686                                         returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) 
     684                                if ( ! unify(
     685                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
    687686                                ) {
    688687                                        // unification failed, do not pursue this candidate
     
    698697                        for ( const ast::DeclWithType * param : funcType->params ) {
    699698                                auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
    700                                 // Try adding the arguments corresponding to the current parameter to the existing 
     699                                // Try adding the arguments corresponding to the current parameter to the existing
    701700                                // matches
    702                                 if ( ! instantiateArgument( 
     701                                if ( ! instantiateArgument(
    703702                                        obj->type, obj->init, args, results, genStart, symtab ) ) return;
    704703                        }
     
    750749                                                        if ( expl.exprs.empty() ) {
    751750                                                                results.emplace_back(
    752                                                                         results[i], move( env ), copy( results[i].need ), 
    753                                                                         copy( results[i].have ), move( open ), nextArg + 1, 
     751                                                                        results[i], move( env ), copy( results[i].need ),
     752                                                                        copy( results[i].have ), move( open ), nextArg + 1,
    754753                                                                        expl.cost );
    755754
     
    760759                                                        results.emplace_back(
    761760                                                                i, expl.exprs.front(), move( env ), copy( results[i].need ),
    762                                                                 copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost, 
     761                                                                copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost,
    763762                                                                expl.exprs.size() == 1 ? 0 : 1, j );
    764763                                                }
     
    780779                /// Adds implicit struct-conversions to the alternative list
    781780                void addAnonConversions( const CandidateRef & cand ) {
    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 
     781                        // adds anonymous member interpretations whenever an aggregate value type is seen.
     782                        // it's okay for the aggregate expression to have reference type -- cast it to the
    784783                        // base type to treat the aggregate as the referenced value
    785784                        ast::ptr< ast::Expr > aggrExpr( cand->expr );
    786785                        ast::ptr< ast::Type > & aggrType = aggrExpr.get_and_mutate()->result;
    787786                        cand->env.apply( aggrType );
    788                        
     787
    789788                        if ( aggrType.as< ast::ReferenceType >() ) {
    790789                                aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() };
     
    799798
    800799                /// Adds aggregate member interpretations
    801                 void addAggMembers( 
    802                         const ast::ReferenceToType * aggrInst, const ast::Expr * expr, 
    803                         const Candidate & cand, const Cost & addedCost, const std::string & name 
     800                void addAggMembers(
     801                        const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
     802                        const Candidate & cand, const Cost & addedCost, const std::string & name
    804803                ) {
    805804                        for ( const ast::Decl * decl : aggrInst->lookup( name ) ) {
    806805                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( decl );
    807                                 CandidateRef newCand = std::make_shared<Candidate>( 
     806                                CandidateRef newCand = std::make_shared<Candidate>(
    808807                                        cand, new ast::MemberExpr{ expr->location, dwt, expr }, addedCost );
    809                                 // add anonymous member interpretations whenever an aggregate value type is seen 
     808                                // add anonymous member interpretations whenever an aggregate value type is seen
    810809                                // as a member expression
    811810                                addAnonConversions( newCand );
     
    815814
    816815                /// Adds tuple member interpretations
    817                 void addTupleMembers( 
    818                         const ast::TupleType * tupleType, const ast::Expr * expr, const Candidate & cand, 
    819                         const Cost & addedCost, const ast::Expr * member 
     816                void addTupleMembers(
     817                        const ast::TupleType * tupleType, const ast::Expr * expr, const Candidate & cand,
     818                        const Cost & addedCost, const ast::Expr * member
    820819                ) {
    821820                        if ( auto constantExpr = dynamic_cast< const ast::ConstantExpr * >( member ) ) {
    822                                 // get the value of the constant expression as an int, must be between 0 and the 
     821                                // get the value of the constant expression as an int, must be between 0 and the
    823822                                // length of the tuple to have meaning
    824823                                long long val = constantExpr->intValue();
    825824                                if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    826825                                        addCandidate(
    827                                                 cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val }, 
     826                                                cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val },
    828827                                                addedCost );
    829828                                }
     
    837836                        if ( funcFinder.candidates.empty() ) return;
    838837
    839                         std::vector< CandidateFinder > argCandidates = 
     838                        std::vector< CandidateFinder > argCandidates =
    840839                                selfFinder.findSubExprs( untypedExpr->args );
    841                        
     840
    842841                        // take care of possible tuple assignments
    843842                        // if not tuple assignment, handled as normal function call
     
    877876                                                if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    878877                                                        CandidateRef newFunc{ new Candidate{ *func } };
    879                                                         newFunc->expr = 
     878                                                        newFunc->expr =
    880879                                                                referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    881880                                                        makeFunctionCandidates( newFunc, function, argExpansions, found );
    882881                                                }
    883                                         } else if ( 
    884                                                 auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult ) 
     882                                        } else if (
     883                                                auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult )
    885884                                        ) {
    886885                                                if ( const ast::EqvClass * clz = func->env.lookup( inst->name ) ) {
    887886                                                        if ( auto function = clz->bound.as< ast::FunctionType >() ) {
    888887                                                                CandidateRef newFunc{ new Candidate{ *func } };
    889                                                                 newFunc->expr = 
     888                                                                newFunc->expr =
    890889                                                                        referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    891890                                                                makeFunctionCandidates( newFunc, function, argExpansions, found );
     
    901900                                std::vector< ExplodedArg > funcE;
    902901                                funcE.reserve( funcFinder.candidates.size() );
    903                                 for ( const CandidateRef & func : funcFinder ) { 
     902                                for ( const CandidateRef & func : funcFinder ) {
    904903                                        funcE.emplace_back( *func, symtab );
    905904                                }
     
    913912                                                        if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    914913                                                                CandidateRef newOp{ new Candidate{ *op} };
    915                                                                 newOp->expr = 
     914                                                                newOp->expr =
    916915                                                                        referenceToRvalueConversion( newOp->expr, newOp->cost );
    917916                                                                makeFunctionCandidates( newOp, function, argExpansions, found );
     
    922921                        }
    923922
    924                         // Implement SFINAE; resolution errors are only errors if there aren't any non-error 
     923                        // Implement SFINAE; resolution errors are only errors if there aren't any non-error
    925924                        // candidates
    926925                        if ( found.empty() && ! errors.isEmpty() ) { throw errors; }
     
    934933                                        auto pointer = appExpr->func->result.strict_as< ast::PointerType >();
    935934                                        auto function = pointer->base.strict_as< ast::FunctionType >();
    936                                        
     935
    937936                                        std::cerr << "Case +++++++++++++ " << appExpr->func << std::endl;
    938937                                        std::cerr << "parameters are:" << std::endl;
     
    957956                        promoteCvtCost( winners );
    958957
    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 
     958                        // function may return a struct/union value, in which case we need to add candidates
     959                        // for implicit conversions to each of the anonymous members, which must happen after
    961960                        // `findMinCost`, since anon conversions are never the cheapest
    962961                        for ( const CandidateRef & c : winners ) {
     
    966965
    967966                        if ( candidates.empty() && targetType && ! targetType->isVoid() ) {
    968                                 // If resolution is unsuccessful with a target type, try again without, since it 
     967                                // If resolution is unsuccessful with a target type, try again without, since it
    969968                                // will sometimes succeed when it wouldn't with a target type binding.
    970969                                // For example:
     
    10161015                                cand->env.extractOpenVars( open );
    10171016
    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 
     1017                                // It is possible that a cast can throw away some values in a multiply-valued
     1018                                // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of the
     1019                                // subexpression results that are cast directly. The candidate is invalid if it
    10211020                                // has fewer results than there are types to cast to.
    10221021                                int discardedValues = cand->expr->result->size() - toType->size();
     
    10371036                                        // count one safe conversion for each value that is thrown away
    10381037                                        thisCost.incSafe( discardedValues );
    1039                                         CandidateRef newCand = std::make_shared<Candidate>( 
    1040                                                 restructureCast( cand->expr, toType, castExpr->isGenerated ), 
    1041                                                 copy( cand->env ), move( open ), move( need ), cand->cost, 
     1038                                        CandidateRef newCand = std::make_shared<Candidate>(
     1039                                                restructureCast( cand->expr, toType, castExpr->isGenerated ),
     1040                                                copy( cand->env ), move( open ), move( need ), cand->cost,
    10421041                                                cand->cost + thisCost );
    10431042                                        inferParameters( newCand, matches );
     
    10571056                        finder.find( castExpr->arg, ResolvMode::withoutPrune() );
    10581057                        for ( CandidateRef & r : finder.candidates ) {
    1059                                 addCandidate( 
    1060                                         *r, 
     1058                                addCandidate(
     1059                                        *r,
    10611060                                        new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } );
    10621061                        }
     
    10671066                        aggFinder.find( memberExpr->aggregate, ResolvMode::withAdjustment() );
    10681067                        for ( CandidateRef & agg : aggFinder.candidates ) {
    1069                                 // it's okay for the aggregate expression to have reference type -- cast it to the 
     1068                                // it's okay for the aggregate expression to have reference type -- cast it to the
    10701069                                // base type to treat the aggregate as the referenced value
    10711070                                Cost addedCost = Cost::zero;
     
    10741073                                // find member of the given type
    10751074                                if ( auto structInst = agg->expr->result.as< ast::StructInstType >() ) {
    1076                                         addAggMembers( 
     1075                                        addAggMembers(
    10771076                                                structInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    10781077                                } else if ( auto unionInst = agg->expr->result.as< ast::UnionInstType >() ) {
    1079                                         addAggMembers( 
     1078                                        addAggMembers(
    10801079                                                unionInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    10811080                                } else if ( auto tupleType = agg->expr->result.as< ast::TupleType >() ) {
     
    10971096
    10981097                                CandidateRef newCand = std::make_shared<Candidate>(
    1099                                         newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero, 
     1098                                        newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
    11001099                                        cost );
    11011100                                PRINT(
     
    11071106                                        std::cerr << std::endl;
    11081107                                )
    1109                                 newCand->expr = ast::mutate_field( 
    1110                                         newCand->expr.get(), &ast::Expr::result, 
     1108                                newCand->expr = ast::mutate_field(
     1109                                        newCand->expr.get(), &ast::Expr::result,
    11111110                                        renameTyVars( newCand->expr->result ) );
    1112                                 // add anonymous member interpretations whenever an aggregate value type is seen 
     1111                                // add anonymous member interpretations whenever an aggregate value type is seen
    11131112                                // as a name expression
    11141113                                addAnonConversions( newCand );
     
    11201119                        // not sufficient to just pass `variableExpr` here, type might have changed since
    11211120                        // creation
    1122                         addCandidate( 
     1121                        addCandidate(
    11231122                                new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv );
    11241123                }
     
    11301129                void postvisit( const ast::SizeofExpr * sizeofExpr ) {
    11311130                        if ( sizeofExpr->type ) {
    1132                                 addCandidate( 
    1133                                         new ast::SizeofExpr{ 
    1134                                                 sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) }, 
     1131                                addCandidate(
     1132                                        new ast::SizeofExpr{
     1133                                                sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) },
    11351134                                        tenv );
    11361135                        } else {
     
    11411140                                CandidateList winners = findMinCost( finder.candidates );
    11421141                                if ( winners.size() != 1 ) {
    1143                                         SemanticError( 
     1142                                        SemanticError(
    11441143                                                sizeofExpr->expr.get(), "Ambiguous expression in sizeof operand: " );
    11451144                                }
     
    11541153                void postvisit( const ast::AlignofExpr * alignofExpr ) {
    11551154                        if ( alignofExpr->type ) {
    1156                                 addCandidate( 
    1157                                         new ast::AlignofExpr{ 
    1158                                                 alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) }, 
     1155                                addCandidate(
     1156                                        new ast::AlignofExpr{
     1157                                                alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) },
    11591158                                        tenv );
    11601159                        } else {
     
    11651164                                CandidateList winners = findMinCost( finder.candidates );
    11661165                                if ( winners.size() != 1 ) {
    1167                                         SemanticError( 
     1166                                        SemanticError(
    11681167                                                alignofExpr->expr.get(), "Ambiguous expression in alignof operand: " );
    11691168                                }
     
    11721171                                choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    11731172                                choice->cost = Cost::zero;
    1174                                 addCandidate( 
     1173                                addCandidate(
    11751174                                        *choice, new ast::AlignofExpr{ alignofExpr->location, choice->expr } );
    11761175                        }
     
    11851184                        for ( const ast::Decl * member : aggInst->lookup( offsetofExpr->member ) ) {
    11861185                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( member );
    1187                                 addCandidate( 
     1186                                addCandidate(
    11881187                                        new ast::OffsetofExpr{ offsetofExpr->location, aggInst, dwt }, tenv );
    11891188                        }
     
    12181217
    12191218                                        addCandidate(
    1220                                                 new ast::LogicalExpr{ 
     1219                                                new ast::LogicalExpr{
    12211220                                                        logicalExpr->location, r1->expr, r2->expr, logicalExpr->isAnd },
    12221221                                                move( env ), move( open ), move( need ), r1->cost + r2->cost );
     
    12561255                                                ast::AssertionSet have;
    12571256
    1258                                                 // unify true and false results, then infer parameters to produce new 
     1257                                                // unify true and false results, then infer parameters to produce new
    12591258                                                // candidates
    12601259                                                ast::ptr< ast::Type > common;
    1261                                                 if ( 
    1262                                                         unify( 
    1263                                                                 r2->expr->result, r3->expr->result, env, need, have, open, symtab, 
    1264                                                                 common ) 
     1260                                                if (
     1261                                                        unify(
     1262                                                                r2->expr->result, r3->expr->result, env, need, have, open, symtab,
     1263                                                                common )
    12651264                                                ) {
    12661265                                                        // generate typed expression
    1267                                                         ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{ 
     1266                                                        ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{
    12681267                                                                conditionalExpr->location, r1->expr, r2->expr, r3->expr };
    12691268                                                        newExpr->result = common ? common : r2->expr->result;
    12701269                                                        // convert both options to result type
    12711270                                                        Cost cost = r1->cost + r2->cost + r3->cost;
    1272                                                         newExpr->arg2 = computeExpressionConversionCost( 
     1271                                                        newExpr->arg2 = computeExpressionConversionCost(
    12731272                                                                newExpr->arg2, newExpr->result, symtab, env, cost );
    12741273                                                        newExpr->arg3 = computeExpressionConversionCost(
     
    12871286                        ast::TypeEnvironment env{ tenv };
    12881287                        ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, symtab, env );
    1289                        
     1288
    12901289                        CandidateFinder finder2{ symtab, env };
    12911290                        finder2.find( commaExpr->arg2, ResolvMode::withAdjustment() );
     
    13301329
    13311330                                        ast::ptr< ast::Type > common;
    1332                                         if ( 
    1333                                                 unify( 
    1334                                                         r1->expr->result, r2->expr->result, env, need, have, open, symtab, 
    1335                                                         common ) 
     1331                                        if (
     1332                                                unify(
     1333                                                        r1->expr->result, r2->expr->result, env, need, have, open, symtab,
     1334                                                        common )
    13361335                                        ) {
    13371336                                                // generate new expression
    1338                                                 ast::RangeExpr * newExpr = 
     1337                                                ast::RangeExpr * newExpr =
    13391338                                                        new ast::RangeExpr{ rangeExpr->location, r1->expr, r2->expr };
    13401339                                                newExpr->result = common ? common : r1->expr->result;
    13411340                                                // add candidate
    13421341                                                CandidateRef newCand = std::make_shared<Candidate>(
    1343                                                         newExpr, move( env ), move( open ), move( need ), 
     1342                                                        newExpr, move( env ), move( open ), move( need ),
    13441343                                                        r1->cost + r2->cost );
    13451344                                                inferParameters( newCand, candidates );
     
    13501349
    13511350                void postvisit( const ast::UntypedTupleExpr * tupleExpr ) {
    1352                         std::vector< CandidateFinder > subCandidates = 
     1351                        std::vector< CandidateFinder > subCandidates =
    13531352                                selfFinder.findSubExprs( tupleExpr->exprs );
    13541353                        std::vector< CandidateList > possibilities;
     
    13701369
    13711370                                addCandidate(
    1372                                         new ast::TupleExpr{ tupleExpr->location, move( exprs ) }, 
     1371                                        new ast::TupleExpr{ tupleExpr->location, move( exprs ) },
    13731372                                        move( env ), move( open ), move( need ), sumCost( subs ) );
    13741373                        }
     
    14121411                                toType = SymTab::validateType( initExpr->location, toType, symtab );
    14131412                                toType = adjustExprType( toType, tenv, symtab );
    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. 
     1413                                // The call to find must occur inside this loop, otherwise polymorphic return
     1414                                // types are not bound to the initialization type, since return type variables are
     1415                                // only open for the duration of resolving the UntypedExpr.
    14171416                                CandidateFinder finder{ symtab, tenv, toType };
    14181417                                finder.find( initExpr->expr, ResolvMode::withAdjustment() );
     
    14261425                                        )
    14271426
    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 
     1427                                        // It is possible that a cast can throw away some values in a multiply-valued
     1428                                        // expression, e.g. cast-to-void, one value to zero. Figure out the prefix of
     1429                                        // the subexpression results that are cast directly. The candidate is invalid
    14311430                                        // if it has fewer results than there are types to cast to.
    14321431                                        int discardedValues = cand->expr->result->size() - toType->size();
     
    14361435                                        unify( toType, cand->expr->result, env, need, have, open, symtab );
    14371436                                        Cost thisCost = castCost( cand->expr->result, toType, symtab, env );
    1438                                        
     1437
    14391438                                        if ( thisCost != Cost::infinity ) {
    14401439                                                // count one safe conversion for each value that is thrown away
    14411440                                                thisCost.incSafe( discardedValues );
    1442                                                 CandidateRef newCand = std::make_shared<Candidate>( 
    1443                                                         new ast::InitExpr{ 
    1444                                                                 initExpr->location, restructureCast( cand->expr, toType ), 
    1445                                                                 initAlt.designation }, 
     1441                                                CandidateRef newCand = std::make_shared<Candidate>(
     1442                                                        new ast::InitExpr{
     1443                                                                initExpr->location, restructureCast( cand->expr, toType ),
     1444                                                                initAlt.designation },
    14461445                                                        copy( cand->env ), move( open ), move( need ), cand->cost, thisCost );
    14471446                                                inferParameters( newCand, matches );
     
    14691468        };
    14701469
    1471         /// Prunes a list of candidates down to those that have the minimum conversion cost for a given 
     1470        /// Prunes a list of candidates down to those that have the minimum conversion cost for a given
    14721471        /// return type. Skips ambiguous candidates.
    14731472        CandidateList pruneCandidates( CandidateList & candidates ) {
     
    14861485                        {
    14871486                                ast::ptr< ast::Type > newType = candidate->expr->result;
     1487                                assertf(candidate->expr->result, "Result of expression %p for candidate is null", candidate->expr.get());
    14881488                                candidate->env.apply( newType );
    14891489                                mangleName = Mangle::mangle( newType );
     
    14941494                                if ( candidate->cost < found->second.candidate->cost ) {
    14951495                                        PRINT(
    1496                                                 std::cerr << "cost " << candidate->cost << " beats " 
     1496                                                std::cerr << "cost " << candidate->cost << " beats "
    14971497                                                        << found->second.candidate->cost << std::endl;
    14981498                                        )
     
    15001500                                        found->second = PruneStruct{ candidate };
    15011501                                } else if ( candidate->cost == found->second.candidate->cost ) {
    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 
     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
    15041504                                        // that is at least as good
    15051505                                        if ( findDeletedExpr( candidate->expr ) ) {
     
    15151515                                } else {
    15161516                                        PRINT(
    1517                                                 std::cerr << "cost " << candidate->cost << " loses to " 
     1517                                                std::cerr << "cost " << candidate->cost << " loses to "
    15181518                                                        << found->second.candidate->cost << std::endl;
    15191519                                        )
     
    15301530
    15311531                        CandidateRef cand = target.second.candidate;
    1532                        
     1532
    15331533                        ast::ptr< ast::Type > newResult = cand->expr->result;
    15341534                        cand->env.applyFree( newResult );
    15351535                        cand->expr = ast::mutate_field(
    15361536                                cand->expr.get(), &ast::Expr::result, move( newResult ) );
    1537                        
     1537
    15381538                        out.emplace_back( cand );
    15391539                }
     
    15581558                std::vector< std::string > errors;
    15591559                for ( CandidateRef & candidate : candidates ) {
    1560                         satisfyAssertions( candidate, symtab, satisfied, errors );
     1560                        satisfyAssertions( candidate, localSyms, satisfied, errors );
    15611561                }
    15621562
     
    15831583
    15841584                CandidateList pruned = pruneCandidates( candidates );
    1585                
     1585
    15861586                if ( mode.failFast && pruned.empty() ) {
    15871587                        std::ostringstream stream;
     
    16021602                )
    16031603                PRINT(
    1604                         std::cerr << "there are " << candidates.size() << " alternatives after elimination" 
     1604                        std::cerr << "there are " << candidates.size() << " alternatives after elimination"
    16051605                                << std::endl;
    16061606                )
    16071607        }
    16081608
    1609         // 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
    16101610        // adjusted
    16111611        if ( mode.adjust ) {
    16121612                for ( CandidateRef & r : candidates ) {
    1613                         r->expr = ast::mutate_field( 
    1614                                 r->expr.get(), &ast::Expr::result, 
    1615                                 adjustExprType( r->expr->result, r->env, symtab ) );
     1613                        r->expr = ast::mutate_field(
     1614                                r->expr.get(), &ast::Expr::result,
     1615                                adjustExprType( r->expr->result, r->env, localSyms ) );
    16161616                }
    16171617        }
     
    16251625}
    16261626
    1627 std::vector< CandidateFinder > CandidateFinder::findSubExprs( 
    1628         const std::vector< ast::ptr< ast::Expr > > & xs 
     1627std::vector< CandidateFinder > CandidateFinder::findSubExprs(
     1628        const std::vector< ast::ptr< ast::Expr > > & xs
    16291629) {
    16301630        std::vector< CandidateFinder > out;
    16311631
    16321632        for ( const auto & x : xs ) {
    1633                 out.emplace_back( symtab, env );
     1633                out.emplace_back( localSyms, env );
    16341634                out.back().find( x, ResolvMode::withAdjustment() );
    1635                
     1635
    16361636                PRINT(
    16371637                        std::cerr << "findSubExprs" << std::endl;
Note: See TracChangeset for help on using the changeset viewer.