Skip to content

Commit 2b35e6f

Browse files
committed
auto merge of #19357 : michaelwoerister/rust/fix-issue-18791, r=alexcrichton
One negative side-effect of this change is that there might be quite a bit of copying strings out of the codemap, i.e. one copy for every block that gets translated, just for taking a look at the last character of the block. If this turns out to cause a performance problem then `CodeMap::span_to_snippet()` could be changed return `Option<&str>` instead of `Option<String>`. Fixes #18791
2 parents 8dbe632 + 61a0a7f commit 2b35e6f

File tree

5 files changed

+62
-18
lines changed

5 files changed

+62
-18
lines changed

src/librustc_trans/trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1816,7 +1816,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18161816

18171817
// cleanup scope for the incoming arguments
18181818
let fn_cleanup_debug_loc =
1819-
debuginfo::get_cleanup_debug_loc_for_ast_node(fn_ast_id, body.span, true);
1819+
debuginfo::get_cleanup_debug_loc_for_ast_node(ccx, fn_ast_id, body.span, true);
18201820
let arg_scope = fcx.push_custom_cleanup_scope_with_debug_loc(fn_cleanup_debug_loc);
18211821

18221822
let block_ty = node_id_type(bcx, body.id);

src/librustc_trans/trans/controlflow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
5555

5656
let id = ast_util::stmt_id(s);
5757
let cleanup_debug_loc =
58-
debuginfo::get_cleanup_debug_loc_for_ast_node(id, s.span, false);
58+
debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(), id, s.span, false);
5959
fcx.push_ast_cleanup_scope(cleanup_debug_loc);
6060

6161
match s.node {
@@ -103,7 +103,7 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
103103
let mut bcx = bcx;
104104

105105
let cleanup_debug_loc =
106-
debuginfo::get_cleanup_debug_loc_for_ast_node(b.id, b.span, true);
106+
debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(), b.id, b.span, true);
107107
fcx.push_ast_cleanup_scope(cleanup_debug_loc);
108108

109109
for s in b.stmts.iter() {

src/librustc_trans/trans/debuginfo.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -1047,10 +1047,11 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
10471047
})
10481048
}
10491049

1050-
pub fn get_cleanup_debug_loc_for_ast_node(node_id: ast::NodeId,
1051-
node_span: Span,
1052-
is_block: bool)
1053-
-> NodeInfo {
1050+
pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1051+
node_id: ast::NodeId,
1052+
node_span: Span,
1053+
is_block: bool)
1054+
-> NodeInfo {
10541055
// A debug location needs two things:
10551056
// (1) A span (of which only the beginning will actually be used)
10561057
// (2) An AST node-id which will be used to look up the lexical scope
@@ -1080,15 +1081,25 @@ pub fn get_cleanup_debug_loc_for_ast_node(node_id: ast::NodeId,
10801081
// scope is actually left when the cleanup code is executed.
10811082
// In practice it shouldn't make much of a difference.
10821083

1083-
let cleanup_span = if is_block {
1084-
Span {
1085-
lo: node_span.hi - codemap::BytePos(1), // closing brace should always be 1 byte...
1086-
hi: node_span.hi,
1087-
expn_id: node_span.expn_id
1084+
let mut cleanup_span = node_span;
1085+
1086+
if is_block {
1087+
// Not all blocks actually have curly braces (e.g. simple closure
1088+
// bodies), in which case we also just want to return the span of the
1089+
// whole expression.
1090+
let code_snippet = cx.sess().codemap().span_to_snippet(node_span);
1091+
if let Some(code_snippet) = code_snippet {
1092+
let bytes = code_snippet.as_bytes();
1093+
1094+
if bytes.len() > 0 && bytes[bytes.len()-1 ..] == b"}" {
1095+
cleanup_span = Span {
1096+
lo: node_span.hi - codemap::BytePos(1),
1097+
hi: node_span.hi,
1098+
expn_id: node_span.expn_id
1099+
};
1100+
}
10881101
}
1089-
} else {
1090-
node_span
1091-
};
1102+
}
10921103

10931104
NodeInfo {
10941105
id: node_id,

src/librustc_trans/trans/expr.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
9797

9898
debug!("trans_into() expr={}", expr.repr(bcx.tcx()));
9999

100-
let cleanup_debug_loc = debuginfo::get_cleanup_debug_loc_for_ast_node(expr.id,
100+
let cleanup_debug_loc = debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(),
101+
expr.id,
101102
expr.span,
102103
false);
103104
bcx.fcx.push_ast_cleanup_scope(cleanup_debug_loc);
@@ -130,7 +131,8 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
130131
let mut bcx = bcx;
131132
let fcx = bcx.fcx;
132133

133-
let cleanup_debug_loc = debuginfo::get_cleanup_debug_loc_for_ast_node(expr.id,
134+
let cleanup_debug_loc = debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(),
135+
expr.id,
134136
expr.span,
135137
false);
136138
fcx.push_ast_cleanup_scope(cleanup_debug_loc);
@@ -618,7 +620,10 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
618620
ast::ExprRepeat(..) | ast::ExprVec(..) => {
619621
// Special case for slices.
620622
let cleanup_debug_loc =
621-
debuginfo::get_cleanup_debug_loc_for_ast_node(x.id, x.span, false);
623+
debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(),
624+
x.id,
625+
x.span,
626+
false);
622627
fcx.push_ast_cleanup_scope(cleanup_debug_loc);
623628
let datum = unpack_datum!(
624629
bcx, tvec::trans_slice_vec(bcx, expr, &**x));
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2013-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+
// ignore-android: FIXME(#10381)
12+
// min-lldb-version: 310
13+
14+
// compile-flags:-g
15+
16+
#![feature(non_ascii_idents)]
17+
18+
// This test checks whether debuginfo generation can handle multi-byte UTF-8
19+
// characters at the end of a block. There's no need to do anything in the
20+
// debugger -- just make sure that the compiler doesn't crash.
21+
// See also issue #18791.
22+
23+
struct C { θ: u8 }
24+
25+
fn main() {
26+
let x = C { θ: 0 };
27+
(|c: C| c.θ )(x);
28+
}

0 commit comments

Comments
 (0)