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

A macro to get the current function name. #2818

wants to merge 6 commits into from

Conversation

Lokathor
Copy link
Contributor

text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation

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)

@comex
Copy link

comex commented Nov 15, 2019

👍

Pie-in-the-sky: It would be nice to have a more flexible feature where you could have a function automatically receive its caller's file/line/function name/etc., like C++ recently added with std::source_location (although the design C++ picked is terrible). But of course there's no need for that to block the current RFC.

@Lokathor
Copy link
Contributor Author

That actually was requested earlier today: #2815

@CryZe
Copy link

CryZe commented Nov 15, 2019

It would be nice to have a more flexible feature where you could have a function automatically receive its caller's file/line/function name/etc.

@comex This is already being implemented rust-lang/rust#65881

text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
text/0000-fn_name_macro.md Show resolved Hide resolved
text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
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.

# 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.

text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
text/0000-fn_name_macro.md Show resolved Hide resolved
text/0000-fn_name_macro.md Show resolved Hide resolved
text/0000-fn_name_macro.md Outdated Show resolved Hide resolved
@Centril Centril added T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC. A-macros-libstd Proposals that introduce new standard library macros labels Nov 15, 2019
@Centril
Copy link
Contributor

Centril commented Nov 15, 2019

Who is going to implement this RFC by the way? I think we should have someone available to do that, with mentoring if necessary (if so a mentor is required, e.g. @petrochenkov), before accepting the RFC.

@da-x
Copy link
Member

da-x commented Nov 15, 2019

I have a reference implementation of this feature.

https://github.com/da-x/rust/tree/function-macro-1.38.0

It's working, but would probably need some changes to conform to the RFC.

@Centril
Copy link
Contributor

Centril commented Nov 15, 2019

https://github.com/da-x/rust/tree/function-macro-1.38.0

Hmm; it feels fairly invasive to add &Option<ast::Path> in so many places. Looking over that, I think something like item_path!() which is the concatenation of the module_path!() as well as e.g. StructName::function_name would be less invasive and strictly more general.

@da-x
Copy link
Member

da-x commented Nov 15, 2019

@Centril I agree regarding having &Option<ast::Path> added in the internal API, and so I've originally also had a change to extend ExtCtxt with a new field instead. However 1) it's for a much earlier rustc version and 2) it uses Rc as in the new Option<Rc<ast::Path>> field which I opt to avoid. Need to see how it fits into the scheme of things now.

@comex
Copy link

comex commented Nov 15, 2019

@comex This is already being implemented rust-lang/rust#65881

What! Now that's the kind of pleasant surprise that comes rarely.

Hmm... but if that is already being implemented, might it make sense to not add a new macro, but instead just add the function name to Location?

It seems like Location::caller() is already enough to get you the current location – making it equivalent to file!()/line!()/etc. – if the current function is not #[track_caller]. But we should probably add something that always gets the current location even if the current function is #[track_caller]; I'll comment in the tracking issue.

On the other hand, it may be worth adding a macro just to avoid confusing people who see the macros but don't know about Location.

Lokathor and others added 4 commits November 15, 2019 18:44
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
@Lokathor
Copy link
Contributor Author

Updated based on current feedback.

I'm extremely convinced by the item_path!() idea, to the point where if Centril had simply suggested it yesterday instead of today I wouldn't have even opened this RFC.

# 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

@joshtriplett
Copy link
Member

I'm in favor of item_path! as well, as a generalization of this that seems quite useful.

@Lokathor
Copy link
Contributor Author

This time you write it Josh ;3

@nagisa
Copy link
Member

nagisa commented Jan 12, 2020

I wonder if specifying this in terms of type_name::<$thisfunction>() is better and whether this could be more composable and general if we instead added a macro to produce $thisfunction rather than type_name::<$thisfunction>().

@Centril
Copy link
Contributor

Centril commented Jan 17, 2020

@nagisa That would presumably need to account for substitutions to polymorphic functions as well as considering nested fns in fns, no? To me, item_path! seems more general.

@eddyb
Copy link
Member

eddyb commented Jan 19, 2020

If we're bikeshedding the name, something like def_path! feels a bit more general.
(although both it and item_path! feel a bit weird wrt closures)

@Diggsey
Copy link
Contributor

Diggsey commented Jan 19, 2020

Also, scope!/scope_name!/scope_path!/path! are options for the more general version.

@Silentdoer
Copy link

this is in wip?

@Lokathor
Copy link
Contributor Author

No, this is pretty dead I'd have to say.

The idea isn't fundamentally bad, it's just we all got busy with other things.

I'll close this for now.

@Lokathor Lokathor closed this Jul 13, 2020
@ArekPiekarz
Copy link

In the meantime we can use function_name!() from stdext crate - https://docs.rs/stdext/0.2.1/stdext/macro.function_name.html

@brainstorm
Copy link

brainstorm commented Jul 5, 2021

@ArekPiekarz Is the latest version (0.3.0) still working for that purpose? I'm getting the following while trying it out:

% cargo build
   Compiling stdext v0.3.0
error[E0391]: cycle detected when caching mir of `num::integer::<impl at /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:274:9: 440:10>::BITS` for CTFE
   --> /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:277:13
    |
277 |             const BITS: u32 = Self::BITS;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
445 | impl_integer!(u8, u16, u32, u64, u128);
    | --------------------------------------- in this macro invocation
    |
    = note: ...which requires normalizing `<u8 as num::integer::Integer>::BITS`...
note: ...which requires simplifying constant for the type system `num::integer::<impl at /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:274:9: 440:10>::BITS`...
   --> /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:277:13
    |
277 |             const BITS: u32 = Self::BITS;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
445 | impl_integer!(u8, u16, u32, u64, u128);
    | --------------------------------------- in this macro invocation
note: ...which requires simplifying constant for the type system `num::integer::<impl at /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:274:9: 440:10>::BITS`...
   --> /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:277:13
    |
277 |             const BITS: u32 = Self::BITS;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
445 | impl_integer!(u8, u16, u32, u64, u128);
    | --------------------------------------- in this macro invocation
note: ...which requires const-evaluating + checking `num::integer::<impl at /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:274:9: 440:10>::BITS`...
   --> /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:277:13
    |
277 |             const BITS: u32 = Self::BITS;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
445 | impl_integer!(u8, u16, u32, u64, u128);
    | --------------------------------------- in this macro invocation
    = note: ...which again requires caching mir of `num::integer::<impl at /Users/rvalls/.cargo/registry/src/github.com-1ecc6299db9ec823/stdext-0.3.0/src/num/integer.rs:274:9: 440:10>::BITS` for CTFE, completing the cycle
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
error: could not compile `stdext`

To learn more, run the command again with --verbose.

In the meantime I reckon that https://stackoverflow.com/a/63904992/457116 might be a better alternative until this RFC gets merged/implemented for good.

@ArekPiekarz
Copy link

@brainstorm I'm not the author of that crate, but I just tested that it still works in a simple program. Can you share code which exhibits the problem?

@brainstorm
Copy link

@ArekPiekarz I don't have much time to cook a proper small reproducer like I used to in https://github.com/brainstorm/dotenv-codegen-rustc-hang, but here's a 2 line start if you want to have a crack at it:

git clone https://github.com/umccr/aws-benchmarks && cd aws-benchmarks
git checkout 560e531b9bd263f73bbf547eb27f7e2485461c3c && cargo build

... maybe some interaction of the other crates I'm pulling in? Don't know 🤷🏻‍♂️

@ArekPiekarz
Copy link

@brainstorm I have built your project with your instructions without any errors. Here is the log - https://pastebin.com/m86af0pz
I'm on Manjaro 21.0.7 with Rust 1.53.

@brainstorm
Copy link

Yep, that was it! I was running with rustc 1.52.1 (9bc8c42bb 2021-05-09), then did rustup update to 1.53 and everything worked, thx!... stdext should have a MSRV to that, I'll notify upstream accordingly.

@AsteriskZuo
Copy link

The lack of official support is a bit of a shame.

@silverweed
Copy link

So...has Rust just given up on this? Are we doomed to depend on a separate crate for this trivial functionality as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros-libstd Proposals that introduce new standard library macros T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.