Skip to main content

rustc_ast_lowering/delegation/
generics.rs

1use hir::HirId;
2use hir::def::{DefKind, Res};
3use rustc_ast::*;
4use rustc_data_structures::fx::FxHashSet;
5use rustc_hir as hir;
6use rustc_hir::def_id::DefId;
7use rustc_middle::ty::GenericParamDefKind;
8use rustc_middle::{bug, ty};
9use rustc_span::symbol::kw;
10use rustc_span::{Ident, Span, sym};
11
12use crate::LoweringContext;
13use crate::diagnostics::DelegationInfersMismatch;
14
15#[derive(#[automatically_derived]
impl ::core::fmt::Debug for GenericsPosition {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                GenericsPosition::Parent => "Parent",
                GenericsPosition::Child => "Child",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for GenericsPosition {
    #[inline]
    fn clone(&self) -> GenericsPosition { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for GenericsPosition { }Copy, #[automatically_derived]
impl ::core::cmp::Eq for GenericsPosition {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for GenericsPosition {
    #[inline]
    fn eq(&self, other: &GenericsPosition) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
16pub(super) enum GenericsPosition {
17    Parent,
18    Child,
19}
20
21#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for GenericArgSlot<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            GenericArgSlot::UserSpecified =>
                ::core::fmt::Formatter::write_str(f, "UserSpecified"),
            GenericArgSlot::Generate(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "Generate", __self_0, &__self_1),
        }
    }
}Debug)]
22pub(super) enum GenericArgSlot<T> {
23    UserSpecified,
24    Generate(T, Option<usize> /* Infer arg index from AST */),
25}
26
27pub(super) struct DelegationGenerics<T> {
28    data: T,
29    pos: GenericsPosition,
30    trait_impl: bool,
31}
32
33type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>;
34
35impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
36    fn generate_all(
37        params: &'hir [ty::GenericParamDef],
38        pos: GenericsPosition,
39        trait_impl: bool,
40    ) -> Self {
41        DelegationGenerics {
42            data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(),
43            pos,
44            trait_impl,
45        }
46    }
47}
48
49/// Used for storing either ty generics or their uplifted HIR version. First we obtain
50/// ty generics. Next, at some point of generics processing we need to uplift those
51/// generics to HIR, for this purpose we use `into_hir_generics` that uplifts ty generics
52/// and replaces Ty variant with Hir. Such approach is useful as we can call this method
53/// at any time knowing that uplifting will occur at most only once. Then, in order to obtain generic
54/// params or args we use `hir_generics_or_empty` or `into_generic_args` functions.
55/// There also may be situations when we obtained ty generics but never uplifted them to HIR,
56/// meaning we did not propagate them and thus we do not need to generate generic params
57/// (i.e., method call scenarios), in such a case this approach helps
58/// a lot as if `into_hir_generics` will not be called then uplifting will not happen.
59pub(super) enum HirOrTyGenerics<'hir> {
60    Ty(DelegationGenerics<TyGenerics<'hir>>),
61    Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
62}
63
64pub(super) struct GenericsGenerationResult<'hir> {
65    pub(super) generics: HirOrTyGenerics<'hir>,
66    pub(super) args_segment_id: HirId,
67    pub(super) use_for_sig_inheritance: bool,
68}
69
70impl GenericsGenerationResult<'_> {
71    pub(super) fn segment_id_for_sig(&self) -> Option<HirId> {
72        self.use_for_sig_inheritance.then(|| self.args_segment_id)
73    }
74}
75
76pub(super) struct GenericsGenerationResults<'hir> {
77    pub(super) parent: GenericsGenerationResult<'hir>,
78    pub(super) child: GenericsGenerationResult<'hir>,
79    pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>,
80}
81
82pub(super) struct DelegationGenericArgsIterator<'hir> {
83    index: usize = Default::default(),
84    params: &'hir [hir::GenericParam<'hir>],
85}
86
87/// During generic args propagation we need to create generic args
88/// (and their `HirId`s) on demand, as some of generic args can not be used
89/// and in this case an assert of an unseen `HirId` will be triggered. Moreover,
90/// when replacing infers with generated generic params we should reuse existing
91/// `HirId` of replaced infer, thus this iterator abstracts the way `HirId`s are
92/// created for new generic args.
93impl<'hir> DelegationGenericArgsIterator<'hir> {
94    pub(super) fn next(
95        &mut self,
96        ctx: &mut LoweringContext<'_, 'hir>,
97        hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId,
98    ) -> Option<hir::GenericArg<'hir>> {
99        let p = loop {
100            if self.index >= self.params.len() {
101                return None;
102            }
103
104            let p = self.params[self.index];
105            self.index += 1;
106
107            // Skip self generic arg, we do not need to propagate it.
108            if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() {
109                continue;
110            }
111
112            break p;
113        };
114
115        let hir_id = hir_id_factory(ctx);
116
117        Some(match p.kind {
118            hir::GenericParamKind::Lifetime { .. } => {
119                hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime {
120                    hir_id,
121                    ident: p.name.ident(),
122                    kind: hir::LifetimeKind::Param(p.def_id),
123                    source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
124                    syntax: hir::LifetimeSyntax::ExplicitBound,
125                }))
126            }
127            hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty {
128                hir_id,
129                span: p.span,
130                kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)),
131            })),
132            hir::GenericParamKind::Const { .. } => {
133                hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg {
134                    hir_id,
135                    kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)),
136                    span: p.span,
137                }))
138            }
139        })
140    }
141
142    pub(super) fn consume_all(
143        mut self,
144        ctx: &mut LoweringContext<'_, 'hir>,
145    ) -> Vec<hir::GenericArg<'hir>> {
146        let mut args = ::alloc::vec::Vec::new()vec![];
147        while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) {
148            args.push(arg);
149        }
150
151        args
152    }
153}
154
155impl<'hir> HirOrTyGenerics<'hir> {
156    pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) {
157        if let HirOrTyGenerics::Ty(ty) = self {
158            let rename_self = ty.pos == GenericsPosition::Child;
159            let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self);
160
161            *self = HirOrTyGenerics::Hir(DelegationGenerics {
162                data: params,
163                pos: ty.pos,
164                trait_impl: ty.trait_impl,
165            });
166        }
167    }
168
169    fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> {
170        match self {
171            HirOrTyGenerics::Ty(_) => hir::Generics::empty(),
172            HirOrTyGenerics::Hir(hir) => hir.data,
173        }
174    }
175
176    pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> {
177        match self {
178            HirOrTyGenerics::Ty(_) => {
179                ::rustc_middle::util::bug::bug_fmt(format_args!("attempting to get generic args before uplifting to HIR"))bug!("attempting to get generic args before uplifting to HIR")
180            }
181            HirOrTyGenerics::Hir(hir) => {
182                DelegationGenericArgsIterator { params: hir.data.params, .. }
183            }
184        }
185    }
186
187    pub(super) fn infer_indices(&self) -> FxHashSet<usize> {
188        match self {
189            HirOrTyGenerics::Ty(ty) => ty
190                .data
191                .iter()
192                .flat_map(|slot| match slot {
193                    GenericArgSlot::Generate(_, Some(idx)) => Some(*idx),
194                    _ => None,
195                })
196                .collect(),
197            HirOrTyGenerics::Hir(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("accessed infer indices on uplifted generics"))bug!("accessed infer indices on uplifted generics"),
198        }
199    }
200
201    pub(super) fn is_trait_impl(&self) -> bool {
202        match self {
203            HirOrTyGenerics::Ty(ty) => ty.trait_impl,
204            HirOrTyGenerics::Hir(hir) => hir.trait_impl,
205        }
206    }
207
208    pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> {
209        match self {
210            HirOrTyGenerics::Ty(_) => {
211                ::rustc_middle::util::bug::bug_fmt(format_args!("accessed ty-level generics while searching for uplifted `Self` param"))bug!("accessed ty-level generics while searching for uplifted `Self` param")
212            }
213            HirOrTyGenerics::Hir(hir) => hir
214                .data
215                .params
216                .iter()
217                .find(|p| p.name.ident().name == kw::SelfUpper)
218                .expect("`Self` generic param is not found while expected"),
219        }
220    }
221
222    pub(crate) fn pos(&self) -> GenericsPosition {
223        match self {
224            HirOrTyGenerics::Ty(ty) => ty.pos,
225            HirOrTyGenerics::Hir(hir) => hir.pos,
226        }
227    }
228}
229
230impl<'hir> GenericsGenerationResult<'hir> {
231    fn new(generics: DelegationGenerics<TyGenerics<'hir>>) -> GenericsGenerationResult<'hir> {
232        GenericsGenerationResult {
233            generics: HirOrTyGenerics::Ty(generics),
234            args_segment_id: HirId::INVALID,
235            use_for_sig_inheritance: false,
236        }
237    }
238}
239
240impl<'hir> GenericsGenerationResults<'hir> {
241    pub(super) fn all_params(&self) -> impl Iterator<Item = hir::GenericParam<'hir>> {
242        let parent = self.parent.generics.hir_generics_or_empty().params;
243        let child = self.child.generics.hir_generics_or_empty().params;
244
245        // Order generics, first we have parent and child lifetimes,
246        // then parent and child types and consts.
247        // `generics_of` in `rustc_hir_analysis` will order them anyway,
248        // however we want the order to be consistent in HIR too.
249        parent
250            .iter()
251            .filter(|p| p.is_lifetime())
252            .chain(child.iter().filter(|p| p.is_lifetime()))
253            .chain(parent.iter().filter(|p| !p.is_lifetime()))
254            .chain(child.iter().filter(|p| !p.is_lifetime()))
255            .copied()
256    }
257
258    /// As we add hack predicates(`'a: 'a`) for all lifetimes (see `uplift_delegation_generic_params`
259    /// and `generate_lifetime_predicate` functions) we need to add them to delegation generics.
260    /// Those predicates will not affect resulting predicate inheritance and folding
261    /// in `rustc_hir_analysis`, as we inherit all predicates from delegation signature.
262    pub(super) fn all_predicates(&self) -> impl Iterator<Item = hir::WherePredicate<'hir>> {
263        self.parent
264            .generics
265            .hir_generics_or_empty()
266            .predicates
267            .into_iter()
268            .chain(self.child.generics.hir_generics_or_empty().predicates)
269            .copied()
270    }
271}
272
273impl<'hir> LoweringContext<'_, 'hir> {
274    pub(super) fn uplift_delegation_generics(
275        &mut self,
276        delegation: &Delegation,
277        sig_id: DefId,
278    ) -> GenericsGenerationResults<'hir> {
279        let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id));
280
281        let segments = &delegation.path.segments;
282        let len = segments.len();
283
284        let get_user_args = |idx: usize| -> Option<&AngleBracketedArgs> {
285            let segment = &segments[idx];
286
287            let Some(args) = segment.args.as_ref() else { return None };
288            let GenericArgs::AngleBracketed(args) = args else {
289                self.tcx.dcx().span_delayed_bug(
290                    segment.span(),
291                    "expected angle-bracketed generic args in delegation segment",
292                );
293
294                return None;
295            };
296
297            // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`,
298            // the same logic applied when we call function `fn f<T>(t: T)`
299            // like that `f::<>(())`, in HIR no `<>` will be generated.
300            (!args.args.is_empty()).then(|| args)
301        };
302
303        let sig_params = &self.tcx.generics_of(sig_id).own_params[..];
304
305        // If we are in trait impl always generate function whose generics matches
306        // those that are defined in trait.
307        if #[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
    DefKind::Impl { of_trait: true } => true,
    _ => false,
}matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) {
308            // Considering parent generics, during signature inheritance
309            // we will take those args that are in trait impl header trait ref.
310            let parent =
311                DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Child, trait_impl: true };
312
313            let parent = GenericsGenerationResult::new(parent);
314
315            let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true);
316            let child = GenericsGenerationResult::new(child);
317
318            return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None };
319        }
320
321        let delegation_in_free_ctx =
322            !#[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
    DefKind::Trait | DefKind::Impl { .. } => true,
    _ => false,
}matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
323
324        let sig_parent = self.tcx.parent(sig_id);
325        let sig_in_trait = #[allow(non_exhaustive_omitted_patterns)] match self.tcx.def_kind(sig_parent)
    {
    DefKind::Trait => true,
    _ => false,
}matches!(self.tcx.def_kind(sig_parent), DefKind::Trait);
326        let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
327
328        let qself_is_infer =
329            delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer());
330
331        let qself_is_none = delegation.qself.is_none();
332
333        let generate_self = free_to_trait_delegation && (qself_is_none || qself_is_infer);
334
335        let can_add_generics_to_parent = len >= 2
336            && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| {
337                #[allow(non_exhaustive_omitted_patterns)] match self.tcx.def_kind(def_id) {
    DefKind::Trait | DefKind::TraitAlias => true,
    _ => false,
}matches!(self.tcx.def_kind(def_id), DefKind::Trait | DefKind::TraitAlias)
338            });
339
340        let parent_generics = if can_add_generics_to_parent {
341            let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params;
342
343            if let Some(args) = get_user_args(len - 2) {
344                DelegationGenerics {
345                    data: self.create_slots_from_args(
346                        args,
347                        &sig_parent_params[usize::from(!generate_self)..],
348                        generate_self,
349                    ),
350                    pos: GenericsPosition::Parent,
351                    trait_impl: false,
352                }
353            } else {
354                DelegationGenerics::generate_all(
355                    &sig_parent_params[usize::from(!generate_self)..],
356                    GenericsPosition::Parent,
357                    false,
358                )
359            }
360        } else {
361            DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Parent, trait_impl: false }
362        };
363
364        let child_generics = if let Some(args) = get_user_args(len - 1) {
365            let synth_params_index =
366                sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len());
367
368            let mut slots =
369                self.create_slots_from_args(args, &sig_params[..synth_params_index], false);
370
371            for synth_param in &sig_params[synth_params_index..] {
372                slots.push(GenericArgSlot::Generate(synth_param, None));
373            }
374
375            DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl: false }
376        } else {
377            DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false)
378        };
379
380        GenericsGenerationResults {
381            parent: GenericsGenerationResult::new(parent_generics),
382            child: GenericsGenerationResult::new(child_generics),
383            self_ty_propagation_kind: match free_to_trait_delegation {
384                true => Some(match qself_is_none {
385                    true => hir::DelegationSelfTyPropagationKind::SelfParam,
386                    false => match qself_is_infer {
387                        true => hir::DelegationSelfTyPropagationKind::SelfParam,
388                        // HirId is filled during generic args propagation.
389                        false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID),
390                    },
391                }),
392                false => None,
393            },
394        }
395    }
396
397    /// Generates generic argument slots for user-specified `args` and
398    /// generic `params` of the signature function. This function checks whether
399    /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in
400    /// user-specified args, and if so we add `Generate` slot meaning we have to
401    /// generate generic param for delegation and propagate it instead of this infer.
402    /// We zip over user-specified args and signature generic params, so if there are more
403    /// infers than generic params then we will not process all infers thus not generating
404    /// more generic params then needed (anyway it is an error).
405    fn create_slots_from_args(
406        &self,
407        args: &AngleBracketedArgs,
408        params: &'hir [ty::GenericParamDef],
409        add_first_self: bool,
410    ) -> TyGenerics<'hir> {
411        let mut slots = ::alloc::vec::Vec::new()vec![];
412        if add_first_self {
413            slots.push(GenericArgSlot::Generate(&params[0], None));
414        }
415
416        let params = &params[usize::from(add_first_self)..];
417        for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
418            let AngleBracketedArg::Arg(arg) = arg else { continue };
419
420            let is_infer = match arg {
421                GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
422                GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
423                GenericArg::Const(_) => false,
424            };
425
426            // If `'_` is used instead of `_` (or vice versa) we emit a meaningful
427            // error instead of processing this infer or leaving it as is for signature
428            // inheritance.
429            if is_infer
430                && #[allow(non_exhaustive_omitted_patterns)] match (arg, &param.kind) {
    (GenericArg::Lifetime(_),
        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. })
        |
        (GenericArg::Type(_) | GenericArg::Const(_),
        GenericParamDefKind::Lifetime { .. }) => true,
    _ => false,
}matches!(
431                    (arg, &param.kind),
432                    (
433                        GenericArg::Lifetime(_),
434                        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. }
435                    ) | (
436                        GenericArg::Type(_) | GenericArg::Const(_),
437                        GenericParamDefKind::Lifetime { .. }
438                    )
439                )
440            {
441                let (actual, expected) = if #[allow(non_exhaustive_omitted_patterns)] match arg {
    GenericArg::Lifetime(..) => true,
    _ => false,
}matches!(arg, GenericArg::Lifetime(..)) {
442                    (kw::UnderscoreLifetime, kw::Underscore)
443                } else {
444                    (kw::Underscore, kw::UnderscoreLifetime)
445                };
446
447                self.tcx.dcx().emit_err(DelegationInfersMismatch {
448                    span: arg.span(),
449                    actual,
450                    expected,
451                });
452            }
453
454            slots.push(match is_infer {
455                true => GenericArgSlot::Generate(param, Some(idx)),
456                false => GenericArgSlot::UserSpecified,
457            });
458        }
459
460        slots
461    }
462
463    fn uplift_delegation_generic_params(
464        &mut self,
465        span: Span,
466        params: &[GenericArgSlot<&ty::GenericParamDef>],
467        rename_self: bool,
468    ) -> &'hir hir::Generics<'hir> {
469        let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| {
470            let GenericArgSlot::Generate(p, _) = p else { return None };
471
472            let def_kind = match p.kind {
473                GenericParamDefKind::Lifetime => DefKind::LifetimeParam,
474                GenericParamDefKind::Type { .. } => DefKind::TyParam,
475                GenericParamDefKind::Const { .. } => DefKind::ConstParam,
476            };
477
478            // Rename Self generic param to This so it is properly propagated.
479            // If the user will create a function `fn foo<Self>() {}` with generic
480            // param "Self" then it will not be generated in HIR, the same thing
481            // applies to traits, `trait Trait<Self> {}` will be represented as
482            // `trait Trait {}` in HIR and "unexpected keyword `Self` in generic parameters"
483            // error will be emitted.
484            // Note that we do not rename `Self` to `This` after non-recursive reuse
485            // from Trait, in this case the `Self` should not be propagated
486            // (we rely that implicit `Self` generic param of a trait is named "Self")
487            // and it is OK to have Self generic param generated during lowering.
488            let param_name =
489                if rename_self && p.name == kw::SelfUpper { sym::This } else { p.name };
490
491            let param_ident = Ident::new(param_name, span);
492            let def_name = Some(param_ident.name);
493            let node_id = self.next_node_id();
494
495            let def_id = self.create_def(node_id, def_name, def_kind, span);
496
497            let kind = match p.kind {
498                GenericParamDefKind::Lifetime => {
499                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
500                }
501                GenericParamDefKind::Type { synthetic, .. } => {
502                    hir::GenericParamKind::Type { default: None, synthetic }
503                }
504                GenericParamDefKind::Const { .. } => {
505                    let hir_id = self.next_id();
506                    let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id));
507
508                    hir::GenericParamKind::Const {
509                        ty: self.arena.alloc(hir::Ty { kind, hir_id, span }),
510                        default: None,
511                    }
512                }
513            };
514
515            // Important: we don't use `self.next_id()` as we want to execute
516            // `lower_node_id` routine so param's id is added to `self.children`.
517            let hir_id = self.lower_node_id(node_id);
518
519            Some(hir::GenericParam {
520                hir_id,
521                colon_span: Some(span),
522                def_id,
523                kind,
524                name: hir::ParamName::Plain(param_ident),
525                pure_wrt_drop: p.pure_wrt_drop,
526                source: hir::GenericParamSource::Generics,
527                span,
528            })
529        }));
530
531        // HACK: for now we generate predicates such that all lifetimes are early bound,
532        // we can not not generate early-bound lifetimes, but we can't know which of them
533        // are late-bound at this level of compilation.
534        let predicates =
535            self.arena.alloc_from_iter(params.iter().filter_map(|p| {
536                p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span))
537            }));
538
539        self.arena.alloc(hir::Generics {
540            params,
541            predicates,
542            has_where_clause_predicates: false,
543            where_clause_span: span,
544            span,
545        })
546    }
547
548    fn generate_lifetime_predicate(
549        &mut self,
550        p: &hir::GenericParam<'hir>,
551        span: Span,
552    ) -> hir::WherePredicate<'hir> {
553        let create_lifetime = |this: &mut Self| -> &'hir hir::Lifetime {
554            this.arena.alloc(hir::Lifetime {
555                hir_id: this.next_id(),
556                ident: p.name.ident(),
557                kind: hir::LifetimeKind::Param(p.def_id),
558                source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
559                syntax: hir::LifetimeSyntax::ExplicitBound,
560            })
561        };
562
563        hir::WherePredicate {
564            hir_id: self.next_id(),
565            span,
566            kind: self.arena.alloc(hir::WherePredicateKind::RegionPredicate(
567                hir::WhereRegionPredicate {
568                    in_where_clause: true,
569                    lifetime: create_lifetime(self),
570                    bounds: self
571                        .arena
572                        .alloc_slice(&[hir::GenericBound::Outlives(create_lifetime(self))]),
573                },
574            )),
575        }
576    }
577
578    pub(super) fn create_generic_arg_path(
579        &mut self,
580        p: &hir::GenericParam<'hir>,
581    ) -> hir::QPath<'hir> {
582        let res = Res::Def(
583            match p.kind {
584                hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
585                hir::GenericParamKind::Type { .. } => DefKind::TyParam,
586                hir::GenericParamKind::Const { .. } => DefKind::ConstParam,
587            },
588            p.def_id.to_def_id(),
589        );
590
591        self.create_resolved_path(res, p.name.ident(), p.span)
592    }
593
594    pub(super) fn create_resolved_path(
595        &mut self,
596        res: Res,
597        ident: Ident,
598        span: Span,
599    ) -> hir::QPath<'hir> {
600        hir::QPath::Resolved(
601            None,
602            self.arena.alloc(hir::Path {
603                segments: self.arena.alloc_slice(&[hir::PathSegment {
604                    args: None,
605                    hir_id: self.next_id(),
606                    ident,
607                    infer_args: false,
608                    res,
609                    delegation_child_segment: false,
610                }]),
611                res,
612                span,
613            }),
614        )
615    }
616}