1use std::debug_assert_matches;
6
7use rustc_data_structures::fx::{FxHashMap, FxHashSet};
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 delegation_parent_consts: FxHashSet<ty::ParamConst>,
25}
26
27impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamIndexRemapper<'tcx> {
28 fn cx(&self) -> TyCtxt<'tcx> {
29 self.tcx
30 }
31
32 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
33 if !ty.has_param() {
34 return ty;
35 }
36
37 if let ty::Param(param) = ty.kind()
38 && let Some(index) = self.remap_table.get(¶m.index)
39 {
40 return Ty::new_param(self.tcx, *index, param.name);
41 }
42 ty.super_fold_with(self)
43 }
44
45 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
46 if let ty::ReEarlyParam(param) = r.kind()
47 && let Some(index) = self.remap_table.get(¶m.index).copied()
48 {
49 return ty::Region::new_early_param(
50 self.tcx,
51 ty::EarlyParamRegion { index, name: param.name },
52 );
53 }
54 r
55 }
56
57 fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
58 if let ty::ConstKind::Param(param) = ct.kind()
59 && let Some(idx) = self.remap_table.get(¶m.index)
60 {
61 let param = ty::ParamConst::new(*idx, param.name);
62 return ty::Const::new_param(self.tcx, param);
63 }
64 ct.super_fold_with(self)
65 }
66}
67
68#[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)]
69enum SelfPositionKind {
70 AfterLifetimes(Option<DelegationSelfTyPropagationKind>),
71 Zero,
72 None,
73}
74
75fn create_self_position_kind(
76 tcx: TyCtxt<'_>,
77 delegation_id: LocalDefId,
78 sig_id: DefId,
79) -> SelfPositionKind {
80 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
81 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
82 | (FnKind::AssocTraitImpl, FnKind::AssocTrait)
83 | (FnKind::AssocTrait, FnKind::AssocTrait)
84 | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero,
85
86 (FnKind::Free, FnKind::AssocTrait) => {
87 let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind;
88 SelfPositionKind::AfterLifetimes(kind)
89 }
90
91 _ => SelfPositionKind::None,
92 }
93}
94
95#[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)]
96enum FnKind {
97 Free,
98 AssocInherentImpl,
99 AssocTrait,
100 AssocTraitImpl,
101}
102
103fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into<DefId>) -> FnKind {
104 let def_id = def_id.into();
105
106 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);
107
108 let parent = tcx.parent(def_id);
109 match tcx.def_kind(parent) {
110 DefKind::Trait => FnKind::AssocTrait,
111 DefKind::Impl { of_trait: true } => FnKind::AssocTraitImpl,
112 DefKind::Impl { of_trait: false } => FnKind::AssocInherentImpl,
113 _ => FnKind::Free,
114 }
115}
116
117#[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)]
120enum InheritanceKind {
121 WithParent(bool),
131 Own,
135}
136
137fn create_mapping<'tcx>(
147 tcx: TyCtxt<'tcx>,
148 sig_id: DefId,
149 def_id: LocalDefId,
150) -> FxHashMap<u32, u32> {
151 let mut mapping: FxHashMap<u32, u32> = Default::default();
152
153 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
154 let is_self_at_zero = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::Zero => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::Zero);
155
156 if is_self_at_zero {
158 mapping.insert(0, 0);
159 }
160
161 let mut args_index = 0;
162
163 args_index += is_self_at_zero as usize;
164 args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id);
165
166 let sig_generics = tcx.generics_of(sig_id);
167 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);
168
169 if process_sig_parent_generics {
170 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
171 let param = sig_generics.param_at(i, tcx);
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
179 for param in &sig_generics.own_params {
180 if !param.kind.is_ty_or_const() {
181 mapping.insert(param.index, args_index as u32);
182 args_index += 1;
183 }
184 }
185
186 if #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes { .. } => true,
_ => false,
}matches!(self_pos_kind, SelfPositionKind::AfterLifetimes { .. }) {
190 mapping.insert(0, args_index as u32);
191 args_index += 1;
192 }
193
194 if process_sig_parent_generics {
195 for i in (sig_generics.has_self as usize)..sig_generics.parent_count {
196 let param = sig_generics.param_at(i, tcx);
197 if param.kind.is_ty_or_const() {
198 mapping.insert(param.index, args_index as u32);
199 args_index += 1;
200 }
201 }
202 }
203
204 for param in &sig_generics.own_params {
205 if param.kind.is_ty_or_const() {
206 mapping.insert(param.index, args_index as u32);
207 args_index += 1;
208 }
209 }
210
211 mapping
212}
213
214fn get_delegation_parent_args_count_without_self<'tcx>(
215 tcx: TyCtxt<'tcx>,
216 delegation_id: LocalDefId,
217 sig_id: DefId,
218) -> usize {
219 let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count;
220
221 match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) {
222 (FnKind::Free, FnKind::Free)
223 | (FnKind::Free, FnKind::AssocTrait)
224 | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0,
225
226 (FnKind::AssocInherentImpl, FnKind::Free)
227 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
228 delegation_parent_args_count }
230
231 (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => {
232 delegation_parent_args_count - 1 }
234
235 (FnKind::AssocTraitImpl, _)
238 | (_, FnKind::AssocTraitImpl)
239 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
240 }
241}
242
243fn get_parent_and_inheritance_kind<'tcx>(
244 tcx: TyCtxt<'tcx>,
245 def_id: LocalDefId,
246 sig_id: DefId,
247) -> (Option<DefId>, InheritanceKind) {
248 match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) {
249 (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
250 (None, InheritanceKind::WithParent(true))
251 }
252
253 (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
254 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own)
255 }
256
257 (FnKind::AssocInherentImpl, FnKind::AssocTrait)
258 | (FnKind::AssocTrait, FnKind::AssocTrait)
259 | (FnKind::AssocInherentImpl, FnKind::Free)
260 | (FnKind::AssocTrait, FnKind::Free) => {
261 (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false))
262 }
263
264 (FnKind::AssocTraitImpl, _)
267 | (_, FnKind::AssocTraitImpl)
268 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
269 }
270}
271
272fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option<Ty<'tcx>> {
273 let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id");
274 let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
275
276 match (caller_kind, callee_kind) {
277 (FnKind::Free, FnKind::AssocTrait)
278 | (FnKind::AssocInherentImpl, FnKind::Free)
279 | (FnKind::Free, FnKind::Free)
280 | (FnKind::AssocTrait, FnKind::Free)
281 | (FnKind::AssocTrait, FnKind::AssocTrait) => {
282 match create_self_position_kind(tcx, delegation_id, sig_id) {
283 SelfPositionKind::None => None,
284 SelfPositionKind::AfterLifetimes(propagation_kind) => {
285 Some(match propagation_kind {
286 Some(kind) => match kind {
287 DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => {
288 let ctx = ItemCtxt::new(tcx, delegation_id);
289 ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty())
290 }
291 DelegationSelfTyPropagationKind::SelfParam => {
292 let index = tcx.generics_of(delegation_id).own_counts().lifetimes;
293 Ty::new_param(tcx, index as u32, kw::SelfUpper)
294 }
295 },
296 None => Ty::new_error_with_message(
297 tcx,
298 tcx.def_span(delegation_id),
299 "self propagation kind must be specified for `AfterLifetimes` variant",
300 ),
301 })
302 }
303 SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)),
304 }
305 }
306
307 (FnKind::AssocTraitImpl, FnKind::AssocTrait)
308 | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some(
309 tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(),
310 ),
311
312 (FnKind::AssocTraitImpl, _)
315 | (_, FnKind::AssocTraitImpl)
316 | (_, FnKind::AssocInherentImpl) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
317 }
318}
319
320fn create_generic_args<'tcx>(
336 tcx: TyCtxt<'tcx>,
337 sig_id: DefId,
338 delegation_id: LocalDefId,
339 mut parent_args: &[ty::GenericArg<'tcx>],
340 mut child_args: &[ty::GenericArg<'tcx>],
341) -> (Vec<ty::GenericArg<'tcx>>, &'tcx [ty::GenericArg<'tcx>]) {
342 let delegation_generics = tcx.generics_of(delegation_id);
343 let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id);
344
345 let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count();
346 let synth_args = &delegation_args[real_args_count..];
347
348 let mut delegation_parent_args =
349 &delegation_args[delegation_generics.has_self as usize..delegation_generics.parent_count];
350
351 let delegation_args = &delegation_args[delegation_generics.parent_count..];
352
353 let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id));
354 if #[allow(non_exhaustive_omitted_patterns)] match kinds {
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => true,
_ => false,
}matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) {
355 let parent = tcx.local_parent(delegation_id);
359
360 parent_args =
361 tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
362
363 child_args =
364 &delegation_args[delegation_args.len() - delegation_generics.own_params.len()..];
365
366 delegation_parent_args = &[];
367 }
368
369 let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into());
370
371 if self_type.is_some() && !parent_args.is_empty() {
374 parent_args = &parent_args[1..];
375 }
376
377 let (zero_self, after_lifetimes_self) =
378 match create_self_position_kind(tcx, delegation_id, sig_id) {
379 SelfPositionKind::AfterLifetimes(_) => {
380 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
381 (None, self_type)
382 }
383 SelfPositionKind::Zero => {
384 if !self_type.is_some() {
::core::panicking::panic("assertion failed: self_type.is_some()")
};assert!(self_type.is_some());
385 (self_type, None)
386 }
387 SelfPositionKind::None => (None, None),
388 };
389
390 let zero_self = zero_self.as_ref().into_iter();
391 let after_lifetimes_self = after_lifetimes_self.as_ref().into_iter();
392
393 let args = zero_self
394 .chain(delegation_parent_args)
395 .chain(parent_args.iter().filter(|a| a.as_region().is_some()))
396 .chain(child_args.iter().filter(|a| a.as_region().is_some()))
397 .chain(after_lifetimes_self)
398 .chain(parent_args.iter().filter(|a| a.as_region().is_none()))
399 .chain(child_args.iter().filter(|a| a.as_region().is_none()))
400 .chain(synth_args)
401 .copied()
402 .collect::<Vec<_>>();
403
404 (args, delegation_parent_args)
405}
406
407pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
408 tcx: TyCtxt<'tcx>,
409 def_id: LocalDefId,
410 sig_id: DefId,
411) -> ty::GenericPredicates<'tcx> {
412 struct PredicatesCollector<'tcx> {
413 tcx: TyCtxt<'tcx>,
414 preds: Vec<(ty::Clause<'tcx>, Span)>,
415 args: Vec<ty::GenericArg<'tcx>>,
416 folder: ParamIndexRemapper<'tcx>,
417 filter_self_preds: bool,
418 }
419
420 impl<'tcx> PredicatesCollector<'tcx> {
421 fn with_own_preds(
422 mut self,
423 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
424 def_id: DefId,
425 ) -> Self {
426 let preds = f(def_id);
427 let args = self.args.as_slice();
428
429 for pred in preds.predicates {
430 if self.filter_self_preds
433 && let Some(trait_pred) = pred.0.as_trait_clause()
434 && trait_pred.self_ty().skip_binder().is_param(0)
436 {
437 continue;
438 }
439
440 if let ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) =
468 pred.0.as_predicate().fold_with(&mut self.folder).kind().skip_binder()
469 {
470 let unnorm_const = EarlyBinder::bind(self.tcx, ct).instantiate(self.tcx, args);
471 if let ty::ConstKind::Param(param) = unnorm_const.skip_norm_wip().kind()
472 && self.folder.delegation_parent_consts.contains(¶m)
473 {
474 continue;
475 }
476 }
477
478 let new_pred = pred.0.fold_with(&mut self.folder);
479 self.preds.push((
480 EarlyBinder::bind(self.tcx, new_pred)
481 .instantiate(self.tcx, args)
482 .skip_norm_wip(),
483 pred.1,
484 ));
485 }
486
487 self
488 }
489
490 fn with_preds(
491 mut self,
492 f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
493 def_id: DefId,
494 ) -> Self {
495 let preds = f(def_id);
496 if let Some(parent_def_id) = preds.parent {
497 self = self.with_own_preds(f, parent_def_id);
498 }
499
500 self.with_own_preds(f, def_id)
501 }
502 }
503
504 let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
505 let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
506 let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
507 let filter_self_preds = #[allow(non_exhaustive_omitted_patterns)] match self_pos_kind {
SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
=> true,
_ => false,
}matches!(
508 self_pos_kind,
509 SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..)))
510 );
511
512 let collector = PredicatesCollector { tcx, preds: ::alloc::vec::Vec::new()vec![], args, folder, filter_self_preds };
513 let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id);
514
515 let preds = match inh_kind {
519 InheritanceKind::WithParent(false) => {
520 collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id)
521 }
522 InheritanceKind::WithParent(true) => {
523 collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id)
524 }
525 InheritanceKind::Own => {
526 collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id)
527 }
528 }
529 .preds;
530
531 ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) }
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}