Skip to content

Commit

Permalink
Record expansion_that_defined into crate metadata
Browse files Browse the repository at this point in the history
Fixes #77523

Now that hygiene serialization is implemented, we also need to record
`expansion_that_defined` so that we properly handle a foreign
`SyntaxContext`.
  • Loading branch information
Aaron1011 committed Oct 5, 2020
1 parent f317a93 commit 8d11f90
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 2 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.tables.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
}

fn get_expn_that_defined(&self, id: DefIndex, sess: &Session) -> ExpnId {
self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
}

/// Iterates over all the stability attributes in the given crate.
fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
// FIXME: For a proc macro crate, not sure whether we should return the "host"
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
}

crate_extern_paths => { cdata.source().paths().cloned().collect() }
expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
}

pub fn provide(providers: &mut Providers) {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@ impl EncodeContext<'a, 'tcx> {
ty::Visibility::from_hir(enum_vis, enum_id, self.tcx));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
Expand Down Expand Up @@ -883,6 +884,7 @@ impl EncodeContext<'a, 'tcx> {
record!(self.tables.visibility[def_id] <- field.vis);
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- variant_data.fields()[field_index].attrs);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
self.encode_ident_span(def_id, field.ident);
self.encode_stability(def_id);
self.encode_deprecation(def_id);
Expand Down Expand Up @@ -924,6 +926,7 @@ impl EncodeContext<'a, 'tcx> {
record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr));
record!(self.tables.visibility[def_id] <- ctor_vis);
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
self.encode_stability(def_id);
self.encode_deprecation(def_id);
self.encode_item_type(def_id);
Expand Down Expand Up @@ -1339,6 +1342,7 @@ impl EncodeContext<'a, 'tcx> {
ty::Visibility::from_hir(&item.vis, item.hir_id, tcx));
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- item.attrs);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expansion_that_defined(def_id));
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
hir::ItemKind::ForeignMod(ref fm) => record!(self.tables.children[def_id] <-
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ define_tables! {
variances: Table<DefIndex, Lazy<[ty::Variance]>>,
generics: Table<DefIndex, Lazy<ty::Generics>>,
explicit_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
// FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
// doesn't handle shorthands in its own (de)serialization impls,
// as it's an `enum` for which we want to derive (de)serialization,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ rustc_queries! {
eval_always
desc { |tcx| "parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
}

/// Internal helper query. Use `tcx.expansion_that_defined` instead
query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
}
}

Codegen {
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3034,10 +3034,12 @@ impl<'tcx> TyCtxt<'tcx> {
.hygienic_eq(def_name.span.ctxt(), self.expansion_that_defined(def_parent_def_id))
}

fn expansion_that_defined(self, scope: DefId) -> ExpnId {
pub fn expansion_that_defined(self, scope: DefId) -> ExpnId {
match scope.as_local() {
// Parsing and expansion aren't incremental, so we don't
// need to go through a query for the same-crate case.
Some(scope) => self.hir().definitions().expansion_that_defined(scope),
None => ExpnId::root(),
None => self.expn_that_defined(scope),
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/hygiene/auxiliary/def-site-async-await.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// edition:2018

extern crate opaque_hygiene;

pub async fn serve() {
opaque_hygiene::make_it!();
}
21 changes: 21 additions & 0 deletions src/test/ui/hygiene/auxiliary/opaque-hygiene.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// force-host
// no-prefer-dynamic

#![feature(proc_macro_quote)]
#![crate_type = "proc-macro"]

extern crate proc_macro;
use proc_macro::{TokenStream, quote};

#[proc_macro]
pub fn make_it(input: TokenStream) -> TokenStream {
// `quote!` applies def-site hygiene
quote! {
trait Foo {
fn my_fn(&self) {}
}

impl<T> Foo for T {}
"a".my_fn();
}
}
19 changes: 19 additions & 0 deletions src/test/ui/hygiene/issue-77523-def-site-async-await.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// build-pass
// aux-build:opaque-hygiene.rs
// aux-build:def-site-async-await.rs

// Regression test for issue #77523
// Tests that we don't ICE when an unusual combination
// of def-site hygiene and cross-crate monomorphization occurs.

extern crate def_site_async_await;

use std::future::Future;

fn mk_ctxt() -> std::task::Context<'static> {
panic!()
}

fn main() {
Box::pin(def_site_async_await::serve()).as_mut().poll(&mut mk_ctxt());
}

0 comments on commit 8d11f90

Please sign in to comment.