fn into_expr(mut self) -> P<ast::Expr> {
        let mut locals = Vec::new();
        let mut counts = Vec::new();
        let mut pats = Vec::new();
        let mut heads = Vec::new();

        // First, build up the static array which will become our precompiled
        // format "string"
        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.name());
        let piece_ty = self.ecx.ty_rptr(
                self.fmtsp,
                self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
                Some(static_lifetime),
                ast::Mutability::Immutable);
        let pieces = Context::static_array(self.ecx,
                                           "__STATIC_FMTSTR",
                                           piece_ty,
                                           self.str_pieces);

        // Before consuming the expressions, we have to remember spans for
        // count arguments as they are now generated separate from other
        // arguments, hence have no access to the `P<ast::Expr>`'s.
        let spans_pos: Vec<_> = self.args.iter().map(|e| e.span.clone()).collect();

        // Right now there is a bug such that for the expression:
        //      foo(bar(&1))
        // the lifetime of `1` doesn't outlast the call to `bar`, so it's not
        // valid for the call to `foo`. To work around this all arguments to the
        // format! string are shoved into locals. Furthermore, we shove the address
        // of each variable because we don't want to move out of the arguments
        // passed to this function.
        for (i, e) in self.args.into_iter().enumerate() {
            let name = self.ecx.ident_of(&format!("__arg{}", i));
            pats.push(self.ecx.pat_ident(DUMMY_SP, name));
            for ref arg_ty in self.arg_unique_types[i].iter() {
                locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty,
                                                self.ecx.expr_ident(e.span, name)));
            }
            heads.push(self.ecx.expr_addr_of(e.span, e));
        }
        for pos in self.count_args {
            let name = self.ecx.ident_of(&match pos {
                Exact(i) => format!("__arg{}", i),
                _ => panic!("should never happen"),
            });
            let span = match pos {
                Exact(i) => spans_pos[i],
                _ => panic!("should never happen"),
            };
            counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count,
                                            self.ecx.expr_ident(span, name)));
        }

        // Now create a vector containing all the arguments
        let args = locals.into_iter().chain(counts.into_iter());

        let args_array = self.ecx.expr_vec(self.fmtsp, args.collect());

        // Constructs an AST equivalent to:
        //
        //      match (&arg0, &arg1) {
        //          (tmp0, tmp1) => args_array
        //      }
        //
        // It was:
        //
        //      let tmp0 = &arg0;
        //      let tmp1 = &arg1;
        //      args_array
        //
        // Because of #11585 the new temporary lifetime rule, the enclosing
        // statements for these temporaries become the let's themselves.
        // If one or more of them are RefCell's, RefCell borrow() will also
        // end there; they don't last long enough for args_array to use them.
        // The match expression solves the scope problem.
        //
        // Note, it may also very well be transformed to:
        //
        //      match arg0 {
        //          ref tmp0 => {
        //              match arg1 => {
        //                  ref tmp1 => args_array } } }
        //
        // But the nested match expression is proved to perform not as well
        // as series of let's; the first approach does.
        let pat = self.ecx.pat_tuple(self.fmtsp, pats);
        let arm = self.ecx.arm(self.fmtsp, vec!(pat), args_array);
        let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads));
        let result = self.ecx.expr_match(self.fmtsp, head, vec!(arm));

        let args_slice = self.ecx.expr_addr_of(self.fmtsp, result);

        // Now create the fmt::Arguments struct with all our locals we created.
        let (fn_name, fn_args) = if self.all_pieces_simple {
            ("new_v1", vec![pieces, args_slice])
        } else {
            // Build up the static array which will store our precompiled
            // nonstandard placeholders, if there are any.
            let piece_ty = self.ecx.ty_path(self.ecx.path_global(
                    self.macsp,
                    Context::rtpath(self.ecx, "Argument")));
            let fmt = Context::static_array(self.ecx,
                                            "__STATIC_FMTARGS",
                                            piece_ty,
                                            self.pieces);

            ("new_v1_formatted", vec![pieces, args_slice, fmt])
        };

        let path = self.ecx.std_path(&["fmt", "Arguments", fn_name]);
        self.ecx.expr_call_global(self.macsp, path, fn_args)
    }
/// Actually builds the expression which the format_args! block will be
/// expanded to
Actually builds the expression which the format_args. block will be
expanded to
Actually builds the expression which the format_args . block will be expanded to
fn into_expr(mut self) -> P<ast::Expr> {
        let mut locals = Vec::new();
        let mut counts = Vec::new();
        let mut pats = Vec::new();
        let mut heads = Vec::new();
        // First, build up the static array which will become our precompiled
        // format "string"
        let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.name());
        let piece_ty = self.ecx.ty_rptr(
                self.fmtsp,
                self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
                Some(static_lifetime),
                ast::Mutability::Immutable);
        let pieces = Context::static_array(self.ecx,
                                           "__STATIC_FMTSTR",
                                           piece_ty,
                                           self.str_pieces);
        // Before consuming the expressions, we have to remember spans for
        // count arguments as they are now generated separate from other
        // arguments, hence have no access to the `P<ast::Expr>`'s.
        let spans_pos: Vec<_> = self.args.iter().map(|e| e.span.clone()).collect();
        // Right now there is a bug such that for the expression:
        //      foo(bar(&1))
        // the lifetime of `1` doesn't outlast the call to `bar`, so it's not
        // valid for the call to `foo`. To work around this all arguments to the
        // format! string are shoved into locals. Furthermore, we shove the address
        // of each variable because we don't want to move out of the arguments
        // passed to this function.
        for (i, e) in self.args.into_iter().enumerate() {
            let name = self.ecx.ident_of(&format!("__arg{}", i));
            pats.push(self.ecx.pat_ident(DUMMY_SP, name));
            for ref arg_ty in self.arg_unique_types[i].iter() {
                locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty,
                                                self.ecx.expr_ident(e.span, name)));
            }
            heads.push(self.ecx.expr_addr_of(e.span, e));
        }
        for pos in self.count_args {
            let name = self.ecx.ident_of(&match pos {
                Exact(i) => format!("__arg{}", i),
                _ => panic!("should never happen"),
            });
            let span = match pos {
                Exact(i) => spans_pos[i],
                _ => panic!("should never happen"),
            };
            counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count,
                                            self.ecx.expr_ident(span, name)));
        }
        // Now create a vector containing all the arguments
        let args = locals.into_iter().chain(counts.into_iter());
        let args_array = self.ecx.expr_vec(self.fmtsp, args.collect());
        // Constructs an AST equivalent to:
        //
        //      match (&arg0, &arg1) {
        //          (tmp0, tmp1) => args_array
        //      }
        //
        // It was:
        //
        //      let tmp0 = &arg0;
        //      let tmp1 = &arg1;
        //      args_array
        //
        // Because of #11585 the new temporary lifetime rule, the enclosing
        // statements for these temporaries become the let's themselves.
        // If one or more of them are RefCell's, RefCell borrow() will also
        // end there; they don't last long enough for args_array to use them.
        // The match expression solves the scope problem.
        //
        // Note, it may also very well be transformed to:
        //
        //      match arg0 {
        //          ref tmp0 => {
        //              match arg1 => {
        //                  ref tmp1 => args_array } } }
        //
        // But the nested match expression is proved to perform not as well
        // as series of let's; the first approach does.
        let pat = self.ecx.pat_tuple(self.fmtsp, pats);
        let arm = self.ecx.arm(self.fmtsp, vec!(pat), args_array);
        let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads));
        let result = self.ecx.expr_match(self.fmtsp, head, vec!(arm));
        let args_slice = self.ecx.expr_addr_of(self.fmtsp, result);
        // Now create the fmt::Arguments struct with all our locals we created.
        let (fn_name, fn_args) = if self.all_pieces_simple {
            ("new_v1", vec![pieces, args_slice])
        } else {
            // Build up the static array which will store our precompiled
            // nonstandard placeholders, if there are any.
            let piece_ty = self.ecx.ty_path(self.ecx.path_global(
                    self.macsp,
                    Context::rtpath(self.ecx, "Argument")));
            let fmt = Context::static_array(self.ecx,
                                            "__STATIC_FMTARGS",
                                            piece_ty,
                                            self.pieces);
            ("new_v1_formatted", vec![pieces, args_slice, fmt])
        };
        let path = self.ecx.std_path(&["fmt", "Arguments", fn_name]);
        self.ecx.expr_call_global(self.macsp, path, fn_args)
    }
fn into_expr ( mut self ) -> P < ast :: Expr > { let mut locals = Vec :: new ( ) ; let mut counts = Vec :: new ( ) ; let mut pats = Vec :: new ( ) ; let mut heads = Vec :: new ( ) ; // First, build up the static array which will become our precompiled // format "string" let static_lifetime = self . ecx . lifetime ( self . fmtsp , keywords :: StaticLifetime . name ( ) ) ; let piece_ty = self . ecx . ty_rptr ( self . fmtsp , self . ecx . ty_ident ( self . fmtsp , self . ecx . ident_of ( " " ) ) , Some ( static_lifetime ) , ast :: Mutability :: Immutable ) ; let pieces = Context :: static_array ( self . ecx , " " , piece_ty , self . str_pieces ) ; // Before consuming the expressions, we have to remember spans for // count arguments as they are now generated separate from other // arguments, hence have no access to the `P<ast::Expr>`'s. let spans_pos : Vec < _ > = self . args . iter ( ) . map ( | e | e . span . clone ( ) ) . collect ( ) ; // Right now there is a bug such that for the expression: //      foo(bar(&1)) // the lifetime of `1` doesn't outlast the call to `bar`, so it's not // valid for the call to `foo`. To work around this all arguments to the // format! string are shoved into locals. Furthermore, we shove the address // of each variable because we don't want to move out of the arguments // passed to this function. for ( i , e ) in self . args . into_iter ( ) . enumerate ( ) { let name = self . ecx . ident_of ( & format ! ( " " i ) ) ; pats . push ( self . ecx . pat_ident ( DUMMY_SP , name ) ) ; for ref arg_ty in self . arg_unique_types [ i ] . iter ( ) { locals . push ( Context :: format_arg ( self . ecx , self . macsp , e . span , arg_ty , self . ecx . expr_ident ( e . span , name ) ) ) ; } heads . push ( self . ecx . expr_addr_of ( e . span , e ) ) ; } for pos in self . count_args { let name = self . ecx . ident_of ( & match pos { Exact ( i ) => format ! ( " " i ) , _ => panic ! ( " " ) , } ) ; let span = match pos { Exact ( i ) => spans_pos [ i ] , _ => panic ! ( " " ) , } ; counts . push ( Context :: format_arg ( self . ecx , self . macsp , span , & Count , self . ecx . expr_ident ( span , name ) ) ) ; } // Now create a vector containing all the arguments let args = locals . into_iter ( ) . chain ( counts . into_iter ( ) ) ; let args_array = self . ecx . expr_vec ( self . fmtsp , args . collect ( ) ) ; // Constructs an AST equivalent to: // //      match (&arg0, &arg1) { //          (tmp0, tmp1) => args_array //      } // // It was: // //      let tmp0 = &arg0; //      let tmp1 = &arg1; //      args_array // // Because of #11585 the new temporary lifetime rule, the enclosing // statements for these temporaries become the let's themselves. // If one or more of them are RefCell's, RefCell borrow() will also // end there; they don't last long enough for args_array to use them. // The match expression solves the scope problem. // // Note, it may also very well be transformed to: // //      match arg0 { //          ref tmp0 => { //              match arg1 => { //                  ref tmp1 => args_array } } } // // But the nested match expression is proved to perform not as well // as series of let's; the first approach does. let pat = self . ecx . pat_tuple ( self . fmtsp , pats ) ; let arm = self . ecx . arm ( self . fmtsp , vec ! ( pat ) , args_array ) ; let head = self . ecx . expr ( self . fmtsp , ast :: ExprKind :: Tup ( heads ) ) ; let result = self . ecx . expr_match ( self . fmtsp , head , vec ! ( arm ) ) ; let args_slice = self . ecx . expr_addr_of ( self . fmtsp , result ) ; // Now create the fmt::Arguments struct with all our locals we created. let ( fn_name , fn_args ) = if self . all_pieces_simple { ( " " , vec ! [ pieces args_slice ] ) } else { // Build up the static array which will store our precompiled // nonstandard placeholders, if there are any. let piece_ty = self . ecx . ty_path ( self . ecx . path_global ( self . macsp , Context :: rtpath ( self . ecx , " " ) ) ) ; let fmt = Context :: static_array ( self . ecx , " " , piece_ty , self . pieces ) ; ( " " , vec ! [ pieces args_slice fmt ] ) } ; let path = self . ecx . std_path ( & [ " " , " " , fn_name ] ) ; self . ecx . expr_call_global ( self . macsp , path , fn_args ) }
Actually builds the expression which the format_args!
Actually builds the expression which the format_args!
mut self
mut self