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> ),
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#[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
97impl<'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 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 Specified(&'a AngleBracketedArgs),
256 NotSpecified,
259 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 qself_is_none: bool,
284 qself_is_infer: bool,
286 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 (!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 trait_impl {
381 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 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 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 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(¶ms[0], None));
521 }
522
523 let params = ¶ms[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_infer
532 && #[allow(non_exhaustive_omitted_patterns)] match (arg, ¶m.kind) {
(GenericArg::Lifetime(_),
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. })
|
(GenericArg::Type(_) | GenericArg::Const(_),
GenericParamDefKind::Lifetime { .. }) => true,
_ => false,
}matches!(
533 (arg, ¶m.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 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 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 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 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 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}