1use std::debug_assert_matches;
6
7use rustc_data_structures::fx::FxHashMap;
8use rustc_hir::def::DefKind;
9use rustc_hir::def_id::{DefId, LocalDefId};
10use rustc_hir::{HirId, PathSegment};
11use rustc_middle::ty::{
12 self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
13};
14use rustc_span::{ErrorGuaranteed, Span, kw};
15
16use crate::collect::ItemCtxt;
17use crate::hir_ty_lowering::HirTyLowerer;
18
19type RemapTable = FxHashMap<u32, u32>;
20
21struct ParamIndexRemapper<'tcx> {
22 tcx: TyCtxt<'tcx>,
23 remap_table: RemapTable,
24}
25
26impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> {
27 fn cx(&self) -> TyCtxt<'tcx> {
28 self.tcx
29 }
30
31 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
32 if !ty.has_param() {
33 return ty;
34 }
35
36 if let ty::Param(param) = ty.kind()
37 && let Some(index) = self.remap_table.get(¶m.index)
38 {
39 return Ty::new_param(self.tcx, *index, param.name);
40 }
41 ty.super_fold_with(self)
42 }
43
44 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
45 if let ty::ReEarlyParam(param) = r.kind()
46 && let Some(index) = self.remap_table.get(¶m.index).copied()
47 {
48 return ty::Region::new_early_param(
49 self.tcx,
50 ty::EarlyParamRegion { index, name: param.name },
51 );
52 }
53 r
54 }
55
56 fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
57 if let ty::ConstKind::Param(param) = ct.kind()
58 && let Some(idx) = self.remap_table.get(¶m.index)
59 {
60 let param = ty::ParamConst::new(*idx, param.name);
61 return ty::Const::new_param(self.tcx, param);
62 }
63 ct.super_fold_with(self)
64 }
65}
66
67enum SelfPositionKind {
68 AfterLifetimes,
69 Zero,
70 None,
71}
72
73fn create_self_position_kind(caller_kind: FnKind, callee_kind: FnKind) -> SelfPositionKind {
74 match (caller_kind, callee_kind) {
75 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
76 | (FnKind::AssocTraitImpl, FnKind::AssocTrait)
77 | (FnKind::AssocTrait, FnKind::AssocTrait)
78 | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
79
80 (FnKind::Free, FnKind::AssocTrait) => SelfPositionKind::AfterLifetimes,
81
82 _ => SelfPositionKind::None,
83 }
84}
85
86#[derive(#[automatically_derived]
impl ::core::clone::Clone for FnKind {
#[inline]
fn clone(&self) -> FnKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FnKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for FnKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
FnKind::Free => "Free",
FnKind::AssocInherentImpl => "AssocInherentImpl",
FnKind::AssocTrait => "AssocTrait",
FnKind::AssocTraitImpl => "AssocTraitImpl",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for FnKind {
#[inline]
fn eq(&self, other: &FnKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
87enum FnKind {
88 Free,
89 AssocInherentImpl,
90 AssocTrait,
91 AssocTraitImpl,
92}
93
94fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> FnKind {
95 let def_id = def_id.into();
96
97 if true {
match tcx.def_kind(def_id) {
DefKind::Fn | DefKind::AssocFn => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Fn | DefKind::AssocFn",
::core::option::Option::None);
}
};
};debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
98
99 let parent = tcx.parent(def_id);
100 match tcx.def_kind(parent) {
101 DefKind::Trait => FnKind::AssocTrait,
102 DefKind::Impl { of_trait: true } => FnKind::AssocTraitImpl,
103 DefKind::Impl { of_trait: false } => FnKind::AssocInherentImpl,
104 _ => FnKind::Free,
105 }
106}
107
108#[derive(#[automatically_derived]
impl ::core::clone::Clone for InheritanceKind {
#[inline]
fn clone(&self) -> InheritanceKind {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InheritanceKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for InheritanceKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
InheritanceKind::WithParent(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"WithParent", &__self_0),
InheritanceKind::Own =>
::core::fmt::Formatter::write_str(f, "Own"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for InheritanceKind {
#[inline]
fn eq(&self, other: &InheritanceKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(InheritanceKind::WithParent(__self_0),
InheritanceKind::WithParent(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
111enum InheritanceKind {
112 WithParent(bool),
122 Own,
126}
127
128fn create_mapping<'tcx>(
138 tcx: TyCtxt<'tcx>,
139 sig_id: DefId,
140 def_id: LocalDefId,
141) -> FxHashMap<u32, u32> {
142 let mut mapping: FxHashMap<u32, u32> = Default::default();
143
144 let (caller_kind, callee_kind) = (fn_kind(tcx, def_id), fn_kind(tcx, sig_id));
145 let self_pos_kind = create_self_position_kind(caller_kind, callee_kind);
146 let is_self_at_zero = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::Zero => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::Zero);
147
148 if is_self_at_zero {
150 mapping.insert(0, 0);
151 }
152
153 let mut args_index = 0;
154
155 args_index += is_self_at_zero as usize;
156 args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id);
157
158 let sig_generics = tcx.generics_of(sig_id);
159 let process_sig_parent_generics = #[allow(non_exhaustive_omitted_patterns)] match callee_kind {
FnKind::AssocTrait => true,
_ => false,
}matches!(callee_kind, FnKind::AssocTrait);
160
161 if process_sig_parent_generics {
162 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
163 let param = sig_generics.param_at(i, tcx);
164 if !param.kind.is_ty_or_const() {
165 mapping.insert(param.index, args_index as u32);
166 args_index += 1;
167 }
168 }
169 }
170
171 for param in &sig_generics.own_params {
172 if !param.kind.is_ty_or_const() {
173 mapping.insert(param.index, args_index as u32);
174 args_index += 1;
175 }
176 }
177
178 if #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::AfterLifetimes) {
180 mapping.insert(0, args_index as u32);
181 args_index += 1;
182 }
183
184 if process_sig_parent_generics {
185 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
186 let param = sig_generics.param_at(i, tcx);
187 if param.kind.is_ty_or_const() {
188 mapping.insert(param.index, args_index as u32);
189 args_index += 1;
190 }
191 }
192 }
193
194 for param in &sig_generics.own_params {
195 if param.kind.is_ty_or_const() {
196 mapping.insert(param.index, args_index as u32);
197 args_index += 1;
198 }
199 }
200
201 mapping
202}
203
204fn get_delegation_parent_args_count_without_self<'tcx>(
205 tcx: TyCtxt<'tcx>,
206 delegation_id: LocalDefId,
207 sig_id: DefId,
208) -> usize {
209 let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count;
210
211 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
212 (FnKind::Free, FnKind::Free)
213 | (FnKind::Free, FnKind::AssocTrait)
214 | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
215
216 (FnKind::AssocInherentImpl, FnKind::Free)
217 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
218 delegation_parent_args_count }
220
221 (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => {
222 delegation_parent_args_count - 1 }
224
225 (FnKind::AssocTraitImpl, _)
228 | (_, FnKind::AssocTraitImpl)
229 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
230 }
231}
232
233fn get_parent_and_inheritance_kind<'tcx>(
234 tcx: TyCtxt<'tcx>,
235 def_id: LocalDefId,
236 sig_id: DefId,
237) -> (Option<DefId>, InheritanceKind) {
238 match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) {
239 (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
240 (None, InheritanceKind::WithParent(true))
241 }
242
243 (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
244 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own)
245 }
246
247 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
248 | (FnKind::AssocTrait, FnKind::AssocTrait)
249 | (FnKind::AssocInherentImpl, FnKind::Free)
250 | (FnKind::AssocTrait, FnKind::Free) => {
251 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false))
252 }
253
254 (FnKind::AssocTraitImpl, _)
257 | (_, FnKind::AssocTraitImpl)
258 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
259 }
260}
261
262fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
263 let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
264 let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
265
266 match (caller_kind, callee_kind) {
267 (FnKind::Free, FnKind::AssocTrait)
268 | (FnKind::AssocInherentImpl, FnKind::Free)
269 | (FnKind::Free, FnKind::Free)
270 | (FnKind::AssocTrait, FnKind::Free)
271 | (FnKind::AssocTrait, FnKind::AssocTrait) => {
272 match create_self_position_kind(caller_kind, callee_kind) {
273 SelfPositionKind::None => None,
274 SelfPositionKind::AfterLifetimes => {
275 Some(tcx.generics_of(delegation_id).own_counts().lifetimes)
277 }
278 SelfPositionKind::Zero => Some(0),
279 }
280 .map(|self_index| Ty::new_param(tcx, self_index as u32, kw::SelfUpper))
281 }
282
283 (FnKind::AssocTraitImpl, FnKind::AssocTrait)
284 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
285 Some(tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity())
286 }
287
288 (FnKind::AssocTraitImpl, _)
291 | (_, FnKind::AssocTraitImpl)
292 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
293 }
294}
295
296fn create_generic_args<'tcx>(
312 tcx: TyCtxt<'tcx>,
313 sig_id: DefId,
314 delegation_id: LocalDefId,
315 mut parent_args: &[ty::GenericArg<'tcx>],
316 child_args: &[ty::GenericArg<'tcx>],
317) -> Vec<ty::GenericArg<'tcx>> {
318 let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
319
320 let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
321
322 let deleg_parent_args_without_self_count =
323 get_delegation_parent_args_count_without_self(tcx, delegation_id, sig_id);
324
325 let delegation_generics = tcx.generics_of(delegation_id);
326 let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
327 let synth_args = &delegation_args[real_args_count..];
328 let delegation_args = &delegation_args[..real_args_count];
329
330 let args = match (caller_kind, callee_kind) {
331 (FnKind::Free, FnKind::Free)
332 | (FnKind::Free, FnKind::AssocTrait)
333 | (FnKind::AssocInherentImpl, FnKind::Free)
334 | (FnKind::AssocTrait, FnKind::Free)
335 | (FnKind::AssocTrait, FnKind::AssocTrait) => delegation_args,
336
337 (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
338 let parent = tcx.local_parent(delegation_id);
342 parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().args;
343
344 if !child_args.is_empty() {
{
::core::panicking::panic_fmt(format_args!("Child args can not be used in trait impl case"));
}
};assert!(child_args.is_empty(), "Child args can not be used in trait impl case");
345
346 tcx.mk_args(&delegation_args[delegation_generics.parent_count..])
347 }
348
349 (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
350 let self_ty = tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity();
351
352 tcx.mk_args_from_iter(
353 std::iter::once(ty::GenericArg::from(self_ty))
354 .chain(delegation_args.iter().copied()),
355 )
356 }
357
358 (FnKind::AssocTraitImpl, _)
361 | (_, FnKind::AssocTraitImpl)
362 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
363 };
364
365 let mut new_args = ::alloc::vec::Vec::new()vec![];
366
367 let self_pos_kind = create_self_position_kind(caller_kind, callee_kind);
368 let mut lifetimes_end_pos;
369
370 if !parent_args.is_empty() {
371 let parent_args_lifetimes_count =
372 parent_args.iter().filter(|a| a.as_region().is_some()).count();
373
374 match self_pos_kind {
375 SelfPositionKind::AfterLifetimes => {
376 new_args.extend(&parent_args[1..1 + parent_args_lifetimes_count]);
377
378 lifetimes_end_pos = parent_args_lifetimes_count;
379
380 new_args.push(parent_args[0]);
381
382 new_args.extend(&parent_args[1 + parent_args_lifetimes_count..]);
383 }
384 SelfPositionKind::Zero => {
385 lifetimes_end_pos = 1 + parent_args_lifetimes_count;
386 new_args.extend_from_slice(parent_args);
387
388 for i in 0..deleg_parent_args_without_self_count {
389 new_args.insert(1 + i, args[1 + i]);
390 }
391
392 lifetimes_end_pos += deleg_parent_args_without_self_count;
393 }
394 SelfPositionKind::None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
396 };
397 } else {
398 let self_impact = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::Zero => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::Zero) as usize;
399
400 lifetimes_end_pos = self_impact
401 + deleg_parent_args_without_self_count
402 + &args[self_impact + deleg_parent_args_without_self_count..]
403 .iter()
404 .filter(|a| a.as_region().is_some())
405 .count();
406
407 new_args.extend_from_slice(args);
408 }
409
410 if !child_args.is_empty() {
411 let child_lifetimes_count = child_args.iter().filter(|a| a.as_region().is_some()).count();
412
413 for i in 0..child_lifetimes_count {
414 new_args.insert(lifetimes_end_pos + i, child_args[i]);
415 }
416
417 new_args.extend_from_slice(&child_args[child_lifetimes_count..]);
418 } else if !parent_args.is_empty() {
419 let child_args = &delegation_args[delegation_generics.parent_count..];
420
421 let child_lifetimes_count =
422 child_args.iter().take_while(|a| a.as_region().is_some()).count();
423
424 for i in 0..child_lifetimes_count {
425 new_args.insert(lifetimes_end_pos + i, child_args[i]);
426 }
427
428 let skip_self = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::AfterLifetimes);
429 new_args.extend(&child_args[child_lifetimes_count + skip_self as usize..]);
430 }
431
432 new_args.extend(synth_args);
433
434 new_args
435}
436
437pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
438 tcx: TyCtxt<'tcx>,
439 def_id: LocalDefId,
440 sig_id: DefId,
441) -> ty::GenericPredicates<'tcx> {
442 struct PredicatesCollector<'tcx> {
443 tcx: TyCtxt<'tcx>,
444 preds: Vec<(ty::Clause<'tcx>, Span)>,
445 args: Vec<ty::GenericArg<'tcx>>,
446 folder: ParamIndexRemapper<'tcx>,
447 }
448
449 impl<'tcx> PredicatesCollector<'tcx> {
450 fn with_own_preds(
451 mut self,
452 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
453 def_id: DefId,
454 ) -> Self {
455 let preds = f(def_id);
456 let args = self.args.as_slice();
457
458 for pred in preds.predicates {
459 let new_pred = pred.0.fold_with(&mut self.folder);
460 self.preds.push((EarlyBinder::bind(new_pred).instantiate(self.tcx, args), pred.1));
461 }
462
463 self
464 }
465
466 fn with_preds(
467 mut self,
468 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
469 def_id: DefId,
470 ) -> Self {
471 let preds = f(def_id);
472 if let Some(parent_def_id) = preds.parent {
473 self = self.with_own_preds(f, parent_def_id);
474 }
475
476 self.with_own_preds(f, def_id)
477 }
478 }
479
480 let (parent_args, child_args) = get_delegation_user_specified_args(tcx, def_id);
481 let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
482 let collector = PredicatesCollector { tcx, preds: ::alloc::vec::Vec::new()vec![], args, folder };
483
484 let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id);
485
486 let preds = match inh_kind {
490 InheritanceKind::WithParent(false) => {
491 collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id)
492 }
493 InheritanceKind::WithParent(true) => {
494 collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id)
495 }
496 InheritanceKind::Own => {
497 collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id)
498 }
499 }
500 .preds;
501
502 ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) }
503}
504
505fn create_folder_and_args<'tcx>(
506 tcx: TyCtxt<'tcx>,
507 def_id: LocalDefId,
508 sig_id: DefId,
509 parent_args: &'tcx [ty::GenericArg<'tcx>],
510 child_args: &'tcx [ty::GenericArg<'tcx>],
511) -> (ParamIndexRemapper<'tcx>, Vec<ty::GenericArg<'tcx>>) {
512 let args = create_generic_args(tcx, sig_id, def_id, parent_args, child_args);
513 let remap_table = create_mapping(tcx, sig_id, def_id);
514
515 (ParamIndexRemapper { tcx, remap_table }, args)
516}
517
518fn check_constraints<'tcx>(
519 tcx: TyCtxt<'tcx>,
520 def_id: LocalDefId,
521 sig_id: DefId,
522) -> Result<(), ErrorGuaranteed> {
523 let mut ret = Ok(());
524
525 let mut emit = |descr| {
526 ret = Err(tcx.dcx().emit_err(crate::errors::UnsupportedDelegation {
527 span: tcx.def_span(def_id),
528 descr,
529 callee_span: tcx.def_span(sig_id),
530 }));
531 };
532
533 if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic {
534 emit("delegation to C-variadic functions is not allowed");
536 }
537
538 ret
539}
540
541pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
542 tcx: TyCtxt<'tcx>,
543 def_id: LocalDefId,
544) -> &'tcx [Ty<'tcx>] {
545 let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("Delegation must have sig_id");
546 let caller_sig = tcx.fn_sig(sig_id);
547
548 if let Err(err) = check_constraints(tcx, def_id, sig_id) {
549 let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
550 let err_type = Ty::new_error(tcx, err);
551 return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type));
552 }
553
554 let (parent_args, child_args) = get_delegation_user_specified_args(tcx, def_id);
555 let (mut folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
556 let caller_sig = EarlyBinder::bind(caller_sig.skip_binder().fold_with(&mut folder));
557
558 let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_binder();
559 let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output()));
560 tcx.arena.alloc_from_iter(sig_iter)
561}
562
563fn get_delegation_user_specified_args<'tcx>(
568 tcx: TyCtxt<'tcx>,
569 delegation_id: LocalDefId,
570) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
571 let info = tcx
572 .hir_node(tcx.local_def_id_to_hir_id(delegation_id))
573 .fn_sig()
574 .expect("Lowering delegation")
575 .decl
576 .opt_delegation_generics()
577 .expect("Lowering delegation");
578
579 let get_segment = |hir_id: HirId| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
580 let segment = tcx.hir_node(hir_id).expect_path_segment();
581 segment.res.opt_def_id().map(|def_id| (segment, def_id))
582 };
583
584 let ctx = ItemCtxt::new(tcx, delegation_id);
585 let lowerer = ctx.lowerer();
586
587 let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| {
588 let self_ty = get_delegation_self_ty(tcx, delegation_id);
589
590 lowerer
591 .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty)
592 .0
593 .as_slice()
594 });
595
596 let child_args = info
597 .child_args_segment_id
598 .and_then(get_segment)
599 .filter(|(_, def_id)| #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(*def_id) {
DefKind::Fn | DefKind::AssocFn => true,
_ => false,
}matches!(tcx.def_kind(*def_id), DefKind::Fn | DefKind::AssocFn))
600 .map(|(segment, def_id)| {
601 let parent_args = if let Some(parent_args) = parent_args {
602 parent_args
603 } else {
604 let parent = tcx.parent(def_id);
605 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(parent) {
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(parent), DefKind::Trait) {
606 ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
607 } else {
608 &[]
609 }
610 };
611
612 let args = lowerer
613 .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None)
614 .0;
615
616 let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count();
617 &args[parent_args.len()..args.len() - synth_params_count]
618 });
619
620 (parent_args.unwrap_or_default(), child_args.unwrap_or_default())
621}