Using struct S(u8); as function, how is that concept called?

Today I learned this code (the one in main) is valid:

struct S(u8);

enum E {
    A(u8),
}

fn f(x: fn(u8) -> S) {}
fn ff(x: impl Fn(u8) -> S) {}
fn g(x: fn(u8) -> E) {}
fn gg(x: impl Fn(u8) -> E) {}

fn main() {
    f(S);
    ff(S);
    g(E::A);
    gg(E::A);
}

In other words, S and E::A can also be used as function pointers or closures.

Does this concept (the act of transforming or additionally treating a syntactic 'tupled constructor syntax' as a function) have a name?

1 Like

Maybe "constructor function"? https://rust-lang.github.io/rfcs/1506-adt-kinds.html#tuple-structs

3 Likes

Interesting, the RFC says the struct S(T) syntax actually declares 2 things at the same time, so from the frame of my question it's more of a dual purpose declaration, one yielding a type, the other one a constructor function.

Thanks!

Note that unit structs similarly declare a const value (not a function) in addition to their type.

struct U;
fn main() {
    let variable: U = U;
    //       type ^   ^ value
}

You might have a point that these dual declarations aren't as uncommon as I thought. It's probably that unit structs are pervasive and you sort-of forget what's happening, while passing "enum variants as function pointers" was new to me.

Tried to get an overview, which of the following is allowed:

struct _S1;
type _T1 = fn() -> _S1;
//const _C1: _T1 = _S1;

struct _S2();
type _T2 = fn() -> _S2;
const _C2: _T2 = _S2;

struct _S3{}
type _T3 = fn() -> _S3;
//const _C3: _T3 = _S3;

fn main() {
    let _v11 = _S1;
    //let _v12 = _S1();
    let _v13 = _S1{};

    let _v21 = _S2;
    let _v22 = _S2();
    let _v23 = _S2{};

    //let _v31 = _S3;
    //let _v32 = _S3();
    let _v33 = _S3{};
}

(Playground)

The commented-out lines are not valid.

It simply reflects how the struct definition looks like. No parens (unit struct) = scalar value. Parens (tuple struct) = function. Curly braces (struct with named fields) = no value equivalent because there’s no syntax in Rust for "calling" something with curlies and named parameters.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.