]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/decoder.rs
No need to have tcx::opt_def_path() now that we store all DefPaths
[rust.git] / src / librustc_metadata / decoder.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Decoding metadata from a single crate's metadata
12
13 use astencode::decode_inlined_item;
14 use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
15 use schema::*;
16
17 use rustc::hir::map::{DefKey, DefPath, DefPathData};
18 use rustc::hir;
19 use rustc::hir::intravisit::IdRange;
20
21 use rustc::middle::cstore::{InlinedItem, LinkagePreference};
22 use rustc::hir::def::{self, Def, CtorKind};
23 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
24 use rustc::middle::lang_items;
25 use rustc::session::Session;
26 use rustc::ty::{self, Ty, TyCtxt};
27 use rustc::ty::subst::Substs;
28
29 use rustc_const_math::ConstInt;
30
31 use rustc::mir::Mir;
32
33 use std::borrow::Cow;
34 use std::cell::Ref;
35 use std::io;
36 use std::mem;
37 use std::str;
38 use std::u32;
39
40 use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
41 use syntax::attr;
42 use syntax::ast::{self, NodeId};
43 use syntax::codemap;
44 use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP};
45
46 pub struct DecodeContext<'a, 'tcx: 'a> {
47     opaque: opaque::Decoder<'a>,
48     cdata: Option<&'a CrateMetadata>,
49     sess: Option<&'a Session>,
50     tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
51     from_id_range: IdRange,
52     to_id_range: IdRange,
53
54     // Cache the last used filemap for translating spans as an optimization.
55     last_filemap_index: usize,
56
57     lazy_state: LazyState,
58 }
59
60 /// Abstract over the various ways one can create metadata decoders.
61 pub trait Metadata<'a, 'tcx>: Copy {
62     fn raw_bytes(self) -> &'a [u8];
63     fn cdata(self) -> Option<&'a CrateMetadata> { None }
64     fn sess(self) -> Option<&'a Session> { None }
65     fn tcx(self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> { None }
66
67     fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
68         let id_range = IdRange {
69             min: NodeId::from_u32(u32::MIN),
70             max: NodeId::from_u32(u32::MAX),
71         };
72         let tcx = self.tcx();
73         DecodeContext {
74             opaque: opaque::Decoder::new(self.raw_bytes(), pos),
75             cdata: self.cdata(),
76             sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
77             tcx: tcx,
78             from_id_range: id_range,
79             to_id_range: id_range,
80             last_filemap_index: 0,
81             lazy_state: LazyState::NoNode,
82         }
83     }
84 }
85
86 impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
87     fn raw_bytes(self) -> &'a [u8] {
88         match *self {
89             MetadataBlob::Inflated(ref vec) => vec,
90             MetadataBlob::Archive(ref ar) => ar.as_slice(),
91             MetadataBlob::Raw(ref vec) => vec,
92         }
93     }
94 }
95
96 impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata {
97     fn raw_bytes(self) -> &'a [u8] {
98         self.blob.raw_bytes()
99     }
100     fn cdata(self) -> Option<&'a CrateMetadata> {
101         Some(self)
102     }
103 }
104
105 impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, &'a Session) {
106     fn raw_bytes(self) -> &'a [u8] {
107         self.0.raw_bytes()
108     }
109     fn cdata(self) -> Option<&'a CrateMetadata> {
110         Some(self.0)
111     }
112     fn sess(self) -> Option<&'a Session> {
113         Some(&self.1)
114     }
115 }
116
117 impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'a, 'tcx, 'tcx>) {
118     fn raw_bytes(self) -> &'a [u8] {
119         self.0.raw_bytes()
120     }
121     fn cdata(self) -> Option<&'a CrateMetadata> {
122         Some(self.0)
123     }
124     fn tcx(self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
125         Some(self.1)
126     }
127 }
128
129 // HACK(eddyb) Only used by astencode to customize the from/to IdRange's.
130 impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'a, 'tcx, 'tcx>, [IdRange; 2]) {
131     fn raw_bytes(self) -> &'a [u8] {
132         self.0.raw_bytes()
133     }
134     fn cdata(self) -> Option<&'a CrateMetadata> {
135         Some(self.0)
136     }
137     fn tcx(self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
138         Some(self.1)
139     }
140
141     fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
142         let mut dcx = (self.0, self.1).decoder(pos);
143         dcx.from_id_range = self.2[0];
144         dcx.to_id_range = self.2[1];
145         dcx
146     }
147 }
148
149 impl<'a, 'tcx: 'a, T: Decodable> Lazy<T> {
150     pub fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> T {
151         let mut dcx = meta.decoder(self.position);
152         dcx.lazy_state = LazyState::NodeStart(self.position);
153         T::decode(&mut dcx).unwrap()
154     }
155 }
156
157 impl<'a, 'tcx: 'a, T: Decodable> LazySeq<T> {
158     pub fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> impl Iterator<Item = T> + 'a {
159         let mut dcx = meta.decoder(self.position);
160         dcx.lazy_state = LazyState::NodeStart(self.position);
161         (0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
162     }
163 }
164
165 impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
166     pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
167         self.tcx.expect("missing TyCtxt in DecodeContext")
168     }
169
170     pub fn cdata(&self) -> &'a CrateMetadata {
171         self.cdata.expect("missing CrateMetadata in DecodeContext")
172     }
173
174     fn with_position<F: FnOnce(&mut Self) -> R, R>(&mut self, pos: usize, f: F) -> R {
175         let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
176         let old_opaque = mem::replace(&mut self.opaque, new_opaque);
177         let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode);
178         let r = f(self);
179         self.opaque = old_opaque;
180         self.lazy_state = old_state;
181         r
182     }
183
184     fn read_lazy_distance(&mut self, min_size: usize) -> Result<usize, <Self as Decoder>::Error> {
185         let distance = self.read_usize()?;
186         let position = match self.lazy_state {
187             LazyState::NoNode => bug!("read_lazy_distance: outside of a metadata node"),
188             LazyState::NodeStart(start) => {
189                 assert!(distance + min_size <= start);
190                 start - distance - min_size
191             }
192             LazyState::Previous(last_min_end) => last_min_end + distance,
193         };
194         self.lazy_state = LazyState::Previous(position + min_size);
195         Ok(position)
196     }
197 }
198
199 macro_rules! decoder_methods {
200     ($($name:ident -> $ty:ty;)*) => {
201         $(fn $name(&mut self) -> Result<$ty, Self::Error> {
202             self.opaque.$name()
203         })*
204     }
205 }
206
207 impl<'doc, 'tcx> Decoder for DecodeContext<'doc, 'tcx> {
208     type Error = <opaque::Decoder<'doc> as Decoder>::Error;
209
210     decoder_methods! {
211         read_nil -> ();
212
213         read_u64 -> u64;
214         read_u32 -> u32;
215         read_u16 -> u16;
216         read_u8 -> u8;
217         read_usize -> usize;
218
219         read_i64 -> i64;
220         read_i32 -> i32;
221         read_i16 -> i16;
222         read_i8 -> i8;
223         read_isize -> isize;
224
225         read_bool -> bool;
226         read_f64 -> f64;
227         read_f32 -> f32;
228         read_char -> char;
229         read_str -> Cow<str>;
230     }
231
232     fn error(&mut self, err: &str) -> Self::Error {
233         self.opaque.error(err)
234     }
235 }
236
237 impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
238     fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
239         Ok(Lazy::with_position(self.read_lazy_distance(Lazy::<T>::min_size())?))
240     }
241 }
242
243 impl<'a, 'tcx, T> SpecializedDecoder<LazySeq<T>> for DecodeContext<'a, 'tcx> {
244     fn specialized_decode(&mut self) -> Result<LazySeq<T>, Self::Error> {
245         let len = self.read_usize()?;
246         let position = if len == 0 {
247             0
248         } else {
249             self.read_lazy_distance(LazySeq::<T>::min_size(len))?
250         };
251         Ok(LazySeq::with_position_and_length(position, len))
252     }
253 }
254
255 impl<'a, 'tcx> SpecializedDecoder<NodeId> for DecodeContext<'a, 'tcx> {
256     fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
257         let id = u32::decode(self)?;
258
259         // from_id_range should be non-empty
260         assert!(!self.from_id_range.empty());
261         // Make sure that translating the NodeId will actually yield a
262         // meaningful result
263         if !self.from_id_range.contains(NodeId::from_u32(id)) {
264             bug!("NodeId::decode: {} out of DecodeContext range ({:?} -> {:?})",
265                  id,
266                  self.from_id_range,
267                  self.to_id_range);
268         }
269
270         // Use wrapping arithmetic because otherwise it introduces control flow.
271         // Maybe we should just have the control flow? -- aatch
272         Ok(NodeId::from_u32(id.wrapping_sub(self.from_id_range.min.as_u32())
273             .wrapping_add(self.to_id_range.min.as_u32())))
274     }
275 }
276
277 impl<'a, 'tcx> SpecializedDecoder<CrateNum> for DecodeContext<'a, 'tcx> {
278     fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> {
279         let cnum = CrateNum::from_u32(u32::decode(self)?);
280         if cnum == LOCAL_CRATE {
281             Ok(self.cdata().cnum)
282         } else {
283             Ok(self.cdata().cnum_map.borrow()[cnum])
284         }
285     }
286 }
287
288 impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
289     fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
290         let lo = BytePos::decode(self)?;
291         let hi = BytePos::decode(self)?;
292
293         let sess = if let Some(sess) = self.sess {
294             sess
295         } else {
296             return Ok(syntax_pos::mk_sp(lo, hi));
297         };
298
299         let (lo, hi) = if lo > hi {
300             // Currently macro expansion sometimes produces invalid Span values
301             // where lo > hi. In order not to crash the compiler when trying to
302             // translate these values, let's transform them into something we
303             // can handle (and which will produce useful debug locations at
304             // least some of the time).
305             // This workaround is only necessary as long as macro expansion is
306             // not fixed. FIXME(#23480)
307             (lo, lo)
308         } else {
309             (lo, hi)
310         };
311
312         let imported_filemaps = self.cdata().imported_filemaps(&sess.codemap());
313         let filemap = {
314             // Optimize for the case that most spans within a translated item
315             // originate from the same filemap.
316             let last_filemap = &imported_filemaps[self.last_filemap_index];
317
318             if lo >= last_filemap.original_start_pos && lo <= last_filemap.original_end_pos &&
319                hi >= last_filemap.original_start_pos &&
320                hi <= last_filemap.original_end_pos {
321                 last_filemap
322             } else {
323                 let mut a = 0;
324                 let mut b = imported_filemaps.len();
325
326                 while b - a > 1 {
327                     let m = (a + b) / 2;
328                     if imported_filemaps[m].original_start_pos > lo {
329                         b = m;
330                     } else {
331                         a = m;
332                     }
333                 }
334
335                 self.last_filemap_index = a;
336                 &imported_filemaps[a]
337             }
338         };
339
340         let lo = (lo - filemap.original_start_pos) + filemap.translated_filemap.start_pos;
341         let hi = (hi - filemap.original_start_pos) + filemap.translated_filemap.start_pos;
342
343         Ok(syntax_pos::mk_sp(lo, hi))
344     }
345 }
346
347 // FIXME(#36588) These impls are horribly unsound as they allow
348 // the caller to pick any lifetime for 'tcx, including 'static,
349 // by using the unspecialized proxies to them.
350
351 impl<'a, 'tcx> SpecializedDecoder<Ty<'tcx>> for DecodeContext<'a, 'tcx> {
352     fn specialized_decode(&mut self) -> Result<Ty<'tcx>, Self::Error> {
353         let tcx = self.tcx();
354
355         // Handle shorthands first, if we have an usize > 0x80.
356         if self.opaque.data[self.opaque.position()] & 0x80 != 0 {
357             let pos = self.read_usize()?;
358             assert!(pos >= SHORTHAND_OFFSET);
359             let key = ty::CReaderCacheKey {
360                 cnum: self.cdata().cnum,
361                 pos: pos - SHORTHAND_OFFSET,
362             };
363             if let Some(ty) = tcx.rcache.borrow().get(&key).cloned() {
364                 return Ok(ty);
365             }
366
367             let ty = self.with_position(key.pos, Ty::decode)?;
368             tcx.rcache.borrow_mut().insert(key, ty);
369             Ok(ty)
370         } else {
371             Ok(tcx.mk_ty(ty::TypeVariants::decode(self)?))
372         }
373     }
374 }
375
376
377 impl<'a, 'tcx> SpecializedDecoder<ty::GenericPredicates<'tcx>> for DecodeContext<'a, 'tcx> {
378     fn specialized_decode(&mut self) -> Result<ty::GenericPredicates<'tcx>, Self::Error> {
379         Ok(ty::GenericPredicates {
380             parent: Decodable::decode(self)?,
381             predicates: (0..self.read_usize()?).map(|_| {
382                     // Handle shorthands first, if we have an usize > 0x80.
383                     if self.opaque.data[self.opaque.position()] & 0x80 != 0 {
384                         let pos = self.read_usize()?;
385                         assert!(pos >= SHORTHAND_OFFSET);
386                         let pos = pos - SHORTHAND_OFFSET;
387
388                         self.with_position(pos, ty::Predicate::decode)
389                     } else {
390                         ty::Predicate::decode(self)
391                     }
392                 })
393                 .collect::<Result<Vec<_>, _>>()?,
394         })
395     }
396 }
397
398 impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> {
399     fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
400         Ok(self.tcx().mk_substs((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
401     }
402 }
403
404 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx> {
405     fn specialized_decode(&mut self) -> Result<&'tcx ty::Region, Self::Error> {
406         Ok(self.tcx().mk_region(Decodable::decode(self)?))
407     }
408 }
409
410 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
411     fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
412         Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
413     }
414 }
415
416 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::BareFnTy<'tcx>> for DecodeContext<'a, 'tcx> {
417     fn specialized_decode(&mut self) -> Result<&'tcx ty::BareFnTy<'tcx>, Self::Error> {
418         Ok(self.tcx().mk_bare_fn(Decodable::decode(self)?))
419     }
420 }
421
422 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::AdtDef> for DecodeContext<'a, 'tcx> {
423     fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
424         let def_id = DefId::decode(self)?;
425         Ok(self.tcx().lookup_adt_def(def_id))
426     }
427 }
428
429 impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>
430     for DecodeContext<'a, 'tcx> {
431     fn specialized_decode(&mut self)
432         -> Result<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>, Self::Error> {
433         Ok(self.tcx().mk_existential_predicates((0..self.read_usize()?)
434                                                 .map(|_| Decodable::decode(self)))?)
435     }
436 }
437
438 impl<'a, 'tcx> MetadataBlob {
439     pub fn is_compatible(&self) -> bool {
440         self.raw_bytes().starts_with(METADATA_HEADER)
441     }
442
443     pub fn get_rustc_version(&self) -> String {
444         Lazy::with_position(METADATA_HEADER.len() + 4).decode(self)
445     }
446
447     pub fn get_root(&self) -> CrateRoot {
448         let slice = self.raw_bytes();
449         let offset = METADATA_HEADER.len();
450         let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) |
451                    ((slice[offset + 2] as u32) << 8) |
452                    ((slice[offset + 3] as u32) << 0)) as usize;
453         Lazy::with_position(pos).decode(self)
454     }
455
456     pub fn list_crate_metadata(&self, out: &mut io::Write) -> io::Result<()> {
457         write!(out, "=External Dependencies=\n")?;
458         let root = self.get_root();
459         for (i, dep) in root.crate_deps.decode(self).enumerate() {
460             write!(out, "{} {}-{}\n", i + 1, dep.name, dep.hash)?;
461         }
462         write!(out, "\n")?;
463         Ok(())
464     }
465 }
466
467 impl<'tcx> EntryKind<'tcx> {
468     fn to_def(&self, did: DefId) -> Option<Def> {
469         Some(match *self {
470             EntryKind::Const => Def::Const(did),
471             EntryKind::AssociatedConst(_) => Def::AssociatedConst(did),
472             EntryKind::ImmStatic |
473             EntryKind::ForeignImmStatic => Def::Static(did, false),
474             EntryKind::MutStatic |
475             EntryKind::ForeignMutStatic => Def::Static(did, true),
476             EntryKind::Struct(_) => Def::Struct(did),
477             EntryKind::Union(_) => Def::Union(did),
478             EntryKind::Fn(_) |
479             EntryKind::ForeignFn(_) => Def::Fn(did),
480             EntryKind::Method(_) => Def::Method(did),
481             EntryKind::Type => Def::TyAlias(did),
482             EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
483             EntryKind::Mod(_) => Def::Mod(did),
484             EntryKind::Variant(_) => Def::Variant(did),
485             EntryKind::Trait(_) => Def::Trait(did),
486             EntryKind::Enum => Def::Enum(did),
487             EntryKind::MacroDef(_) => Def::Macro(did),
488
489             EntryKind::ForeignMod |
490             EntryKind::Impl(_) |
491             EntryKind::DefaultImpl(_) |
492             EntryKind::Field |
493             EntryKind::Closure(_) => return None,
494         })
495     }
496     fn is_const_fn(&self, meta: &CrateMetadata) -> bool {
497         let constness = match *self {
498             EntryKind::Method(data) => data.decode(meta).fn_data.constness,
499             EntryKind::Fn(data) => data.decode(meta).constness,
500             _ => hir::Constness::NotConst,
501         };
502         constness == hir::Constness::Const
503     }
504 }
505
506 impl<'a, 'tcx> CrateMetadata {
507     fn is_proc_macro(&self, id: DefIndex) -> bool {
508         self.proc_macros.is_some() && id != CRATE_DEF_INDEX
509     }
510
511     fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
512         assert!(!self.is_proc_macro(item_id));
513         self.root.index.lookup(self.blob.raw_bytes(), item_id)
514     }
515
516     fn entry(&self, item_id: DefIndex) -> Entry<'tcx> {
517         match self.maybe_entry(item_id) {
518             None => {
519                 bug!("entry: id not found: {:?} in crate {:?} with number {}",
520                      item_id,
521                      self.name,
522                      self.cnum)
523             }
524             Some(d) => d.decode(self),
525         }
526     }
527
528     fn local_def_id(&self, index: DefIndex) -> DefId {
529         DefId {
530             krate: self.cnum,
531             index: index,
532         }
533     }
534
535     fn item_name(&self, item_index: DefIndex) -> ast::Name {
536         self.def_key(item_index)
537             .disambiguated_data
538             .data
539             .get_opt_name()
540             .expect("no name in item_name")
541     }
542
543     pub fn get_def(&self, index: DefIndex) -> Option<Def> {
544         match self.is_proc_macro(index) {
545             true => Some(Def::Macro(self.local_def_id(index))),
546             false => self.entry(index).kind.to_def(self.local_def_id(index)),
547         }
548     }
549
550     pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
551         match self.is_proc_macro(index) {
552             true => DUMMY_SP,
553             false => self.entry(index).span.decode((self, sess)),
554         }
555     }
556
557     pub fn get_trait_def(&self,
558                          item_id: DefIndex,
559                          tcx: TyCtxt<'a, 'tcx, 'tcx>)
560                          -> ty::TraitDef {
561         let data = match self.entry(item_id).kind {
562             EntryKind::Trait(data) => data.decode(self),
563             _ => bug!(),
564         };
565
566         ty::TraitDef::new(self.local_def_id(item_id),
567                           data.unsafety,
568                           data.paren_sugar,
569                           self.def_path(item_id).deterministic_hash(tcx))
570     }
571
572     fn get_variant(&self,
573                    item: &Entry<'tcx>,
574                    index: DefIndex)
575                    -> (ty::VariantDef, Option<DefIndex>) {
576         let data = match item.kind {
577             EntryKind::Variant(data) |
578             EntryKind::Struct(data) |
579             EntryKind::Union(data) => data.decode(self),
580             _ => bug!(),
581         };
582
583         (ty::VariantDef {
584             did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
585             name: self.item_name(index),
586             fields: item.children.decode(self).map(|index| {
587                 let f = self.entry(index);
588                 ty::FieldDef {
589                     did: self.local_def_id(index),
590                     name: self.item_name(index),
591                     vis: f.visibility
592                 }
593             }).collect(),
594             disr_val: ConstInt::Infer(data.disr),
595             ctor_kind: data.ctor_kind,
596         }, data.struct_ctor)
597     }
598
599     pub fn get_adt_def(&self,
600                        item_id: DefIndex,
601                        tcx: TyCtxt<'a, 'tcx, 'tcx>)
602                        -> &'tcx ty::AdtDef {
603         let item = self.entry(item_id);
604         let did = self.local_def_id(item_id);
605         let mut ctor_index = None;
606         let variants = if let EntryKind::Enum = item.kind {
607             item.children
608                 .decode(self)
609                 .map(|index| {
610                     let (variant, struct_ctor) = self.get_variant(&self.entry(index), index);
611                     assert_eq!(struct_ctor, None);
612                     variant
613                 })
614                 .collect()
615         } else {
616             let (variant, struct_ctor) = self.get_variant(&item, item_id);
617             ctor_index = struct_ctor;
618             vec![variant]
619         };
620         let kind = match item.kind {
621             EntryKind::Enum => ty::AdtKind::Enum,
622             EntryKind::Struct(_) => ty::AdtKind::Struct,
623             EntryKind::Union(_) => ty::AdtKind::Union,
624             _ => bug!("get_adt_def called on a non-ADT {:?}", did),
625         };
626
627         let adt = tcx.alloc_adt_def(did, kind, variants);
628         if let Some(ctor_index) = ctor_index {
629             // Make adt definition available through constructor id as well.
630             tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);
631         }
632
633         adt
634     }
635
636     pub fn get_predicates(&self,
637                           item_id: DefIndex,
638                           tcx: TyCtxt<'a, 'tcx, 'tcx>)
639                           -> ty::GenericPredicates<'tcx> {
640         self.entry(item_id).predicates.unwrap().decode((self, tcx))
641     }
642
643     pub fn get_super_predicates(&self,
644                                 item_id: DefIndex,
645                                 tcx: TyCtxt<'a, 'tcx, 'tcx>)
646                                 -> ty::GenericPredicates<'tcx> {
647         match self.entry(item_id).kind {
648             EntryKind::Trait(data) => data.decode(self).super_predicates.decode((self, tcx)),
649             _ => bug!(),
650         }
651     }
652
653     pub fn get_generics(&self,
654                         item_id: DefIndex,
655                         tcx: TyCtxt<'a, 'tcx, 'tcx>)
656                         -> ty::Generics<'tcx> {
657         self.entry(item_id).generics.unwrap().decode((self, tcx))
658     }
659
660     pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
661         self.entry(id).ty.unwrap().decode((self, tcx))
662     }
663
664     pub fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
665         match self.is_proc_macro(id) {
666             true => None,
667             false => self.entry(id).stability.map(|stab| stab.decode(self)),
668         }
669     }
670
671     pub fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
672         match self.is_proc_macro(id) {
673             true => None,
674             false => self.entry(id).deprecation.map(|depr| depr.decode(self)),
675         }
676     }
677
678     pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
679         match self.is_proc_macro(id) {
680             true => ty::Visibility::Public,
681             false => self.entry(id).visibility,
682         }
683     }
684
685     fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> {
686         match self.entry(id).kind {
687             EntryKind::Impl(data) => data.decode(self),
688             _ => bug!(),
689         }
690     }
691
692     pub fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
693         self.get_impl_data(id).parent_impl
694     }
695
696     pub fn get_impl_polarity(&self, id: DefIndex) -> hir::ImplPolarity {
697         self.get_impl_data(id).polarity
698     }
699
700     pub fn get_custom_coerce_unsized_kind(&self,
701                                           id: DefIndex)
702                                           -> Option<ty::adjustment::CustomCoerceUnsized> {
703         self.get_impl_data(id).coerce_unsized_kind
704     }
705
706     pub fn get_impl_trait(&self,
707                           id: DefIndex,
708                           tcx: TyCtxt<'a, 'tcx, 'tcx>)
709                           -> Option<ty::TraitRef<'tcx>> {
710         self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx)))
711     }
712
713     /// Iterates over the language items in the given crate.
714     pub fn get_lang_items(&self) -> Vec<(DefIndex, usize)> {
715         self.root.lang_items.decode(self).collect()
716     }
717
718     /// Iterates over each child of the given item.
719     pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F)
720         where F: FnMut(def::Export)
721     {
722         if let Some(ref proc_macros) = self.proc_macros {
723             if id == CRATE_DEF_INDEX {
724                 for (id, &(name, _)) in proc_macros.iter().enumerate() {
725                     let def = Def::Macro(DefId { krate: self.cnum, index: DefIndex::new(id + 1) });
726                     callback(def::Export { name: name, def: def });
727                 }
728             }
729             return
730         }
731
732         // Find the item.
733         let item = match self.maybe_entry(id) {
734             None => return,
735             Some(item) => item.decode(self),
736         };
737
738         // Iterate over all children.
739         let macros_only = self.dep_kind.get().macros_only();
740         for child_index in item.children.decode(self) {
741             if macros_only {
742                 continue
743             }
744
745             // Get the item.
746             if let Some(child) = self.maybe_entry(child_index) {
747                 let child = child.decode(self);
748                 match child.kind {
749                     EntryKind::MacroDef(..) => {}
750                     _ if macros_only => continue,
751                     _ => {}
752                 }
753
754                 // Hand off the item to the callback.
755                 match child.kind {
756                     // FIXME(eddyb) Don't encode these in children.
757                     EntryKind::ForeignMod => {
758                         for child_index in child.children.decode(self) {
759                             if let Some(def) = self.get_def(child_index) {
760                                 callback(def::Export {
761                                     def: def,
762                                     name: self.item_name(child_index),
763                                 });
764                             }
765                         }
766                         continue;
767                     }
768                     EntryKind::Impl(_) |
769                     EntryKind::DefaultImpl(_) => continue,
770
771                     _ => {}
772                 }
773
774                 let def_key = self.def_key(child_index);
775                 if let (Some(def), Some(name)) =
776                     (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
777                     callback(def::Export {
778                         def: def,
779                         name: name,
780                     });
781                     // For non-reexport structs and variants add their constructors to children.
782                     // Reexport lists automatically contain constructors when necessary.
783                     match def {
784                         Def::Struct(..) => {
785                             if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
786                                 let ctor_kind = self.get_ctor_kind(child_index);
787                                 let ctor_def = Def::StructCtor(ctor_def_id, ctor_kind);
788                                 callback(def::Export {
789                                     def: ctor_def,
790                                     name: name,
791                                 });
792                             }
793                         }
794                         Def::Variant(def_id) => {
795                             // Braced variants, unlike structs, generate unusable names in
796                             // value namespace, they are reserved for possible future use.
797                             let ctor_kind = self.get_ctor_kind(child_index);
798                             let ctor_def = Def::VariantCtor(def_id, ctor_kind);
799                             callback(def::Export {
800                                 def: ctor_def,
801                                 name: name,
802                             });
803                         }
804                         _ => {}
805                     }
806                 }
807             }
808         }
809
810         if let EntryKind::Mod(data) = item.kind {
811             for exp in data.decode(self).reexports.decode(self) {
812                 match exp.def {
813                     Def::Macro(..) => {}
814                     _ if macros_only => continue,
815                     _ => {}
816                 }
817                 callback(exp);
818             }
819         }
820     }
821
822     pub fn maybe_get_item_ast(&self,
823                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
824                               id: DefIndex)
825                               -> Option<&'tcx InlinedItem> {
826         debug!("Looking up item: {:?}", id);
827         if self.is_proc_macro(id) { return None; }
828         let item_doc = self.entry(id);
829         let item_did = self.local_def_id(id);
830         item_doc.ast.map(|ast| {
831             let ast = ast.decode(self);
832             decode_inlined_item(self, tcx, ast, item_did)
833         })
834     }
835
836     pub fn is_item_mir_available(&self, id: DefIndex) -> bool {
837         !self.is_proc_macro(id) &&
838         self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
839     }
840
841     pub fn can_have_local_instance(&self,
842                                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
843                                    id: DefIndex) -> bool {
844         self.maybe_entry(id).map_or(false, |item| {
845             let item = item.decode(self);
846             // if we don't have a MIR, then this item was never meant to be locally instantiated
847             // or we have a bug in the metadata serialization
848             item.mir.is_some() && (
849                 // items with generics always can have local instances if monomorphized
850                 item.generics.map_or(false, |generics| {
851                     let generics = generics.decode((self, tcx));
852                     generics.parent_types != 0 || !generics.types.is_empty()
853                 }) ||
854                 match item.kind {
855                     EntryKind::Closure(_) => true,
856                     _ => false,
857                 } ||
858                 item.kind.is_const_fn(self) ||
859                 attr::requests_inline(&self.get_attributes(&item))
860             )
861         })
862     }
863
864     pub fn maybe_get_item_mir(&self,
865                               tcx: TyCtxt<'a, 'tcx, 'tcx>,
866                               id: DefIndex)
867                               -> Option<Mir<'tcx>> {
868         match self.is_proc_macro(id) {
869             true => None,
870             false => self.entry(id).mir.map(|mir| mir.decode((self, tcx))),
871         }
872     }
873
874     pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
875         let item = self.entry(id);
876         let parent_and_name = || {
877             let def_key = self.def_key(id);
878             (self.local_def_id(def_key.parent.unwrap()),
879              def_key.disambiguated_data.data.get_opt_name().unwrap())
880         };
881
882         Some(match item.kind {
883             EntryKind::AssociatedConst(container) => {
884                 let (parent, name) = parent_and_name();
885                 ty::AssociatedItem {
886                     name: name,
887                     kind: ty::AssociatedKind::Const,
888                     vis: item.visibility,
889                     defaultness: container.defaultness(),
890                     def_id: self.local_def_id(id),
891                     container: container.with_def_id(parent),
892                     method_has_self_argument: false
893                 }
894             }
895             EntryKind::Method(data) => {
896                 let (parent, name) = parent_and_name();
897                 let data = data.decode(self);
898                 ty::AssociatedItem {
899                     name: name,
900                     kind: ty::AssociatedKind::Method,
901                     vis: item.visibility,
902                     defaultness: data.container.defaultness(),
903                     def_id: self.local_def_id(id),
904                     container: data.container.with_def_id(parent),
905                     method_has_self_argument: data.has_self
906                 }
907             }
908             EntryKind::AssociatedType(container) => {
909                 let (parent, name) = parent_and_name();
910                 ty::AssociatedItem {
911                     name: name,
912                     kind: ty::AssociatedKind::Type,
913                     vis: item.visibility,
914                     defaultness: container.defaultness(),
915                     def_id: self.local_def_id(id),
916                     container: container.with_def_id(parent),
917                     method_has_self_argument: false
918                 }
919             }
920             _ => return None,
921         })
922     }
923
924     pub fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
925         self.entry(id).variances.decode(self).collect()
926     }
927
928     pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
929         match self.entry(node_id).kind {
930             EntryKind::Struct(data) |
931             EntryKind::Union(data) |
932             EntryKind::Variant(data) => data.decode(self).ctor_kind,
933             _ => CtorKind::Fictive,
934         }
935     }
936
937     pub fn get_struct_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
938         match self.entry(node_id).kind {
939             EntryKind::Struct(data) => {
940                 data.decode(self).struct_ctor.map(|index| self.local_def_id(index))
941             }
942             _ => None,
943         }
944     }
945
946     pub fn get_item_attrs(&self, node_id: DefIndex) -> Vec<ast::Attribute> {
947         if self.is_proc_macro(node_id) {
948             return Vec::new();
949         }
950         // The attributes for a tuple struct are attached to the definition, not the ctor;
951         // we assume that someone passing in a tuple struct ctor is actually wanting to
952         // look at the definition
953         let mut item = self.entry(node_id);
954         let def_key = self.def_key(node_id);
955         if def_key.disambiguated_data.data == DefPathData::StructCtor {
956             item = self.entry(def_key.parent.unwrap());
957         }
958         self.get_attributes(&item)
959     }
960
961     pub fn get_struct_field_names(&self, id: DefIndex) -> Vec<ast::Name> {
962         self.entry(id)
963             .children
964             .decode(self)
965             .map(|index| self.item_name(index))
966             .collect()
967     }
968
969     fn get_attributes(&self, item: &Entry<'tcx>) -> Vec<ast::Attribute> {
970         item.attributes
971             .decode(self)
972             .map(|mut attr| {
973                 // Need new unique IDs: old thread-local IDs won't map to new threads.
974                 attr.id = attr::mk_attr_id();
975                 attr
976             })
977             .collect()
978     }
979
980     // Translate a DefId from the current compilation environment to a DefId
981     // for an external crate.
982     fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
983         for (local, &global) in self.cnum_map.borrow().iter_enumerated() {
984             if global == did.krate {
985                 return Some(DefId {
986                     krate: local,
987                     index: did.index,
988                 });
989             }
990         }
991
992         None
993     }
994
995     pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec<DefId> {
996         self.entry(id)
997             .inherent_impls
998             .decode(self)
999             .map(|index| self.local_def_id(index))
1000             .collect()
1001     }
1002
1003     pub fn get_implementations_for_trait(&self, filter: Option<DefId>, result: &mut Vec<DefId>) {
1004         // Do a reverse lookup beforehand to avoid touching the crate_num
1005         // hash map in the loop below.
1006         let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) {
1007             Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)),
1008             Some(None) => return,
1009             None => None,
1010         };
1011
1012         // FIXME(eddyb) Make this O(1) instead of O(n).
1013         for trait_impls in self.root.impls.decode(self) {
1014             if filter.is_some() && filter != Some(trait_impls.trait_id) {
1015                 continue;
1016             }
1017
1018             result.extend(trait_impls.impls.decode(self).map(|index| self.local_def_id(index)));
1019
1020             if filter.is_some() {
1021                 break;
1022             }
1023         }
1024     }
1025
1026     pub fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
1027         self.def_key(id).parent.and_then(|parent_index| {
1028             match self.entry(parent_index).kind {
1029                 EntryKind::Trait(_) => Some(self.local_def_id(parent_index)),
1030                 _ => None,
1031             }
1032         })
1033     }
1034
1035
1036     pub fn get_native_libraries(&self) -> Vec<NativeLibrary> {
1037         self.root.native_libraries.decode(self).collect()
1038     }
1039
1040     pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> {
1041         self.root
1042             .dylib_dependency_formats
1043             .decode(self)
1044             .enumerate()
1045             .flat_map(|(i, link)| {
1046                 let cnum = CrateNum::new(i + 1);
1047                 link.map(|link| (self.cnum_map.borrow()[cnum], link))
1048             })
1049             .collect()
1050     }
1051
1052     pub fn get_missing_lang_items(&self) -> Vec<lang_items::LangItem> {
1053         self.root.lang_items_missing.decode(self).collect()
1054     }
1055
1056     pub fn get_fn_arg_names(&self, id: DefIndex) -> Vec<ast::Name> {
1057         let arg_names = match self.entry(id).kind {
1058             EntryKind::Fn(data) |
1059             EntryKind::ForeignFn(data) => data.decode(self).arg_names,
1060             EntryKind::Method(data) => data.decode(self).fn_data.arg_names,
1061             _ => LazySeq::empty(),
1062         };
1063         arg_names.decode(self).collect()
1064     }
1065
1066     pub fn get_exported_symbols(&self) -> Vec<DefId> {
1067         self.root.exported_symbols.decode(self).map(|index| self.local_def_id(index)).collect()
1068     }
1069
1070     pub fn get_macro(&self, id: DefIndex) -> (ast::Name, MacroDef) {
1071         let entry = self.entry(id);
1072         match entry.kind {
1073             EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)),
1074             _ => bug!(),
1075         }
1076     }
1077
1078     pub fn is_const_fn(&self, id: DefIndex) -> bool {
1079         self.entry(id).kind.is_const_fn(self)
1080     }
1081
1082     pub fn is_foreign_item(&self, id: DefIndex) -> bool {
1083         match self.entry(id).kind {
1084             EntryKind::ForeignImmStatic |
1085             EntryKind::ForeignMutStatic |
1086             EntryKind::ForeignFn(_) => true,
1087             _ => false,
1088         }
1089     }
1090
1091     pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool {
1092         self.dllimport_foreign_items.contains(&id)
1093     }
1094
1095     pub fn is_defaulted_trait(&self, trait_id: DefIndex) -> bool {
1096         match self.entry(trait_id).kind {
1097             EntryKind::Trait(data) => data.decode(self).has_default_impl,
1098             _ => bug!(),
1099         }
1100     }
1101
1102     pub fn is_default_impl(&self, impl_id: DefIndex) -> bool {
1103         match self.entry(impl_id).kind {
1104             EntryKind::DefaultImpl(_) => true,
1105             _ => false,
1106         }
1107     }
1108
1109     pub fn closure_kind(&self, closure_id: DefIndex) -> ty::ClosureKind {
1110         match self.entry(closure_id).kind {
1111             EntryKind::Closure(data) => data.decode(self).kind,
1112             _ => bug!(),
1113         }
1114     }
1115
1116     pub fn closure_ty(&self,
1117                       closure_id: DefIndex,
1118                       tcx: TyCtxt<'a, 'tcx, 'tcx>)
1119                       -> ty::ClosureTy<'tcx> {
1120         match self.entry(closure_id).kind {
1121             EntryKind::Closure(data) => data.decode(self).ty.decode((self, tcx)),
1122             _ => bug!(),
1123         }
1124     }
1125
1126     pub fn def_key(&self, index: DefIndex) -> DefKey {
1127         self.def_path_table.def_key(index)
1128     }
1129
1130     // Returns the path leading to the thing with this `id`.
1131     pub fn def_path(&self, id: DefIndex) -> DefPath {
1132         debug!("def_path(id={:?})", id);
1133         DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent))
1134     }
1135
1136     /// Imports the codemap from an external crate into the codemap of the crate
1137     /// currently being compiled (the "local crate").
1138     ///
1139     /// The import algorithm works analogous to how AST items are inlined from an
1140     /// external crate's metadata:
1141     /// For every FileMap in the external codemap an 'inline' copy is created in the
1142     /// local codemap. The correspondence relation between external and local
1143     /// FileMaps is recorded in the `ImportedFileMap` objects returned from this
1144     /// function. When an item from an external crate is later inlined into this
1145     /// crate, this correspondence information is used to translate the span
1146     /// information of the inlined item so that it refers the correct positions in
1147     /// the local codemap (see `<decoder::DecodeContext as SpecializedDecoder<Span>>`).
1148     ///
1149     /// The import algorithm in the function below will reuse FileMaps already
1150     /// existing in the local codemap. For example, even if the FileMap of some
1151     /// source file of libstd gets imported many times, there will only ever be
1152     /// one FileMap object for the corresponding file in the local codemap.
1153     ///
1154     /// Note that imported FileMaps do not actually contain the source code of the
1155     /// file they represent, just information about length, line breaks, and
1156     /// multibyte characters. This information is enough to generate valid debuginfo
1157     /// for items inlined from other crates.
1158     pub fn imported_filemaps(&'a self,
1159                              local_codemap: &codemap::CodeMap)
1160                              -> Ref<'a, Vec<cstore::ImportedFileMap>> {
1161         {
1162             let filemaps = self.codemap_import_info.borrow();
1163             if !filemaps.is_empty() {
1164                 return filemaps;
1165             }
1166         }
1167
1168         let external_codemap = self.root.codemap.decode(self);
1169
1170         let imported_filemaps = external_codemap.map(|filemap_to_import| {
1171                 // Try to find an existing FileMap that can be reused for the filemap to
1172                 // be imported. A FileMap is reusable if it is exactly the same, just
1173                 // positioned at a different offset within the codemap.
1174                 let reusable_filemap = {
1175                     local_codemap.files
1176                         .borrow()
1177                         .iter()
1178                         .find(|fm| are_equal_modulo_startpos(&fm, &filemap_to_import))
1179                         .map(|rc| rc.clone())
1180                 };
1181
1182                 match reusable_filemap {
1183                     Some(fm) => {
1184
1185                         debug!("CrateMetaData::imported_filemaps reuse \
1186                                 filemap {:?} original (start_pos {:?} end_pos {:?}) \
1187                                 translated (start_pos {:?} end_pos {:?})",
1188                                filemap_to_import.name,
1189                                filemap_to_import.start_pos, filemap_to_import.end_pos,
1190                                fm.start_pos, fm.end_pos);
1191
1192                         cstore::ImportedFileMap {
1193                             original_start_pos: filemap_to_import.start_pos,
1194                             original_end_pos: filemap_to_import.end_pos,
1195                             translated_filemap: fm,
1196                         }
1197                     }
1198                     None => {
1199                         // We can't reuse an existing FileMap, so allocate a new one
1200                         // containing the information we need.
1201                         let syntax_pos::FileMap { name,
1202                                                   abs_path,
1203                                                   start_pos,
1204                                                   end_pos,
1205                                                   lines,
1206                                                   multibyte_chars,
1207                                                   .. } = filemap_to_import;
1208
1209                         let source_length = (end_pos - start_pos).to_usize();
1210
1211                         // Translate line-start positions and multibyte character
1212                         // position into frame of reference local to file.
1213                         // `CodeMap::new_imported_filemap()` will then translate those
1214                         // coordinates to their new global frame of reference when the
1215                         // offset of the FileMap is known.
1216                         let mut lines = lines.into_inner();
1217                         for pos in &mut lines {
1218                             *pos = *pos - start_pos;
1219                         }
1220                         let mut multibyte_chars = multibyte_chars.into_inner();
1221                         for mbc in &mut multibyte_chars {
1222                             mbc.pos = mbc.pos - start_pos;
1223                         }
1224
1225                         let local_version = local_codemap.new_imported_filemap(name,
1226                                                                                abs_path,
1227                                                                                source_length,
1228                                                                                lines,
1229                                                                                multibyte_chars);
1230                         debug!("CrateMetaData::imported_filemaps alloc \
1231                                 filemap {:?} original (start_pos {:?} end_pos {:?}) \
1232                                 translated (start_pos {:?} end_pos {:?})",
1233                                local_version.name, start_pos, end_pos,
1234                                local_version.start_pos, local_version.end_pos);
1235
1236                         cstore::ImportedFileMap {
1237                             original_start_pos: start_pos,
1238                             original_end_pos: end_pos,
1239                             translated_filemap: local_version,
1240                         }
1241                     }
1242                 }
1243             })
1244             .collect();
1245
1246         // This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
1247         *self.codemap_import_info.borrow_mut() = imported_filemaps;
1248         self.codemap_import_info.borrow()
1249     }
1250 }
1251
1252 fn are_equal_modulo_startpos(fm1: &syntax_pos::FileMap, fm2: &syntax_pos::FileMap) -> bool {
1253     if fm1.byte_length() != fm2.byte_length() {
1254         return false;
1255     }
1256
1257     if fm1.name != fm2.name {
1258         return false;
1259     }
1260
1261     let lines1 = fm1.lines.borrow();
1262     let lines2 = fm2.lines.borrow();
1263
1264     if lines1.len() != lines2.len() {
1265         return false;
1266     }
1267
1268     for (&line1, &line2) in lines1.iter().zip(lines2.iter()) {
1269         if (line1 - fm1.start_pos) != (line2 - fm2.start_pos) {
1270             return false;
1271         }
1272     }
1273
1274     let multibytes1 = fm1.multibyte_chars.borrow();
1275     let multibytes2 = fm2.multibyte_chars.borrow();
1276
1277     if multibytes1.len() != multibytes2.len() {
1278         return false;
1279     }
1280
1281     for (mb1, mb2) in multibytes1.iter().zip(multibytes2.iter()) {
1282         if (mb1.bytes != mb2.bytes) || ((mb1.pos - fm1.start_pos) != (mb2.pos - fm2.start_pos)) {
1283             return false;
1284         }
1285     }
1286
1287     true
1288 }