Allow for self to be used inside blocks passed to macros
Nobody has claimed this yet.
- Dominant language
- Markdown
- Stars
- 6.6k
- Forks
- 1.7k
- Avg merge
- 16h 14m
- Merged PRs (30d)
- 1
Description
As reported in https://github.com/rust-lang/rust/issues/15682 it is currently not allowed use the word self in a block passed to a macro because of hygiene issues.
struct A {
pub v: i64
}
macro_rules! pretty {
( $t:ty => $body:block ) => (
impl $t {
pub fn pretty(&self) -> String $body
}
)
}
pretty! (A => {
format!("<A:{}>", self.v)
});
fn main() {
println!("Pretty: {}", A { v: 3 }.pretty());
}
Proposal
I would like to propose to implement the workaround suggested by @Ryman and make an exception for the self keyword in the macro hygiene checker. Afterwards an issue/rfc can be made for a more complete solution.
Advantage
It will enable a class of macros that are currently unavailable. There are some workarounds but they make the macros less intuitive to use, for example the previous example could be written like this:
macro_rules! pretty {
( $t:ty, $_self:ident => $body:block ) => (
impl $t {
pub fn pretty(&$_self) -> String $body
}
)
}
And used like this:
pretty! (A, self => {
format!("<A:{}>", self.v)
});
This works but is unintuitive and gives a confusing error when used with another ident than self.
Disadvantage
@huonw pointed out that this solution will break when an implementation is nested inside a method. This is valid of course, but to me it feels like a bit of a convoluted case. If it does happen in the real world I feel it would not likely fail silently, as both selfs would have to share an interface for the compilation to succeed.
Should this feature be blocked because it has no perfect solution right now? (A more complete suggestion was suggested by @Ryman but it looks to me like it would be a deep and complex hack)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the linked issue 15682 and the macro-hygiene discussion, then compare the proposed self-based and identifier-based macro examples in this issue. Done means the requested exception is specified and the shown macro usage is supported without breaking the nested-implementation case; no source files or tests are named here.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100