Skip to content

Conversation

@cyangle
Copy link
Contributor

@cyangle cyangle commented Dec 7, 2025

Fixes #16484

Gemini AI analysis of root cause and fix:

Root Cause

The interpreter's compile_call_arg method in compiler.cr was unconditionally calling downcast when casting an argument type to the target definition's argument type. This is incorrect because:

Downcast is for narrowing types (e.g., Union → String)
Upcast is for widening types (e.g., String → Union)
When calling arg_to_log(a) where a is a String but the method expects Int32 | String, the interpreter incorrectly tried to downcast String to Int32 | String, which failed because no such downcast handler exists (nor should it).

Fix

  • Before blindly downcasting, check if an upcast is needed. If so, use upcast.
    if obj_type == filtered_type && !to_type.is_a?(GenericClassType) &&
    to_type.can_be_stored?
    filtered_type = to_type
    @upcast = true
    end
  • Added a missing upcast_distinct handler for VirtualType → NonGenericClassType, which was exposed once the interpreter started using upcast in more places

@cyangle cyangle marked this pull request as draft December 7, 2025 21:42
@cyangle cyangle force-pushed the fix_incorrect_downcast branch from cdfc533 to 021f478 Compare December 7, 2025 22:49
@cyangle cyangle marked this pull request as ready for review December 7, 2025 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interpreter crashes with missing downcast_distinct from String to (Int32 | String)

1 participant