Use LifetimeRes during lowering.
This commit is contained in:
parent
69985f0175
commit
f385f856cd
9 changed files with 709 additions and 799 deletions
|
@ -53,7 +53,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
e.span,
|
||||
seg,
|
||||
ParamMode::Optional,
|
||||
0,
|
||||
ParenthesizedGenericArgs::Err,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
));
|
||||
|
|
|
@ -30,6 +30,7 @@ pub(super) struct NodeCollector<'a, 'hir> {
|
|||
definitions: &'a definitions::Definitions,
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(sess, definitions, bodies))]
|
||||
pub(super) fn index_hir<'hir>(
|
||||
sess: &Session,
|
||||
definitions: &definitions::Definitions,
|
||||
|
@ -65,6 +66,7 @@ pub(super) fn index_hir<'hir>(
|
|||
}
|
||||
|
||||
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
||||
debug_assert_eq!(self.owner, hir_id.owner);
|
||||
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
|
||||
|
@ -138,8 +140,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
});
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
||||
debug!("visit_item: {:?}", i);
|
||||
debug_assert_eq!(i.def_id, self.owner);
|
||||
self.with_parent(i.hir_id(), |this| {
|
||||
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
||||
|
@ -152,6 +154,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
});
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
|
||||
debug_assert_eq!(fi.def_id, self.owner);
|
||||
self.with_parent(fi.hir_id(), |this| {
|
||||
|
@ -170,6 +173,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
||||
debug_assert_eq!(ti.def_id, self.owner);
|
||||
self.with_parent(ti.hir_id(), |this| {
|
||||
|
@ -177,6 +181,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
});
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
|
||||
debug_assert_eq!(ii.def_id, self.owner);
|
||||
self.with_parent(ii.hir_id(), |this| {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
|
||||
use super::{AstOwner, ImplTraitContext, ImplTraitPosition, ResolverAstLowering};
|
||||
use super::{LoweringContext, ParamMode};
|
||||
use crate::{Arena, FnDeclKind};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
|
@ -81,13 +81,13 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
is_in_loop_condition: false,
|
||||
is_in_trait_impl: false,
|
||||
is_in_dyn_type: false,
|
||||
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
|
||||
generator_kind: None,
|
||||
task_context: None,
|
||||
current_item: None,
|
||||
lifetimes_to_define: Vec::new(),
|
||||
lifetimes_to_define: Default::default(),
|
||||
is_collecting_anonymous_lifetimes: None,
|
||||
in_scope_lifetimes: Vec::new(),
|
||||
captured_lifetimes: None,
|
||||
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||
allow_into_future: Some([sym::into_future][..].into()),
|
||||
|
@ -143,12 +143,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
LocalDefId { local_def_index }
|
||||
};
|
||||
|
||||
let parent_hir = self.lower_node(parent_id).unwrap().node().expect_item();
|
||||
let parent_hir = self.lower_node(parent_id).unwrap();
|
||||
self.with_lctx(item.id, |lctx| {
|
||||
// Evaluate with the lifetimes in `params` in-scope.
|
||||
// This is used to track which lifetimes have already been defined,
|
||||
// and which need to be replicated when lowering an async fn.
|
||||
match parent_hir.kind {
|
||||
match parent_hir.node().expect_item().kind {
|
||||
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref generics, .. }) => {
|
||||
lctx.is_in_trait_impl = of_trait.is_some();
|
||||
lctx.in_scope_lifetimes = generics
|
||||
|
@ -157,7 +157,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
.filter(|param| {
|
||||
matches!(param.kind, hir::GenericParamKind::Lifetime { .. })
|
||||
})
|
||||
.map(|param| param.name)
|
||||
.map(|param| {
|
||||
let def_id =
|
||||
parent_hir.nodes.local_id_to_def_id[¶m.hir_id.local_id];
|
||||
let name = param.name;
|
||||
(name, def_id)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
|
@ -167,7 +172,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
|||
.filter(|param| {
|
||||
matches!(param.kind, hir::GenericParamKind::Lifetime { .. })
|
||||
})
|
||||
.map(|param| param.name)
|
||||
.map(|param| {
|
||||
let def_id =
|
||||
parent_hir.nodes.local_id_to_def_id[¶m.hir_id.local_id];
|
||||
let name = param.name;
|
||||
(name, def_id)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
_ => {}
|
||||
|
@ -288,20 +298,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let body_id =
|
||||
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
|
||||
|
||||
let (generics, decl) = this.add_in_band_defs(
|
||||
generics,
|
||||
fn_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this, idty| {
|
||||
let (generics, decl) =
|
||||
this.add_in_band_defs(generics, fn_def_id, |this, idty| {
|
||||
let ret_id = asyncness.opt_return_id();
|
||||
this.lower_fn_decl(
|
||||
&decl,
|
||||
Some((fn_def_id, idty)),
|
||||
FnDeclKind::Fn,
|
||||
ret_id,
|
||||
)
|
||||
},
|
||||
);
|
||||
this.lower_fn_decl(&decl, Some((id, idty)), FnDeclKind::Fn, ret_id)
|
||||
});
|
||||
let sig = hir::FnSig {
|
||||
decl,
|
||||
header: this.lower_fn_header(header),
|
||||
|
@ -420,11 +421,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// lifetime to be added, but rather a reference to a
|
||||
// parent lifetime.
|
||||
let lowered_trait_def_id = hir_id.expect_owner();
|
||||
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
|
||||
ast_generics,
|
||||
lowered_trait_def_id,
|
||||
AnonymousLifetimeMode::CreateParameter,
|
||||
|this, _| {
|
||||
let (generics, (trait_ref, lowered_ty)) =
|
||||
self.add_in_band_defs(ast_generics, lowered_trait_def_id, |this, _| {
|
||||
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
|
||||
this.lower_trait_ref(
|
||||
trait_ref,
|
||||
|
@ -436,8 +434,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
|
||||
(trait_ref, lowered_ty)
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let new_impl_items =
|
||||
self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
|
||||
|
@ -750,18 +747,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
kind: match i.kind {
|
||||
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
|
||||
let fdec = &sig.decl;
|
||||
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
|
||||
generics,
|
||||
def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this, _| {
|
||||
let (generics, (fn_dec, fn_args)) =
|
||||
self.add_in_band_defs(generics, def_id, |this, _| {
|
||||
(
|
||||
// Disallow `impl Trait` in foreign items.
|
||||
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
|
||||
this.lower_fn_params_to_names(fdec),
|
||||
)
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
|
||||
}
|
||||
|
@ -868,13 +861,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
|
||||
let names = self.lower_fn_params_to_names(&sig.decl);
|
||||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
sig,
|
||||
trait_item_def_id,
|
||||
FnDeclKind::Trait,
|
||||
None,
|
||||
);
|
||||
let (generics, sig) =
|
||||
self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
|
||||
|
@ -884,7 +872,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
sig,
|
||||
trait_item_def_id,
|
||||
i.id,
|
||||
FnDeclKind::Trait,
|
||||
asyncness.opt_return_id(),
|
||||
);
|
||||
|
@ -958,8 +946,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
|
||||
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
||||
let impl_item_def_id = self.resolver.local_def_id(i.id);
|
||||
|
||||
let (generics, kind) = match &i.kind {
|
||||
AssocItemKind::Const(_, ty, expr) => {
|
||||
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
|
||||
|
@ -976,7 +962,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let (generics, sig) = self.lower_method_sig(
|
||||
generics,
|
||||
sig,
|
||||
impl_item_def_id,
|
||||
i.id,
|
||||
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
|
||||
asyncness.opt_return_id(),
|
||||
);
|
||||
|
@ -1363,17 +1349,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
&mut self,
|
||||
generics: &Generics,
|
||||
sig: &FnSig,
|
||||
fn_def_id: LocalDefId,
|
||||
id: NodeId,
|
||||
kind: FnDeclKind,
|
||||
is_async: Option<NodeId>,
|
||||
) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
|
||||
let fn_def_id = self.resolver.local_def_id(id);
|
||||
let header = self.lower_fn_header(sig.header);
|
||||
let (generics, decl) = self.add_in_band_defs(
|
||||
generics,
|
||||
fn_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
|
||||
);
|
||||
let (generics, decl) = self.add_in_band_defs(generics, fn_def_id, |this, idty| {
|
||||
this.lower_fn_decl(&sig.decl, Some((id, idty)), kind, is_async)
|
||||
});
|
||||
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
|
||||
}
|
||||
|
||||
|
@ -1498,14 +1482,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
|
||||
fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
|
||||
self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
|
||||
hir::WhereClause {
|
||||
predicates: this.arena.alloc_from_iter(
|
||||
wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
|
||||
),
|
||||
span: this.lower_span(wc.span),
|
||||
}
|
||||
})
|
||||
hir::WhereClause {
|
||||
predicates: self.arena.alloc_from_iter(
|
||||
wc.predicates.iter().map(|predicate| self.lower_where_predicate(predicate)),
|
||||
),
|
||||
span: self.lower_span(wc.span),
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,14 @@
|
|||
use crate::ImplTraitPosition;
|
||||
|
||||
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
|
||||
use super::{GenericArgsCtor, ParenthesizedGenericArgs};
|
||||
use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs};
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode};
|
||||
|
||||
use rustc_ast::{self as ast, *};
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use smallvec::smallvec;
|
||||
|
@ -47,30 +46,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
_ => param_mode,
|
||||
};
|
||||
|
||||
// Figure out if this is a type/trait segment,
|
||||
// which may need lifetime elision performed.
|
||||
let parent_def_id = |this: &mut Self, def_id: DefId| DefId {
|
||||
krate: def_id.krate,
|
||||
index: this.resolver.def_key(def_id).parent.expect("missing parent"),
|
||||
};
|
||||
let type_def_id = match partial_res.base_res() {
|
||||
Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => {
|
||||
Some(parent_def_id(self, def_id))
|
||||
}
|
||||
Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => {
|
||||
Some(parent_def_id(self, def_id))
|
||||
}
|
||||
Res::Def(DefKind::Struct, def_id)
|
||||
| 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 =>
|
||||
{
|
||||
Some(def_id)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let parenthesized_generic_args = match partial_res.base_res() {
|
||||
// `a::b::Trait(Args)`
|
||||
Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
|
||||
|
@ -90,13 +65,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
_ => ParenthesizedGenericArgs::Err,
|
||||
};
|
||||
|
||||
let num_lifetimes = type_def_id
|
||||
.map_or(0, |def_id| self.resolver.item_generics_num_lifetimes(def_id));
|
||||
self.lower_path_segment(
|
||||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
num_lifetimes,
|
||||
parenthesized_generic_args,
|
||||
itctx.reborrow(),
|
||||
)
|
||||
|
@ -143,7 +115,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
0,
|
||||
ParenthesizedGenericArgs::Err,
|
||||
itctx.reborrow(),
|
||||
));
|
||||
|
@ -184,7 +155,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
0,
|
||||
ParenthesizedGenericArgs::Err,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
)
|
||||
|
@ -209,14 +179,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
path_span: Span,
|
||||
segment: &PathSegment,
|
||||
param_mode: ParamMode,
|
||||
expected_lifetimes: usize,
|
||||
parenthesized_generic_args: ParenthesizedGenericArgs,
|
||||
itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> hir::PathSegment<'hir> {
|
||||
debug!(
|
||||
"path_span: {:?}, lower_path_segment(segment: {:?}, expected_lifetimes: {:?})",
|
||||
path_span, segment, expected_lifetimes
|
||||
);
|
||||
debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
|
||||
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 {
|
||||
|
@ -224,7 +190,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||
}
|
||||
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
|
||||
ParenthesizedGenericArgs::Ok => {
|
||||
self.lower_parenthesized_parameter_data(segment.id, data)
|
||||
}
|
||||
ParenthesizedGenericArgs::Err => {
|
||||
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
|
||||
err.span_label(data.span, "only `Fn` traits may use parentheses");
|
||||
|
@ -274,33 +242,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
let has_lifetimes =
|
||||
generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
|
||||
if !generic_args.parenthesized && !has_lifetimes && expected_lifetimes > 0 {
|
||||
// Note: these spans are used for diagnostics when they can't be inferred.
|
||||
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
||||
let elided_lifetime_span = if generic_args.span.is_empty() {
|
||||
// If there are no brackets, use the identifier span.
|
||||
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
|
||||
// originating from macros, since the segment's span might be from a macro arg.
|
||||
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
|
||||
} else if generic_args.is_empty() {
|
||||
// If there are brackets, but not generic arguments, then use the opening bracket
|
||||
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
|
||||
} else {
|
||||
// Else use an empty span right after the opening bracket.
|
||||
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
|
||||
};
|
||||
generic_args.args = self
|
||||
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes)
|
||||
.map(GenericArg::Lifetime)
|
||||
.chain(generic_args.args.into_iter())
|
||||
.collect();
|
||||
if let (ParamMode::Explicit, AnonymousLifetimeMode::CreateParameter) =
|
||||
(param_mode, self.anonymous_lifetime_mode)
|
||||
{
|
||||
// Late resolver should have issued the error.
|
||||
self.sess
|
||||
.delay_span_bug(elided_lifetime_span, "implicit lifetime not allowed here");
|
||||
}
|
||||
if !generic_args.parenthesized && !has_lifetimes {
|
||||
self.maybe_insert_elided_lifetimes_in_path(
|
||||
path_span,
|
||||
segment.id,
|
||||
segment.ident.span,
|
||||
&mut generic_args,
|
||||
);
|
||||
}
|
||||
|
||||
let res = self.expect_full_res(segment.id);
|
||||
|
@ -323,6 +271,49 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn maybe_insert_elided_lifetimes_in_path(
|
||||
&mut self,
|
||||
path_span: Span,
|
||||
segment_id: NodeId,
|
||||
segment_ident_span: Span,
|
||||
generic_args: &mut GenericArgsCtor<'hir>,
|
||||
) {
|
||||
let (start, end) = match self.resolver.get_lifetime_res(segment_id) {
|
||||
Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end),
|
||||
None => return,
|
||||
Some(_) => panic!(),
|
||||
};
|
||||
let expected_lifetimes = end.as_usize() - start.as_usize();
|
||||
debug!(expected_lifetimes);
|
||||
|
||||
// Note: these spans are used for diagnostics when they can't be inferred.
|
||||
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
||||
let elided_lifetime_span = if generic_args.span.is_empty() {
|
||||
// If there are no brackets, use the identifier span.
|
||||
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
|
||||
// originating from macros, since the segment's span might be from a macro arg.
|
||||
segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span)
|
||||
} else if generic_args.is_empty() {
|
||||
// If there are brackets, but not generic arguments, then use the opening bracket
|
||||
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
|
||||
} else {
|
||||
// Else use an empty span right after the opening bracket.
|
||||
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
|
||||
};
|
||||
|
||||
generic_args.args.insert_many(
|
||||
0,
|
||||
(start.as_u32()..end.as_u32()).map(|i| {
|
||||
let id = NodeId::from_u32(i);
|
||||
let l = self.lower_lifetime(&Lifetime {
|
||||
id,
|
||||
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span),
|
||||
});
|
||||
GenericArg::Lifetime(l)
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn lower_angle_bracketed_parameter_data(
|
||||
&mut self,
|
||||
data: &AngleBracketedArgs,
|
||||
|
@ -354,6 +345,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
fn lower_parenthesized_parameter_data(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
data: &ParenthesizedArgs,
|
||||
) -> (GenericArgsCtor<'hir>, bool) {
|
||||
// Switch to `PassThrough` mode for anonymous lifetimes; this
|
||||
|
@ -361,31 +353,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// 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 { span, inputs, inputs_span, output } = data;
|
||||
let inputs = this.arena.alloc_from_iter(inputs.iter().map(|ty| {
|
||||
this.lower_ty_direct(
|
||||
ty,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam),
|
||||
)
|
||||
}));
|
||||
let output_ty = match output {
|
||||
FnRetTy::Ty(ty) => this
|
||||
.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
|
||||
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
|
||||
};
|
||||
let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];
|
||||
let binding = this.output_ty_binding(output_ty.span, output_ty);
|
||||
(
|
||||
GenericArgsCtor {
|
||||
args,
|
||||
bindings: arena_vec![this; binding],
|
||||
parenthesized: true,
|
||||
span: data.inputs_span,
|
||||
},
|
||||
false,
|
||||
)
|
||||
})
|
||||
if let Some((_, _, binders)) = &mut self.captured_lifetimes {
|
||||
binders.insert(id);
|
||||
}
|
||||
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
|
||||
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
|
||||
self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
|
||||
}));
|
||||
let output_ty = match output {
|
||||
FnRetTy::Ty(ty) => {
|
||||
self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
|
||||
}
|
||||
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
|
||||
};
|
||||
let args = smallvec![GenericArg::Type(self.ty_tup(*inputs_span, inputs))];
|
||||
let binding = self.output_ty_binding(output_ty.span, output_ty);
|
||||
if let Some((_, _, binders)) = &mut self.captured_lifetimes {
|
||||
binders.remove(&id);
|
||||
}
|
||||
(
|
||||
GenericArgsCtor {
|
||||
args,
|
||||
bindings: arena_vec![self; binding],
|
||||
parenthesized: true,
|
||||
span: data.inputs_span,
|
||||
},
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
/// An associated type binding `Output = $ty`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue