Skip to content

Commit 4aa48a3

Browse files
Map invalid Spans to DUMMY_SP during crate metadata encoding.
This mirrors what we for stabilizing the incr. comp. cache and is necessary for reproducible builds.
1 parent 78f24d8 commit 4aa48a3

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

src/librustc_metadata/decoder.rs

+11-17
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,17 @@ impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
270270

271271
impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
272272
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
273-
let lo = BytePos::decode(self)?;
274-
let hi = BytePos::decode(self)?;
273+
let tag = u8::decode(self)?;
275274

276-
if lo == BytePos(0) && hi == BytePos(0) {
277-
// Don't try to rebase DUMMY_SP. Otherwise it will look like a valid
278-
// Span again.
275+
if tag == TAG_INVALID_SPAN {
279276
return Ok(DUMMY_SP)
280277
}
281278

282-
if hi < lo {
283-
// Consistently map invalid spans to DUMMY_SP.
284-
return Ok(DUMMY_SP)
285-
}
279+
debug_assert_eq!(tag, TAG_VALID_SPAN);
280+
281+
let lo = BytePos::decode(self)?;
282+
let len = BytePos::decode(self)?;
283+
let hi = lo + len;
286284

287285
let sess = if let Some(sess) = self.sess {
288286
sess
@@ -297,9 +295,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
297295
let last_filemap = &imported_filemaps[self.last_filemap_index];
298296

299297
if lo >= last_filemap.original_start_pos &&
300-
lo <= last_filemap.original_end_pos &&
301-
hi >= last_filemap.original_start_pos &&
302-
hi <= last_filemap.original_end_pos {
298+
lo <= last_filemap.original_end_pos {
303299
last_filemap
304300
} else {
305301
let mut a = 0;
@@ -323,11 +319,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
323319
debug_assert!(lo >= filemap.original_start_pos &&
324320
lo <= filemap.original_end_pos);
325321

326-
if hi < filemap.original_start_pos || hi > filemap.original_end_pos {
327-
// `hi` points to a different FileMap than `lo` which is invalid.
328-
// Again, map invalid Spans to DUMMY_SP.
329-
return Ok(DUMMY_SP)
330-
}
322+
// Make sure we correctly filtered out invalid spans during encoding
323+
debug_assert!(hi >= filemap.original_start_pos &&
324+
hi <= filemap.original_end_pos);
331325

332326
let lo = (lo + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
333327
let hi = (hi + filemap.translated_filemap.start_pos) - filemap.original_start_pos;

src/librustc_metadata/encoder.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use syntax::ast::{self, CRATE_NODE_ID};
4141
use syntax::codemap::Spanned;
4242
use syntax::attr;
4343
use syntax::symbol::Symbol;
44-
use syntax_pos::{self, FileName};
44+
use syntax_pos::{self, FileName, FileMap, Span, DUMMY_SP};
4545

4646
use rustc::hir::{self, PatKind};
4747
use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -57,6 +57,9 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
5757
lazy_state: LazyState,
5858
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
5959
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
60+
61+
// This is used to speed up Span encoding.
62+
filemap_cache: Rc<FileMap>,
6063
}
6164

6265
macro_rules! encoder_methods {
@@ -140,6 +143,40 @@ impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
140143
}
141144
}
142145

146+
impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
147+
fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
148+
if *span == DUMMY_SP {
149+
return TAG_INVALID_SPAN.encode(self)
150+
}
151+
152+
let span = span.data();
153+
154+
if span.lo > span.hi {
155+
return TAG_INVALID_SPAN.encode(self)
156+
}
157+
158+
if !self.filemap_cache.contains(span.lo) {
159+
let codemap = self.tcx.sess.codemap();
160+
let filemap_index = codemap.lookup_filemap_idx(span.lo);
161+
self.filemap_cache = codemap.files()[filemap_index].clone();
162+
}
163+
164+
if !self.filemap_cache.contains(span.hi) {
165+
return TAG_INVALID_SPAN.encode(self)
166+
}
167+
168+
TAG_VALID_SPAN.encode(self)?;
169+
span.lo.encode(self)?;
170+
171+
// Encode length which is usually less than span.hi and profits more
172+
// from the variable-length integer encoding that we use.
173+
let len = span.hi - span.lo;
174+
len.encode(self)
175+
176+
// Don't encode the expansion context.
177+
}
178+
}
179+
143180
impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
144181
fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> {
145182
ty_codec::encode_with_shorthand(self, ty, |ecx| &mut ecx.type_shorthands)
@@ -1648,6 +1685,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
16481685
lazy_state: LazyState::NoNode,
16491686
type_shorthands: Default::default(),
16501687
predicate_shorthands: Default::default(),
1688+
filemap_cache: tcx.sess.codemap().files()[0].clone(),
16511689
};
16521690

16531691
// Encode the rustc version string in a predictable location.

src/librustc_metadata/schema.rs

+4
Original file line numberDiff line numberDiff line change
@@ -521,3 +521,7 @@ pub struct GeneratorData<'tcx> {
521521
pub layout: mir::GeneratorLayout<'tcx>,
522522
}
523523
impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
524+
525+
// Tags used for encoding Spans:
526+
pub const TAG_VALID_SPAN: u8 = 0;
527+
pub const TAG_INVALID_SPAN: u8 = 1;

0 commit comments

Comments
 (0)