//! get confused if the spans from leaf AST nodes occur in multiple places
//! in the HIR, especially for multiple identifiers.
-mod expr;
-mod item;
-
use crate::arena::Arena;
use crate::dep_graph::DepGraph;
-use crate::hir::{self, ParamName};
-use crate::hir::HirVec;
-use crate::hir::map::{DefKey, DefPathData, Definitions};
+use crate::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
-use crate::hir::def::{Namespace, Res, DefKind, PartialRes, PerNS};
-use crate::hir::{GenericArg, ConstArg};
+use crate::hir::map::{DefKey, DefPathData, Definitions};
use crate::hir::ptr::P;
+use crate::hir::{self, ParamName};
+use crate::hir::{ConstArg, GenericArg};
use crate::lint;
use crate::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
use crate::middle::cstore::CrateStore;
-use crate::session::Session;
use crate::session::config::nightly_options;
+use crate::session::Session;
+use crate::util::captures::Captures;
use crate::util::common::FN_OUTPUT_NAME;
use crate::util::nodemap::{DefIdMap, NodeMap};
use errors::Applicability;
use rustc_data_structures::fx::FxHashSet;
-use rustc_index::vec::IndexVec;
use rustc_data_structures::sync::Lrc;
+use rustc_index::vec::IndexVec;
+use smallvec::SmallVec;
use std::collections::BTreeMap;
use std::mem;
-use smallvec::SmallVec;
-use syntax::attr;
use syntax::ast;
-use syntax::ptr::P as AstP;
use syntax::ast::*;
+use syntax::attr;
use syntax::errors;
use syntax::print::pprust;
-use syntax::token::{self, Nonterminal, Token};
-use syntax::tokenstream::{TokenStream, TokenTree};
+use syntax::ptr::P as AstP;
use syntax::sess::ParseSess;
-use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
+use syntax::source_map::{respan, DesugaringKind, ExpnData, ExpnKind, Spanned};
use syntax::symbol::{kw, sym, Symbol};
+use syntax::token::{self, Nonterminal, Token};
+use syntax::tokenstream::{TokenStream, TokenTree};
use syntax::visit::{self, Visitor};
use syntax_pos::hygiene::ExpnId;
use syntax_pos::Span;
use rustc_error_codes::*;
+macro_rules! arena_vec {
+ () => (
+ &[]
+ );
+ ($this:expr; $($x:expr),*) => (
+ $this.arena.alloc_from_iter(vec![$($x),*])
+ );
+}
+
+mod expr;
+mod item;
+
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
pub struct LoweringContext<'a, 'hir: 'a> {
allow_try_trait: Option<Lrc<[Symbol]>>,
allow_gen_future: Option<Lrc<[Symbol]>>,
+ allow_into_future: Option<Lrc<[Symbol]>>,
}
pub trait Resolver {
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
/// and if so, what meaning it has.
#[derive(Debug)]
-enum ImplTraitContext<'a> {
+enum ImplTraitContext<'b, 'a> {
/// Treat `impl Trait` as shorthand for a new universal generic parameter.
/// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
/// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
///
/// Newly generated parameters should be inserted into the given `Vec`.
- Universal(&'a mut Vec<hir::GenericParam>),
+ Universal(&'b mut Vec<hir::GenericParam<'a>>),
/// Treat `impl Trait` as shorthand for a new opaque type.
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
Other,
}
-impl<'a> ImplTraitContext<'a> {
+impl<'b, 'a> ImplTraitContext<'b, 'a> {
#[inline]
fn disallowed() -> Self {
ImplTraitContext::Disallowed(ImplTraitPosition::Other)
}
- fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
+ fn reborrow(&'c mut self) -> ImplTraitContext<'c, 'a> {
use self::ImplTraitContext::*;
match self {
Universal(params) => Universal(params),
in_scope_lifetimes: Vec::new(),
allow_try_trait: Some([sym::try_trait][..].into()),
allow_gen_future: Some([sym::gen_future][..].into()),
- }.lower_crate(krate)
+ allow_into_future: Some([sym::into_future][..].into()),
+ }
+ .lower_crate(krate)
}
#[derive(Copy, Clone, PartialEq)]
PassThrough,
}
-struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
+struct ImplTraitTypeIdVisitor<'a> {
+ ids: &'a mut SmallVec<[NodeId; 1]>,
+}
impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
fn visit_ty(&mut self, ty: &'a Ty) {
match ty.kind {
- | TyKind::Typeof(_)
- | TyKind::BareFn(_)
- => return,
+ TyKind::Typeof(_) | TyKind::BareFn(_) => return,
TyKind::ImplTrait(id, _) => self.ids.push(id),
- _ => {},
+ _ => {}
}
visit::walk_ty(self, ty);
}
- fn visit_path_segment(
- &mut self,
- path_span: Span,
- path_segment: &'v PathSegment,
- ) {
+ fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
if let Some(ref p) = path_segment.args {
if let GenericArgs::Parenthesized(_) = **p {
return;
}
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: DefIndex) {
match tree.kind {
UseTreeKind::Simple(_, id1, id2) => {
for &id in &[id1, id2] {
match item.kind {
AssocItemKind::Fn(_, None) => {
// Ignore patterns in trait methods without bodies
- self.with_hir_id_owner(None, |this| {
- visit::walk_trait_item(this, item)
- });
+ self.with_hir_id_owner(None, |this| visit::walk_trait_item(this, item));
}
_ => self.with_hir_id_owner(Some(item.id), |this| {
visit::walk_trait_item(this, item);
- })
+ }),
}
}
fn visit_foreign_item(&mut self, i: &'tcx ForeignItem) {
// Ignore patterns in foreign items
- self.with_hir_id_owner(None, |this| {
- visit::walk_foreign_item(this, i)
- });
+ self.with_hir_id_owner(None, |this| visit::walk_foreign_item(this, i));
}
fn visit_ty(&mut self, t: &'tcx Ty) {
match t.kind {
// Mirrors the case in visit::walk_ty
TyKind::BareFn(ref f) => {
- walk_list!(
- self,
- visit_generic_param,
- &f.generic_params
- );
+ walk_list!(self, visit_generic_param, &f.generic_params);
// Mirrors visit::walk_fn_decl
for parameter in &f.decl.inputs {
// We don't lower the ids of argument patterns
visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
let module = self.lower_mod(&c.module);
- let attrs = self.arena.alloc_from_iter(self.lower_attrs(&c.attrs).into_iter());
+ let attrs = self.lower_attrs(&c.attrs);
let body_ids = body_ids(&self.bodies);
- self.resolver
- .definitions()
- .init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
+ self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
hir::Crate {
module,
where
F: FnOnce(&mut Self) -> T,
{
- let counter = self.item_local_id_counters
+ let counter = self
+ .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();
debug_assert!(def_index == new_def_index);
debug_assert!(new_counter >= counter);
- let prev = self.item_local_id_counters
- .insert(owner, new_counter)
- .unwrap();
+ let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
ret
}
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: def_index, 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("you forgot to call `create_def_with_parent` or are lowering node-IDs \
- that do not belong to the current owner");
-
- hir::HirId {
- owner: def_index,
- local_id: hir::ItemLocalId::from_u32(local_id),
- }
+ let def_index = this.resolver.definitions().opt_def_index(owner).expect(
+ "you forgot to call `create_def_with_parent` or are lowering node-IDs \
+ that do not belong to the current owner",
+ );
+
+ hir::HirId { owner: def_index, local_id: hir::ItemLocalId::from_u32(local_id) }
})
}
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
let result = op(self);
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
- debug!("with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}",
- old_anonymous_lifetime_mode);
+ debug!(
+ "with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}",
+ old_anonymous_lifetime_mode
+ );
result
}
parent_id: DefId,
anonymous_lifetime_mode: AnonymousLifetimeMode,
f: F,
- ) -> (Vec<hir::GenericParam>, T)
+ ) -> (Vec<hir::GenericParam<'hir>>, T)
where
- F: FnOnce(&mut LoweringContext<'_, '_>) -> (Vec<hir::GenericParam>, T),
+ F: FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
{
assert!(!self.is_collecting_in_band_lifetimes);
assert!(self.lifetimes_to_define.is_empty());
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_id.index))
.chain(in_band_ty_params.into_iter())
.collect();
span: Span,
hir_name: ParamName,
parent_index: DefIndex,
- ) -> hir::GenericParam {
+ ) -> hir::GenericParam<'hir> {
let node_id = self.resolver.next_node_id();
// Get the name we'll use to make the def-path. Note
// that collisions are ok here and this shouldn't
// really show up for end-user.
let (str_name, kind) = match hir_name {
- ParamName::Plain(ident) => (
- ident.name,
- hir::LifetimeParamKind::InBand,
- ),
- ParamName::Fresh(_) => (
- kw::UnderscoreLifetime,
- hir::LifetimeParamKind::Elided,
- ),
- ParamName::Error => (
- kw::UnderscoreLifetime,
- hir::LifetimeParamKind::Error,
- ),
+ ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::InBand),
+ ParamName::Fresh(_) => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided),
+ ParamName::Error => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Error),
};
// Add a definition for the in-band lifetime def.
hir::GenericParam {
hir_id: self.lower_node_id(node_id),
name: hir_name,
- attrs: hir_vec![],
- bounds: hir_vec![],
+ attrs: &[],
+ bounds: &[],
span,
pure_wrt_drop: false,
- kind: hir::GenericParamKind::Lifetime { kind }
+ kind: hir::GenericParamKind::Lifetime { kind },
}
}
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.modern() == hir_name.modern())
+ {
return;
}
// for them.
fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T
where
- F: FnOnce(&mut LoweringContext<'_, 'hir>) -> T,
+ F: FnOnce(&mut Self) -> T,
{
let old_len = self.in_scope_lifetimes.len();
let lt_def_names = params.iter().filter_map(|param| match param.kind {
parent_id: DefId,
anonymous_lifetime_mode: AnonymousLifetimeMode,
f: F,
- ) -> (hir::Generics, T)
+ ) -> (hir::Generics<'hir>, T)
where
- F: FnOnce(&mut LoweringContext<'_, '_>, &mut Vec<hir::GenericParam>) -> T,
+ F: FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
{
- let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
- &generics.params,
- |this| {
+ 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| {
let mut params = Vec::new();
// Note: it is necessary to lower generics *before* calling `f`.
// `lifetimes_to_define`. If we swapped the order of these two,
// in-band-lifetimes introduced by generics or where-clauses
// wouldn't have been added yet.
- let generics = this.lower_generics(
- generics,
- ImplTraitContext::Universal(&mut params),
- );
+ let generics =
+ this.lower_generics_mut(generics, ImplTraitContext::Universal(&mut params));
let res = f(this, &mut params);
(params, (generics, res))
})
- },
- );
+ });
- let mut lowered_params: Vec<_> = lowered_generics
- .params
- .into_iter()
- .chain(in_band_defs)
- .collect();
+ let mut lowered_params: Vec<_> =
+ lowered_generics.params.into_iter().chain(in_band_defs).collect();
// FIXME(const_generics): the compiler doesn't always cope with
// unsorted generic parameters at the moment, so we make sure
// that they're ordered correctly here for now. (When we chain
// the `in_band_defs`, we might make the order unsorted.)
- lowered_params.sort_by_key(|param| {
- match param.kind {
- hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime,
- hir::GenericParamKind::Type { .. } => ParamKindOrd::Type,
- hir::GenericParamKind::Const { .. } => ParamKindOrd::Const,
- }
+ lowered_params.sort_by_key(|param| match param.kind {
+ hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime,
+ hir::GenericParamKind::Type { .. } => ParamKindOrd::Type,
+ hir::GenericParamKind::Const { .. } => ParamKindOrd::Const,
});
lowered_generics.params = lowered_params.into();
+ let lowered_generics = lowered_generics.into_generics(self.arena);
(lowered_generics, res)
}
fn with_dyn_type_scope<T, F>(&mut self, in_scope: bool, f: F) -> T
where
- F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+ F: FnOnce(&mut Self) -> T,
{
let was_in_dyn_type = self.is_in_dyn_type;
self.is_in_dyn_type = in_scope;
fn with_new_scopes<T, F>(&mut self, f: F) -> T
where
- F: FnOnce(&mut LoweringContext<'_, '_>) -> T,
+ F: FnOnce(&mut Self) -> T,
{
let was_in_loop_condition = self.is_in_loop_condition;
self.is_in_loop_condition = false;
}
}
- fn lower_attrs_arena(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
- self.arena.alloc_from_iter(
- attrs.iter().map(|a| self.lower_attr(a))
- )
- }
-
- fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
- attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into()
+ fn lower_attrs(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
+ self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)))
}
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
// lower attributes (we use the AST version) there is nowhere to keep
// the `HirId`s. We don't actually need HIR version of attributes anyway.
let kind = match attr.kind {
- AttrKind::Normal(ref item) => {
- AttrKind::Normal(AttrItem {
- path: item.path.clone(),
- args: self.lower_mac_args(&item.args),
- })
- }
- AttrKind::DocComment(comment) => AttrKind::DocComment(comment)
+ AttrKind::Normal(ref item) => AttrKind::Normal(AttrItem {
+ path: item.path.clone(),
+ args: self.lower_mac_args(&item.args),
+ }),
+ AttrKind::DocComment(comment) => AttrKind::DocComment(comment),
};
- Attribute {
- kind,
- id: attr.id,
- style: attr.style,
- span: attr.span,
- }
+ Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
}
fn lower_mac_args(&mut self, args: &MacArgs) -> MacArgs {
match *args {
MacArgs::Empty => MacArgs::Empty,
- MacArgs::Delimited(dspan, delim, ref tokens) =>
- MacArgs::Delimited(dspan, delim, self.lower_token_stream(tokens.clone())),
- MacArgs::Eq(eq_span, ref tokens) =>
- MacArgs::Eq(eq_span, self.lower_token_stream(tokens.clone())),
+ MacArgs::Delimited(dspan, delim, ref tokens) => {
+ MacArgs::Delimited(dspan, delim, self.lower_token_stream(tokens.clone()))
+ }
+ MacArgs::Eq(eq_span, ref tokens) => {
+ MacArgs::Eq(eq_span, self.lower_token_stream(tokens.clone()))
+ }
}
}
fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
- tokens
- .into_trees()
- .flat_map(|tree| self.lower_token_tree(tree).into_trees())
- .collect()
+ tokens.into_trees().flat_map(|tree| self.lower_token_tree(tree).into_trees()).collect()
}
fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
match tree {
TokenTree::Token(token) => self.lower_token(token),
- TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
- span,
- delim,
- self.lower_token_stream(tts),
- ).into(),
+ TokenTree::Delimited(span, delim, tts) => {
+ TokenTree::Delimited(span, delim, self.lower_token_stream(tts)).into()
+ }
}
}
fn lower_assoc_ty_constraint(
&mut self,
constraint: &AssocTyConstraint,
- itctx: ImplTraitContext<'_>,
- ) -> hir::TypeBinding {
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::TypeBinding<'hir> {
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
let kind = match constraint.kind {
- AssocTyConstraintKind::Equality { ref ty } => hir::TypeBindingKind::Equality {
- ty: self.lower_ty(ty, itctx)
- },
+ AssocTyConstraintKind::Equality { ref ty } => {
+ hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }
+ }
AssocTyConstraintKind::Bound { ref bounds } => {
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let (desugar_to_impl_trait, itctx) = match itctx {
// then to an opaque type).
//
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
- ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
- (true, ImplTraitContext::OpaqueTy(None)),
+ ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
+ (true, ImplTraitContext::OpaqueTy(None))
+ }
// We are in the parameter position, but not within a dyn type:
//
itctx,
);
- hir::TypeBindingKind::Equality {
- ty
- }
+ hir::TypeBindingKind::Equality { ty }
})
} else {
// Desugar `AssocTy: Bounds` into a type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);
- hir::TypeBindingKind::Constraint {
- bounds
- }
+ hir::TypeBindingKind::Constraint { bounds }
}
}
};
fn lower_generic_arg(
&mut self,
arg: &ast::GenericArg,
- itctx: ImplTraitContext<'_>
- ) -> hir::GenericArg {
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericArg<'hir> {
match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)),
ast::GenericArg::Type(ty) => {
// 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_index = 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.
attrs: AttrVec::new(),
};
- let ct = self.with_new_scopes(|this| {
- hir::AnonConst {
- hir_id: this.lower_node_id(node_id),
- body: this.lower_const_body(path_expr.span, Some(&path_expr)),
- }
- });
- return GenericArg::Const(ConstArg {
- value: ct,
- span: ty.span,
+ let ct = self.with_new_scopes(|this| hir::AnonConst {
+ hir_id: this.lower_node_id(node_id),
+ body: this.lower_const_body(path_expr.span, Some(&path_expr)),
});
+ return GenericArg::Const(ConstArg { value: ct, span: ty.span });
}
}
}
GenericArg::Type(self.lower_ty_direct(&ty, itctx))
}
- ast::GenericArg::Const(ct) => {
- GenericArg::Const(ConstArg {
- value: self.lower_anon_const(&ct),
- span: ct.value.span,
- })
- }
+ ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
+ value: self.lower_anon_const(&ct),
+ span: ct.value.span,
+ }),
}
}
- fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_>) -> P<hir::Ty> {
- P(self.lower_ty_direct(t, itctx))
+ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> {
+ self.arena.alloc(self.lower_ty_direct(t, itctx))
}
fn lower_path_ty(
qself: &Option<QSelf>,
path: &Path,
param_mode: ParamMode,
- itctx: ImplTraitContext<'_>
- ) -> hir::Ty {
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::Ty<'hir> {
let id = self.lower_node_id(t.id);
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
let ty = self.ty_path(id, t.span, qpath);
ty
}
- fn ty(&mut self, span: Span, kind: hir::TyKind) -> hir::Ty {
+ fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
hir::Ty { hir_id: self.next_id(), kind, span }
}
- fn ty_tup(&mut self, span: Span, tys: HirVec<hir::Ty>) -> hir::Ty {
+ fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
self.ty(span, hir::TyKind::Tup(tys))
}
- fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::Ty {
+ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> {
let kind = match t.kind {
TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => hir::TyKind::Err,
};
hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
}
- TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
- &f.generic_params,
- |this| {
- this.with_anonymous_lifetime_mode(
- AnonymousLifetimeMode::PassThrough,
- |this| {
- hir::TyKind::BareFn(P(hir::BareFnTy {
- generic_params: this.lower_generic_params(
- &f.generic_params,
- &NodeMap::default(),
- ImplTraitContext::disallowed(),
- ),
- unsafety: f.unsafety,
- abi: this.lower_extern(f.ext),
- decl: this.lower_fn_decl(&f.decl, None, false, None),
- param_names: this.lower_fn_params_to_names(&f.decl),
- }))
- },
- )
- },
- ),
+ TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| {
+ this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
+ hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
+ generic_params: this.lower_generic_params(
+ &f.generic_params,
+ &NodeMap::default(),
+ ImplTraitContext::disallowed(),
+ ),
+ unsafety: f.unsafety,
+ abi: this.lower_extern(f.ext),
+ decl: this.lower_fn_decl(&f.decl, None, false, None),
+ param_names: this.lower_fn_params_to_names(&f.decl),
+ }))
+ })
+ }),
TyKind::Never => hir::TyKind::Never,
TyKind::Tup(ref tys) => {
- hir::TyKind::Tup(tys.iter().map(|ty| {
- self.lower_ty_direct(ty, itctx.reborrow())
- }).collect())
+ hir::TyKind::Tup(self.arena.alloc_from_iter(
+ tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())),
+ ))
}
TyKind::Paren(ref ty) => {
return self.lower_ty_direct(ty, itctx);
let res = self.lower_res(res);
hir::TyKind::Path(hir::QPath::Resolved(
None,
- P(hir::Path {
+ self.arena.alloc(hir::Path {
res,
- segments: hir_vec![hir::PathSegment::from_ident(
+ segments: arena_vec![self; hir::PathSegment::from_ident(
Ident::with_dummy_span(kw::SelfUpper)
)],
span: t.span,
}),
))
- },
+ }
TyKind::Array(ref ty, ref length) => {
hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
}
- TyKind::Typeof(ref expr) => {
- hir::TyKind::Typeof(self.lower_anon_const(expr))
- }
+ TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
TyKind::TraitObject(ref bounds, kind) => {
let mut lifetime_bound = None;
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
- let bounds = bounds
- .iter()
- .filter_map(|bound| match *bound {
- GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
- Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
- }
- GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
- GenericBound::Outlives(ref lifetime) => {
- if lifetime_bound.is_none() {
- lifetime_bound = Some(this.lower_lifetime(lifetime));
+ let bounds =
+ this.arena.alloc_from_iter(bounds.iter().filter_map(
+ |bound| match *bound {
+ GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
+ Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
}
- None
- }
- })
- .collect();
+ GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+ GenericBound::Outlives(ref lifetime) => {
+ if lifetime_bound.is_none() {
+ lifetime_bound = Some(this.lower_lifetime(lifetime));
+ }
+ None
+ }
+ },
+ ));
let lifetime_bound =
lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
(bounds, lifetime_bound)
let span = t.span;
match itctx {
ImplTraitContext::OpaqueTy(fn_def_id) => {
- self.lower_opaque_impl_trait(
- span, fn_def_id, def_node_id,
- |this| this.lower_param_bounds(bounds, itctx),
- )
+ self.lower_opaque_impl_trait(span, fn_def_id, def_node_id, |this| {
+ this.lower_param_bounds(bounds, itctx)
+ })
}
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_index =
+ self.resolver.definitions().opt_def_index(def_node_id).unwrap();
let hir_bounds = self.lower_param_bounds(
bounds,
hir_id: self.lower_node_id(def_node_id),
name: ParamName::Plain(ident),
pure_wrt_drop: false,
- attrs: hir_vec![],
+ attrs: &[],
bounds: hir_bounds,
span,
kind: hir::GenericParamKind::Type {
default: None,
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
- }
+ },
});
hir::TyKind::Path(hir::QPath::Resolved(
None,
- P(hir::Path {
+ self.arena.alloc(hir::Path {
span,
res: Res::Def(DefKind::TyParam, DefId::local(def_index)),
- segments: hir_vec![hir::PathSegment::from_ident(ident)],
+ segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
}),
))
}
ImplTraitContext::Disallowed(pos) => {
- let allowed_in = if self.sess.features_untracked()
- .impl_trait_in_bindings {
+ let allowed_in = if self.sess.features_untracked().impl_trait_in_bindings {
"bindings or function and inherent method return types"
} else {
"function and inherent method return types"
"`impl Trait` not allowed outside of {}",
allowed_in,
);
- if pos == ImplTraitPosition::Binding &&
- nightly_options::is_nightly_build() {
- help!(err,
- "add `#![feature(impl_trait_in_bindings)]` to the crate \
- attributes to enable");
+ if pos == ImplTraitPosition::Binding && nightly_options::is_nightly_build()
+ {
+ help!(
+ err,
+ "add `#![feature(impl_trait_in_bindings)]` to the crate \
+ attributes to enable"
+ );
}
err.emit();
hir::TyKind::Err
}
};
- hir::Ty {
- kind,
- span: t.span,
- hir_id: self.lower_node_id(t.id),
- }
+ hir::Ty { kind, span: t.span, hir_id: self.lower_node_id(t.id) }
}
fn lower_opaque_impl_trait(
span: Span,
fn_def_id: Option<DefId>,
opaque_ty_node_id: NodeId,
- lower_bounds: impl FnOnce(&mut LoweringContext<'_, '_>) -> hir::GenericBounds,
- ) -> hir::TyKind {
+ lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
+ ) -> hir::TyKind<'hir> {
debug!(
"lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
- fn_def_id,
- opaque_ty_node_id,
- span,
+ fn_def_id, opaque_ty_node_id, span,
);
// Make sure we know that some funky desugaring has been going on here.
// desugaring that explicitly states that we don't want to track that.
// Not tracking it makes lints in rustc and clippy very fragile, as
// frequently opened issues show.
- let opaque_ty_span = self.mark_span_with_reason(
- DesugaringKind::OpaqueTy,
- span,
- None,
- );
+ 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_index =
+ self.resolver.definitions().opt_def_index(opaque_ty_node_id).unwrap();
self.allocate_hir_id_counter(opaque_ty_node_id);
&hir_bounds,
);
- debug!(
- "lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,
- );
+ debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,);
- debug!(
- "lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs,
- );
+ debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs,);
- self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
+ self.with_hir_id_owner(opaque_ty_node_id, move |lctx| {
let opaque_ty_item = hir::OpaqueTy {
generics: hir::Generics {
params: lifetime_defs,
- where_clause: hir::WhereClause {
- predicates: hir_vec![],
- span,
- },
+ where_clause: hir::WhereClause { predicates: &[], span },
span,
},
bounds: hir_bounds,
};
trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_index);
- let opaque_ty_id = lctx.generate_opaque_type(
- opaque_ty_node_id,
- opaque_ty_item,
- span,
- opaque_ty_span,
- );
+ let opaque_ty_id =
+ lctx.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, lifetimes)
fn generate_opaque_type(
&mut self,
opaque_ty_node_id: NodeId,
- opaque_ty_item: hir::OpaqueTy,
+ opaque_ty_item: hir::OpaqueTy<'hir>,
span: Span,
opaque_ty_span: Span,
) -> hir::HirId {
&mut self,
opaque_ty_id: NodeId,
parent_index: DefIndex,
- bounds: &hir::GenericBounds,
- ) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
+ bounds: hir::GenericBounds<'hir>,
+ ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) {
debug!(
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
parent_index={:?}, \
collect_elided_lifetimes: bool,
currently_bound_lifetimes: Vec<hir::LifetimeName>,
already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
- output_lifetimes: Vec<hir::GenericArg>,
- output_lifetime_params: Vec<hir::GenericParam>,
+ output_lifetimes: Vec<hir::GenericArg<'hir>>,
+ output_lifetime_params: Vec<hir::GenericParam<'hir>>,
}
- impl<'r, 'a, 'v, 'hir> hir::intravisit::Visitor<'v>
- for ImplTraitLifetimeCollector<'r, 'a, 'hir>
- {
+ impl<'r, 'a, 'v, 'hir> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> {
fn nested_visit_map<'this>(
&'this mut self,
) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
hir::intravisit::NestedVisitorMap::None
}
- fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
+ fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) {
// Don't collect elided lifetimes used inside of `Fn()` syntax.
if parameters.parenthesized {
let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
}
}
- fn visit_ty(&mut self, t: &'v hir::Ty) {
+ fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
// Don't collect elided lifetimes used inside of `fn()` syntax.
if let hir::TyKind::BareFn(_) = t.kind {
let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
fn visit_poly_trait_ref(
&mut self,
- trait_ref: &'v hir::PolyTraitRef,
+ trait_ref: &'v hir::PolyTraitRef<'v>,
modifier: hir::TraitBoundModifier,
) {
// Record the "stack height" of `for<'a>` lifetime bindings
self.currently_bound_lifetimes.truncate(old_len);
}
- fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
+ fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) {
// Record the introduction of 'a in `for<'a> ...`.
if let hir::GenericParamKind::Lifetime { .. } = param.kind {
// Introduce lifetimes one at a time so that we can handle
};
if !self.currently_bound_lifetimes.contains(&name)
- && !self.already_defined_lifetimes.contains(&name) {
+ && !self.already_defined_lifetimes.contains(&name)
+ {
self.already_defined_lifetimes.insert(name);
self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime {
def_node_id,
DefPathData::LifetimeNs(name.ident().name),
ExpnId::root(),
- lifetime.span);
+ lifetime.span,
+ );
let (name, kind) = match name {
hir::LifetimeName::Underscore => (
hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)),
hir::LifetimeParamKind::Elided,
),
- hir::LifetimeName::Param(param_name) => (
- param_name,
- hir::LifetimeParamKind::Explicit,
- ),
+ hir::LifetimeName::Param(param_name) => {
+ (param_name, hir::LifetimeParamKind::Explicit)
+ }
_ => bug!("expected `LifetimeName::Param` or `ParamName::Plain`"),
};
name,
span: lifetime.span,
pure_wrt_drop: false,
- attrs: hir_vec![],
- bounds: hir_vec![],
- kind: hir::GenericParamKind::Lifetime { kind }
+ attrs: &[],
+ bounds: &[],
+ kind: hir::GenericParamKind::Lifetime { kind },
});
}
}
hir::intravisit::walk_param_bound(&mut lifetime_collector, &bound);
}
+ let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. } =
+ lifetime_collector;
+
(
- lifetime_collector.output_lifetimes.into(),
- lifetime_collector.output_lifetime_params.into(),
+ self.arena.alloc_from_iter(output_lifetimes),
+ self.arena.alloc_from_iter(output_lifetime_params),
)
}
qself: &Option<QSelf>,
p: &Path,
param_mode: ParamMode,
- mut itctx: ImplTraitContext<'_>,
- ) -> hir::QPath {
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::QPath<'hir> {
let qself_position = qself.as_ref().map(|q| q.position);
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
- let partial_res = self.resolver
- .get_partial_res(id)
- .unwrap_or_else(|| PartialRes::new(Res::Err));
+ let partial_res =
+ self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
let proj_start = p.segments.len() - partial_res.unresolved_segments();
- let path = P(hir::Path {
+ let path = self.arena.alloc(hir::Path {
res: self.lower_res(partial_res.base_res()),
- segments: p.segments[..proj_start]
- .iter()
- .enumerate()
- .map(|(i, segment)| {
+ segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(
+ |(i, segment)| {
let param_mode = match (qself_position, param_mode) {
(Some(j), ParamMode::Optional) if i < j => {
// This segment is part of the trait path in a
| Res::Def(DefKind::Union, def_id)
| Res::Def(DefKind::Enum, def_id)
| Res::Def(DefKind::TyAlias, def_id)
- | Res::Def(DefKind::Trait, def_id) if i + 1 == proj_start =>
+ | Res::Def(DefKind::Trait, def_id)
+ if i + 1 == proj_start =>
{
Some(def_id)
}
ParenthesizedGenericArgs::Ok
}
// `a::b::Trait(Args)::TraitItem`
- Res::Def(DefKind::Method, _) |
- Res::Def(DefKind::AssocConst, _) |
- Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => {
+ Res::Def(DefKind::Method, _)
+ | Res::Def(DefKind::AssocConst, _)
+ | Res::Def(DefKind::AssocTy, _)
+ if i + 2 == proj_start =>
+ {
ParenthesizedGenericArgs::Ok
}
// Avoid duplicated errors.
return n;
}
assert!(!def_id.is_local());
- let item_generics = self.resolver.cstore()
+ let item_generics = self
+ .resolver
+ .cstore()
.item_generics_cloned_untracked(def_id, self.sess);
let n = item_generics.own_counts().lifetimes;
self.type_def_lifetime_params.insert(def_id, n);
itctx.reborrow(),
None,
)
- })
- .collect(),
+ },
+ )),
span: p.span,
});
// e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
// `<I as Iterator>::Item::default`.
let new_id = self.next_id();
- P(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
+ self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
};
// Anything after the base path are associated "extensions",
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
- let segment = P(self.lower_path_segment(
+ let segment = self.arena.alloc(self.lower_path_segment(
p.span,
segment,
param_mode,
// Wrap the associated extension in another type node.
let new_id = self.next_id();
- ty = P(self.ty_path(new_id, p.span, qpath));
+ ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath));
}
// We should've returned in the for loop above.
p: &Path,
param_mode: ParamMode,
explicit_owner: Option<NodeId>,
- ) -> hir::Path {
+ ) -> hir::Path<'hir> {
hir::Path {
res,
- segments: p.segments
- .iter()
- .map(|segment| {
- self.lower_path_segment(
- p.span,
- segment,
- param_mode,
- 0,
- ParenthesizedGenericArgs::Err,
- ImplTraitContext::disallowed(),
- explicit_owner,
- )
- })
- .collect(),
+ segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
+ self.lower_path_segment(
+ p.span,
+ segment,
+ param_mode,
+ 0,
+ ParenthesizedGenericArgs::Err,
+ ImplTraitContext::disallowed(),
+ explicit_owner,
+ )
+ })),
span: p.span,
}
}
- fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
+ fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path<'hir> {
let res = self.expect_full_res(id);
let res = self.lower_res(res);
self.lower_path_extra(res, p, param_mode, None)
param_mode: ParamMode,
expected_lifetimes: usize,
parenthesized_generic_args: ParenthesizedGenericArgs,
- itctx: ImplTraitContext<'_>,
+ itctx: ImplTraitContext<'_, 'hir>,
explicit_owner: Option<NodeId>,
- ) -> hir::PathSegment {
+ ) -> hir::PathSegment<'hir> {
let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
let msg = "parenthesized type parameters may only be used with a `Fn` trait";
match **generic_args {
if data.inputs.len() > 0 {
if let Some(split) = snippet.find('(') {
let trait_name = &snippet[0..split];
- let args = &snippet[split + 1 .. snippet.len() - 1];
+ let args = &snippet[split + 1..snippet.len() - 1];
err.span_suggestion(
data.span,
"use angle brackets instead",
self.lower_angle_bracketed_parameter_data(
&data.as_angle_bracketed_args(),
param_mode,
- itctx
- ).0,
+ itctx,
+ )
+ .0,
false,
)
}
GenericArg::Lifetime(_) => true,
_ => false,
});
- let first_generic_span = generic_args.args.iter().map(|a| a.span())
- .chain(generic_args.bindings.iter().map(|b| b.span)).next();
+ let first_generic_span = generic_args
+ .args
+ .iter()
+ .map(|a| a.span())
+ .chain(generic_args.bindings.iter().map(|b| b.span))
+ .next();
if !generic_args.parenthesized && !has_lifetimes {
- generic_args.args =
- self.elided_path_lifetimes(path_span, expected_lifetimes)
- .into_iter()
- .map(|lt| GenericArg::Lifetime(lt))
- .chain(generic_args.args.into_iter())
+ generic_args.args = self
+ .elided_path_lifetimes(path_span, expected_lifetimes)
+ .into_iter()
+ .map(|lt| GenericArg::Lifetime(lt))
+ .chain(generic_args.args.into_iter())
.collect();
if expected_lifetimes > 0 && param_mode == ParamMode::Explicit {
let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", ");
);
err.emit();
}
- AnonymousLifetimeMode::PassThrough |
- AnonymousLifetimeMode::ReportError => {
+ AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
ELIDED_LIFETIMES_IN_PATHS,
CRATE_NODE_ID,
incl_angl_brckt,
insertion_sp,
suggestion,
- )
+ ),
);
}
}
segment.ident, segment.id, id,
);
- hir::PathSegment::new(
- segment.ident,
- Some(id),
- Some(self.lower_res(res)),
- generic_args,
+ hir::PathSegment {
+ ident: segment.ident,
+ hir_id: Some(id),
+ res: Some(self.lower_res(res)),
infer_args,
- )
+ args: if generic_args.is_empty() {
+ None
+ } else {
+ Some(self.arena.alloc(generic_args.into_generic_args(self.arena)))
+ },
+ }
}
fn lower_angle_bracketed_parameter_data(
&mut self,
data: &AngleBracketedArgs,
param_mode: ParamMode,
- mut itctx: ImplTraitContext<'_>,
- ) -> (hir::GenericArgs, bool) {
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> (GenericArgsCtor<'hir>, bool) {
let &AngleBracketedArgs { ref args, ref constraints, .. } = data;
let has_non_lt_args = args.iter().any(|arg| match arg {
ast::GenericArg::Lifetime(_) => false,
ast::GenericArg::Const(_) => true,
});
(
- hir::GenericArgs {
+ GenericArgsCtor {
args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
- bindings: constraints.iter()
- .map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow()))
- .collect(),
+ bindings: self.arena.alloc_from_iter(
+ constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())),
+ ),
parenthesized: false,
},
- !has_non_lt_args && param_mode == ParamMode::Optional
+ !has_non_lt_args && param_mode == ParamMode::Optional,
)
}
fn lower_parenthesized_parameter_data(
&mut self,
data: &ParenthesizedArgs,
- ) -> (hir::GenericArgs, bool) {
+ ) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this
// means that we permit things like `&Ref<T>`, where `Ref` has
// a hidden lifetime parameter. This is needed for backwards
// compatibility, even in contexts like an impl header where
// we generally don't permit such things (see #51008).
- self.with_anonymous_lifetime_mode(
- AnonymousLifetimeMode::PassThrough,
- |this| {
- let &ParenthesizedArgs { ref inputs, ref output, span } = data;
- let inputs = inputs
- .iter()
- .map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
- .collect();
- let output_ty = match output {
- FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
- FunctionRetTy::Default(_) => P(this.ty_tup(span, hir::HirVec::new())),
- };
- let args = hir_vec![GenericArg::Type(this.ty_tup(span, inputs))];
- let binding = hir::TypeBinding {
- hir_id: this.next_id(),
- ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
- span: output_ty.span,
- kind: hir::TypeBindingKind::Equality { ty: output_ty },
- };
- (
- hir::GenericArgs { args, bindings: hir_vec![binding], parenthesized: true },
- false,
- )
- }
- )
+ self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
+ let &ParenthesizedArgs { ref inputs, ref output, span } = data;
+ let inputs = this.arena.alloc_from_iter(
+ inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
+ );
+ let output_ty = match output {
+ FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
+ FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
+ };
+ let args = vec![GenericArg::Type(this.ty_tup(span, inputs))];
+ let binding = hir::TypeBinding {
+ hir_id: this.next_id(),
+ ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
+ span: output_ty.span,
+ kind: hir::TypeBindingKind::Equality { ty: output_ty },
+ };
+ (
+ GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true },
+ false,
+ )
+ })
}
- fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
+ fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) {
let mut ids = SmallVec::<[NodeId; 1]>::new();
if self.sess.features_untracked().impl_trait_in_bindings {
if let Some(ref ty) = l.ty {
}
}
let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
- (hir::Local {
- hir_id: self.lower_node_id(l.id),
- 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))
- } else {
- ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
- }
- )),
- pat: self.lower_pat(&l.pat),
- init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
- span: l.span,
- attrs: l.attrs.clone(),
- source: hir::LocalSource::Normal,
- }, ids)
+ 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))
+ } else {
+ ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
+ },
+ )
+ });
+ let init = l.init.as_ref().map(|e| self.lower_expr(e));
+ (
+ hir::Local {
+ hir_id: self.lower_node_id(l.id),
+ ty,
+ pat: self.lower_pat(&l.pat),
+ init,
+ span: l.span,
+ attrs: l.attrs.clone(),
+ source: hir::LocalSource::Normal,
+ },
+ ids,
+ )
}
- fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
+ fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
// Skip the `...` (`CVarArgs`) trailing arguments from the AST,
// as they are not explicit in HIR/Ty function signatures.
// (instead, the `c_variadic` flag is set to `true`)
if decl.c_variadic() {
inputs = &inputs[..inputs.len() - 1];
}
- inputs
- .iter()
- .map(|param| match param.pat.kind {
- PatKind::Ident(_, ident, _) => ident,
- _ => Ident::new(kw::Invalid, param.pat.span),
- })
- .collect()
+ self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
+ PatKind::Ident(_, ident, _) => ident,
+ _ => Ident::new(kw::Invalid, param.pat.span),
+ }))
}
// Lowers a function declaration.
fn lower_fn_decl(
&mut self,
decl: &FnDecl,
- mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam>)>,
+ mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
impl_trait_return_allow: bool,
make_ret_async: Option<NodeId>,
- ) -> P<hir::FnDecl> {
- debug!("lower_fn_decl(\
+ ) -> &'hir hir::FnDecl<'hir> {
+ debug!(
+ "lower_fn_decl(\
fn_decl: {:?}, \
in_band_ty_params: {:?}, \
impl_trait_return_allow: {}, \
make_ret_async: {:?})",
- decl,
- in_band_ty_params,
- impl_trait_return_allow,
- make_ret_async,
+ decl, in_band_ty_params, impl_trait_return_allow, make_ret_async,
);
let lt_mode = if make_ret_async.is_some() {
// In `async fn`, argument-position elided lifetimes
if c_variadic {
inputs = &inputs[..inputs.len() - 1];
}
- inputs
- .iter()
- .map(|param| {
- if let Some((_, ibty)) = &mut in_band_ty_params {
- this.lower_ty_direct(¶m.ty, ImplTraitContext::Universal(ibty))
- } else {
- this.lower_ty_direct(¶m.ty, ImplTraitContext::disallowed())
- }
- })
- .collect::<HirVec<_>>()
+ this.arena.alloc_from_iter(inputs.iter().map(|param| {
+ if let Some((_, ibty)) = &mut in_band_ty_params {
+ this.lower_ty_direct(¶m.ty, ImplTraitContext::Universal(ibty))
+ } else {
+ this.lower_ty_direct(¶m.ty, ImplTraitContext::disallowed())
+ }
+ }))
});
let output = if let Some(ret_id) = make_ret_async {
Some((def_id, _)) if impl_trait_return_allow => {
hir::Return(self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(def_id))))
}
- _ => {
- hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
- }
+ _ => hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed())),
},
FunctionRetTy::Default(span) => hir::DefaultReturn(span),
}
};
- P(hir::FnDecl {
+ self.arena.alloc(hir::FnDecl {
inputs,
output,
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,
- _ => false,
- };
+ 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,
+ _ => false,
+ };
- match arg.ty.kind {
- TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
- TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
- // Given we are only considering `ImplicitSelf` types, we needn't consider
- // the case where we have a mutable pattern to a reference as that would
- // no longer be an `ImplicitSelf`.
- TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() &&
- mt.mutbl == ast::Mutability::Mut =>
- hir::ImplicitSelfKind::MutRef,
- TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() =>
- hir::ImplicitSelfKind::ImmRef,
- _ => hir::ImplicitSelfKind::None,
+ match arg.ty.kind {
+ TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
+ TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
+ // Given we are only considering `ImplicitSelf` types, we needn't consider
+ // the case where we have a mutable pattern to a reference as that would
+ // no longer be an `ImplicitSelf`.
+ TyKind::Rptr(_, ref mt)
+ if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
+ {
+ hir::ImplicitSelfKind::MutRef
}
- },
- ),
+ TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
+ hir::ImplicitSelfKind::ImmRef
+ }
+ _ => hir::ImplicitSelfKind::None,
+ }
+ }),
})
}
output: &FunctionRetTy,
fn_def_id: DefId,
opaque_ty_node_id: NodeId,
- ) -> hir::FunctionRetTy {
+ ) -> hir::FunctionRetTy<'hir> {
debug!(
"lower_async_fn_ret_ty(\
output={:?}, \
let span = output.span();
- let opaque_ty_span = self.mark_span_with_reason(
- DesugaringKind::Async,
- span,
- None,
- );
+ 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_index =
+ self.resolver.definitions().opt_def_index(opaque_ty_node_id).unwrap();
self.allocate_hir_id_counter(opaque_ty_node_id);
//
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
// hence the elision takes place at the fn site.
- let future_bound = this.with_anonymous_lifetime_mode(
- AnonymousLifetimeMode::CreateParameter,
- |this| this.lower_async_fn_output_type_to_future_bound(
- output,
- fn_def_id,
- span,
- ),
- );
+ let future_bound = this
+ .with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
+ this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
+ });
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
//
// Note: this must be done after lowering the output type,
// as the output type may introduce new in-band lifetimes.
- let lifetime_params: Vec<(Span, ParamName)> =
- this.in_scope_lifetimes
- .iter().cloned()
- .map(|name| (name.ident().span, name))
- .chain(this.lifetimes_to_define.iter().cloned())
- .collect();
+ let lifetime_params: Vec<(Span, ParamName)> = this
+ .in_scope_lifetimes
+ .iter()
+ .cloned()
+ .map(|name| (name.ident().span, name))
+ .chain(this.lifetimes_to_define.iter().cloned())
+ .collect();
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
let generic_params =
- lifetime_params
- .iter().cloned()
- .map(|(span, hir_name)| {
- this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_index)
- })
- .collect();
+ this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
+ this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_index)
+ }));
let opaque_ty_item = hir::OpaqueTy {
generics: hir::Generics {
params: generic_params,
- where_clause: hir::WhereClause {
- predicates: hir_vec![],
- span,
- },
+ where_clause: hir::WhereClause { predicates: &[], span },
span,
},
- bounds: hir_vec![future_bound],
+ bounds: arena_vec![this; future_bound],
impl_trait_fn: Some(fn_def_id),
origin: hir::OpaqueTyOrigin::AsyncFn,
};
trace!("exist ty from async fn def index: {:#?}", opaque_ty_def_index);
- let opaque_ty_id = this.generate_opaque_type(
- opaque_ty_node_id,
- opaque_ty_item,
- span,
- opaque_ty_span,
- );
+ let opaque_ty_id =
+ this.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span);
(opaque_ty_id, lifetime_params)
});
//
// For the "output" lifetime parameters, we just want to
// generate `'_`.
- let mut generic_args: Vec<_> =
- lifetime_params[..input_lifetimes_count]
+ let mut generic_args: Vec<_> = lifetime_params[..input_lifetimes_count]
.iter()
.map(|&(span, hir_name)| {
// Input lifetime like `'a` or `'1`:
})
})
.collect();
- generic_args.extend(
- lifetime_params[input_lifetimes_count..]
- .iter()
- .map(|&(span, _)| {
- // Output lifetime like `'_`.
- GenericArg::Lifetime(hir::Lifetime {
- hir_id: self.next_id(),
- span,
- name: hir::LifetimeName::Implicit,
- })
- })
- );
+ generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
+ // Output lifetime like `'_`.
+ GenericArg::Lifetime(hir::Lifetime {
+ hir_id: self.next_id(),
+ span,
+ name: hir::LifetimeName::Implicit,
+ })));
+ let generic_args = self.arena.alloc_from_iter(generic_args);
// Create the `Foo<...>` reference itself. Note that the `type
// Foo = impl Trait` is, internally, created as a child of the
// async fn, so the *type parameters* are inherited. It's
// only the lifetime parameters that we must supply.
- let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args.into());
+ let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args);
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
- hir::FunctionRetTy::Return(P(opaque_ty))
+ hir::FunctionRetTy::Return(self.arena.alloc(opaque_ty))
}
/// Transforms `-> T` into `Future<Output = T>`
output: &FunctionRetTy,
fn_def_id: DefId,
span: Span,
- ) -> hir::GenericBound {
+ ) -> hir::GenericBound<'hir> {
// Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output {
FunctionRetTy::Ty(ty) => self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(fn_def_id))),
- FunctionRetTy::Default(ret_ty_span) => P(self.ty_tup(*ret_ty_span, hir_vec![])),
+ FunctionRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
};
// "<Output = T>"
- let future_params = P(hir::GenericArgs {
- args: hir_vec![],
- bindings: hir_vec![hir::TypeBinding {
+ let future_params = self.arena.alloc(hir::GenericArgs {
+ args: &[],
+ bindings: arena_vec![self; hir::TypeBinding {
ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
- kind: hir::TypeBindingKind::Equality {
- ty: output_ty,
- },
+ kind: hir::TypeBindingKind::Equality { ty: output_ty },
hir_id: self.next_id(),
span,
}],
});
// ::std::future::Future<future_params>
- let future_path =
- P(self.std_path(span, &[sym::future, sym::Future], Some(future_params), false));
+ let future_path = self.arena.alloc(self.std_path(
+ span,
+ &[sym::future, sym::Future],
+ Some(future_params),
+ false,
+ ));
hir::GenericBound::Trait(
hir::PolyTraitRef {
- trait_ref: hir::TraitRef {
- path: future_path,
- hir_ref_id: self.next_id(),
- },
- bound_generic_params: hir_vec![],
+ trait_ref: hir::TraitRef { path: future_path, hir_ref_id: self.next_id() },
+ bound_generic_params: &[],
span,
},
hir::TraitBoundModifier::None,
fn lower_param_bound(
&mut self,
tpb: &GenericBound,
- itctx: ImplTraitContext<'_>,
- ) -> hir::GenericBound {
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericBound<'hir> {
match *tpb {
- GenericBound::Trait(ref ty, modifier) => {
- hir::GenericBound::Trait(
- self.lower_poly_trait_ref(ty, itctx),
- self.lower_trait_bound_modifier(modifier),
- )
- }
+ GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
+ self.lower_poly_trait_ref(ty, itctx),
+ self.lower_trait_bound_modifier(modifier),
+ ),
GenericBound::Outlives(ref lifetime) => {
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
}
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
let span = l.ident.span;
match l.ident {
- ident if ident.name == kw::StaticLifetime =>
- self.new_named_lifetime(l.id, span, hir::LifetimeName::Static),
- ident if ident.name == kw::UnderscoreLifetime =>
- match self.anonymous_lifetime_mode {
- AnonymousLifetimeMode::CreateParameter => {
- let fresh_name = self.collect_fresh_in_band_lifetime(span);
- self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
- }
+ ident if ident.name == kw::StaticLifetime => {
+ self.new_named_lifetime(l.id, span, hir::LifetimeName::Static)
+ }
+ ident if ident.name == kw::UnderscoreLifetime => match self.anonymous_lifetime_mode {
+ AnonymousLifetimeMode::CreateParameter => {
+ let fresh_name = self.collect_fresh_in_band_lifetime(span);
+ self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
+ }
- AnonymousLifetimeMode::PassThrough => {
- self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
- }
+ AnonymousLifetimeMode::PassThrough => {
+ self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
+ }
- AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
- },
+ AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
+ },
ident => {
self.maybe_collect_in_band_lifetime(ident);
let param_name = ParamName::Plain(ident);
span: Span,
name: hir::LifetimeName,
) -> hir::Lifetime {
- hir::Lifetime {
- hir_id: self.lower_node_id(id),
- span,
- name,
- }
+ hir::Lifetime { hir_id: self.lower_node_id(id), span, name }
+ }
+
+ fn lower_generic_params_mut(
+ &mut self,
+ params: &[GenericParam],
+ add_bounds: &NodeMap<Vec<GenericBound>>,
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> Vec<hir::GenericParam<'hir>> {
+ params
+ .iter()
+ .map(|param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
+ .collect()
}
fn lower_generic_params(
&mut self,
params: &[GenericParam],
add_bounds: &NodeMap<Vec<GenericBound>>,
- mut itctx: ImplTraitContext<'_>,
- ) -> hir::HirVec<hir::GenericParam> {
- params.iter().map(|param| {
- self.lower_generic_param(param, add_bounds, itctx.reborrow())
- }).collect()
- }
-
- fn lower_generic_param(&mut self,
- param: &GenericParam,
- add_bounds: &NodeMap<Vec<GenericBound>>,
- mut itctx: ImplTraitContext<'_>)
- -> hir::GenericParam {
- let mut bounds = self.with_anonymous_lifetime_mode(
- AnonymousLifetimeMode::ReportError,
- |this| this.lower_param_bounds(¶m.bounds, itctx.reborrow()),
- );
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> &'hir [hir::GenericParam<'hir>] {
+ self.arena.alloc_from_iter(self.lower_generic_params_mut(params, add_bounds, itctx))
+ }
+
+ fn lower_generic_param(
+ &mut self,
+ param: &GenericParam,
+ add_bounds: &NodeMap<Vec<GenericBound>>,
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericParam<'hir> {
+ let mut bounds: Vec<_> = self
+ .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
+ this.lower_param_bounds_mut(¶m.bounds, itctx.reborrow()).collect()
+ });
let (name, kind) = match param.kind {
GenericParamKind::Lifetime => {
let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
self.is_collecting_in_band_lifetimes = false;
- let lt = self.with_anonymous_lifetime_mode(
- AnonymousLifetimeMode::ReportError,
- |this| this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }),
- );
+ let lt = self
+ .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
+ this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident })
+ });
let param_name = match lt.name {
hir::LifetimeName::Param(param_name) => param_name,
hir::LifetimeName::Implicit
- | hir::LifetimeName::Underscore
- | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
+ | hir::LifetimeName::Underscore
+ | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
span_bug!(
param.ident.span,
hir::LifetimeName::Error => ParamName::Error,
};
- let kind = hir::GenericParamKind::Lifetime {
- kind: hir::LifetimeParamKind::Explicit
- };
+ let kind =
+ hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
self.is_collecting_in_band_lifetimes = was_collecting_in_band;
GenericParamKind::Type { ref default, .. } => {
let add_bounds = add_bounds.get(¶m.id).map_or(&[][..], |x| &x);
if !add_bounds.is_empty() {
- let params = self.lower_param_bounds(add_bounds, itctx.reborrow()).into_iter();
- bounds = bounds.into_iter()
- .chain(params)
- .collect();
+ let params = self.lower_param_bounds_mut(add_bounds, itctx.reborrow());
+ bounds.extend(params);
}
let kind = hir::GenericParamKind::Type {
- default: default.as_ref().map(|x| {
- self.lower_ty(x, ImplTraitContext::OpaqueTy(None))
- }),
- synthetic: param.attrs.iter()
- .filter(|attr| attr.check_name(sym::rustc_synthetic))
- .map(|_| hir::SyntheticTyParamKind::ImplTrait)
- .next(),
+ default: default
+ .as_ref()
+ .map(|x| self.lower_ty(x, ImplTraitContext::OpaqueTy(None))),
+ synthetic: param
+ .attrs
+ .iter()
+ .filter(|attr| attr.check_name(sym::rustc_synthetic))
+ .map(|_| hir::SyntheticTyParamKind::ImplTrait)
+ .next(),
};
(hir::ParamName::Plain(param.ident), kind)
}
- GenericParamKind::Const { ref ty } => {
- (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const {
+ GenericParamKind::Const { ref ty } => (
+ hir::ParamName::Plain(param.ident),
+ hir::GenericParamKind::Const {
ty: self.lower_ty(&ty, ImplTraitContext::disallowed()),
- })
- }
+ },
+ ),
};
hir::GenericParam {
span: param.ident.span,
pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
attrs: self.lower_attrs(¶m.attrs),
- bounds,
+ bounds: self.arena.alloc_from_iter(bounds),
kind,
}
}
- fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir::TraitRef {
+ fn lower_trait_ref(
+ &mut self,
+ p: &TraitRef,
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> 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),
};
- hir::TraitRef {
- path,
- hir_ref_id: self.lower_node_id(p.ref_id),
- }
+ hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
}
fn lower_poly_trait_ref(
&mut self,
p: &PolyTraitRef,
- mut itctx: ImplTraitContext<'_>,
- ) -> hir::PolyTraitRef {
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::PolyTraitRef<'hir> {
let bound_generic_params = self.lower_generic_params(
&p.bound_generic_params,
&NodeMap::default(),
itctx.reborrow(),
);
- let trait_ref = self.with_in_scope_lifetime_defs(
- &p.bound_generic_params,
- |this| this.lower_trait_ref(&p.trait_ref, itctx),
- );
+ let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| {
+ this.lower_trait_ref(&p.trait_ref, itctx)
+ });
- hir::PolyTraitRef {
- bound_generic_params,
- trait_ref,
- span: p.span,
- }
+ hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
}
- fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_>) -> hir::MutTy {
- hir::MutTy {
- ty: self.lower_ty(&mt.ty, itctx),
- mutbl: mt.mutbl,
- }
+ fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> {
+ hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
+ }
+
+ fn lower_param_bounds(
+ &mut self,
+ bounds: &[GenericBound],
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericBounds<'hir> {
+ self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
}
- fn lower_param_bounds(&mut self, bounds: &[GenericBound], mut itctx: ImplTraitContext<'_>)
- -> hir::GenericBounds {
- bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
+ fn lower_param_bounds_mut<'s>(
+ &'s mut self,
+ bounds: &'s [GenericBound],
+ mut itctx: ImplTraitContext<'s, 'hir>,
+ ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
+ bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow()))
}
- fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
+ fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> &'hir hir::Block<'hir> {
+ self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break))
+ }
+
+ fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> {
let mut stmts = vec![];
- let mut expr = None;
+ let mut expr: Option<&'hir _> = None;
for (index, stmt) in b.stmts.iter().enumerate() {
if index == b.stmts.len() - 1 {
if let StmtKind::Expr(ref e) = stmt.kind {
- expr = Some(P(self.lower_expr(e)));
+ expr = Some(self.lower_expr(e));
} else {
stmts.extend(self.lower_stmt(stmt));
}
}
}
- P(hir::Block {
+ hir::Block {
hir_id: self.lower_node_id(b.id),
- stmts: stmts.into(),
+ stmts: self.arena.alloc_from_iter(stmts),
expr,
rules: self.lower_block_check_mode(&b.rules),
span: b.span,
targeted_by_break,
- })
+ }
}
/// Lowers a block directly to an expression, presuming that it
/// has no attributes and is not targeted by a `break`.
- fn lower_block_expr(&mut self, b: &Block) -> hir::Expr {
+ fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
let block = self.lower_block(b, false);
self.expr_block(block, AttrVec::new())
}
- fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
+ fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
let node = match p.kind {
PatKind::Wild => hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, ident, ref sub) => {
let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
node
}
- PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
+ PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
PatKind::TupleStruct(ref path, ref pats) => {
let qpath = self.lower_qpath(
p.id,
hir::PatKind::TupleStruct(qpath, pats, ddpos)
}
PatKind::Or(ref pats) => {
- hir::PatKind::Or(pats.iter().map(|x| self.lower_pat(x)).collect())
+ hir::PatKind::Or(self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))))
}
PatKind::Path(ref qself, ref path) => {
let qpath = self.lower_qpath(
ImplTraitContext::disallowed(),
);
- let fs = fields
- .iter()
- .map(|f| hir::FieldPat {
- hir_id: self.next_id(),
- ident: f.ident,
- pat: self.lower_pat(&f.pat),
- is_shorthand: f.is_shorthand,
- span: f.span,
- })
- .collect();
+ let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
+ hir_id: self.next_id(),
+ ident: f.ident,
+ pat: self.lower_pat(&f.pat),
+ is_shorthand: f.is_shorthand,
+ span: f.span,
+ }));
hir::PatKind::Struct(qpath, fs, etc)
}
PatKind::Tuple(ref pats) => {
hir::PatKind::Tuple(pats, ddpos)
}
PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
- PatKind::Ref(ref inner, mutbl) => {
- hir::PatKind::Ref(self.lower_pat(inner), mutbl)
- }
+ PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl),
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
- P(self.lower_expr(e1)),
- P(self.lower_expr(e2)),
+ self.lower_expr(e1),
+ self.lower_expr(e2),
self.lower_range_end(end),
),
PatKind::Slice(ref pats) => self.lower_pat_slice(pats),
&mut self,
pats: &[AstP<Pat>],
ctx: &str,
- ) -> (HirVec<P<hir::Pat>>, Option<usize>) {
+ ) -> (&'hir [&'hir hir::Pat<'hir>], Option<usize>) {
let mut elems = Vec::with_capacity(pats.len());
let mut rest = None;
}
}
- (elems.into(), rest.map(|(ddpos, _)| ddpos))
+ (self.arena.alloc_from_iter(elems), rest.map(|(ddpos, _)| ddpos))
}
/// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
/// When encountering `($binding_mode $ident @)? ..` (`slice`),
/// this is interpreted as a sub-slice pattern semantically.
/// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
- fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind {
+ fn lower_pat_slice(&mut self, pats: &[AstP<Pat>]) -> hir::PatKind<'hir> {
let mut before = Vec::new();
let mut after = Vec::new();
let mut slice = None;
prev_rest_span = Some(pat.span);
slice = Some(self.pat_wild_with_node_id_of(pat));
break;
- },
+ }
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
let node = self.lower_pat_ident(pat, bm, ident, lower_sub);
slice = Some(self.pat_with_node_id_of(pat, node));
break;
- },
+ }
// It was not a subslice pattern so lower it normally.
_ => before.push(self.lower_pat(pat)),
}
// The `HirValidator` is merciless; add a `_` pattern to avoid ICEs.
after.push(self.pat_wild_with_node_id_of(pat));
Some(sub.span)
- },
+ }
_ => None,
};
if let Some(rest_span) = rest_span {
}
}
- hir::PatKind::Slice(before.into(), slice, after.into())
+ hir::PatKind::Slice(
+ self.arena.alloc_from_iter(before),
+ slice,
+ self.arena.alloc_from_iter(after),
+ )
}
fn lower_pat_ident(
p: &Pat,
binding_mode: &BindingMode,
ident: Ident,
- lower_sub: impl FnOnce(&mut Self) -> Option<P<hir::Pat>>,
- ) -> hir::PatKind {
+ lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
+ ) -> hir::PatKind<'hir> {
match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
// `None` can occur in body-less function signatures
res @ None | res @ Some(Res::Local(_)) => {
}
Some(res) => hir::PatKind::Path(hir::QPath::Resolved(
None,
- P(hir::Path {
+ self.arena.alloc(hir::Path {
span: ident.span,
res: self.lower_res(res),
- segments: hir_vec![hir::PathSegment::from_ident(ident)],
+ segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
}),
)),
}
}
- fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> P<hir::Pat> {
+ fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
self.pat_with_node_id_of(p, hir::PatKind::Wild)
}
/// Construct a `Pat` with the `HirId` of `p.id` lowered.
- fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind) -> P<hir::Pat> {
- P(hir::Pat {
- hir_id: self.lower_node_id(p.id),
- kind,
- span: p.span,
- })
+ fn pat_with_node_id_of(&mut self, p: &Pat, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
+ self.arena.alloc(hir::Pat { hir_id: self.lower_node_id(p.id), kind, span: p.span })
}
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
}
/// Used to ban the `..` pattern in places it shouldn't be semantically.
- fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind {
+ fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> {
self.diagnostic()
.struct_span_err(sp, "`..` patterns are not allowed here")
.note("only allowed in tuple, tuple struct, and slice patterns")
}
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
- self.with_new_scopes(|this| {
- hir::AnonConst {
- hir_id: this.lower_node_id(c.id),
- body: this.lower_const_body(c.value.span, Some(&c.value)),
- }
+ self.with_new_scopes(|this| hir::AnonConst {
+ hir_id: this.lower_node_id(c.id),
+ body: this.lower_const_body(c.value.span, Some(&c.value)),
})
}
- fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt; 1]> {
+ fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
let kind = match s.kind {
StmtKind::Local(ref l) => {
let (l, item_ids) = self.lower_local(l);
- let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
+ let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids
.into_iter()
.map(|item_id| {
let item_id = hir::ItemId { id: self.lower_node_id(item_id) };
ids.push({
hir::Stmt {
hir_id: self.lower_node_id(s.id),
- kind: hir::StmtKind::Local(P(l)),
+ kind: hir::StmtKind::Local(self.arena.alloc(l)),
span: s.span,
}
});
return ids;
- },
+ }
StmtKind::Item(ref it) => {
// Can only use the ID once.
let mut id = Some(s.id);
- return self.lower_item_id(it)
+ return self
+ .lower_item_id(it)
.into_iter()
.map(|item_id| {
- let hir_id = id.take()
- .map(|id| self.lower_node_id(id))
- .unwrap_or_else(|| self.next_id());
-
- hir::Stmt {
- hir_id,
- kind: hir::StmtKind::Item(item_id),
- span: s.span,
- }
+ let hir_id = id
+ .take()
+ .map(|id| self.lower_node_id(id))
+ .unwrap_or_else(|| self.next_id());
+
+ hir::Stmt { hir_id, kind: hir::StmtKind::Item(item_id), span: s.span }
})
.collect();
}
- StmtKind::Expr(ref e) => hir::StmtKind::Expr(P(self.lower_expr(e))),
- StmtKind::Semi(ref e) => hir::StmtKind::Semi(P(self.lower_expr(e))),
+ StmtKind::Expr(ref e) => hir::StmtKind::Expr(self.lower_expr(e)),
+ StmtKind::Semi(ref e) => hir::StmtKind::Semi(self.lower_expr(e)),
StmtKind::Mac(..) => panic!("shouldn't exist here"),
};
- smallvec![hir::Stmt {
- hir_id: self.lower_node_id(s.id),
- kind,
- span: s.span,
- }]
+ smallvec![hir::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }]
}
fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
// Helper methods for building HIR.
- fn stmt(&mut self, span: Span, kind: hir::StmtKind) -> hir::Stmt {
+ fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
hir::Stmt { span, kind, hir_id: self.next_id() }
}
- fn stmt_expr(&mut self, span: Span, expr: hir::Expr) -> hir::Stmt {
- self.stmt(span, hir::StmtKind::Expr(P(expr)))
+ fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
+ self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
}
fn stmt_let_pat(
&mut self,
attrs: AttrVec,
span: Span,
- init: Option<P<hir::Expr>>,
- pat: P<hir::Pat>,
+ init: Option<&'hir hir::Expr<'hir>>,
+ pat: &'hir hir::Pat<'hir>,
source: hir::LocalSource,
- ) -> hir::Stmt {
- let local = hir::Local {
- attrs,
- hir_id: self.next_id(),
- init,
- pat,
- source,
- span,
- ty: None,
- };
- self.stmt(span, hir::StmtKind::Local(P(local)))
+ ) -> hir::Stmt<'hir> {
+ let local = hir::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None };
+ self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
}
- fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
- self.block_all(expr.span, hir::HirVec::new(), Some(expr))
+ fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
+ self.block_all(expr.span, &[], Some(expr))
}
fn block_all(
&mut self,
span: Span,
- stmts: hir::HirVec<hir::Stmt>,
- expr: Option<P<hir::Expr>>,
- ) -> hir::Block {
- hir::Block {
+ stmts: &'hir [hir::Stmt<'hir>],
+ expr: Option<&'hir hir::Expr<'hir>>,
+ ) -> &'hir hir::Block<'hir> {
+ let blk = hir::Block {
stmts,
expr,
hir_id: self.next_id(),
rules: hir::DefaultBlock,
span,
targeted_by_break: false,
- }
+ };
+ self.arena.alloc(blk)
}
/// Constructs a `true` or `false` literal pattern.
- fn pat_bool(&mut self, span: Span, val: bool) -> P<hir::Pat> {
+ fn pat_bool(&mut self, span: Span, val: bool) -> &'hir hir::Pat<'hir> {
let expr = self.expr_bool(span, val);
- self.pat(span, hir::PatKind::Lit(P(expr)))
+ self.pat(span, hir::PatKind::Lit(expr))
}
- fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat])
+ fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+ self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], arena_vec![self; pat])
}
- fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat])
+ fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+ self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], arena_vec![self; pat])
}
- fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
- self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat])
+ fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
+ self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], arena_vec![self; pat])
}
- fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
- self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![])
+ fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
+ self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], &[])
}
fn pat_std_enum(
&mut self,
span: Span,
components: &[Symbol],
- subpats: hir::HirVec<P<hir::Pat>>,
- ) -> P<hir::Pat> {
+ subpats: &'hir [&'hir hir::Pat<'hir>],
+ ) -> &'hir hir::Pat<'hir> {
let path = self.std_path(span, components, None, true);
- let qpath = hir::QPath::Resolved(None, P(path));
+ let qpath = hir::QPath::Resolved(None, self.arena.alloc(path));
let pt = if subpats.is_empty() {
hir::PatKind::Path(qpath)
} else {
self.pat(span, pt)
}
- fn pat_ident(&mut self, span: Span, ident: Ident) -> (P<hir::Pat>, hir::HirId) {
+ fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
}
span: Span,
ident: Ident,
bm: hir::BindingAnnotation,
- ) -> (P<hir::Pat>, hir::HirId) {
+ ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
let hir_id = self.next_id();
(
- P(hir::Pat {
+ self.arena.alloc(hir::Pat {
hir_id,
kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
span,
}),
- hir_id
+ hir_id,
)
}
- fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
+ fn pat_wild(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
self.pat(span, hir::PatKind::Wild)
}
- fn pat(&mut self, span: Span, kind: hir::PatKind) -> P<hir::Pat> {
- P(hir::Pat {
- hir_id: self.next_id(),
- kind,
- span,
- })
+ fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
+ self.arena.alloc(hir::Pat { hir_id: self.next_id(), kind, span })
}
/// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when
&mut self,
span: Span,
components: &[Symbol],
- params: Option<P<hir::GenericArgs>>,
+ params: Option<&'hir hir::GenericArgs<'hir>>,
is_value: bool,
- ) -> hir::Path {
+ ) -> hir::Path<'hir> {
let ns = if is_value { Namespace::ValueNS } else { Namespace::TypeNS };
let (path, res) = self.resolver.resolve_str_path(span, self.crate_root, components, ns);
- let mut segments: Vec<_> = path.segments.iter().map(|segment| {
- let res = self.expect_full_res(segment.id);
- hir::PathSegment {
- ident: segment.ident,
- hir_id: Some(self.lower_node_id(segment.id)),
- res: Some(self.lower_res(res)),
- infer_args: true,
- args: None,
- }
- }).collect();
+ let mut segments: Vec<_> = path
+ .segments
+ .iter()
+ .map(|segment| {
+ let res = self.expect_full_res(segment.id);
+ hir::PathSegment {
+ ident: segment.ident,
+ hir_id: Some(self.lower_node_id(segment.id)),
+ res: Some(self.lower_res(res)),
+ infer_args: true,
+ args: None,
+ }
+ })
+ .collect();
segments.last_mut().unwrap().args = params;
hir::Path {
span,
res: res.map_id(|_| panic!("unexpected `NodeId`")),
- segments: segments.into(),
+ segments: self.arena.alloc_from_iter(segments),
}
}
- fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) -> hir::Ty {
+ fn ty_path(
+ &mut self,
+ mut hir_id: hir::HirId,
+ span: Span,
+ qpath: hir::QPath<'hir>,
+ ) -> hir::Ty<'hir> {
let kind = match qpath {
hir::QPath::Resolved(None, path) => {
// Turn trait object paths into `TyKind::TraitObject` instead.
match path.res {
Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
let principal = hir::PolyTraitRef {
- bound_generic_params: hir::HirVec::new(),
- trait_ref: hir::TraitRef {
- path,
- hir_ref_id: hir_id,
- },
+ bound_generic_params: &[],
+ trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
span,
};
// The original ID is taken by the `PolyTraitRef`,
// so the `Ty` itself needs a different one.
hir_id = self.next_id();
- hir::TyKind::TraitObject(hir_vec![principal], self.elided_dyn_bound(span))
+ hir::TyKind::TraitObject(
+ arena_vec![self; principal],
+ self.elided_dyn_bound(span),
+ )
}
_ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
}
_ => hir::TyKind::Path(qpath),
};
- hir::Ty {
- hir_id,
- kind,
- span,
- }
+ hir::Ty { hir_id, kind, span }
}
/// Invoked to create the lifetime argument for a type `&T`
),
};
- let mut err = struct_span_err!(
- self.sess,
- span,
- E0637,
- "{}",
- msg,
- );
+ let mut err = struct_span_err!(self.sess, span, E0637, "{}", msg,);
err.span_label(span, label);
err.emit();
/// sorts of cases are deprecated. This may therefore report a warning or an
/// error, depending on the mode.
fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
- (0..count)
- .map(|_| self.elided_path_lifetime(span))
- .collect()
+ (0..count).map(|_| self.elided_path_lifetime(span)).collect()
}
fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
match self.anonymous_lifetime_mode {
AnonymousLifetimeMode::CreateParameter => {
// We should have emitted E0726 when processing this path above
- self.sess.delay_span_bug(
- span,
- "expected 'implicit elided lifetime not allowed' error",
- );
+ self.sess
+ .delay_span_bug(span, "expected 'implicit elided lifetime not allowed' error");
let id = self.resolver.next_node_id();
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted.
- | AnonymousLifetimeMode::PassThrough
- | AnonymousLifetimeMode::ReportError => self.new_implicit_lifetime(span),
+ AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
+ self.new_implicit_lifetime(span)
+ }
}
}
}
fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
- hir::Lifetime {
- hir_id: self.next_id(),
- span,
- name: hir::LifetimeName::Implicit,
- }
+ hir::Lifetime { hir_id: self.next_id(), span, name: hir::LifetimeName::Implicit }
}
fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
// call site which do not have a macro backtrace. See #61963.
- let is_macro_callsite = self.sess.source_map()
+ let is_macro_callsite = self
+ .sess
+ .source_map()
.span_to_snippet(span)
.map(|snippet| snippet.starts_with("#["))
.unwrap_or(true);
body_ids
}
-/// Checks if the specified expression is a built-in range literal.
-/// (See: `LoweringContext::lower_expr()`).
-pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
- use hir::{Path, QPath, ExprKind, TyKind};
-
- // Returns whether the given path represents a (desugared) range,
- // either in std or core, i.e. has either a `::std::ops::Range` or
- // `::core::ops::Range` prefix.
- fn is_range_path(path: &Path) -> bool {
- let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
- let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
-
- // "{{root}}" is the equivalent of `::` prefix in `Path`.
- if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
- (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
- } else {
- false
- }
- };
-
- // Check whether a span corresponding to a range expression is a
- // range literal, rather than an explicit struct or `new()` call.
- fn is_lit(sess: &Session, span: &Span) -> bool {
- let source_map = sess.source_map();
- let end_point = source_map.end_point(*span);
-
- if let Ok(end_string) = source_map.span_to_snippet(end_point) {
- !(end_string.ends_with("}") || end_string.ends_with(")"))
- } else {
- false
- }
- };
-
- match expr.kind {
- // All built-in range literals but `..=` and `..` desugar to `Struct`s.
- ExprKind::Struct(ref qpath, _, _) => {
- if let QPath::Resolved(None, ref path) = **qpath {
- return is_range_path(&path) && is_lit(sess, &expr.span);
- }
- }
+/// Helper struct for delayed construction of GenericArgs.
+struct GenericArgsCtor<'hir> {
+ args: Vec<hir::GenericArg<'hir>>,
+ bindings: &'hir [hir::TypeBinding<'hir>],
+ parenthesized: bool,
+}
- // `..` desugars to its struct path.
- ExprKind::Path(QPath::Resolved(None, ref path)) => {
- return is_range_path(&path) && is_lit(sess, &expr.span);
- }
+impl GenericArgsCtor<'hir> {
+ fn is_empty(&self) -> bool {
+ self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
+ }
- // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
- ExprKind::Call(ref func, _) => {
- if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
- if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
- let new_call = segment.ident.name == sym::new;
- return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
- }
- }
+ fn into_generic_args(self, arena: &'hir Arena<'hir>) -> hir::GenericArgs<'hir> {
+ hir::GenericArgs {
+ args: arena.alloc_from_iter(self.args),
+ bindings: self.bindings,
+ parenthesized: self.parenthesized,
}
-
- _ => {}
}
-
- false
}