Skip to content

Commit 32af719

Browse files
committed
Always create parameters for functions-like types.
1 parent 4b79b8b commit 32af719

File tree

20 files changed

+303
-177
lines changed

20 files changed

+303
-177
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+42-18
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
223223
}
224224

225225
/// Obtain the list of lifetimes parameters to add to an item.
226+
///
227+
/// Extra lifetime parameters should only be added in places that can appear
228+
/// as a `binder` in `LifetimeRes`.
229+
///
230+
/// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
231+
/// should appear at the enclosing `PolyTraitRef`.
226232
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
227233
self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
228234
}
@@ -721,6 +727,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
721727
}
722728

723729
/// Converts a lifetime into a new generic parameter.
730+
#[tracing::instrument(level = "debug", skip(self))]
724731
fn lifetime_res_to_generic_param(
725732
&mut self,
726733
ident: Ident,
@@ -787,11 +794,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
787794
/// Register a binder to be ignored for lifetime capture.
788795
#[tracing::instrument(level = "debug", skip(self, f))]
789796
#[inline]
790-
fn with_lifetime_binder<T>(&mut self, binder: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
797+
fn with_lifetime_binder<T>(
798+
&mut self,
799+
binder: NodeId,
800+
generic_params: &[GenericParam],
801+
f: impl FnOnce(&mut Self, &'hir [hir::GenericParam<'hir>]) -> T,
802+
) -> T {
803+
let mut generic_params: Vec<_> = self.lower_generic_params_mut(generic_params).collect();
804+
let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
805+
debug!(?extra_lifetimes);
806+
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
807+
self.lifetime_res_to_generic_param(ident, node_id, res)
808+
}));
809+
let generic_params = self.arena.alloc_from_iter(generic_params);
810+
debug!(?generic_params);
811+
791812
if let Some(ctxt) = &mut self.captured_lifetimes {
792813
ctxt.binders_to_ignore.insert(binder);
793814
}
794-
let ret = f(self);
815+
let ret = f(self, generic_params);
795816
if let Some(ctxt) = &mut self.captured_lifetimes {
796817
ctxt.binders_to_ignore.remove(&binder);
797818
}
@@ -1188,15 +1209,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11881209
let lifetime = self.lower_lifetime(&region);
11891210
hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
11901211
}
1191-
TyKind::BareFn(ref f) => self.with_lifetime_binder(t.id, |this| {
1192-
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
1193-
generic_params: this.lower_generic_params(&f.generic_params),
1194-
unsafety: this.lower_unsafety(f.unsafety),
1195-
abi: this.lower_extern(f.ext),
1196-
decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
1197-
param_names: this.lower_fn_params_to_names(&f.decl),
1198-
}))
1199-
}),
1212+
TyKind::BareFn(ref f) => {
1213+
self.with_lifetime_binder(t.id, &f.generic_params, |this, generic_params| {
1214+
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
1215+
generic_params,
1216+
unsafety: this.lower_unsafety(f.unsafety),
1217+
abi: this.lower_extern(f.ext),
1218+
decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
1219+
param_names: this.lower_fn_params_to_names(&f.decl),
1220+
}))
1221+
})
1222+
}
12001223
TyKind::Never => hir::TyKind::Never,
12011224
TyKind::Tup(ref tys) => hir::TyKind::Tup(
12021225
self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
@@ -1963,13 +1986,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19631986
p: &PolyTraitRef,
19641987
itctx: ImplTraitContext,
19651988
) -> hir::PolyTraitRef<'hir> {
1966-
let bound_generic_params = self.lower_generic_params(&p.bound_generic_params);
1967-
1968-
let trait_ref = self.with_lifetime_binder(p.trait_ref.ref_id, |this| {
1969-
this.lower_trait_ref(&p.trait_ref, itctx)
1970-
});
1971-
1972-
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
1989+
self.with_lifetime_binder(
1990+
p.trait_ref.ref_id,
1991+
&p.bound_generic_params,
1992+
|this, bound_generic_params| {
1993+
let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx);
1994+
hir::PolyTraitRef { bound_generic_params, trait_ref, span: this.lower_span(p.span) }
1995+
},
1996+
)
19731997
}
19741998

19751999
fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {

compiler/rustc_ast_lowering/src/path.rs

+22-29
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
191191
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
192192
}
193193
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
194-
ParenthesizedGenericArgs::Ok => {
195-
self.lower_parenthesized_parameter_data(segment.id, data)
196-
}
194+
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
197195
ParenthesizedGenericArgs::Err => {
198196
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
199197
err.span_label(data.span, "only `Fn` traits may use parentheses");
@@ -351,39 +349,34 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
351349

352350
fn lower_parenthesized_parameter_data(
353351
&mut self,
354-
id: NodeId,
355352
data: &ParenthesizedArgs,
356353
) -> (GenericArgsCtor<'hir>, bool) {
357354
// Switch to `PassThrough` mode for anonymous lifetimes; this
358355
// means that we permit things like `&Ref<T>`, where `Ref` has
359356
// a hidden lifetime parameter. This is needed for backwards
360357
// compatibility, even in contexts like an impl header where
361358
// we generally don't permit such things (see #51008).
362-
self.with_lifetime_binder(id, |this| {
363-
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
364-
let inputs = this.arena.alloc_from_iter(inputs.iter().map(|ty| {
365-
this.lower_ty_direct(
366-
ty,
367-
ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam),
368-
)
369-
}));
370-
let output_ty = match output {
371-
FnRetTy::Ty(ty) => this
372-
.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
373-
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
374-
};
375-
let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];
376-
let binding = this.output_ty_binding(output_ty.span, output_ty);
377-
(
378-
GenericArgsCtor {
379-
args,
380-
bindings: arena_vec![this; binding],
381-
parenthesized: true,
382-
span: data.inputs_span,
383-
},
384-
false,
385-
)
386-
})
359+
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
360+
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
361+
self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
362+
}));
363+
let output_ty = match output {
364+
FnRetTy::Ty(ty) => {
365+
self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
366+
}
367+
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
368+
};
369+
let args = smallvec![GenericArg::Type(self.ty_tup(*inputs_span, inputs))];
370+
let binding = self.output_ty_binding(output_ty.span, output_ty);
371+
(
372+
GenericArgsCtor {
373+
args,
374+
bindings: arena_vec![self; binding],
375+
parenthesized: true,
376+
span: data.inputs_span,
377+
},
378+
false,
379+
)
387380
}
388381

389382
/// An associated type binding `Output = $ty`.

compiler/rustc_hir/src/def.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,7 @@ pub enum LifetimeRes {
722722
/// Id of the introducing place. That can be:
723723
/// - an item's id, for the item's generic parameters;
724724
/// - a TraitRef's ref_id, identifying the `for<...>` binder;
725-
/// - a BareFn type's id;
726-
/// - a Path's id when this path has parenthesized generic args.
725+
/// - a BareFn type's id.
727726
///
728727
/// This information is used for impl-trait lifetime captures, to know when to or not to
729728
/// capture any given lifetime.

0 commit comments

Comments
 (0)