@@ -73,13 +73,18 @@ auto demangle(std::string_view s)
7373 return res;
7474}
7575
76+ struct lookup_res {
77+ meta::lookup_res meta_res;
78+ std::string demangled_name;
79+ };
80+
7681auto lookup (
7782 std::string const & name,
7883 current_names_span current_names
7984 )
80- -> meta::expected<meta:: lookup_res>
85+ -> meta::expected<lookup_res>
8186{
82- auto res = meta:: lookup_res{};
87+ auto res = lookup_res{};
8388 auto libraries = meta::get_reachable_metafunction_symbols ();
8489
8590 (void )current_names;
@@ -93,7 +98,7 @@ auto lookup(
9398 {
9499 auto dname = demangle (sym.substr (meta::symbol_prefix.size ()));
95100 if (dname == name) {
96- return {{lib.name , sym}};
101+ return {{{ lib.name , sym}, std::move (dname) }};
97102 }
98103 }
99104 }
@@ -105,7 +110,7 @@ auto lookup(
105110 }
106111
107112 // Case not yet handled.
108- if (res.library .empty ()) {
113+ if (res.meta_res . library .empty ()) {
109114 return meta::diagnostic{" (ICE) metafunction '" + name + " ' not found" };
110115 }
111116 // else
@@ -125,7 +130,30 @@ auto parser::apply_type_metafunctions( declaration_node& n )
125130 n,
126131 rtype,
127132 [&](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+ }
129157 );
130158}
131159
0 commit comments