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