Serialize all foreign SourceFiles into proc-macro crate metadata

Normally, we encode a `Span` that references a foreign `SourceFile` by
encoding information about the foreign crate. When we decode this
`Span`, we lookup the foreign crate in order to decode the `SourceFile`.

However, this approach does not work for proc-macro crates. When we load
a proc-macro crate, we do not deserialzie any of its dependencies (since
a proc-macro crate can only export proc-macros). This means that we
cannot serialize a reference to an upstream crate, since the associated
metadata will not be available when we try to deserialize it.

This commit modifies foreign span handling so that we treat all foreign
`SourceFile`s as local `SourceFile`s when serializing a proc-macro.
All `SourceFile`s will be stored into the metadata of a proc-macro
crate, allowing us to cotinue to deserialize a proc-macro crate without
needing to load any of its dependencies.

Since the number of foreign `SourceFile`s that we load during a
compilation session may be very large, we only serialize a `SourceFile`
if we have also serialized a `Span` which requires it.
This commit is contained in:
Aaron Hill 2020-06-24 13:16:36 -04:00
parent a1528c432e
commit 334373324d
No known key found for this signature in database
GPG key ID: B4087E510E98B164
13 changed files with 220 additions and 43 deletions

View file

@ -16,8 +16,8 @@ fn y /* 0#0 */() { }
/*
Expansions:
0: parent: ExpnId(0), call_site_ctxt: #0, kind: Root
1: parent: ExpnId(0), call_site_ctxt: #0, kind: Macro(Bang, "foo")
0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "foo")
SyntaxContexts:
#0: parent: #0, outer_mark: (ExpnId(0), Opaque)

View file

@ -0,0 +1,10 @@
#[macro_export]
macro_rules! make_it {
($name:ident) => {
#[proc_macro]
pub fn $name(input: TokenStream) -> TokenStream {
println!("Def site: {:?}", Span::def_site());
input
}
};
}

View file

@ -0,0 +1,12 @@
// force-host
// no-prefer-dynamic
// edition:2018
#![feature(proc_macro_def_site)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
extern crate make_macro;
use proc_macro::{TokenStream, Span};
make_macro::make_it!(print_def_site);

View file

@ -10,11 +10,16 @@ error[E0603]: derive macro import `Empty` is private
LL | use m::Empty;
| ^^^^^ private derive macro import
|
note: the derive macro import `Empty` is defined here
note: the derive macro import `Empty` is defined here...
--> $DIR/disappearing-resolution.rs:9:9
|
LL | use test_macros::Empty;
| ^^^^^^^^^^^^^^^^^^
note: ...and refers to the derive macro `Empty` which is defined here
--> $DIR/auxiliary/test-macros.rs:25:1
|
LL | pub fn empty_derive(_: TokenStream) -> TokenStream {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider importing it directly
error: aborting due to 2 previous errors

View file

@ -0,0 +1,11 @@
// aux-build:make-macro.rs
// aux-build:meta-macro.rs
// edition:2018
// compile-flags: -Z span-debug -Z unpretty=expanded,hygiene
// check-pass
extern crate meta_macro;
fn main() {
meta_macro::print_def_site!();
}

View file

@ -0,0 +1,30 @@
Def site: $DIR/auxiliary/make-macro.rs:5:9: 8:10 (#3)
#![feature /* 280#0 */(prelude_import)]
#[prelude_import /* 527#1 */]
use std /* 687#1 */::prelude /* 526#1 */::v1 /* 783#1 */::*;
#[macro_use /* 404#1 */]
extern crate std /* 687#1 */;
// aux-build:make-macro.rs
// aux-build:meta-macro.rs
// edition:2018
// compile-flags: -Z span-debug -Z unpretty=expanded,hygiene
// check-pass
extern crate meta_macro /* 834#0 */;
fn main /* 406#0 */() { }
/*
Expansions:
0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "meta_macro::print_def_site")
SyntaxContexts:
#0: parent: #0, outer_mark: (ExpnId(0), Opaque)
#1: parent: #0, outer_mark: (ExpnId(1), Opaque)
#2: parent: #0, outer_mark: (ExpnId(1), Transparent)
#3: parent: #0, outer_mark: (ExpnId(2), Opaque)
#4: parent: #0, outer_mark: (ExpnId(2), Transparent)
#5: parent: #0, outer_mark: (ExpnId(2), SemiTransparent)
*/

View file

@ -0,0 +1,11 @@
// aux-build:make-macro.rs
// aux-build:meta-macro.rs
// edition:2018
// compile-flags: -Z span-debug
// run-pass
extern crate meta_macro;
fn main() {
meta_macro::print_def_site!();
}

View file

@ -0,0 +1 @@
Def site: $DIR/auxiliary/make-macro.rs:5:9: 8:10 (#3)