use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
use crate::hir::map::{DefKey, DefPathData, Definitions};
use crate::hir::ptr::P;
-use crate::hir::HirVec;
use crate::hir::{self, ParamName};
use crate::hir::{ConstArg, GenericArg};
use crate::lint;
use crate::middle::cstore::CrateStore;
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;
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()),
+ allow_into_future: Some([sym::into_future][..].into()),
}
.lower_crate(krate)
}
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);
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());
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
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 },
// 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| {
// 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));
+ this.lower_generics_mut(generics, ImplTraitContext::Universal(&mut params));
let res = f(this, &mut params);
(params, (generics, res))
})
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 lower_attrs_arena(&mut self, attrs: &[Attribute]) -> &'hir [Attribute] {
+ fn lower_attrs(&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_attr(&mut self, attr: &Attribute) -> Attribute {
// Note that we explicitly do not walk the path. Since we don't really
// lower attributes (we use the AST version) there is nowhere to keep
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 {
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) => {
}
}
- 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,
}
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 {
+ hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
generic_params: this.lower_generic_params(
&f.generic_params,
&NodeMap::default(),
})
}),
TyKind::Never => hir::TyKind::Never,
- TyKind::Tup(ref tys) => hir::TyKind::Tup(
- tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())).collect(),
- ),
+ TyKind::Tup(ref tys) => {
+ 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(Ident::with_dummy_span(
- kw::SelfUpper
- ))],
+ segments: arena_vec![self; hir::PathSegment::from_ident(
+ Ident::with_dummy_span(kw::SelfUpper)
+ )],
span: t.span,
}),
))
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)
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 {
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)],
}),
))
}
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,
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,
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> {
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
name,
span: lifetime.span,
pure_wrt_drop: false,
- attrs: hir_vec![],
- bounds: hir_vec![],
+ 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()));
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
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 {
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,
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
// 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 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(_) => P(this.ty_tup(span, hir::HirVec::new())),
+ FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
};
- let args = hir_vec![GenericArg::Type(this.ty_tup(span, inputs))];
+ 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 },
};
- (hir::GenericArgs { args, bindings: hir_vec![binding], parenthesized: true }, false)
+ (
+ GenericArgsCtor { args, bindings: arena_vec![this; binding], parenthesized: true },
+ false,
+ )
})
}
},
)
});
- let ty = ty.map(|ty| &*self.arena.alloc(ty.into_inner()));
let init = l.init.as_ref().map(|e| self.lower_expr(e));
(
hir::Local {
)
}
- 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> {
+ ) -> &'hir hir::FnDecl<'hir> {
debug!(
"lower_fn_decl(\
fn_decl: {:?}, \
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 {
}
};
- P(hir::FnDecl {
+ self.arena.alloc(hir::FnDecl {
inputs,
output,
c_variadic,
output: &FunctionRetTy,
fn_def_id: DefId,
opaque_ty_node_id: NodeId,
- ) -> hir::FunctionRetTy {
+ ) -> hir::FunctionRetTy<'hir> {
debug!(
"lower_async_fn_ret_ty(\
output={:?}, \
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();
+ 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)
+ }));
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,
};
})
})
.collect();
- generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)| {
+ 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 },
hir_id: self.next_id(),
});
// ::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![],
+ 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),
hir::Lifetime { hir_id: self.lower_node_id(id), span, name }
}
- fn lower_generic_params(
+ fn lower_generic_params_mut(
&mut self,
params: &[GenericParam],
add_bounds: &NodeMap<Vec<GenericBound>>,
- mut itctx: ImplTraitContext<'_>,
- ) -> hir::HirVec<hir::GenericParam> {
+ 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>>,
+ 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::GenericParam {
- let mut bounds = self
+ mut itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericParam<'hir> {
+ let mut bounds: Vec<_> = self
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
- this.lower_param_bounds(¶m.bounds, itctx.reborrow())
+ this.lower_param_bounds_mut(¶m.bounds, itctx.reborrow()).collect()
});
let (name, kind) = match param.kind {
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 {
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),
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(),
hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
}
- fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_>) -> hir::MutTy {
+ 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],
- mut itctx: ImplTraitContext<'_>,
- ) -> hir::GenericBounds {
- bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
+ itctx: ImplTraitContext<'_, 'hir>,
+ ) -> hir::GenericBounds<'hir> {
+ self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
+ }
+
+ 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) -> &'hir hir::Block<'hir> {
}
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)],
}),
)),
}
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 {
&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);
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(),
+ 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)),
}
body_ids.sort_by_key(|b| bodies[b].value.span);
body_ids
}
+
+/// Helper struct for delayed construction of GenericArgs.
+struct GenericArgsCtor<'hir> {
+ args: Vec<hir::GenericArg<'hir>>,
+ bindings: &'hir [hir::TypeBinding<'hir>],
+ parenthesized: bool,
+}
+
+impl GenericArgsCtor<'hir> {
+ fn is_empty(&self) -> bool {
+ self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
+ }
+
+ 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,
+ }
+ }
+}