Skip to content

Support type transformations in FRU (functional record update) syntaxΒ #1975

@abonander

Description

@abonander

I remember discussing this a while ago. I thought I had an issue open somewhere for this but I guess not.

It's currently not allowed to use FRU (functional record update) syntax to return a transformed type, i.e.:

struct Foo<T> {
    val: T,
    tag: &'static str,
}

impl<T> Foo<T> {
    fn transform<U>(self, val: U) -> Foo<U> {
        Foo { val: val, .. self }
    }
}

will throw a "mismatched type" error with the span of self in the FRU literal because it is of type Foo<T> and not Foo<U>, even though the remaining fields of self are compatible.

According to RFC 736, FRU is supposed to be just syntactic sugar for a full struct literal, but a full struct literal works in this case because it doesn't place any restriction on the type of self.

Possible solutions:

  • Move fields nominally (foo: <tail expr>.foo, bar: <tail expr>.bar, etc.) and typecheck them individually, not typechecking the tail expression at all. This could allow FRU to work even between otherwise incompatible types which have compatible fields. I like this one more but it may be too implicit for some, and I gather that we don't want to add too much meaning to field names.

  • Only check equality of the outermost type constructor between the FRU literal and the tail expression, i.e. check that Foo<T> ~= Foo<U>; then, typecheck the moved fields individually. This would allow the above use-case but disallow using an entirely different type as the source or destination.

As far as I understand it, this should be backwards-compatible since it would strictly allow more code to compile.

Edit: clarify generic params

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions