Skip to content

@couldCoerce - check if a type will coerce to another #3641

Closed

Description

@archaistvolts

Sometimes its safe to assign a variable to a similar type when the types don't exactly match. Such is the case with []const u8 and [3]u8. Checking if the types match fails, but it IS safe to assign a []const u8 variable to a value of type [3]u8. I would like to be able to test if [3]u8 can be coerced into a []const u8.

I ran into this issue trying to instantiate a tagged union from a runtime known tag, I check the union field type against val: var on line 82 of the linked gist. It would have been safe to assign the value, but because the types don't match control flow proceeds into the 'else unreachable' branch.

A @couldCoerce method would eliminate the need for possibly complex type comparisons necessary to determine wether it is safe to perform this assignment.

//            if (unionField.field_type == @typeOf(val)) {
            if (@couldCoerce(unionField.field_type, @typeOf(val))) {
                return @unionInit(Tagged, unionField.name, val);
...

Here is a condensed version of the gist:

const std = @import("std");

const Tag = {A, B,  C };
const Tagged = union(Tag) {
    A: bool,
    B: i32,
    C: []const u8,
};

pub fn main() anyerror!void {
    var tagged = Tagged{ .A = true };
    var tag = @as(Tag, tagged);
    tag = .C;

    tagged = try initTagged3(tag, "foo");
}

fn initTagged3(tag: Tag, val: var) !Tagged {
    const uT = @typeInfo(Tagged).Union;
    inline for (uT.fields) |unionField| {
        if (@intToEnum(Tag, unionField.enum_field.?.value) == tag) {
            if (unionField.field_type == @typeOf(val)) {
            // **********************************
            // Proposed change
            // if (@couldCoerce(unionField.field_type, @typeOf(val))) {
            // **********************************
                return @unionInit(Tagged, unionField.name, val);
            } else {
                unreachable;
            }
        }
    }
    return error.Invalid;
}

Activity

  1. added
    proposalThis issue suggests language modifications. If it also has the "accepted" label then it is planned.
    on Nov 10, 2019
  2. added this to the 0.7.0 milestone on Nov 14, 2019
  3. modified the milestones: 0.7.0, 0.8.0 on Oct 27, 2020
  4. modified the milestones: 0.8.0, 0.9.0 on May 19, 2021
  5. modified the milestones: 0.9.0, 0.10.0 on Nov 23, 2021
  6. billzez commented on Jan 13, 2023

    @billzez
    Contributor

    I would also find this useful. Can this be reopened?

  7. maxzhao commented on Jan 13, 2023

    @maxzhao
    Contributor

    please reopen, it's very useful for some case

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

    proposalThis issue suggests language modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions