Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r4e13e2a r18e683b  
    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 
     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               
    259265                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 
    265                 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                                                         newResult.expr = new ast::TupleExpr{ CodeLocation{}, {} };
     372                                                        std::vector< ast::ptr< ast::Expr > > emptyList;
     373                                                        newResult.expr =
     374                                                                new ast::TupleExpr{ CodeLocation{}, move( emptyList ) };
    373375                                                        argType = newResult.expr->result;
    374376                                                } else {
     
    398400
    399401                                                // check unification for ttype before adding to final
    400                                                 if (
    401                                                         unify(
     402                                                if ( 
     403                                                        unify( 
    402404                                                                ttype, argType, newResult.env, newResult.need, newResult.have,
    403                                                                 newResult.open, symtab )
     405                                                                newResult.open, symtab ) 
    404406                                                ) {
    405407                                                        finalResults.emplace_back( move( newResult ) );
     
    422424                                                if ( expl.exprs.empty() ) {
    423425                                                        results.emplace_back(
    424                                                                 results[i], move( env ), copy( results[i].need ),
     426                                                                results[i], move( env ), copy( results[i].need ), 
    425427                                                                copy( results[i].have ), move( open ), nextArg + 1, expl.cost );
    426 
     428                                                       
    427429                                                        continue;
    428430                                                }
     
    430432                                                // add new result
    431433                                                results.emplace_back(
    432                                                         i, expl.exprs.front(), move( env ), copy( results[i].need ),
    433                                                         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, 
    434436                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    435437                                        }
     
    477479
    478480                                        results.emplace_back(
    479                                                 i, expr, move( env ), move( need ), move( have ), move( open ), nextArg,
     481                                                i, expr, move( env ), move( need ), move( have ), move( open ), nextArg, 
    480482                                                nTuples, Cost::zero, nextExpl, results[i].explAlt );
    481483                                }
     
    493495                                        if ( unify( paramType, cnst->result, env, need, have, open, symtab ) ) {
    494496                                                results.emplace_back(
    495                                                         i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ),
     497                                                        i, new ast::DefaultArgExpr{ cnst->location, cnst }, move( env ), 
    496498                                                        move( need ), move( have ), move( open ), nextArg, nTuples );
    497499                                        }
     
    515517                                if ( expl.exprs.empty() ) {
    516518                                        results.emplace_back(
    517                                                 results[i], move( env ), move( need ), move( have ), move( open ),
     519                                                results[i], move( env ), move( need ), move( have ), move( open ), 
    518520                                                nextArg + 1, expl.cost );
    519 
     521                                       
    520522                                        continue;
    521523                                }
     
    537539                                        // add new result
    538540                                        results.emplace_back(
    539                                                 i, expr, move( env ), move( need ), move( have ), move( open ),
     541                                                i, expr, move( env ), move( need ), move( have ), move( open ), 
    540542                                                nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
    541543                                }
     
    546548                genStart = genEnd;
    547549
    548                 return genEnd != results.size();  // were any new results added?
     550                return genEnd != results.size();
    549551        }
    550552
    551553        /// Generate a cast expression from `arg` to `toType`
    552         const ast::Expr * restructureCast(
     554        const ast::Expr * restructureCast( 
    553555                ast::ptr< ast::Expr > & arg, const ast::Type * toType, ast::GeneratedFlag isGenerated = ast::GeneratedCast
    554556        ) {
    555                 if (
    556                         arg->result->size() > 1
    557                         && ! toType->isVoid()
    558                         && ! dynamic_cast< const ast::ReferenceType * >( toType )
     557                if ( 
     558                        arg->result->size() > 1 
     559                        && ! toType->isVoid() 
     560                        && ! dynamic_cast< const ast::ReferenceType * >( toType ) 
    559561                ) {
    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
     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 
    564566                        // UniqueExpr ensures that the side effects will still be produced)
    565567                        if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    566                                 // 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 
    567569                                // the expression
    568570                                arg = new ast::UniqueExpr{ arg->location, arg };
     
    572574                                // cast each component
    573575                                ast::ptr< ast::Expr > idx = new ast::TupleIndexExpr{ arg->location, arg, i };
    574                                 components.emplace_back(
     576                                components.emplace_back( 
    575577                                        restructureCast( idx, toType->getComponent( i ), isGenerated ) );
    576578                        }
     
    592594
    593595        /// Actually visits expressions to find their candidate interpretations
    594         class Finder final : public ast::WithShortCircuiting {
     596        struct Finder final : public ast::WithShortCircuiting {
     597                CandidateFinder & selfFinder;
    595598                const ast::SymbolTable & symtab;
    596         public:
    597                 CandidateFinder & selfFinder;
    598599                CandidateList & candidates;
    599600                const ast::TypeEnvironment & tenv;
     
    601602
    602603                Finder( CandidateFinder & f )
    603                 : symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ),
     604                : selfFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ),
    604605                  targetType( f.targetType ) {}
    605 
     606               
    606607                void previsit( const ast::Node * ) { visit_children = false; }
    607608
     
    638639
    639640                /// Completes a function candidate with arguments located
    640                 void validateFunctionCandidate(
    641                         const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results,
    642                         CandidateList & out
     641                void validateFunctionCandidate( 
     642                        const CandidateRef & func, ArgPack & result, const std::vector< ArgPack > & results, 
     643                        CandidateList & out 
    643644                ) {
    644                         ast::ApplicationExpr * appExpr =
     645                        ast::ApplicationExpr * appExpr = 
    645646                                new ast::ApplicationExpr{ func->expr->location, func->expr };
    646647                        // sum cost and accumulate arguments
     
    656657                        appExpr->args = move( vargs );
    657658                        // build and validate new candidate
    658                         auto newCand =
     659                        auto newCand = 
    659660                                std::make_shared<Candidate>( appExpr, result.env, result.open, result.need, cost );
    660661                        PRINT(
     
    668669                /// Builds a list of candidates for a function, storing them in out
    669670                void makeFunctionCandidates(
    670                         const CandidateRef & func, const ast::FunctionType * funcType,
     671                        const CandidateRef & func, const ast::FunctionType * funcType, 
    671672                        const ExplodedArgs_new & args, CandidateList & out
    672673                ) {
     
    675676                        ast::TypeEnvironment funcEnv{ func->env };
    676677                        makeUnifiableVars( funcType, funcOpen, funcNeed );
    677                         // add all type variables as open variables now so that those not used in the
    678                         // 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
    679680                        funcEnv.add( funcType->forall );
    680681
     
    682683                                // attempt to narrow based on expected target type
    683684                                const ast::Type * returnType = funcType->returns.front()->get_type();
    684                                 if ( ! unify(
    685                                         returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
     685                                if ( ! unify( 
     686                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) 
    686687                                ) {
    687688                                        // unification failed, do not pursue this candidate
     
    697698                        for ( const ast::DeclWithType * param : funcType->params ) {
    698699                                auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
    699                                 // 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 
    700701                                // matches
    701                                 if ( ! instantiateArgument(
     702                                if ( ! instantiateArgument( 
    702703                                        obj->type, obj->init, args, results, genStart, symtab ) ) return;
    703704                        }
     
    749750                                                        if ( expl.exprs.empty() ) {
    750751                                                                results.emplace_back(
    751                                                                         results[i], move( env ), copy( results[i].need ),
    752                                                                         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, 
    753754                                                                        expl.cost );
    754755
     
    759760                                                        results.emplace_back(
    760761                                                                i, expl.exprs.front(), move( env ), copy( results[i].need ),
    761                                                                 copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost,
     762                                                                copy( results[i].have ), move( open ), nextArg + 1, 0, expl.cost, 
    762763                                                                expl.exprs.size() == 1 ? 0 : 1, j );
    763764                                                }
     
    779780                /// Adds implicit struct-conversions to the alternative list
    780781                void addAnonConversions( const CandidateRef & cand ) {
    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
     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 
    783784                        // base type to treat the aggregate as the referenced value
    784785                        ast::ptr< ast::Expr > aggrExpr( cand->expr );
    785786                        ast::ptr< ast::Type > & aggrType = aggrExpr.get_and_mutate()->result;
    786787                        cand->env.apply( aggrType );
    787 
     788                       
    788789                        if ( aggrType.as< ast::ReferenceType >() ) {
    789790                                aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() };
     
    798799
    799800                /// Adds aggregate member interpretations
    800                 void addAggMembers(
    801                         const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
    802                         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 
    803804                ) {
    804805                        for ( const ast::Decl * decl : aggrInst->lookup( name ) ) {
    805806                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( decl );
    806                                 CandidateRef newCand = std::make_shared<Candidate>(
     807                                CandidateRef newCand = std::make_shared<Candidate>( 
    807808                                        cand, new ast::MemberExpr{ expr->location, dwt, expr }, addedCost );
    808                                 // add anonymous member interpretations whenever an aggregate value type is seen
     809                                // add anonymous member interpretations whenever an aggregate value type is seen 
    809810                                // as a member expression
    810811                                addAnonConversions( newCand );
     
    814815
    815816                /// Adds tuple member interpretations
    816                 void addTupleMembers(
    817                         const ast::TupleType * tupleType, const ast::Expr * expr, const Candidate & cand,
    818                         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 
    819820                ) {
    820821                        if ( auto constantExpr = dynamic_cast< const ast::ConstantExpr * >( member ) ) {
    821                                 // 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 
    822823                                // length of the tuple to have meaning
    823824                                long long val = constantExpr->intValue();
    824825                                if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    825826                                        addCandidate(
    826                                                 cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val },
     827                                                cand, new ast::TupleIndexExpr{ expr->location, expr, (unsigned)val }, 
    827828                                                addedCost );
    828829                                }
     
    836837                        if ( funcFinder.candidates.empty() ) return;
    837838
    838                         std::vector< CandidateFinder > argCandidates =
     839                        std::vector< CandidateFinder > argCandidates = 
    839840                                selfFinder.findSubExprs( untypedExpr->args );
    840 
     841                       
    841842                        // take care of possible tuple assignments
    842843                        // if not tuple assignment, handled as normal function call
     
    876877                                                if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    877878                                                        CandidateRef newFunc{ new Candidate{ *func } };
    878                                                         newFunc->expr =
     879                                                        newFunc->expr = 
    879880                                                                referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    880881                                                        makeFunctionCandidates( newFunc, function, argExpansions, found );
    881882                                                }
    882                                         } else if (
    883                                                 auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult )
     883                                        } else if ( 
     884                                                auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult ) 
    884885                                        ) {
    885886                                                if ( const ast::EqvClass * clz = func->env.lookup( inst->name ) ) {
    886887                                                        if ( auto function = clz->bound.as< ast::FunctionType >() ) {
    887888                                                                CandidateRef newFunc{ new Candidate{ *func } };
    888                                                                 newFunc->expr =
     889                                                                newFunc->expr = 
    889890                                                                        referenceToRvalueConversion( newFunc->expr, newFunc->cost );
    890891                                                                makeFunctionCandidates( newFunc, function, argExpansions, found );
     
    900901                                std::vector< ExplodedArg > funcE;
    901902                                funcE.reserve( funcFinder.candidates.size() );
    902                                 for ( const CandidateRef & func : funcFinder ) {
     903                                for ( const CandidateRef & func : funcFinder ) { 
    903904                                        funcE.emplace_back( *func, symtab );
    904905                                }
     
    912913                                                        if ( auto function = pointer->base.as< ast::FunctionType >() ) {
    913914                                                                CandidateRef newOp{ new Candidate{ *op} };
    914                                                                 newOp->expr =
     915                                                                newOp->expr = 
    915916                                                                        referenceToRvalueConversion( newOp->expr, newOp->cost );
    916917                                                                makeFunctionCandidates( newOp, function, argExpansions, found );
     
    921922                        }
    922923
    923                         // 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 
    924925                        // candidates
    925926                        if ( found.empty() && ! errors.isEmpty() ) { throw errors; }
     
    933934                                        auto pointer = appExpr->func->result.strict_as< ast::PointerType >();
    934935                                        auto function = pointer->base.strict_as< ast::FunctionType >();
    935 
     936                                       
    936937                                        std::cerr << "Case +++++++++++++ " << appExpr->func << std::endl;
    937938                                        std::cerr << "parameters are:" << std::endl;
     
    956957                        promoteCvtCost( winners );
    957958
    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
     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 
    960961                        // `findMinCost`, since anon conversions are never the cheapest
    961962                        for ( const CandidateRef & c : winners ) {
     
    965966
    966967                        if ( candidates.empty() && targetType && ! targetType->isVoid() ) {
    967                                 // 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 
    968969                                // will sometimes succeed when it wouldn't with a target type binding.
    969970                                // For example:
     
    10151016                                cand->env.extractOpenVars( open );
    10161017
    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
     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 
    10201021                                // has fewer results than there are types to cast to.
    10211022                                int discardedValues = cand->expr->result->size() - toType->size();
     
    10361037                                        // count one safe conversion for each value that is thrown away
    10371038                                        thisCost.incSafe( discardedValues );
    1038                                         CandidateRef newCand = std::make_shared<Candidate>(
    1039                                                 restructureCast( cand->expr, toType, castExpr->isGenerated ),
    1040                                                 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, 
    10411042                                                cand->cost + thisCost );
    10421043                                        inferParameters( newCand, matches );
     
    10561057                        finder.find( castExpr->arg, ResolvMode::withoutPrune() );
    10571058                        for ( CandidateRef & r : finder.candidates ) {
    1058                                 addCandidate(
    1059                                         *r,
     1059                                addCandidate( 
     1060                                        *r, 
    10601061                                        new ast::VirtualCastExpr{ castExpr->location, r->expr, castExpr->result } );
    10611062                        }
     
    10661067                        aggFinder.find( memberExpr->aggregate, ResolvMode::withAdjustment() );
    10671068                        for ( CandidateRef & agg : aggFinder.candidates ) {
    1068                                 // 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 
    10691070                                // base type to treat the aggregate as the referenced value
    10701071                                Cost addedCost = Cost::zero;
     
    10731074                                // find member of the given type
    10741075                                if ( auto structInst = agg->expr->result.as< ast::StructInstType >() ) {
    1075                                         addAggMembers(
     1076                                        addAggMembers( 
    10761077                                                structInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    10771078                                } else if ( auto unionInst = agg->expr->result.as< ast::UnionInstType >() ) {
    1078                                         addAggMembers(
     1079                                        addAggMembers( 
    10791080                                                unionInst, agg->expr, *agg, addedCost, getMemberName( memberExpr ) );
    10801081                                } else if ( auto tupleType = agg->expr->result.as< ast::TupleType >() ) {
     
    10961097
    10971098                                CandidateRef newCand = std::make_shared<Candidate>(
    1098                                         newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
     1099                                        newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero, 
    10991100                                        cost );
    11001101                                PRINT(
     
    11061107                                        std::cerr << std::endl;
    11071108                                )
    1108                                 newCand->expr = ast::mutate_field(
    1109                                         newCand->expr.get(), &ast::Expr::result,
     1109                                newCand->expr = ast::mutate_field( 
     1110                                        newCand->expr.get(), &ast::Expr::result, 
    11101111                                        renameTyVars( newCand->expr->result ) );
    1111                                 // add anonymous member interpretations whenever an aggregate value type is seen
     1112                                // add anonymous member interpretations whenever an aggregate value type is seen 
    11121113                                // as a name expression
    11131114                                addAnonConversions( newCand );
     
    11191120                        // not sufficient to just pass `variableExpr` here, type might have changed since
    11201121                        // creation
    1121                         addCandidate(
     1122                        addCandidate( 
    11221123                                new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv );
    11231124                }
     
    11291130                void postvisit( const ast::SizeofExpr * sizeofExpr ) {
    11301131                        if ( sizeofExpr->type ) {
    1131                                 addCandidate(
    1132                                         new ast::SizeofExpr{
    1133                                                 sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) },
     1132                                addCandidate( 
     1133                                        new ast::SizeofExpr{ 
     1134                                                sizeofExpr->location, resolveTypeof( sizeofExpr->type, symtab ) }, 
    11341135                                        tenv );
    11351136                        } else {
     
    11401141                                CandidateList winners = findMinCost( finder.candidates );
    11411142                                if ( winners.size() != 1 ) {
    1142                                         SemanticError(
     1143                                        SemanticError( 
    11431144                                                sizeofExpr->expr.get(), "Ambiguous expression in sizeof operand: " );
    11441145                                }
     
    11531154                void postvisit( const ast::AlignofExpr * alignofExpr ) {
    11541155                        if ( alignofExpr->type ) {
    1155                                 addCandidate(
    1156                                         new ast::AlignofExpr{
    1157                                                 alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) },
     1156                                addCandidate( 
     1157                                        new ast::AlignofExpr{ 
     1158                                                alignofExpr->location, resolveTypeof( alignofExpr->type, symtab ) }, 
    11581159                                        tenv );
    11591160                        } else {
     
    11641165                                CandidateList winners = findMinCost( finder.candidates );
    11651166                                if ( winners.size() != 1 ) {
    1166                                         SemanticError(
     1167                                        SemanticError( 
    11671168                                                alignofExpr->expr.get(), "Ambiguous expression in alignof operand: " );
    11681169                                }
     
    11711172                                choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    11721173                                choice->cost = Cost::zero;
    1173                                 addCandidate(
     1174                                addCandidate( 
    11741175                                        *choice, new ast::AlignofExpr{ alignofExpr->location, choice->expr } );
    11751176                        }
     
    11841185                        for ( const ast::Decl * member : aggInst->lookup( offsetofExpr->member ) ) {
    11851186                                auto dwt = strict_dynamic_cast< const ast::DeclWithType * >( member );
    1186                                 addCandidate(
     1187                                addCandidate( 
    11871188                                        new ast::OffsetofExpr{ offsetofExpr->location, aggInst, dwt }, tenv );
    11881189                        }
     
    12171218
    12181219                                        addCandidate(
    1219                                                 new ast::LogicalExpr{
     1220                                                new ast::LogicalExpr{ 
    12201221                                                        logicalExpr->location, r1->expr, r2->expr, logicalExpr->isAnd },
    12211222                                                move( env ), move( open ), move( need ), r1->cost + r2->cost );
     
    12551256                                                ast::AssertionSet have;
    12561257
    1257                                                 // unify true and false results, then infer parameters to produce new
     1258                                                // unify true and false results, then infer parameters to produce new 
    12581259                                                // candidates
    12591260                                                ast::ptr< ast::Type > common;
    1260                                                 if (
    1261                                                         unify(
    1262                                                                 r2->expr->result, r3->expr->result, env, need, have, open, symtab,
    1263                                                                 common )
     1261                                                if ( 
     1262                                                        unify( 
     1263                                                                r2->expr->result, r3->expr->result, env, need, have, open, symtab, 
     1264                                                                common ) 
    12641265                                                ) {
    12651266                                                        // generate typed expression
    1266                                                         ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{
     1267                                                        ast::ConditionalExpr * newExpr = new ast::ConditionalExpr{ 
    12671268                                                                conditionalExpr->location, r1->expr, r2->expr, r3->expr };
    12681269                                                        newExpr->result = common ? common : r2->expr->result;
    12691270                                                        // convert both options to result type
    12701271                                                        Cost cost = r1->cost + r2->cost + r3->cost;
    1271                                                         newExpr->arg2 = computeExpressionConversionCost(
     1272                                                        newExpr->arg2 = computeExpressionConversionCost( 
    12721273                                                                newExpr->arg2, newExpr->result, symtab, env, cost );
    12731274                                                        newExpr->arg3 = computeExpressionConversionCost(
     
    12861287                        ast::TypeEnvironment env{ tenv };
    12871288                        ast::ptr< ast::Expr > arg1 = resolveInVoidContext( commaExpr->arg1, symtab, env );
    1288 
     1289                       
    12891290                        CandidateFinder finder2{ symtab, env };
    12901291                        finder2.find( commaExpr->arg2, ResolvMode::withAdjustment() );
     
    13291330
    13301331                                        ast::ptr< ast::Type > common;
    1331                                         if (
    1332                                                 unify(
    1333                                                         r1->expr->result, r2->expr->result, env, need, have, open, symtab,
    1334                                                         common )
     1332                                        if ( 
     1333                                                unify( 
     1334                                                        r1->expr->result, r2->expr->result, env, need, have, open, symtab, 
     1335                                                        common ) 
    13351336                                        ) {
    13361337                                                // generate new expression
    1337                                                 ast::RangeExpr * newExpr =
     1338                                                ast::RangeExpr * newExpr = 
    13381339                                                        new ast::RangeExpr{ rangeExpr->location, r1->expr, r2->expr };
    13391340                                                newExpr->result = common ? common : r1->expr->result;
    13401341                                                // add candidate
    13411342                                                CandidateRef newCand = std::make_shared<Candidate>(
    1342                                                         newExpr, move( env ), move( open ), move( need ),
     1343                                                        newExpr, move( env ), move( open ), move( need ), 
    13431344                                                        r1->cost + r2->cost );
    13441345                                                inferParameters( newCand, candidates );
     
    13491350
    13501351                void postvisit( const ast::UntypedTupleExpr * tupleExpr ) {
    1351                         std::vector< CandidateFinder > subCandidates =
     1352                        std::vector< CandidateFinder > subCandidates = 
    13521353                                selfFinder.findSubExprs( tupleExpr->exprs );
    13531354                        std::vector< CandidateList > possibilities;
     
    13691370
    13701371                                addCandidate(
    1371                                         new ast::TupleExpr{ tupleExpr->location, move( exprs ) },
     1372                                        new ast::TupleExpr{ tupleExpr->location, move( exprs ) }, 
    13721373                                        move( env ), move( open ), move( need ), sumCost( subs ) );
    13731374                        }
     
    14111412                                toType = SymTab::validateType( initExpr->location, toType, symtab );
    14121413                                toType = adjustExprType( toType, tenv, symtab );
    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.
     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. 
    14161417                                CandidateFinder finder{ symtab, tenv, toType };
    14171418                                finder.find( initExpr->expr, ResolvMode::withAdjustment() );
     
    14251426                                        )
    14261427
    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
     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 
    14301431                                        // if it has fewer results than there are types to cast to.
    14311432                                        int discardedValues = cand->expr->result->size() - toType->size();
     
    14351436                                        unify( toType, cand->expr->result, env, need, have, open, symtab );
    14361437                                        Cost thisCost = castCost( cand->expr->result, toType, symtab, env );
    1437 
     1438                                       
    14381439                                        if ( thisCost != Cost::infinity ) {
    14391440                                                // count one safe conversion for each value that is thrown away
    14401441                                                thisCost.incSafe( discardedValues );
    1441                                                 CandidateRef newCand = std::make_shared<Candidate>(
    1442                                                         new ast::InitExpr{
    1443                                                                 initExpr->location, restructureCast( cand->expr, toType ),
    1444                                                                 initAlt.designation },
     1442                                                CandidateRef newCand = std::make_shared<Candidate>( 
     1443                                                        new ast::InitExpr{ 
     1444                                                                initExpr->location, restructureCast( cand->expr, toType ), 
     1445                                                                initAlt.designation }, 
    14451446                                                        copy( cand->env ), move( open ), move( need ), cand->cost, thisCost );
    14461447                                                inferParameters( newCand, matches );
     
    14681469        };
    14691470
    1470         /// 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 
    14711472        /// return type. Skips ambiguous candidates.
    14721473        CandidateList pruneCandidates( CandidateList & candidates ) {
     
    14851486                        {
    14861487                                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, localSyms, satisfied, errors );
     1560                        satisfyAssertions( candidate, symtab, 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, localSyms ) );
     1613                        r->expr = ast::mutate_field( 
     1614                                r->expr.get(), &ast::Expr::result, 
     1615                                adjustExprType( r->expr->result, r->env, symtab ) );
    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( localSyms, env );
     1633                out.emplace_back( symtab, 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.