Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A macro to get the current function name. #2818

Closed
wants to merge 6 commits into from
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions text/0000-fn_name_macro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
- Feature Name: fn_name_macro
- Start Date: 2019-11-14
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)

<!-- https://github.com/rust-lang/rfcs/issues/1743 -->

# Summary
[summary]: #summary

This RFC adds an additional macro, `function!`, to the `core` crate. When invoked, the macro expands to the name of the function that contains the call site.

# Motivation
[motivation]: #motivation
Lokathor marked this conversation as resolved.
Show resolved Hide resolved

This is a useful extension of Rust's existing debug reporting: `file!`, `line!`, `column!` and `module_path!`.

For most people the name of the function is a much more immediate way to understand the context of a message than file name and line number.
Lokathor marked this conversation as resolved.
Show resolved Hide resolved
Lokathor marked this conversation as resolved.
Show resolved Hide resolved

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

For debug information about what's happening within the program there's several useful macros that you might use. One of them is the `function!` macro, which expands to the name of the current function. If used outside of a function it causes a compilation error.
Lokathor marked this conversation as resolved.
Show resolved Hide resolved
Lokathor marked this conversation as resolved.
Show resolved Hide resolved

# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section needs some elaboration to consider the various cases (e.g. like the one @kennytm raised) and give examples of code and what the result is.

Also, looking at the implementation of module_path! in libsyntax_ext https://github.com/rust-lang/rust/blob/9e8c4e6fb1c952048fb823e59f4c9c6487bf9a58/src/libsyntax_ext/source_util.rs#L65-L73 it looks like the information is readily available. In this case however, the information is not available in cx or reachable fields. Some elaboration on the implementation would be good. cc @petrochenkov since they are the most likely T-compiler reviewer for this RFC. Also, this probably has little to do with "debuginfo" -- that's a different part of the compiler that comes into play much later in the compilation process.


Use of the `function!` macro expands to the compiler's internal name for the function. This will generally be the name that the user wrote into the file but in the case of a closure or similar it will be something like the function's name with a unique suffix.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about a closure in a static?

static F: &(dyn Fn() -> &'static str + Sync) = &|| "1";

(the fully-qualified name is currently playground::F::{{closure}})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eddyb know this one (i hope)

Lokathor marked this conversation as resolved.
Show resolved Hide resolved

The exact text is considered "debug" information and not subject to Rust's stability guarantee.

# Drawbacks
[drawbacks]: #drawbacks
Centril marked this conversation as resolved.
Show resolved Hide resolved

* Doing this adds another macro to `core`.
* This macro in particular cannot be implemented in Rust itself, it requires special support from `rustc`, as well as from all potential alternative compilers for the Rust language.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

Previous discussion was within an issue of the RFCs repo: https://github.com/rust-lang/rfcs/issues/1743

In summary, this is _extremely_ useful for debug purposes, and has been highly desired for nearly two years.
Lokathor marked this conversation as resolved.
Show resolved Hide resolved

Alternative: we could call it `fn_name!` instead.

# Prior art
[prior-art]: #prior-art

* C99 has a `__func__` pre-processor macro that expands to the current funciton name. [link](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1642.html)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Luckily) This is not a pre-processor macro, just a predefined identifier provided by the C compiler

* C# has a `nameof` operator which can be used on functions

# Unresolved questions
[unresolved-questions]: #unresolved-questions

None, other than perhaps bikeshed on the name.

# Future possibilities
[future-possibilities]: #future-possibilities

None. This is a small change that's pretty open and shut.