File tree 5 files changed +54
-18
lines changed
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;
117
117
use std:: str;
118
118
use std:: uint;
119
119
use syntax:: ast:: * ;
120
- use syntax:: codemap:: Span ;
120
+ use syntax:: codemap:: { BytePos , original_sp , Span } ;
121
121
use syntax:: parse:: token:: special_idents;
122
122
use syntax:: parse:: token;
123
123
use syntax:: print:: pprust:: { expr_to_str, block_to_str} ;
@@ -1473,10 +1473,11 @@ impl<'a> Liveness<'a> {
1473
1473
} ;
1474
1474
if ends_with_stmt {
1475
1475
let last_stmt = body. stmts . last ( ) . unwrap ( ) ;
1476
+ let original_span = original_sp ( last_stmt. span , sp) ;
1476
1477
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
1480
1481
} ;
1481
1482
self . ir . tcx . sess . span_note (
1482
1483
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 {
141
141
Span { lo : lo, hi : hi, expn_info : None }
142
142
}
143
143
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
+
144
155
/// A source code location used for error reporting
145
156
pub struct Loc {
146
157
/// Information about the original source
Original file line number Diff line number Diff line change @@ -686,7 +686,7 @@ mod test {
686
686
}),
687
687
span: sp(17,18)},
688
688
ast::DUMMY_NODE_ID),
689
- span: sp(17,18 )}),
689
+ span: sp(17,19 )}),
690
690
expr: None,
691
691
id: ast::DUMMY_NODE_ID,
692
692
rules: ast::DefaultBlock, // no idea
Original file line number Diff line number Diff line change @@ -3260,9 +3260,14 @@ impl<'a> Parser<'a> {
3260
3260
match self . token {
3261
3261
token:: SEMI => {
3262
3262
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
+ } ;
3263
3268
stmts. push ( @codemap:: Spanned {
3264
3269
node : StmtSemi ( e, stmt_id) ,
3265
- span : stmt . span ,
3270
+ span : span_with_semi ,
3266
3271
} ) ;
3267
3272
}
3268
3273
token:: RBRACE => {
@@ -3275,33 +3280,26 @@ impl<'a> Parser<'a> {
3275
3280
}
3276
3281
StmtMac ( ref m, _) => {
3277
3282
// statement macro; might be an expr
3278
- let has_semi;
3279
3283
match self . token {
3280
3284
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
+ } ) ;
3282
3290
}
3283
3291
token:: RBRACE => {
3284
3292
// if a block ends in `m!(arg)` without
3285
3293
// a `;`, it must be an expr
3286
- has_semi = false ;
3287
3294
expr = Some (
3288
3295
self . mk_mac_expr ( stmt. span . lo ,
3289
3296
stmt. span . hi ,
3290
3297
m. node . clone ( ) ) ) ;
3291
3298
}
3292
3299
_ => {
3293
- has_semi = false ;
3294
3300
stmts. push ( stmt) ;
3295
3301
}
3296
3302
}
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
- }
3305
3303
}
3306
3304
_ => { // all other kinds of statements:
3307
3305
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