diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 7f740f9c033..178e2a4d1bc 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -117,7 +117,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. - if item.vis == hir::Public || item.span == DUMMY_SP { + if item.vis == hir::Public || item.span.source_equal(&DUMMY_SP) { return; } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index ba4d1e2193e..03dc25e1b3c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -356,7 +356,7 @@ pub fn pat_is_ident(pat: P) -> bool { // since I'm using this to replace ==, it seems appropriate // to compare the span, global, etc. fields as well. pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { - (a.span == b.span) + (a.span.source_equal(&b.span)) && (a.global == b.global) && (segments_name_eq(&a.segments[..], &b.segments[..])) } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index ca01623fef9..9557310f318 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -123,7 +123,7 @@ impl Sub for CharPos { /// able to use many of the functions on spans in codemap and you cannot assume /// that the length of the span = hi - lo; there may be space in the BytePos /// range between files. -#[derive(Clone, Copy, Hash)] +#[derive(Clone, Copy, Hash, PartialEq, Eq)] pub struct Span { pub lo: BytePos, pub hi: BytePos, @@ -151,13 +151,21 @@ pub const COMMAND_LINE_SP: Span = Span { lo: BytePos(0), impl Span { /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { - if self == DUMMY_SP { other } else { self } + if self.source_equal(&DUMMY_SP) { other } else { self } } pub fn contains(self, other: Span) -> bool { self.lo <= other.lo && other.hi <= self.hi } + /// Return true if the spans are equal with regards to the source text. + /// + /// Use this instead of `==` when either span could be generated code, + /// and you only care that they point to the same bytes of source text. + pub fn source_equal(&self, other: &Span) -> bool { + self.lo == other.lo && self.hi == other.hi + } + /// Returns `Some(span)`, a union of `self` and `other`, on overlap. pub fn merge(self, other: Span) -> Option { if self.expn_id != other.expn_id { @@ -192,15 +200,6 @@ pub struct Spanned { pub span: Span, } -impl PartialEq for Span { - fn eq(&self, other: &Span) -> bool { - return (*self).lo == (*other).lo && (*self).hi == (*other).hi; - } - fn ne(&self, other: &Span) -> bool { !(*self).eq(other) } -} - -impl Eq for Span {} - impl Encodable for Span { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_struct("Span", 2, |s| { @@ -940,7 +939,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().is_empty() && sp == DUMMY_SP { + if self.files.borrow().is_empty() && sp.source_equal(&DUMMY_SP) { return "no-location".to_string(); } @@ -1307,7 +1306,7 @@ impl CodeMap { expninfo.map_or(/* hit the top level */ true, |info| { let span_comes_from_this_expansion = - info.callee.span.map_or(span == info.call_site, |mac_span| { + info.callee.span.map_or(span.source_equal(&info.call_site), |mac_span| { mac_span.contains(span) }); diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index c1239bfd66d..7e0e17423de 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -10,7 +10,7 @@ use self::Destination::*; -use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, DUMMY_SP, Pos, Span, MultiSpan}; +use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Pos, Span, MultiSpan}; use diagnostics; use errors::{Level, RenderSpan, CodeSuggestion, DiagnosticBuilder}; @@ -175,9 +175,7 @@ impl EmitterWriter { let msp = rsp.span(); let bounds = msp.to_span_bounds(); - // We cannot check equality directly with COMMAND_LINE_SP - // since PartialEq is manually implemented to ignore the ExpnId - let ss = if bounds.expn_id == COMMAND_LINE_EXPN { + let ss = if bounds == COMMAND_LINE_SP { "".to_string() } else if let EndSpan(_) = *rsp { let span_end = Span { lo: bounds.hi, hi: bounds.hi, expn_id: bounds.expn_id}; @@ -606,7 +604,7 @@ impl EmitterWriter { }; // Don't print recursive invocations - if span != last_span { + if !span.source_equal(&last_span) { let mut diag_string = macro_decl_name; if let Some(def_site_span) = def_site_span { diag_string.push_str(&format!(" (defined in {})",