Skip to content

Commit f9fbb65

Browse files
author
babenko
committed
YT-21993: Fix duplicate type tag on derive from template
7ec29a7b370f343f910075ff9fd87ea9469d2aa0
1 parent 1475372 commit f9fbb65

File tree

6 files changed

+102
-21
lines changed

6 files changed

+102
-21
lines changed

yt/yt/core/phoenix/descriptors.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,29 @@ const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTagOrThrow(TTypeT
136136
return *descriptor;
137137
}
138138

139+
const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTag(TTypeTag tag) const
140+
{
141+
const auto* descriptor = FindTypeDescriptorByTag(tag);
142+
YT_VERIFY(descriptor);
143+
return *descriptor;
144+
}
145+
139146
const TTypeDescriptor* TUniverseDescriptor::FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const
140147
{
141148
auto it = TypeIndexToDescriptor_.find(typeIndex);
142149
return it == TypeIndexToDescriptor_.end() ? nullptr : it->second;
143150
}
144151

152+
const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const
153+
{
154+
const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
155+
YT_VERIFY(descriptor);
156+
return *descriptor;
157+
}
158+
145159
const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const
146160
{
147-
const auto& descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
161+
const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
148162
if (!descriptor) {
149163
THROW_ERROR_EXCEPTION("Type %v is not registered",
150164
CppDemangle(typeIndex.name()));

yt/yt/core/phoenix/descriptors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ class TUniverseDescriptor
9191
const NYson::TYsonString& GetSchemaYson() const;
9292

9393
const TTypeDescriptor* FindTypeDescriptorByTag(TTypeTag tag) const ;
94+
const TTypeDescriptor& GetTypeDescriptorByTag(TTypeTag tag) const;
9495
const TTypeDescriptor& GetTypeDescriptorByTagOrThrow(TTypeTag tag) const;
9596

9697
const TTypeDescriptor* FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const ;
98+
const TTypeDescriptor& GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const;
9799
const TTypeDescriptor& GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const;
98100

99101
private:

yt/yt/core/phoenix/type_decl-inl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private: \
8383
public: \
8484
static const ::NYT::NPhoenix2::TTypeDescriptor& GetTypeDescriptor() \
8585
{ \
86-
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ true>(); \
86+
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
8787
return descriptor; \
8888
} \
8989
\
@@ -136,4 +136,8 @@ public: \
136136

137137
////////////////////////////////////////////////////////////////////////////////
138138

139+
const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag);
140+
141+
////////////////////////////////////////////////////////////////////////////////
142+
139143
} // namespace NYT::NPhoenix2::NDetail

yt/yt/core/phoenix/type_def-inl.h

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include <concepts>
2020

21+
namespace NYT::NPhoenix2::NDetail {
22+
2123
////////////////////////////////////////////////////////////////////////////////
2224

2325
#undef PHOENIX_DEFINE_TYPE
@@ -26,22 +28,10 @@
2628

2729
////////////////////////////////////////////////////////////////////////////////
2830

29-
#define PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs) \
30-
template <class T> \
31-
struct TPhoenixTypeInitializer__; \
32-
\
33-
template <> \
34-
struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \
35-
{ \
36-
[[maybe_unused]] static inline const void* Dummy = &type PP_DEPAREN(parenthesizedTypeArgs)::GetTypeDescriptor(); \
37-
}
38-
3931
#define PHOENIX_DEFINE_TYPE(type) \
40-
PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \
41-
\
4232
const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \
4333
{ \
44-
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ false>(); \
34+
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
4535
return descriptor; \
4636
} \
4737
\
@@ -79,23 +69,46 @@
7969
YT_VERIFY(context.IsLoad()); \
8070
type::LoadImpl(context.LoadContext()); \
8171
} \
72+
} \
73+
\
74+
template <class T> \
75+
struct TPhoenixTypeInitializer__; \
76+
\
77+
template <> \
78+
struct TPhoenixTypeInitializer__<type> \
79+
{ \
80+
[[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, false>(); \
8281
}
8382

8483
#define PHOENIX_DEFINE_TEMPLATE_TYPE(type, parenthesizedTypeArgs) \
85-
PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs)
84+
template <class T> \
85+
struct TPhoenixTypeInitializer__; \
86+
\
87+
template <> \
88+
struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \
89+
{ \
90+
[[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type PP_DEPAREN(parenthesizedTypeArgs), true>(); \
91+
}
8692

8793
#define PHOENIX_DEFINE_OPAQUE_TYPE(type) \
88-
PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \
89-
\
9094
const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \
9195
{ \
92-
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \
96+
static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
9397
return descriptor; \
98+
} \
99+
\
100+
template <class T> \
101+
struct TPhoenixTypeInitializer__; \
102+
\
103+
template <> \
104+
struct TPhoenixTypeInitializer__<type> \
105+
{ \
106+
[[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \
94107
}
95108

96109
////////////////////////////////////////////////////////////////////////////////
97110

98-
namespace NYT::NPhoenix2::NDetail {
111+
const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag);
99112

100113
////////////////////////////////////////////////////////////////////////////////
101114

yt/yt/core/phoenix/type_registry.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ class TTypeRegistry
8080
if (!Sealed_.exchange(true)) {
8181
YT_LOG_INFO("Type registry is sealed");
8282
}
83+
return GetUniverseDescriptorUnchecked();
84+
}
85+
86+
const TUniverseDescriptor& GetUniverseDescriptorUnchecked()
87+
{
8388
return UniverseDescriptor_;
8489
}
8590

@@ -88,13 +93,23 @@ class TTypeRegistry
8893
std::atomic<bool> Sealed_;
8994
};
9095

96+
TTypeRegistry* GetTypeRegistry()
97+
{
98+
return LeakySingleton<NDetail::TTypeRegistry>();
99+
}
100+
101+
const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag)
102+
{
103+
return GetTypeRegistry()->GetUniverseDescriptorUnchecked().GetTypeDescriptorByTag(tag);
104+
}
105+
91106
} // namespace NDetail
92107

93108
////////////////////////////////////////////////////////////////////////////////
94109

95110
ITypeRegistry* ITypeRegistry::Get()
96111
{
97-
return LeakySingleton<NDetail::TTypeRegistry>();
112+
return NDetail::GetTypeRegistry();
98113
}
99114

100115
////////////////////////////////////////////////////////////////////////////////

yt/yt/core/phoenix/unittests/phoenix_ut.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,5 +1578,38 @@ TEST(TPhoenixTest, PrivateInner)
15781578

15791579
////////////////////////////////////////////////////////////////////////////////
15801580

1581+
namespace NSeveralSpecializationsOfOneTemplate {
1582+
1583+
struct TDerivedFromTemplate
1584+
: public TPair<double, double>
1585+
{
1586+
bool operator==(const TDerivedFromTemplate&) const = default;
1587+
1588+
PHOENIX_DECLARE_TYPE(TDerivedFromTemplate, 0xf09c298f);
1589+
};
1590+
1591+
void TDerivedFromTemplate::RegisterMetadata(auto&& registrar)
1592+
{
1593+
registrar.template BaseType<TPair<double, double>>();
1594+
}
1595+
1596+
PHOENIX_DEFINE_TYPE(TDerivedFromTemplate);
1597+
1598+
} // namespace NSeveralSpecializationsOfOneTemplate
1599+
1600+
TEST(TPhoenixTest, SeveralSpecializationsOfOneTemplate)
1601+
{
1602+
using namespace NSeveralSpecializationsOfOneTemplate;
1603+
1604+
TDerivedFromTemplate tp1;
1605+
tp1.First = 1.1;
1606+
tp1.Second = 2.2;
1607+
1608+
auto tp2 = Deserialize<TDerivedFromTemplate>(Serialize(tp1));
1609+
EXPECT_EQ(tp1, tp2);
1610+
}
1611+
1612+
////////////////////////////////////////////////////////////////////////////////
1613+
15811614
} // namespace
15821615
} // namespace NYT::NPhoenix2

0 commit comments

Comments
 (0)