Skip to content
This repository has been archived by the owner on Jun 6, 2021. It is now read-only.

Note: Meta Expression

Alex Rønne Petersen edited this page Jun 8, 2013 · 6 revisions

The meta expression can be used to retrieve compile-time information about various language constructs. The data returned by the meta expression is computed at compile time, and as such, is CTE-compatible and can be used in all contexts where CTE is triggered (e.g. in macros).

The grammar is:

meta-expression ::= "meta" ( meta-type-expression |
                             meta-fn-expression |
                             meta-trait-expression |
                             meta-glob-expression |
                             meta-tls-expression |
                             meta-macro-expression )
meta-type-expression ::= "type" type
meta-fn-expression ::= "fn" qualified-identifier
meta-trait-expression ::= "trait" qualified-identifier
meta-glob-expression ::= "glob" qualified-identifier
meta-tls-expression ::= "tls" qualified-identifier
meta-macro-expression ::= "macro" qualified-identifier

Each of these expressions returns a managed pointer to a particular structure in core::meta:

Expression Structure
meta type core::meta::TypeInfo
meta fn core::meta::FunctionInfo
meta trait core::meta::TraitInfo
meta glob core::meta::GlobalVarInfo
meta tls core::meta::TLSVarInfo
meta macro core::meta::MacroInfo

For example, we can do:

let ty = meta type int;
assert match ty.desc {
    @Int() { true; }
    _ { false; }
};

Or:

let ty = meta type *int;
assert match ty.desc {
    @UnsafePtr(@Constant(), @TypeInfo(_, _, @Int())) { true; }
    _ { false; }
};

Or:

let f = meta fn core::dbg::breakpoint;
assert match f.ret_type.desc {
    @Boolean() { true; }
    _ { false; }
};

And so on.

A meta expression can be applied to both uninstantiated versions of a generic declaration and fully instantiated versions. For example, we might have a function foo:

pub fn foo<T>(x : T) -> T {
    // ...
}

We can do both of these:

let fn_info_1 = meta fn foo;
let fn_info_2 = meta fn foo<int>;

The difference is simply that the latter FunctionInfo structure will have more complete type information because the function is instantiated. Note that obtaining information about an instantiated generic declaration does not cause code to be generated for that instance.

Clone this wiki locally