Skip to content

Commit 0caebfa

Browse files
committed
Hygiene serialization implementation
1 parent 6c8927b commit 0caebfa

32 files changed

+929
-284
lines changed

src/librustc_ast_lowering/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use rustc_data_structures::thin_vec::ThinVec;
99
use rustc_errors::struct_span_err;
1010
use rustc_hir as hir;
1111
use rustc_hir::def::Res;
12-
use rustc_span::source_map::{respan, DesugaringKind, ForLoopLoc, Span, Spanned};
12+
use rustc_span::hygiene::ForLoopLoc;
13+
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
1314
use rustc_span::symbol::{sym, Ident, Symbol};
1415
use rustc_target::asm;
1516
use std::collections::hash_map::Entry;

src/librustc_expand/base.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_data_structures::sync::{self, Lrc};
1313
use rustc_errors::{DiagnosticBuilder, ErrorReported};
1414
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
1515
use rustc_session::{parse::ParseSess, Limit};
16-
use rustc_span::def_id::DefId;
16+
use rustc_span::def_id::{DefId, LOCAL_CRATE};
1717
use rustc_span::edition::Edition;
1818
use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind};
1919
use rustc_span::source_map::SourceMap;
@@ -873,6 +873,8 @@ impl SyntaxExtension {
873873
local_inner_macros: self.local_inner_macros,
874874
edition: self.edition,
875875
macro_def_id,
876+
krate: LOCAL_CRATE,
877+
orig_id: None,
876878
}
877879
}
878880
}

src/librustc_expand/expand.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::base::*;
22
use crate::config::StripUnconfigured;
33
use crate::configure;
4-
use crate::hygiene::{ExpnData, ExpnId, ExpnKind, SyntaxContext};
4+
use crate::hygiene::{ExpnData, ExpnKind, SyntaxContext};
55
use crate::mbe::macro_rules::annotate_err_with_kind;
66
use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwnership};
77
use crate::placeholders::{placeholder, PlaceholderExpander};
@@ -27,7 +27,7 @@ use rustc_session::parse::{feature_err, ParseSess};
2727
use rustc_session::Limit;
2828
use rustc_span::source_map::respan;
2929
use rustc_span::symbol::{sym, Ident, Symbol};
30-
use rustc_span::{FileName, Span, DUMMY_SP};
30+
use rustc_span::{ExpnId, FileName, Span, DUMMY_SP};
3131

3232
use smallvec::{smallvec, SmallVec};
3333
use std::io::ErrorKind;

src/librustc_metadata/creader.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,16 @@ impl<'a> CrateLoader<'a> {
307307
let private_dep =
308308
self.sess.opts.externs.get(&name.as_str()).map(|e| e.is_private_dep).unwrap_or(false);
309309

310-
info!("register crate `{}` (private_dep = {})", crate_root.name(), private_dep);
311-
312310
// Claim this crate number and cache it
313311
let cnum = self.cstore.alloc_new_crate_num();
314312

313+
info!(
314+
"register crate `{}` (cnum = {}. private_dep = {})",
315+
crate_root.name(),
316+
cnum,
317+
private_dep
318+
);
319+
315320
// Maintain a reference to the top most crate.
316321
// Stash paths for top-most crate locally if necessary.
317322
let crate_paths;
@@ -339,22 +344,21 @@ impl<'a> CrateLoader<'a> {
339344
None
340345
};
341346

342-
self.cstore.set_crate_data(
347+
let crate_metadata = CrateMetadata::new(
348+
self.sess,
349+
metadata,
350+
crate_root,
351+
raw_proc_macros,
343352
cnum,
344-
CrateMetadata::new(
345-
self.sess,
346-
metadata,
347-
crate_root,
348-
raw_proc_macros,
349-
cnum,
350-
cnum_map,
351-
dep_kind,
352-
source,
353-
private_dep,
354-
host_hash,
355-
),
353+
cnum_map,
354+
dep_kind,
355+
source,
356+
private_dep,
357+
host_hash,
356358
);
357359

360+
self.cstore.set_crate_data(cnum, crate_metadata);
361+
358362
Ok(cnum)
359363
}
360364

@@ -569,6 +573,8 @@ impl<'a> CrateLoader<'a> {
569573
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?;
570574
crate_num_map.push(cnum);
571575
}
576+
577+
debug!("resolve_crate_deps: cnum_map for {:?} is {:?}", krate, crate_num_map);
572578
Ok(crate_num_map)
573579
}
574580

src/librustc_metadata/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#![feature(proc_macro_internals)]
1010
#![feature(min_specialization)]
1111
#![feature(stmt_expr_attributes)]
12+
#![feature(never_type)]
1213
#![recursion_limit = "256"]
1314

1415
extern crate proc_macro;

src/librustc_metadata/rmeta/decoder.rs

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,21 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
3232
use rustc_middle::util::common::record_time;
3333
use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder, UseSpecializedDecodable};
3434
use rustc_session::Session;
35+
use rustc_span::hygiene::ExpnDataDecodeMode;
3536
use rustc_span::source_map::{respan, Spanned};
3637
use rustc_span::symbol::{sym, Ident, Symbol};
37-
use rustc_span::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP};
38+
use rustc_span::{self, hygiene::MacroKind, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
3839

3940
use log::debug;
4041
use proc_macro::bridge::client::ProcMacro;
42+
use std::cell::Cell;
4143
use std::io;
4244
use std::mem;
4345
use std::num::NonZeroUsize;
4446
use std::path::Path;
4547

4648
pub use cstore_impl::{provide, provide_extern};
49+
use rustc_span::hygiene::HygieneContext;
4750

4851
mod cstore_impl;
4952

@@ -106,6 +109,13 @@ crate struct CrateMetadata {
106109
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
107110
host_hash: Option<Svh>,
108111

112+
/// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
113+
/// and `ExpnId`).
114+
/// Note that we store a `HygieneContext` for each `CrateMetadat`. This is
115+
/// because `SyntaxContext` ids are not globally unique, so we need
116+
/// to track which ids we've decoded on a per-crate basis.
117+
hygiene_context: HygieneContext,
118+
109119
// --- Data used only for improving diagnostics ---
110120
/// Information about the `extern crate` item or path that caused this crate to be loaded.
111121
/// If this is `None`, then the crate was injected (e.g., by the allocator).
@@ -411,6 +421,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
411421

412422
let lo = BytePos::decode(self)?;
413423
let len = BytePos::decode(self)?;
424+
let ctxt = SyntaxContext::decode(self)?;
414425
let hi = lo + len;
415426

416427
let sess = if let Some(sess) = self.sess {
@@ -524,7 +535,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
524535
let hi =
525536
(hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
526537

527-
Ok(Span::with_root_ctxt(lo, hi))
538+
Ok(Span::new(lo, hi, ctxt))
528539
}
529540
}
530541

@@ -1120,6 +1131,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11201131
!self.is_proc_macro(id) && self.root.tables.mir.get(self, id).is_some()
11211132
}
11221133

1134+
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
1135+
if let EntryKind::Mod(m) = self.kind(id) {
1136+
m.decode((self, sess)).expansion
1137+
} else {
1138+
panic!("Expected module, found {:?}", self.local_def_id(id))
1139+
}
1140+
}
1141+
11231142
fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
11241143
self.root
11251144
.tables
@@ -1652,6 +1671,7 @@ impl CrateMetadata {
16521671
private_dep,
16531672
host_hash,
16541673
extern_crate: Lock::new(None),
1674+
hygiene_context: HygieneContext::new(),
16551675
}
16561676
}
16571677

@@ -1784,3 +1804,57 @@ fn macro_kind(raw: &ProcMacro) -> MacroKind {
17841804
ProcMacro::Bang { .. } => MacroKind::Bang,
17851805
}
17861806
}
1807+
1808+
impl<'a, 'tcx> SpecializedDecoder<SyntaxContext> for DecodeContext<'a, 'tcx> {
1809+
fn specialized_decode(&mut self) -> Result<SyntaxContext, Self::Error> {
1810+
let cdata = self.cdata();
1811+
let sess = self.sess.unwrap();
1812+
let cname = cdata.root.name;
1813+
rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| {
1814+
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
1815+
Ok(cdata
1816+
.root
1817+
.syntax_contexts
1818+
.get(&cdata, id)
1819+
.unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
1820+
.decode((&cdata, sess)))
1821+
})
1822+
}
1823+
}
1824+
1825+
impl<'a, 'tcx> SpecializedDecoder<ExpnId> for DecodeContext<'a, 'tcx> {
1826+
fn specialized_decode(&mut self) -> Result<ExpnId, Self::Error> {
1827+
let local_cdata = self.cdata();
1828+
let sess = self.sess.unwrap();
1829+
let expn_cnum = Cell::new(None);
1830+
let get_ctxt = |cnum| {
1831+
expn_cnum.set(Some(cnum));
1832+
if cnum == LOCAL_CRATE {
1833+
&local_cdata.hygiene_context
1834+
} else {
1835+
&local_cdata.cstore.get_crate_data(cnum).cdata.hygiene_context
1836+
}
1837+
};
1838+
1839+
rustc_span::hygiene::decode_expn_id(
1840+
self,
1841+
ExpnDataDecodeMode::Metadata(get_ctxt),
1842+
|_this, index| {
1843+
let cnum = expn_cnum.get().unwrap();
1844+
// Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
1845+
// are stored in the owning crate, to avoid duplication.
1846+
let crate_data = if cnum == LOCAL_CRATE {
1847+
local_cdata
1848+
} else {
1849+
local_cdata.cstore.get_crate_data(cnum)
1850+
};
1851+
Ok(crate_data
1852+
.root
1853+
.expn_data
1854+
.get(&crate_data, index)
1855+
.unwrap()
1856+
.decode((&crate_data, sess)))
1857+
},
1858+
)
1859+
}
1860+
}

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ use rustc_middle::ty::{self, TyCtxt};
2121
use rustc_session::utils::NativeLibKind;
2222
use rustc_session::{CrateDisambiguator, Session};
2323
use rustc_span::source_map::{self, Span, Spanned};
24-
use rustc_span::symbol::{Ident, Symbol};
24+
use rustc_span::symbol::Symbol;
2525

2626
use rustc_data_structures::sync::Lrc;
27+
use rustc_span::ExpnId;
2728
use smallvec::SmallVec;
2829
use std::any::Any;
2930

@@ -417,13 +418,7 @@ impl CStore {
417418
attr::mark_used(attr);
418419
}
419420

420-
let ident = data
421-
.def_key(id.index)
422-
.disambiguated_data
423-
.data
424-
.get_opt_name()
425-
.map(Ident::with_dummy_span) // FIXME: cross-crate hygiene
426-
.expect("no name in load_macro");
421+
let ident = data.item_ident(id.index, sess);
427422

428423
LoadedMacro::MacroDef(
429424
ast::Item {
@@ -454,6 +449,10 @@ impl CStore {
454449
pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize {
455450
self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes
456451
}
452+
453+
pub fn module_expansion_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
454+
self.get_crate_data(def_id.krate).module_expansion(def_id.index, sess)
455+
}
457456
}
458457

459458
impl CrateStore for CStore {

0 commit comments

Comments
 (0)