@@ -2112,3 +2112,276 @@ LL │ ┃ )>>) {}
2112
2112
. anonymized_line_numbers ( true ) ;
2113
2113
assert_data_eq ! ( renderer. render( input_new) , expected) ;
2114
2114
}
2115
+
2116
+ // This tests that an ellipsis is not inserted into Unicode text when a line
2117
+ // wasn't actually trimmed.
2118
+ //
2119
+ // This is a regression test where `...` was inserted because the code wasn't
2120
+ // properly accounting for the *rendered* length versus the length in bytes in
2121
+ // all cases.
2122
+ #[ test]
2123
+ fn unicode_cut_handling ( ) {
2124
+ let source = "version = \" 0.1.0\" \n # Ensure that the spans from toml handle utf-8 correctly\n authors = [\n { name = \" Z\u{351} \u{36b} \u{343} \u{36a} \u{302} \u{36b} \u{33d} \u{34f} \u{334} \u{319} \u{324} \u{31e} \u{349} \u{35a} \u{32f} \u{31e} \u{320} \u{34d} A\u{36b} \u{357} \u{334} \u{362} \u{335} \u{31c} \u{330} \u{354} L\u{368} \u{367} \u{369} \u{358} \u{320} G\u{311} \u{357} \u{30e} \u{305} \u{35b} \u{341} \u{334} \u{33b} \u{348} \u{34d} \u{354} \u{339} O\u{342} \u{30c} \u{30c} \u{358} \u{328} \u{335} \u{339} \u{33b} \u{31d} \u{333} \" , email = 1 }\n ]\n " ;
2125
+ let input = Level :: Error . message ( "title" ) . group (
2126
+ Group :: new ( ) . element (
2127
+ Snippet :: source ( source)
2128
+ . fold ( false )
2129
+ . annotation ( AnnotationKind :: Primary . span ( 85 ..228 ) . label ( "annotation" ) ) ,
2130
+ ) ,
2131
+ ) ;
2132
+ let expected = str![ [ r#"
2133
+ error: title
2134
+ |
2135
+ 1 | version = "0.1.0"
2136
+ 2 | # Ensure that the spans from toml handle utf-8 correctly
2137
+ 3 | authors = [
2138
+ | ___________^
2139
+ 4 | | { name = "Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯...A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘", email = 1 }
2140
+ 5 | | ]
2141
+ | |_^ annotation
2142
+ "# ] ] ;
2143
+ let renderer = Renderer :: plain ( ) ;
2144
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2145
+ }
2146
+
2147
+ #[ test]
2148
+ fn unicode_cut_handling2 ( ) {
2149
+ let source = "/*这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?" ;
2150
+ let input = Level :: Error
2151
+ . message ( "expected item, found `?`" )
2152
+ . group (
2153
+ Group :: new ( ) . element (
2154
+ Snippet :: source ( source)
2155
+ . fold ( false )
2156
+ . annotation ( AnnotationKind :: Primary . span ( 499 ..500 ) . label ( "expected item" ) )
2157
+ ) . element (
2158
+ Level :: Note . title ( "for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>" )
2159
+ )
2160
+ ) ;
2161
+
2162
+ let expected = str![ [ r#"
2163
+ error: expected item, found `?`
2164
+ |
2165
+ 1.|....
2166
+ |^ expected item
2167
+ = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
2168
+ "# ] ] ;
2169
+
2170
+ let renderer = Renderer :: plain ( ) ;
2171
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2172
+ }
2173
+
2174
+ #[ test]
2175
+ fn unicode_cut_handling3 ( ) {
2176
+ let source = "/*这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?" ;
2177
+ let input = Level :: Error
2178
+ . message ( "expected item, found `?`" )
2179
+ . group (
2180
+ Group :: new ( ) . element (
2181
+ Snippet :: source ( source)
2182
+ . fold ( false )
2183
+ . annotation ( AnnotationKind :: Primary . span ( 251 ..254 ) . label ( "expected item" ) )
2184
+ ) . element (
2185
+ Level :: Note . title ( "for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>" )
2186
+ )
2187
+ ) ;
2188
+
2189
+ let expected = str![ [ r#"
2190
+ error: expected item, found `?`
2191
+ |
2192
+ 1 | ...的。这是宽的。*/? ...
2193
+ ^ | expected item
2194
+ = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
2195
+ "# ] ] ;
2196
+
2197
+ let renderer = Renderer :: plain ( ) . term_width ( 43 ) ;
2198
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2199
+ }
2200
+
2201
+ #[ test]
2202
+ fn unicode_cut_handling4 ( ) {
2203
+ let source = "/*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/?" ;
2204
+ let input = Level :: Error
2205
+ . message ( "expected item, found `?`" )
2206
+ . group (
2207
+ Group :: new ( ) . element (
2208
+ Snippet :: source ( source)
2209
+ . fold ( false )
2210
+ . annotation ( AnnotationKind :: Primary . span ( 334 ..335 ) . label ( "expected item" ) )
2211
+ ) . element (
2212
+ Level :: Note . title ( "for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>" )
2213
+ )
2214
+ ) ;
2215
+
2216
+ let expected = str![ [ r#"
2217
+ error: expected item, found `?`
2218
+ |
2219
+ 1 | ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/?
2220
+ | ^ expected item
2221
+ = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
2222
+ "# ] ] ;
2223
+
2224
+ let renderer = Renderer :: plain ( ) ;
2225
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2226
+ }
2227
+
2228
+ #[ test]
2229
+ fn diagnostic_width ( ) {
2230
+ let source = r##"// ignore-tidy-linelength
2231
+
2232
+ fn main() {
2233
+ let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4";
2234
+ //~^ ERROR mismatched types
2235
+ }
2236
+ "## ;
2237
+ let input = Level :: Error . message ( "mismatched types" ) . id ( "E0308" ) . group (
2238
+ Group :: new ( ) . element (
2239
+ Snippet :: source ( source)
2240
+ . origin ( "$DIR/non-whitespace-trimming-unicode.rs" )
2241
+ . fold ( true )
2242
+ . annotation (
2243
+ AnnotationKind :: Primary
2244
+ . span ( 1207 ..1209 )
2245
+ . label ( "expected `()`, found integer" ) ,
2246
+ )
2247
+ . annotation (
2248
+ AnnotationKind :: Context
2249
+ . span ( 1202 ..1204 )
2250
+ . label ( "expected due to this" ) ,
2251
+ ) ,
2252
+ ) ,
2253
+ ) ;
2254
+
2255
+ let expected = str![ [ r#"
2256
+ error[E0308]: mismatched types
2257
+ --> $DIR/non-whitespace-trimming-unicode.rs:4:415
2258
+ |
2259
+ LL | ...♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂...
2260
+ | -- ^^ expected `()`, found integer
2261
+ | |
2262
+ | expected due to this
2263
+ "# ] ] ;
2264
+
2265
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( true ) ;
2266
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2267
+ }
2268
+
2269
+ #[ test]
2270
+ fn diagnostic_width2 ( ) {
2271
+ let source = r##"//@ revisions: ascii unicode
2272
+ //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
2273
+ // ignore-tidy-linelength
2274
+
2275
+ fn main() {
2276
+ let unicode_is_fun = "‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥";
2277
+ let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
2278
+ //[ascii]~^ ERROR cannot add `&str` to `&str`
2279
+ }
2280
+ "## ;
2281
+ let input = Level :: Error
2282
+ . message ( "cannot add `&str` to `&str`" )
2283
+ . id ( "E0369" )
2284
+ . group (
2285
+ Group :: new ( )
2286
+ . element (
2287
+ Snippet :: source ( source)
2288
+ . origin ( "$DIR/non-1-width-unicode-multiline-label.rs" )
2289
+ . fold ( true )
2290
+ . annotation ( AnnotationKind :: Context . span ( 970 ..984 ) . label ( "&str" ) )
2291
+ . annotation ( AnnotationKind :: Context . span ( 987 ..1001 ) . label ( "&str" ) )
2292
+ . annotation (
2293
+ AnnotationKind :: Primary
2294
+ . span ( 985 ..986 )
2295
+ . label ( "`+` cannot be used to concatenate two `&str` strings" ) ,
2296
+ ) ,
2297
+ )
2298
+ . element (
2299
+ Level :: Note
2300
+ . title ( "string concatenation requires an owned `String` on the left" ) ,
2301
+ ) ,
2302
+ )
2303
+ . group (
2304
+ Group :: new ( )
2305
+ . element ( Level :: Help . title ( "create an owned `String` from a string reference" ) )
2306
+ . element (
2307
+ Snippet :: source ( source)
2308
+ . origin ( "$DIR/non-1-width-unicode-multiline-label.rs" )
2309
+ . fold ( true )
2310
+ . patch ( Patch :: new ( 984 ..984 , ".to_owned()" ) ) ,
2311
+ ) ,
2312
+ ) ;
2313
+
2314
+ let expected = str![ [ r#"
2315
+ error[E0369]: cannot add `&str` to `&str`
2316
+ ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:7:260
2317
+ │
2318
+ LL │ …ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋…࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
2319
+ │ ┬───────────── ┯ ────────────── &str
2320
+ │ │ │
2321
+ │ │ `+` cannot be used to concatenate two `&str` strings
2322
+ │ &str
2323
+ │
2324
+ ╰ note: string concatenation requires an owned `String` on the left
2325
+ help: create an owned `String` from a string reference
2326
+ ╭╴
2327
+ LL │ let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!";
2328
+ ╰╴ +++++++++++
2329
+ "# ] ] ;
2330
+
2331
+ let renderer = Renderer :: plain ( )
2332
+ . anonymized_line_numbers ( true )
2333
+ . theme ( OutputTheme :: Unicode ) ;
2334
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2335
+ }
2336
+
2337
+ #[ test]
2338
+ fn macros_not_utf8 ( ) {
2339
+ let source = r##"//@ error-pattern: did not contain valid UTF-8
2340
+ //@ reference: input.encoding.utf8
2341
+ //@ reference: input.encoding.invalid
2342
+
2343
+ fn foo() {
2344
+ include!("not-utf8.bin");
2345
+ }
2346
+ "## ;
2347
+ let bin_source = "�|�\u{0002} !5�cc\u{0015} \u{0002} �Ӻi��WWj�ȥ�'�}�\u{0012} �J�ȉ��W�\u{001e} O�@����\u{001c} w�V���LO����\u{0014} [ \u{0003} _�'���SQ�~ذ��ų&��-\t ��lN~��!@␌ _#���kQ��h�\u{001d} �:�\u{001c} \u{0007} �" ;
2348
+ let input = Level :: Error
2349
+ . message ( "couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8" )
2350
+ . group (
2351
+ Group :: new ( ) . element (
2352
+ Snippet :: source ( source)
2353
+ . origin ( "$DIR/not-utf8.rs" )
2354
+ . fold ( true )
2355
+ . annotation ( AnnotationKind :: Primary . span ( 136 ..160 ) ) ,
2356
+ ) ,
2357
+ )
2358
+ . group (
2359
+ Group :: new ( )
2360
+ . element ( Level :: Note . title ( "byte `193` is not valid utf-8" ) )
2361
+ . element (
2362
+ Snippet :: source ( bin_source)
2363
+ . origin ( "$DIR/not-utf8.bin" )
2364
+ . fold ( true )
2365
+ . annotation ( AnnotationKind :: Primary . span ( 0 ..0 ) ) ,
2366
+ )
2367
+ . element ( Level :: Note . title ( "this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)" ) ) ,
2368
+ ) ;
2369
+
2370
+ let expected = str![ [ r#"
2371
+ error: couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8
2372
+ --> $DIR/not-utf8.rs:6:5
2373
+ |
2374
+ LL | include!("not-utf8.bin");
2375
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
2376
+ |
2377
+ note: byte `193` is not valid utf-8
2378
+ --> $DIR/not-utf8.bin:1:1
2379
+ |
2380
+ LL | �|�␂!5�cc␕␂�Ӻi��WWj�ȥ�'�}�␒�J�ȉ��W�␞O�@����␜w�V���LO����␔[ ␃_�'���SQ�~ذ��ų&��- ��lN~��!@␌ _#���kQ��h�␝�:�...
2381
+ | ^
2382
+ = note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)
2383
+ "# ] ] ;
2384
+
2385
+ let renderer = Renderer :: plain ( ) . anonymized_line_numbers ( true ) ;
2386
+ assert_data_eq ! ( renderer. render( input) , expected) ;
2387
+ }
0 commit comments