@@ -239,18 +239,66 @@ impl Ord for Span {
239239 }
240240}
241241
242+ #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq , PartialOrd , Ord , RustcEncodable , RustcDecodable ) ]
243+ pub enum SpanId {
244+ Span ( Span ) ,
245+ DefId ( DefId ) ,
246+ }
247+
248+ impl Default for SpanId {
249+ fn default ( ) -> SpanId {
250+ SpanId :: Span ( DUMMY_SP )
251+ }
252+ }
253+
254+ impl From < Span > for SpanId {
255+ fn from ( span : Span ) -> SpanId {
256+ SpanId :: Span ( span)
257+ }
258+ }
259+
260+ impl SpanId {
261+ pub fn is_dummy ( self ) -> bool {
262+ match self {
263+ SpanId :: Span ( sp) => sp. is_dummy ( ) ,
264+ _ => false ,
265+ }
266+ }
267+ }
268+
269+ pub trait SpanLike :
270+ Copy + Clone + std:: fmt:: Debug + Hash + PartialEq + Eq + PartialOrd + Ord + Default
271+ {
272+ fn is_dummy ( & self ) -> bool ;
273+ }
274+
275+ impl SpanLike for Span {
276+ fn is_dummy ( & self ) -> bool {
277+ Span :: is_dummy ( * self )
278+ }
279+ }
280+
281+ impl SpanLike for SpanId {
282+ fn is_dummy ( & self ) -> bool {
283+ SpanId :: is_dummy ( * self )
284+ }
285+ }
286+
242287/// A collection of spans. Spans have two orthogonal attributes:
243288///
244289/// - They can be *primary spans*. In this case they are the locus of
245290/// the error, and would be rendered with `^^^`.
246291/// - They can have a *label*. In this case, the label is written next
247292/// to the mark in the snippet when we render.
248293#[ derive( Clone , Debug , Hash , PartialEq , Eq , RustcEncodable , RustcDecodable ) ]
249- pub struct MultiSpan {
294+ pub struct Multi < Span > {
250295 primary_spans : Vec < Span > ,
251296 span_labels : Vec < ( Span , String ) > ,
252297}
253298
299+ pub type MultiSpan = Multi < Span > ;
300+ pub type MultiSpanId = Multi < SpanId > ;
301+
254302impl Span {
255303 #[ inline]
256304 pub fn lo ( self ) -> BytePos {
@@ -592,7 +640,7 @@ impl Span {
592640}
593641
594642#[ derive( Clone , Debug ) ]
595- pub struct SpanLabel {
643+ pub struct Labelled < Span > {
596644 /// The span we are going to include in the final snippet.
597645 pub span : Span ,
598646
@@ -604,6 +652,9 @@ pub struct SpanLabel {
604652 pub label : Option < String > ,
605653}
606654
655+ pub type SpanLabel = Labelled < Span > ;
656+ pub type SpanIdLabel = Labelled < SpanId > ;
657+
607658impl Default for Span {
608659 fn default ( ) -> Self {
609660 DUMMY_SP
@@ -651,19 +702,19 @@ impl fmt::Debug for SpanData {
651702 }
652703}
653704
654- impl MultiSpan {
705+ impl < Span : SpanLike > Multi < Span > {
655706 #[ inline]
656- pub fn new ( ) -> MultiSpan {
657- MultiSpan { primary_spans : vec ! [ ] , span_labels : vec ! [ ] }
707+ pub fn new ( ) -> Self {
708+ Self { primary_spans : vec ! [ ] , span_labels : vec ! [ ] }
658709 }
659710
660- pub fn from_span ( primary_span : Span ) -> MultiSpan {
661- MultiSpan { primary_spans : vec ! [ primary_span] , span_labels : vec ! [ ] }
711+ pub fn from_span ( primary_span : impl Into < Span > ) -> Self {
712+ Self { primary_spans : vec ! [ primary_span. into ( ) ] , span_labels : vec ! [ ] }
662713 }
663714
664- pub fn from_spans ( mut vec : Vec < Span > ) -> MultiSpan {
715+ pub fn from_spans ( mut vec : Vec < Span > ) -> Self {
665716 vec. sort ( ) ;
666- MultiSpan { primary_spans : vec, span_labels : vec ! [ ] }
717+ Self { primary_spans : vec, span_labels : vec ! [ ] }
667718 }
668719
669720 pub fn push_span_label ( & mut self , span : Span , label : String ) {
@@ -720,22 +771,23 @@ impl MultiSpan {
720771 /// span `P`, if there is at least one label with span `P`, we return
721772 /// those labels (marked as primary). But otherwise we return
722773 /// `SpanLabel` instances with empty labels.
723- pub fn span_labels ( & self ) -> Vec < SpanLabel > {
724- let is_primary = |span| self . primary_spans . contains ( & span) ;
774+ pub fn span_labels ( & self ) -> Vec < Labelled < Span > > {
775+ let is_primary = |span| self . primary_spans . contains ( span) ;
725776
726777 let mut span_labels = self
727778 . span_labels
728779 . iter ( )
729- . map ( |& ( span, ref label) | SpanLabel {
730- span,
780+ . map ( |( span, label) | Labelled {
781+ span : span . clone ( ) ,
731782 is_primary : is_primary ( span) ,
732783 label : Some ( label. clone ( ) ) ,
733784 } )
734785 . collect :: < Vec < _ > > ( ) ;
735786
736- for & span in & self . primary_spans {
737- if !span_labels. iter ( ) . any ( |sl| sl. span == span) {
738- span_labels. push ( SpanLabel { span, is_primary : true , label : None } ) ;
787+ for span in & self . primary_spans {
788+ if !span_labels. iter ( ) . any ( |sl| & sl. span == span) {
789+ let span = span. clone ( ) ;
790+ span_labels. push ( Labelled { span, is_primary : true , label : None } ) ;
739791 }
740792 }
741793
@@ -748,15 +800,42 @@ impl MultiSpan {
748800 }
749801}
750802
751- impl From < Span > for MultiSpan {
752- fn from ( span : Span ) -> MultiSpan {
753- MultiSpan :: from_span ( span)
803+ impl < S > Multi < S > {
804+ pub fn map_span < S2 > ( & self , f : impl Fn ( & S ) -> S2 ) -> Multi < S2 > {
805+ Multi {
806+ primary_spans : self . primary_spans . iter ( ) . map ( & f) . collect ( ) ,
807+ span_labels : self . span_labels . iter ( ) . map ( |( s, l) | ( f ( s) , l. clone ( ) ) ) . collect ( ) ,
808+ }
809+ }
810+ }
811+
812+ impl < Span : SpanLike > From < Span > for Multi < Span > {
813+ fn from ( span : Span ) -> Multi < Span > {
814+ Multi :: from_span ( span)
815+ }
816+ }
817+
818+ impl From < Span > for MultiSpanId {
819+ fn from ( span : Span ) -> MultiSpanId {
820+ Multi :: from_span ( span)
821+ }
822+ }
823+
824+ impl From < MultiSpan > for MultiSpanId {
825+ fn from ( ms : MultiSpan ) -> MultiSpanId {
826+ ms. map_span ( |s| SpanId :: Span ( * s) )
827+ }
828+ }
829+
830+ impl < Span : SpanLike > From < Vec < Span > > for Multi < Span > {
831+ fn from ( spans : Vec < Span > ) -> Multi < Span > {
832+ Multi :: from_spans ( spans)
754833 }
755834}
756835
757- impl From < Vec < Span > > for MultiSpan {
758- fn from ( spans : Vec < Span > ) -> MultiSpan {
759- MultiSpan :: from_spans ( spans)
836+ impl From < Vec < Span > > for MultiSpanId {
837+ fn from ( spans : Vec < Span > ) -> MultiSpanId {
838+ Multi :: from_spans ( spans) . into ( )
760839 }
761840}
762841
0 commit comments