#![feature(array_value_iter)]
#![feature(crate_visibility_modifier)]
+#![feature(marker_trait_attr)]
+#![feature(specialization)]
+#![feature(or_patterns)]
#![recursion_limit = "256"]
-use rustc::arena::Arena;
-use rustc::dep_graph::DepGraph;
-use rustc::hir::map::definitions::{DefKey, DefPathData, Definitions};
-use rustc::hir::map::Map;
-use rustc::{bug, span_bug};
use rustc_ast::ast;
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
-use rustc_hir::def_id::{DefId, DefIdMap, DefIndex, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::intravisit;
use rustc_hir::{ConstArg, GenericArg, ParamName};
use rustc_index::vec::IndexVec;
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
+rustc_hir::arena_types!(::arena::declare_arena, [], 'tcx);
+
struct LoweringContext<'a, 'hir: 'a> {
crate_root: Option<Symbol>,
/// HACK(Centril): there is a cyclic dependency between the parser and lowering
/// if we don't have this function pointer. To avoid that dependency so that
- /// librustc is independent of the parser, we use dynamic dispatch here.
+ /// librustc_middle is independent of the parser, we use dynamic dispatch here.
nt_to_tokenstream: NtToTokenstream,
/// Used to allocate HIR nodes
generator_kind: Option<hir::GeneratorKind>,
+ /// When inside an `async` context, this is the `HirId` of the
+ /// `task_context` local bound to the resume argument of the generator.
+ task_context: Option<hir::HirId>,
+
/// Used to get the current `fn`'s def span to point to when using `await`
/// outside of an `async fn`.
current_item: Option<Span>,
/// against this list to see if it is already in-scope, or if a definition
/// needs to be created for it.
///
- /// We always store a `modern()` version of the param-name in this
+ /// We always store a `normalize_to_macros_2_0()` version of the param-name in this
/// vector.
in_scope_lifetimes: Vec<ParamName>,
type_def_lifetime_params: DefIdMap<usize>,
- current_hir_id_owner: Vec<(DefIndex, u32)>,
+ current_hir_id_owner: Vec<(LocalDefId, u32)>,
item_local_id_counters: NodeMap<u32>,
- node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
+ node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
allow_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>,
pub fn lower_crate<'a, 'hir>(
sess: &'a Session,
- dep_graph: &'a DepGraph,
krate: &'a Crate,
resolver: &'a mut dyn Resolver,
nt_to_tokenstream: NtToTokenstream,
arena: &'hir Arena<'hir>,
) -> hir::Crate<'hir> {
- // We're constructing the HIR here; we don't care what we will
- // read, since we haven't even constructed the *input* to
- // incr. comp. yet.
- dep_graph.assert_ignored();
-
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
LoweringContext {
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
type_def_lifetime_params: Default::default(),
current_module: hir::CRATE_HIR_ID,
- current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
+ current_hir_id_owner: vec![(LocalDefId { local_def_index: CRATE_DEF_INDEX }, 0)],
item_local_id_counters: Default::default(),
node_id_to_hir_id: IndexVec::new(),
generator_kind: None,
+ task_context: None,
current_item: None,
lifetimes_to_define: Vec::new(),
is_collecting_in_band_lifetimes: false,
}
impl MiscCollector<'_, '_, '_> {
- fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree, owner: DefIndex) {
+ fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree, owner: LocalDefId) {
match tree.kind {
UseTreeKind::Simple(_, id1, id2) => {
for &id in &[id1, id2] {
_ => false,
})
.count();
- self.lctx.type_def_lifetime_params.insert(def_id, count);
+ self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count);
}
ItemKind::Use(ref use_tree) => {
self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
}
self.lower_node_id(CRATE_NODE_ID);
- debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
+ debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));
visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c);
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
let module = self.lower_mod(&c.module);
let attrs = self.lower_attrs(&c.attrs);
let body_ids = body_ids(&self.bodies);
- let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id]).collect();
+ let proc_macros =
+ c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
hir::Crate {
- module,
- attrs,
- span: c.span,
+ item: hir::CrateItem { module, attrs, span: c.span },
exported_macros: self.arena.alloc_from_iter(self.exported_macros),
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
items: self.items,
ast_node_id: NodeId,
alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId,
) -> hir::HirId {
- if ast_node_id == DUMMY_NODE_ID {
- return hir::DUMMY_HIR_ID;
- }
+ assert_ne!(ast_node_id, DUMMY_NODE_ID);
let min_size = ast_node_id.as_usize() + 1;
if min_size > self.node_id_to_hir_id.len() {
- self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
+ self.node_id_to_hir_id.resize(min_size, None);
}
- let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
-
- if existing_hir_id == hir::DUMMY_HIR_ID {
+ if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
+ existing_hir_id
+ } else {
// Generate a new `HirId`.
let hir_id = alloc_hir_id(self);
- self.node_id_to_hir_id[ast_node_id] = hir_id;
+ self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
hir_id
- } else {
- existing_hir_id
}
}
.item_local_id_counters
.insert(owner, HIR_ID_COUNTER_LOCKED)
.unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner));
- let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
- self.current_hir_id_owner.push((def_index, counter));
+ let def_id = self.resolver.definitions().local_def_id(owner);
+ self.current_hir_id_owner.push((def_id, counter));
let ret = f(self);
- let (new_def_index, new_counter) = self.current_hir_id_owner.pop().unwrap();
+ let (new_def_id, new_counter) = self.current_hir_id_owner.pop().unwrap();
- debug_assert!(def_index == new_def_index);
+ debug_assert!(def_id == new_def_id);
debug_assert!(new_counter >= counter);
let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
/// properly. Calling the method twice with the same `NodeId` is fine though.
fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
self.lower_node_id_generic(ast_node_id, |this| {
- let &mut (def_index, ref mut local_id_counter) =
+ let &mut (owner, ref mut local_id_counter) =
this.current_hir_id_owner.last_mut().unwrap();
let local_id = *local_id_counter;
*local_id_counter += 1;
- hir::HirId { owner: def_index, local_id: hir::ItemLocalId::from_u32(local_id) }
+ hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
})
}
debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
*local_id_counter += 1;
- let def_index = this.resolver.definitions().opt_def_index(owner).expect(
+ let owner = this.resolver.definitions().opt_local_def_id(owner).expect(
"you forgot to call `create_def_with_parent` or are lowering node-IDs \
- that do not belong to the current owner",
+ that do not belong to the current owner",
);
- hir::HirId { owner: def_index, local_id: hir::ItemLocalId::from_u32(local_id) }
+ hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
})
}
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
if pr.unresolved_segments() != 0 {
- bug!("path not fully resolved: {:?}", pr);
+ panic!("path not fully resolved: {:?}", pr);
}
pr.base_res()
})
/// parameter while `f` is running (and restored afterwards).
fn collect_in_band_defs<T>(
&mut self,
- parent_id: DefId,
+ parent_def_id: LocalDefId,
anonymous_lifetime_mode: AnonymousLifetimeMode,
f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
) -> (Vec<hir::GenericParam<'hir>>, T) {
let params = lifetimes_to_define
.into_iter()
- .map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_id.index))
+ .map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
.chain(in_band_ty_params.into_iter())
.collect();
&mut self,
span: Span,
hir_name: ParamName,
- parent_index: DefIndex,
+ parent_def_id: LocalDefId,
) -> hir::GenericParam<'hir> {
let node_id = self.resolver.next_node_id();
// Add a definition for the in-band lifetime def.
self.resolver.definitions().create_def_with_parent(
- parent_index,
+ parent_def_id,
node_id,
DefPathData::LifetimeNs(str_name),
ExpnId::root(),
return;
}
- if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.modern())) {
+ if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.normalize_to_macros_2_0())) {
return;
}
let hir_name = ParamName::Plain(ident);
- if self.lifetimes_to_define.iter().any(|(_, lt_name)| lt_name.modern() == hir_name.modern())
- {
+ if self.lifetimes_to_define.iter().any(|(_, lt_name)| {
+ lt_name.normalize_to_macros_2_0() == hir_name.normalize_to_macros_2_0()
+ }) {
return;
}
) -> T {
let old_len = self.in_scope_lifetimes.len();
let lt_def_names = params.iter().filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => Some(ParamName::Plain(param.ident.modern())),
+ GenericParamKind::Lifetime { .. } => {
+ Some(ParamName::Plain(param.ident.normalize_to_macros_2_0()))
+ }
_ => None,
});
self.in_scope_lifetimes.extend(lt_def_names);
fn add_in_band_defs<T>(
&mut self,
generics: &Generics,
- parent_id: DefId,
+ parent_def_id: LocalDefId,
anonymous_lifetime_mode: AnonymousLifetimeMode,
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
) -> (hir::Generics<'hir>, T) {
let (in_band_defs, (mut lowered_generics, res)) =
self.with_in_scope_lifetime_defs(&generics.params, |this| {
- this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
+ this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
let mut params = Vec::new();
// Note: it is necessary to lower generics *before* calling `f`.
// When lowering `async fn`, there's a final step when lowering
// constructing the HIR for `impl bounds...` and then lowering that.
let impl_trait_node_id = self.resolver.next_node_id();
- let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
+ let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
self.resolver.definitions().create_def_with_parent(
- parent_def_index,
+ parent_def_id,
impl_trait_node_id,
DefPathData::ImplTrait,
ExpnId::root(),
// Construct a AnonConst where the expr is the "ty"'s path.
- let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
+ let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
let node_id = self.resolver.next_node_id();
// Add a definition for the in-band const def.
self.resolver.definitions().create_def_with_parent(
- parent_def_index,
+ parent_def_id,
node_id,
DefPathData::AnonConst,
ExpnId::root(),
let bounds =
this.arena.alloc_from_iter(bounds.iter().filter_map(
|bound| match *bound {
- GenericBound::Trait(ref ty, TraitBoundModifier::None)
- | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
- Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
- }
+ GenericBound::Trait(
+ ref ty,
+ TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
+ ) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())),
// `?const ?Bound` will cause an error during AST validation
// anyways, so treat it like `?Bound` as compilation proceeds.
- GenericBound::Trait(_, TraitBoundModifier::Maybe)
- | GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
- None
- }
+ GenericBound::Trait(
+ _,
+ TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
+ ) => None,
GenericBound::Outlives(ref lifetime) => {
if lifetime_bound.is_none() {
lifetime_bound = Some(this.lower_lifetime(lifetime));
}
ImplTraitContext::Universal(in_band_ty_params) => {
// Add a definition for the in-band `Param`.
- let def_index =
- self.resolver.definitions().opt_def_index(def_node_id).unwrap();
+ let def_id = self.resolver.definitions().local_def_id(def_node_id);
let hir_bounds = self.lower_param_bounds(
bounds,
None,
self.arena.alloc(hir::Path {
span,
- res: Res::Def(DefKind::TyParam, DefId::local(def_index)),
+ res: Res::Def(DefKind::TyParam, def_id.to_def_id()),
segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
}),
))
}
}
}
- TyKind::Mac(_) => bug!("`TyKind::Mac` should have been expanded by now"),
+ TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
TyKind::CVarArgs => {
self.sess.delay_span_bug(
t.span,
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
- let opaque_ty_def_index =
- self.resolver.definitions().opt_def_index(opaque_ty_node_id).unwrap();
+ let opaque_ty_def_id = self.resolver.definitions().local_def_id(opaque_ty_node_id);
self.allocate_hir_id_counter(opaque_ty_node_id);
let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds);
- let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
- opaque_ty_node_id,
- opaque_ty_def_index,
- &hir_bounds,
- );
+ let (lifetimes, lifetime_defs) =
+ self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id, opaque_ty_def_id, &hir_bounds);
debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,);
origin,
};
- trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_index);
+ trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
let opaque_ty_id =
lctx.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
fn lifetimes_from_impl_trait_bounds(
&mut self,
opaque_ty_id: NodeId,
- parent_index: DefIndex,
+ parent_def_id: LocalDefId,
bounds: hir::GenericBounds<'hir>,
) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) {
debug!(
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
- parent_index={:?}, \
+ parent_def_id={:?}, \
bounds={:#?})",
- opaque_ty_id, parent_index, bounds,
+ opaque_ty_id, parent_def_id, bounds,
);
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
struct ImplTraitLifetimeCollector<'r, 'a, 'hir> {
context: &'r mut LoweringContext<'a, 'hir>,
- parent: DefIndex,
+ parent: LocalDefId,
opaque_ty_id: NodeId,
collect_elided_lifetimes: bool,
currently_bound_lifetimes: Vec<hir::LifetimeName>,
}
impl<'r, 'a, 'v, 'hir> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> {
- type Map = Map<'v>;
+ type Map = intravisit::ErasedMap<'v>;
- fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<'_, Self::Map> {
+ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
intravisit::NestedVisitorMap::None
}
hir::LifetimeName::Param(param_name) => {
(param_name, hir::LifetimeParamKind::Explicit)
}
- _ => bug!("expected `LifetimeName::Param` or `ParamName::Plain`"),
+ _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"),
};
self.output_lifetime_params.push(hir::GenericParam {
let mut lifetime_collector = ImplTraitLifetimeCollector {
context: self,
- parent: parent_index,
+ parent: parent_def_id,
opaque_ty_id,
collect_elided_lifetimes: true,
currently_bound_lifetimes: Vec::new(),
visitor.visit_ty(ty);
}
}
- let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
+ let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
let ty = l.ty.as_ref().map(|t| {
self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
- ImplTraitContext::OpaqueTy(Some(parent_def_id), hir::OpaqueTyOrigin::Misc)
+ ImplTraitContext::OpaqueTy(
+ Some(parent_def_id.to_def_id()),
+ hir::OpaqueTyOrigin::Misc,
+ )
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
c_variadic,
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
let is_mutable_pat = match arg.pat.kind {
- PatKind::Ident(BindingMode::ByValue(mt), _, _)
- | PatKind::Ident(BindingMode::ByRef(mt), _, _) => mt == Mutability::Mut,
+ PatKind::Ident(BindingMode::ByValue(mt) | BindingMode::ByRef(mt), _, _) => {
+ mt == Mutability::Mut
+ }
_ => false,
};
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
- let opaque_ty_def_index =
- self.resolver.definitions().opt_def_index(opaque_ty_node_id).unwrap();
+ let opaque_ty_def_id = self.resolver.definitions().local_def_id(opaque_ty_node_id);
self.allocate_hir_id_counter(opaque_ty_node_id);
let generic_params =
this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
- this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_index)
+ this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
}));
let opaque_ty_item = hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn,
};
- trace!("exist ty from async fn def index: {:#?}", opaque_ty_def_index);
+ trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
let opaque_ty_id =
this.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
| hir::LifetimeName::Underscore
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
- span_bug!(
+ self.sess.diagnostic().span_bug(
param.ident.span,
"object-lifetime-default should not occur here",
);
) -> hir::TraitRef<'hir> {
let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
hir::QPath::Resolved(None, path) => path,
- qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
+ qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
};
hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
}
StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)),
StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)),
StmtKind::Empty => return smallvec![],
- StmtKind::Mac(..) => panic!("shouldn't exist here"),
+ StmtKind::MacCall(..) => panic!("shouldn't exist here"),
};
smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }]
}
hir::QPath::Resolved(None, path) => {
// Turn trait object paths into `TyKind::TraitObject` instead.
match path.res {
- Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
+ Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
let principal = hir::PolyTraitRef {
bound_generic_params: &[],
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },