Skip to content

Tapioca DSL crashes when using T::Struct containing generic members #2130

Open
@amanda-mitchell

Description

Summary

When running tapioca dsl in a Rails app that

  • Overrides T::Configuration.call_validation_error_handler during application load with a handler that raises errors
  • Contains a T::Struct with a member whose type is a generic interface
  • Instantiates that struct during app startup with a concrete implementation of the generic interface

Tapioca will crash while trying to create the struct because of a type mismatch error between the interface and the implementation.

I created a repository containing what seems to be the absolute minimum configuration necessary to activate this bug. You can find it here: https://github.com/amanda-mitchell/tapioca-bug-repro

The short version of my analysis is that while most type checks are suppressed by Tapioca setting the default check level to :never, members declared on T::Struct don't respect this setting, so they still produce type errors.

Workarounds

Although I'd love to see this get a long term fix, I'd also like to document some potential workarounds for folks who might run across this in the meantime.

Use setter_validate

T::Struct contains an undocumented option for member declarations called setter_validate, and this is expected to a proc that performs validation side effects. Providing an empty (no-op) lambda will force the implementation of T::Struct onto an alternate code path that does not activate the bug.

Wrap the type in an intersection with Kernel

Simply switching the type from MyInterface[TypeArgument] to T.all(MyInterface[TypeArgument], Kernel) is also enough to nudge T::Struct onto the code path listed above.

Disable runtime checks while running Tapioca

If you have some code that can detect when Tapioca is running and set your implementation of T::Configuration.call_validation_error_handler to something that no-ops, you won't encounter the crash.

Metadata

Assignees

No one assigned

    Labels

    help-wantedWe support this change, and welcome community contributions for it.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions