Repository: godotengine/godot-cpp (C++)

Issue:
Compile time regression(?)
### Godot version

-

### godot-cpp version

2ffff669f557351e85423e9edbc7a0e6520b613e

### System information

Arch Linux

### Issue description

Commit introduces ~X3 compilation time.

### Steps to reproduce

Bisected from master, benchmarked with
```bash
time scons
```
command

Approximate compile time of good commit
```
real	5m4.576s
user	44m50.995s
sys	1m48.742s
```
bad commit
```
real	15m37.927s
user	145m58.519s
sys	3m25.119s
```

### Minimal reproduction project

godot-cpp repo


Discussion: My machine appears to be much faster than yours, however, I am still able to reproduce this in my testing.

I tried with these commands:

```
scons -c
time scons
```

On 730ccaae392c5838b8907b3cedd56b19be6b6d8c (the commit before PR https://github.com/godotengine/godot-cpp/pull/1162):

```
real    0m35.237s
user    13m15.284s
sys     2m19.489s
```

On 96565e1de5042baeb4835e56021fc995f1647fd1 (current master):

```
real    1m55.579s
user    51m56.977s
sys     3m50.841s
```

My guess is that this is from the changes to `type_info.hpp` which ends up getting included everywhere. I'm not sure how to improve this...

cc @Repiteo 



Fix (patch):
diff --git a/include/godot_cpp/core/type_info.hpp b/include/godot_cpp/core/type_info.hpp
index d847598a3..b78f7e73b 100644
--- a/include/godot_cpp/core/type_info.hpp
+++ b/include/godot_cpp/core/type_info.hpp
@@ -33,7 +33,6 @@
 
 #include <godot_cpp/core/object.hpp>
 #include <godot_cpp/variant/typed_array.hpp>
-#include <godot_cpp/variant/typed_dictionary.hpp>
 #include <godot_cpp/variant/variant.hpp>
 
 #include <gdextension_interface.h>
@@ -414,206 +413,6 @@ MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
 
 #undef MAKE_TYPED_ARRAY_INFO
 
-template <typename K, typename V>
-struct PtrToArg<TypedDictionary<K, V>> {
-	_FORCE_INLINE_ static TypedDictionary<K, V> convert(const void *p_ptr) {
-		return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
-	}
-	typedef Dictionary EncodeT;
-	_FORCE_INLINE_ static void encode(TypedDictionary<K, V> p_val, void *p_ptr) {
-		*(Dictionary *)p_ptr = p_val;
-	}
-};
-
-template <typename K, typename V>
-struct PtrToArg<const TypedDictionary<K, V> &> {
-	typedef Dictionary EncodeT;
-	_FORCE_INLINE_ static TypedDictionary<K, V>
-	convert(const void *p_ptr) {
-		return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
-	}
-};
-
-template <typename K, typename V>
-struct GetTypeInfo<TypedDictionary<K, V>> {
-	static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
-	static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
-	static inline PropertyInfo get_class_info() {
-		return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
-	}
-};
-
-template <typename K, typename V>
-struct GetTypeInfo<const TypedDictionary<K, V> &> {
-	static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
-	static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
-	static inline PropertyInfo get_class_info() {
-		return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
-	}
-};
-
-#define MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type)                                                                                                     \
-	template <typename T>                                                                                                                                                  \
-	struct GetTypeInfo<TypedDictionary<T, m_type>> {                                                                                                                       \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
-		static inline PropertyInfo get_class_info() {                                                                                                                      \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
-					vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
-		}                                                                                                                                                                  \
-	};                                                                                                                                                                     \
-	template <typename T>                                                                                                                                                  \
-	struct GetTypeInfo<const TypedDictionary<T, m_type> &> {                                                                                                               \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
-		static inline PropertyInfo get_class_info() {                                                                                                                      \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
-					vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
-		}                                                                                                                                                                  \
-	};                                                                                                                                                                     \
-	template <typename T>                                                                                                                                                  \
-	struct GetTypeInfo<TypedDictionary<m_type, T>> {                                                                                                                       \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
-		static inline PropertyInfo get_class_info() {                                                                                                                      \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
-					vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
-		}                                                                                                                                                                  \
-	};                                                                                                                                                                     \
-	template <typename T>                                                                                                                                                  \
-	struct GetTypeInfo<const TypedDictionary<m_type, T> &> {                                                                                                               \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
-		static inline PropertyInfo get_class_info() {                                                                                                                      \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
-					vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
-		}                                                                                                                                                                  \
-	};
-
-#define MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type_key, m_variant_type_key, m_type_value, m_variant_type_value)                                           \
-	template <>                                                                                                                                           \
-	struct GetTypeInfo<TypedDictionary<m_type_key, m_type_value>> {                                                                                       \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                       \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                     \
-		static inline PropertyInfo get_class_info() {                                                                                                     \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                       \
-					vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
-							m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data()));    \
-		}                                                                                                                                                 \
-	};                                                                                                                                                    \
-	template <>                                                                                                                                           \
-	struct GetTypeInfo<const TypedDictionary<m_type_key, m_type_value> &> {                                                                               \
-		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                       \
-		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                     \
-		static inline PropertyInfo get_class_info() {                                                                                                     \
-			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                       \
-					vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
-							m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data()));    \
-		}                                                                                                                                                 \
-	};
-
-#define MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type)                                                     \
-	MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type)                                                 \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, bool, Variant::BOOL)                               \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint8_t, Variant::INT)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int8_t, Variant::INT)                              \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint16_t, Variant::INT)                            \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int16_t, Variant::INT)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint32_t, Variant::INT)                            \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int32_t, Variant::INT)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint64_t, Variant::INT)                            \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int64_t, Variant::INT)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, float, Variant::FLOAT)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, double, Variant::FLOAT)                            \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, String, Variant::STRING)                           \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2, Variant::VECTOR2)                         \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2i, Variant::VECTOR2I)                       \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2, Variant::RECT2)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2i, Variant::RECT2I)                           \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3, Variant::VECTOR3)                         \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3i, Variant::VECTOR3I)                       \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform2D, Variant::TRANSFORM2D)                 \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Plane, Variant::PLANE)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Quaternion, Variant::QUATERNION)                   \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, AABB, Variant::AABB)                               \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Basis, Variant::BASIS)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform3D, Variant::TRANSFORM3D)                 \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Color, Variant::COLOR)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, StringName, Variant::STRING_NAME)                  \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, NodePath, Variant::NODE_PATH)                      \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, RID, Variant::RID)                                 \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Callable, Variant::CALLABLE)                       \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Signal, Variant::SIGNAL)                           \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Dictionary, Variant::DICTIONARY)                   \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Array, Variant::ARRAY)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedByteArray, Variant::PACKED_BYTE_ARRAY)       \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt32Array, Variant::PACKED_INT32_ARRAY)     \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt64Array, Variant::PACKED_INT64_ARRAY)     \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY) \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY) \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedStringArray, Variant::PACKED_STRING_ARRAY)   \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY) \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY) \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY) \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedColorArray, Variant::PACKED_COLOR_ARRAY)     \
-	/* MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, IPAddress, Variant::STRING) */
-
-#define MAKE_TYPED_DICTIONARY_INFO(m_type, m_variant_type)                             \
-	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Variant, Variant::NIL) \
-	MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type)
-
-MAKE_TYPED_DICTIONARY_INFO_NIL(Variant, Variant::NIL)
-MAKE_TYPED_DICTIONARY_INFO(bool, Variant::BOOL)
-MAKE_TYPED_DICTIONARY_INFO(uint8_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(int8_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(uint16_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(int16_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(uint32_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(int32_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(uint64_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(int64_t, Variant::INT)
-MAKE_TYPED_DICTIONARY_INFO(float, Variant::FLOAT)
-MAKE_TYPED_DICTIONARY_INFO(double, Variant::FLOAT)
-MAKE_TYPED_DICTIONARY_INFO(String, Variant::STRING)
-MAKE_TYPED_DICTIONARY_INFO(Vector2, Variant::VECTOR2)
-MAKE_TYPED_DICTIONARY_INFO(Vector2i, Variant::VECTOR2I)
-MAKE_TYPED_DICTIONARY_INFO(Rect2, Variant::RECT2)
-MAKE_TYPED_DICTIONARY_INFO(Rect2i, Variant::RECT2I)
-MAKE_TYPED_DICTIONARY_INFO(Vector3, Variant::VECTOR3)
-MAKE_TYPED_DICTIONARY_INFO(Vector3i, Variant::VECTOR3I)
-MAKE_TYPED_DICTIONARY_INFO(Transform2D, Variant::TRANSFORM2D)
-MAKE_TYPED_DICTIONARY_INFO(Plane, Variant::PLANE)
-MAKE_TYPED_DICTIONARY_INFO(Quaternion, Variant::QUATERNION)
-MAKE_TYPED_DICTIONARY_INFO(AABB, Variant::AABB)
-MAKE_TYPED_DICTIONARY_INFO(Basis, Variant::BASIS)
-MAKE_TYPED_DICTIONARY_INFO(Transform3D, Variant::TRANSFORM3D)
-MAKE_TYPED_DICTIONARY_INFO(Color, Variant::COLOR)
-MAKE_TYPED_DICTIONARY_INFO(StringName, Variant::STRING_NAME)
-MAKE_TYPED_DICTIONARY_INFO(NodePath, Variant::NODE_PATH)
-MAKE_TYPED_DICTIONARY_INFO(RID, Variant::RID)
-MAKE_TYPED_DICTIONARY_INFO(Callable, Variant::CALLABLE)
-MAKE_TYPED_DICTIONARY_INFO(Signal, Variant::SIGNAL)
-MAKE_TYPED_DICTIONARY_INFO(Dictionary, Variant::DICTIONARY)
-MAKE_TYPED_DICTIONARY_INFO(Array, Variant::ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
-MAKE_TYPED_DICTIONARY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
-/*
-MAKE_TYPED_DICTIONARY_INFO(IPAddress, Variant::STRING)
-*/
-
-#undef MAKE_TYPED_DICTIONARY_INFO
-#undef MAKE_TYPED_DICTIONARY_INFO_NIL
-#undef MAKE_TYPED_DICTIONARY_INFO_EXPANDED
-#undef MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT
-
 #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
 
 } // namespace godot
diff --git a/include/godot_cpp/variant/typed_dictionary.hpp b/include/godot_cpp/variant/typed_dictionary.hpp
index e7f35352c..deb5871a0 100644
--- a/include/godot_cpp/variant/typed_dictionary.hpp
+++ b/include/godot_cpp/variant/typed_dictionary.hpp
@@ -31,6 +31,7 @@
 #ifndef GODOT_TYPED_DICTIONARY_HPP
 #define GODOT_TYPED_DICTIONARY_HPP
 
+#include <godot_cpp/core/type_info.hpp>
 #include <godot_cpp/variant/dictionary.hpp>
 #include <godot_cpp/variant/variant.hpp>
 
@@ -233,6 +234,206 @@ MAKE_TYPED_DICTIONARY(IPAddress, Variant::STRING)
 #undef MAKE_TYPED_DICTIONARY_EXPANDED
 #undef MAKE_TYPED_DICTIONARY_WITH_OBJECT
 
+template <typename K, typename V>
+struct PtrToArg<TypedDictionary<K, V>> {
+	_FORCE_INLINE_ static TypedDictionary<K, V> convert(const void *p_ptr) {
+		return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
+	}
+	typedef Dictionary EncodeT;
+	_FORCE_INLINE_ static void encode(TypedDictionary<K, V> p_val, void *p_ptr) {
+		*(Dictionary *)p_ptr = p_val;
+	}
+};
+
+template <typename K, typename V>
+struct PtrToArg<const TypedDictionary<K, V> &> {
+	typedef Dictionary EncodeT;
+	_FORCE_INLINE_ static TypedDictionary<K, V>
+	convert(const void *p_ptr) {
+		return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
+	}
+};
+
+template <typename K, typename V>
+struct GetTypeInfo<TypedDictionary<K, V>> {
+	static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
+	static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
+	}
+};
+
+template <typename K, typename V>
+struct GetTypeInfo<const TypedDictionary<K, V> &> {
+	static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
+	static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
+	static inline PropertyInfo get_class_info() {
+		return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
+	}
+};
+
+#define MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type)                                                                                                     \
+	template <typename T>                                                                                                                                                  \
+	struct GetTypeInfo<TypedDictionary<T, m_type>> {                                                                                                                       \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
+		static inline PropertyInfo get_class_info() {                                                                                                                      \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
+					vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
+		}                                                                                                                                                                  \
+	};                                                                                                                                                                     \
+	template <typename T>                                                                                                                                                  \
+	struct GetTypeInfo<const TypedDictionary<T, m_type> &> {                                                                                                               \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
+		static inline PropertyInfo get_class_info() {                                                                                                                      \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
+					vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
+		}                                                                                                                                                                  \
+	};                                                                                                                                                                     \
+	template <typename T>                                                                                                                                                  \
+	struct GetTypeInfo<TypedDictionary<m_type, T>> {                                                                                                                       \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
+		static inline PropertyInfo get_class_info() {                                                                                                                      \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
+					vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
+		}                                                                                                                                                                  \
+	};                                                                                                                                                                     \
+	template <typename T>                                                                                                                                                  \
+	struct GetTypeInfo<const TypedDictionary<m_type, T> &> {                                                                                                               \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                                        \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                                      \
+		static inline PropertyInfo get_class_info() {                                                                                                                      \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                                        \
+					vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
+		}                                                                                                                                                                  \
+	};
+
+#define MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type_key, m_variant_type_key, m_type_value, m_variant_type_value)                                           \
+	template <>                                                                                                                                           \
+	struct GetTypeInfo<TypedDictionary<m_type_key, m_type_value>> {                                                                                       \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                       \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                     \
+		static inline PropertyInfo get_class_info() {                                                                                                     \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                       \
+					vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
+							m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data()));    \
+		}                                                                                                                                                 \
+	};                                                                                                                                                    \
+	template <>                                                                                                                                           \
+	struct GetTypeInfo<const TypedDictionary<m_type_key, m_type_value> &> {                                                                               \
+		static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;                                                       \
+		static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;                                     \
+		static inline PropertyInfo get_class_info() {                                                                                                     \
+			return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE,                                                       \
+					vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
+							m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data()));    \
+		}                                                                                                                                                 \
+	};
+
+#define MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type)                                                     \
+	MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type)                                                 \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, bool, Variant::BOOL)                               \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint8_t, Variant::INT)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int8_t, Variant::INT)                              \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint16_t, Variant::INT)                            \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int16_t, Variant::INT)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint32_t, Variant::INT)                            \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int32_t, Variant::INT)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint64_t, Variant::INT)                            \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int64_t, Variant::INT)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, float, Variant::FLOAT)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, double, Variant::FLOAT)                            \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, String, Variant::STRING)                           \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2, Variant::VECTOR2)                         \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2i, Variant::VECTOR2I)                       \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2, Variant::RECT2)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2i, Variant::RECT2I)                           \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3, Variant::VECTOR3)                         \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3i, Variant::VECTOR3I)                       \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform2D, Variant::TRANSFORM2D)                 \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Plane, Variant::PLANE)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Quaternion, Variant::QUATERNION)                   \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, AABB, Variant::AABB)                               \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Basis, Variant::BASIS)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform3D, Variant::TRANSFORM3D)                 \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Color, Variant::COLOR)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, StringName, Variant::STRING_NAME)                  \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, NodePath, Variant::NODE_PATH)                      \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, RID, Variant::RID)                                 \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Callable, Variant::CALLABLE)                       \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Signal, Variant::SIGNAL)                           \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Dictionary, Variant::DICTIONARY)                   \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Array, Variant::ARRAY)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedByteArray, Variant::PACKED_BYTE_ARRAY)       \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt32Array, Variant::PACKED_INT32_ARRAY)     \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt64Array, Variant::PACKED_INT64_ARRAY)     \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY) \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY) \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedStringArray, Variant::PACKED_STRING_ARRAY)   \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY) \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY) \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY) \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedColorArray, Variant::PACKED_COLOR_ARRAY)     \
+	/* MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, IPAddress, Variant::STRING) */
+
+#define MAKE_TYPED_DICTIONARY_INFO(m_type, m_variant_type)                             \
+	MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Variant, Variant::NIL) \
+	MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type)
+
+MAKE_TYPED_DICTIONARY_INFO_NIL(Variant, Variant::NIL)
+MAKE_TYPED_DICTIONARY_INFO(bool, Variant::BOOL)
+MAKE_TYPED_DICTIONARY_INFO(uint8_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(int8_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(uint16_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(int16_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(uint32_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(int32_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(uint64_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(int64_t, Variant::INT)
+MAKE_TYPED_DICTIONARY_INFO(float, Variant::FLOAT)
+MAKE_TYPED_DICTIONARY_INFO(double, Variant::FLOAT)
+MAKE_TYPED_DICTIONARY_INFO(String, Variant::STRING)
+MAKE_TYPED_DICTIONARY_INFO(Vector2, Variant::VECTOR2)
+MAKE_TYPED_DICTIONARY_INFO(Vector2i, Variant::VECTOR2I)
+MAKE_TYPED_DICTIONARY_INFO(Rect2, Variant::RECT2)
+MAKE_TYPED_DICTIONARY_INFO(Rect2i, Variant::RECT2I)
+MAKE_TYPED_DICTIONARY_INFO(Vector3, Variant::VECTOR3)
+MAKE_TYPED_DICTIONARY_INFO(Vector3i, Variant::VECTOR3I)
+MAKE_TYPED_DICTIONARY_INFO(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_DICTIONARY_INFO(Plane, Variant::PLANE)
+MAKE_TYPED_DICTIONARY_INFO(Quaternion, Variant::QUATERNION)
+MAKE_TYPED_DICTIONARY_INFO(AABB, Variant::AABB)
+MAKE_TYPED_DICTIONARY_INFO(Basis, Variant::BASIS)
+MAKE_TYPED_DICTIONARY_INFO(Transform3D, Variant::TRANSFORM3D)
+MAKE_TYPED_DICTIONARY_INFO(Color, Variant::COLOR)
+MAKE_TYPED_DICTIONARY_INFO(StringName, Variant::STRING_NAME)
+MAKE_TYPED_DICTIONARY_INFO(NodePath, Variant::NODE_PATH)
+MAKE_TYPED_DICTIONARY_INFO(RID, Variant::RID)
+MAKE_TYPED_DICTIONARY_INFO(Callable, Variant::CALLABLE)
+MAKE_TYPED_DICTIONARY_INFO(Signal, Variant::SIGNAL)
+MAKE_TYPED_DICTIONARY_INFO(Dictionary, Variant::DICTIONARY)
+MAKE_TYPED_DICTIONARY_INFO(Array, Variant::ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
+MAKE_TYPED_DICTIONARY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
+/*
+MAKE_TYPED_DICTIONARY_INFO(IPAddress, Variant::STRING)
+*/
+
+#undef MAKE_TYPED_DICTIONARY_INFO
+#undef MAKE_TYPED_DICTIONARY_INFO_NIL
+#undef MAKE_TYPED_DICTIONARY_INFO_EXPANDED
+#undef MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT
+
 } // namespace godot
 
 #endif // GODOT_TYPED_DICTIONARY_HPP