-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Macro that expands into string holding function name (or module path, etc) #1743
Comments
there's an open RFC for the function name: #1719 |
C# has a nice implementation of this: They have the |
Not really. C#'s |
Hi all, I've implemented this feature over current Rust beta in: https://github.com/da-x/rust/tree/function-macro I have not included type parameters in the output string because it's not very useful for me. But I did include the nesting, though (a::b..). This is my first time hacking on Rust's compiler, so bear with me that it may be ugly/inefficient, etc. |
@da-x quick question: #1719 (comment) EDIT: sounds like line numbers would be a good way to differentiate two same-named inner functions that are at the same nest-level. EDIT2: I've decided to not post the following as a new post, and just discard it; but on second thought, I figured I might as well include it here(hidden by a `details` tag, ie. click me to open) - it's a reply attempt to the next comment by da-x
It's worth noting that such use of Taking example from your implementation,
test
main
main::inner
main::inner::inner_a
main::inner2
main::inner2::inner_b
test
main
inner
inner_a
inner2
inner_b The following example( playground ) gives an idea why fn main() {
{
fn inner() {
println!("inner/{}", line!());
fn inner_a() {
println!("inner::inner_a/{}", line!());
}
inner_a();
}
inner();
}
fn inner() {
println!("inner/{}", line!());
fn inner_a() {
println!("inner::inner_a/{}", line!());
}
inner_a();
}
inner();
}
//output:
inner/4
inner::inner_a/6
inner/13
inner::inner_a/15 |
@xftroxgpx another case to consider are two calls to |
So, What's the status of it? |
Now that I am actually using my implementation in the logging system I am writing, I fixed some bugs there. Updated my branch (also rebased ontop 1.25.0). Before, the names from methods functions, default implementation of trait methods, and the name of the struct for which the method is implemented, were all missing. |
Hi all, Although the RFC is not fully formed, I submitted an implementation as a pull request so we can have a working reference implementation that may assist in promoting the discussion and maybe reach some conclusions how to move this forward. |
Nominating for discussion; this has been around for a while, and it seems completely reasonable. I'd like to see this myself. |
We discussed this (and rust-lang/rust#49820) in the @rust-lang/lang meeting. There was full consensus that Rust should have a macro to return the function name. Procedurally, this needs to have an RFC (or revive the old one), and an implementation with tests and a feature gate. Other open questions include:
|
Isn't that something that can happen with new Rust versions? The release notes could communicate it right? As long as they build their existing project with a version of Rust prior to the release with the new macro they should be fine? I guess it's more of an issue with using crates? Is crates.io able to inspect each crates src for such usage in some way?
Presumably I get the file name and line that the closure was declared in, like a source map. Since the closure has no name(is using the function parameter name useful?) it might make sense to use the named function it was declared in(not file and function name that is taking the closure as a parameter, eg |
This is quite a pain for anything related to logging and error reporting.
Call the built-in one
First, you need not guarantee the stability of this macro output. Second, you can make it compatible with a backtrace/unwinding output, i.e. output whatever |
Unfortunately, not. It would take too much time to do all the steps required to ship this on stable by the time the edition goes into feature freeze. |
Unfortunately, tracking this for some one just doing a search seems to be rather difficult having so many issues related to this: Eg: (.. and probably quite a few more, that left me jumping back and forth) If this is indeed the latest issue, I think it would be quite useful to have a section in the main post, for older references and make sure it's indicated that this is the latest one, and RFC links if any. It's rather funny, for some relatively simple, it's leaving behind so much "discussion cruft". |
Following the ongoing effort in Rust 2018 to make macros first class citizens like other items, perhaps it is worth to consider having |
Any traction on this? I am getting tired of adding let fn_name = "func" everywhere... |
I'd like to see this revived as well. @pnkfelix Do you have time to write up an RFC? It shouldn't be an especially complex RFC, and with the current state of macro scoping I think it's reasonable to add a new macro and expect that it won't break people who have their own macros. I think if you pick a reasonable name we can hopefully avoid bikeshedding it. The only remaining bikeshedding I know of: how should it interact with closures? I would argue for expanding to the name of the lexically containing named function, as closures don't have any meaningful name. |
A closure's name should (bikeshed) probably be the name of the creating function with a line number or other identifier stuck on to the end, I definitely have functions that end up holding more than one closure. |
@Lokathor Interesting. I would expect most uses of this to go along with usage of the file and line (and possibly column) macros. How would you feel about just |
Small data point: Other parts of rustc, including the legacy mangling format, haven't switched to that yet, AFAIK, but maybe they should? (it's a detail I meant to change and I've forgotten about since, TBH) |
I wouldn't normally think to pair func_name!() with line!() and file!() because usually when i want it I want "emergency println debugging" and i'm just throwing in a few printers and i delete them once i've sorted out what's wrong. For example, in an emulator i've been working on the past bit i've regularly wanted to just kinda keep a mild log of the control flow when adding a new part into the mix, so something like fn draw_to_bitmap(&self, bitmap: &mut Bitmap) { will get a temporary Another thing that I often wanted this sort of thing for is a way to format the function's name into an error message, That said, i have used file! and line! before, and i'm not opposed to having them help disambiguate things as well, i just wouldn't normally think to use them right away. If (I assume that the particular format of this macro would be "debug string info, subject to change in the future", and that we're not going to be tied to the format we pick here forever.) |
Agreed. Alright, let's assume for now that closures use the same internal format that they use elsewhere, and we can always change that later. |
uh, sure |
Proper PR opened #2818 |
RFC #466 was closed back in the days before we had a protocol for opening up follow-up issues to use to gather links to related discussion.
The idea is that we already have some macros (
file!
andline!
) that are useful for reporting source code context, and it might be nice to expand that collection with macros that include other information, such as the current function name, which I believe was the suggestion of thefunction!
macro that was at one point described in RFC #466 (whose draft contents have now been lost, apparently).Here is my attempt to retrieve the Motivation from that original draft text. (I don't think we need the detailed design in the description of an issue like this.)
module_path!
macro that expands into a string representing the path to the current module; such a macro would be usable outside offn
definitions, e.g. instatic
items.The text was updated successfully, but these errors were encountered: