`typeof` as a macro?

The typeof operator, commonly used in c, has been discussed many times by rust-lang, and its implementation is explicitly blocked. However, as rust's generic and constant support becomes more sophisticated, some complex types that are not written by humans will be difficult or outright inexpressive to express when participating in constant generic operations. As a keyword operator this is rejected by rust, and as a function it affects some non-constant variable capture issues, so what about as a macro that can only accept statically typed identifiers? For example:

let value = 0usize;
let foobar: type_of!(value) = 42;

If this macro only returns a type signature, I don't think it would affect the use of variables, and we could use it in more places. Now I have to use tait for this, but using tait has more secondary risks and is harder to read.

I don't think a keyword or not has been a major point. The issue that's always brought up is interaction with type inference, which to my knowledge has not been answered concretely. I don't have any examples off-hand, but I'm sure digging through old threads would bring some up.

2 Likes

If/once we have type alias impl trait, typeof becomes fairly simple. In fact, TAIT satisfies a good number of the use cases, just a bit less conveniently.

If a feature (that isn't purely sugar) has been in limbo for years, it's rarely because of syntax, and usually because of semantics. So "make it a macro" rarely helps (and usually has been considered) for functionality expanding the language.

Given offset_of! exists (unstable) as a macro (and reasonably likely to only stabilize the single struct field form first), though, it does seem not unlikely that type_of! will take the shape of a fairly restricted macro initially as well. Just fairly unlikely to happen before TAIT, which essentially ends up as a more restricted form of type_of! (since you specify the traits that uses are allowed to use).

Somewhat amusingly, there's a fairly straightforward answer from the implementation side: it's just a name for the type inference variable as would currently exist. Justifying that this does a useful and predictable thing in all cases is harder.

The expected behavior of this implementation would be for T::name to have the same "must be known before this point" restrictions that t.name does. However, this positionality can be quite surprising when items are otherwise (essentially) fully order independent. It seems not unlikely that type_of! would be necessarily forbidden from showing up in type aliases, since it's dependent on generic context.

2 Likes

I think you can do this today, if you spell it as follows:

let value = 0usize;
let foobar;
if false { foobar = value; }
else { foobar = 42; }

(Hooray for if false tricks.)

3 Likes

This is just an example, a simplified version of what I actually need can be found here:

How to call a static method on a statically typed variable? - help - The Rust Programming Language Forum (rust-lang.org)