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 },
1213 itctx,
1214 );
1215 let bounds = this.arena.alloc_from_iter([bound]);
1216 let lifetime_bound = this.elided_dyn_bound(t.span);
1217 (bounds, lifetime_bound)
1218 });
1219 let kind = hir::TyKind::TraitObject(
1220 bounds,
1221 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1222 );
1223 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1224 }
1225
1226 let id = self.lower_node_id(t.id);
1227 let qpath = self.lower_qpath(
1228 t.id,
1229 qself,
1230 path,
1231 param_mode,
1232 AllowReturnTypeNotation::Yes,
1233 itctx,
1234 None,
1235 );
1236 self.ty_path(id, t.span, qpath)
1237 }
1238
1239 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1240 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1241 }
1242
1243 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1244 self.ty(span, hir::TyKind::Tup(tys))
1245 }
1246
1247 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1248 let kind = match &t.kind {
1249 TyKind::Infer => hir::TyKind::Infer(()),
1250 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1251 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1252 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1253 TyKind::Ref(region, mt) => {
1254 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1255 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1256 }
1257 TyKind::PinnedRef(region, mt) => {
1258 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1259 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1260 let span = self.lower_span(t.span);
1261 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1262 let args = self.arena.alloc(hir::GenericArgs {
1263 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1264 constraints: &[],
1265 parenthesized: hir::GenericArgsParentheses::No,
1266 span_ext: span,
1267 });
1268 let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1269 hir::TyKind::Path(path)
1270 }
1271 TyKind::BareFn(f) => {
1272 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1273 hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1274 generic_params,
1275 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1276 abi: self.lower_extern(f.ext),
1277 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1278 param_idents: self.lower_fn_params_to_idents(&f.decl),
1279 }))
1280 }
1281 TyKind::UnsafeBinder(f) => {
1282 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1283 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1284 generic_params,
1285 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1286 }))
1287 }
1288 TyKind::Never => hir::TyKind::Never,
1289 TyKind::Tup(tys) => hir::TyKind::Tup(
1290 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1291 ),
1292 TyKind::Paren(ty) => {
1293 return self.lower_ty_direct(ty, itctx);
1294 }
1295 TyKind::Path(qself, path) => {
1296 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1297 }
1298 TyKind::ImplicitSelf => {
1299 let hir_id = self.next_id();
1300 let res = self.expect_full_res(t.id);
1301 let res = self.lower_res(res);
1302 hir::TyKind::Path(hir::QPath::Resolved(
1303 None,
1304 self.arena.alloc(hir::Path {
1305 res,
1306 segments: arena_vec![self; hir::PathSegment::new(
1307 Ident::with_dummy_span(kw::SelfUpper),
1308 hir_id,
1309 res
1310 )],
1311 span: self.lower_span(t.span),
1312 }),
1313 ))
1314 }
1315 TyKind::Array(ty, length) => hir::TyKind::Array(
1316 self.lower_ty(ty, itctx),
1317 self.lower_array_length_to_const_arg(length),
1318 ),
1319 TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1320 TyKind::TraitObject(bounds, kind) => {
1321 let mut lifetime_bound = None;
1322 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1323 let bounds =
1324 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1325 GenericBound::Trait(ty) => {
1329 let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1330 Some(trait_ref)
1331 }
1332 GenericBound::Outlives(lifetime) => {
1333 if lifetime_bound.is_none() {
1334 lifetime_bound = Some(this.lower_lifetime(
1335 lifetime,
1336 LifetimeSource::Other,
1337 lifetime.ident.into(),
1338 ));
1339 }
1340 None
1341 }
1342 GenericBound::Use(_, span) => {
1344 this.dcx()
1345 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1346 None
1347 }
1348 }));
1349 let lifetime_bound =
1350 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1351 (bounds, lifetime_bound)
1352 });
1353 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1354 }
1355 TyKind::ImplTrait(def_node_id, bounds) => {
1356 let span = t.span;
1357 match itctx {
1358 ImplTraitContext::OpaqueTy { origin } => {
1359 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1360 }
1361 ImplTraitContext::Universal => {
1362 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1363 ast::GenericBound::Use(_, span) => Some(span),
1364 _ => None,
1365 }) {
1366 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1367 }
1368
1369 let def_id = self.local_def_id(*def_node_id);
1370 let name = self.tcx.item_name(def_id.to_def_id());
1371 let ident = Ident::new(name, span);
1372 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1373 *def_node_id,
1374 span,
1375 ident,
1376 bounds,
1377 );
1378 self.impl_trait_defs.push(param);
1379 if let Some(bounds) = bounds {
1380 self.impl_trait_bounds.push(bounds);
1381 }
1382 path
1383 }
1384 ImplTraitContext::InBinding => {
1385 hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1386 }
1387 ImplTraitContext::FeatureGated(position, feature) => {
1388 let guar = self
1389 .tcx
1390 .sess
1391 .create_feature_err(
1392 MisplacedImplTrait {
1393 span: t.span,
1394 position: DiagArgFromDisplay(&position),
1395 },
1396 feature,
1397 )
1398 .emit();
1399 hir::TyKind::Err(guar)
1400 }
1401 ImplTraitContext::Disallowed(position) => {
1402 let guar = self.dcx().emit_err(MisplacedImplTrait {
1403 span: t.span,
1404 position: DiagArgFromDisplay(&position),
1405 });
1406 hir::TyKind::Err(guar)
1407 }
1408 }
1409 }
1410 TyKind::Pat(ty, pat) => {
1411 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1412 }
1413 TyKind::MacCall(_) => {
1414 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1415 }
1416 TyKind::CVarArgs => {
1417 let guar = self.dcx().span_delayed_bug(
1418 t.span,
1419 "`TyKind::CVarArgs` should have been handled elsewhere",
1420 );
1421 hir::TyKind::Err(guar)
1422 }
1423 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1424 };
1425
1426 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1427 }
1428
1429 fn lower_ty_direct_lifetime(
1430 &mut self,
1431 t: &Ty,
1432 region: Option<Lifetime>,
1433 ) -> &'hir hir::Lifetime {
1434 let (region, syntax) = match region {
1435 Some(region) => (region, region.ident.into()),
1436
1437 None => {
1438 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1439 self.resolver.get_lifetime_res(t.id)
1440 {
1441 assert_eq!(start.plus(1), end);
1442 start
1443 } else {
1444 self.next_node_id()
1445 };
1446 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1447 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1448 (region, LifetimeSyntax::Implicit)
1449 }
1450 };
1451 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1452 }
1453
1454 #[instrument(level = "debug", skip(self), ret)]
1486 fn lower_opaque_impl_trait(
1487 &mut self,
1488 span: Span,
1489 origin: hir::OpaqueTyOrigin<LocalDefId>,
1490 opaque_ty_node_id: NodeId,
1491 bounds: &GenericBounds,
1492 itctx: ImplTraitContext,
1493 ) -> hir::TyKind<'hir> {
1494 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1500
1501 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1502 this.lower_param_bounds(bounds, itctx)
1503 })
1504 }
1505
1506 fn lower_opaque_inner(
1507 &mut self,
1508 opaque_ty_node_id: NodeId,
1509 origin: hir::OpaqueTyOrigin<LocalDefId>,
1510 opaque_ty_span: Span,
1511 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1512 ) -> hir::TyKind<'hir> {
1513 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1514 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1515 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1516
1517 let bounds = lower_item_bounds(self);
1518 let opaque_ty_def = hir::OpaqueTy {
1519 hir_id: opaque_ty_hir_id,
1520 def_id: opaque_ty_def_id,
1521 bounds,
1522 origin,
1523 span: self.lower_span(opaque_ty_span),
1524 };
1525 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1526
1527 hir::TyKind::OpaqueDef(opaque_ty_def)
1528 }
1529
1530 fn lower_precise_capturing_args(
1531 &mut self,
1532 precise_capturing_args: &[PreciseCapturingArg],
1533 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1534 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1535 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1536 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1537 ),
1538 PreciseCapturingArg::Arg(path, id) => {
1539 let [segment] = path.segments.as_slice() else {
1540 panic!();
1541 };
1542 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1543 partial_res.full_res().expect("no partial res expected for precise capture arg")
1544 });
1545 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1546 hir_id: self.lower_node_id(*id),
1547 ident: self.lower_ident(segment.ident),
1548 res: self.lower_res(res),
1549 })
1550 }
1551 }))
1552 }
1553
1554 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1555 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1556 PatKind::Missing => None,
1557 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1558 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1559 _ => {
1560 self.dcx().span_delayed_bug(
1561 param.pat.span,
1562 "non-missing/ident/wild param pat must trigger an error",
1563 );
1564 None
1565 }
1566 }))
1567 }
1568
1569 #[instrument(level = "debug", skip(self))]
1579 fn lower_fn_decl(
1580 &mut self,
1581 decl: &FnDecl,
1582 fn_node_id: NodeId,
1583 fn_span: Span,
1584 kind: FnDeclKind,
1585 coro: Option<CoroutineKind>,
1586 ) -> &'hir hir::FnDecl<'hir> {
1587 let c_variadic = decl.c_variadic();
1588
1589 let mut inputs = &decl.inputs[..];
1593 if c_variadic {
1594 inputs = &inputs[..inputs.len() - 1];
1595 }
1596 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1597 let itctx = match kind {
1598 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1599 ImplTraitContext::Universal
1600 }
1601 FnDeclKind::ExternFn => {
1602 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1603 }
1604 FnDeclKind::Closure => {
1605 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1606 }
1607 FnDeclKind::Pointer => {
1608 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1609 }
1610 };
1611 self.lower_ty_direct(¶m.ty, itctx)
1612 }));
1613
1614 let output = match coro {
1615 Some(coro) => {
1616 let fn_def_id = self.local_def_id(fn_node_id);
1617 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1618 }
1619 None => match &decl.output {
1620 FnRetTy::Ty(ty) => {
1621 let itctx = match kind {
1622 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1623 origin: hir::OpaqueTyOrigin::FnReturn {
1624 parent: self.local_def_id(fn_node_id),
1625 in_trait_or_impl: None,
1626 },
1627 },
1628 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1629 origin: hir::OpaqueTyOrigin::FnReturn {
1630 parent: self.local_def_id(fn_node_id),
1631 in_trait_or_impl: Some(hir::RpitContext::Trait),
1632 },
1633 },
1634 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1635 origin: hir::OpaqueTyOrigin::FnReturn {
1636 parent: self.local_def_id(fn_node_id),
1637 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1638 },
1639 },
1640 FnDeclKind::ExternFn => {
1641 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1642 }
1643 FnDeclKind::Closure => {
1644 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1645 }
1646 FnDeclKind::Pointer => {
1647 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1648 }
1649 };
1650 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1651 }
1652 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1653 },
1654 };
1655
1656 self.arena.alloc(hir::FnDecl {
1657 inputs,
1658 output,
1659 c_variadic,
1660 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1661 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1662 let is_mutable_pat = matches!(
1663 arg.pat.kind,
1664 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1665 );
1666
1667 match &arg.ty.kind {
1668 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1669 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1670 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1674 if mt.ty.kind.is_implicit_self() =>
1675 {
1676 match mt.mutbl {
1677 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1678 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1679 }
1680 }
1681 _ => hir::ImplicitSelfKind::None,
1682 }
1683 }),
1684 })
1685 }
1686
1687 #[instrument(level = "debug", skip(self))]
1696 fn lower_coroutine_fn_ret_ty(
1697 &mut self,
1698 output: &FnRetTy,
1699 fn_def_id: LocalDefId,
1700 coro: CoroutineKind,
1701 fn_kind: FnDeclKind,
1702 fn_span: Span,
1703 ) -> hir::FnRetTy<'hir> {
1704 let span = self.lower_span(fn_span);
1705
1706 let (opaque_ty_node_id, allowed_features) = match coro {
1707 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1708 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1709 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1710 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1711 }
1712 };
1713
1714 let opaque_ty_span =
1715 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1716
1717 let in_trait_or_impl = match fn_kind {
1718 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1719 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1720 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1721 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1722 };
1723
1724 let opaque_ty_ref = self.lower_opaque_inner(
1725 opaque_ty_node_id,
1726 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1727 opaque_ty_span,
1728 |this| {
1729 let bound = this.lower_coroutine_fn_output_type_to_bound(
1730 output,
1731 coro,
1732 opaque_ty_span,
1733 ImplTraitContext::OpaqueTy {
1734 origin: hir::OpaqueTyOrigin::FnReturn {
1735 parent: fn_def_id,
1736 in_trait_or_impl,
1737 },
1738 },
1739 );
1740 arena_vec![this; bound]
1741 },
1742 );
1743
1744 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1745 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1746 }
1747
1748 fn lower_coroutine_fn_output_type_to_bound(
1750 &mut self,
1751 output: &FnRetTy,
1752 coro: CoroutineKind,
1753 opaque_ty_span: Span,
1754 itctx: ImplTraitContext,
1755 ) -> hir::GenericBound<'hir> {
1756 let output_ty = match output {
1758 FnRetTy::Ty(ty) => {
1759 self.lower_ty(ty, itctx)
1763 }
1764 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1765 };
1766
1767 let (assoc_ty_name, trait_lang_item) = match coro {
1769 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1770 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1771 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1772 };
1773
1774 let bound_args = self.arena.alloc(hir::GenericArgs {
1775 args: &[],
1776 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1777 parenthesized: hir::GenericArgsParentheses::No,
1778 span_ext: DUMMY_SP,
1779 });
1780
1781 hir::GenericBound::Trait(hir::PolyTraitRef {
1782 bound_generic_params: &[],
1783 modifiers: hir::TraitBoundModifiers::NONE,
1784 trait_ref: hir::TraitRef {
1785 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1786 hir_ref_id: self.next_id(),
1787 },
1788 span: opaque_ty_span,
1789 })
1790 }
1791
1792 #[instrument(level = "trace", skip(self))]
1793 fn lower_param_bound(
1794 &mut self,
1795 tpb: &GenericBound,
1796 itctx: ImplTraitContext,
1797 ) -> hir::GenericBound<'hir> {
1798 match tpb {
1799 GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1800 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1801 lifetime,
1802 LifetimeSource::OutlivesBound,
1803 lifetime.ident.into(),
1804 )),
1805 GenericBound::Use(args, span) => hir::GenericBound::Use(
1806 self.lower_precise_capturing_args(args),
1807 self.lower_span(*span),
1808 ),
1809 }
1810 }
1811
1812 fn lower_lifetime(
1813 &mut self,
1814 l: &Lifetime,
1815 source: LifetimeSource,
1816 syntax: LifetimeSyntax,
1817 ) -> &'hir hir::Lifetime {
1818 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1819 }
1820
1821 fn lower_lifetime_hidden_in_path(
1822 &mut self,
1823 id: NodeId,
1824 span: Span,
1825 angle_brackets: AngleBrackets,
1826 ) -> &'hir hir::Lifetime {
1827 self.new_named_lifetime(
1828 id,
1829 id,
1830 Ident::new(kw::UnderscoreLifetime, span),
1831 LifetimeSource::Path { angle_brackets },
1832 LifetimeSyntax::Implicit,
1833 )
1834 }
1835
1836 #[instrument(level = "debug", skip(self))]
1837 fn new_named_lifetime(
1838 &mut self,
1839 id: NodeId,
1840 new_id: NodeId,
1841 ident: Ident,
1842 source: LifetimeSource,
1843 syntax: LifetimeSyntax,
1844 ) -> &'hir hir::Lifetime {
1845 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1846 let res = match res {
1847 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1848 LifetimeRes::Fresh { param, .. } => {
1849 assert_eq!(ident.name, kw::UnderscoreLifetime);
1850 let param = self.local_def_id(param);
1851 hir::LifetimeKind::Param(param)
1852 }
1853 LifetimeRes::Infer => {
1854 assert_eq!(ident.name, kw::UnderscoreLifetime);
1855 hir::LifetimeKind::Infer
1856 }
1857 LifetimeRes::Static { .. } => {
1858 assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1859 hir::LifetimeKind::Static
1860 }
1861 LifetimeRes::Error => hir::LifetimeKind::Error,
1862 LifetimeRes::ElidedAnchor { .. } => {
1863 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1864 }
1865 };
1866
1867 debug!(?res);
1868 self.arena.alloc(hir::Lifetime::new(
1869 self.lower_node_id(new_id),
1870 self.lower_ident(ident),
1871 res,
1872 source,
1873 syntax,
1874 ))
1875 }
1876
1877 fn lower_generic_params_mut(
1878 &mut self,
1879 params: &[GenericParam],
1880 source: hir::GenericParamSource,
1881 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1882 params.iter().map(move |param| self.lower_generic_param(param, source))
1883 }
1884
1885 fn lower_generic_params(
1886 &mut self,
1887 params: &[GenericParam],
1888 source: hir::GenericParamSource,
1889 ) -> &'hir [hir::GenericParam<'hir>] {
1890 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1891 }
1892
1893 #[instrument(level = "trace", skip(self))]
1894 fn lower_generic_param(
1895 &mut self,
1896 param: &GenericParam,
1897 source: hir::GenericParamSource,
1898 ) -> hir::GenericParam<'hir> {
1899 let (name, kind) = self.lower_generic_param_kind(param, source);
1900
1901 let hir_id = self.lower_node_id(param.id);
1902 self.lower_attrs(hir_id, ¶m.attrs, param.span());
1903 hir::GenericParam {
1904 hir_id,
1905 def_id: self.local_def_id(param.id),
1906 name,
1907 span: self.lower_span(param.span()),
1908 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1909 kind,
1910 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1911 source,
1912 }
1913 }
1914
1915 fn lower_generic_param_kind(
1916 &mut self,
1917 param: &GenericParam,
1918 source: hir::GenericParamSource,
1919 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1920 match ¶m.kind {
1921 GenericParamKind::Lifetime => {
1922 let ident = self.lower_ident(param.ident);
1925 let param_name =
1926 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1927 ParamName::Error(ident)
1928 } else {
1929 ParamName::Plain(ident)
1930 };
1931 let kind =
1932 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1933
1934 (param_name, kind)
1935 }
1936 GenericParamKind::Type { default, .. } => {
1937 let default = default
1940 .as_ref()
1941 .filter(|_| match source {
1942 hir::GenericParamSource::Generics => true,
1943 hir::GenericParamSource::Binder => {
1944 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1945 span: param.span(),
1946 });
1947
1948 false
1949 }
1950 })
1951 .map(|def| {
1952 self.lower_ty(
1953 def,
1954 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1955 )
1956 });
1957
1958 let kind = hir::GenericParamKind::Type { default, synthetic: false };
1959
1960 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1961 }
1962 GenericParamKind::Const { ty, kw_span: _, default } => {
1963 let ty = self
1964 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1965
1966 let default = default
1969 .as_ref()
1970 .filter(|_| match source {
1971 hir::GenericParamSource::Generics => true,
1972 hir::GenericParamSource::Binder => {
1973 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1974 span: param.span(),
1975 });
1976
1977 false
1978 }
1979 })
1980 .map(|def| self.lower_anon_const_to_const_arg(def));
1981
1982 (
1983 hir::ParamName::Plain(self.lower_ident(param.ident)),
1984 hir::GenericParamKind::Const { ty, default, synthetic: false },
1985 )
1986 }
1987 }
1988 }
1989
1990 fn lower_trait_ref(
1991 &mut self,
1992 modifiers: ast::TraitBoundModifiers,
1993 p: &TraitRef,
1994 itctx: ImplTraitContext,
1995 ) -> hir::TraitRef<'hir> {
1996 let path = match self.lower_qpath(
1997 p.ref_id,
1998 &None,
1999 &p.path,
2000 ParamMode::Explicit,
2001 AllowReturnTypeNotation::No,
2002 itctx,
2003 Some(modifiers),
2004 ) {
2005 hir::QPath::Resolved(None, path) => path,
2006 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2007 };
2008 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2009 }
2010
2011 #[instrument(level = "debug", skip(self))]
2012 fn lower_poly_trait_ref(
2013 &mut self,
2014 p: &PolyTraitRef,
2015 itctx: ImplTraitContext,
2016 ) -> hir::PolyTraitRef<'hir> {
2017 let bound_generic_params =
2018 self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
2019 let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
2020 let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
2021 hir::PolyTraitRef {
2022 bound_generic_params,
2023 modifiers,
2024 trait_ref,
2025 span: self.lower_span(p.span),
2026 }
2027 }
2028
2029 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2030 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2031 }
2032
2033 #[instrument(level = "debug", skip(self), ret)]
2034 fn lower_param_bounds(
2035 &mut self,
2036 bounds: &[GenericBound],
2037 itctx: ImplTraitContext,
2038 ) -> hir::GenericBounds<'hir> {
2039 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2040 }
2041
2042 fn lower_param_bounds_mut(
2043 &mut self,
2044 bounds: &[GenericBound],
2045 itctx: ImplTraitContext,
2046 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2047 bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2048 }
2049
2050 #[instrument(level = "debug", skip(self), ret)]
2051 fn lower_universal_param_and_bounds(
2052 &mut self,
2053 node_id: NodeId,
2054 span: Span,
2055 ident: Ident,
2056 bounds: &[GenericBound],
2057 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2058 let def_id = self.local_def_id(node_id);
2060 let span = self.lower_span(span);
2061
2062 let param = hir::GenericParam {
2064 hir_id: self.lower_node_id(node_id),
2065 def_id,
2066 name: ParamName::Plain(self.lower_ident(ident)),
2067 pure_wrt_drop: false,
2068 span,
2069 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2070 colon_span: None,
2071 source: hir::GenericParamSource::Generics,
2072 };
2073
2074 let preds = self.lower_generic_bound_predicate(
2075 ident,
2076 node_id,
2077 &GenericParamKind::Type { default: None },
2078 bounds,
2079 None,
2080 span,
2081 ImplTraitContext::Universal,
2082 hir::PredicateOrigin::ImplTrait,
2083 );
2084
2085 let hir_id = self.next_id();
2086 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2087 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2088 None,
2089 self.arena.alloc(hir::Path {
2090 span,
2091 res,
2092 segments:
2093 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2094 }),
2095 ));
2096
2097 (param, preds, ty)
2098 }
2099
2100 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2103 let block = self.lower_block(b, false);
2104 self.expr_block(block)
2105 }
2106
2107 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2108 match c.value.peel_parens().kind {
2111 ExprKind::Underscore => {
2112 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2113 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2114 }
2115 _ => self.lower_anon_const_to_const_arg(c),
2116 }
2117 }
2118
2119 #[instrument(level = "debug", skip(self))]
2123 fn lower_const_path_to_const_arg(
2124 &mut self,
2125 path: &Path,
2126 res: Res<NodeId>,
2127 ty_id: NodeId,
2128 span: Span,
2129 ) -> &'hir hir::ConstArg<'hir> {
2130 let tcx = self.tcx;
2131
2132 let ct_kind = if path
2133 .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2134 && (tcx.features().min_generic_const_args()
2135 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2136 {
2137 let qpath = self.lower_qpath(
2138 ty_id,
2139 &None,
2140 path,
2141 ParamMode::Explicit,
2142 AllowReturnTypeNotation::No,
2143 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2145 None,
2146 );
2147 hir::ConstArgKind::Path(qpath)
2148 } else {
2149 let node_id = self.next_node_id();
2151 let span = self.lower_span(span);
2152
2153 let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2158 let hir_id = self.lower_node_id(node_id);
2159
2160 let path_expr = Expr {
2161 id: ty_id,
2162 kind: ExprKind::Path(None, path.clone()),
2163 span,
2164 attrs: AttrVec::new(),
2165 tokens: None,
2166 };
2167
2168 let ct = self.with_new_scopes(span, |this| {
2169 self.arena.alloc(hir::AnonConst {
2170 def_id,
2171 hir_id,
2172 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2173 span,
2174 })
2175 });
2176 hir::ConstArgKind::Anon(ct)
2177 };
2178
2179 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2180 }
2181
2182 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2185 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2186 }
2187
2188 #[instrument(level = "debug", skip(self))]
2189 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2190 let tcx = self.tcx;
2191 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2194 && let [stmt] = block.stmts.as_slice()
2195 && let StmtKind::Expr(expr) = &stmt.kind
2196 && let ExprKind::Path(..) = &expr.kind
2197 {
2198 expr
2199 } else {
2200 &anon.value
2201 };
2202 let maybe_res =
2203 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2204 if let ExprKind::Path(qself, path) = &expr.kind
2205 && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2206 && (tcx.features().min_generic_const_args()
2207 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2208 {
2209 let qpath = self.lower_qpath(
2210 expr.id,
2211 qself,
2212 path,
2213 ParamMode::Explicit,
2214 AllowReturnTypeNotation::No,
2215 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2217 None,
2218 );
2219
2220 return ConstArg {
2221 hir_id: self.lower_node_id(anon.id),
2222 kind: hir::ConstArgKind::Path(qpath),
2223 };
2224 }
2225
2226 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2227 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2228 }
2229
2230 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2233 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2234 let def_id = this.local_def_id(c.id);
2235 let hir_id = this.lower_node_id(c.id);
2236 hir::AnonConst {
2237 def_id,
2238 hir_id,
2239 body: this.lower_const_body(c.value.span, Some(&c.value)),
2240 span: this.lower_span(c.value.span),
2241 }
2242 }))
2243 }
2244
2245 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2246 match u {
2247 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2248 UserProvided => hir::UnsafeSource::UserProvided,
2249 }
2250 }
2251
2252 fn lower_trait_bound_modifiers(
2253 &mut self,
2254 modifiers: TraitBoundModifiers,
2255 ) -> hir::TraitBoundModifiers {
2256 hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2257 }
2258
2259 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2262 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2263 }
2264
2265 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2266 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2267 }
2268
2269 fn stmt_let_pat(
2270 &mut self,
2271 attrs: Option<&'hir [hir::Attribute]>,
2272 span: Span,
2273 init: Option<&'hir hir::Expr<'hir>>,
2274 pat: &'hir hir::Pat<'hir>,
2275 source: hir::LocalSource,
2276 ) -> hir::Stmt<'hir> {
2277 let hir_id = self.next_id();
2278 if let Some(a) = attrs {
2279 assert!(!a.is_empty());
2280 self.attrs.insert(hir_id.local_id, a);
2281 }
2282 let local = hir::LetStmt {
2283 super_: None,
2284 hir_id,
2285 init,
2286 pat,
2287 els: None,
2288 source,
2289 span: self.lower_span(span),
2290 ty: None,
2291 };
2292 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2293 }
2294
2295 fn stmt_super_let_pat(
2296 &mut self,
2297 span: Span,
2298 pat: &'hir hir::Pat<'hir>,
2299 init: Option<&'hir hir::Expr<'hir>>,
2300 ) -> hir::Stmt<'hir> {
2301 let hir_id = self.next_id();
2302 let local = hir::LetStmt {
2303 super_: Some(span),
2304 hir_id,
2305 init,
2306 pat,
2307 els: None,
2308 source: hir::LocalSource::Normal,
2309 span: self.lower_span(span),
2310 ty: None,
2311 };
2312 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2313 }
2314
2315 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2316 self.block_all(expr.span, &[], Some(expr))
2317 }
2318
2319 fn block_all(
2320 &mut self,
2321 span: Span,
2322 stmts: &'hir [hir::Stmt<'hir>],
2323 expr: Option<&'hir hir::Expr<'hir>>,
2324 ) -> &'hir hir::Block<'hir> {
2325 let blk = hir::Block {
2326 stmts,
2327 expr,
2328 hir_id: self.next_id(),
2329 rules: hir::BlockCheckMode::DefaultBlock,
2330 span: self.lower_span(span),
2331 targeted_by_break: false,
2332 };
2333 self.arena.alloc(blk)
2334 }
2335
2336 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2337 let field = self.single_pat_field(span, pat);
2338 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2339 }
2340
2341 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2342 let field = self.single_pat_field(span, pat);
2343 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2344 }
2345
2346 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2347 let field = self.single_pat_field(span, pat);
2348 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2349 }
2350
2351 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2352 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2353 }
2354
2355 fn single_pat_field(
2356 &mut self,
2357 span: Span,
2358 pat: &'hir hir::Pat<'hir>,
2359 ) -> &'hir [hir::PatField<'hir>] {
2360 let field = hir::PatField {
2361 hir_id: self.next_id(),
2362 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2363 is_shorthand: false,
2364 pat,
2365 span: self.lower_span(span),
2366 };
2367 arena_vec![self; field]
2368 }
2369
2370 fn pat_lang_item_variant(
2371 &mut self,
2372 span: Span,
2373 lang_item: hir::LangItem,
2374 fields: &'hir [hir::PatField<'hir>],
2375 ) -> &'hir hir::Pat<'hir> {
2376 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2377 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2378 }
2379
2380 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2381 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2382 }
2383
2384 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2385 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2386 }
2387
2388 fn pat_ident_binding_mode(
2389 &mut self,
2390 span: Span,
2391 ident: Ident,
2392 bm: hir::BindingMode,
2393 ) -> (&'hir hir::Pat<'hir>, HirId) {
2394 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2395 (self.arena.alloc(pat), hir_id)
2396 }
2397
2398 fn pat_ident_binding_mode_mut(
2399 &mut self,
2400 span: Span,
2401 ident: Ident,
2402 bm: hir::BindingMode,
2403 ) -> (hir::Pat<'hir>, HirId) {
2404 let hir_id = self.next_id();
2405
2406 (
2407 hir::Pat {
2408 hir_id,
2409 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2410 span: self.lower_span(span),
2411 default_binding_modes: true,
2412 },
2413 hir_id,
2414 )
2415 }
2416
2417 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2418 self.arena.alloc(hir::Pat {
2419 hir_id: self.next_id(),
2420 kind,
2421 span: self.lower_span(span),
2422 default_binding_modes: true,
2423 })
2424 }
2425
2426 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2427 hir::Pat {
2428 hir_id: self.next_id(),
2429 kind,
2430 span: self.lower_span(span),
2431 default_binding_modes: false,
2432 }
2433 }
2434
2435 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2436 let kind = match qpath {
2437 hir::QPath::Resolved(None, path) => {
2438 match path.res {
2440 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2441 let principal = hir::PolyTraitRef {
2442 bound_generic_params: &[],
2443 modifiers: hir::TraitBoundModifiers::NONE,
2444 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2445 span: self.lower_span(span),
2446 };
2447
2448 hir_id = self.next_id();
2451 hir::TyKind::TraitObject(
2452 arena_vec![self; principal],
2453 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2454 )
2455 }
2456 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2457 }
2458 }
2459 _ => hir::TyKind::Path(qpath),
2460 };
2461
2462 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2463 }
2464
2465 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2470 let r = hir::Lifetime::new(
2471 self.next_id(),
2472 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2473 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2474 LifetimeSource::Other,
2475 LifetimeSyntax::Implicit,
2476 );
2477 debug!("elided_dyn_bound: r={:?}", r);
2478 self.arena.alloc(r)
2479 }
2480}
2481
2482struct GenericArgsCtor<'hir> {
2484 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2485 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2486 parenthesized: hir::GenericArgsParentheses,
2487 span: Span,
2488}
2489
2490impl<'hir> GenericArgsCtor<'hir> {
2491 fn is_empty(&self) -> bool {
2492 self.args.is_empty()
2493 && self.constraints.is_empty()
2494 && self.parenthesized == hir::GenericArgsParentheses::No
2495 }
2496
2497 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2498 let ga = hir::GenericArgs {
2499 args: this.arena.alloc_from_iter(self.args),
2500 constraints: self.constraints,
2501 parenthesized: self.parenthesized,
2502 span_ext: this.lower_span(self.span),
2503 };
2504 this.arena.alloc(ga)
2505 }
2506}