You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using reflect.Method() or reflect.MethodByName() with a non-constant argument, dead code elimination is disabled for public functions. This makes the final binary bigger than it should. See for example kubernetes/kubernetes#132216 for an effort on the subject.
I am using the expr.Function() to declare function, so I think it should be possible to avoid calling reflect.MethodByName(). Would you consider a tag "exprdeclarative" or something like that to opt out reflect?
With expr.Function() no reflect.MethodByName() is needed. But reflect.MethodByName() is kept as a fallback for other calls. There is no way to tell linter what this code will not be reachable.
One of the solutions is to introduce build tag which will hide reflect.MethodByName() usage.
OK, I can do that. My idea is to have reflect_on.go and reflectmethod_off.go, one with const disableReflectMethod := true and the other with const disableReflectMethod := false, and use this const in conditionals and rely on Go dead code elimination. Tag could be expr_no_reflectmethod (both .Method() and .MethodByName() should be removed).
I know the bottom part of the function is using expr.Function() but for the upper part, I don't know exactly if the whole if/else should be removed, only the if part or only the switch/case. I think only the if part should be removed, but I can't be really sure. It seems that I will have to guess everything and this is unlikely to be correct.
Activity
vincentbernat commentedon Nov 21, 2025
FI, I have just remove code using the culprit methods from expr: master...vincentbernat:expr:feature/dce-elimination. My own tests still pass. This is to show what could be possible.
antonmedv commentedon Nov 21, 2025
With expr.Function() no reflect.MethodByName() is needed. But reflect.MethodByName() is kept as a fallback for other calls. There is no way to tell linter what this code will not be reachable.
One of the solutions is to introduce build tag which will hide reflect.MethodByName() usage.
vincentbernat commentedon Nov 21, 2025
Yes, that was my point. Would you be OK with such a tag?
antonmedv commentedon Nov 21, 2025
Yes, we just need to find a good name (expr_no_method_by_name?) and documentation.
vincentbernat commentedon Nov 21, 2025
OK, I can do that. My idea is to have
reflect_on.goandreflectmethod_off.go, one withconst disableReflectMethod := trueand the other withconst disableReflectMethod := false, and use this const in conditionals and rely on Go dead code elimination. Tag could beexpr_no_reflectmethod(both.Method()and.MethodByName()should be removed).vincentbernat commentedon Nov 21, 2025
I think I may have been too optimistic about my ability to do that. For example, looking at:
I know the bottom part of the function is using
expr.Function()but for the upper part, I don't know exactly if the whole if/else should be removed, only the if part or only the switch/case. I think only the if part should be removed, but I can't be really sure. It seems that I will have to guess everything and this is unlikely to be correct.I have updated the branch master...vincentbernat:expr:feature/dce-elimination with my current situation. Next steps would be to adapt the tests plus add a test to avoid a regression.
antonmedv commentedon Nov 21, 2025
I see. I will try to work on this park as well.
ofek-frame commentedon Mar 31, 2026
Hey - any news on this front? We're encountering the same issue of DCE being disabled because of it.
Thank you!
feat(v2): add v2 package as a DCE-friendly alternative
feat(static): add "static" package as a DCE-friendly alternative
feat: add "expr_noreflectmethod" build tag
feat: add "expr_noreflectmethod" build tag
feat: add "expr_noreflectmethod" build tag
feat: add "expr_noreflectmethod" build tag