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