@@ -201,6 +201,7 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
201
201
Functions[" Visit" ] = &TCallableConstraintTransformer::VisitWrap;
202
202
Functions[" VariantItem" ] = &TCallableConstraintTransformer::VariantItemWrap;
203
203
Functions[" Variant" ] = &TCallableConstraintTransformer::VariantWrap;
204
+ Functions[" DynamicVariant" ] = &TCallableConstraintTransformer::DynamicVariantWrap;
204
205
Functions[" Guess" ] = &TCallableConstraintTransformer::GuessWrap;
205
206
Functions[" Mux" ] = &TCallableConstraintTransformer::MuxWrap;
206
207
Functions[" Nth" ] = &TCallableConstraintTransformer::NthWrap;
@@ -668,6 +669,43 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
668
669
FilterFromHead<TPartOfChoppedConstraintNode>(input, filter, ctx);
669
670
FilterFromHead<TPartOfUniqueConstraintNode>(input, filterForUnique, ctx);
670
671
FilterFromHead<TPartOfDistinctConstraintNode>(input, filterForDistinct, ctx);
672
+
673
+ const auto unwrapedOutItemType = RemoveOptionalType (outItemType);
674
+ const auto unwrapedInItemType = RemoveOptionalType (inItemType);
675
+ if (unwrapedInItemType->GetKind () == ETypeAnnotationKind::Variant && unwrapedOutItemType->GetKind () == ETypeAnnotationKind::Variant
676
+ && unwrapedOutItemType->Cast <TVariantExprType>()->GetUnderlyingType ()->GetKind () == ETypeAnnotationKind::Tuple) {
677
+
678
+ const auto tupleUnderInType = unwrapedInItemType->Cast <TVariantExprType>()->GetUnderlyingType ()->Cast <TTupleExprType>();
679
+ const auto tupleUnderOutType = unwrapedOutItemType->Cast <TVariantExprType>()->GetUnderlyingType ()->Cast <TTupleExprType>();
680
+ if (auto multi = input->Head ().GetConstraint <TMultiConstraintNode>()) {
681
+ if (tupleUnderOutType->GetSize () < tupleUnderInType->GetSize ()) {
682
+ TMultiConstraintNode::TMapType multiItems;
683
+ std::copy_if (multi->GetItems ().cbegin (), multi->GetItems ().cend (),
684
+ std::back_inserter (multiItems),
685
+ [&](const auto & item) { return item.first < tupleUnderOutType->GetSize (); }
686
+ );
687
+ if (!multiItems.empty ()) {
688
+ input->AddConstraint (ctx.MakeConstraint <TMultiConstraintNode>(std::move (multiItems)));
689
+ }
690
+ } else {
691
+ input->AddConstraint (multi);
692
+ }
693
+ }
694
+ if (auto varItem = input->Head ().GetConstraint <TVarIndexConstraintNode>()) {
695
+ if (tupleUnderOutType->GetSize () < tupleUnderInType->GetSize ()) {
696
+ TVarIndexConstraintNode::TMapType filteredItems;
697
+ std::copy_if (varItem->GetIndexMapping ().cbegin (), varItem->GetIndexMapping ().cend (),
698
+ std::back_inserter (filteredItems),
699
+ [&](const auto & item) { return item.second < tupleUnderOutType->GetSize (); }
700
+ );
701
+ if (!filteredItems.empty ()) {
702
+ input->AddConstraint (ctx.MakeConstraint <TVarIndexConstraintNode>(std::move (filteredItems)));
703
+ }
704
+ } else {
705
+ input->AddConstraint (varItem);
706
+ }
707
+ }
708
+ }
671
709
return TStatus::Ok;
672
710
}
673
711
@@ -1985,6 +2023,28 @@ class TCallableConstraintTransformer : public TCallableTransformerBase<TCallable
1985
2023
return TStatus::Ok;
1986
2024
}
1987
2025
2026
+ TStatus DynamicVariantWrap (const TExprNode::TPtr& input, TExprNode::TPtr& /* output*/ , TExprContext& ctx) const {
2027
+ if (auto underlyingType = RemoveOptionalType (input->GetTypeAnn ())->Cast <TVariantExprType>()->GetUnderlyingType (); underlyingType->GetKind () == ETypeAnnotationKind::Tuple) {
2028
+ TConstraintSet target;
2029
+ CopyExcept (target, input->Head ().GetConstraintSet (), TVarIndexConstraintNode::Name ());
2030
+ TMultiConstraintNode::TMapType items;
2031
+ for (ui32 i = 0 ; i < underlyingType->Cast <TTupleExprType>()->GetSize (); ++i) {
2032
+ items.emplace_back (i, target);
2033
+ }
2034
+ input->AddConstraint (ctx.MakeConstraint <TMultiConstraintNode>(std::move (items)));
2035
+ if (auto varIndex = input->Head ().GetConstraint <TVarIndexConstraintNode>()) {
2036
+ TVarIndexConstraintNode::TMapType filteredItems;
2037
+ for (ui32 i = 0 ; i < underlyingType->Cast <TTupleExprType>()->GetSize (); ++i) {
2038
+ for (auto & item: varIndex->GetIndexMapping ()) {
2039
+ filteredItems.push_back (std::make_pair (i, item.second ));
2040
+ }
2041
+ }
2042
+ input->AddConstraint (ctx.MakeConstraint <TVarIndexConstraintNode>(std::move (filteredItems)));
2043
+ }
2044
+ }
2045
+ return TStatus::Ok;
2046
+ }
2047
+
1988
2048
TStatus GuessWrap (const TExprNode::TPtr& input, TExprNode::TPtr& /* output*/ , TExprContext& ctx) const {
1989
2049
auto inputType = input->Head ().GetTypeAnn ();
1990
2050
if (inputType->GetKind () == ETypeAnnotationKind::Optional) {
0 commit comments