1use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6use rustc_hir::def::DefKind;
7use rustc_hir::def_id::{DefId, LocalDefId};
8use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment};
9use rustc_middle::ty::{
10 self, EarlyBinder, RegionExt, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
11 TypeVisitableExt,
12};
13use rustc_span::{ErrorGuaranteed, Span, kw};
14
15use crate::collect::ItemCtxt;
16use crate::hir_ty_lowering::HirTyLowerer;
17
18type RemapTable = FxHashMap<u32, u32>;
19
20struct ParamIndexRemapper<'tcx> {
21 tcx: TyCtxt<'tcx>,
22 remap_table: RemapTable,
23 delegation_parent_consts: FxHashSet<ty::ParamConst>,
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 match tcx.def_kind(def_id) {
106 DefKind::Fn => FnKind::Free,
107 DefKind::AssocFn => match tcx.def_kind(tcx.parent(def_id)) {
108 DefKind::Trait => FnKind::AssocTrait,
109 DefKind::Impl { of_trait } => match of_trait {
110 true => FnKind::AssocTraitImpl,
111 false => FnKind::AssocInherentImpl,
112 },
113 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("associated function can only be in trait or impl")));
}unreachable!("associated function can only be in trait or impl"),
114 },
115 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("delegation/signature can be either free or associated function")));
}unreachable!("delegation/signature can be either free or associated function"),
116 }
117}
118
119#[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)]
122enum InheritanceKind {
123 WithParent(bool),
133 Own,
137}
138
139fn create_mapping<'tcx>(
149 tcx: TyCtxt<'tcx>,
150 sig_id: DefId,
151 def_id: LocalDefId,
152) -> FxHashMap<u32, u32> {
153 let mut mapping: FxHashMap<u32, u32> = Default::default();
154
155 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
156 let is_self_at_zero = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::Zero => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::Zero);
157
158 if is_self_at_zero {
160 mapping.insert(0, 0);
161 }
162
163 let mut args_index = 0;
164
165 args_index += is_self_at_zero as usize;
166 args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id);
167
168 let sig_generics = tcx.generics_of(sig_id);
169 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);
170
171 if process_sig_parent_generics {
172 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
173 let param = sig_generics.param_at(i, tcx);
174 if !param.kind.is_ty_or_const() {
175 mapping.insert(param.index, args_index as u32);
176 args_index += 1;
177 }
178 }
179 }
180
181 for param in &sig_generics.own_params {
182 if !param.kind.is_ty_or_const() {
183 mapping.insert(param.index, args_index as u32);
184 args_index += 1;
185 }
186 }
187
188 if #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes { .. } => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::AfterLifetimes { .. }) {
192 mapping.insert(0, args_index as u32);
193 args_index += 1;
194 }
195
196 if process_sig_parent_generics {
197 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
198 let param = sig_generics.param_at(i, tcx);
199 if param.kind.is_ty_or_const() {
200 mapping.insert(param.index, args_index as u32);
201 args_index += 1;
202 }
203 }
204 }
205
206 for param in &sig_generics.own_params {
207 if param.kind.is_ty_or_const() {
208 mapping.insert(param.index, args_index as u32);
209 args_index += 1;
210 }
211 }
212
213 mapping
214}
215
216fn get_delegation_parent_args_count_without_self<'tcx>(
217 tcx: TyCtxt<'tcx>,
218 delegation_id: LocalDefId,
219 sig_id: DefId,
220) -> usize {
221 let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count;
222
223 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
224 (FnKind::Free, FnKind::Free)
225 | (FnKind::Free, FnKind::AssocTrait)
226 | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
227
228 (FnKind::AssocInherentImpl, FnKind::Free)
229 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
230 delegation_parent_args_count }
232
233 (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => {
234 delegation_parent_args_count - 1 }
236
237 (FnKind::AssocTraitImpl, _)
240 | (_, FnKind::AssocTraitImpl)
241 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
242 }
243}
244
245fn get_parent_and_inheritance_kind<'tcx>(
246 tcx: TyCtxt<'tcx>,
247 def_id: LocalDefId,
248 sig_id: DefId,
249) -> (Option<DefId>, InheritanceKind) {
250 match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) {
251 (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
252 (None, InheritanceKind::WithParent(true))
253 }
254
255 (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
256 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own)
257 }
258
259 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
260 | (FnKind::AssocTrait, FnKind::AssocTrait)
261 | (FnKind::AssocInherentImpl, FnKind::Free)
262 | (FnKind::AssocTrait, FnKind::Free) => {
263 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false))
264 }
265
266 (FnKind::AssocTraitImpl, _)
269 | (_, FnKind::AssocTraitImpl)
270 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
271 }
272}
273
274fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
275 let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
276 let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
277
278 match (caller_kind, callee_kind) {
279 (FnKind::Free, FnKind::AssocTrait)
280 | (FnKind::AssocInherentImpl, FnKind::Free)
281 | (FnKind::Free, FnKind::Free)
282 | (FnKind::AssocTrait, FnKind::Free)
283 | (FnKind::AssocTrait, FnKind::AssocTrait) => {
284 match create_self_position_kind(tcx, delegation_id, sig_id) {
285 SelfPositionKind::None => None,
286 SelfPositionKind::AfterLifetimes(propagation_kind) => {
287 Some(match propagation_kind {
288 Some(kind) => match kind {
289 DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => {
290 let ctx = ItemCtxt::new(tcx, delegation_id);
291 ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty())
292 }
293 DelegationSelfTyPropagationKind::SelfParam => {
294 let index = tcx.generics_of(delegation_id).own_counts().lifetimes;
295 Ty::new_param(tcx, index as u32, kw::SelfUpper)
296 }
297 },
298 None => Ty::new_error_with_message(
299 tcx,
300 tcx.def_span(delegation_id),
301 "self propagation kind must be specified for `AfterLifetimes` variant",
302 ),
303 })
304 }
305 SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
306 }
307 }
308
309 (FnKind::AssocTraitImpl, FnKind::AssocTrait)
310 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some(
311 tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(),
312 ),
313
314 (FnKind::AssocTraitImpl, _)
317 | (_, FnKind::AssocTraitImpl)
318 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
319 }
320}
321
322fn create_generic_args<'tcx>(
338 tcx: TyCtxt<'tcx>,
339 sig_id: DefId,
340 delegation_id: LocalDefId,
341 mut parent_args: &[ty::GenericArg<'tcx>],
342 mut child_args: &[ty::GenericArg<'tcx>],
343) -> (Vec<ty::GenericArg<'tcx>>, &'tcx [ty::GenericArg<'tcx>]) {
344 let delegation_generics = tcx.generics_of(delegation_id);
345 let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
346
347 let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
348 let synth_args = &delegation_args[real_args_count..];
349
350 let mut delegation_parent_args =
351 &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count];
352
353 let delegation_args = &delegation_args[delegation_generics.parent_count..];
354
355 let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
356 if #[allow(non_exhaustive_omitted_patterns)] match kinds {
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => true,
_ => false,
}matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) {
357 let parent = tcx.local_parent(delegation_id);
361
362 parent_args =
363 tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
364
365 child_args =
366 &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..];
367
368 delegation_parent_args = &[];
369 }
370
371 let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into());
372
373 if self_type.is_some() && !parent_args.is_empty() {
376 parent_args = &parent_args[1..];
377 }
378
379 let (zero_self, after_lifetimes_self) =
380 match create_self_position_kind(tcx, delegation_id, sig_id) {
381 SelfPositionKind::AfterLifetimes(_) => {
382 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
383 (None, self_type)
384 }
385 SelfPositionKind::Zero => {
386 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
387 (self_type, None)
388 }
389 SelfPositionKind::None => (None, None),
390 };
391
392 let zero_self = zero_self.as_ref().into_iter();
393 let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter();
394
395 let args = zero_self
396 .chain(delegation_parent_args)
397 .chain(parent_args.iter().filter(|a| a.as_region().is_some()))
398 .chain(child_args.iter().filter(|a| a.as_region().is_some()))
399 .chain(after_lifetimes_self)
400 .chain(parent_args.iter().filter(|a| a.as_region().is_none()))
401 .chain(child_args.iter().filter(|a| a.as_region().is_none()))
402 .chain(synth_args)
403 .copied()
404 .collect::<Vec<_>>();
405
406 (args, delegation_parent_args)
407}
408
409pub(crate) fn inherit_clauses_for_delegation_item<'tcx>(
410 tcx: TyCtxt<'tcx>,
411 def_id: LocalDefId,
412 sig_id: DefId,
413) -> ty::GenericClauses<'tcx> {
414 struct ClausesCollector<'tcx> {
415 tcx: TyCtxt<'tcx>,
416 clauses: Vec<(ty::Clause<'tcx>, Span)>,
417 args: Vec<ty::GenericArg<'tcx>>,
418 folder: ParamIndexRemapper<'tcx>,
419 filter_self_clauses: bool,
420 }
421
422 impl<'tcx> ClausesCollector<'tcx> {
423 fn with_own_clauses(
424 mut self,
425 f: impl Fn(DefId) -> ty::GenericClauses<'tcx>,
426 def_id: DefId,
427 ) -> Self {
428 let clauses = f(def_id);
429 let args = self.args.as_slice();
430
431 for clause in clauses.clauses {
432 if self.filter_self_clauses
435 && let Some(trait_clause) = clause.0.as_trait_clause()
436 && trait_clause.self_ty().skip_binder().is_param(0)
438 {
439 continue;
440 }
441
442 if let ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) =
470 clause.0.as_predicate().fold_with(&mut self.folder).kind().skip_binder()
471 {
472 let unnorm_const = EarlyBinder::bind(self.tcx, ct).instantiate(self.tcx, args);
473 if let ty::ConstKind::Param(param) = unnorm_const.skip_norm_wip().kind()
474 && self.folder.delegation_parent_consts.contains(¶m)
475 {
476 continue;
477 }
478 }
479
480 let new_clause = clause.0.fold_with(&mut self.folder);
481 self.clauses.push((
482 EarlyBinder::bind(self.tcx, new_clause)
483 .instantiate(self.tcx, args)
484 .skip_norm_wip(),
485 clause.1,
486 ));
487 }
488
489 self
490 }
491
492 fn with_clauses(
493 mut self,
494 f: impl Fn(DefId) -> ty::GenericClauses<'tcx> + Copy,
495 def_id: DefId,
496 ) -> Self {
497 let preds = f(def_id);
498 if let Some(parent_def_id) = preds.parent {
499 self = self.with_own_clauses(f, parent_def_id);
500 }
501
502 self.with_own_clauses(f, def_id)
503 }
504 }
505
506 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
507 let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
508 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
509 let filter_self_clauses = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
=> true,
_ => false,
}matches!(
510 self_pos_kind,
511 SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
512 );
513
514 let collector = ClausesCollector { tcx, clauses: ::alloc::vec::Vec::new()vec![], args, folder, filter_self_clauses };
515 let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id);
516
517 let clauses = match inh_kind {
521 InheritanceKind::WithParent(false) => {
522 collector.with_clauses(|def_id| tcx.explicit_clauses_of(def_id), sig_id)
523 }
524 InheritanceKind::WithParent(true) => {
525 collector.with_clauses(|def_id| tcx.clauses_of(def_id), sig_id)
526 }
527 InheritanceKind::Own => collector.with_own_clauses(|def_id| tcx.clauses_of(def_id), sig_id),
528 }
529 .clauses;
530
531 ty::GenericClauses { parent, clauses: tcx.arena.alloc_from_iter(clauses) }
532}
533
534fn create_folder_and_args<'tcx>(
535 tcx: TyCtxt<'tcx>,
536 def_id: LocalDefId,
537 sig_id: DefId,
538 parent_args: &'tcx [ty::GenericArg<'tcx>],
539 child_args: &'tcx [ty::GenericArg<'tcx>],
540) -> (ParamIndexRemapper<'tcx>, Vec<ty::GenericArg<'tcx>>) {
541 let (args, delegation_parent_args) =
542 create_generic_args(tcx, sig_id, def_id, parent_args, child_args);
543
544 let remap_table = create_mapping(tcx, sig_id, def_id);
545
546 let delegation_parent_consts = delegation_parent_args
547 .iter()
548 .filter_map(|a| {
549 a.as_const().and_then(|c| {
550 if let ty::ConstKind::Param(param) = c.kind() { Some(param) } else { None }
551 })
552 })
553 .collect();
554
555 (ParamIndexRemapper { tcx, remap_table, delegation_parent_consts }, args)
556}
557
558fn check_constraints<'tcx>(
559 tcx: TyCtxt<'tcx>,
560 def_id: LocalDefId,
561 sig_id: DefId,
562) -> Result<(), ErrorGuaranteed> {
563 let mut ret = Ok(());
564
565 let mut emit = |descr| {
566 ret = Err(tcx.dcx().emit_err(crate::diagnostics::UnsupportedDelegation {
567 span: tcx.def_span(def_id),
568 descr,
569 callee_span: tcx.def_span(sig_id),
570 }));
571 };
572
573 if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic() {
574 emit("delegation to C-variadic functions is not allowed");
576 }
577
578 ret
579}
580
581pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
582 tcx: TyCtxt<'tcx>,
583 def_id: LocalDefId,
584) -> &'tcx [Ty<'tcx>] {
585 let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("Delegation must have sig_id");
586 let caller_sig = tcx.fn_sig(sig_id);
587
588 if let Err(err) = check_constraints(tcx, def_id, sig_id) {
589 let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
590 let err_type = Ty::new_error(tcx, err);
591 return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type));
592 }
593
594 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
595 let (mut folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
596 let caller_sig = EarlyBinder::bind(tcx, caller_sig.skip_binder().fold_with(&mut folder));
597
598 let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_binder();
599 let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output()));
600 tcx.arena.alloc_from_iter(sig_iter)
601}
602
603pub(crate) fn delegation_user_specified_args<'tcx>(
608 tcx: TyCtxt<'tcx>,
609 delegation_id: LocalDefId,
610) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
611 let info = tcx.hir_delegation_info(delegation_id);
612
613 let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
614 let segment = tcx.hir_node(hir_id).expect_path_segment();
615 segment.res.opt_def_id().map(|def_id| (segment, def_id))
616 };
617
618 let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id);
619 let lowerer = ctx.lowerer();
620 let parent_args = info
621 .parent_seg_id_for_sig
622 .and_then(get_segment)
623 .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))
624 .map(|(segment, def_id)| {
625 let self_ty = get_delegation_self_ty(tcx, delegation_id);
626
627 lowerer
628 .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty)
629 .0
630 .as_slice()
631 });
632
633 let child_args = info
634 .child_seg_id_for_sig
635 .and_then(get_segment)
636 .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))
637 .map(|(segment, def_id)| {
638 let parent_args = if let Some(parent_args) = parent_args {
639 parent_args
640 } else {
641 let parent = tcx.parent(def_id);
642 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(parent) {
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(parent), DefKind::Trait) {
643 ty::GenericArgs::identity_for_item(tcx, parent).as_slice()
644 } else {
645 &[]
646 }
647 };
648
649 let args = lowerer
650 .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None)
651 .0;
652
653 let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count();
654 &args[parent_args.len()..args.len() - synth_params_count]
655 });
656
657 (parent_args.unwrap_or_default(), child_args.unwrap_or_default())
658}