Skip to content

access to &self in display() #6

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

Closed
colin-kiegel opened this issue Dec 19, 2015 · 6 comments
Closed

access to &self in display() #6

colin-kiegel opened this issue Dec 19, 2015 · 6 comments

Comments

@colin-kiegel
Copy link
Contributor

compile error: self is not available in a static method. Maybe a self argument is missing? [E0424]

I would like to reuse the error description in the Display::fmt function on some occasions. It would be nice to do this by delegation to self.description(). There might be addional usecases for &self access.

quick_error! {
    #[derive(Debug)]
    pub enum LoaderError {
        ArrayTemplateNotFound(name: String) {
            description("Template not found")
            display("{}: {:?}", self.description(), name)
        }
    }
}
@tailhook
Copy link
Owner

Well, I'm okay with this proposal. But I'm not sure it's possible. You will need to define name "self" in this code too because of macro hygiene. Like display2(self, "{}: {:?}", self.description(), name).

@colin-kiegel
Copy link
Contributor Author

You are right - this is macro hygiene. It should work by passing a closure like display_fn(|self_| { format!("{}", self_.description()), or possibly better display_fn(|self_, f| { write!(f, "{}", self_.description()) - since using write! should save the allocation done by format!.

The question then is how to react if someone defines both display and display_fn (or whatever the name will be).

@colin-kiegel
Copy link
Contributor Author

Ok, you were right again. Passing a closure didn't work. With PR #8 the macro uses closures internally now, but the signature of display_fn is like you suggested. What do you think? Should it be called display_ref instead?

I was also thinking about trying to overload the definition of display("...") and display(X, "..."), but I am not sure if that could lead to problems in some corner cases, where "..." might be behind an identifier X. I didn't test that.

Regarding the question of duplicate display vs. display_fn implementations - the current design will silently only take the first implementation in order of appearance. This is the current behaviour with multiple display implementations.

@tailhook
Copy link
Owner

Well, I think the syntax should be:

display(self) -> ("...", a, b)

Because there is a similar from(x) -> (..) construction. Otherwise it's fine.

@colin-kiegel
Copy link
Contributor Author

Hm, I can't get it to work - rust either complains

src/lib.rs:616:25: 616:43 error: expected ident, found "I/O error: {err}"
src/lib.rs:616                 display("I/O error: {err}", err=err)
                                       ^~~~~~~~~~~~~~~~~~

or

src/lib.rs:626:25: 626:30 error: format argument must be a string literal.
src/lib.rs:626                 display(self_) -> ("{} {}: {}", self_.description(), place, err)
                                       ^~~~~

Depending on which matcher comes first:

    (FIND_DISPLAY_IMPL $name:ident $item:ident
        { display($self_:ident) -> ($($exprs:tt)*) $($tail:tt)* }
    ) => {
        |$self_: &$name, f: &mut ::std::fmt::Formatter| { write!(f, $($exprs)*) }
    };
    (FIND_DISPLAY_IMPL $name:ident $item:ident
        { display($($exprs:tt)*) $($tail:tt)* }
    ) => {
        |_, f: &mut ::std::fmt::Formatter| { write!(f, $($exprs)*) }
    };

@tailhook
Copy link
Owner

@colin-kiegel, I think I've figured out a way to do that in #10. Could you take a look if I'm missing something? I will probably squash the commits then.

tailhook added a commit that referenced this issue Dec 24, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants