| 887 | } |
| 888 | } |
| 889 | string getNamelessHint ( ExpressionPtr left, ExpressionPtr right, const string & op ) const { |
| 890 | if ( left->rtti_isMakeTuple() ) { |
| 891 | auto mkt = static_cast<ExprMakeTuple*>(left); |
| 892 | ExprVar * firstField = nullptr; |
| 893 | for ( const auto & val : mkt->values ) { |
| 894 | auto value = val; |
| 895 | if ( value->rtti_isR2V() ) { |
| 896 | value = static_cast<ExprRef2Value*>(value)->subexpr; |
| 897 | } |
| 898 | if ( value->rtti_isField() ) { |
| 899 | auto field = static_cast<ExprField*>(value); |
| 900 | if ( field->value->rtti_isVar() ) { |
| 901 | auto var = static_cast<ExprVar*>(field->value); |
| 902 | if ( var->variable->type->isTuple() ) { |
| 903 | if ( !firstField ) { |
| 904 | firstField = var; |
| 905 | } else if ( firstField->variable != var->variable ) { |
| 906 | return ""; |
| 907 | } |
| 908 | } else { |
| 909 | return ""; |
| 910 | } |
| 911 | } else { |
| 912 | return ""; |
| 913 | } |
| 914 | } else { |
| 915 | return ""; |
| 916 | } |
| 917 | } |
| 918 | return "did u mean " + firstField->name + " " + op + " " + right->describe(); |
| 919 | } |
| 920 | return ""; |
| 921 | } |
| 922 | virtual void preVisit ( ExprCopy * expr ) override { |
| 923 | Visitor::preVisit(expr); |
| 924 | verifyOnlyFastAot(expr->func, expr->at); |