Auto merge of #95573 - cjgillot:lower-query, r=michaelwoerister
Make lowering a query Split from https://github.com/rust-lang/rust/pull/88186. This PR refactors the relationship between lowering and the resolver outputs in order to make lowering itself a query. In a first part, lowering is changed to avoid modifying resolver outputs, by maintaining its own data structures for creating new `NodeId`s and so. Then, the `TyCtxt` is modified to allow creating new `LocalDefId`s from inside it. This is done by: - enclosing `Definitions` in a lock, so as to allow modification; - creating a query `register_def` whose purpose is to declare a `LocalDefId` to the query system. See `TyCtxt::create_def` and `TyCtxt::iter_local_def_id` for more detailed explanations of the design.
This commit is contained in:
commit
0f573a0c54
37 changed files with 462 additions and 391 deletions
|
@ -24,10 +24,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
) -> &'hir hir::InlineAsm<'hir> {
|
||||
// Rustdoc needs to support asm! from foreign architectures: don't try
|
||||
// lowering the register constraints in this case.
|
||||
let asm_arch = if self.sess.opts.actually_rustdoc { None } else { self.sess.asm_arch };
|
||||
if asm_arch.is_none() && !self.sess.opts.actually_rustdoc {
|
||||
struct_span_err!(self.sess, sp, E0472, "inline assembly is unsupported on this target")
|
||||
.emit();
|
||||
let asm_arch =
|
||||
if self.tcx.sess.opts.actually_rustdoc { None } else { self.tcx.sess.asm_arch };
|
||||
if asm_arch.is_none() && !self.tcx.sess.opts.actually_rustdoc {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
sp,
|
||||
E0472,
|
||||
"inline assembly is unsupported on this target"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
// Inline assembly is currently only stable for these architectures.
|
||||
|
@ -40,9 +46,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
| asm::InlineAsmArch::RiscV32
|
||||
| asm::InlineAsmArch::RiscV64
|
||||
);
|
||||
if !is_stable && !self.sess.features_untracked().asm_experimental_arch {
|
||||
if !is_stable && !self.tcx.features().asm_experimental_arch {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::asm_experimental_arch,
|
||||
sp,
|
||||
"inline assembly is not stable yet on this architecture",
|
||||
|
@ -52,17 +58,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
|
||||
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
|
||||
&& !self.sess.opts.actually_rustdoc
|
||||
&& !self.tcx.sess.opts.actually_rustdoc
|
||||
{
|
||||
self.sess
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
|
||||
.emit();
|
||||
}
|
||||
if asm.options.contains(InlineAsmOptions::MAY_UNWIND)
|
||||
&& !self.sess.features_untracked().asm_unwind
|
||||
{
|
||||
if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::asm_unwind,
|
||||
sp,
|
||||
"the `may_unwind` option is unstable",
|
||||
|
@ -73,12 +78,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let mut clobber_abis = FxHashMap::default();
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
||||
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
|
||||
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
|
||||
Ok(abi) => {
|
||||
// If the abi was already in the list, emit an error
|
||||
match clobber_abis.get(&abi) {
|
||||
Some((prev_name, prev_sp)) => {
|
||||
let mut err = self.sess.struct_span_err(
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
*abi_span,
|
||||
&format!("`{}` ABI specified multiple times", prev_name),
|
||||
);
|
||||
|
@ -86,7 +91,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// Multiple different abi names may actually be the same ABI
|
||||
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
|
||||
let source_map = self.sess.source_map();
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
if source_map.span_to_snippet(*prev_sp)
|
||||
!= source_map.span_to_snippet(*abi_span)
|
||||
{
|
||||
|
@ -101,7 +106,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
Err(&[]) => {
|
||||
self.sess
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
*abi_span,
|
||||
"`clobber_abi` is not supported on this target",
|
||||
|
@ -109,8 +115,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
.emit();
|
||||
}
|
||||
Err(supported_abis) => {
|
||||
let mut err =
|
||||
self.sess.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
|
||||
let mut err = self
|
||||
.tcx
|
||||
.sess
|
||||
.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
|
||||
let mut abis = format!("`{}`", supported_abis[0]);
|
||||
for m in &supported_abis[1..] {
|
||||
let _ = write!(abis, ", `{}`", m);
|
||||
|
@ -128,7 +136,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// Lower operands to HIR. We use dummy register classes if an error
|
||||
// occurs during lowering because we still need to be able to produce a
|
||||
// valid HIR.
|
||||
let sess = self.sess;
|
||||
let sess = self.tcx.sess;
|
||||
let mut operands: Vec<_> = asm
|
||||
.operands
|
||||
.iter()
|
||||
|
@ -184,9 +192,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
InlineAsmOperand::Const { ref anon_const } => {
|
||||
if !self.sess.features_untracked().asm_const {
|
||||
if !self.tcx.features().asm_const {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&sess.parse_sess,
|
||||
sym::asm_const,
|
||||
*op_sp,
|
||||
"const operands for inline assembly are unstable",
|
||||
|
@ -198,9 +206,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
InlineAsmOperand::Sym { ref sym } => {
|
||||
if !self.sess.features_untracked().asm_sym {
|
||||
if !self.tcx.features().asm_sym {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&sess.parse_sess,
|
||||
sym::asm_sym,
|
||||
*op_sp,
|
||||
"sym operands for inline assembly are unstable",
|
||||
|
|
|
@ -159,9 +159,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
span,
|
||||
kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)),
|
||||
});
|
||||
if !self.sess.features_untracked().let_else {
|
||||
if !self.tcx.features().let_else {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::let_else,
|
||||
local.span,
|
||||
"`let...else` statements are unstable",
|
||||
|
|
|
@ -46,7 +46,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let hir_id = self.lower_node_id(e.id);
|
||||
return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
|
||||
} else {
|
||||
self.sess
|
||||
self.tcx.sess
|
||||
.struct_span_err(
|
||||
e.span,
|
||||
"#[rustc_box] requires precisely one argument \
|
||||
|
@ -207,8 +207,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
|
||||
}
|
||||
ExprKind::Underscore => {
|
||||
self.sess
|
||||
.struct_span_err(
|
||||
self.tcx
|
||||
.sess.struct_span_err(
|
||||
e.span,
|
||||
"in expressions, `_` can only be used on the left-hand side of an assignment",
|
||||
)
|
||||
|
@ -245,7 +245,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let rest = match &se.rest {
|
||||
StructRest::Base(e) => Some(self.lower_expr(e)),
|
||||
StructRest::Rest(sp) => {
|
||||
self.sess
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(*sp, "base expression required after `..`")
|
||||
.span_label(*sp, "add a base expression here")
|
||||
.emit();
|
||||
|
@ -474,7 +475,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
} else {
|
||||
let try_span = this.mark_span_with_reason(
|
||||
DesugaringKind::TryBlock,
|
||||
this.sess.source_map().end_point(body.span),
|
||||
this.tcx.sess.source_map().end_point(body.span),
|
||||
this.allow_try_trait.clone(),
|
||||
);
|
||||
|
||||
|
@ -653,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
Some(hir::GeneratorKind::Async(_)) => {}
|
||||
Some(hir::GeneratorKind::Gen) | None => {
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
dot_await_span,
|
||||
E0728,
|
||||
"`await` is only allowed inside `async` functions and blocks"
|
||||
|
@ -878,7 +879,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
Some(hir::GeneratorKind::Gen) => {
|
||||
if decl.inputs.len() > 1 {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0628,
|
||||
"too many parameters for a generator (expected 0 or 1 parameters)"
|
||||
|
@ -892,8 +893,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
None => {
|
||||
if movability == Movability::Static {
|
||||
struct_span_err!(self.sess, fn_decl_span, E0697, "closures cannot be static")
|
||||
.emit();
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0697,
|
||||
"closures cannot be static"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -916,7 +922,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||
struct_span_err!(
|
||||
this.sess,
|
||||
this.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0708,
|
||||
"`async` non-`move` closures with parameters are not currently supported",
|
||||
|
@ -1163,7 +1169,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
let fields_omitted = match &se.rest {
|
||||
StructRest::Base(e) => {
|
||||
self.sess
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
e.span,
|
||||
"functional record updates are not allowed in destructuring \
|
||||
|
@ -1371,7 +1378,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
Some(hir::GeneratorKind::Gen) => {}
|
||||
Some(hir::GeneratorKind::Async(_)) => {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0727,
|
||||
"`async` generators are not yet supported"
|
||||
|
@ -1516,7 +1523,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
span,
|
||||
self.allow_try_trait.clone(),
|
||||
);
|
||||
let try_span = self.sess.source_map().end_point(span);
|
||||
let try_span = self.tcx.sess.source_map().end_point(span);
|
||||
let try_span = self.mark_span_with_reason(
|
||||
DesugaringKind::QuestionMark,
|
||||
try_span,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use super::ResolverAstLoweringExt;
|
||||
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
|
||||
use super::{LoweringContext, ParamMode};
|
||||
use crate::{Arena, FnDeclKind};
|
||||
use super::{FnDeclKind, LoweringContext, ParamMode};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::AssocCtxt;
|
||||
|
@ -12,12 +11,9 @@ use rustc_errors::struct_span_err;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_hir::PredicateOrigin;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::ty::{ResolverAstLowering, ResolverOutputs};
|
||||
use rustc_session::cstore::CrateStoreDyn;
|
||||
use rustc_session::Session;
|
||||
use rustc_middle::ty::{DefIdTree, ResolverAstLowering, TyCtxt};
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
|
@ -27,12 +23,8 @@ use smallvec::{smallvec, SmallVec};
|
|||
use std::iter;
|
||||
|
||||
pub(super) struct ItemLowerer<'a, 'hir> {
|
||||
pub(super) sess: &'a Session,
|
||||
pub(super) definitions: &'a mut Definitions,
|
||||
pub(super) cstore: &'a CrateStoreDyn,
|
||||
pub(super) resolutions: &'a ResolverOutputs,
|
||||
pub(super) tcx: TyCtxt<'hir>,
|
||||
pub(super) resolver: &'a mut ResolverAstLowering,
|
||||
pub(super) arena: &'hir Arena<'hir>,
|
||||
pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'a>>,
|
||||
pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
|
||||
}
|
||||
|
@ -65,12 +57,9 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
) {
|
||||
let mut lctx = LoweringContext {
|
||||
// Pseudo-globals.
|
||||
sess: &self.sess,
|
||||
definitions: self.definitions,
|
||||
cstore: self.cstore,
|
||||
resolutions: self.resolutions,
|
||||
tcx: self.tcx,
|
||||
resolver: self.resolver,
|
||||
arena: self.arena,
|
||||
arena: self.tcx.hir_arena,
|
||||
|
||||
// HirId handling.
|
||||
bodies: Vec::new(),
|
||||
|
@ -144,12 +133,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
|
||||
let def_id = self.resolver.node_id_to_def_id[&item.id];
|
||||
|
||||
let parent_id = {
|
||||
let parent = self.definitions.def_key(def_id).parent;
|
||||
let local_def_index = parent.unwrap();
|
||||
LocalDefId { local_def_index }
|
||||
};
|
||||
|
||||
let parent_id = self.tcx.local_parent(def_id);
|
||||
let parent_hir = self.lower_node(parent_id).unwrap();
|
||||
self.with_lctx(item.id, |lctx| {
|
||||
// Evaluate with the lifetimes in `params` in-scope.
|
||||
|
@ -1278,7 +1262,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
|
||||
fn error_on_invalid_abi(&self, abi: StrLit) {
|
||||
struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
|
||||
struct_span_err!(self.tcx.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
|
||||
.span_label(abi.span, "invalid ABI")
|
||||
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
|
||||
.emit();
|
||||
|
|
|
@ -49,18 +49,15 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_errors::{struct_span_err, Applicability, Handler};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_hir::definitions::{DefPathData, Definitions};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_middle::ty::{ResolverAstLowering, ResolverOutputs};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_session::cstore::CrateStoreDyn;
|
||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
|
@ -83,19 +80,12 @@ mod item;
|
|||
mod pat;
|
||||
mod path;
|
||||
|
||||
rustc_hir::arena_types!(rustc_arena::declare_arena);
|
||||
|
||||
struct LoweringContext<'a, 'hir: 'a> {
|
||||
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
||||
sess: &'a Session,
|
||||
|
||||
definitions: &'a mut Definitions,
|
||||
cstore: &'a CrateStoreDyn,
|
||||
resolutions: &'a ResolverOutputs,
|
||||
struct LoweringContext<'a, 'hir> {
|
||||
tcx: TyCtxt<'hir>,
|
||||
resolver: &'a mut ResolverAstLowering,
|
||||
|
||||
/// Used to allocate HIR nodes.
|
||||
arena: &'hir Arena<'hir>,
|
||||
arena: &'hir hir::Arena<'hir>,
|
||||
|
||||
/// Bodies inside the owner being lowered.
|
||||
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
||||
|
@ -391,61 +381,58 @@ fn index_crate<'a>(
|
|||
/// Compute the hash for the HIR of the full crate.
|
||||
/// This hash will then be part of the crate_hash which is stored in the metadata.
|
||||
fn compute_hir_hash(
|
||||
sess: &Session,
|
||||
definitions: &Definitions,
|
||||
cstore: &CrateStoreDyn,
|
||||
resolver: &ResolverOutputs,
|
||||
tcx: TyCtxt<'_>,
|
||||
owners: &IndexVec<LocalDefId, hir::MaybeOwner<&hir::OwnerInfo<'_>>>,
|
||||
) -> Fingerprint {
|
||||
let mut hir_body_nodes: Vec<_> = owners
|
||||
.iter_enumerated()
|
||||
.filter_map(|(def_id, info)| {
|
||||
let info = info.as_owner()?;
|
||||
let def_path_hash = definitions.def_path_hash(def_id);
|
||||
let def_path_hash = tcx.hir().def_path_hash(def_id);
|
||||
Some((def_path_hash, info))
|
||||
})
|
||||
.collect();
|
||||
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
|
||||
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
let mut hcx = StableHashingContext::new(sess, definitions, cstore, &resolver.source_span);
|
||||
hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
stable_hasher.finish()
|
||||
tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
stable_hasher.finish()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lower_crate<'hir>(
|
||||
sess: &Session,
|
||||
krate: &Crate,
|
||||
definitions: &mut Definitions,
|
||||
cstore: &CrateStoreDyn,
|
||||
resolutions: &ResolverOutputs,
|
||||
mut resolver: ResolverAstLowering,
|
||||
arena: &'hir Arena<'hir>,
|
||||
) -> &'hir hir::Crate<'hir> {
|
||||
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
|
||||
pub fn lower_to_hir<'hir>(tcx: TyCtxt<'hir>, (): ()) -> hir::Crate<'hir> {
|
||||
let sess = tcx.sess;
|
||||
let krate = tcx.untracked_crate.steal();
|
||||
let mut resolver = tcx.resolver_for_lowering(()).steal();
|
||||
|
||||
let ast_index = index_crate(&resolver.node_id_to_def_id, krate);
|
||||
|
||||
let mut owners =
|
||||
IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, definitions.def_index_count());
|
||||
let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
|
||||
let mut owners = IndexVec::from_fn_n(
|
||||
|_| hir::MaybeOwner::Phantom,
|
||||
tcx.definitions_untracked().def_index_count(),
|
||||
);
|
||||
|
||||
for def_id in ast_index.indices() {
|
||||
item::ItemLowerer {
|
||||
sess,
|
||||
definitions,
|
||||
cstore,
|
||||
resolutions,
|
||||
tcx,
|
||||
resolver: &mut resolver,
|
||||
arena,
|
||||
ast_index: &ast_index,
|
||||
owners: &mut owners,
|
||||
}
|
||||
.lower_node(def_id);
|
||||
}
|
||||
|
||||
let hir_hash = compute_hir_hash(sess, definitions, cstore, resolutions, &owners);
|
||||
let krate = hir::Crate { owners, hir_hash };
|
||||
arena.alloc(krate)
|
||||
// Drop AST to free memory
|
||||
std::mem::drop(ast_index);
|
||||
sess.time("drop_ast", || std::mem::drop(krate));
|
||||
|
||||
// Discard hygiene data, which isn't required after lowering to HIR.
|
||||
if !sess.opts.debugging_opts.keep_hygiene_data {
|
||||
rustc_span::hygiene::clear_syntax_context_map();
|
||||
}
|
||||
|
||||
let hir_hash = compute_hir_hash(tcx, &owners);
|
||||
hir::Crate { owners, hir_hash }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
|
@ -464,38 +451,25 @@ enum ParenthesizedGenericArgs {
|
|||
}
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
|
||||
StableHashingContext::new(
|
||||
self.sess,
|
||||
self.definitions,
|
||||
self.cstore,
|
||||
&self.resolutions.source_span,
|
||||
)
|
||||
}
|
||||
|
||||
fn create_def(
|
||||
&mut self,
|
||||
parent: LocalDefId,
|
||||
node_id: ast::NodeId,
|
||||
data: DefPathData,
|
||||
) -> LocalDefId {
|
||||
debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
|
||||
assert!(
|
||||
self.opt_local_def_id(node_id).is_none(),
|
||||
"adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
|
||||
node_id,
|
||||
data,
|
||||
self.definitions.def_key(self.local_def_id(node_id)),
|
||||
self.tcx.hir().def_key(self.local_def_id(node_id)),
|
||||
);
|
||||
|
||||
let def_id = self.definitions.create_def(parent, data);
|
||||
let def_id = self.tcx.create_def(parent, data);
|
||||
|
||||
// Some things for which we allocate `LocalDefId`s don't correspond to
|
||||
// anything in the AST, so they don't have a `NodeId`. For these cases
|
||||
// we don't need a mapping from `NodeId` to `LocalDefId`.
|
||||
if node_id != ast::DUMMY_NODE_ID {
|
||||
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
|
||||
self.resolver.node_id_to_def_id.insert(node_id, def_id);
|
||||
}
|
||||
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
|
||||
self.resolver.node_id_to_def_id.insert(node_id, def_id);
|
||||
|
||||
def_id
|
||||
}
|
||||
|
@ -515,6 +489,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
|
||||
}
|
||||
|
||||
/// Freshen the `LoweringContext` and ready it to lower a nested item.
|
||||
/// The lowered item is registered into `self.children`.
|
||||
///
|
||||
/// This function sets up `HirId` lowering infrastructure,
|
||||
/// and stashes the shared mutable state to avoid pollution by the closure.
|
||||
#[instrument(level = "debug", skip(self, f))]
|
||||
fn with_hir_id_owner(
|
||||
&mut self,
|
||||
|
@ -533,8 +512,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
|
||||
let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
|
||||
let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
|
||||
// Do not reset `next_node_id` and `node_id_to_def_id` as we want to refer to the
|
||||
// subdefinitions' nodes.
|
||||
|
||||
// Do not reset `next_node_id` and `node_id_to_def_id`:
|
||||
// we want `f` to be able to refer to the `LocalDefId`s that the caller created.
|
||||
// and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
|
||||
|
||||
// Always allocate the first `HirId` for the owner itself.
|
||||
let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
|
||||
|
@ -578,7 +559,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
bodies.sort_by_key(|(k, _)| *k);
|
||||
let bodies = SortedMap::from_presorted_elements(bodies);
|
||||
let (hash_including_bodies, hash_without_bodies) = self.hash_owner(node, &bodies);
|
||||
let (nodes, parenting) = index::index_hir(self.sess, self.definitions, node, &bodies);
|
||||
let (nodes, parenting) =
|
||||
index::index_hir(self.tcx.sess, &*self.tcx.definitions_untracked(), node, &bodies);
|
||||
let nodes = hir::OwnerNodes {
|
||||
hash_including_bodies,
|
||||
hash_without_bodies,
|
||||
|
@ -587,10 +569,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
local_id_to_def_id,
|
||||
};
|
||||
let attrs = {
|
||||
let mut hcx = self.create_stable_hashing_context();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
attrs.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
let hash = stable_hasher.finish();
|
||||
let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
attrs.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
stable_hasher.finish()
|
||||
});
|
||||
hir::AttributeMap { map: attrs, hash }
|
||||
};
|
||||
|
||||
|
@ -604,18 +587,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
node: hir::OwnerNode<'hir>,
|
||||
bodies: &SortedMap<hir::ItemLocalId, &'hir hir::Body<'hir>>,
|
||||
) -> (Fingerprint, Fingerprint) {
|
||||
let mut hcx = self.create_stable_hashing_context();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
|
||||
node.hash_stable(hcx, &mut stable_hasher)
|
||||
});
|
||||
let hash_including_bodies = stable_hasher.finish();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
|
||||
node.hash_stable(hcx, &mut stable_hasher)
|
||||
});
|
||||
let hash_without_bodies = stable_hasher.finish();
|
||||
(hash_including_bodies, hash_without_bodies)
|
||||
self.tcx.with_stable_hashing_context(|mut hcx| {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
|
||||
node.hash_stable(hcx, &mut stable_hasher)
|
||||
});
|
||||
let hash_including_bodies = stable_hasher.finish();
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
|
||||
node.hash_stable(hcx, &mut stable_hasher)
|
||||
});
|
||||
let hash_without_bodies = stable_hasher.finish();
|
||||
(hash_including_bodies, hash_without_bodies)
|
||||
})
|
||||
}
|
||||
|
||||
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
|
||||
|
@ -656,9 +640,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generate a new `HirId` without a backing `NodeId`.
|
||||
fn next_id(&mut self) -> hir::HirId {
|
||||
let node_id = self.next_node_id();
|
||||
self.lower_node_id(node_id)
|
||||
let owner = self.current_hir_id_owner;
|
||||
let local_id = self.item_local_id_counter;
|
||||
assert_ne!(local_id, hir::ItemLocalId::new(0));
|
||||
self.item_local_id_counter.increment_by(1);
|
||||
hir::HirId { owner, local_id }
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
|
@ -691,8 +679,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.resolver.get_import_res(id).present_items()
|
||||
}
|
||||
|
||||
fn diagnostic(&self) -> &rustc_errors::Handler {
|
||||
self.sess.diagnostic()
|
||||
fn diagnostic(&self) -> &Handler {
|
||||
self.tcx.sess.diagnostic()
|
||||
}
|
||||
|
||||
/// Reuses the span but adds information like the kind of the desugaring and features that are
|
||||
|
@ -703,18 +691,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
span: Span,
|
||||
allow_internal_unstable: Option<Lrc<[Symbol]>>,
|
||||
) -> Span {
|
||||
span.mark_with_reason(
|
||||
allow_internal_unstable,
|
||||
reason,
|
||||
self.sess.edition(),
|
||||
self.create_stable_hashing_context(),
|
||||
)
|
||||
self.tcx.with_stable_hashing_context(|hcx| {
|
||||
span.mark_with_reason(allow_internal_unstable, reason, self.tcx.sess.edition(), hcx)
|
||||
})
|
||||
}
|
||||
|
||||
/// Intercept all spans entering HIR.
|
||||
/// Mark a span as relative to the current owning item.
|
||||
fn lower_span(&self, span: Span) -> Span {
|
||||
if self.sess.opts.debugging_opts.incremental_relative_spans {
|
||||
if self.tcx.sess.opts.debugging_opts.incremental_relative_spans {
|
||||
span.with_parent(Some(self.current_hir_id_owner))
|
||||
} else {
|
||||
// Do not make spans relative when not using incremental compilation.
|
||||
|
@ -1061,7 +1046,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
|
||||
let mut err = self.sess.struct_span_err(
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
data.span,
|
||||
"parenthesized generic arguments cannot be used in associated type constraints",
|
||||
);
|
||||
|
@ -1106,7 +1091,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)),
|
||||
ast::GenericArg::Type(ty) => {
|
||||
match ty.kind {
|
||||
TyKind::Infer if self.sess.features_untracked().generic_arg_infer => {
|
||||
TyKind::Infer if self.tcx.features().generic_arg_infer => {
|
||||
return GenericArg::Infer(hir::InferArg {
|
||||
hir_id: self.lower_node_id(ty.id),
|
||||
span: self.lower_span(ty.span),
|
||||
|
@ -1203,7 +1188,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
} else {
|
||||
self.next_node_id()
|
||||
};
|
||||
let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
|
||||
let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
|
||||
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
|
||||
});
|
||||
let lifetime = self.lower_lifetime(®ion);
|
||||
|
@ -1307,7 +1292,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
ImplTraitContext::Disallowed(position) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
t.span,
|
||||
E0562,
|
||||
"`impl Trait` only allowed in function and inherent method return types, not in {}",
|
||||
|
@ -1320,7 +1305,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
|
||||
TyKind::CVarArgs => {
|
||||
self.sess.delay_span_bug(
|
||||
self.tcx.sess.delay_span_bug(
|
||||
t.span,
|
||||
"`TyKind::CVarArgs` should have been handled elsewhere",
|
||||
);
|
||||
|
@ -1925,7 +1910,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
hir_id,
|
||||
name,
|
||||
span: self.lower_span(param.span()),
|
||||
pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle),
|
||||
pure_wrt_drop: self.tcx.sess.contains_name(¶m.attrs, sym::may_dangle),
|
||||
kind,
|
||||
colon_span: param.colon_span.map(|s| self.lower_span(s)),
|
||||
}
|
||||
|
@ -2067,11 +2052,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||
match c.value.kind {
|
||||
ExprKind::Underscore => {
|
||||
if self.sess.features_untracked().generic_arg_infer {
|
||||
if self.tcx.features().generic_arg_infer {
|
||||
hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
|
||||
} else {
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::generic_arg_infer,
|
||||
c.value.span,
|
||||
"using `_` for array lengths is unstable",
|
||||
|
|
|
@ -133,7 +133,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// We should've returned in the for loop above.
|
||||
|
||||
self.sess.diagnostic().span_bug(
|
||||
self.diagnostic().span_bug(
|
||||
p.span,
|
||||
&format!(
|
||||
"lower_qpath: no final extension segment in {}..{}",
|
||||
|
@ -193,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
|
||||
ParenthesizedGenericArgs::Err => {
|
||||
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
|
||||
let mut err = struct_span_err!(self.tcx.sess, data.span, E0214, "{}", msg);
|
||||
err.span_label(data.span, "only `Fn` traits may use parentheses");
|
||||
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
||||
if !data.inputs.is_empty() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue