11use self :: InternalDebugLocation :: * ;
22
3- use super :: utils:: { debug_context, span_start } ;
3+ use super :: utils:: debug_context;
44use super :: metadata:: UNKNOWN_COLUMN_NUMBER ;
55use rustc_codegen_ssa:: mir:: debuginfo:: FunctionDebugContext ;
66
77use crate :: llvm;
88use crate :: llvm:: debuginfo:: DIScope ;
99use crate :: builder:: Builder ;
10+ use crate :: common:: CodegenCx ;
1011use rustc_codegen_ssa:: traits:: * ;
1112
13+ use std:: num:: NonZeroUsize ;
14+
1215use libc:: c_uint;
1316use syntax_pos:: { Span , Pos } ;
1417
@@ -23,8 +26,7 @@ pub fn set_source_location<D>(
2326) {
2427 let dbg_loc = if debug_context. source_locations_enabled {
2528 debug ! ( "set_source_location: {}" , bx. sess( ) . source_map( ) . span_to_string( span) ) ;
26- let loc = span_start ( bx. cx ( ) , span) ;
27- InternalDebugLocation :: new ( scope, loc. line , loc. col . to_usize ( ) )
29+ InternalDebugLocation :: from_span ( bx. cx ( ) , scope, span)
2830 } else {
2931 UnknownLocation
3032 } ;
@@ -34,18 +36,43 @@ pub fn set_source_location<D>(
3436
3537#[ derive( Copy , Clone , PartialEq ) ]
3638pub enum InternalDebugLocation < ' ll > {
37- KnownLocation { scope : & ' ll DIScope , line : usize , col : usize } ,
39+ KnownLocation {
40+ scope : & ' ll DIScope ,
41+ line : usize ,
42+ col : Option < NonZeroUsize > ,
43+ } ,
3844 UnknownLocation
3945}
4046
4147impl InternalDebugLocation < ' ll > {
42- pub fn new ( scope : & ' ll DIScope , line : usize , col : usize ) -> Self {
48+ pub fn new ( scope : & ' ll DIScope , line : usize , col : Option < NonZeroUsize > ) -> Self {
4349 KnownLocation {
4450 scope,
4551 line,
4652 col,
4753 }
4854 }
55+
56+ pub fn from_span ( cx : & CodegenCx < ' ll , ' _ > , scope : & ' ll DIScope , span : Span ) -> Self {
57+ let pos = cx. sess ( ) . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
58+
59+ // FIXME: Rust likes to emit zero-width spans just after the end of a function. For now,
60+ // zero-width spans to the preceding column to avoid emitting a column that points past the
61+ // end of a line. E.g.,
62+ // |xyz = None
63+ // x|yz = 1
64+ // xy|z = 2
65+ //
66+ // See discussion in https://github.com/rust-lang/rust/issues/65437
67+ let col0 = pos. col . to_usize ( ) ;
68+ let col1 = if span. is_empty ( ) {
69+ NonZeroUsize :: new ( col0)
70+ } else {
71+ NonZeroUsize :: new ( col0 + 1 )
72+ } ;
73+
74+ Self :: new ( scope, pos. line , col1)
75+ }
4976}
5077
5178pub fn set_debug_location (
@@ -60,9 +87,9 @@ pub fn set_debug_location(
6087 let col_used = if bx. sess ( ) . target . target . options . is_like_msvc {
6188 UNKNOWN_COLUMN_NUMBER
6289 } else {
63- ( col + 1 ) as c_uint
90+ col. map_or ( UNKNOWN_COLUMN_NUMBER , |c| c . get ( ) as c_uint )
6491 } ;
65- debug ! ( "setting debug location to {} {}" , line, col ) ;
92+ debug ! ( "setting debug location to {} {}" , line, col_used ) ;
6693
6794 unsafe {
6895 Some ( llvm:: LLVMRustDIBuilderCreateDebugLocation (
0 commit comments