1use std::iter;
40
41use ast::visit::Visitor;
42use hir::def::{DefKind, PartialRes, Res};
43use hir::{BodyId, HirId};
44use rustc_abi::ExternAbi;
45use rustc_ast::*;
46use rustc_attr_parsing::{AttributeParser, ShouldEmit};
47use rustc_data_structures::fx::FxHashSet;
48use rustc_errors::ErrorGuaranteed;
49use rustc_hir::attrs::{AttributeKind, InlineAttr};
50use rustc_hir::def_id::{DefId, LocalDefId};
51use rustc_middle::span_bug;
52use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs, ResolverAstLowering};
53use rustc_span::symbol::kw;
54use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
55use smallvec::SmallVec;
56use {rustc_ast as ast, rustc_hir as hir};
57
58use crate::delegation::generics::{GenericsGenerationResult, GenericsGenerationResults};
59use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee};
60use crate::{
61 AllowReturnTypeNotation, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext,
62 ParamMode, ResolverAstLoweringExt,
63};
64
65mod generics;
66
67pub(crate) struct DelegationResults<'hir> {
68 pub body_id: hir::BodyId,
69 pub sig: hir::FnSig<'hir>,
70 pub ident: Ident,
71 pub generics: &'hir hir::Generics<'hir>,
72}
73
74struct AttrAdditionInfo {
75 pub equals: fn(&hir::Attribute) -> bool,
76 pub kind: AttrAdditionKind,
77}
78
79enum AttrAdditionKind {
80 Default { factory: fn(Span) -> hir::Attribute },
81 Inherit { flag: DelegationFnSigAttrs, factory: fn(Span, &hir::Attribute) -> hir::Attribute },
82}
83
84const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
85
86static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
87 AttrAdditionInfo {
88 equals: |a| #[allow(non_exhaustive_omitted_patterns)] match a {
hir::Attribute::Parsed(AttributeKind::MustUse { .. }) => true,
_ => false,
}matches!(a, hir::Attribute::Parsed(AttributeKind::MustUse { .. })),
89 kind: AttrAdditionKind::Inherit {
90 factory: |span, original_attr| {
91 let reason = match original_attr {
92 hir::Attribute::Parsed(AttributeKind::MustUse { reason, .. }) => *reason,
93 _ => None,
94 };
95
96 hir::Attribute::Parsed(AttributeKind::MustUse { span, reason })
97 },
98 flag: DelegationFnSigAttrs::MUST_USE,
99 },
100 },
101 AttrAdditionInfo {
102 equals: |a| #[allow(non_exhaustive_omitted_patterns)] match a {
hir::Attribute::Parsed(AttributeKind::Inline(..)) => true,
_ => false,
}matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))),
103 kind: AttrAdditionKind::Default {
104 factory: |span| hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span)),
105 },
106 },
107];
108
109type DelegationIdsVec = SmallVec<[DefId; 1]>;
110
111struct DelegationIds {
115 path: DelegationIdsVec,
116}
117
118impl DelegationIds {
119 fn new(path: DelegationIdsVec) -> Self {
120 if !!path.is_empty() {
::core::panicking::panic("assertion failed: !path.is_empty()")
};assert!(!path.is_empty());
121 Self { path }
122 }
123
124 fn root_function_id(&self) -> DefId {
126 *self.path.last().expect("Ids vector can't be empty")
127 }
128
129 fn delegee_id(&self) -> DefId {
132 *self.path.first().expect("Ids vector can't be empty")
133 }
134}
135
136impl<'hir> LoweringContext<'_, 'hir> {
137 fn is_method(&self, def_id: DefId, span: Span) -> bool {
138 match self.tcx.def_kind(def_id) {
139 DefKind::Fn => false,
140 DefKind::AssocFn => match def_id.as_local() {
141 Some(local_def_id) => self
142 .resolver
143 .delegation_fn_sigs
144 .get(&local_def_id)
145 .is_some_and(|sig| sig.has_self),
146 None => self.tcx.associated_item(def_id).is_method(),
147 },
148 _ => ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("unexpected DefKind for delegation item"))span_bug!(span, "unexpected DefKind for delegation item"),
149 }
150 }
151
152 pub(crate) fn lower_delegation(
153 &mut self,
154 delegation: &Delegation,
155 item_id: NodeId,
156 ) -> DelegationResults<'hir> {
157 let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
158
159 let ids = if let Some(delegation_info) =
161 self.resolver.delegation_infos.get(&self.local_def_id(item_id))
162 {
163 self.get_delegation_ids(delegation_info.resolution_node, span)
164 } else {
165 return self.generate_delegation_error(
166 self.dcx().span_delayed_bug(
167 span,
168 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("LoweringContext: the delegation {0:?} is unresolved",
item_id))
})format!("LoweringContext: the delegation {:?} is unresolved", item_id),
169 ),
170 span,
171 delegation,
172 );
173 };
174
175 match ids {
176 Ok(ids) => {
177 self.add_attrs_if_needed(span, &ids);
178
179 let delegee_id = ids.delegee_id();
180 let root_function_id = ids.root_function_id();
181
182 let is_method = self.is_method(root_function_id, span);
186
187 let (param_count, c_variadic) = self.param_count(root_function_id);
190
191 let mut generics = self.lower_delegation_generics(
192 delegation,
193 ids.root_function_id(),
194 item_id,
195 span,
196 );
197
198 let body_id = self.lower_delegation_body(
199 delegation,
200 item_id,
201 is_method,
202 param_count,
203 &mut generics,
204 span,
205 );
206
207 let decl = self.lower_delegation_decl(
211 delegee_id,
212 param_count,
213 c_variadic,
214 span,
215 &generics,
216 );
217
218 let sig = self.lower_delegation_sig(root_function_id, decl, span);
221 let ident = self.lower_ident(delegation.ident);
222
223 let generics = self.arena.alloc(hir::Generics {
224 has_where_clause_predicates: false,
225 params: self.arena.alloc_from_iter(generics.all_params(item_id, span, self)),
226 predicates: self
227 .arena
228 .alloc_from_iter(generics.all_predicates(item_id, span, self)),
229 span,
230 where_clause_span: span,
231 });
232
233 DelegationResults { body_id, sig, ident, generics }
234 }
235 Err(err) => self.generate_delegation_error(err, span, delegation),
236 }
237 }
238
239 fn add_attrs_if_needed(&mut self, span: Span, ids: &DelegationIds) {
240 let new_attrs =
241 self.create_new_attrs(ATTRS_ADDITIONS, span, ids, self.attrs.get(&PARENT_ID));
242
243 if new_attrs.is_empty() {
244 return;
245 }
246
247 let new_arena_allocated_attrs = match self.attrs.get(&PARENT_ID) {
248 Some(existing_attrs) => self.arena.alloc_from_iter(
249 existing_attrs.iter().map(|a| a.clone()).chain(new_attrs.into_iter()),
250 ),
251 None => self.arena.alloc_from_iter(new_attrs.into_iter()),
252 };
253
254 self.attrs.insert(PARENT_ID, new_arena_allocated_attrs);
255 }
256
257 fn create_new_attrs(
258 &self,
259 candidate_additions: &[AttrAdditionInfo],
260 span: Span,
261 ids: &DelegationIds,
262 existing_attrs: Option<&&[hir::Attribute]>,
263 ) -> Vec<hir::Attribute> {
264 let defs_orig_attrs = ids
265 .path
266 .iter()
267 .map(|def_id| (*def_id, self.parse_local_original_attrs(*def_id)))
268 .collect::<Vec<_>>();
269
270 candidate_additions
271 .iter()
272 .filter_map(|addition_info| {
273 if let Some(existing_attrs) = existing_attrs
274 && existing_attrs
275 .iter()
276 .any(|existing_attr| (addition_info.equals)(existing_attr))
277 {
278 return None;
279 }
280
281 match addition_info.kind {
282 AttrAdditionKind::Default { factory } => Some(factory(span)),
283 AttrAdditionKind::Inherit { flag, factory } => {
284 for (def_id, orig_attrs) in &defs_orig_attrs {
285 let original_attr = match def_id.as_local() {
286 Some(local_id) => self
287 .get_attrs(local_id)
288 .flags
289 .contains(flag)
290 .then(|| {
291 orig_attrs
292 .as_ref()
293 .map(|attrs| {
294 attrs.iter().find(|base_attr| {
295 (addition_info.equals)(base_attr)
296 })
297 })
298 .flatten()
299 })
300 .flatten(),
301 None =>
302 {
303 #[allow(deprecated)]
304 self.tcx
305 .get_all_attrs(*def_id)
306 .iter()
307 .find(|base_attr| (addition_info.equals)(base_attr))
308 }
309 };
310
311 if let Some(original_attr) = original_attr {
312 return Some(factory(span, original_attr));
313 }
314 }
315
316 None
317 }
318 }
319 })
320 .collect::<Vec<_>>()
321 }
322
323 fn parse_local_original_attrs(&self, def_id: DefId) -> Option<Vec<hir::Attribute>> {
324 if let Some(local_id) = def_id.as_local() {
325 let attrs = &self.get_attrs(local_id).to_inherit;
326
327 if !attrs.is_empty() {
328 return Some(AttributeParser::parse_limited_all(
329 self.tcx.sess,
330 attrs,
331 None,
332 hir::Target::Fn,
333 DUMMY_SP,
334 DUMMY_NODE_ID,
335 Some(self.tcx.features()),
336 ShouldEmit::Nothing,
337 ));
338 }
339 }
340
341 None
342 }
343
344 fn get_attrs(&self, local_id: LocalDefId) -> &DelegationAttrs {
345 if let Some(fn_sig) = self.resolver.delegation_fn_sigs.get(&local_id) {
347 &fn_sig.attrs
348 } else {
349 &self.resolver.delegation_infos[&local_id].attrs
350 }
351 }
352
353 fn get_delegation_ids(
354 &self,
355 mut node_id: NodeId,
356 span: Span,
357 ) -> Result<DelegationIds, ErrorGuaranteed> {
358 let mut visited: FxHashSet<NodeId> = Default::default();
359 let mut path: DelegationIdsVec = Default::default();
360
361 loop {
362 visited.insert(node_id);
363
364 let Some(def_id) = self.get_resolution_id(node_id) else {
365 return Err(self.tcx.dcx().span_delayed_bug(
366 span,
367 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("LoweringContext: couldn\'t resolve node {0:?} in delegation item",
node_id))
})format!(
368 "LoweringContext: couldn't resolve node {:?} in delegation item",
369 node_id
370 ),
371 ));
372 };
373
374 path.push(def_id);
375
376 if let Some(local_id) = def_id.as_local()
380 && let Some(delegation_info) = self.resolver.delegation_infos.get(&local_id)
381 {
382 node_id = delegation_info.resolution_node;
383 if visited.contains(&node_id) {
384 return Err(match visited.len() {
387 1 => self.dcx().emit_err(UnresolvedDelegationCallee { span }),
388 _ => self.dcx().emit_err(CycleInDelegationSignatureResolution { span }),
389 });
390 }
391 } else {
392 return Ok(DelegationIds::new(path));
393 }
394 }
395 }
396
397 fn get_resolution_id(&self, node_id: NodeId) -> Option<DefId> {
398 self.resolver.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id())
399 }
400
401 fn param_count(&self, def_id: DefId) -> (usize, bool ) {
403 if let Some(local_sig_id) = def_id.as_local() {
404 match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
405 Some(sig) => (sig.param_count, sig.c_variadic),
406 None => (0, false),
407 }
408 } else {
409 let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
410 (sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic)
411 }
412 }
413
414 fn lower_delegation_decl(
415 &mut self,
416 sig_id: DefId,
417 param_count: usize,
418 c_variadic: bool,
419 span: Span,
420 generics: &GenericsGenerationResults<'hir>,
421 ) -> &'hir hir::FnDecl<'hir> {
422 let decl_param_count = param_count - c_variadic as usize;
425 let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty {
426 hir_id: self.next_id(),
427 kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)),
428 span,
429 }));
430
431 let output = self.arena.alloc(hir::Ty {
432 hir_id: self.next_id(),
433 kind: hir::TyKind::InferDelegation(
434 sig_id,
435 hir::InferDelegationKind::Output(self.arena.alloc(hir::DelegationGenerics {
436 child_args_segment_id: generics.child.args_segment_id,
437 parent_args_segment_id: generics.parent.args_segment_id,
438 })),
439 ),
440 span,
441 });
442
443 self.arena.alloc(hir::FnDecl {
444 inputs,
445 output: hir::FnRetTy::Return(output),
446 c_variadic,
447 lifetime_elision_allowed: true,
448 implicit_self: hir::ImplicitSelfKind::None,
449 })
450 }
451
452 fn lower_delegation_sig(
453 &mut self,
454 sig_id: DefId,
455 decl: &'hir hir::FnDecl<'hir>,
456 span: Span,
457 ) -> hir::FnSig<'hir> {
458 let header = if let Some(local_sig_id) = sig_id.as_local() {
459 match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
460 Some(sig) => {
461 let parent = self.tcx.parent(sig_id);
462 let default_safety =
466 if sig.attrs.flags.contains(DelegationFnSigAttrs::TARGET_FEATURE)
467 || self.tcx.def_kind(parent) == DefKind::ForeignMod
468 {
469 hir::Safety::Unsafe
470 } else {
471 hir::Safety::Safe
472 };
473 self.lower_fn_header(sig.header, default_safety, &[])
474 }
475 None => self.generate_header_error(),
476 }
477 } else {
478 let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
479 let asyncness = match self.tcx.asyncness(sig_id) {
480 Asyncness::Yes => hir::IsAsync::Async(span),
481 Asyncness::No => hir::IsAsync::NotAsync,
482 };
483 hir::FnHeader {
484 safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
485 hir::HeaderSafety::SafeTargetFeatures
486 } else {
487 hir::HeaderSafety::Normal(sig.safety)
488 },
489 constness: self.tcx.constness(sig_id),
490 asyncness,
491 abi: sig.abi,
492 }
493 };
494
495 hir::FnSig { decl, header, span }
496 }
497
498 fn generate_param(
499 &mut self,
500 is_method: bool,
501 idx: usize,
502 span: Span,
503 ) -> (hir::Param<'hir>, NodeId) {
504 let pat_node_id = self.next_node_id();
505 let pat_id = self.lower_node_id(pat_node_id);
506 let name = if is_method && idx == 0 {
508 kw::SelfLower
509 } else {
510 Symbol::intern(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("arg{0}", idx))
})format!("arg{idx}"))
511 };
512 let ident = Ident::with_dummy_span(name);
513 let pat = self.arena.alloc(hir::Pat {
514 hir_id: pat_id,
515 kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, ident, None),
516 span,
517 default_binding_modes: false,
518 });
519
520 (hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
521 }
522
523 fn generate_arg(
524 &mut self,
525 is_method: bool,
526 idx: usize,
527 param_id: HirId,
528 span: Span,
529 ) -> hir::Expr<'hir> {
530 let name = if is_method && idx == 0 {
532 kw::SelfLower
533 } else {
534 Symbol::intern(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("arg{0}", idx))
})format!("arg{idx}"))
535 };
536
537 let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
538 ident: Ident::with_dummy_span(name),
539 hir_id: self.next_id(),
540 res: Res::Local(param_id),
541 args: None,
542 infer_args: false,
543 }));
544
545 let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
546 self.mk_expr(hir::ExprKind::Path(hir::QPath::Resolved(None, path)), span)
547 }
548
549 fn lower_delegation_body(
550 &mut self,
551 delegation: &Delegation,
552 item_id: NodeId,
553 is_method: bool,
554 param_count: usize,
555 generics: &mut GenericsGenerationResults<'hir>,
556 span: Span,
557 ) -> BodyId {
558 let block = delegation.body.as_deref();
559
560 self.lower_body(|this| {
561 let mut parameters: Vec<hir::Param<'_>> = Vec::with_capacity(param_count);
562 let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
563
564 for idx in 0..param_count {
565 let (param, pat_node_id) = this.generate_param(is_method, idx, span);
566 parameters.push(param);
567
568 let arg = if let Some(block) = block
569 && idx == 0
570 {
571 let mut self_resolver = SelfResolver {
572 resolver: this.resolver,
573 path_id: delegation.id,
574 self_param_id: pat_node_id,
575 };
576 self_resolver.visit_block(block);
577 this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
579 this.lower_target_expr(&block)
580 } else {
581 this.generate_arg(is_method, idx, param.pat.hir_id, span)
582 };
583 args.push(arg);
584 }
585
586 let final_expr = this.finalize_body_lowering(delegation, item_id, args, generics, span);
587
588 (this.arena.alloc_from_iter(parameters), final_expr)
589 })
590 }
591
592 fn lower_target_expr(&mut self, block: &Block) -> hir::Expr<'hir> {
595 if let [stmt] = block.stmts.as_slice()
596 && let StmtKind::Expr(expr) = &stmt.kind
597 {
598 return self.lower_expr_mut(expr);
599 }
600
601 let block = self.lower_block(block, false);
602 self.mk_expr(hir::ExprKind::Block(block, None), block.span)
603 }
604
605 fn finalize_body_lowering(
621 &mut self,
622 delegation: &Delegation,
623 item_id: NodeId,
624 args: Vec<hir::Expr<'hir>>,
625 generics: &mut GenericsGenerationResults<'hir>,
626 span: Span,
627 ) -> hir::Expr<'hir> {
628 let args = self.arena.alloc_from_iter(args);
629
630 let has_generic_args =
631 delegation.path.segments.iter().rev().skip(1).any(|segment| segment.args.is_some());
632
633 let call = if self
634 .get_resolution_id(delegation.id)
635 .map(|def_id| self.is_method(def_id, span))
636 .unwrap_or_default()
637 && delegation.qself.is_none()
638 && !has_generic_args
639 && !args.is_empty()
640 {
641 let ast_segment = delegation.path.segments.last().unwrap();
642 let segment = self.lower_path_segment(
643 delegation.path.span,
644 ast_segment,
645 ParamMode::Optional,
646 GenericArgsMode::Err,
647 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
648 None,
649 );
650
651 let segment = self.process_segment(item_id, span, &segment, &mut generics.child, false);
654 let segment = self.arena.alloc(segment);
655
656 self.arena.alloc(hir::Expr {
657 hir_id: self.next_id(),
658 kind: hir::ExprKind::MethodCall(segment, &args[0], &args[1..], span),
659 span,
660 })
661 } else {
662 let path = self.lower_qpath(
663 delegation.id,
664 &delegation.qself,
665 &delegation.path,
666 ParamMode::Optional,
667 AllowReturnTypeNotation::No,
668 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
669 None,
670 );
671
672 let new_path = match path {
673 hir::QPath::Resolved(ty, path) => {
674 let mut new_path = path.clone();
675 let len = new_path.segments.len();
676
677 new_path.segments = self.arena.alloc_from_iter(
678 new_path.segments.iter().enumerate().map(|(idx, segment)| {
679 let mut process_segment = |result, add_lifetimes| {
680 self.process_segment(item_id, span, segment, result, add_lifetimes)
681 };
682
683 if idx + 2 == len {
684 process_segment(&mut generics.parent, true)
685 } else if idx + 1 == len {
686 process_segment(&mut generics.child, false)
687 } else {
688 segment.clone()
689 }
690 }),
691 );
692
693 hir::QPath::Resolved(ty, self.arena.alloc(new_path))
694 }
695 hir::QPath::TypeRelative(ty, segment) => {
696 let segment =
697 self.process_segment(item_id, span, segment, &mut generics.child, false);
698
699 hir::QPath::TypeRelative(ty, self.arena.alloc(segment))
700 }
701 };
702
703 let callee_path = self.arena.alloc(self.mk_expr(hir::ExprKind::Path(new_path), span));
704 self.arena.alloc(self.mk_expr(hir::ExprKind::Call(callee_path, args), span))
705 };
706
707 let block = self.arena.alloc(hir::Block {
708 stmts: &[],
709 expr: Some(call),
710 hir_id: self.next_id(),
711 rules: hir::BlockCheckMode::DefaultBlock,
712 span,
713 targeted_by_break: false,
714 });
715
716 self.mk_expr(hir::ExprKind::Block(block, None), span)
717 }
718
719 fn process_segment(
720 &mut self,
721 item_id: NodeId,
722 span: Span,
723 segment: &hir::PathSegment<'hir>,
724 result: &mut GenericsGenerationResult<'hir>,
725 add_lifetimes: bool,
726 ) -> hir::PathSegment<'hir> {
727 let segment = if !result.generics.is_user_specified()
730 && let Some(args) = result
731 .generics
732 .into_hir_generics(self, item_id, span)
733 .into_generic_args(self, add_lifetimes, span)
734 {
735 hir::PathSegment { args: Some(args), ..segment.clone() }
736 } else {
737 segment.clone()
738 };
739
740 if result.generics.is_user_specified() {
741 result.args_segment_id = Some(segment.hir_id);
742 }
743
744 segment
745 }
746
747 fn generate_delegation_error(
748 &mut self,
749 err: ErrorGuaranteed,
750 span: Span,
751 delegation: &Delegation,
752 ) -> DelegationResults<'hir> {
753 let decl = self.arena.alloc(hir::FnDecl {
754 inputs: &[],
755 output: hir::FnRetTy::DefaultReturn(span),
756 c_variadic: false,
757 lifetime_elision_allowed: true,
758 implicit_self: hir::ImplicitSelfKind::None,
759 });
760
761 let header = self.generate_header_error();
762 let sig = hir::FnSig { decl, header, span };
763
764 let ident = self.lower_ident(delegation.ident);
765
766 let body_id = self.lower_body(|this| {
767 let body_expr = match delegation.body.as_ref() {
768 Some(box block) => {
769 let stmts = this.arena.alloc_from_iter([hir::Stmt {
775 hir_id: this.next_id(),
776 kind: rustc_hir::StmtKind::Semi(
777 this.arena.alloc(this.lower_target_expr(block)),
778 ),
779 span,
780 }]);
781
782 let block = this.arena.alloc(hir::Block {
783 stmts,
784 expr: None,
785 hir_id: this.next_id(),
786 rules: hir::BlockCheckMode::DefaultBlock,
787 span,
788 targeted_by_break: false,
789 });
790
791 hir::ExprKind::Block(block, None)
792 }
793 None => hir::ExprKind::Err(err),
794 };
795
796 (&[], this.mk_expr(body_expr, span))
797 });
798
799 let generics = hir::Generics::empty();
800 DelegationResults { ident, generics, body_id, sig }
801 }
802
803 fn generate_header_error(&self) -> hir::FnHeader {
804 hir::FnHeader {
805 safety: hir::Safety::Safe.into(),
806 constness: hir::Constness::NotConst,
807 asyncness: hir::IsAsync::NotAsync,
808 abi: ExternAbi::Rust,
809 }
810 }
811
812 #[inline]
813 fn mk_expr(&mut self, kind: hir::ExprKind<'hir>, span: Span) -> hir::Expr<'hir> {
814 hir::Expr { hir_id: self.next_id(), kind, span }
815 }
816}
817
818struct SelfResolver<'a> {
819 resolver: &'a mut ResolverAstLowering,
820 path_id: NodeId,
821 self_param_id: NodeId,
822}
823
824impl<'a> SelfResolver<'a> {
825 fn try_replace_id(&mut self, id: NodeId) {
826 if let Some(res) = self.resolver.partial_res_map.get(&id)
827 && let Some(Res::Local(sig_id)) = res.full_res()
828 && sig_id == self.path_id
829 {
830 let new_res = PartialRes::new(Res::Local(self.self_param_id));
831 self.resolver.partial_res_map.insert(id, new_res);
832 }
833 }
834}
835
836impl<'ast, 'a> Visitor<'ast> for SelfResolver<'a> {
837 fn visit_id(&mut self, id: NodeId) {
838 self.try_replace_id(id);
839 }
840}