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