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

Try rethinking the format_args! macro #11838

Closed
alexcrichton opened this issue Jan 27, 2014 · 5 comments
Closed

Try rethinking the format_args! macro #11838

alexcrichton opened this issue Jan 27, 2014 · 5 comments
Labels
A-syntaxext Area: Syntax extensions

Comments

@alexcrichton
Copy link
Member

This macro was written when rvalue lifetimes were pretty short, so the first argument is a closure or a bare function taking a local as an argument (the local is restrained to an inserted scope).

With our newly minted rvalue lifetime rules, this macro should be re-evaluated. It really wants to look like this:

let args = format_args!("foo, {} {}", "bar", 3);
@huonw
Copy link
Member

huonw commented Jan 27, 2014

(I think calling it parse_format!() or something would make sense if it gets converted to returning a value like this. )

@alexcrichton
Copy link
Member Author

Currently the formatting code does a bunch of function calls with references, and I wasn't able to get it to work out. I think that this may be the crux of it though:

struct Foo<'a> {                   
    v: &'a int                     
}                                  

fn foo<'a>(f: &'a int) -> Foo<'a> {
    Foo { v: f }                   
}                                  

fn main() {                        
    let args = foo(&1);            
}                                  

That code does not compile today

$ rustc out.rs
out.rs:10:20: 10:22 error: borrowed value does not live long enough
out.rs:10     let args = foo(&1);
                             ^~
out.rs:9:11: 11:2 note: reference must be valid for the block at 9:10...
out.rs:9 fn main() {
out.rs:10     let args = foo(&1);
out.rs:11 }
out.rs:10:9: 10:23 note: ...but borrowed value is only valid for the statement at 10:8
out.rs:10     let args = foo(&1);
                  ^~~~~~~~~~~~~~
error: aborting due to previous error

@nikomatsakis, should that code compile?

@nikomatsakis
Copy link
Contributor

Nope. This is one of the cases of temporary lifetimes that won't work well without inference. Though you could write:

match format_args!(...) {
    args => {
    }
}

and that ought to work. Somewhat goofy.

@nikomatsakis
Copy link
Contributor

Another option is to remove the intermediate function. If it expanded to: let args = Foo { one: &1 } then the rvalue lifetime rules would work out just fine, because it's syntactically visible that the &1 is being assigned into args.

@alexcrichton
Copy link
Member Author

Sadly, I don't think this is possible for now then. Function calls are used to enforce trait bounds of formatting traits and to get nice error messages, so it looks like we're stuck with the closure/function solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-syntaxext Area: Syntax extensions
Projects
None yet
Development

No branches or pull requests

3 participants