1use std::assert_matches;
2
3use hir::HirId;
4use hir::def::{DefKind, Res};
5use rustc_ast::*;
6use rustc_data_structures::fx::FxHashSet;
7use rustc_hir as hir;
8use rustc_hir::def_id::DefId;
9use rustc_middle::ty;
10use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
11use rustc_span::symbol::kw;
12use rustc_span::{ErrorGuaranteed, Ident, Span, bug, sym};
13
14use crate::LoweringContext;
15use crate::delegation::resolution::resolver::DelegationResolver;
16use crate::diagnostics::{
17 DelegationInfersMismatch, DelegationToInherentImplMustContainParentGenerics,
18 DelegationToInherentImplParentContainsInfer,
19};
20
21#[derive(#[automatically_derived]
impl ::core::fmt::Debug for GenericsPosition {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
GenericsPosition::Parent => "Parent",
GenericsPosition::Child => "Child",
})
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for GenericsPosition { }
#[automatically_derived]
impl ::core::clone::Clone for GenericsPosition {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for GenericsPosition { }Copy, #[automatically_derived]
impl ::core::cmp::Eq for GenericsPosition { }Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for GenericsPosition { }
#[automatically_derived]
impl ::core::cmp::PartialEq for GenericsPosition {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq)]
22pub(super) enum GenericsPosition {
23 Parent,
24 Child,
25}
26
27#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for GenericArgSlot<T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::UserSpecified =>
::core::fmt::Formatter::write_str(f, "UserSpecified"),
Self::Generate(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"Generate", __self_0, &__self_1),
}
}
}Debug)]
28pub(super) enum GenericArgSlot<T> {
29 UserSpecified,
30 Generate(T, Option<usize> ),
31}
32
33#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for DelegationGenerics<T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f,
"DelegationGenerics", "data", &self.data, "pos", &self.pos,
"trait_impl", &self.trait_impl, "has_implicit_self",
&&self.has_implicit_self)
}
}Debug)]
34pub(super) struct DelegationGenerics<T> {
35 data: T,
36 pos: GenericsPosition,
37 trait_impl: bool,
38 has_implicit_self: bool,
39}
40
41type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>;
42
43impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
44 fn generate_all(
45 params: &'hir [ty::GenericParamDef],
46 pos: GenericsPosition,
47 trait_impl: bool,
48 has_implicit_self: bool,
49 ) -> Self {
50 DelegationGenerics {
51 data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(),
52 pos,
53 trait_impl,
54 has_implicit_self,
55 }
56 }
57}
58
59#[derive(#[automatically_derived]
impl<'hir> ::core::fmt::Debug for HirOrTyGenerics<'hir> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Ty(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ty",
&__self_0),
Self::Hir(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Hir",
&__self_0),
}
}
}Debug)]
70pub(super) enum HirOrTyGenerics<'hir> {
71 Ty(DelegationGenerics<TyGenerics<'hir>>),
72 Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
73}
74
75#[derive(#[automatically_derived]
impl<'hir> ::core::fmt::Debug for GenericsGenerationResult<'hir> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"GenericsGenerationResult", "generics", &self.generics,
"args_segment_id", &self.args_segment_id,
"use_for_sig_inheritance", &&self.use_for_sig_inheritance)
}
}Debug)]
76pub(super) struct GenericsGenerationResult<'hir> {
77 pub(super) generics: HirOrTyGenerics<'hir>,
78 pub(super) args_segment_id: HirId,
79 pub(super) use_for_sig_inheritance: bool,
80}
81
82impl GenericsGenerationResult<'_> {
83 pub(super) fn segment_id_for_sig(&self) -> Option<HirId> {
84 self.use_for_sig_inheritance.then(|| self.args_segment_id)
85 }
86}
87
88pub(super) struct GenericsGenerationResults<'hir> {
89 pub(super) parent: GenericsGenerationResult<'hir>,
90 pub(super) child: GenericsGenerationResult<'hir>,
91 pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>,
92}
93
94#[derive(#[automatically_derived]
impl<'hir> ::core::fmt::Debug for DelegationGenericArgsIterator<'hir> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"DelegationGenericArgsIterator", "index", &self.index, "params",
&self.params, "has_implicit_self", &&self.has_implicit_self)
}
}Debug)]
95pub(super) struct DelegationGenericArgsIterator<'hir> {
96 index: usize = Default::default(),
97 params: &'hir [hir::GenericParam<'hir>],
98 has_implicit_self: bool,
99}
100
101impl<'hir> DelegationGenericArgsIterator<'hir> {
108 pub(super) fn next(
109 &mut self,
110 ctx: &mut LoweringContext<'_, 'hir>,
111 hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId,
112 ) -> Option<hir::GenericArg<'hir>> {
113 let p = loop {
114 if self.index >= self.params.len() {
115 return None;
116 }
117
118 let p = self.params[self.index];
119 let is_implicit_self = self.has_implicit_self && self.index == 0;
120 self.index += 1;
121
122 if is_implicit_self || p.is_impl_trait() {
123 continue;
124 }
125
126 break p;
127 };
128
129 let hir_id = hir_id_factory(ctx);
130
131 Some(match p.kind {
132 hir::GenericParamKind::Lifetime { .. } => {
133 hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime {
134 hir_id,
135 ident: p.name.ident(),
136 kind: hir::LifetimeKind::Param(p.def_id),
137 source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
138 syntax: hir::LifetimeSyntax::ExplicitBound,
139 }))
140 }
141 hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty {
142 hir_id,
143 span: p.span,
144 kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)),
145 })),
146 hir::GenericParamKind::Const { .. } => {
147 hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg {
148 hir_id,
149 kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)),
150 span: p.span,
151 }))
152 }
153 })
154 }
155
156 pub(super) fn consume_all(
157 mut self,
158 ctx: &mut LoweringContext<'_, 'hir>,
159 ) -> Vec<hir::GenericArg<'hir>> {
160 let mut args = ::alloc::vec::Vec::new()vec![];
161
162 while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) {
163 args.push(arg);
164 }
165
166 args
167 }
168}
169
170impl<'hir> HirOrTyGenerics<'hir> {
171 pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) {
172 if let HirOrTyGenerics::Ty(ty) = self {
173 let rename_self = ty.pos == GenericsPosition::Child;
174 let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self);
175
176 *self = HirOrTyGenerics::Hir(DelegationGenerics {
177 data: params,
178 pos: ty.pos,
179 trait_impl: ty.trait_impl,
180 has_implicit_self: ty.has_implicit_self,
181 });
182 }
183 }
184
185 fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> {
186 match self {
187 HirOrTyGenerics::Ty(_) => hir::Generics::empty(),
188 HirOrTyGenerics::Hir(hir) => hir.data,
189 }
190 }
191
192 pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> {
193 match self {
194 HirOrTyGenerics::Ty(_) => {
195 ::rustc_span::macros::bug_impl(None,
format_args!("attempting to get generic args before uplifting to HIR"),
Location::caller())bug!("attempting to get generic args before uplifting to HIR")
196 }
197 HirOrTyGenerics::Hir(hir) => DelegationGenericArgsIterator {
198 params: hir.data.params,
199 has_implicit_self: hir.has_implicit_self,
200 ..
201 },
202 }
203 }
204
205 pub(super) fn infer_indices(&self) -> FxHashSet<usize> {
206 match self {
207 HirOrTyGenerics::Ty(ty) => ty
208 .data
209 .iter()
210 .flat_map(|slot| match slot {
211 GenericArgSlot::Generate(_, Some(idx)) => Some(*idx),
212 _ => None,
213 })
214 .collect(),
215 HirOrTyGenerics::Hir(_) => ::rustc_span::macros::bug_impl(None,
format_args!("accessed infer indices on uplifted generics"),
Location::caller())bug!("accessed infer indices on uplifted generics"),
216 }
217 }
218
219 pub(super) fn is_trait_impl(&self) -> bool {
220 match self {
221 HirOrTyGenerics::Ty(ty) => ty.trait_impl,
222 HirOrTyGenerics::Hir(hir) => hir.trait_impl,
223 }
224 }
225
226 pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> {
227 match self {
228 HirOrTyGenerics::Ty(_) => {
229 ::rustc_span::macros::bug_impl(None,
format_args!("accessed ty-level generics while searching for uplifted `Self` param"),
Location::caller())bug!("accessed ty-level generics while searching for uplifted `Self` param")
230 }
231 HirOrTyGenerics::Hir(hir) => hir
232 .data
233 .params
234 .iter()
235 .find(|p| p.name.ident().name == kw::SelfUpper)
236 .expect("`Self` generic param is not found while expected"),
237 }
238 }
239
240 pub(crate) fn pos(&self) -> GenericsPosition {
241 match self {
242 HirOrTyGenerics::Ty(ty) => ty.pos,
243 HirOrTyGenerics::Hir(hir) => hir.pos,
244 }
245 }
246}
247
248impl<'hir> GenericsGenerationResult<'hir> {
249 fn new(generics: DelegationGenerics<TyGenerics<'hir>>) -> GenericsGenerationResult<'hir> {
250 GenericsGenerationResult {
251 generics: HirOrTyGenerics::Ty(generics),
252 args_segment_id: HirId::INVALID,
253 use_for_sig_inheritance: false,
254 }
255 }
256}
257
258#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for ParentSegmentArgs<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Specified(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Specified", &__self_0),
Self::NotSpecified =>
::core::fmt::Formatter::write_str(f, "NotSpecified"),
Self::Invalid => ::core::fmt::Formatter::write_str(f, "Invalid"),
}
}
}Debug)]
259enum ParentSegmentArgs<'a> {
260 Specified(&'a AngleBracketedArgs),
263 NotSpecified,
266 Invalid,
277}
278
279struct GenericsResolution<'a, 'tcx> {
280 trait_impl: bool,
281
282 parent_args: ParentSegmentArgs<'a>,
283 child_args: Option<&'a AngleBracketedArgs>,
284
285 sig_parent_params: &'tcx [ty::GenericParamDef],
286 sig_child_params: &'tcx [ty::GenericParamDef],
287
288 free_to_trait_delegation: bool,
289 qself_is_none: bool,
291 qself_is_infer: bool,
293 generate_free_to_trait_self: bool,
295}
296
297impl<'hir> DelegationResolver<'_, 'hir> {
298 fn resolve_generics<'a>(
299 &self,
300 delegation: &'a Delegation,
301 sig_id: DefId,
302 ) -> Result<GenericsResolution<'a, 'hir>, ErrorGuaranteed> {
303 let tcx = self.tcx();
304 let delegation_parent_kind = tcx.def_kind(tcx.local_parent(self.owner_id()));
305
306 let delegation_in_free_ctx =
307 !#[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
DefKind::Trait | DefKind::Impl { .. } => true,
_ => false,
}matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
308
309 let sig_in_trait = #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(tcx.parent(sig_id))
{
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Trait);
310 let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
311
312 let mut sig_parent_params: &[ty::GenericParamDef] = &[];
313
314 let qself_is_infer =
315 delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer());
316
317 let qself_is_none = delegation.qself.is_none();
318
319 let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] {
320 let res = self.get_resolution_id(parent_segment.id)?;
321 if !#[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(res) {
DefKind::Mod => true,
_ => false,
}matches!(tcx.def_kind(res), DefKind::Mod) {
322 {
match tcx.def_kind(res) {
DefKind::Trait | DefKind::Struct | DefKind::Enum => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::Trait | DefKind::Struct | DefKind::Enum",
::core::option::Option::None);
}
}
};assert_matches!(
323 tcx.def_kind(res),
324 DefKind::Trait | DefKind::Struct | DefKind::Enum
325 );
326
327 sig_parent_params = &tcx.generics_of(res).own_params;
328 self.get_user_args(parent_segment)
329 .map(|args| ParentSegmentArgs::Specified(args))
330 .unwrap_or(ParentSegmentArgs::NotSpecified)
331 } else {
332 ParentSegmentArgs::Invalid
333 }
334 } else {
335 ParentSegmentArgs::Invalid
336 };
337
338 Ok(GenericsResolution {
339 parent_args,
340 sig_parent_params,
341 qself_is_none,
342 qself_is_infer,
343 free_to_trait_delegation,
344 generate_free_to_trait_self: free_to_trait_delegation
345 && (qself_is_none || qself_is_infer),
346 trait_impl: #[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
DefKind::Impl { of_trait: true } => true,
_ => false,
}matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }),
347 sig_child_params: &tcx.generics_of(sig_id).own_params,
348 child_args: self.get_user_args(
349 delegation.path.segments.last().expect("must be at least one segment"),
350 ),
351 })
352 }
353
354 fn get_user_args<'a>(&self, segment: &'a PathSegment) -> Option<&'a AngleBracketedArgs> {
355 let Some(args) = &segment.args else { return None };
356 let GenericArgs::AngleBracketed(args) = args else {
357 self.tcx().dcx().span_delayed_bug(
358 segment.span(),
359 "expected angle-bracketed generic args in delegation segment",
360 );
361
362 return None;
363 };
364
365 (!args.args.is_empty()).then(|| args)
369 }
370
371 pub(super) fn resolve_and_generate_generics(
372 &self,
373 delegation: &Delegation,
374 sig_id: DefId,
375 span: Span,
376 ) -> Result<GenericsGenerationResults<'hir>, ErrorGuaranteed> {
377 let res @ GenericsResolution {
378 trait_impl,
379 generate_free_to_trait_self,
380 sig_child_params,
381 sig_parent_params,
382 ..
383 } = self.resolve_generics(delegation, sig_id)?;
384
385 if trait_impl {
388 let parent = DelegationGenerics {
391 data: ::alloc::vec::Vec::new()vec![],
392 pos: GenericsPosition::Child,
393 trait_impl: true,
394 has_implicit_self: false,
395 };
396
397 let parent = GenericsGenerationResult::new(parent);
398
399 let child = DelegationGenerics::generate_all(
400 sig_child_params,
401 GenericsPosition::Child,
402 true,
403 false,
404 );
405
406 let child = GenericsGenerationResult::new(child);
407
408 return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None });
409 }
410
411 self.check_delegation_to_inherent_impl(&res.parent_args, sig_id, span)?;
412
413 let tcx = self.tcx();
414
415 let skip_self =
417 !generate_free_to_trait_self && tcx.def_kind(tcx.parent(sig_id)) == DefKind::Trait;
418
419 let parent_generics = match res.parent_args {
420 ParentSegmentArgs::Specified(args) => DelegationGenerics {
421 data: Self::create_slots_from_args(
422 tcx,
423 args,
424 &sig_parent_params[usize::from(skip_self)..],
425 generate_free_to_trait_self,
426 ),
427 pos: GenericsPosition::Parent,
428 trait_impl,
429 has_implicit_self: generate_free_to_trait_self,
430 },
431 ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all(
432 &sig_parent_params[usize::from(skip_self)..],
433 GenericsPosition::Parent,
434 trait_impl,
435 generate_free_to_trait_self,
436 ),
437 ParentSegmentArgs::Invalid => DelegationGenerics {
438 data: ::alloc::vec::Vec::new()vec![],
439 pos: GenericsPosition::Parent,
440 trait_impl,
441 has_implicit_self: false,
442 },
443 };
444
445 let child_generics = if let Some(args) = res.child_args {
446 let synth_params_index = sig_child_params
447 .iter()
448 .position(|p| p.kind.is_synthetic())
449 .unwrap_or(sig_child_params.len());
450
451 let mut slots = Self::create_slots_from_args(
452 tcx,
453 args,
454 &sig_child_params[..synth_params_index],
455 trait_impl,
456 );
457
458 for synth_param in &sig_child_params[synth_params_index..] {
459 slots.push(GenericArgSlot::Generate(synth_param, None));
460 }
461
462 DelegationGenerics {
463 data: slots,
464 pos: GenericsPosition::Child,
465 trait_impl,
466 has_implicit_self: false,
467 }
468 } else {
469 DelegationGenerics::generate_all(
470 sig_child_params,
471 GenericsPosition::Child,
472 trait_impl,
473 false,
474 )
475 };
476
477 Ok(GenericsGenerationResults {
478 parent: GenericsGenerationResult::new(parent_generics),
479 child: GenericsGenerationResult::new(child_generics),
480 self_ty_propagation_kind: match res.free_to_trait_delegation {
481 true => Some(match res.qself_is_none {
482 true => hir::DelegationSelfTyPropagationKind::SelfParam,
483 false => match res.qself_is_infer {
484 true => hir::DelegationSelfTyPropagationKind::SelfParam,
485 false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID),
487 },
488 }),
489 false => None,
490 },
491 })
492 }
493
494 fn check_delegation_to_inherent_impl(
495 &self,
496 parent_args: &ParentSegmentArgs<'_>,
497 sig_id: DefId,
498 span: Span,
499 ) -> Result<(), ErrorGuaranteed> {
500 let tcx = self.tcx();
501
502 if !(tcx.def_kind(sig_id) == DefKind::AssocFn
503 && #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(tcx.parent(sig_id))
{
DefKind::Impl { of_trait: false } => true,
_ => false,
}matches!(tcx.def_kind(tcx.parent(sig_id)), DefKind::Impl { of_trait: false }))
504 {
505 return Ok(());
506 }
507
508 let ty::Adt(def, _) = tcx.type_of(tcx.parent(sig_id)).skip_binder().kind() else {
509 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("parent of inherent function can be only struct or enum")));
}unreachable!("parent of inherent function can be only struct or enum")
510 };
511
512 match parent_args {
513 ParentSegmentArgs::Invalid => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
514 ParentSegmentArgs::Specified(args) => args
515 .args
516 .iter()
517 .all(|arg| {
518 let AngleBracketedArg::Arg(arg) = arg else { return false };
519 !arg.is_maybe_parenthesised_infer()
520 })
521 .ok_or_else(|| {
522 self.tcx().dcx().emit_err(DelegationToInherentImplParentContainsInfer { span })
523 }),
524 ParentSegmentArgs::NotSpecified => match tcx.generics_of(def.did()).own_params.len() {
525 0 => Ok(()),
526 _ => Err(self
527 .tcx()
528 .dcx()
529 .emit_err(DelegationToInherentImplMustContainParentGenerics { span })),
530 },
531 }
532 }
533
534 fn create_slots_from_args(
543 tcx: TyCtxt<'_>,
544 args: &AngleBracketedArgs,
545 params: &'hir [ty::GenericParamDef],
546 add_first_self: bool,
547 ) -> TyGenerics<'hir> {
548 let mut slots = ::alloc::vec::Vec::new()vec![];
549 if add_first_self {
550 slots.push(GenericArgSlot::Generate(¶ms[0], None));
551 }
552
553 let params = ¶ms[usize::from(add_first_self)..];
554 for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
555 let AngleBracketedArg::Arg(arg) = arg else { continue };
556 let is_infer = arg.is_maybe_parenthesised_infer();
557
558 if is_infer
562 && #[allow(non_exhaustive_omitted_patterns)] match (arg, ¶m.kind) {
(GenericArg::Lifetime(_),
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. })
|
(GenericArg::Type(_) | GenericArg::Const(_),
GenericParamDefKind::Lifetime { .. }) => true,
_ => false,
}matches!(
563 (arg, ¶m.kind),
564 (
565 GenericArg::Lifetime(_),
566 GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. }
567 ) | (
568 GenericArg::Type(_) | GenericArg::Const(_),
569 GenericParamDefKind::Lifetime { .. }
570 )
571 )
572 {
573 let (actual, expected) = if #[allow(non_exhaustive_omitted_patterns)] match arg {
GenericArg::Lifetime(..) => true,
_ => false,
}matches!(arg, GenericArg::Lifetime(..)) {
574 (kw::UnderscoreLifetime, kw::Underscore)
575 } else {
576 (kw::Underscore, kw::UnderscoreLifetime)
577 };
578
579 tcx.dcx().emit_err(DelegationInfersMismatch { span: arg.span(), actual, expected });
580 }
581
582 slots.push(match is_infer {
583 true => GenericArgSlot::Generate(param, Some(idx)),
584 false => GenericArgSlot::UserSpecified,
585 });
586 }
587
588 slots
589 }
590}
591
592impl<'hir> GenericsGenerationResults<'hir> {
593 pub(super) fn all_params(&self) -> impl Iterator<Item = hir::GenericParam<'hir>> {
594 let parent = self.parent.generics.hir_generics_or_empty().params;
595 let child = self.child.generics.hir_generics_or_empty().params;
596
597 parent
602 .iter()
603 .filter(|p| p.is_lifetime())
604 .chain(child.iter().filter(|p| p.is_lifetime()))
605 .chain(parent.iter().filter(|p| !p.is_lifetime()))
606 .chain(child.iter().filter(|p| !p.is_lifetime()))
607 .copied()
608 }
609
610 pub(super) fn all_predicates(&self) -> impl Iterator<Item = hir::WherePredicate<'hir>> {
615 self.parent
616 .generics
617 .hir_generics_or_empty()
618 .predicates
619 .into_iter()
620 .chain(self.child.generics.hir_generics_or_empty().predicates)
621 .copied()
622 }
623}
624
625impl<'hir> LoweringContext<'_, 'hir> {
626 fn uplift_delegation_generic_params(
627 &mut self,
628 span: Span,
629 params: &[GenericArgSlot<&ty::GenericParamDef>],
630 rename_self: bool,
631 ) -> &'hir hir::Generics<'hir> {
632 let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| {
633 let GenericArgSlot::Generate(p, _) = p else { return None };
634
635 let def_kind = match p.kind {
636 GenericParamDefKind::Lifetime => DefKind::LifetimeParam,
637 GenericParamDefKind::Type { .. } => DefKind::TyParam,
638 GenericParamDefKind::Const { .. } => DefKind::ConstParam,
639 };
640
641 let param_name =
652 if rename_self && p.name == kw::SelfUpper { sym::This } else { p.name };
653
654 let param_ident = Ident::new(param_name, span);
655 let def_name = Some(param_ident.name);
656 let node_id = self.next_node_id();
657
658 let def_id = self.create_def(node_id, def_name, def_kind, span);
659
660 let kind = match p.kind {
661 GenericParamDefKind::Lifetime => {
662 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
663 }
664 GenericParamDefKind::Type { synthetic, .. } => {
665 hir::GenericParamKind::Type { default: None, synthetic }
666 }
667 GenericParamDefKind::Const { .. } => {
668 let hir_id = self.next_id();
669 let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id));
670
671 hir::GenericParamKind::Const {
672 ty: self.arena.alloc(hir::Ty { kind, hir_id, span }),
673 default: None,
674 }
675 }
676 };
677
678 let hir_id = self.lower_node_id(node_id);
681
682 Some(hir::GenericParam {
683 hir_id,
684 colon_span: Some(span),
685 def_id,
686 kind,
687 name: hir::ParamName::Plain(param_ident),
688 pure_wrt_drop: p.pure_wrt_drop,
689 source: hir::GenericParamSource::Generics,
690 span,
691 })
692 }));
693
694 let predicates =
698 self.arena.alloc_from_iter(params.iter().filter_map(|p| {
699 p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span))
700 }));
701
702 self.arena.alloc(hir::Generics {
703 params,
704 predicates,
705 has_where_clause_predicates: false,
706 where_clause_span: span,
707 span,
708 })
709 }
710
711 fn generate_lifetime_predicate(
712 &mut self,
713 p: &hir::GenericParam<'hir>,
714 span: Span,
715 ) -> hir::WherePredicate<'hir> {
716 let create_lifetime = |this: &mut Self| -> &'hir hir::Lifetime {
717 this.arena.alloc(hir::Lifetime {
718 hir_id: this.next_id(),
719 ident: p.name.ident(),
720 kind: hir::LifetimeKind::Param(p.def_id),
721 source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
722 syntax: hir::LifetimeSyntax::ExplicitBound,
723 })
724 };
725
726 hir::WherePredicate {
727 hir_id: self.next_id(),
728 span,
729 kind: self.arena.alloc(hir::WherePredicateKind::RegionPredicate(
730 hir::WhereRegionPredicate {
731 in_where_clause: true,
732 lifetime: create_lifetime(self),
733 bounds: self
734 .arena
735 .alloc_slice(&[hir::GenericBound::Outlives(create_lifetime(self))]),
736 },
737 )),
738 }
739 }
740
741 pub(super) fn create_generic_arg_path(
742 &mut self,
743 p: &hir::GenericParam<'hir>,
744 ) -> hir::QPath<'hir> {
745 let res = Res::Def(
746 match p.kind {
747 hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
748 hir::GenericParamKind::Type { .. } => DefKind::TyParam,
749 hir::GenericParamKind::Const { .. } => DefKind::ConstParam,
750 },
751 p.def_id.to_def_id(),
752 );
753
754 self.create_resolved_qpath(res, p.name.ident(), p.span)
755 }
756
757 pub(super) fn create_resolved_qpath(
758 &mut self,
759 res: Res,
760 ident: Ident,
761 span: Span,
762 ) -> hir::QPath<'hir> {
763 hir::QPath::Resolved(
764 None,
765 self.arena.alloc(hir::Path {
766 segments: self.arena.alloc_slice(&[hir::PathSegment {
767 args: None,
768 hir_id: self.next_id(),
769 ident,
770 infer_args: false,
771 res,
772 delegation_child_segment: false,
773 }]),
774 res,
775 span,
776 }),
777 )
778 }
779}