File tree Expand file tree Collapse file tree 5 files changed +54
-18
lines changed Expand file tree Collapse file tree 5 files changed +54
-18
lines changed Original file line number Diff line number Diff line change @@ -117,7 +117,7 @@ use std::rc::Rc;
117117use std:: str;
118118use std:: uint;
119119use syntax:: ast:: * ;
120- use syntax:: codemap:: Span ;
120+ use syntax:: codemap:: { BytePos , original_sp , Span } ;
121121use syntax:: parse:: token:: special_idents;
122122use syntax:: parse:: token;
123123use syntax:: print:: pprust:: { expr_to_str, block_to_str} ;
@@ -1473,10 +1473,11 @@ impl<'a> Liveness<'a> {
14731473 } ;
14741474 if ends_with_stmt {
14751475 let last_stmt = body. stmts . last ( ) . unwrap ( ) ;
1476+ let original_span = original_sp ( last_stmt. span , sp) ;
14761477 let span_semicolon = Span {
1477- lo : last_stmt . span . hi ,
1478- hi : last_stmt . span . hi ,
1479- expn_info : last_stmt . span . expn_info
1478+ lo : original_span . hi - BytePos ( 1 ) ,
1479+ hi : original_span . hi ,
1480+ expn_info : original_span . expn_info
14801481 } ;
14811482 self . ir . tcx . sess . span_note (
14821483 span_semicolon, "consider removing this semicolon:" ) ;
Original file line number Diff line number Diff line change @@ -141,6 +141,17 @@ pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
141141 Span { lo : lo, hi : hi, expn_info : None }
142142}
143143
144+ /// Return the span itself if it doesn't come from a macro expansion,
145+ /// otherwise return the call site span up to the `enclosing_sp` by
146+ /// following the `expn_info` chain.
147+ pub fn original_sp ( sp : Span , enclosing_sp : Span ) -> Span {
148+ match ( sp. expn_info , enclosing_sp. expn_info ) {
149+ ( None , _) => sp,
150+ ( Some ( expn1) , Some ( expn2) ) if expn1. call_site == expn2. call_site => sp,
151+ ( Some ( expn1) , _) => original_sp ( expn1. call_site , enclosing_sp) ,
152+ }
153+ }
154+
144155/// A source code location used for error reporting
145156pub struct Loc {
146157 /// Information about the original source
Original file line number Diff line number Diff line change @@ -686,7 +686,7 @@ mod test {
686686 } ) ,
687687 span: sp( 17 , 18 ) } ,
688688 ast:: DUMMY_NODE_ID ) ,
689- span: sp( 17 , 18 ) } ) ,
689+ span: sp( 17 , 19 ) } ) ,
690690 expr: None ,
691691 id: ast:: DUMMY_NODE_ID ,
692692 rules: ast:: DefaultBlock , // no idea
Original file line number Diff line number Diff line change @@ -3260,9 +3260,14 @@ impl<'a> Parser<'a> {
32603260 match self . token {
32613261 token:: SEMI => {
32623262 self . bump ( ) ;
3263+ let span_with_semi = Span {
3264+ lo : stmt. span . lo ,
3265+ hi : self . last_span . hi ,
3266+ expn_info : stmt. span . expn_info ,
3267+ } ;
32633268 stmts. push ( @codemap:: Spanned {
32643269 node : StmtSemi ( e, stmt_id) ,
3265- span : stmt . span ,
3270+ span : span_with_semi ,
32663271 } ) ;
32673272 }
32683273 token:: RBRACE => {
@@ -3275,33 +3280,26 @@ impl<'a> Parser<'a> {
32753280 }
32763281 StmtMac ( ref m, _) => {
32773282 // statement macro; might be an expr
3278- let has_semi;
32793283 match self . token {
32803284 token:: SEMI => {
3281- has_semi = true ;
3285+ self . bump ( ) ;
3286+ stmts. push ( @codemap:: Spanned {
3287+ node : StmtMac ( ( * m) . clone ( ) , true ) ,
3288+ span : stmt. span ,
3289+ } ) ;
32823290 }
32833291 token:: RBRACE => {
32843292 // if a block ends in `m!(arg)` without
32853293 // a `;`, it must be an expr
3286- has_semi = false ;
32873294 expr = Some (
32883295 self . mk_mac_expr ( stmt. span . lo ,
32893296 stmt. span . hi ,
32903297 m. node . clone ( ) ) ) ;
32913298 }
32923299 _ => {
3293- has_semi = false ;
32943300 stmts. push ( stmt) ;
32953301 }
32963302 }
3297-
3298- if has_semi {
3299- self . bump ( ) ;
3300- stmts. push ( @codemap:: Spanned {
3301- node : StmtMac ( ( * m) . clone ( ) , true ) ,
3302- span : stmt. span ,
3303- } ) ;
3304- }
33053303 }
33063304 _ => { // all other kinds of statements:
33073305 stmts. push ( stmt) ;
Original file line number Diff line number Diff line change 1+ // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+ // file at the top-level directory of this distribution and at
3+ // http://rust-lang.org/COPYRIGHT.
4+ //
5+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+ // option. This file may not be copied, modified, or distributed
9+ // except according to those terms.
10+
11+ // Regression test for #13428
12+
13+ fn foo ( ) -> ~str { //~ ERROR not all control paths return a value
14+ format ! ( "Hello {}" ,
15+ "world" )
16+ // Put the trailing semicolon on its own line to test that the
17+ // note message gets the offending semicolon exactly
18+ ; //~ NOTE consider removing this semicolon
19+ }
20+
21+ fn bar ( ) -> ~str { //~ ERROR not all control paths return a value
22+ "foobar" . to_owned ( )
23+ ; //~ NOTE consider removing this semicolon
24+ }
25+
26+ pub fn main ( ) { }
You can’t perform that action at this time.
0 commit comments