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