@@ -233,7 +233,6 @@ macro_rules! maybe_whole {
233233 )
234234}
235235
236-
237236fn maybe_append ( mut lhs : Vec < Attribute > , rhs : Option < Vec < Attribute > > )
238237 -> Vec < Attribute > {
239238 if let Some ( ref attrs) = rhs {
@@ -255,6 +254,7 @@ pub struct Parser<'a> {
255254 pub cfg : CrateConfig ,
256255 /// the previous token or None (only stashed sometimes).
257256 pub last_token : Option < Box < token:: Token > > ,
257+ last_token_interpolated : bool ,
258258 pub buffer : [ TokenAndSpan ; 4 ] ,
259259 pub buffer_start : isize ,
260260 pub buffer_end : isize ,
@@ -362,6 +362,7 @@ impl<'a> Parser<'a> {
362362 span : span,
363363 last_span : span,
364364 last_token : None ,
365+ last_token_interpolated : false ,
365366 buffer : [
366367 placeholder. clone ( ) ,
367368 placeholder. clone ( ) ,
@@ -542,6 +543,19 @@ impl<'a> Parser<'a> {
542543 self . commit_stmt ( & [ edible] , & [ ] )
543544 }
544545
546+ /// returns the span of expr, if it was not interpolated or the span of the interpolated token
547+ fn interpolated_or_expr_span ( & self ,
548+ expr : PResult < ' a , P < Expr > > )
549+ -> PResult < ' a , ( Span , P < Expr > ) > {
550+ expr. map ( |e| {
551+ if self . last_token_interpolated {
552+ ( self . last_span , e)
553+ } else {
554+ ( e. span , e)
555+ }
556+ } )
557+ }
558+
545559 pub fn parse_ident ( & mut self ) -> PResult < ' a , ast:: Ident > {
546560 self . check_strict_keywords ( ) ;
547561 self . check_reserved_keywords ( ) ;
@@ -933,6 +947,7 @@ impl<'a> Parser<'a> {
933947 } else {
934948 None
935949 } ;
950+ self . last_token_interpolated = self . token . is_interpolated ( ) ;
936951 let next = if self . buffer_start == self . buffer_end {
937952 self . reader . real_token ( )
938953 } else {
@@ -2328,18 +2343,20 @@ impl<'a> Parser<'a> {
23282343 -> PResult < ' a , P < Expr > > {
23292344 let attrs = try!( self . parse_or_use_outer_attributes ( already_parsed_attrs) ) ;
23302345
2331- let b = try!( self . parse_bottom_expr ( ) ) ;
2332- self . parse_dot_or_call_expr_with ( b, attrs)
2346+ let b = self . parse_bottom_expr ( ) ;
2347+ let ( span, b) = try!( self . interpolated_or_expr_span ( b) ) ;
2348+ self . parse_dot_or_call_expr_with ( b, span. lo , attrs)
23332349 }
23342350
23352351 pub fn parse_dot_or_call_expr_with ( & mut self ,
23362352 e0 : P < Expr > ,
2353+ lo : BytePos ,
23372354 attrs : ThinAttributes )
23382355 -> PResult < ' a , P < Expr > > {
23392356 // Stitch the list of outer attributes onto the return value.
23402357 // A little bit ugly, but the best way given the current code
23412358 // structure
2342- self . parse_dot_or_call_expr_with_ ( e0)
2359+ self . parse_dot_or_call_expr_with_ ( e0, lo )
23432360 . map ( |expr|
23442361 expr. map ( |mut expr| {
23452362 expr. attrs . update ( |a| a. prepend ( attrs) ) ;
@@ -2366,7 +2383,8 @@ impl<'a> Parser<'a> {
23662383 fn parse_dot_suffix ( & mut self ,
23672384 ident : Ident ,
23682385 ident_span : Span ,
2369- self_value : P < Expr > )
2386+ self_value : P < Expr > ,
2387+ lo : BytePos )
23702388 -> PResult < ' a , P < Expr > > {
23712389 let ( _, tys, bindings) = if self . eat ( & token:: ModSep ) {
23722390 try!( self . expect_lt ( ) ) ;
@@ -2380,8 +2398,6 @@ impl<'a> Parser<'a> {
23802398 self . span_err ( last_span, "type bindings are only permitted on trait paths" ) ;
23812399 }
23822400
2383- let lo = self_value. span . lo ;
2384-
23852401 Ok ( match self . token {
23862402 // expr.f() method call.
23872403 token:: OpenDelim ( token:: Paren ) => {
@@ -2414,9 +2430,8 @@ impl<'a> Parser<'a> {
24142430 } )
24152431 }
24162432
2417- fn parse_dot_or_call_expr_with_ ( & mut self , e0 : P < Expr > ) -> PResult < ' a , P < Expr > > {
2433+ fn parse_dot_or_call_expr_with_ ( & mut self , e0 : P < Expr > , lo : BytePos ) -> PResult < ' a , P < Expr > > {
24182434 let mut e = e0;
2419- let lo = e. span . lo ;
24202435 let mut hi;
24212436 loop {
24222437 // expr.f
@@ -2427,7 +2442,7 @@ impl<'a> Parser<'a> {
24272442 hi = self . span . hi ;
24282443 self . bump ( ) ;
24292444
2430- e = try!( self . parse_dot_suffix ( i, mk_sp ( dot_pos, hi) , e) ) ;
2445+ e = try!( self . parse_dot_suffix ( i, mk_sp ( dot_pos, hi) , e, lo ) ) ;
24312446 }
24322447 token:: Literal ( token:: Integer ( n) , suf) => {
24332448 let sp = self . span ;
@@ -2480,7 +2495,7 @@ impl<'a> Parser<'a> {
24802495 let dot_pos = self . last_span . hi ;
24812496 e = try!( self . parse_dot_suffix ( special_idents:: invalid,
24822497 mk_sp ( dot_pos, dot_pos) ,
2483- e) ) ;
2498+ e, lo ) ) ;
24842499 }
24852500 }
24862501 continue ;
@@ -2715,27 +2730,31 @@ impl<'a> Parser<'a> {
27152730 let ex = match self . token {
27162731 token:: Not => {
27172732 self . bump ( ) ;
2718- let e = try!( self . parse_prefix_expr ( None ) ) ;
2719- hi = e. span . hi ;
2733+ let e = self . parse_prefix_expr ( None ) ;
2734+ let ( span, e) = try!( self . interpolated_or_expr_span ( e) ) ;
2735+ hi = span. hi ;
27202736 self . mk_unary ( UnNot , e)
27212737 }
27222738 token:: BinOp ( token:: Minus ) => {
27232739 self . bump ( ) ;
2724- let e = try!( self . parse_prefix_expr ( None ) ) ;
2725- hi = e. span . hi ;
2740+ let e = self . parse_prefix_expr ( None ) ;
2741+ let ( span, e) = try!( self . interpolated_or_expr_span ( e) ) ;
2742+ hi = span. hi ;
27262743 self . mk_unary ( UnNeg , e)
27272744 }
27282745 token:: BinOp ( token:: Star ) => {
27292746 self . bump ( ) ;
2730- let e = try!( self . parse_prefix_expr ( None ) ) ;
2731- hi = e. span . hi ;
2747+ let e = self . parse_prefix_expr ( None ) ;
2748+ let ( span, e) = try!( self . interpolated_or_expr_span ( e) ) ;
2749+ hi = span. hi ;
27322750 self . mk_unary ( UnDeref , e)
27332751 }
27342752 token:: BinOp ( token:: And ) | token:: AndAnd => {
27352753 try!( self . expect_and ( ) ) ;
27362754 let m = try!( self . parse_mutability ( ) ) ;
2737- let e = try!( self . parse_prefix_expr ( None ) ) ;
2738- hi = e. span . hi ;
2755+ let e = self . parse_prefix_expr ( None ) ;
2756+ let ( span, e) = try!( self . interpolated_or_expr_span ( e) ) ;
2757+ hi = span. hi ;
27392758 ExprAddrOf ( m, e)
27402759 }
27412760 token:: Ident ( ..) if self . token . is_keyword ( keywords:: In ) => {
@@ -2753,9 +2772,10 @@ impl<'a> Parser<'a> {
27532772 }
27542773 token:: Ident ( ..) if self . token . is_keyword ( keywords:: Box ) => {
27552774 self . bump ( ) ;
2756- let subexpression = try!( self . parse_prefix_expr ( None ) ) ;
2757- hi = subexpression. span . hi ;
2758- ExprBox ( subexpression)
2775+ let e = self . parse_prefix_expr ( None ) ;
2776+ let ( span, e) = try!( self . interpolated_or_expr_span ( e) ) ;
2777+ hi = span. hi ;
2778+ ExprBox ( e)
27592779 }
27602780 _ => return self . parse_dot_or_call_expr ( Some ( attrs) )
27612781 } ;
@@ -2790,12 +2810,21 @@ impl<'a> Parser<'a> {
27902810 try!( self . parse_prefix_expr ( attrs) )
27912811 }
27922812 } ;
2813+
2814+
27932815 if self . expr_is_complete ( & * lhs) {
27942816 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
27952817 return Ok ( lhs) ;
27962818 }
27972819 self . expected_tokens . push ( TokenType :: Operator ) ;
27982820 while let Some ( op) = AssocOp :: from_token ( & self . token ) {
2821+
2822+ let lhs_span = if self . last_token_interpolated {
2823+ self . last_span
2824+ } else {
2825+ lhs. span
2826+ } ;
2827+
27992828 let cur_op_span = self . span ;
28002829 let restrictions = if op. is_assign_like ( ) {
28012830 self . restrictions & Restrictions :: RESTRICTION_NO_STRUCT_LITERAL
@@ -2812,12 +2841,12 @@ impl<'a> Parser<'a> {
28122841 // Special cases:
28132842 if op == AssocOp :: As {
28142843 let rhs = try!( self . parse_ty ( ) ) ;
2815- lhs = self . mk_expr ( lhs . span . lo , rhs. span . hi ,
2844+ lhs = self . mk_expr ( lhs_span . lo , rhs. span . hi ,
28162845 ExprCast ( lhs, rhs) , None ) ;
28172846 continue
28182847 } else if op == AssocOp :: Colon {
28192848 let rhs = try!( self . parse_ty ( ) ) ;
2820- lhs = self . mk_expr ( lhs . span . lo , rhs. span . hi ,
2849+ lhs = self . mk_expr ( lhs_span . lo , rhs. span . hi ,
28212850 ExprType ( lhs, rhs) , None ) ;
28222851 continue
28232852 } else if op == AssocOp :: DotDot {
@@ -2839,7 +2868,7 @@ impl<'a> Parser<'a> {
28392868 } else {
28402869 None
28412870 } ;
2842- let ( lhs_span, rhs_span) = ( lhs . span , if let Some ( ref x) = rhs {
2871+ let ( lhs_span, rhs_span) = ( lhs_span , if let Some ( ref x) = rhs {
28432872 x. span
28442873 } else {
28452874 cur_op_span
@@ -2879,14 +2908,14 @@ impl<'a> Parser<'a> {
28792908 AssocOp :: Equal | AssocOp :: Less | AssocOp :: LessEqual | AssocOp :: NotEqual |
28802909 AssocOp :: Greater | AssocOp :: GreaterEqual => {
28812910 let ast_op = op. to_ast_binop ( ) . unwrap ( ) ;
2882- let ( lhs_span, rhs_span) = ( lhs . span , rhs. span ) ;
2911+ let ( lhs_span, rhs_span) = ( lhs_span , rhs. span ) ;
28832912 let binary = self . mk_binary ( codemap:: respan ( cur_op_span, ast_op) , lhs, rhs) ;
28842913 self . mk_expr ( lhs_span. lo , rhs_span. hi , binary, None )
28852914 }
28862915 AssocOp :: Assign =>
2887- self . mk_expr ( lhs . span . lo , rhs. span . hi , ExprAssign ( lhs, rhs) , None ) ,
2916+ self . mk_expr ( lhs_span . lo , rhs. span . hi , ExprAssign ( lhs, rhs) , None ) ,
28882917 AssocOp :: Inplace =>
2889- self . mk_expr ( lhs . span . lo , rhs. span . hi , ExprInPlace ( lhs, rhs) , None ) ,
2918+ self . mk_expr ( lhs_span . lo , rhs. span . hi , ExprInPlace ( lhs, rhs) , None ) ,
28902919 AssocOp :: AssignOp ( k) => {
28912920 let aop = match k {
28922921 token:: Plus => BiAdd ,
@@ -2900,7 +2929,7 @@ impl<'a> Parser<'a> {
29002929 token:: Shl => BiShl ,
29012930 token:: Shr => BiShr
29022931 } ;
2903- let ( lhs_span, rhs_span) = ( lhs . span , rhs. span ) ;
2932+ let ( lhs_span, rhs_span) = ( lhs_span , rhs. span ) ;
29042933 let aopexpr = self . mk_assign_op ( codemap:: respan ( cur_op_span, aop) , lhs, rhs) ;
29052934 self . mk_expr ( lhs_span. lo , rhs_span. hi , aopexpr, None )
29062935 }
@@ -3834,7 +3863,8 @@ impl<'a> Parser<'a> {
38343863 let e = self . mk_mac_expr ( span. lo , span. hi ,
38353864 mac. and_then ( |m| m. node ) ,
38363865 None ) ;
3837- let e = try!( self . parse_dot_or_call_expr_with ( e, attrs) ) ;
3866+ let lo = e. span . lo ;
3867+ let e = try!( self . parse_dot_or_call_expr_with ( e, lo, attrs) ) ;
38383868 let e = try!( self . parse_assoc_expr_with ( 0 , LhsExpr :: AlreadyParsed ( e) ) ) ;
38393869 try!( self . handle_expression_like_statement (
38403870 e,
0 commit comments