Skip to main content

rustc_ast_lowering/delegation/
generics.rs

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