2121#![ feature( core_io_borrowed_buf) ]
2222#![ feature( map_try_insert) ]
2323#![ feature( negative_impls) ]
24+ #![ feature( normalize_lexically) ]
2425#![ feature( read_buf) ]
2526#![ feature( rustc_attrs) ]
2627// tidy-alphabetical-end
@@ -496,6 +497,15 @@ impl RealFileName {
496497 . file_name ( )
497498 . map_or_else ( || "" . into ( ) , |f| f. to_string_lossy ( ) ) ,
498499 FileNameDisplayPreference :: Scope ( scope) => self . path ( scope) . to_string_lossy ( ) ,
500+ FileNameDisplayPreference :: Diagnostics ( scope) => {
501+ let path = self . path ( scope) ;
502+ match path. normalize_lexically ( ) {
503+ Ok ( normalized) => {
504+ Cow :: Owned ( normalized. into_os_string ( ) . to_string_lossy ( ) . into_owned ( ) )
505+ }
506+ Err ( _) => path. to_string_lossy ( ) ,
507+ }
508+ }
499509 }
500510 }
501511}
@@ -533,15 +543,23 @@ enum FileNameDisplayPreference {
533543 Local ,
534544 Short ,
535545 Scope ( RemapPathScopeComponents ) ,
546+ Diagnostics ( RemapPathScopeComponents ) ,
547+ }
548+
549+ impl < ' a > FileNameDisplay < ' a > {
550+ pub fn to_string_lossy ( & self ) -> Cow < ' a , str > {
551+ match self . inner {
552+ FileName :: Real ( inner) => inner. to_string_lossy ( self . display_pref ) ,
553+ _ => Cow :: from ( self . to_string ( ) ) ,
554+ }
555+ }
536556}
537557
538558impl fmt:: Display for FileNameDisplay < ' _ > {
539559 fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
540560 use FileName :: * ;
541561 match * self . inner {
542- Real ( ref name) => {
543- write ! ( fmt, "{}" , name. to_string_lossy( self . display_pref) )
544- }
562+ Real ( ref name) => write ! ( fmt, "{}" , name. to_string_lossy( self . display_pref) ) ,
545563 CfgSpec ( _) => write ! ( fmt, "<cfgspec>" ) ,
546564 MacroExpansion ( _) => write ! ( fmt, "<macro expansion>" ) ,
547565 Anon ( _) => write ! ( fmt, "<anon>" ) ,
@@ -554,15 +572,6 @@ impl fmt::Display for FileNameDisplay<'_> {
554572 }
555573}
556574
557- impl < ' a > FileNameDisplay < ' a > {
558- pub fn to_string_lossy ( & self ) -> Cow < ' a , str > {
559- match self . inner {
560- FileName :: Real ( inner) => inner. to_string_lossy ( self . display_pref ) ,
561- _ => Cow :: from ( self . to_string ( ) ) ,
562- }
563- }
564- }
565-
566575impl FileName {
567576 pub fn is_real ( & self ) -> bool {
568577 use FileName :: * ;
@@ -609,6 +618,12 @@ impl FileName {
609618 FileNameDisplay { inner : self , display_pref : FileNameDisplayPreference :: Scope ( scope) }
610619 }
611620
621+ /// Like `display`, but with `.` and `..` resolved lexically. See #51349.
622+ #[ inline]
623+ pub fn display_normalized ( & self , scope : RemapPathScopeComponents ) -> FileNameDisplay < ' _ > {
624+ FileNameDisplay { inner : self , display_pref : FileNameDisplayPreference :: Diagnostics ( scope) }
625+ }
626+
612627 pub fn macro_expansion_source_code ( src : & str ) -> FileName {
613628 let mut hasher = StableHasher :: new ( ) ;
614629 src. hash ( & mut hasher) ;
0 commit comments