1use hir::HirId;
2use hir::def::{DefKind, Res};
3use rustc_ast::*;
4use rustc_data_structures::fx::FxHashSet;
5use rustc_hir as hir;
6use rustc_hir::def_id::DefId;
7use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
8use rustc_middle::{bug, ty};
9use rustc_span::symbol::kw;
10use rustc_span::{ErrorGuaranteed, Ident, Span, sym};
11
12use crate::LoweringContext;
13use crate::delegation::resolution::resolver::DelegationResolver;
14use crate::diagnostics::DelegationInfersMismatch;
15
16#[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]
impl ::core::clone::Clone for GenericsPosition {
#[inline]
fn clone(&self) -> GenericsPosition { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for GenericsPosition { }Copy, #[automatically_derived]
impl ::core::cmp::Eq for GenericsPosition {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for GenericsPosition {
#[inline]
fn eq(&self, other: &GenericsPosition) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
17pub(super) enum GenericsPosition {
18 Parent,
19 Child,
20}
21
22#[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 {
GenericArgSlot::UserSpecified =>
::core::fmt::Formatter::write_str(f, "UserSpecified"),
GenericArgSlot::Generate(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"Generate", __self_0, &__self_1),
}
}
}Debug)]
23pub(super) enum GenericArgSlot<T> {
24 UserSpecified,
25 Generate(T, Option<usize> ),
26}
27
28pub(super) struct DelegationGenerics<T> {
29 data: T,
30 pos: GenericsPosition,
31 trait_impl: bool,
32}
33
34type TyGenerics<'hir> = Vec<GenericArgSlot<&'hir ty::GenericParamDef>>;
35
36impl<'hir> DelegationGenerics<TyGenerics<'hir>> {
37 fn generate_all(
38 params: &'hir [ty::GenericParamDef],
39 pos: GenericsPosition,
40 trait_impl: bool,
41 ) -> Self {
42 DelegationGenerics {
43 data: params.iter().map(|p| GenericArgSlot::Generate(p, None)).collect(),
44 pos,
45 trait_impl,
46 }
47 }
48}
49
50pub(super) enum HirOrTyGenerics<'hir> {
61 Ty(DelegationGenerics<TyGenerics<'hir>>),
62 Hir(DelegationGenerics<&'hir hir::Generics<'hir>>),
63}
64
65pub(super) struct GenericsGenerationResult<'hir> {
66 pub(super) generics: HirOrTyGenerics<'hir>,
67 pub(super) args_segment_id: HirId,
68 pub(super) use_for_sig_inheritance: bool,
69}
70
71impl GenericsGenerationResult<'_> {
72 pub(super) fn segment_id_for_sig(&self) -> Option<HirId> {
73 self.use_for_sig_inheritance.then(|| self.args_segment_id)
74 }
75}
76
77pub(super) struct GenericsGenerationResults<'hir> {
78 pub(super) parent: GenericsGenerationResult<'hir>,
79 pub(super) child: GenericsGenerationResult<'hir>,
80 pub(super) self_ty_propagation_kind: Option<hir::DelegationSelfTyPropagationKind>,
81}
82
83pub(super) struct DelegationGenericArgsIterator<'hir> {
84 index: usize = Default::default(),
85 params: &'hir [hir::GenericParam<'hir>],
86}
87
88impl<'hir> DelegationGenericArgsIterator<'hir> {
95 pub(super) fn next(
96 &mut self,
97 ctx: &mut LoweringContext<'_, 'hir>,
98 hir_id_factory: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> HirId,
99 ) -> Option<hir::GenericArg<'hir>> {
100 let p = loop {
101 if self.index >= self.params.len() {
102 return None;
103 }
104
105 let p = self.params[self.index];
106 self.index += 1;
107
108 if p.name.ident().name == kw::SelfUpper || p.is_impl_trait() {
110 continue;
111 }
112
113 break p;
114 };
115
116 let hir_id = hir_id_factory(ctx);
117
118 Some(match p.kind {
119 hir::GenericParamKind::Lifetime { .. } => {
120 hir::GenericArg::Lifetime(ctx.arena.alloc(hir::Lifetime {
121 hir_id,
122 ident: p.name.ident(),
123 kind: hir::LifetimeKind::Param(p.def_id),
124 source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
125 syntax: hir::LifetimeSyntax::ExplicitBound,
126 }))
127 }
128 hir::GenericParamKind::Type { .. } => hir::GenericArg::Type(ctx.arena.alloc(hir::Ty {
129 hir_id,
130 span: p.span,
131 kind: hir::TyKind::Path(ctx.create_generic_arg_path(&p)),
132 })),
133 hir::GenericParamKind::Const { .. } => {
134 hir::GenericArg::Const(ctx.arena.alloc(hir::ConstArg {
135 hir_id,
136 kind: hir::ConstArgKind::Path(ctx.create_generic_arg_path(&p)),
137 span: p.span,
138 }))
139 }
140 })
141 }
142
143 pub(super) fn consume_all(
144 mut self,
145 ctx: &mut LoweringContext<'_, 'hir>,
146 ) -> Vec<hir::GenericArg<'hir>> {
147 let mut args = ::alloc::vec::Vec::new()vec![];
148 while let Some(arg) = self.next(ctx, |ctx| ctx.next_id()) {
149 args.push(arg);
150 }
151
152 args
153 }
154}
155
156impl<'hir> HirOrTyGenerics<'hir> {
157 pub(super) fn into_hir_generics(&mut self, ctx: &mut LoweringContext<'_, 'hir>, span: Span) {
158 if let HirOrTyGenerics::Ty(ty) = self {
159 let rename_self = ty.pos == GenericsPosition::Child;
160 let params = ctx.uplift_delegation_generic_params(span, &ty.data, rename_self);
161
162 *self = HirOrTyGenerics::Hir(DelegationGenerics {
163 data: params,
164 pos: ty.pos,
165 trait_impl: ty.trait_impl,
166 });
167 }
168 }
169
170 fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> {
171 match self {
172 HirOrTyGenerics::Ty(_) => hir::Generics::empty(),
173 HirOrTyGenerics::Hir(hir) => hir.data,
174 }
175 }
176
177 pub(super) fn create_args_iterator(&self) -> DelegationGenericArgsIterator<'hir> {
178 match self {
179 HirOrTyGenerics::Ty(_) => {
180 ::rustc_middle::util::bug::bug_fmt(format_args!("attempting to get generic args before uplifting to HIR"))bug!("attempting to get generic args before uplifting to HIR")
181 }
182 HirOrTyGenerics::Hir(hir) => {
183 DelegationGenericArgsIterator { params: hir.data.params, .. }
184 }
185 }
186 }
187
188 pub(super) fn infer_indices(&self) -> FxHashSet<usize> {
189 match self {
190 HirOrTyGenerics::Ty(ty) => ty
191 .data
192 .iter()
193 .flat_map(|slot| match slot {
194 GenericArgSlot::Generate(_, Some(idx)) => Some(*idx),
195 _ => None,
196 })
197 .collect(),
198 HirOrTyGenerics::Hir(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("accessed infer indices on uplifted generics"))bug!("accessed infer indices on uplifted generics"),
199 }
200 }
201
202 pub(super) fn is_trait_impl(&self) -> bool {
203 match self {
204 HirOrTyGenerics::Ty(ty) => ty.trait_impl,
205 HirOrTyGenerics::Hir(hir) => hir.trait_impl,
206 }
207 }
208
209 pub(super) fn find_self_param(&self) -> &'hir hir::GenericParam<'hir> {
210 match self {
211 HirOrTyGenerics::Ty(_) => {
212 ::rustc_middle::util::bug::bug_fmt(format_args!("accessed ty-level generics while searching for uplifted `Self` param"))bug!("accessed ty-level generics while searching for uplifted `Self` param")
213 }
214 HirOrTyGenerics::Hir(hir) => hir
215 .data
216 .params
217 .iter()
218 .find(|p| p.name.ident().name == kw::SelfUpper)
219 .expect("`Self` generic param is not found while expected"),
220 }
221 }
222
223 pub(crate) fn pos(&self) -> GenericsPosition {
224 match self {
225 HirOrTyGenerics::Ty(ty) => ty.pos,
226 HirOrTyGenerics::Hir(hir) => hir.pos,
227 }
228 }
229}
230
231impl<'hir> GenericsGenerationResult<'hir> {
232 fn new(generics: DelegationGenerics<TyGenerics<'hir>>) -> GenericsGenerationResult<'hir> {
233 GenericsGenerationResult {
234 generics: HirOrTyGenerics::Ty(generics),
235 args_segment_id: HirId::INVALID,
236 use_for_sig_inheritance: false,
237 }
238 }
239}
240
241enum ParentSegmentArgs<'a> {
242 Specified(&'a AngleBracketedArgs),
245 NotSpecified,
248 Invalid,
259}
260
261struct GenericsResolution<'a, 'tcx> {
262 trait_impl: bool,
263
264 parent_args: ParentSegmentArgs<'a>,
265 child_args: Option<&'a AngleBracketedArgs>,
266
267 sig_parent_params: &'tcx [ty::GenericParamDef],
268 sig_child_params: &'tcx [ty::GenericParamDef],
269
270 free_to_trait_delegation: bool,
271 qself_is_none: bool,
273 qself_is_infer: bool,
275 generate_self: bool,
277}
278
279impl<'hir> DelegationResolver<'_, 'hir> {
280 fn resolve_generics<'a>(
281 &self,
282 delegation: &'a Delegation,
283 sig_id: DefId,
284 ) -> Result<GenericsResolution<'a, 'hir>, ErrorGuaranteed> {
285 let tcx = self.tcx();
286 let delegation_parent_kind = tcx.def_kind(tcx.local_parent(self.owner_id()));
287
288 let delegation_in_free_ctx =
289 !#[allow(non_exhaustive_omitted_patterns)] match delegation_parent_kind {
DefKind::Trait | DefKind::Impl { .. } => true,
_ => false,
}matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. });
290
291 let sig_parent = tcx.parent(sig_id);
292 let sig_in_trait = #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(sig_parent) {
DefKind::Trait => true,
_ => false,
}matches!(tcx.def_kind(sig_parent), DefKind::Trait);
293 let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
294
295 let mut sig_parent_params: &[ty::GenericParamDef] = &[];
296
297 let qself_is_infer =
298 delegation.qself.as_ref().is_some_and(|qself| qself.ty.is_maybe_parenthesised_infer());
299
300 let qself_is_none = delegation.qself.is_none();
301
302 let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] {
303 let res = self.get_resolution_id(parent_segment.id)?;
304 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(res) {
DefKind::Trait | DefKind::TraitAlias => true,
_ => false,
}matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) {
305 sig_parent_params = &tcx.generics_of(sig_parent).own_params;
306 self.get_user_args(parent_segment)
307 .map(|args| ParentSegmentArgs::Specified(args))
308 .unwrap_or(ParentSegmentArgs::NotSpecified)
309 } else {
310 ParentSegmentArgs::Invalid
311 }
312 } else {
313 ParentSegmentArgs::Invalid
314 };
315
316 Ok(GenericsResolution {
317 parent_args,
318 sig_parent_params,
319 qself_is_none,
320 qself_is_infer,
321 free_to_trait_delegation,
322 generate_self: free_to_trait_delegation && (qself_is_none || qself_is_infer),
323 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 }),
324 sig_child_params: &tcx.generics_of(sig_id).own_params,
325 child_args: self.get_user_args(
326 delegation.path.segments.last().expect("must be at least one segment"),
327 ),
328 })
329 }
330
331 fn get_user_args<'a>(&self, segment: &'a PathSegment) -> Option<&'a AngleBracketedArgs> {
332 let Some(args) = &segment.args else { return None };
333 let GenericArgs::AngleBracketed(args) = args else {
334 self.tcx().dcx().span_delayed_bug(
335 segment.span(),
336 "expected angle-bracketed generic args in delegation segment",
337 );
338
339 return None;
340 };
341
342 (!args.args.is_empty()).then(|| args)
346 }
347
348 pub(super) fn resolve_and_generate_generics(
349 &self,
350 delegation: &Delegation,
351 sig_id: DefId,
352 ) -> Result<GenericsGenerationResults<'hir>, ErrorGuaranteed> {
353 let res @ GenericsResolution {
354 trait_impl,
355 generate_self,
356 sig_child_params,
357 sig_parent_params,
358 ..
359 } = self.resolve_generics(delegation, sig_id)?;
360
361 if trait_impl {
364 let parent =
367 DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Child, trait_impl: true };
368
369 let parent = GenericsGenerationResult::new(parent);
370
371 let child =
372 DelegationGenerics::generate_all(sig_child_params, GenericsPosition::Child, true);
373
374 let child = GenericsGenerationResult::new(child);
375
376 return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None });
377 }
378
379 let tcx = self.tcx();
380 let parent_generics = match res.parent_args {
381 ParentSegmentArgs::Specified(args) => DelegationGenerics {
382 data: Self::create_slots_from_args(
383 tcx,
384 args,
385 &sig_parent_params[usize::from(!generate_self)..],
386 generate_self,
387 ),
388 pos: GenericsPosition::Parent,
389 trait_impl,
390 },
391 ParentSegmentArgs::NotSpecified => DelegationGenerics::generate_all(
392 &sig_parent_params[usize::from(!generate_self)..],
393 GenericsPosition::Parent,
394 trait_impl,
395 ),
396 ParentSegmentArgs::Invalid => {
397 DelegationGenerics { data: ::alloc::vec::Vec::new()vec![], pos: GenericsPosition::Parent, trait_impl }
398 }
399 };
400
401 let child_generics = if let Some(args) = res.child_args {
402 let synth_params_index = sig_child_params
403 .iter()
404 .position(|p| p.kind.is_synthetic())
405 .unwrap_or(sig_child_params.len());
406
407 let mut slots = Self::create_slots_from_args(
408 tcx,
409 args,
410 &sig_child_params[..synth_params_index],
411 trait_impl,
412 );
413
414 for synth_param in &sig_child_params[synth_params_index..] {
415 slots.push(GenericArgSlot::Generate(synth_param, None));
416 }
417
418 DelegationGenerics { data: slots, pos: GenericsPosition::Child, trait_impl }
419 } else {
420 DelegationGenerics::generate_all(sig_child_params, GenericsPosition::Child, trait_impl)
421 };
422
423 Ok(GenericsGenerationResults {
424 parent: GenericsGenerationResult::new(parent_generics),
425 child: GenericsGenerationResult::new(child_generics),
426 self_ty_propagation_kind: match res.free_to_trait_delegation {
427 true => Some(match res.qself_is_none {
428 true => hir::DelegationSelfTyPropagationKind::SelfParam,
429 false => match res.qself_is_infer {
430 true => hir::DelegationSelfTyPropagationKind::SelfParam,
431 false => hir::DelegationSelfTyPropagationKind::SelfTy(HirId::INVALID),
433 },
434 }),
435 false => None,
436 },
437 })
438 }
439
440 fn create_slots_from_args(
449 tcx: TyCtxt<'_>,
450 args: &AngleBracketedArgs,
451 params: &'hir [ty::GenericParamDef],
452 add_first_self: bool,
453 ) -> TyGenerics<'hir> {
454 let mut slots = ::alloc::vec::Vec::new()vec![];
455 if add_first_self {
456 slots.push(GenericArgSlot::Generate(¶ms[0], None));
457 }
458
459 let params = ¶ms[usize::from(add_first_self)..];
460 for (idx, (arg, param)) in args.args.iter().zip(params).enumerate() {
461 let AngleBracketedArg::Arg(arg) = arg else { continue };
462
463 let is_infer = match arg {
464 GenericArg::Lifetime(lt) => lt.ident.name == kw::UnderscoreLifetime,
465 GenericArg::Type(ty) => ty.is_maybe_parenthesised_infer(),
466 GenericArg::Const(_) => false,
467 };
468
469 if is_infer
473 && #[allow(non_exhaustive_omitted_patterns)] match (arg, ¶m.kind) {
(GenericArg::Lifetime(_),
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. })
|
(GenericArg::Type(_) | GenericArg::Const(_),
GenericParamDefKind::Lifetime { .. }) => true,
_ => false,
}matches!(
474 (arg, ¶m.kind),
475 (
476 GenericArg::Lifetime(_),
477 GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. }
478 ) | (
479 GenericArg::Type(_) | GenericArg::Const(_),
480 GenericParamDefKind::Lifetime { .. }
481 )
482 )
483 {
484 let (actual, expected) = if #[allow(non_exhaustive_omitted_patterns)] match arg {
GenericArg::Lifetime(..) => true,
_ => false,
}matches!(arg, GenericArg::Lifetime(..)) {
485 (kw::UnderscoreLifetime, kw::Underscore)
486 } else {
487 (kw::Underscore, kw::UnderscoreLifetime)
488 };
489
490 tcx.dcx().emit_err(DelegationInfersMismatch { span: arg.span(), actual, expected });
491 }
492
493 slots.push(match is_infer {
494 true => GenericArgSlot::Generate(param, Some(idx)),
495 false => GenericArgSlot::UserSpecified,
496 });
497 }
498
499 slots
500 }
501}
502
503impl<'hir> GenericsGenerationResults<'hir> {
504 pub(super) fn all_params(&self) -> impl Iterator<Item = hir::GenericParam<'hir>> {
505 let parent = self.parent.generics.hir_generics_or_empty().params;
506 let child = self.child.generics.hir_generics_or_empty().params;
507
508 parent
513 .iter()
514 .filter(|p| p.is_lifetime())
515 .chain(child.iter().filter(|p| p.is_lifetime()))
516 .chain(parent.iter().filter(|p| !p.is_lifetime()))
517 .chain(child.iter().filter(|p| !p.is_lifetime()))
518 .copied()
519 }
520
521 pub(super) fn all_predicates(&self) -> impl Iterator<Item = hir::WherePredicate<'hir>> {
526 self.parent
527 .generics
528 .hir_generics_or_empty()
529 .predicates
530 .into_iter()
531 .chain(self.child.generics.hir_generics_or_empty().predicates)
532 .copied()
533 }
534}
535
536impl<'hir> LoweringContext<'_, 'hir> {
537 fn uplift_delegation_generic_params(
538 &mut self,
539 span: Span,
540 params: &[GenericArgSlot<&ty::GenericParamDef>],
541 rename_self: bool,
542 ) -> &'hir hir::Generics<'hir> {
543 let params = self.arena.alloc_from_iter(params.iter().flat_map(|p| {
544 let GenericArgSlot::Generate(p, _) = p else { return None };
545
546 let def_kind = match p.kind {
547 GenericParamDefKind::Lifetime => DefKind::LifetimeParam,
548 GenericParamDefKind::Type { .. } => DefKind::TyParam,
549 GenericParamDefKind::Const { .. } => DefKind::ConstParam,
550 };
551
552 let param_name =
563 if rename_self && p.name == kw::SelfUpper { sym::This } else { p.name };
564
565 let param_ident = Ident::new(param_name, span);
566 let def_name = Some(param_ident.name);
567 let node_id = self.next_node_id();
568
569 let def_id = self.create_def(node_id, def_name, def_kind, span);
570
571 let kind = match p.kind {
572 GenericParamDefKind::Lifetime => {
573 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
574 }
575 GenericParamDefKind::Type { synthetic, .. } => {
576 hir::GenericParamKind::Type { default: None, synthetic }
577 }
578 GenericParamDefKind::Const { .. } => {
579 let hir_id = self.next_id();
580 let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id));
581
582 hir::GenericParamKind::Const {
583 ty: self.arena.alloc(hir::Ty { kind, hir_id, span }),
584 default: None,
585 }
586 }
587 };
588
589 let hir_id = self.lower_node_id(node_id);
592
593 Some(hir::GenericParam {
594 hir_id,
595 colon_span: Some(span),
596 def_id,
597 kind,
598 name: hir::ParamName::Plain(param_ident),
599 pure_wrt_drop: p.pure_wrt_drop,
600 source: hir::GenericParamSource::Generics,
601 span,
602 })
603 }));
604
605 let predicates =
609 self.arena.alloc_from_iter(params.iter().filter_map(|p| {
610 p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span))
611 }));
612
613 self.arena.alloc(hir::Generics {
614 params,
615 predicates,
616 has_where_clause_predicates: false,
617 where_clause_span: span,
618 span,
619 })
620 }
621
622 fn generate_lifetime_predicate(
623 &mut self,
624 p: &hir::GenericParam<'hir>,
625 span: Span,
626 ) -> hir::WherePredicate<'hir> {
627 let create_lifetime = |this: &mut Self| -> &'hir hir::Lifetime {
628 this.arena.alloc(hir::Lifetime {
629 hir_id: this.next_id(),
630 ident: p.name.ident(),
631 kind: hir::LifetimeKind::Param(p.def_id),
632 source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
633 syntax: hir::LifetimeSyntax::ExplicitBound,
634 })
635 };
636
637 hir::WherePredicate {
638 hir_id: self.next_id(),
639 span,
640 kind: self.arena.alloc(hir::WherePredicateKind::RegionPredicate(
641 hir::WhereRegionPredicate {
642 in_where_clause: true,
643 lifetime: create_lifetime(self),
644 bounds: self
645 .arena
646 .alloc_slice(&[hir::GenericBound::Outlives(create_lifetime(self))]),
647 },
648 )),
649 }
650 }
651
652 pub(super) fn create_generic_arg_path(
653 &mut self,
654 p: &hir::GenericParam<'hir>,
655 ) -> hir::QPath<'hir> {
656 let res = Res::Def(
657 match p.kind {
658 hir::GenericParamKind::Lifetime { .. } => DefKind::LifetimeParam,
659 hir::GenericParamKind::Type { .. } => DefKind::TyParam,
660 hir::GenericParamKind::Const { .. } => DefKind::ConstParam,
661 },
662 p.def_id.to_def_id(),
663 );
664
665 self.create_resolved_path(res, p.name.ident(), p.span)
666 }
667
668 pub(super) fn create_resolved_path(
669 &mut self,
670 res: Res,
671 ident: Ident,
672 span: Span,
673 ) -> hir::QPath<'hir> {
674 hir::QPath::Resolved(
675 None,
676 self.arena.alloc(hir::Path {
677 segments: self.arena.alloc_slice(&[hir::PathSegment {
678 args: None,
679 hir_id: self.next_id(),
680 ident,
681 infer_args: false,
682 res,
683 delegation_child_segment: false,
684 }]),
685 res,
686 span,
687 }),
688 )
689 }
690}