1#![allow(internal_features)]
35#![doc(rust_logo)]
36#![feature(assert_matches)]
37#![feature(box_patterns)]
38#![feature(if_let_guard)]
39#![feature(let_chains)]
40#![feature(rustdoc_internals)]
41#![warn(unreachable_pub)]
42use std::sync::Arc;
45
46use rustc_ast::node_id::NodeMap;
47use rustc_ast::{self as ast, *};
48use rustc_data_structures::captures::Captures;
49use rustc_data_structures::fingerprint::Fingerprint;
50use rustc_data_structures::sorted_map::SortedMap;
51use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
52use rustc_data_structures::tagged_ptr::TaggedRef;
53use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
54use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
55use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
56use rustc_hir::{
57 self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, ParamName, TraitCandidate,
58};
59use rustc_index::{Idx, IndexSlice, IndexVec};
60use rustc_macros::extension;
61use rustc_middle::span_bug;
62use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
63use rustc_session::parse::{add_feature_diagnostics, feature_err};
64use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
65use smallvec::{SmallVec, smallvec};
66use thin_vec::ThinVec;
67use tracing::{debug, instrument, trace};
68
69use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
70
71macro_rules! arena_vec {
72 ($this:expr; $($x:expr),*) => (
73 $this.arena.alloc_from_iter([$($x),*])
74 );
75}
76
77mod asm;
78mod block;
79mod delegation;
80mod errors;
81mod expr;
82mod format;
83mod index;
84mod item;
85mod pat;
86mod path;
87pub mod stability;
88
89rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
90
91struct LoweringContext<'a, 'hir> {
92 tcx: TyCtxt<'hir>,
93 resolver: &'a mut ResolverAstLowering,
94
95 arena: &'hir hir::Arena<'hir>,
97
98 bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
100 attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
102 children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
104
105 contract_ensures: Option<(Span, Ident, HirId)>,
106
107 coroutine_kind: Option<hir::CoroutineKind>,
108
109 task_context: Option<HirId>,
112
113 current_item: Option<Span>,
116
117 catch_scope: Option<HirId>,
118 loop_scope: Option<HirId>,
119 is_in_loop_condition: bool,
120 is_in_trait_impl: bool,
121 is_in_dyn_type: bool,
122
123 current_hir_id_owner: hir::OwnerId,
124 item_local_id_counter: hir::ItemLocalId,
125 trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
126
127 impl_trait_defs: Vec<hir::GenericParam<'hir>>,
128 impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
129
130 ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
132 #[cfg(debug_assertions)]
134 node_id_to_local_id: NodeMap<hir::ItemLocalId>,
135
136 allow_try_trait: Arc<[Symbol]>,
137 allow_gen_future: Arc<[Symbol]>,
138 allow_async_iterator: Arc<[Symbol]>,
139 allow_for_await: Arc<[Symbol]>,
140 allow_async_fn_traits: Arc<[Symbol]>,
141}
142
143impl<'a, 'hir> LoweringContext<'a, 'hir> {
144 fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
145 Self {
146 tcx,
148 resolver,
149 arena: tcx.hir_arena,
150
151 bodies: Vec::new(),
153 attrs: SortedMap::default(),
154 children: Vec::default(),
155 contract_ensures: None,
156 current_hir_id_owner: hir::CRATE_OWNER_ID,
157 item_local_id_counter: hir::ItemLocalId::ZERO,
158 ident_and_label_to_local_id: Default::default(),
159 #[cfg(debug_assertions)]
160 node_id_to_local_id: Default::default(),
161 trait_map: Default::default(),
162
163 catch_scope: None,
165 loop_scope: None,
166 is_in_loop_condition: false,
167 is_in_trait_impl: false,
168 is_in_dyn_type: false,
169 coroutine_kind: None,
170 task_context: None,
171 current_item: None,
172 impl_trait_defs: Vec::new(),
173 impl_trait_bounds: Vec::new(),
174 allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
175 allow_gen_future: if tcx.features().async_fn_track_caller() {
176 [sym::gen_future, sym::closure_track_caller].into()
177 } else {
178 [sym::gen_future].into()
179 },
180 allow_for_await: [sym::async_iterator].into(),
181 allow_async_fn_traits: [sym::async_fn_traits].into(),
182 allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
185 }
186 }
187
188 pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
189 self.tcx.dcx()
190 }
191}
192
193#[extension(trait ResolverAstLoweringExt)]
194impl ResolverAstLowering {
195 fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
196 if let ExprKind::Path(None, path) = &expr.kind {
197 if path.segments.last().unwrap().args.is_some() {
200 return None;
201 }
202
203 if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
204 if def_id.is_local() {
208 return None;
209 }
210
211 if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
212 return v.clone();
213 }
214 }
215 }
216
217 None
218 }
219
220 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
222 self.partial_res_map.get(&id).copied()
223 }
224
225 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
227 self.import_res_map.get(&id).copied().unwrap_or_default()
228 }
229
230 fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
232 self.label_res_map.get(&id).copied()
233 }
234
235 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
237 self.lifetimes_res_map.get(&id).copied()
238 }
239
240 fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
248 self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
249 }
250}
251
252#[derive(Debug, Copy, Clone, PartialEq, Eq)]
255enum ImplTraitContext {
256 Universal,
262
263 OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
268
269 InBinding,
274
275 FeatureGated(ImplTraitPosition, Symbol),
277 Disallowed(ImplTraitPosition),
279}
280
281#[derive(Debug, Copy, Clone, PartialEq, Eq)]
283enum ImplTraitPosition {
284 Path,
285 Variable,
286 Trait,
287 Bound,
288 Generic,
289 ExternFnParam,
290 ClosureParam,
291 PointerParam,
292 FnTraitParam,
293 ExternFnReturn,
294 ClosureReturn,
295 PointerReturn,
296 FnTraitReturn,
297 GenericDefault,
298 ConstTy,
299 StaticTy,
300 AssocTy,
301 FieldTy,
302 Cast,
303 ImplSelf,
304 OffsetOf,
305}
306
307impl std::fmt::Display for ImplTraitPosition {
308 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
309 let name = match self {
310 ImplTraitPosition::Path => "paths",
311 ImplTraitPosition::Variable => "the type of variable bindings",
312 ImplTraitPosition::Trait => "traits",
313 ImplTraitPosition::Bound => "bounds",
314 ImplTraitPosition::Generic => "generics",
315 ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
316 ImplTraitPosition::ClosureParam => "closure parameters",
317 ImplTraitPosition::PointerParam => "`fn` pointer parameters",
318 ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
319 ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
320 ImplTraitPosition::ClosureReturn => "closure return types",
321 ImplTraitPosition::PointerReturn => "`fn` pointer return types",
322 ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
323 ImplTraitPosition::GenericDefault => "generic parameter defaults",
324 ImplTraitPosition::ConstTy => "const types",
325 ImplTraitPosition::StaticTy => "static types",
326 ImplTraitPosition::AssocTy => "associated types",
327 ImplTraitPosition::FieldTy => "field types",
328 ImplTraitPosition::Cast => "cast expression types",
329 ImplTraitPosition::ImplSelf => "impl headers",
330 ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
331 };
332
333 write!(f, "{name}")
334 }
335}
336
337#[derive(Copy, Clone, Debug, PartialEq, Eq)]
338enum FnDeclKind {
339 Fn,
340 Inherent,
341 ExternFn,
342 Closure,
343 Pointer,
344 Trait,
345 Impl,
346}
347
348#[derive(Copy, Clone)]
349enum AstOwner<'a> {
350 NonOwner,
351 Crate(&'a ast::Crate),
352 Item(&'a ast::Item),
353 AssocItem(&'a ast::AssocItem, visit::AssocCtxt),
354 ForeignItem(&'a ast::ForeignItem),
355}
356
357fn index_crate<'a>(
358 node_id_to_def_id: &NodeMap<LocalDefId>,
359 krate: &'a Crate,
360) -> IndexVec<LocalDefId, AstOwner<'a>> {
361 let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
362 *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
363 AstOwner::Crate(krate);
364 visit::walk_crate(&mut indexer, krate);
365 return indexer.index;
366
367 struct Indexer<'s, 'a> {
368 node_id_to_def_id: &'s NodeMap<LocalDefId>,
369 index: IndexVec<LocalDefId, AstOwner<'a>>,
370 }
371
372 impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> {
373 fn visit_attribute(&mut self, _: &'a Attribute) {
374 }
377
378 fn visit_item(&mut self, item: &'a ast::Item) {
379 let def_id = self.node_id_to_def_id[&item.id];
380 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
381 visit::walk_item(self, item)
382 }
383
384 fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
385 let def_id = self.node_id_to_def_id[&item.id];
386 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
387 AstOwner::AssocItem(item, ctxt);
388 visit::walk_assoc_item(self, item, ctxt);
389 }
390
391 fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
392 let def_id = self.node_id_to_def_id[&item.id];
393 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
394 AstOwner::ForeignItem(item);
395 visit::walk_item(self, item);
396 }
397 }
398}
399
400fn compute_hir_hash(
403 tcx: TyCtxt<'_>,
404 owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
405) -> Fingerprint {
406 let mut hir_body_nodes: Vec<_> = owners
407 .iter_enumerated()
408 .filter_map(|(def_id, info)| {
409 let info = info.as_owner()?;
410 let def_path_hash = tcx.hir().def_path_hash(def_id);
411 Some((def_path_hash, info))
412 })
413 .collect();
414 hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
415
416 tcx.with_stable_hashing_context(|mut hcx| {
417 let mut stable_hasher = StableHasher::new();
418 hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
419 stable_hasher.finish()
420 })
421}
422
423pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
424 let sess = tcx.sess;
425 tcx.ensure_done().output_filenames(());
427 tcx.ensure_done().early_lint_checks(());
428 tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
429 tcx.ensure_done().get_lang_items(());
430 let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
431
432 let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
433 let mut owners = IndexVec::from_fn_n(
434 |_| hir::MaybeOwner::Phantom,
435 tcx.definitions_untracked().def_index_count(),
436 );
437
438 for def_id in ast_index.indices() {
439 item::ItemLowerer {
440 tcx,
441 resolver: &mut resolver,
442 ast_index: &ast_index,
443 owners: &mut owners,
444 }
445 .lower_node(def_id);
446 }
447
448 drop(ast_index);
450 sess.time("drop_ast", || drop(krate));
451
452 let opt_hir_hash =
454 if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
455 hir::Crate { owners, opt_hir_hash }
456}
457
458#[derive(Copy, Clone, PartialEq, Debug)]
459enum ParamMode {
460 Explicit,
462 Optional,
464}
465
466#[derive(Copy, Clone, Debug)]
467enum AllowReturnTypeNotation {
468 Yes,
470 No,
472}
473
474enum GenericArgsMode {
475 ParenSugar,
477 ReturnTypeNotation,
479 Err,
481 Silence,
483}
484
485impl<'a, 'hir> LoweringContext<'a, 'hir> {
486 fn create_def(
487 &mut self,
488 parent: LocalDefId,
489 node_id: ast::NodeId,
490 name: Symbol,
491 def_kind: DefKind,
492 span: Span,
493 ) -> LocalDefId {
494 debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
495 assert!(
496 self.opt_local_def_id(node_id).is_none(),
497 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
498 node_id,
499 def_kind,
500 self.tcx.hir().def_key(self.local_def_id(node_id)),
501 );
502
503 let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id();
504
505 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
506 self.resolver.node_id_to_def_id.insert(node_id, def_id);
507
508 def_id
509 }
510
511 fn next_node_id(&mut self) -> NodeId {
512 let start = self.resolver.next_node_id;
513 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
514 self.resolver.next_node_id = ast::NodeId::from_u32(next);
515 start
516 }
517
518 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
521 self.resolver.node_id_to_def_id.get(&node).copied()
522 }
523
524 fn local_def_id(&self, node: NodeId) -> LocalDefId {
525 self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
526 }
527
528 #[instrument(level = "debug", skip(self, f))]
534 fn with_hir_id_owner(
535 &mut self,
536 owner: NodeId,
537 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
538 ) {
539 let def_id = self.local_def_id(owner);
540
541 let current_attrs = std::mem::take(&mut self.attrs);
542 let current_bodies = std::mem::take(&mut self.bodies);
543 let current_ident_and_label_to_local_id =
544 std::mem::take(&mut self.ident_and_label_to_local_id);
545
546 #[cfg(debug_assertions)]
547 let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
548 let current_trait_map = std::mem::take(&mut self.trait_map);
549 let current_owner =
550 std::mem::replace(&mut self.current_hir_id_owner, hir::OwnerId { def_id });
551 let current_local_counter =
552 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
553 let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
554 let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
555
556 #[cfg(debug_assertions)]
562 {
563 let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
564 debug_assert_eq!(_old, None);
565 }
566
567 let item = f(self);
568 debug_assert_eq!(def_id, item.def_id().def_id);
569 debug_assert!(self.impl_trait_defs.is_empty());
571 debug_assert!(self.impl_trait_bounds.is_empty());
572 let info = self.make_owner_info(item);
573
574 self.attrs = current_attrs;
575 self.bodies = current_bodies;
576 self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
577
578 #[cfg(debug_assertions)]
579 {
580 self.node_id_to_local_id = current_node_id_to_local_id;
581 }
582 self.trait_map = current_trait_map;
583 self.current_hir_id_owner = current_owner;
584 self.item_local_id_counter = current_local_counter;
585 self.impl_trait_defs = current_impl_trait_defs;
586 self.impl_trait_bounds = current_impl_trait_bounds;
587
588 debug_assert!(!self.children.iter().any(|(id, _)| id == &def_id));
589 self.children.push((def_id, hir::MaybeOwner::Owner(info)));
590 }
591
592 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
593 let attrs = std::mem::take(&mut self.attrs);
594 let mut bodies = std::mem::take(&mut self.bodies);
595 let trait_map = std::mem::take(&mut self.trait_map);
596
597 #[cfg(debug_assertions)]
598 for (id, attrs) in attrs.iter() {
599 if attrs.is_empty() {
601 panic!("Stored empty attributes for {:?}", id);
602 }
603 }
604
605 bodies.sort_by_key(|(k, _)| *k);
606 let bodies = SortedMap::from_presorted_elements(bodies);
607
608 let (opt_hash_including_bodies, attrs_hash) =
610 self.tcx.hash_owner_nodes(node, &bodies, &attrs);
611 let num_nodes = self.item_local_id_counter.as_usize();
612 let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
613 let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
614 let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
615
616 self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
617 }
618
619 #[instrument(level = "debug", skip(self), ret)]
625 fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
626 assert_ne!(ast_node_id, DUMMY_NODE_ID);
627
628 let owner = self.current_hir_id_owner;
629 let local_id = self.item_local_id_counter;
630 assert_ne!(local_id, hir::ItemLocalId::ZERO);
631 self.item_local_id_counter.increment_by(1);
632 let hir_id = HirId { owner, local_id };
633
634 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
635 self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
636 }
637
638 if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
639 self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
640 }
641
642 #[cfg(debug_assertions)]
644 {
645 let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
646 assert_eq!(old, None);
647 }
648
649 hir_id
650 }
651
652 #[instrument(level = "debug", skip(self), ret)]
654 fn next_id(&mut self) -> HirId {
655 let owner = self.current_hir_id_owner;
656 let local_id = self.item_local_id_counter;
657 assert_ne!(local_id, hir::ItemLocalId::ZERO);
658 self.item_local_id_counter.increment_by(1);
659 HirId { owner, local_id }
660 }
661
662 #[instrument(level = "trace", skip(self))]
663 fn lower_res(&mut self, res: Res<NodeId>) -> Res {
664 let res: Result<Res, ()> = res.apply_id(|id| {
665 let owner = self.current_hir_id_owner;
666 let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
667 Ok(HirId { owner, local_id })
668 });
669 trace!(?res);
670
671 res.unwrap_or(Res::Err)
677 }
678
679 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
680 self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
681 }
682
683 fn lower_import_res(&mut self, id: NodeId, span: Span) -> SmallVec<[Res; 3]> {
684 let res = self.resolver.get_import_res(id).present_items();
685 let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect();
686 if res.is_empty() {
687 self.dcx().span_delayed_bug(span, "no resolution for an import");
688 return smallvec![Res::Err];
689 }
690 res
691 }
692
693 fn make_lang_item_qpath(
694 &mut self,
695 lang_item: hir::LangItem,
696 span: Span,
697 args: Option<&'hir hir::GenericArgs<'hir>>,
698 ) -> hir::QPath<'hir> {
699 hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
700 }
701
702 fn make_lang_item_path(
703 &mut self,
704 lang_item: hir::LangItem,
705 span: Span,
706 args: Option<&'hir hir::GenericArgs<'hir>>,
707 ) -> &'hir hir::Path<'hir> {
708 let def_id = self.tcx.require_lang_item(lang_item, Some(span));
709 let def_kind = self.tcx.def_kind(def_id);
710 let res = Res::Def(def_kind, def_id);
711 self.arena.alloc(hir::Path {
712 span,
713 res,
714 segments: self.arena.alloc_from_iter([hir::PathSegment {
715 ident: Ident::new(lang_item.name(), span),
716 hir_id: self.next_id(),
717 res,
718 args,
719 infer_args: args.is_none(),
720 }]),
721 })
722 }
723
724 fn mark_span_with_reason(
727 &self,
728 reason: DesugaringKind,
729 span: Span,
730 allow_internal_unstable: Option<Arc<[Symbol]>>,
731 ) -> Span {
732 self.tcx.with_stable_hashing_context(|hcx| {
733 span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
734 })
735 }
736
737 fn lower_span(&self, span: Span) -> Span {
740 if self.tcx.sess.opts.incremental.is_some() {
741 span.with_parent(Some(self.current_hir_id_owner.def_id))
742 } else {
743 span
745 }
746 }
747
748 fn lower_ident(&self, ident: Ident) -> Ident {
749 Ident::new(ident.name, self.lower_span(ident.span))
750 }
751
752 #[instrument(level = "debug", skip(self))]
754 fn lifetime_res_to_generic_param(
755 &mut self,
756 ident: Ident,
757 node_id: NodeId,
758 res: LifetimeRes,
759 source: hir::GenericParamSource,
760 ) -> Option<hir::GenericParam<'hir>> {
761 let (name, kind) = match res {
762 LifetimeRes::Param { .. } => {
763 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
764 }
765 LifetimeRes::Fresh { param, kind, .. } => {
766 let _def_id = self.create_def(
768 self.current_hir_id_owner.def_id,
769 param,
770 kw::UnderscoreLifetime,
771 DefKind::LifetimeParam,
772 ident.span,
773 );
774 debug!(?_def_id);
775
776 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
777 }
778 LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
779 res => panic!(
780 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
781 res, ident, ident.span
782 ),
783 };
784 let hir_id = self.lower_node_id(node_id);
785 let def_id = self.local_def_id(node_id);
786 Some(hir::GenericParam {
787 hir_id,
788 def_id,
789 name,
790 span: self.lower_span(ident.span),
791 pure_wrt_drop: false,
792 kind: hir::GenericParamKind::Lifetime { kind },
793 colon_span: None,
794 source,
795 })
796 }
797
798 #[instrument(level = "debug", skip(self))]
804 #[inline]
805 fn lower_lifetime_binder(
806 &mut self,
807 binder: NodeId,
808 generic_params: &[GenericParam],
809 ) -> &'hir [hir::GenericParam<'hir>] {
810 let mut generic_params: Vec<_> = self
811 .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
812 .collect();
813 let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
814 debug!(?extra_lifetimes);
815 generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
816 self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
817 }));
818 let generic_params = self.arena.alloc_from_iter(generic_params);
819 debug!(?generic_params);
820
821 generic_params
822 }
823
824 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
825 let was_in_dyn_type = self.is_in_dyn_type;
826 self.is_in_dyn_type = in_scope;
827
828 let result = f(self);
829
830 self.is_in_dyn_type = was_in_dyn_type;
831
832 result
833 }
834
835 fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
836 let current_item = self.current_item;
837 self.current_item = Some(scope_span);
838
839 let was_in_loop_condition = self.is_in_loop_condition;
840 self.is_in_loop_condition = false;
841
842 let old_contract = self.contract_ensures.take();
843
844 let catch_scope = self.catch_scope.take();
845 let loop_scope = self.loop_scope.take();
846 let ret = f(self);
847 self.catch_scope = catch_scope;
848 self.loop_scope = loop_scope;
849
850 self.contract_ensures = old_contract;
851
852 self.is_in_loop_condition = was_in_loop_condition;
853
854 self.current_item = current_item;
855
856 ret
857 }
858
859 fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [hir::Attribute] {
860 if attrs.is_empty() {
861 &[]
862 } else {
863 debug_assert_eq!(id.owner, self.current_hir_id_owner);
864 let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
865 debug_assert!(!ret.is_empty());
866 self.attrs.insert(id.local_id, ret);
867 ret
868 }
869 }
870
871 fn lower_attr(&self, attr: &Attribute) -> hir::Attribute {
872 let kind = match attr.kind {
877 AttrKind::Normal(ref normal) => hir::AttrKind::Normal(Box::new(hir::AttrItem {
878 unsafety: self.lower_safety(normal.item.unsafety, hir::Safety::Safe),
879 path: hir::AttrPath {
880 segments: normal
881 .item
882 .path
883 .segments
884 .iter()
885 .map(|i| i.ident)
886 .collect::<Vec<_>>()
887 .into_boxed_slice(),
888 span: normal.item.path.span,
889 },
890 args: self.lower_attr_args(&normal.item.args),
891 })),
892 AttrKind::DocComment(comment_kind, data) => {
893 hir::AttrKind::DocComment(comment_kind, data)
894 }
895 };
896
897 hir::Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
898 }
899
900 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
901 debug_assert_eq!(id.owner, self.current_hir_id_owner);
902 debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
903 if let Some(&a) = self.attrs.get(&target_id.local_id) {
904 debug_assert!(!a.is_empty());
905 self.attrs.insert(id.local_id, a);
906 }
907 }
908
909 fn lower_attr_args(&self, args: &AttrArgs) -> hir::AttrArgs {
910 match args {
911 AttrArgs::Empty => hir::AttrArgs::Empty,
912 AttrArgs::Delimited(args) => hir::AttrArgs::Delimited(self.lower_delim_args(args)),
913 &AttrArgs::Eq { eq_span, ref expr } => {
917 let lit = if let ExprKind::Lit(token_lit) = expr.kind
920 && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
921 {
922 lit
923 } else {
924 let guar = self.dcx().has_errors().unwrap();
925 MetaItemLit {
926 symbol: kw::Empty,
927 suffix: None,
928 kind: LitKind::Err(guar),
929 span: DUMMY_SP,
930 }
931 };
932 hir::AttrArgs::Eq { eq_span, expr: lit }
933 }
934 }
935 }
936
937 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
938 DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
939 }
940
941 #[instrument(level = "debug", skip_all)]
943 fn lower_assoc_item_constraint(
944 &mut self,
945 constraint: &AssocItemConstraint,
946 itctx: ImplTraitContext,
947 ) -> hir::AssocItemConstraint<'hir> {
948 debug!(?constraint, ?itctx);
949 let gen_args = if let Some(gen_args) = &constraint.gen_args {
951 let gen_args_ctor = match gen_args {
952 GenericArgs::AngleBracketed(data) => {
953 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
954 }
955 GenericArgs::Parenthesized(data) => {
956 if let Some(first_char) = constraint.ident.as_str().chars().next()
957 && first_char.is_ascii_lowercase()
958 {
959 let mut err = if !data.inputs.is_empty() {
960 self.dcx().create_err(errors::BadReturnTypeNotation::Inputs {
961 span: data.inputs_span,
962 })
963 } else if let FnRetTy::Ty(ty) = &data.output {
964 self.dcx().create_err(errors::BadReturnTypeNotation::Output {
965 span: data.inputs_span.shrink_to_hi().to(ty.span),
966 })
967 } else {
968 self.dcx().create_err(errors::BadReturnTypeNotation::NeedsDots {
969 span: data.inputs_span,
970 })
971 };
972 if !self.tcx.features().return_type_notation()
973 && self.tcx.sess.is_nightly_build()
974 {
975 add_feature_diagnostics(
976 &mut err,
977 &self.tcx.sess,
978 sym::return_type_notation,
979 );
980 }
981 err.emit();
982 GenericArgsCtor {
983 args: Default::default(),
984 constraints: &[],
985 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
986 span: data.span,
987 }
988 } else {
989 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
990 self.lower_angle_bracketed_parameter_data(
993 &data.as_angle_bracketed_args(),
994 ParamMode::Explicit,
995 itctx,
996 )
997 .0
998 }
999 }
1000 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
1001 args: Default::default(),
1002 constraints: &[],
1003 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1004 span: *span,
1005 },
1006 };
1007 gen_args_ctor.into_generic_args(self)
1008 } else {
1009 self.arena.alloc(hir::GenericArgs::none())
1010 };
1011 let kind = match &constraint.kind {
1012 AssocItemConstraintKind::Equality { term } => {
1013 let term = match term {
1014 Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1015 Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1016 };
1017 hir::AssocItemConstraintKind::Equality { term }
1018 }
1019 AssocItemConstraintKind::Bound { bounds } => {
1020 if self.is_in_dyn_type {
1022 let suggestion = match itctx {
1023 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1024 let bound_end_span = constraint
1025 .gen_args
1026 .as_ref()
1027 .map_or(constraint.ident.span, |args| args.span());
1028 if bound_end_span.eq_ctxt(constraint.span) {
1029 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1030 } else {
1031 None
1032 }
1033 }
1034 _ => None,
1035 };
1036
1037 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1038 span: constraint.span,
1039 suggestion,
1040 });
1041 let err_ty =
1042 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1043 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1044 } else {
1045 let bounds = self.lower_param_bounds(bounds, itctx);
1048
1049 hir::AssocItemConstraintKind::Bound { bounds }
1050 }
1051 }
1052 };
1053
1054 hir::AssocItemConstraint {
1055 hir_id: self.lower_node_id(constraint.id),
1056 ident: self.lower_ident(constraint.ident),
1057 gen_args,
1058 kind,
1059 span: self.lower_span(constraint.span),
1060 }
1061 }
1062
1063 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1064 let sub = if data.inputs.is_empty() {
1066 let parentheses_span =
1067 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1068 AssocTyParenthesesSub::Empty { parentheses_span }
1069 }
1070 else {
1072 let open_param = data.inputs_span.shrink_to_lo().to(data
1074 .inputs
1075 .first()
1076 .unwrap()
1077 .span
1078 .shrink_to_lo());
1079 let close_param =
1081 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1082 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1083 };
1084 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1085 }
1086
1087 #[instrument(level = "debug", skip(self))]
1088 fn lower_generic_arg(
1089 &mut self,
1090 arg: &ast::GenericArg,
1091 itctx: ImplTraitContext,
1092 ) -> hir::GenericArg<'hir> {
1093 match arg {
1094 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
1095 ast::GenericArg::Type(ty) => {
1096 if ty.is_maybe_parenthesised_infer() {
1099 return GenericArg::Infer(hir::InferArg {
1100 hir_id: self.lower_node_id(ty.id),
1101 span: self.lower_span(ty.span),
1102 });
1103 }
1104
1105 match &ty.kind {
1106 TyKind::Path(None, path) => {
1113 if let Some(res) = self
1114 .resolver
1115 .get_partial_res(ty.id)
1116 .and_then(|partial_res| partial_res.full_res())
1117 {
1118 if !res.matches_ns(Namespace::TypeNS)
1119 && path.is_potential_trivial_const_arg()
1120 {
1121 debug!(
1122 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1123 ty,
1124 );
1125
1126 let ct =
1127 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1128 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1129 }
1130 }
1131 }
1132 _ => {}
1133 }
1134 GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1135 }
1136 ast::GenericArg::Const(ct) => {
1137 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1138 }
1139 }
1140 }
1141
1142 #[instrument(level = "debug", skip(self))]
1143 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1144 self.arena.alloc(self.lower_ty_direct(t, itctx))
1145 }
1146
1147 fn lower_path_ty(
1148 &mut self,
1149 t: &Ty,
1150 qself: &Option<ptr::P<QSelf>>,
1151 path: &Path,
1152 param_mode: ParamMode,
1153 itctx: ImplTraitContext,
1154 ) -> hir::Ty<'hir> {
1155 if qself.is_none()
1161 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1162 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1163 {
1164 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1165 let bound = this.lower_poly_trait_ref(
1166 &PolyTraitRef {
1167 bound_generic_params: ThinVec::new(),
1168 modifiers: TraitBoundModifiers::NONE,
1169 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1170 span: t.span,
1171 },
1172 itctx,
1173 );
1174 let bounds = this.arena.alloc_from_iter([bound]);
1175 let lifetime_bound = this.elided_dyn_bound(t.span);
1176 (bounds, lifetime_bound)
1177 });
1178 let kind = hir::TyKind::TraitObject(
1179 bounds,
1180 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1181 );
1182 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1183 }
1184
1185 let id = self.lower_node_id(t.id);
1186 let qpath = self.lower_qpath(
1187 t.id,
1188 qself,
1189 path,
1190 param_mode,
1191 AllowReturnTypeNotation::Yes,
1192 itctx,
1193 None,
1194 );
1195 self.ty_path(id, t.span, qpath)
1196 }
1197
1198 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1199 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1200 }
1201
1202 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1203 self.ty(span, hir::TyKind::Tup(tys))
1204 }
1205
1206 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1207 let kind = match &t.kind {
1208 TyKind::Infer => hir::TyKind::Infer(()),
1209 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1210 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1211 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1212 TyKind::Ref(region, mt) => {
1213 let region = region.unwrap_or_else(|| {
1214 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1215 self.resolver.get_lifetime_res(t.id)
1216 {
1217 debug_assert_eq!(start.plus(1), end);
1218 start
1219 } else {
1220 self.next_node_id()
1221 };
1222 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1223 Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1224 });
1225 let lifetime = self.lower_lifetime(®ion);
1226 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1227 }
1228 TyKind::PinnedRef(region, mt) => {
1229 let region = region.unwrap_or_else(|| {
1230 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1231 self.resolver.get_lifetime_res(t.id)
1232 {
1233 debug_assert_eq!(start.plus(1), end);
1234 start
1235 } else {
1236 self.next_node_id()
1237 };
1238 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1239 Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1240 });
1241 let lifetime = self.lower_lifetime(®ion);
1242 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1243 let span = self.lower_span(t.span);
1244 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1245 let args = self.arena.alloc(hir::GenericArgs {
1246 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1247 constraints: &[],
1248 parenthesized: hir::GenericArgsParentheses::No,
1249 span_ext: span,
1250 });
1251 let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1252 hir::TyKind::Path(path)
1253 }
1254 TyKind::BareFn(f) => {
1255 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1256 hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1257 generic_params,
1258 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1259 abi: self.lower_extern(f.ext),
1260 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1261 param_names: self.lower_fn_params_to_names(&f.decl),
1262 }))
1263 }
1264 TyKind::UnsafeBinder(f) => {
1265 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1266 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1267 generic_params,
1268 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1269 }))
1270 }
1271 TyKind::Never => hir::TyKind::Never,
1272 TyKind::Tup(tys) => hir::TyKind::Tup(
1273 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1274 ),
1275 TyKind::Paren(ty) => {
1276 return self.lower_ty_direct(ty, itctx);
1277 }
1278 TyKind::Path(qself, path) => {
1279 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1280 }
1281 TyKind::ImplicitSelf => {
1282 let hir_id = self.next_id();
1283 let res = self.expect_full_res(t.id);
1284 let res = self.lower_res(res);
1285 hir::TyKind::Path(hir::QPath::Resolved(
1286 None,
1287 self.arena.alloc(hir::Path {
1288 res,
1289 segments: arena_vec![self; hir::PathSegment::new(
1290 Ident::with_dummy_span(kw::SelfUpper),
1291 hir_id,
1292 res
1293 )],
1294 span: self.lower_span(t.span),
1295 }),
1296 ))
1297 }
1298 TyKind::Array(ty, length) => hir::TyKind::Array(
1299 self.lower_ty(ty, itctx),
1300 self.lower_array_length_to_const_arg(length),
1301 ),
1302 TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1303 TyKind::TraitObject(bounds, kind) => {
1304 let mut lifetime_bound = None;
1305 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1306 let bounds =
1307 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1308 GenericBound::Trait(ty) => {
1312 let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1313 Some(trait_ref)
1314 }
1315 GenericBound::Outlives(lifetime) => {
1316 if lifetime_bound.is_none() {
1317 lifetime_bound = Some(this.lower_lifetime(lifetime));
1318 }
1319 None
1320 }
1321 GenericBound::Use(_, span) => {
1323 this.dcx()
1324 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1325 None
1326 }
1327 }));
1328 let lifetime_bound =
1329 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1330 (bounds, lifetime_bound)
1331 });
1332 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1333 }
1334 TyKind::ImplTrait(def_node_id, bounds) => {
1335 let span = t.span;
1336 match itctx {
1337 ImplTraitContext::OpaqueTy { origin } => {
1338 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1339 }
1340 ImplTraitContext::Universal => {
1341 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1342 ast::GenericBound::Use(_, span) => Some(span),
1343 _ => None,
1344 }) {
1345 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1346 }
1347
1348 let def_id = self.local_def_id(*def_node_id);
1349 let name = self.tcx.item_name(def_id.to_def_id());
1350 let ident = Ident::new(name, span);
1351 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1352 *def_node_id,
1353 span,
1354 ident,
1355 bounds,
1356 );
1357 self.impl_trait_defs.push(param);
1358 if let Some(bounds) = bounds {
1359 self.impl_trait_bounds.push(bounds);
1360 }
1361 path
1362 }
1363 ImplTraitContext::InBinding => {
1364 hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1365 }
1366 ImplTraitContext::FeatureGated(position, feature) => {
1367 let guar = self
1368 .tcx
1369 .sess
1370 .create_feature_err(
1371 MisplacedImplTrait {
1372 span: t.span,
1373 position: DiagArgFromDisplay(&position),
1374 },
1375 feature,
1376 )
1377 .emit();
1378 hir::TyKind::Err(guar)
1379 }
1380 ImplTraitContext::Disallowed(position) => {
1381 let guar = self.dcx().emit_err(MisplacedImplTrait {
1382 span: t.span,
1383 position: DiagArgFromDisplay(&position),
1384 });
1385 hir::TyKind::Err(guar)
1386 }
1387 }
1388 }
1389 TyKind::Pat(ty, pat) => {
1390 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
1391 }
1392 TyKind::MacCall(_) => {
1393 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1394 }
1395 TyKind::CVarArgs => {
1396 let guar = self.dcx().span_delayed_bug(
1397 t.span,
1398 "`TyKind::CVarArgs` should have been handled elsewhere",
1399 );
1400 hir::TyKind::Err(guar)
1401 }
1402 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1403 };
1404
1405 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1406 }
1407
1408 #[instrument(level = "debug", skip(self), ret)]
1440 fn lower_opaque_impl_trait(
1441 &mut self,
1442 span: Span,
1443 origin: hir::OpaqueTyOrigin<LocalDefId>,
1444 opaque_ty_node_id: NodeId,
1445 bounds: &GenericBounds,
1446 itctx: ImplTraitContext,
1447 ) -> hir::TyKind<'hir> {
1448 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1454
1455 match origin {
1457 rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
1458 if !self.tcx.features().precise_capturing_in_traits()
1459 && let Some(span) = bounds.iter().find_map(|bound| match *bound {
1460 ast::GenericBound::Use(_, span) => Some(span),
1461 _ => None,
1462 })
1463 {
1464 let mut diag =
1465 self.tcx.dcx().create_err(errors::NoPreciseCapturesOnRpitit { span });
1466 add_feature_diagnostics(
1467 &mut diag,
1468 self.tcx.sess,
1469 sym::precise_capturing_in_traits,
1470 );
1471 diag.emit();
1472 }
1473 }
1474 _ => {}
1475 }
1476
1477 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1478 this.lower_param_bounds(bounds, itctx)
1479 })
1480 }
1481
1482 fn lower_opaque_inner(
1483 &mut self,
1484 opaque_ty_node_id: NodeId,
1485 origin: hir::OpaqueTyOrigin<LocalDefId>,
1486 opaque_ty_span: Span,
1487 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1488 ) -> hir::TyKind<'hir> {
1489 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1490 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1491 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1492
1493 let bounds = lower_item_bounds(self);
1494 let opaque_ty_def = hir::OpaqueTy {
1495 hir_id: opaque_ty_hir_id,
1496 def_id: opaque_ty_def_id,
1497 bounds,
1498 origin,
1499 span: self.lower_span(opaque_ty_span),
1500 };
1501 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1502
1503 hir::TyKind::OpaqueDef(opaque_ty_def)
1504 }
1505
1506 fn lower_precise_capturing_args(
1507 &mut self,
1508 precise_capturing_args: &[PreciseCapturingArg],
1509 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1510 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1511 PreciseCapturingArg::Lifetime(lt) => {
1512 hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
1513 }
1514 PreciseCapturingArg::Arg(path, id) => {
1515 let [segment] = path.segments.as_slice() else {
1516 panic!();
1517 };
1518 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1519 partial_res.full_res().expect("no partial res expected for precise capture arg")
1520 });
1521 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1522 hir_id: self.lower_node_id(*id),
1523 ident: self.lower_ident(segment.ident),
1524 res: self.lower_res(res),
1525 })
1526 }
1527 }))
1528 }
1529
1530 fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1531 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1532 PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1533 _ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
1534 }))
1535 }
1536
1537 #[instrument(level = "debug", skip(self))]
1547 fn lower_fn_decl(
1548 &mut self,
1549 decl: &FnDecl,
1550 fn_node_id: NodeId,
1551 fn_span: Span,
1552 kind: FnDeclKind,
1553 coro: Option<CoroutineKind>,
1554 ) -> &'hir hir::FnDecl<'hir> {
1555 let c_variadic = decl.c_variadic();
1556
1557 let mut inputs = &decl.inputs[..];
1561 if c_variadic {
1562 inputs = &inputs[..inputs.len() - 1];
1563 }
1564 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1565 let itctx = match kind {
1566 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1567 ImplTraitContext::Universal
1568 }
1569 FnDeclKind::ExternFn => {
1570 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1571 }
1572 FnDeclKind::Closure => {
1573 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1574 }
1575 FnDeclKind::Pointer => {
1576 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1577 }
1578 };
1579 self.lower_ty_direct(¶m.ty, itctx)
1580 }));
1581
1582 let output = match coro {
1583 Some(coro) => {
1584 let fn_def_id = self.local_def_id(fn_node_id);
1585 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1586 }
1587 None => match &decl.output {
1588 FnRetTy::Ty(ty) => {
1589 let itctx = match kind {
1590 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1591 origin: hir::OpaqueTyOrigin::FnReturn {
1592 parent: self.local_def_id(fn_node_id),
1593 in_trait_or_impl: None,
1594 },
1595 },
1596 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1597 origin: hir::OpaqueTyOrigin::FnReturn {
1598 parent: self.local_def_id(fn_node_id),
1599 in_trait_or_impl: Some(hir::RpitContext::Trait),
1600 },
1601 },
1602 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1603 origin: hir::OpaqueTyOrigin::FnReturn {
1604 parent: self.local_def_id(fn_node_id),
1605 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1606 },
1607 },
1608 FnDeclKind::ExternFn => {
1609 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1610 }
1611 FnDeclKind::Closure => {
1612 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1613 }
1614 FnDeclKind::Pointer => {
1615 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1616 }
1617 };
1618 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1619 }
1620 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1621 },
1622 };
1623
1624 self.arena.alloc(hir::FnDecl {
1625 inputs,
1626 output,
1627 c_variadic,
1628 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1629 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1630 let is_mutable_pat = matches!(
1631 arg.pat.kind,
1632 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1633 );
1634
1635 match &arg.ty.kind {
1636 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1637 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1638 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1642 if mt.ty.kind.is_implicit_self() =>
1643 {
1644 match mt.mutbl {
1645 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1646 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1647 }
1648 }
1649 _ => hir::ImplicitSelfKind::None,
1650 }
1651 }),
1652 })
1653 }
1654
1655 #[instrument(level = "debug", skip(self))]
1664 fn lower_coroutine_fn_ret_ty(
1665 &mut self,
1666 output: &FnRetTy,
1667 fn_def_id: LocalDefId,
1668 coro: CoroutineKind,
1669 fn_kind: FnDeclKind,
1670 fn_span: Span,
1671 ) -> hir::FnRetTy<'hir> {
1672 let span = self.lower_span(fn_span);
1673
1674 let (opaque_ty_node_id, allowed_features) = match coro {
1675 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1676 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1677 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1678 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1679 }
1680 };
1681
1682 let opaque_ty_span =
1683 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1684
1685 let in_trait_or_impl = match fn_kind {
1686 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1687 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1688 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1689 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1690 };
1691
1692 let opaque_ty_ref = self.lower_opaque_inner(
1693 opaque_ty_node_id,
1694 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1695 opaque_ty_span,
1696 |this| {
1697 let bound = this.lower_coroutine_fn_output_type_to_bound(
1698 output,
1699 coro,
1700 opaque_ty_span,
1701 ImplTraitContext::OpaqueTy {
1702 origin: hir::OpaqueTyOrigin::FnReturn {
1703 parent: fn_def_id,
1704 in_trait_or_impl,
1705 },
1706 },
1707 );
1708 arena_vec![this; bound]
1709 },
1710 );
1711
1712 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1713 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1714 }
1715
1716 fn lower_coroutine_fn_output_type_to_bound(
1718 &mut self,
1719 output: &FnRetTy,
1720 coro: CoroutineKind,
1721 opaque_ty_span: Span,
1722 itctx: ImplTraitContext,
1723 ) -> hir::GenericBound<'hir> {
1724 let output_ty = match output {
1726 FnRetTy::Ty(ty) => {
1727 self.lower_ty(ty, itctx)
1731 }
1732 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1733 };
1734
1735 let (assoc_ty_name, trait_lang_item) = match coro {
1737 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1738 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1739 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1740 };
1741
1742 let bound_args = self.arena.alloc(hir::GenericArgs {
1743 args: &[],
1744 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1745 parenthesized: hir::GenericArgsParentheses::No,
1746 span_ext: DUMMY_SP,
1747 });
1748
1749 hir::GenericBound::Trait(hir::PolyTraitRef {
1750 bound_generic_params: &[],
1751 modifiers: hir::TraitBoundModifiers::NONE,
1752 trait_ref: hir::TraitRef {
1753 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1754 hir_ref_id: self.next_id(),
1755 },
1756 span: opaque_ty_span,
1757 })
1758 }
1759
1760 #[instrument(level = "trace", skip(self))]
1761 fn lower_param_bound(
1762 &mut self,
1763 tpb: &GenericBound,
1764 itctx: ImplTraitContext,
1765 ) -> hir::GenericBound<'hir> {
1766 match tpb {
1767 GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1768 GenericBound::Outlives(lifetime) => {
1769 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
1770 }
1771 GenericBound::Use(args, span) => hir::GenericBound::Use(
1772 self.lower_precise_capturing_args(args),
1773 self.lower_span(*span),
1774 ),
1775 }
1776 }
1777
1778 fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
1779 let ident = self.lower_ident(l.ident);
1780 self.new_named_lifetime(l.id, l.id, ident)
1781 }
1782
1783 #[instrument(level = "debug", skip(self))]
1784 fn new_named_lifetime_with_res(
1785 &mut self,
1786 id: NodeId,
1787 ident: Ident,
1788 res: LifetimeRes,
1789 ) -> &'hir hir::Lifetime {
1790 let res = match res {
1791 LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param),
1792 LifetimeRes::Fresh { param, .. } => {
1793 let param = self.local_def_id(param);
1794 hir::LifetimeName::Param(param)
1795 }
1796 LifetimeRes::Infer => hir::LifetimeName::Infer,
1797 LifetimeRes::Static { .. } => hir::LifetimeName::Static,
1798 LifetimeRes::Error => hir::LifetimeName::Error,
1799 res => panic!(
1800 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1801 res, ident, ident.span
1802 ),
1803 };
1804
1805 debug!(?res);
1806 self.arena.alloc(hir::Lifetime {
1807 hir_id: self.lower_node_id(id),
1808 ident: self.lower_ident(ident),
1809 res,
1810 })
1811 }
1812
1813 #[instrument(level = "debug", skip(self))]
1814 fn new_named_lifetime(
1815 &mut self,
1816 id: NodeId,
1817 new_id: NodeId,
1818 ident: Ident,
1819 ) -> &'hir hir::Lifetime {
1820 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1821 self.new_named_lifetime_with_res(new_id, ident, res)
1822 }
1823
1824 fn lower_generic_params_mut<'s>(
1825 &'s mut self,
1826 params: &'s [GenericParam],
1827 source: hir::GenericParamSource,
1828 ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
1829 params.iter().map(move |param| self.lower_generic_param(param, source))
1830 }
1831
1832 fn lower_generic_params(
1833 &mut self,
1834 params: &[GenericParam],
1835 source: hir::GenericParamSource,
1836 ) -> &'hir [hir::GenericParam<'hir>] {
1837 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1838 }
1839
1840 #[instrument(level = "trace", skip(self))]
1841 fn lower_generic_param(
1842 &mut self,
1843 param: &GenericParam,
1844 source: hir::GenericParamSource,
1845 ) -> hir::GenericParam<'hir> {
1846 let (name, kind) = self.lower_generic_param_kind(param, source);
1847
1848 let hir_id = self.lower_node_id(param.id);
1849 self.lower_attrs(hir_id, ¶m.attrs);
1850 hir::GenericParam {
1851 hir_id,
1852 def_id: self.local_def_id(param.id),
1853 name,
1854 span: self.lower_span(param.span()),
1855 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1856 kind,
1857 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1858 source,
1859 }
1860 }
1861
1862 fn lower_generic_param_kind(
1863 &mut self,
1864 param: &GenericParam,
1865 source: hir::GenericParamSource,
1866 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1867 match ¶m.kind {
1868 GenericParamKind::Lifetime => {
1869 let ident = self.lower_ident(param.ident);
1872 let param_name =
1873 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1874 ParamName::Error(ident)
1875 } else {
1876 ParamName::Plain(ident)
1877 };
1878 let kind =
1879 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1880
1881 (param_name, kind)
1882 }
1883 GenericParamKind::Type { default, .. } => {
1884 let default = default
1887 .as_ref()
1888 .filter(|_| match source {
1889 hir::GenericParamSource::Generics => true,
1890 hir::GenericParamSource::Binder => {
1891 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1892 span: param.span(),
1893 });
1894
1895 false
1896 }
1897 })
1898 .map(|def| {
1899 self.lower_ty(
1900 def,
1901 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1902 )
1903 });
1904
1905 let kind = hir::GenericParamKind::Type { default, synthetic: false };
1906
1907 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1908 }
1909 GenericParamKind::Const { ty, kw_span: _, default } => {
1910 let ty = self
1911 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1912
1913 let default = default
1916 .as_ref()
1917 .filter(|_| match source {
1918 hir::GenericParamSource::Generics => true,
1919 hir::GenericParamSource::Binder => {
1920 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1921 span: param.span(),
1922 });
1923
1924 false
1925 }
1926 })
1927 .map(|def| self.lower_anon_const_to_const_arg(def));
1928
1929 (
1930 hir::ParamName::Plain(self.lower_ident(param.ident)),
1931 hir::GenericParamKind::Const { ty, default, synthetic: false },
1932 )
1933 }
1934 }
1935 }
1936
1937 fn lower_trait_ref(
1938 &mut self,
1939 modifiers: ast::TraitBoundModifiers,
1940 p: &TraitRef,
1941 itctx: ImplTraitContext,
1942 ) -> hir::TraitRef<'hir> {
1943 let path = match self.lower_qpath(
1944 p.ref_id,
1945 &None,
1946 &p.path,
1947 ParamMode::Explicit,
1948 AllowReturnTypeNotation::No,
1949 itctx,
1950 Some(modifiers),
1951 ) {
1952 hir::QPath::Resolved(None, path) => path,
1953 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
1954 };
1955 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1956 }
1957
1958 #[instrument(level = "debug", skip(self))]
1959 fn lower_poly_trait_ref(
1960 &mut self,
1961 p: &PolyTraitRef,
1962 itctx: ImplTraitContext,
1963 ) -> hir::PolyTraitRef<'hir> {
1964 let bound_generic_params =
1965 self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
1966 let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
1967 let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
1968 hir::PolyTraitRef {
1969 bound_generic_params,
1970 modifiers,
1971 trait_ref,
1972 span: self.lower_span(p.span),
1973 }
1974 }
1975
1976 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1977 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1978 }
1979
1980 #[instrument(level = "debug", skip(self), ret)]
1981 fn lower_param_bounds(
1982 &mut self,
1983 bounds: &[GenericBound],
1984 itctx: ImplTraitContext,
1985 ) -> hir::GenericBounds<'hir> {
1986 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
1987 }
1988
1989 fn lower_param_bounds_mut<'s>(
1990 &'s mut self,
1991 bounds: &'s [GenericBound],
1992 itctx: ImplTraitContext,
1993 ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
1994 bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
1995 }
1996
1997 #[instrument(level = "debug", skip(self), ret)]
1998 fn lower_universal_param_and_bounds(
1999 &mut self,
2000 node_id: NodeId,
2001 span: Span,
2002 ident: Ident,
2003 bounds: &[GenericBound],
2004 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2005 let def_id = self.local_def_id(node_id);
2007 let span = self.lower_span(span);
2008
2009 let param = hir::GenericParam {
2011 hir_id: self.lower_node_id(node_id),
2012 def_id,
2013 name: ParamName::Plain(self.lower_ident(ident)),
2014 pure_wrt_drop: false,
2015 span,
2016 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2017 colon_span: None,
2018 source: hir::GenericParamSource::Generics,
2019 };
2020
2021 let preds = self.lower_generic_bound_predicate(
2022 ident,
2023 node_id,
2024 &GenericParamKind::Type { default: None },
2025 bounds,
2026 None,
2027 span,
2028 ImplTraitContext::Universal,
2029 hir::PredicateOrigin::ImplTrait,
2030 );
2031
2032 let hir_id = self.next_id();
2033 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2034 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2035 None,
2036 self.arena.alloc(hir::Path {
2037 span,
2038 res,
2039 segments:
2040 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2041 }),
2042 ));
2043
2044 (param, preds, ty)
2045 }
2046
2047 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2050 let block = self.lower_block(b, false);
2051 self.expr_block(block)
2052 }
2053
2054 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2055 match c.value.kind {
2056 ExprKind::Underscore => {
2057 if !self.tcx.features().generic_arg_infer() {
2058 feature_err(
2059 &self.tcx.sess,
2060 sym::generic_arg_infer,
2061 c.value.span,
2062 fluent_generated::ast_lowering_underscore_array_length_unstable,
2063 )
2064 .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2065 }
2066 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2067 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2068 }
2069 _ => self.lower_anon_const_to_const_arg(c),
2070 }
2071 }
2072
2073 #[instrument(level = "debug", skip(self))]
2077 fn lower_const_path_to_const_arg(
2078 &mut self,
2079 path: &Path,
2080 res: Res<NodeId>,
2081 ty_id: NodeId,
2082 span: Span,
2083 ) -> &'hir hir::ConstArg<'hir> {
2084 let tcx = self.tcx;
2085
2086 let ct_kind = if path.is_potential_trivial_const_arg()
2088 && (tcx.features().min_generic_const_args()
2089 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2090 {
2091 let qpath = self.lower_qpath(
2092 ty_id,
2093 &None,
2094 path,
2095 ParamMode::Optional,
2096 AllowReturnTypeNotation::No,
2097 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2099 None,
2100 );
2101 hir::ConstArgKind::Path(qpath)
2102 } else {
2103 let parent_def_id = self.current_hir_id_owner.def_id;
2106 let node_id = self.next_node_id();
2107 let span = self.lower_span(span);
2108
2109 let def_id =
2114 self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
2115 let hir_id = self.lower_node_id(node_id);
2116
2117 let path_expr = Expr {
2118 id: ty_id,
2119 kind: ExprKind::Path(None, path.clone()),
2120 span,
2121 attrs: AttrVec::new(),
2122 tokens: None,
2123 };
2124
2125 let ct = self.with_new_scopes(span, |this| {
2126 self.arena.alloc(hir::AnonConst {
2127 def_id,
2128 hir_id,
2129 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2130 span,
2131 })
2132 });
2133 hir::ConstArgKind::Anon(ct)
2134 };
2135
2136 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2137 }
2138
2139 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2142 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2143 }
2144
2145 #[instrument(level = "debug", skip(self))]
2146 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2147 let tcx = self.tcx;
2148 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2151 && let [stmt] = block.stmts.as_slice()
2152 && let StmtKind::Expr(expr) = &stmt.kind
2153 && let ExprKind::Path(..) = &expr.kind
2154 {
2155 expr
2156 } else {
2157 &anon.value
2158 };
2159 let maybe_res =
2160 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2161 if let ExprKind::Path(None, path) = &expr.kind
2163 && path.is_potential_trivial_const_arg()
2164 && (tcx.features().min_generic_const_args()
2165 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2166 {
2167 let qpath = self.lower_qpath(
2168 expr.id,
2169 &None,
2170 path,
2171 ParamMode::Optional,
2172 AllowReturnTypeNotation::No,
2173 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2175 None,
2176 );
2177
2178 return ConstArg {
2179 hir_id: self.lower_node_id(anon.id),
2180 kind: hir::ConstArgKind::Path(qpath),
2181 };
2182 }
2183
2184 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2185 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2186 }
2187
2188 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2191 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2192 let def_id = this.local_def_id(c.id);
2193 let hir_id = this.lower_node_id(c.id);
2194 hir::AnonConst {
2195 def_id,
2196 hir_id,
2197 body: this.lower_const_body(c.value.span, Some(&c.value)),
2198 span: this.lower_span(c.value.span),
2199 }
2200 }))
2201 }
2202
2203 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2204 match u {
2205 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2206 UserProvided => hir::UnsafeSource::UserProvided,
2207 }
2208 }
2209
2210 fn lower_trait_bound_modifiers(
2211 &mut self,
2212 modifiers: TraitBoundModifiers,
2213 ) -> hir::TraitBoundModifiers {
2214 hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2215 }
2216
2217 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2220 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2221 }
2222
2223 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2224 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2225 }
2226
2227 fn stmt_let_pat(
2228 &mut self,
2229 attrs: Option<&'hir [hir::Attribute]>,
2230 span: Span,
2231 init: Option<&'hir hir::Expr<'hir>>,
2232 pat: &'hir hir::Pat<'hir>,
2233 source: hir::LocalSource,
2234 ) -> hir::Stmt<'hir> {
2235 let hir_id = self.next_id();
2236 if let Some(a) = attrs {
2237 debug_assert!(!a.is_empty());
2238 self.attrs.insert(hir_id.local_id, a);
2239 }
2240 let local = hir::LetStmt {
2241 hir_id,
2242 init,
2243 pat,
2244 els: None,
2245 source,
2246 span: self.lower_span(span),
2247 ty: None,
2248 };
2249 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2250 }
2251
2252 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2253 self.block_all(expr.span, &[], Some(expr))
2254 }
2255
2256 fn block_all(
2257 &mut self,
2258 span: Span,
2259 stmts: &'hir [hir::Stmt<'hir>],
2260 expr: Option<&'hir hir::Expr<'hir>>,
2261 ) -> &'hir hir::Block<'hir> {
2262 let blk = hir::Block {
2263 stmts,
2264 expr,
2265 hir_id: self.next_id(),
2266 rules: hir::BlockCheckMode::DefaultBlock,
2267 span: self.lower_span(span),
2268 targeted_by_break: false,
2269 };
2270 self.arena.alloc(blk)
2271 }
2272
2273 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2274 let field = self.single_pat_field(span, pat);
2275 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2276 }
2277
2278 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2279 let field = self.single_pat_field(span, pat);
2280 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2281 }
2282
2283 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2284 let field = self.single_pat_field(span, pat);
2285 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2286 }
2287
2288 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2289 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2290 }
2291
2292 fn single_pat_field(
2293 &mut self,
2294 span: Span,
2295 pat: &'hir hir::Pat<'hir>,
2296 ) -> &'hir [hir::PatField<'hir>] {
2297 let field = hir::PatField {
2298 hir_id: self.next_id(),
2299 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2300 is_shorthand: false,
2301 pat,
2302 span: self.lower_span(span),
2303 };
2304 arena_vec![self; field]
2305 }
2306
2307 fn pat_lang_item_variant(
2308 &mut self,
2309 span: Span,
2310 lang_item: hir::LangItem,
2311 fields: &'hir [hir::PatField<'hir>],
2312 ) -> &'hir hir::Pat<'hir> {
2313 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2314 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2315 }
2316
2317 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2318 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2319 }
2320
2321 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2322 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2323 }
2324
2325 fn pat_ident_binding_mode(
2326 &mut self,
2327 span: Span,
2328 ident: Ident,
2329 bm: hir::BindingMode,
2330 ) -> (&'hir hir::Pat<'hir>, HirId) {
2331 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2332 (self.arena.alloc(pat), hir_id)
2333 }
2334
2335 fn pat_ident_binding_mode_mut(
2336 &mut self,
2337 span: Span,
2338 ident: Ident,
2339 bm: hir::BindingMode,
2340 ) -> (hir::Pat<'hir>, HirId) {
2341 let hir_id = self.next_id();
2342
2343 (
2344 hir::Pat {
2345 hir_id,
2346 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2347 span: self.lower_span(span),
2348 default_binding_modes: true,
2349 },
2350 hir_id,
2351 )
2352 }
2353
2354 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2355 self.arena.alloc(hir::Pat {
2356 hir_id: self.next_id(),
2357 kind,
2358 span: self.lower_span(span),
2359 default_binding_modes: true,
2360 })
2361 }
2362
2363 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2364 hir::Pat {
2365 hir_id: self.next_id(),
2366 kind,
2367 span: self.lower_span(span),
2368 default_binding_modes: false,
2369 }
2370 }
2371
2372 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2373 let kind = match qpath {
2374 hir::QPath::Resolved(None, path) => {
2375 match path.res {
2377 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2378 let principal = hir::PolyTraitRef {
2379 bound_generic_params: &[],
2380 modifiers: hir::TraitBoundModifiers::NONE,
2381 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2382 span: self.lower_span(span),
2383 };
2384
2385 hir_id = self.next_id();
2388 hir::TyKind::TraitObject(
2389 arena_vec![self; principal],
2390 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2391 )
2392 }
2393 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2394 }
2395 }
2396 _ => hir::TyKind::Path(qpath),
2397 };
2398
2399 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2400 }
2401
2402 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2407 let r = hir::Lifetime {
2408 hir_id: self.next_id(),
2409 ident: Ident::new(kw::Empty, self.lower_span(span)),
2410 res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
2411 };
2412 debug!("elided_dyn_bound: r={:?}", r);
2413 self.arena.alloc(r)
2414 }
2415}
2416
2417struct GenericArgsCtor<'hir> {
2419 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2420 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2421 parenthesized: hir::GenericArgsParentheses,
2422 span: Span,
2423}
2424
2425impl<'hir> GenericArgsCtor<'hir> {
2426 fn is_empty(&self) -> bool {
2427 self.args.is_empty()
2428 && self.constraints.is_empty()
2429 && self.parenthesized == hir::GenericArgsParentheses::No
2430 }
2431
2432 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2433 let ga = hir::GenericArgs {
2434 args: this.arena.alloc_from_iter(self.args),
2435 constraints: self.constraints,
2436 parenthesized: self.parenthesized,
2437 span_ext: this.lower_span(self.span),
2438 };
2439 this.arena.alloc(ga)
2440 }
2441}