@@ -73,13 +73,18 @@ auto demangle(std::string_view s)
73
73
return res;
74
74
}
75
75
76
+ struct lookup_res {
77
+ meta::lookup_res meta_res;
78
+ std::string demangled_name;
79
+ };
80
+
76
81
auto lookup (
77
82
std::string const & name,
78
83
current_names_span current_names
79
84
)
80
- -> meta::expected<meta:: lookup_res>
85
+ -> meta::expected<lookup_res>
81
86
{
82
- auto res = meta:: lookup_res{};
87
+ auto res = lookup_res{};
83
88
auto libraries = meta::get_reachable_metafunction_symbols ();
84
89
85
90
(void )current_names;
@@ -93,7 +98,7 @@ auto lookup(
93
98
{
94
99
auto dname = demangle (sym.substr (meta::symbol_prefix.size ()));
95
100
if (dname == name) {
96
- return {{lib.name , sym}};
101
+ return {{{ lib.name , sym}, std::move (dname) }};
97
102
}
98
103
}
99
104
}
@@ -105,7 +110,7 @@ auto lookup(
105
110
}
106
111
107
112
// Case not yet handled.
108
- if (res.library .empty ()) {
113
+ if (res.meta_res . library .empty ()) {
109
114
return meta::diagnostic{" (ICE) metafunction '" + name + " ' not found" };
110
115
}
111
116
// else
@@ -125,7 +130,30 @@ auto parser::apply_type_metafunctions( declaration_node& n )
125
130
n,
126
131
rtype,
127
132
[&](std::string const & msg) { error ( msg, false ); },
128
- [&](std::string const & name) { return lookup (name, current_names); }
133
+ [&](std::string const & name) {
134
+ return lookup (name, current_names).and_then (
135
+ [&](lookup_res res)
136
+ -> meta::expected<meta::lookup_res>
137
+ {
138
+ auto to_metafunction = [](std::string name) {
139
+ return " static_cast<void(*)(cpp2::meta::type_declaration&)>(" + std::move (name) + " )" ;
140
+ };
141
+ auto check = std::string{};
142
+ check += " static_assert(" ;
143
+ check += to_metafunction (name);
144
+ check += " == " ;
145
+ check += to_metafunction (" ::" + std::move (res.demangled_name ));
146
+ check += " , " ;
147
+ // A static_assert doesn't really check that its the evaluated metafunction
148
+ // For that, we would have to load the metafunction symbol at runtime
149
+ check += " \" the metafunction name '" + name + " ' must be " ;
150
+ check += " reachable and equal to the one evaluated by cppfront\" " ;
151
+ check += " );\n " ;
152
+ n.metafunction_lookup_checks .push_back (check);
153
+ return res.meta_res ;
154
+ }
155
+ );
156
+ }
129
157
);
130
158
}
131
159
0 commit comments