Skip to content

[cpp] Invalid code on switch with enum from callable #12586

Closed

Description

@tobil4sk

Regression in #11151

https://github.com/HaxeCheckstyle/tokentree/blob/d6f75b95d037aafe1dbc97cf77352f37c0c74ff3/src/tokentree/TokenTree.hx#L119

Error: ./src/tokentree/TokenTree.cpp: In member function ‘void tokentree::TokenTree_obj::internalFilterCallback(hx::Callable<hx::ObjectPtr<tokentree::FilterResult_obj>(hx::ObjectPtr<tokentree::TokenTree_obj>, int)>, Array<Dynamic>, Dynamic)’:
./src/tokentree/TokenTree.cpp:551:90: error: ‘class hx::ObjectPtr<tokentree::FilterResult_obj>’ has no member named ‘StaticCast’
  551 | HXLINE( 119)                    switch((int)(callback(::hx::ObjectPtr<OBJ_>(this),depth).StaticCast< ::hx::EnumBase >()->_hx_getIndex())){
      |                                                                                          ^~~~~~~~~~
./src/tokentree/TokenTree.cpp:551:117: error: expected primary-expression before ‘>’ token
  551 | HXLINE( 119)                    switch((int)(callback(::hx::ObjectPtr<OBJ_>(this),depth).StaticCast< ::hx::EnumBase >()->_hx_getIndex())){
      |                                                                                                                     ^
./src/tokentree/TokenTree.cpp:551:119: error: expected primary-expression before ‘)’ token
  551 | HXLINE( 119)                    switch((int)(callback(::hx::ObjectPtr<OBJ_>(this),depth).StaticCast< ::hx::EnumBase >()->_hx_getIndex())){
      |                                                                                                                       ^
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-inconsistent-missing-override’ may have been intended to silence earlier diagnostics

Stripped down sample:

enum E {
	A;
	B;
}

function main() {
	final callback:() -> E = () -> cast null;
	trace(callback().match(A));
}
Error: ./src/_Main/Main_Fields_.cpp: In static member function ‘static void _Main::Main_Fields__obj::main()’:
./src/_Main/Main_Fields_.cpp:69:41: error: ‘class hx::ObjectPtr<E_obj>’ has no member named ‘StaticCast’
   69 | HXDLIN(   8)            if ((callback().StaticCast< ::hx::EnumBase >()->_hx_getIndex() == 0)) {
      |                                         ^~~~~~~~~~
./src/_Main/Main_Fields_.cpp:69:68: error: expected primary-expression before ‘>’ token
   69 | HXDLIN(   8)            if ((callback().StaticCast< ::hx::EnumBase >()->_hx_getIndex() == 0)) {
      |                                                                    ^
./src/_Main/Main_Fields_.cpp:69:70: error: expected primary-expression before ‘)’ token
   69 | HXDLIN(   8)            if ((callback().StaticCast< ::hx::EnumBase >()->_hx_getIndex() == 0)) {
      |                                                                      ^

Seems like it should be generating callback()->_hx_getIndex() instead of callback().StaticCast< ::hx::EnumBase >()->_hx_getIndex(), since it's not dynamic anymore.

Activity

  1. tobil4sk commented on Feb 10, 2026

    @tobil4sk
    MemberAuthor

    @Aidan63 thanks for looking into it! With your patch my original program is compiling fine, and so is formatter.

    However, I don't think the test case is actually covering it since the callable result is a regular function argument, not a switch/match. Without your patch it generated this, which still compiled fine for me:

    HXLINE(  14)		 ::unit::issues::_Issue12586::E _hx_tmp = ::hx::Callable<  ::unit::issues::_Issue12586::E() >(new _hx_Closure_0())();
    HXDLIN(  14)		this->eq(::unit::issues::_Issue12586::E_obj::A_dyn(),_hx_tmp,::hx::SourceInfo(HX_("src/unit/issues/Issue12586.hx",70,95,dc,a1),14,HX_("unit.issues.Issue12586",e3,fe,eb,77),HX_("test",52,c8,f9,4c)));
    

    I think we need a test case like this, with an explicit match or switch expression:

    t(callback().match(A));

    I was going to open a PR to add it, but when I added that test the error came back. I was confused because it's the same as my original sample. It turns out, the unit tests are using -D analyzer-optimize, and if I add that it also brings it back:

    	::hx::Callable< void ( ::Dynamic, ::Dynamic) > _hx_tmp = ::haxe::Log_obj::trace;
    	bool _hx_tmp1;
    	if ((::hx::Callable<  ::_Main::E() >(new _hx_Closure_0())().StaticCast< ::hx::EnumBase >()->_hx_getIndex() == 0)) {
    		_hx_tmp1 = true;
    	}
    	else {
    		_hx_tmp1 = false;
    	}
    	_hx_tmp(_hx_tmp1,::hx::SourceInfo(HX_("Main.hx",05,5c,7e,08),9,HX_("Main",59,64,2f,33),HX_("main",39,38,56,48)));
  2. tobil4sk commented on Feb 13, 2026

    @tobil4sk
    MemberAuthor

    @Simn would you mind reopening this? I don't have permission to.

    TLDR is that the error is still present when compiling the sample with -D analyzer-optimize

  3. reopened this on Feb 13, 2026
  4. Aidan63 commented on Mar 3, 2026

    @Aidan63
    Contributor

    I've got a proper fix for this now (https://github.com/Aidan63/haxe/tree/cpp-enum-callable) and have updated that test. I'm just working on fixing one failing cppia test (Issue6560)

  5. Aidan63 commented on Mar 9, 2026

    @Aidan63
    Contributor

    Should be properly fixed now.

  6. tobil4sk commented on Mar 26, 2026

    @tobil4sk
    MemberAuthor

    Seems like it works now with -D analyzer-optimize, but it is broken again with the analyzer disabled... 😅

    The formatter benchmarks are still failing to build.

    Could we reopen?

  7. reopened this on Mar 26, 2026
  8. tobil4sk commented on May 6, 2026

    @tobil4sk
    MemberAuthor

    @Aidan63 thanks! Formatter cpp benchmarks are back now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions