@@ -78,17 +78,65 @@ fn emit_diagnostic(&option::t[span] sp, &str msg, &str kind, u8 color,
78
78
io:: stdout ( ) . write_str ( #fmt ( " %s\n " , msg) ) ;
79
79
alt ( maybe_lines) {
80
80
case ( some ( ?lines) ) {
81
+ // FIXME: reading in the entire file is the worst possible way to
82
+ // get access to the necessary lines.
81
83
auto rdr = io:: file_reader ( lines. name ) ;
82
84
auto file = str:: unsafe_from_bytes ( rdr. read_whole_stream ( ) ) ;
83
85
auto fm = codemap:: get_filemap ( cm, lines. name ) ;
84
- for ( uint line in lines. lines) {
86
+
87
+ // arbitrarily only print up to six lines of the error
88
+ auto max_lines = 6 u;
89
+ auto elided = false ;
90
+ auto display_lines = lines. lines ;
91
+ if ( vec:: len ( display_lines) > max_lines) {
92
+ display_lines = vec:: slice ( display_lines, 0 u, max_lines) ;
93
+ elided = true ;
94
+ }
95
+ // Print the offending lines
96
+ for ( uint line in display_lines) {
85
97
io:: stdout ( ) . write_str ( #fmt ( "%s:%u " , fm. name , line + 1 u) ) ;
86
98
auto s = codemap:: get_line ( fm, line as int , file) ;
87
99
if ( !str:: ends_with ( s, "\n " ) ) {
88
100
s += "\n " ;
89
101
}
90
102
io:: stdout ( ) . write_str ( s) ;
91
103
}
104
+ if ( elided) {
105
+ auto last_line = display_lines. ( vec:: len ( display_lines) - 1 u) ;
106
+ auto s = #fmt ( "%s:%u " , fm. name , last_line + 1 u) ;
107
+ auto indent = str:: char_len ( s) ;
108
+ auto out = "" ;
109
+ while ( indent > 0 u) { out += " " ; indent -= 1 u; }
110
+ out += "...\n " ;
111
+ io:: stdout ( ) . write_str ( out) ;
112
+ }
113
+
114
+ // If there's one line at fault we can easily point to the problem
115
+ if ( vec:: len ( lines. lines ) == 1 u) {
116
+ auto lo = codemap:: lookup_pos ( cm, option:: get ( sp) . lo ) ;
117
+ auto digits = 0 u;
118
+ auto num = lines. lines . ( 0 ) / 10 u;
119
+
120
+ // how many digits must be indent past?
121
+ while ( num > 0 u) { num /= 10 u; digits += 1 u; }
122
+
123
+ // indent past |name:## | and the 0-offset column location
124
+ auto left = str:: char_len ( fm. name ) + digits + lo. col + 3 u;
125
+ auto s = "" ;
126
+ while ( left > 0 u) { str:: push_char ( s, ' ' ) ; left -= 1 u; }
127
+
128
+ s += "^" ;
129
+ auto hi = codemap:: lookup_pos ( cm, option:: get ( sp) . hi ) ;
130
+ if ( hi. col != lo. col ) {
131
+ // the ^ already takes up one space
132
+ auto width = hi. col - lo. col - 1 u;
133
+ while ( width > 0 u) {
134
+ str:: push_char ( s, '~' ) ;
135
+ width -= 1 u;
136
+ }
137
+ }
138
+ io:: stdout ( ) . write_str ( s + "\n " ) ;
139
+ }
92
140
}
93
141
case ( _) { }
94
142
}
0 commit comments