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::{DelegationSelfTyPropagationKind, 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
67#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SelfPositionKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SelfPositionKind::AfterLifetimes(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"AfterLifetimes", &__self_0),
SelfPositionKind::Zero =>
::core::fmt::Formatter::write_str(f, "Zero"),
SelfPositionKind::None =>
::core::fmt::Formatter::write_str(f, "None"),
}
}
}Debug)]
68enum SelfPositionKind {
69 AfterLifetimes(Option<DelegationSelfTyPropagationKind>),
70 Zero,
71 None,
72}
73
74fn create_self_position_kind(
75 tcx: TyCtxt<'_>,
76 delegation_id: LocalDefId,
77 sig_id: DefId,
78) -> SelfPositionKind {
79 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
80 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
81 | (FnKind::AssocTraitImpl, FnKind::AssocTrait)
82 | (FnKind::AssocTrait, FnKind::AssocTrait)
83 | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
84
85 (FnKind::Free, FnKind::AssocTrait) => {
86 let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind;
87 SelfPositionKind::AfterLifetimes(kind)
88 }
89
90 _ => SelfPositionKind::None,
91 }
92}
93
94#[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)]
95enum FnKind {
96 Free,
97 AssocInherentImpl,
98 AssocTrait,
99 AssocTraitImpl,
100}
101
102fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> FnKind {
103 let def_id = def_id.into();
104
105 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);
106
107 let parent = tcx.parent(def_id);
108 match tcx.def_kind(parent) {
109 DefKind::Trait => FnKind::AssocTrait,
110 DefKind::Impl { of_trait: true } => FnKind::AssocTraitImpl,
111 DefKind::Impl { of_trait: false } => FnKind::AssocInherentImpl,
112 _ => FnKind::Free,
113 }
114}
115
116#[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)]
119enum InheritanceKind {
120 WithParent(bool),
130 Own,
134}
135
136fn create_mapping<'tcx>(
146 tcx: TyCtxt<'tcx>,
147 sig_id: DefId,
148 def_id: LocalDefId,
149) -> FxHashMap<u32, u32> {
150 let mut mapping: FxHashMap<u32, u32> = Default::default();
151
152 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
153 let is_self_at_zero = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::Zero => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::Zero);
154
155 if is_self_at_zero {
157 mapping.insert(0, 0);
158 }
159
160 let mut args_index = 0;
161
162 args_index += is_self_at_zero as usize;
163 args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id);
164
165 let sig_generics = tcx.generics_of(sig_id);
166 let process_sig_parent_generics = #[allow(non_exhaustive_omitted_patterns)] match fn_kind(tcx, sig_id) {
FnKind::AssocTrait => true,
_ => false,
}matches!(fn_kind(tcx, sig_id), FnKind::AssocTrait);
167
168 if process_sig_parent_generics {
169 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
170 let param = sig_generics.param_at(i, tcx);
171 if !param.kind.is_ty_or_const() {
172 mapping.insert(param.index, args_index as u32);
173 args_index += 1;
174 }
175 }
176 }
177
178 for param in &sig_generics.own_params {
179 if !param.kind.is_ty_or_const() {
180 mapping.insert(param.index, args_index as u32);
181 args_index += 1;
182 }
183 }
184
185 if #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes { .. } => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::AfterLifetimes { .. }) {
189 mapping.insert(0, args_index as u32);
190 args_index += 1;
191 }
192
193 if process_sig_parent_generics {
194 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
195 let param = sig_generics.param_at(i, tcx);
196 if param.kind.is_ty_or_const() {
197 mapping.insert(param.index, args_index as u32);
198 args_index += 1;
199 }
200 }
201 }
202
203 for param in &sig_generics.own_params {
204 if param.kind.is_ty_or_const() {
205 mapping.insert(param.index, args_index as u32);
206 args_index += 1;
207 }
208 }
209
210 mapping
211}
212
213fn get_delegation_parent_args_count_without_self<'tcx>(
214 tcx: TyCtxt<'tcx>,
215 delegation_id: LocalDefId,
216 sig_id: DefId,
217) -> usize {
218 let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count;
219
220 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
221 (FnKind::Free, FnKind::Free)
222 | (FnKind::Free, FnKind::AssocTrait)
223 | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
224
225 (FnKind::AssocInherentImpl, FnKind::Free)
226 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
227 delegation_parent_args_count }
229
230 (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => {
231 delegation_parent_args_count - 1 }
233
234 (FnKind::AssocTraitImpl, _)
237 | (_, FnKind::AssocTraitImpl)
238 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
239 }
240}
241
242fn get_parent_and_inheritance_kind<'tcx>(
243 tcx: TyCtxt<'tcx>,
244 def_id: LocalDefId,
245 sig_id: DefId,
246) -> (Option<DefId>, InheritanceKind) {
247 match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) {
248 (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
249 (None, InheritanceKind::WithParent(true))
250 }
251
252 (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
253 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own)
254 }
255
256 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
257 | (FnKind::AssocTrait, FnKind::AssocTrait)
258 | (FnKind::AssocInherentImpl, FnKind::Free)
259 | (FnKind::AssocTrait, FnKind::Free) => {
260 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false))
261 }
262
263 (FnKind::AssocTraitImpl, _)
266 | (_, FnKind::AssocTraitImpl)
267 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
268 }
269}
270
271fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
272 let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
273 let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
274
275 match (caller_kind, callee_kind) {
276 (FnKind::Free, FnKind::AssocTrait)
277 | (FnKind::AssocInherentImpl, FnKind::Free)
278 | (FnKind::Free, FnKind::Free)
279 | (FnKind::AssocTrait, FnKind::Free)
280 | (FnKind::AssocTrait, FnKind::AssocTrait) => {
281 match create_self_position_kind(tcx, delegation_id, sig_id) {
282 SelfPositionKind::None => None,
283 SelfPositionKind::AfterLifetimes(propagation_kind) => {
284 Some(match propagation_kind {
285 Some(kind) => match kind {
286 DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => {
287 let ctx = ItemCtxt::new(tcx, delegation_id);
288 ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty())
289 }
290 DelegationSelfTyPropagationKind::SelfParam => {
291 let index = tcx.generics_of(delegation_id).own_counts().lifetimes;
292 Ty::new_param(tcx, index as u32, kw::SelfUpper)
293 }
294 },
295 None => Ty::new_error_with_message(
296 tcx,
297 tcx.def_span(delegation_id),
298 "self propagation kind must be specified for `AfterLifetimes` variant",
299 ),
300 })
301 }
302 SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
303 }
304 }
305
306 (FnKind::AssocTraitImpl, FnKind::AssocTrait)
307 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some(
308 tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(),
309 ),
310
311 (FnKind::AssocTraitImpl, _)
314 | (_, FnKind::AssocTraitImpl)
315 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
316 }
317}
318
319fn create_generic_args<'tcx>(
335 tcx: TyCtxt<'tcx>,
336 sig_id: DefId,
337 delegation_id: LocalDefId,
338 mut parent_args: &[ty::GenericArg<'tcx>],
339 mut child_args: &[ty::GenericArg<'tcx>],
340) -> Vec<ty::GenericArg<'tcx>> {
341 let delegation_generics = tcx.generics_of(delegation_id);
342 let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
343
344 let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
345 let synth_args = &delegation_args[real_args_count..];
346
347 let mut delegation_parent_args =
348 &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count];
349
350 let delegation_args = &delegation_args[delegation_generics.parent_count..];
351
352 let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
353 if #[allow(non_exhaustive_omitted_patterns)] match kinds {
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => true,
_ => false,
}matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) {
354 let parent = tcx.local_parent(delegation_id);
358
359 parent_args =
360 tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
361
362 child_args =
363 &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..];
364
365 delegation_parent_args = &[];
366 }
367
368 let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into());
369
370 if self_type.is_some() && !parent_args.is_empty() {
373 parent_args = &parent_args[1..];
374 }
375
376 let (zero_self, after_lifetimes_self) =
377 match create_self_position_kind(tcx, delegation_id, sig_id) {
378 SelfPositionKind::AfterLifetimes(_) => {
379 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
380 (None, self_type)
381 }
382 SelfPositionKind::Zero => {
383 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
384 (self_type, None)
385 }
386 SelfPositionKind::None => (None, None),
387 };
388
389 let zero_self = zero_self.as_ref().into_iter();
390 let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter();
391
392 zero_self
393 .chain(delegation_parent_args)
394 .chain(parent_args.iter().filter(|a| a.as_region().is_some()))
395 .chain(child_args.iter().filter(|a| a.as_region().is_some()))
396 .chain(after_lifetimes_self)
397 .chain(parent_args.iter().filter(|a| a.as_region().is_none()))
398 .chain(child_args.iter().filter(|a| a.as_region().is_none()))
399 .chain(synth_args)
400 .copied()
401 .collect::<Vec<_>>()
402}
403
404pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
405 tcx: TyCtxt<'tcx>,
406 def_id: LocalDefId,
407 sig_id: DefId,
408) -> ty::GenericPredicates<'tcx> {
409 struct PredicatesCollector<'tcx> {
410 tcx: TyCtxt<'tcx>,
411 preds: Vec<(ty::Clause<'tcx>, Span)>,
412 args: Vec<ty::GenericArg<'tcx>>,
413 folder: ParamIndexRemapper<'tcx>,
414 filter_self_preds: bool,
415 }
416
417 impl<'tcx> PredicatesCollector<'tcx> {
418 fn with_own_preds(
419 mut self,
420 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
421 def_id: DefId,
422 ) -> Self {
423 let preds = f(def_id);
424 let args = self.args.as_slice();
425
426 for pred in preds.predicates {
427 if self.filter_self_preds
430 && let Some(trait_pred) = pred.0.as_trait_clause()
431 && trait_pred.self_ty().skip_binder().is_param(0)
433 {
434 continue;
435 }
436
437 let new_pred = pred.0.fold_with(&mut self.folder);
438 self.preds.push((
439 EarlyBinder::bind(self.tcx, new_pred)
440 .instantiate(self.tcx, args)
441 .skip_norm_wip(),
442 pred.1,
443 ));
444 }
445
446 self
447 }
448
449 fn with_preds(
450 mut self,
451 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
452 def_id: DefId,
453 ) -> Self {
454 let preds = f(def_id);
455 if let Some(parent_def_id) = preds.parent {
456 self = self.with_own_preds(f, parent_def_id);
457 }
458
459 self.with_own_preds(f, def_id)
460 }
461 }
462
463 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
464 let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
465 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
466 let filter_self_preds = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
=> true,
_ => false,
}matches!(
467 self_pos_kind,
468 SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
469 );
470
471 let collector = PredicatesCollector { tcx, preds: ::alloc::vec::Vec::new()vec![], args, folder, filter_self_preds };
472 let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id);
473
474 let preds = match inh_kind {
478 InheritanceKind::WithParent(false) => {
479 collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id)
480 }
481 InheritanceKind::WithParent(true) => {
482 collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id)
483 }
484 InheritanceKind::Own => {
485 collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id)
486 }
487 }
488 .preds;
489
490 ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) }
491}
492
493fn create_folder_and_args<'tcx>(
494 tcx: TyCtxt<'tcx>,
495 def_id: LocalDefId,
496 sig_id: DefId,
497 parent_args: &'tcx [ty::GenericArg<'tcx>],
498 child_args: &'tcx [ty::GenericArg<'tcx>],
499) -> (ParamIndexRemapper<'tcx>, Vec<ty::GenericArg<'tcx>>) {
500 let args = create_generic_args(tcx, sig_id, def_id, parent_args, child_args);
501 let remap_table = create_mapping(tcx, sig_id, def_id);
502
503 (ParamIndexRemapper { tcx, remap_table }, args)
504}
505
506fn check_constraints<'tcx>(
507 tcx: TyCtxt<'tcx>,
508 def_id: LocalDefId,
509 sig_id: DefId,
510) -> Result<(), ErrorGuaranteed> {
511 let mut ret = Ok(());
512
513 let mut emit = |descr| {
514 ret = Err(tcx.dcx().emit_err(crate::diagnostics::UnsupportedDelegation {
515 span: tcx.def_span(def_id),
516 descr,
517 callee_span: tcx.def_span(sig_id),
518 }));
519 };
520
521 if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic() {
522 emit("delegation to C-variadic functions is not allowed");
524 }
525
526 ret
527}
528
529pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
530 tcx: TyCtxt<'tcx>,
531 def_id: LocalDefId,
532) -> &'tcx [Ty<'tcx>] {
533 let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("Delegation must have sig_id");
534 let caller_sig = tcx.fn_sig(sig_id);
535
536 if let Err(err) = check_constraints(tcx, def_id, sig_id) {
537 let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
538 let err_type = Ty::new_error(tcx, err);
539 return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type));
540 }
541
542 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
543 let (mut folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
544 let caller_sig = EarlyBinder::bind(tcx, caller_sig.skip_binder().fold_with(&mut folder));
545
546 let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_binder();
547 let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output()));
548 tcx.arena.alloc_from_iter(sig_iter)
549}
550
551pub(crate) fn delegation_user_specified_args<'tcx>(
556 tcx: TyCtxt<'tcx>,
557 delegation_id: LocalDefId,
558) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
559 let info = tcx.hir_delegation_info(delegation_id);
560
561 let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
562 let segment = tcx.hir_node(hir_id).expect_path_segment();
563 segment.res.opt_def_id().map(|def_id| (segment, def_id))
564 };
565
566 let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id);
567 let lowerer = ctx.lowerer();
568 let parent_args = info
569 .parent_seg_id_for_sig
570 .and_then(get_segment)
571 .filter(|(_, def_id)| #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(*def_id) {
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(*def_id), DefKind::Trait))
572 .map(|(segment, def_id)| {
573 let self_ty = get_delegation_self_ty(tcx, delegation_id);
574
575 lowerer
576 .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty)
577 .0
578 .as_slice()
579 });
580
581 let child_args = info
582 .child_seg_id_for_sig
583 .and_then(get_segment)
584 .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))
585 .map(|(segment, def_id)| {
586 let parent_args = if let Some(parent_args) = parent_args {
587 parent_args
588 } else {
589 let parent = tcx.parent(def_id);
590 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(parent) {
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(parent), DefKind::Trait) {
591 ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
592 } else {
593 &[]
594 }
595 };
596
597 let args = lowerer
598 .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None)
599 .0;
600
601 let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count();
602 &args[parent_args.len()..args.len() - synth_params_count]
603 });
604
605 (parent_args.unwrap_or_default(), child_args.unwrap_or_default())
606}