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)]
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 = #[allow(non_exhaustive_omitted_patterns)] match ty.pos {
    GenericsPosition::Child => true,
    _ => false,
}matches!(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
223impl<'hir> GenericsGenerationResult<'hir> {
224    fn new(generics: DelegationGenerics<TyGenerics<'hir>>) -> GenericsGenerationResult<'hir> {
225        GenericsGenerationResult {
226            generics: HirOrTyGenerics::Ty(generics),
227            args_segment_id: HirId::INVALID,
228            use_for_sig_inheritance: false,
229        }
230    }
231}
232
233impl<'hir> GenericsGenerationResults<'hir> {
234    pub(super) fn all_params(&self) -> impl Iterator<Item = hir::GenericParam<'hir>> {
235        let parent = self.parent.generics.hir_generics_or_empty().params;
236        let child = self.child.generics.hir_generics_or_empty().params;
237
238        // Order generics, first we have parent and child lifetimes,
239        // then parent and child types and consts.
240        // `generics_of` in `rustc_hir_analysis` will order them anyway,
241        // however we want the order to be consistent in HIR too.
242        parent
243            .iter()
244            .filter(|p| p.is_lifetime())
245            .chain(child.iter().filter(|p| p.is_lifetime()))
246            .chain(parent.iter().filter(|p| !p.is_lifetime()))
247            .chain(child.iter().filter(|p| !p.is_lifetime()))
248            .copied()
249    }
250
251    /// As we add hack predicates(`'a: 'a`) for all lifetimes (see `uplift_delegation_generic_params`
252    /// and `generate_lifetime_predicate` functions) we need to add them to delegation generics.
253    /// Those predicates will not affect resulting predicate inheritance and folding
254    /// in `rustc_hir_analysis`, as we inherit all predicates from delegation signature.
255    pub(super) fn all_predicates(&self) -> impl Iterator<Item = hir::WherePredicate<'hir>> {
256        self.parent
257            .generics
258            .hir_generics_or_empty()
259            .predicates
260            .into_iter()
261            .chain(self.child.generics.hir_generics_or_empty().predicates)
262            .copied()
263    }
264}
265
266impl<'hir> LoweringContext<'_, 'hir> {
267    pub(super) fn uplift_delegation_generics(
268        &mut self,
269        delegation: &Delegation,
270        sig_id: DefId,
271    ) -> GenericsGenerationResults<'hir> {
272        let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.owner.def_id));
273
274        let segments = &delegation.path.segments;
275        let len = segments.len();
276
277        let get_user_args = |idx: usize| -> Option<&AngleBracketedArgs> {
278            let segment = &segments[idx];
279
280            let Some(args) = segment.args.as_ref() else { return None };
281            let GenericArgs::AngleBracketed(args) = args else {
282                self.tcx.dcx().span_delayed_bug(
283                    segment.span(),
284                    "expected angle-bracketed generic args in delegation segment",
285                );
286
287                return None;
288            };
289
290            // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`,
291            // the same logic applied when we call function `fn f<T>(t: T)`
292            // like that `f::<>(())`, in HIR no `<>` will be generated.
293            (!args.args.is_empty()).then(|| args)
294        };
295
296        let sig_params = &self.tcx.generics_of(sig_id).own_params[..];
297
298        // If we are in trait impl always generate function whose generics matches
299        // those that are defined in trait.
300        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 }) {
301            // Considering parent generics, during signature inheritance
302            // we will take those args that are in trait impl header trait ref.
303            let parent =
304                DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Child, trait_impl: true };
305
306            let parent = GenericsGenerationResult::new(parent);
307
308            let child = DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, true);
309            let child = GenericsGenerationResult::new(child);
310
311            return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None };
312        }
313
314        let delegation_in_free_ctx =
315            !#[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
    DefKind::Trait | DefKind::Impl { .. } => true,
    _ => false,
}matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
316
317        let sig_parent = self.tcx.parent(sig_id);
318        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);
319        let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
320
321        let qself_is_infer =
322            delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer());
323
324        let qself_is_none = delegation.qself.is_none();
325
326        let generate_self = free_to_trait_delegation && (qself_is_none || qself_is_infer);
327
328        let can_add_generics_to_parent = len >= 2
329            && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| {
330                #[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)
331            });
332
333        let parent_generics = if can_add_generics_to_parent {
334            let sig_parent_params = &self.tcx.generics_of(sig_parent).own_params;
335
336            if let Some(args) = get_user_args(len - 2) {
337                DelegationGenerics {
338                    data: self.create_slots_from_args(
339                        args,
340                        &sig_parent_params[usize::from(!generate_self)..],
341                        generate_self,
342                    ),
343                    pos: GenericsPosition::Parent,
344                    trait_impl: false,
345                }
346            } else {
347                DelegationGenerics::generate_all(
348                    &sig_parent_params[usize::from(!generate_self)..],
349                    GenericsPosition::Parent,
350                    false,
351                )
352            }
353        } else {
354            DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Parent, trait_impl: false }
355        };
356
357        let child_generics = if let Some(args) = get_user_args(len - 1) {
358            let synth_params_index =
359                sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len());
360
361            let mut slots =
362                self.create_slots_from_args(args, &sig_params[..synth_params_index], false);
363
364            for synth_param in &sig_params[synth_params_index..] {
365                slots.push(GenericArgSlot::Generate(synth_param, None));
366            }
367
368            DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl: false }
369        } else {
370            DelegationGenerics::generate_all(sig_params, GenericsPosition::Child, false)
371        };
372
373        GenericsGenerationResults {
374            parent: GenericsGenerationResult::new(parent_generics),
375            child: GenericsGenerationResult::new(child_generics),
376            self_ty_propagation_kind: match free_to_trait_delegation {
377                true => Some(match qself_is_none {
378                    true => hir::DelegationSelfTyPropagationKind::SelfParam,
379                    false => match qself_is_infer {
380                        true => hir::DelegationSelfTyPropagationKind::SelfParam,
381                        // HirId is filled during generic args propagation.
382                        false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID),
383                    },
384                }),
385                false => None,
386            },
387        }
388    }
389
390    /// Generates generic argument slots for user-specified `args` and
391    /// generic `params` of the signature function. This function checks whether
392    /// there are infers (`kw::UnderscoreLifetime` or `kw::Underscore`) in
393    /// user-specified args, and if so we add `Generate` slot meaning we have to
394    /// generate generic param for delegation and propagate it instead of this infer.
395    /// We zip over user-specified args and signature generic params, so if there are more
396    /// infers than generic params then we will not process all infers thus not generating
397    /// more generic params then needed (anyway it is an error).
398    fn create_slots_from_args(
399        &self,
400        args: &AngleBracketedArgs,
401        params: &'hir [ty::GenericParamDef],
402        add_first_self: bool,
403    ) -> TyGenerics<'hir> {
404        let mut slots = ::alloc::vec::Vec::new()vec![];
405        if add_first_self {
406            slots.push(GenericArgSlot::Generate(&params[0], None));
407        }
408
409        let params = &params[usize::from(add_first_self)..];
410        for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
411            let AngleBracketedArg::Arg(arg) = arg else { continue };
412
413            let is_infer = match arg {
414                GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
415                GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
416                GenericArg::Const(_) => false,
417            };
418
419            // If `'_` is used instead of `_` (or vice versa) we emit a meaningful
420            // error instead of processing this infer or leaving it as is for signature
421            // inheritance.
422            if is_infer
423                && #[allow(non_exhaustive_omitted_patterns)] match (arg, &param.kind) {
    (GenericArg::Lifetime(_),
        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. })
        |
        (GenericArg::Type(_) | GenericArg::Const(_),
        GenericParamDefKind::Lifetime { .. }) => true,
    _ => false,
}matches!(
424                    (arg, &param.kind),
425                    (
426                        GenericArg::Lifetime(_),
427                        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. }
428                    ) | (
429                        GenericArg::Type(_) | GenericArg::Const(_),
430                        GenericParamDefKind::Lifetime { .. }
431                    )
432                )
433            {
434                let (actual, expected) = if #[allow(non_exhaustive_omitted_patterns)] match arg {
    GenericArg::Lifetime(..) => true,
    _ => false,
}matches!(arg, GenericArg::Lifetime(..)) {
435                    (kw::UnderscoreLifetime, kw::Underscore)
436                } else {
437                    (kw::Underscore, kw::UnderscoreLifetime)
438                };
439
440                self.tcx.dcx().emit_err(DelegationInfersMismatch {
441                    span: arg.span(),
442                    actual,
443                    expected,
444                });
445            }
446
447            slots.push(match is_infer {
448                true => GenericArgSlot::Generate(param, Some(idx)),
449                false => GenericArgSlot::UserSpecified,
450            });
451        }
452
453        slots
454    }
455
456    fn uplift_delegation_generic_params(
457        &mut self,
458        span: Span,
459        params: &[GenericArgSlot<&ty::GenericParamDef>],
460        rename_self: bool,
461    ) -> &'hir hir::Generics<'hir> {
462        let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| {
463            let GenericArgSlot::Generate(p, _) = p else { return None };
464
465            let def_kind = match p.kind {
466                GenericParamDefKind::Lifetime => DefKind::LifetimeParam,
467                GenericParamDefKind::Type { .. } => DefKind::TyParam,
468                GenericParamDefKind::Const { .. } => DefKind::ConstParam,
469            };
470
471            // Rename Self generic param to This so it is properly propagated.
472            // If the user will create a function `fn foo<Self>() {}` with generic
473            // param "Self" then it will not be generated in HIR, the same thing
474            // applies to traits, `trait Trait<Self> {}` will be represented as
475            // `trait Trait {}` in HIR and "unexpected keyword `Self` in generic parameters"
476            // error will be emitted.
477            // Note that we do not rename `Self` to `This` after non-recursive reuse
478            // from Trait, in this case the `Self` should not be propagated
479            // (we rely that implicit `Self` generic param of a trait is named "Self")
480            // and it is OK to have Self generic param generated during lowering.
481            let param_name =
482                if rename_self && p.name == kw::SelfUpper { sym::This } else { p.name };
483
484            let param_ident = Ident::new(param_name, span);
485            let def_name = Some(param_ident.name);
486            let node_id = self.next_node_id();
487
488            let def_id = self.create_def(node_id, def_name, def_kind, span);
489
490            let kind = match p.kind {
491                GenericParamDefKind::Lifetime => {
492                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
493                }
494                GenericParamDefKind::Type { synthetic, .. } => {
495                    hir::GenericParamKind::Type { default: None, synthetic }
496                }
497                GenericParamDefKind::Const { .. } => {
498                    let hir_id = self.next_id();
499                    let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id));
500
501                    hir::GenericParamKind::Const {
502                        ty: self.arena.alloc(hir::Ty { kind, hir_id, span }),
503                        default: None,
504                    }
505                }
506            };
507
508            // Important: we don't use `self.next_id()` as we want to execute
509            // `lower_node_id` routine so param's id is added to `self.children`.
510            let hir_id = self.lower_node_id(node_id);
511
512            Some(hir::GenericParam {
513                hir_id,
514                colon_span: Some(span),
515                def_id,
516                kind,
517                name: hir::ParamName::Plain(param_ident),
518                pure_wrt_drop: p.pure_wrt_drop,
519                source: hir::GenericParamSource::Generics,
520                span,
521            })
522        }));
523
524        // HACK: for now we generate predicates such that all lifetimes are early bound,
525        // we can not not generate early-bound lifetimes, but we can't know which of them
526        // are late-bound at this level of compilation.
527        let predicates =
528            self.arena.alloc_from_iter(params.iter().filter_map(|p| {
529                p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span))
530            }));
531
532        self.arena.alloc(hir::Generics {
533            params,
534            predicates,
535            has_where_clause_predicates: false,
536            where_clause_span: span,
537            span,
538        })
539    }
540
541    fn generate_lifetime_predicate(
542        &mut self,
543        p: &hir::GenericParam<'hir>,
544        span: Span,
545    ) -> hir::WherePredicate<'hir> {
546        let create_lifetime = |this: &mut Self| -> &'hir hir::Lifetime {
547            this.arena.alloc(hir::Lifetime {
548                hir_id: this.next_id(),
549                ident: p.name.ident(),
550                kind: hir::LifetimeKind::Param(p.def_id),
551                source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
552                syntax: hir::LifetimeSyntax::ExplicitBound,
553            })
554        };
555
556        hir::WherePredicate {
557            hir_id: self.next_id(),
558            span,
559            kind: self.arena.alloc(hir::WherePredicateKind::RegionPredicate(
560                hir::WhereRegionPredicate {
561                    in_where_clause: true,
562                    lifetime: create_lifetime(self),
563                    bounds: self
564                        .arena
565                        .alloc_slice(&[hir::GenericBound::Outlives(create_lifetime(self))]),
566                },
567            )),
568        }
569    }
570
571    pub(super) fn create_generic_arg_path(
572        &mut self,
573        p: &hir::GenericParam<'hir>,
574    ) -> hir::QPath<'hir> {
575        let res = Res::Def(
576            match p.kind {
577                hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
578                hir::GenericParamKind::Type { .. } => DefKind::TyParam,
579                hir::GenericParamKind::Const { .. } => DefKind::ConstParam,
580            },
581            p.def_id.to_def_id(),
582        );
583
584        hir::QPath::Resolved(
585            None,
586            self.arena.alloc(hir::Path {
587                segments: self.arena.alloc_slice(&[hir::PathSegment {
588                    args: None,
589                    hir_id: self.next_id(),
590                    ident: p.name.ident(),
591                    infer_args: false,
592                    res,
593                }]),
594                res,
595                span: p.span,
596            }),
597        )
598    }
599}