(the below is from @ubsan) ``` // one can define their own variant, but I'm lazy #include #include #include template struct return_type {}; template struct return_type()(std::declval())) >> { using type = decltype(std::declval()(std::declval())); }; template using return_type_t = typename return_type::type; // not sure what to call this template struct common_return_type { using type = std::common_type_t...>; }; template using common_return_type_t = typename common_return_type::type; template auto match( std::variant& variant, F&& functor ) -> common_return_type_t { // you could also use static_assert to make it SFINAE-unfriendly return std::visit(functor, variant); } template struct overloaded : Fs... { using Fs::operator()...; overloaded(Fs&&... fs) : Fs(std::forward(fs))... { } }; int main() { auto var = std::variant(0); std::cout << match(var, overloaded( [](int i) { return i; }, [](std::string s) { return 0; } )); } ``` ALTERNATIVE =========== Could just update TU to have: `` stmt.if_let( stmt.match_def( stmt.match( [](::MIR::LValue::Data_Assign& se) { }, [](::MIR::LValue::Data_Drop& se) { } ); ```