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