1#![allow(internal_features)]
35#![cfg_attr(bootstrap, feature(let_chains))]
36#![doc(rust_logo)]
37#![feature(assert_matches)]
38#![feature(box_patterns)]
39#![feature(exact_size_is_empty)]
40#![feature(if_let_guard)]
41#![feature(rustdoc_internals)]
42use std::sync::Arc;
45
46use rustc_ast::node_id::NodeMap;
47use rustc_ast::{self as ast, *};
48use rustc_attr_parsing::{AttributeParser, OmitDoc};
49use rustc_data_structures::fingerprint::Fingerprint;
50use rustc_data_structures::sorted_map::SortedMap;
51use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
52use rustc_data_structures::sync::spawn;
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, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem,
59 LifetimeSource, LifetimeSyntax, ParamName, 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);
459
460 let prof = sess.prof.clone();
462 spawn(move || {
463 let _timer = prof.verbose_generic_activity("drop_ast");
464 drop(krate);
465 });
466
467 let opt_hir_hash =
469 if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
470 hir::Crate { owners, opt_hir_hash }
471}
472
473#[derive(Copy, Clone, PartialEq, Debug)]
474enum ParamMode {
475 Explicit,
477 Optional,
479}
480
481#[derive(Copy, Clone, Debug)]
482enum AllowReturnTypeNotation {
483 Yes,
485 No,
487}
488
489enum GenericArgsMode {
490 ParenSugar,
492 ReturnTypeNotation,
494 Err,
496 Silence,
498}
499
500impl<'a, 'hir> LoweringContext<'a, 'hir> {
501 fn create_def(
502 &mut self,
503 node_id: ast::NodeId,
504 name: Option<Symbol>,
505 def_kind: DefKind,
506 span: Span,
507 ) -> LocalDefId {
508 let parent = self.current_hir_id_owner.def_id;
509 debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
510 assert!(
511 self.opt_local_def_id(node_id).is_none(),
512 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
513 node_id,
514 def_kind,
515 self.tcx.hir_def_key(self.local_def_id(node_id)),
516 );
517
518 let def_id = self
519 .tcx
520 .at(span)
521 .create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator)
522 .def_id();
523
524 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
525 self.resolver.node_id_to_def_id.insert(node_id, def_id);
526
527 def_id
528 }
529
530 fn next_node_id(&mut self) -> NodeId {
531 let start = self.resolver.next_node_id;
532 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
533 self.resolver.next_node_id = ast::NodeId::from_u32(next);
534 start
535 }
536
537 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
540 self.resolver.node_id_to_def_id.get(&node).copied()
541 }
542
543 fn local_def_id(&self, node: NodeId) -> LocalDefId {
544 self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
545 }
546
547 fn owner_id(&self, node: NodeId) -> hir::OwnerId {
549 hir::OwnerId { def_id: self.local_def_id(node) }
550 }
551
552 #[instrument(level = "debug", skip(self, f))]
558 fn with_hir_id_owner(
559 &mut self,
560 owner: NodeId,
561 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
562 ) {
563 let owner_id = self.owner_id(owner);
564
565 let current_attrs = std::mem::take(&mut self.attrs);
566 let current_bodies = std::mem::take(&mut self.bodies);
567 let current_define_opaque = std::mem::take(&mut self.define_opaque);
568 let current_ident_and_label_to_local_id =
569 std::mem::take(&mut self.ident_and_label_to_local_id);
570
571 #[cfg(debug_assertions)]
572 let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
573 let current_trait_map = std::mem::take(&mut self.trait_map);
574 let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);
575 let current_local_counter =
576 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
577 let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
578 let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
579
580 #[cfg(debug_assertions)]
586 {
587 let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
588 debug_assert_eq!(_old, None);
589 }
590
591 let item = f(self);
592 debug_assert_eq!(owner_id, item.def_id());
593 debug_assert!(self.impl_trait_defs.is_empty());
595 debug_assert!(self.impl_trait_bounds.is_empty());
596 let info = self.make_owner_info(item);
597
598 self.attrs = current_attrs;
599 self.bodies = current_bodies;
600 self.define_opaque = current_define_opaque;
601 self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
602
603 #[cfg(debug_assertions)]
604 {
605 self.node_id_to_local_id = current_node_id_to_local_id;
606 }
607 self.trait_map = current_trait_map;
608 self.current_hir_id_owner = current_owner;
609 self.item_local_id_counter = current_local_counter;
610 self.impl_trait_defs = current_impl_trait_defs;
611 self.impl_trait_bounds = current_impl_trait_bounds;
612
613 debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
614 self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
615 }
616
617 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
618 let attrs = std::mem::take(&mut self.attrs);
619 let mut bodies = std::mem::take(&mut self.bodies);
620 let define_opaque = std::mem::take(&mut self.define_opaque);
621 let trait_map = std::mem::take(&mut self.trait_map);
622
623 #[cfg(debug_assertions)]
624 for (id, attrs) in attrs.iter() {
625 if attrs.is_empty() {
627 panic!("Stored empty attributes for {:?}", id);
628 }
629 }
630
631 bodies.sort_by_key(|(k, _)| *k);
632 let bodies = SortedMap::from_presorted_elements(bodies);
633
634 let (opt_hash_including_bodies, attrs_hash) =
636 self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);
637 let num_nodes = self.item_local_id_counter.as_usize();
638 let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
639 let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
640 let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
641
642 self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
643 }
644
645 #[instrument(level = "debug", skip(self), ret)]
651 fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
652 assert_ne!(ast_node_id, DUMMY_NODE_ID);
653
654 let owner = self.current_hir_id_owner;
655 let local_id = self.item_local_id_counter;
656 assert_ne!(local_id, hir::ItemLocalId::ZERO);
657 self.item_local_id_counter.increment_by(1);
658 let hir_id = HirId { owner, local_id };
659
660 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
661 self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
662 }
663
664 if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
665 self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
666 }
667
668 #[cfg(debug_assertions)]
670 {
671 let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
672 assert_eq!(old, None);
673 }
674
675 hir_id
676 }
677
678 #[instrument(level = "debug", skip(self), ret)]
680 fn next_id(&mut self) -> HirId {
681 let owner = self.current_hir_id_owner;
682 let local_id = self.item_local_id_counter;
683 assert_ne!(local_id, hir::ItemLocalId::ZERO);
684 self.item_local_id_counter.increment_by(1);
685 HirId { owner, local_id }
686 }
687
688 #[instrument(level = "trace", skip(self))]
689 fn lower_res(&mut self, res: Res<NodeId>) -> Res {
690 let res: Result<Res, ()> = res.apply_id(|id| {
691 let owner = self.current_hir_id_owner;
692 let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
693 Ok(HirId { owner, local_id })
694 });
695 trace!(?res);
696
697 res.unwrap_or(Res::Err)
703 }
704
705 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
706 self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
707 }
708
709 fn lower_import_res(&mut self, id: NodeId, span: Span) -> SmallVec<[Res; 3]> {
710 let res = self.resolver.get_import_res(id).present_items();
711 let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect();
712 if res.is_empty() {
713 self.dcx().span_delayed_bug(span, "no resolution for an import");
714 return smallvec![Res::Err];
715 }
716 res
717 }
718
719 fn make_lang_item_qpath(
720 &mut self,
721 lang_item: hir::LangItem,
722 span: Span,
723 args: Option<&'hir hir::GenericArgs<'hir>>,
724 ) -> hir::QPath<'hir> {
725 hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
726 }
727
728 fn make_lang_item_path(
729 &mut self,
730 lang_item: hir::LangItem,
731 span: Span,
732 args: Option<&'hir hir::GenericArgs<'hir>>,
733 ) -> &'hir hir::Path<'hir> {
734 let def_id = self.tcx.require_lang_item(lang_item, Some(span));
735 let def_kind = self.tcx.def_kind(def_id);
736 let res = Res::Def(def_kind, def_id);
737 self.arena.alloc(hir::Path {
738 span,
739 res,
740 segments: self.arena.alloc_from_iter([hir::PathSegment {
741 ident: Ident::new(lang_item.name(), span),
742 hir_id: self.next_id(),
743 res,
744 args,
745 infer_args: args.is_none(),
746 }]),
747 })
748 }
749
750 fn mark_span_with_reason(
753 &self,
754 reason: DesugaringKind,
755 span: Span,
756 allow_internal_unstable: Option<Arc<[Symbol]>>,
757 ) -> Span {
758 self.tcx.with_stable_hashing_context(|hcx| {
759 span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
760 })
761 }
762
763 fn lower_span(&self, span: Span) -> Span {
766 if self.tcx.sess.opts.incremental.is_some() {
767 span.with_parent(Some(self.current_hir_id_owner.def_id))
768 } else {
769 span
771 }
772 }
773
774 fn lower_ident(&self, ident: Ident) -> Ident {
775 Ident::new(ident.name, self.lower_span(ident.span))
776 }
777
778 #[instrument(level = "debug", skip(self))]
780 fn lifetime_res_to_generic_param(
781 &mut self,
782 ident: Ident,
783 node_id: NodeId,
784 res: LifetimeRes,
785 source: hir::GenericParamSource,
786 ) -> Option<hir::GenericParam<'hir>> {
787 let (name, kind) = match res {
788 LifetimeRes::Param { .. } => {
789 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
790 }
791 LifetimeRes::Fresh { param, kind, .. } => {
792 let _def_id = self.create_def(
794 param,
795 Some(kw::UnderscoreLifetime),
796 DefKind::LifetimeParam,
797 ident.span,
798 );
799 debug!(?_def_id);
800
801 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
802 }
803 LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
804 res => panic!(
805 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
806 res, ident, ident.span
807 ),
808 };
809 let hir_id = self.lower_node_id(node_id);
810 let def_id = self.local_def_id(node_id);
811 Some(hir::GenericParam {
812 hir_id,
813 def_id,
814 name,
815 span: self.lower_span(ident.span),
816 pure_wrt_drop: false,
817 kind: hir::GenericParamKind::Lifetime { kind },
818 colon_span: None,
819 source,
820 })
821 }
822
823 #[instrument(level = "debug", skip(self))]
829 #[inline]
830 fn lower_lifetime_binder(
831 &mut self,
832 binder: NodeId,
833 generic_params: &[GenericParam],
834 ) -> &'hir [hir::GenericParam<'hir>] {
835 let mut generic_params: Vec<_> = self
836 .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
837 .collect();
838 let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
839 debug!(?extra_lifetimes);
840 generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
841 self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
842 }));
843 let generic_params = self.arena.alloc_from_iter(generic_params);
844 debug!(?generic_params);
845
846 generic_params
847 }
848
849 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
850 let was_in_dyn_type = self.is_in_dyn_type;
851 self.is_in_dyn_type = in_scope;
852
853 let result = f(self);
854
855 self.is_in_dyn_type = was_in_dyn_type;
856
857 result
858 }
859
860 fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
861 let current_item = self.current_item;
862 self.current_item = Some(scope_span);
863
864 let was_in_loop_condition = self.is_in_loop_condition;
865 self.is_in_loop_condition = false;
866
867 let old_contract = self.contract_ensures.take();
868
869 let catch_scope = self.catch_scope.take();
870 let loop_scope = self.loop_scope.take();
871 let ret = f(self);
872 self.catch_scope = catch_scope;
873 self.loop_scope = loop_scope;
874
875 self.contract_ensures = old_contract;
876
877 self.is_in_loop_condition = was_in_loop_condition;
878
879 self.current_item = current_item;
880
881 ret
882 }
883
884 fn lower_attrs(
885 &mut self,
886 id: HirId,
887 attrs: &[Attribute],
888 target_span: Span,
889 ) -> &'hir [hir::Attribute] {
890 if attrs.is_empty() {
891 &[]
892 } else {
893 let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span));
894
895 debug_assert_eq!(id.owner, self.current_hir_id_owner);
896 let ret = self.arena.alloc_from_iter(lowered_attrs);
897
898 if ret.is_empty() {
905 &[]
906 } else {
907 self.attrs.insert(id.local_id, ret);
908 ret
909 }
910 }
911 }
912
913 fn lower_attrs_vec(&self, attrs: &[Attribute], target_span: Span) -> Vec<hir::Attribute> {
914 self.attribute_parser
915 .parse_attribute_list(attrs, target_span, OmitDoc::Lower, |s| self.lower_span(s))
916 }
917
918 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
919 debug_assert_eq!(id.owner, self.current_hir_id_owner);
920 debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
921 if let Some(&a) = self.attrs.get(&target_id.local_id) {
922 debug_assert!(!a.is_empty());
923 self.attrs.insert(id.local_id, a);
924 }
925 }
926
927 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
928 args.clone()
929 }
930
931 #[instrument(level = "debug", skip_all)]
933 fn lower_assoc_item_constraint(
934 &mut self,
935 constraint: &AssocItemConstraint,
936 itctx: ImplTraitContext,
937 ) -> hir::AssocItemConstraint<'hir> {
938 debug!(?constraint, ?itctx);
939 let gen_args = if let Some(gen_args) = &constraint.gen_args {
941 let gen_args_ctor = match gen_args {
942 GenericArgs::AngleBracketed(data) => {
943 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
944 }
945 GenericArgs::Parenthesized(data) => {
946 if let Some(first_char) = constraint.ident.as_str().chars().next()
947 && first_char.is_ascii_lowercase()
948 {
949 let err = match (&data.inputs[..], &data.output) {
950 ([_, ..], FnRetTy::Default(_)) => {
951 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
952 }
953 ([], FnRetTy::Default(_)) => {
954 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
955 }
956 (_, FnRetTy::Ty(ty)) => {
958 let span = data.inputs_span.shrink_to_hi().to(ty.span);
959 errors::BadReturnTypeNotation::Output {
960 span,
961 suggestion: errors::RTNSuggestion {
962 output: span,
963 input: data.inputs_span,
964 },
965 }
966 }
967 };
968 let mut err = self.dcx().create_err(err);
969 if !self.tcx.features().return_type_notation()
970 && self.tcx.sess.is_nightly_build()
971 {
972 add_feature_diagnostics(
973 &mut err,
974 &self.tcx.sess,
975 sym::return_type_notation,
976 );
977 }
978 err.emit();
979 GenericArgsCtor {
980 args: Default::default(),
981 constraints: &[],
982 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
983 span: data.span,
984 }
985 } else {
986 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
987 self.lower_angle_bracketed_parameter_data(
990 &data.as_angle_bracketed_args(),
991 ParamMode::Explicit,
992 itctx,
993 )
994 .0
995 }
996 }
997 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
998 args: Default::default(),
999 constraints: &[],
1000 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1001 span: *span,
1002 },
1003 };
1004 gen_args_ctor.into_generic_args(self)
1005 } else {
1006 self.arena.alloc(hir::GenericArgs::none())
1007 };
1008 let kind = match &constraint.kind {
1009 AssocItemConstraintKind::Equality { term } => {
1010 let term = match term {
1011 Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1012 Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1013 };
1014 hir::AssocItemConstraintKind::Equality { term }
1015 }
1016 AssocItemConstraintKind::Bound { bounds } => {
1017 if self.is_in_dyn_type {
1019 let suggestion = match itctx {
1020 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1021 let bound_end_span = constraint
1022 .gen_args
1023 .as_ref()
1024 .map_or(constraint.ident.span, |args| args.span());
1025 if bound_end_span.eq_ctxt(constraint.span) {
1026 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1027 } else {
1028 None
1029 }
1030 }
1031 _ => None,
1032 };
1033
1034 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1035 span: constraint.span,
1036 suggestion,
1037 });
1038 let err_ty =
1039 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1040 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1041 } else {
1042 let bounds = self.lower_param_bounds(bounds, itctx);
1045
1046 hir::AssocItemConstraintKind::Bound { bounds }
1047 }
1048 }
1049 };
1050
1051 hir::AssocItemConstraint {
1052 hir_id: self.lower_node_id(constraint.id),
1053 ident: self.lower_ident(constraint.ident),
1054 gen_args,
1055 kind,
1056 span: self.lower_span(constraint.span),
1057 }
1058 }
1059
1060 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1061 let sub = if data.inputs.is_empty() {
1063 let parentheses_span =
1064 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1065 AssocTyParenthesesSub::Empty { parentheses_span }
1066 }
1067 else {
1069 let open_param = data.inputs_span.shrink_to_lo().to(data
1071 .inputs
1072 .first()
1073 .unwrap()
1074 .span
1075 .shrink_to_lo());
1076 let close_param =
1078 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1079 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1080 };
1081 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1082 }
1083
1084 #[instrument(level = "debug", skip(self))]
1085 fn lower_generic_arg(
1086 &mut self,
1087 arg: &ast::GenericArg,
1088 itctx: ImplTraitContext,
1089 ) -> hir::GenericArg<'hir> {
1090 match arg {
1091 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1092 lt,
1093 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1094 lt.ident.into(),
1095 )),
1096 ast::GenericArg::Type(ty) => {
1097 if ty.is_maybe_parenthesised_infer() {
1100 return GenericArg::Infer(hir::InferArg {
1101 hir_id: self.lower_node_id(ty.id),
1102 span: self.lower_span(ty.span),
1103 });
1104 }
1105
1106 match &ty.kind {
1107 TyKind::Path(None, path) => {
1114 if let Some(res) = self
1115 .resolver
1116 .get_partial_res(ty.id)
1117 .and_then(|partial_res| partial_res.full_res())
1118 {
1119 if !res.matches_ns(Namespace::TypeNS)
1120 && path.is_potential_trivial_const_arg(false)
1121 {
1122 debug!(
1123 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1124 ty,
1125 );
1126
1127 let ct =
1128 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1129 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1130 }
1131 }
1132 }
1133 _ => {}
1134 }
1135 GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1136 }
1137 ast::GenericArg::Const(ct) => {
1138 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1139 }
1140 }
1141 }
1142
1143 #[instrument(level = "debug", skip(self))]
1144 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1145 self.arena.alloc(self.lower_ty_direct(t, itctx))
1146 }
1147
1148 fn lower_path_ty(
1149 &mut self,
1150 t: &Ty,
1151 qself: &Option<ptr::P<QSelf>>,
1152 path: &Path,
1153 param_mode: ParamMode,
1154 itctx: ImplTraitContext,
1155 ) -> hir::Ty<'hir> {
1156 if qself.is_none()
1162 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1163 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1164 {
1165 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1166 let bound = this.lower_poly_trait_ref(
1167 &PolyTraitRef {
1168 bound_generic_params: ThinVec::new(),
1169 modifiers: TraitBoundModifiers::NONE,
1170 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1171 span: t.span,
1172 },
1173 itctx,
1174 );
1175 let bounds = this.arena.alloc_from_iter([bound]);
1176 let lifetime_bound = this.elided_dyn_bound(t.span);
1177 (bounds, lifetime_bound)
1178 });
1179 let kind = hir::TyKind::TraitObject(
1180 bounds,
1181 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1182 );
1183 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1184 }
1185
1186 let id = self.lower_node_id(t.id);
1187 let qpath = self.lower_qpath(
1188 t.id,
1189 qself,
1190 path,
1191 param_mode,
1192 AllowReturnTypeNotation::Yes,
1193 itctx,
1194 None,
1195 );
1196 self.ty_path(id, t.span, qpath)
1197 }
1198
1199 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1200 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1201 }
1202
1203 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1204 self.ty(span, hir::TyKind::Tup(tys))
1205 }
1206
1207 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1208 let kind = match &t.kind {
1209 TyKind::Infer => hir::TyKind::Infer(()),
1210 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1211 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1212 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1213 TyKind::Ref(region, mt) => {
1214 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1215 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1216 }
1217 TyKind::PinnedRef(region, mt) => {
1218 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1219 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1220 let span = self.lower_span(t.span);
1221 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1222 let args = self.arena.alloc(hir::GenericArgs {
1223 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1224 constraints: &[],
1225 parenthesized: hir::GenericArgsParentheses::No,
1226 span_ext: span,
1227 });
1228 let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1229 hir::TyKind::Path(path)
1230 }
1231 TyKind::BareFn(f) => {
1232 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1233 hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1234 generic_params,
1235 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1236 abi: self.lower_extern(f.ext),
1237 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1238 param_idents: self.lower_fn_params_to_idents(&f.decl),
1239 }))
1240 }
1241 TyKind::UnsafeBinder(f) => {
1242 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1243 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1244 generic_params,
1245 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1246 }))
1247 }
1248 TyKind::Never => hir::TyKind::Never,
1249 TyKind::Tup(tys) => hir::TyKind::Tup(
1250 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1251 ),
1252 TyKind::Paren(ty) => {
1253 return self.lower_ty_direct(ty, itctx);
1254 }
1255 TyKind::Path(qself, path) => {
1256 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1257 }
1258 TyKind::ImplicitSelf => {
1259 let hir_id = self.next_id();
1260 let res = self.expect_full_res(t.id);
1261 let res = self.lower_res(res);
1262 hir::TyKind::Path(hir::QPath::Resolved(
1263 None,
1264 self.arena.alloc(hir::Path {
1265 res,
1266 segments: arena_vec![self; hir::PathSegment::new(
1267 Ident::with_dummy_span(kw::SelfUpper),
1268 hir_id,
1269 res
1270 )],
1271 span: self.lower_span(t.span),
1272 }),
1273 ))
1274 }
1275 TyKind::Array(ty, length) => hir::TyKind::Array(
1276 self.lower_ty(ty, itctx),
1277 self.lower_array_length_to_const_arg(length),
1278 ),
1279 TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1280 TyKind::TraitObject(bounds, kind) => {
1281 let mut lifetime_bound = None;
1282 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1283 let bounds =
1284 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1285 GenericBound::Trait(ty) => {
1289 let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1290 Some(trait_ref)
1291 }
1292 GenericBound::Outlives(lifetime) => {
1293 if lifetime_bound.is_none() {
1294 lifetime_bound = Some(this.lower_lifetime(
1295 lifetime,
1296 LifetimeSource::Other,
1297 lifetime.ident.into(),
1298 ));
1299 }
1300 None
1301 }
1302 GenericBound::Use(_, span) => {
1304 this.dcx()
1305 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1306 None
1307 }
1308 }));
1309 let lifetime_bound =
1310 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1311 (bounds, lifetime_bound)
1312 });
1313 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1314 }
1315 TyKind::ImplTrait(def_node_id, bounds) => {
1316 let span = t.span;
1317 match itctx {
1318 ImplTraitContext::OpaqueTy { origin } => {
1319 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1320 }
1321 ImplTraitContext::Universal => {
1322 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1323 ast::GenericBound::Use(_, span) => Some(span),
1324 _ => None,
1325 }) {
1326 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1327 }
1328
1329 let def_id = self.local_def_id(*def_node_id);
1330 let name = self.tcx.item_name(def_id.to_def_id());
1331 let ident = Ident::new(name, span);
1332 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1333 *def_node_id,
1334 span,
1335 ident,
1336 bounds,
1337 );
1338 self.impl_trait_defs.push(param);
1339 if let Some(bounds) = bounds {
1340 self.impl_trait_bounds.push(bounds);
1341 }
1342 path
1343 }
1344 ImplTraitContext::InBinding => {
1345 hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1346 }
1347 ImplTraitContext::FeatureGated(position, feature) => {
1348 let guar = self
1349 .tcx
1350 .sess
1351 .create_feature_err(
1352 MisplacedImplTrait {
1353 span: t.span,
1354 position: DiagArgFromDisplay(&position),
1355 },
1356 feature,
1357 )
1358 .emit();
1359 hir::TyKind::Err(guar)
1360 }
1361 ImplTraitContext::Disallowed(position) => {
1362 let guar = self.dcx().emit_err(MisplacedImplTrait {
1363 span: t.span,
1364 position: DiagArgFromDisplay(&position),
1365 });
1366 hir::TyKind::Err(guar)
1367 }
1368 }
1369 }
1370 TyKind::Pat(ty, pat) => {
1371 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1372 }
1373 TyKind::MacCall(_) => {
1374 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1375 }
1376 TyKind::CVarArgs => {
1377 let guar = self.dcx().span_delayed_bug(
1378 t.span,
1379 "`TyKind::CVarArgs` should have been handled elsewhere",
1380 );
1381 hir::TyKind::Err(guar)
1382 }
1383 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1384 };
1385
1386 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1387 }
1388
1389 fn lower_ty_direct_lifetime(
1390 &mut self,
1391 t: &Ty,
1392 region: Option<Lifetime>,
1393 ) -> &'hir hir::Lifetime {
1394 let (region, syntax) = match region {
1395 Some(region) => (region, region.ident.into()),
1396
1397 None => {
1398 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1399 self.resolver.get_lifetime_res(t.id)
1400 {
1401 debug_assert_eq!(start.plus(1), end);
1402 start
1403 } else {
1404 self.next_node_id()
1405 };
1406 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1407 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1408 (region, LifetimeSyntax::Hidden)
1409 }
1410 };
1411 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1412 }
1413
1414 #[instrument(level = "debug", skip(self), ret)]
1446 fn lower_opaque_impl_trait(
1447 &mut self,
1448 span: Span,
1449 origin: hir::OpaqueTyOrigin<LocalDefId>,
1450 opaque_ty_node_id: NodeId,
1451 bounds: &GenericBounds,
1452 itctx: ImplTraitContext,
1453 ) -> hir::TyKind<'hir> {
1454 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1460
1461 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1462 this.lower_param_bounds(bounds, itctx)
1463 })
1464 }
1465
1466 fn lower_opaque_inner(
1467 &mut self,
1468 opaque_ty_node_id: NodeId,
1469 origin: hir::OpaqueTyOrigin<LocalDefId>,
1470 opaque_ty_span: Span,
1471 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1472 ) -> hir::TyKind<'hir> {
1473 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1474 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1475 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1476
1477 let bounds = lower_item_bounds(self);
1478 let opaque_ty_def = hir::OpaqueTy {
1479 hir_id: opaque_ty_hir_id,
1480 def_id: opaque_ty_def_id,
1481 bounds,
1482 origin,
1483 span: self.lower_span(opaque_ty_span),
1484 };
1485 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1486
1487 hir::TyKind::OpaqueDef(opaque_ty_def)
1488 }
1489
1490 fn lower_precise_capturing_args(
1491 &mut self,
1492 precise_capturing_args: &[PreciseCapturingArg],
1493 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1494 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1495 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1496 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1497 ),
1498 PreciseCapturingArg::Arg(path, id) => {
1499 let [segment] = path.segments.as_slice() else {
1500 panic!();
1501 };
1502 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1503 partial_res.full_res().expect("no partial res expected for precise capture arg")
1504 });
1505 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1506 hir_id: self.lower_node_id(*id),
1507 ident: self.lower_ident(segment.ident),
1508 res: self.lower_res(res),
1509 })
1510 }
1511 }))
1512 }
1513
1514 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1515 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1516 PatKind::Missing => None,
1517 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1518 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1519 _ => {
1520 self.dcx().span_delayed_bug(
1521 param.pat.span,
1522 "non-missing/ident/wild param pat must trigger an error",
1523 );
1524 None
1525 }
1526 }))
1527 }
1528
1529 #[instrument(level = "debug", skip(self))]
1539 fn lower_fn_decl(
1540 &mut self,
1541 decl: &FnDecl,
1542 fn_node_id: NodeId,
1543 fn_span: Span,
1544 kind: FnDeclKind,
1545 coro: Option<CoroutineKind>,
1546 ) -> &'hir hir::FnDecl<'hir> {
1547 let c_variadic = decl.c_variadic();
1548
1549 let mut inputs = &decl.inputs[..];
1553 if c_variadic {
1554 inputs = &inputs[..inputs.len() - 1];
1555 }
1556 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1557 let itctx = match kind {
1558 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1559 ImplTraitContext::Universal
1560 }
1561 FnDeclKind::ExternFn => {
1562 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1563 }
1564 FnDeclKind::Closure => {
1565 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1566 }
1567 FnDeclKind::Pointer => {
1568 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1569 }
1570 };
1571 self.lower_ty_direct(¶m.ty, itctx)
1572 }));
1573
1574 let output = match coro {
1575 Some(coro) => {
1576 let fn_def_id = self.local_def_id(fn_node_id);
1577 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1578 }
1579 None => match &decl.output {
1580 FnRetTy::Ty(ty) => {
1581 let itctx = match kind {
1582 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1583 origin: hir::OpaqueTyOrigin::FnReturn {
1584 parent: self.local_def_id(fn_node_id),
1585 in_trait_or_impl: None,
1586 },
1587 },
1588 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1589 origin: hir::OpaqueTyOrigin::FnReturn {
1590 parent: self.local_def_id(fn_node_id),
1591 in_trait_or_impl: Some(hir::RpitContext::Trait),
1592 },
1593 },
1594 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1595 origin: hir::OpaqueTyOrigin::FnReturn {
1596 parent: self.local_def_id(fn_node_id),
1597 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1598 },
1599 },
1600 FnDeclKind::ExternFn => {
1601 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1602 }
1603 FnDeclKind::Closure => {
1604 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1605 }
1606 FnDeclKind::Pointer => {
1607 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1608 }
1609 };
1610 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1611 }
1612 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1613 },
1614 };
1615
1616 self.arena.alloc(hir::FnDecl {
1617 inputs,
1618 output,
1619 c_variadic,
1620 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1621 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1622 let is_mutable_pat = matches!(
1623 arg.pat.kind,
1624 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1625 );
1626
1627 match &arg.ty.kind {
1628 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1629 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1630 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1634 if mt.ty.kind.is_implicit_self() =>
1635 {
1636 match mt.mutbl {
1637 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1638 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1639 }
1640 }
1641 _ => hir::ImplicitSelfKind::None,
1642 }
1643 }),
1644 })
1645 }
1646
1647 #[instrument(level = "debug", skip(self))]
1656 fn lower_coroutine_fn_ret_ty(
1657 &mut self,
1658 output: &FnRetTy,
1659 fn_def_id: LocalDefId,
1660 coro: CoroutineKind,
1661 fn_kind: FnDeclKind,
1662 fn_span: Span,
1663 ) -> hir::FnRetTy<'hir> {
1664 let span = self.lower_span(fn_span);
1665
1666 let (opaque_ty_node_id, allowed_features) = match coro {
1667 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1668 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1669 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1670 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1671 }
1672 };
1673
1674 let opaque_ty_span =
1675 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1676
1677 let in_trait_or_impl = match fn_kind {
1678 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1679 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1680 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1681 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1682 };
1683
1684 let opaque_ty_ref = self.lower_opaque_inner(
1685 opaque_ty_node_id,
1686 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1687 opaque_ty_span,
1688 |this| {
1689 let bound = this.lower_coroutine_fn_output_type_to_bound(
1690 output,
1691 coro,
1692 opaque_ty_span,
1693 ImplTraitContext::OpaqueTy {
1694 origin: hir::OpaqueTyOrigin::FnReturn {
1695 parent: fn_def_id,
1696 in_trait_or_impl,
1697 },
1698 },
1699 );
1700 arena_vec![this; bound]
1701 },
1702 );
1703
1704 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1705 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1706 }
1707
1708 fn lower_coroutine_fn_output_type_to_bound(
1710 &mut self,
1711 output: &FnRetTy,
1712 coro: CoroutineKind,
1713 opaque_ty_span: Span,
1714 itctx: ImplTraitContext,
1715 ) -> hir::GenericBound<'hir> {
1716 let output_ty = match output {
1718 FnRetTy::Ty(ty) => {
1719 self.lower_ty(ty, itctx)
1723 }
1724 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1725 };
1726
1727 let (assoc_ty_name, trait_lang_item) = match coro {
1729 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1730 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1731 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1732 };
1733
1734 let bound_args = self.arena.alloc(hir::GenericArgs {
1735 args: &[],
1736 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1737 parenthesized: hir::GenericArgsParentheses::No,
1738 span_ext: DUMMY_SP,
1739 });
1740
1741 hir::GenericBound::Trait(hir::PolyTraitRef {
1742 bound_generic_params: &[],
1743 modifiers: hir::TraitBoundModifiers::NONE,
1744 trait_ref: hir::TraitRef {
1745 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1746 hir_ref_id: self.next_id(),
1747 },
1748 span: opaque_ty_span,
1749 })
1750 }
1751
1752 #[instrument(level = "trace", skip(self))]
1753 fn lower_param_bound(
1754 &mut self,
1755 tpb: &GenericBound,
1756 itctx: ImplTraitContext,
1757 ) -> hir::GenericBound<'hir> {
1758 match tpb {
1759 GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1760 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1761 lifetime,
1762 LifetimeSource::OutlivesBound,
1763 lifetime.ident.into(),
1764 )),
1765 GenericBound::Use(args, span) => hir::GenericBound::Use(
1766 self.lower_precise_capturing_args(args),
1767 self.lower_span(*span),
1768 ),
1769 }
1770 }
1771
1772 fn lower_lifetime(
1773 &mut self,
1774 l: &Lifetime,
1775 source: LifetimeSource,
1776 syntax: LifetimeSyntax,
1777 ) -> &'hir hir::Lifetime {
1778 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1779 }
1780
1781 fn lower_lifetime_hidden_in_path(
1782 &mut self,
1783 id: NodeId,
1784 span: Span,
1785 angle_brackets: AngleBrackets,
1786 ) -> &'hir hir::Lifetime {
1787 self.new_named_lifetime(
1788 id,
1789 id,
1790 Ident::new(kw::UnderscoreLifetime, span),
1791 LifetimeSource::Path { angle_brackets },
1792 LifetimeSyntax::Hidden,
1793 )
1794 }
1795
1796 #[instrument(level = "debug", skip(self))]
1797 fn new_named_lifetime(
1798 &mut self,
1799 id: NodeId,
1800 new_id: NodeId,
1801 ident: Ident,
1802 source: LifetimeSource,
1803 syntax: LifetimeSyntax,
1804 ) -> &'hir hir::Lifetime {
1805 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1806 let res = match res {
1807 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1808 LifetimeRes::Fresh { param, .. } => {
1809 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1810 let param = self.local_def_id(param);
1811 hir::LifetimeKind::Param(param)
1812 }
1813 LifetimeRes::Infer => {
1814 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1815 hir::LifetimeKind::Infer
1816 }
1817 LifetimeRes::Static { .. } => {
1818 debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1819 hir::LifetimeKind::Static
1820 }
1821 LifetimeRes::Error => hir::LifetimeKind::Error,
1822 LifetimeRes::ElidedAnchor { .. } => {
1823 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1824 }
1825 };
1826
1827 debug!(?res);
1828 self.arena.alloc(hir::Lifetime::new(
1829 self.lower_node_id(new_id),
1830 self.lower_ident(ident),
1831 res,
1832 source,
1833 syntax,
1834 ))
1835 }
1836
1837 fn lower_generic_params_mut(
1838 &mut self,
1839 params: &[GenericParam],
1840 source: hir::GenericParamSource,
1841 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1842 params.iter().map(move |param| self.lower_generic_param(param, source))
1843 }
1844
1845 fn lower_generic_params(
1846 &mut self,
1847 params: &[GenericParam],
1848 source: hir::GenericParamSource,
1849 ) -> &'hir [hir::GenericParam<'hir>] {
1850 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1851 }
1852
1853 #[instrument(level = "trace", skip(self))]
1854 fn lower_generic_param(
1855 &mut self,
1856 param: &GenericParam,
1857 source: hir::GenericParamSource,
1858 ) -> hir::GenericParam<'hir> {
1859 let (name, kind) = self.lower_generic_param_kind(param, source);
1860
1861 let hir_id = self.lower_node_id(param.id);
1862 self.lower_attrs(hir_id, ¶m.attrs, param.span());
1863 hir::GenericParam {
1864 hir_id,
1865 def_id: self.local_def_id(param.id),
1866 name,
1867 span: self.lower_span(param.span()),
1868 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1869 kind,
1870 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1871 source,
1872 }
1873 }
1874
1875 fn lower_generic_param_kind(
1876 &mut self,
1877 param: &GenericParam,
1878 source: hir::GenericParamSource,
1879 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1880 match ¶m.kind {
1881 GenericParamKind::Lifetime => {
1882 let ident = self.lower_ident(param.ident);
1885 let param_name =
1886 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1887 ParamName::Error(ident)
1888 } else {
1889 ParamName::Plain(ident)
1890 };
1891 let kind =
1892 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1893
1894 (param_name, kind)
1895 }
1896 GenericParamKind::Type { default, .. } => {
1897 let default = default
1900 .as_ref()
1901 .filter(|_| match source {
1902 hir::GenericParamSource::Generics => true,
1903 hir::GenericParamSource::Binder => {
1904 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1905 span: param.span(),
1906 });
1907
1908 false
1909 }
1910 })
1911 .map(|def| {
1912 self.lower_ty(
1913 def,
1914 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1915 )
1916 });
1917
1918 let kind = hir::GenericParamKind::Type { default, synthetic: false };
1919
1920 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1921 }
1922 GenericParamKind::Const { ty, kw_span: _, default } => {
1923 let ty = self
1924 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1925
1926 let default = default
1929 .as_ref()
1930 .filter(|_| match source {
1931 hir::GenericParamSource::Generics => true,
1932 hir::GenericParamSource::Binder => {
1933 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1934 span: param.span(),
1935 });
1936
1937 false
1938 }
1939 })
1940 .map(|def| self.lower_anon_const_to_const_arg(def));
1941
1942 (
1943 hir::ParamName::Plain(self.lower_ident(param.ident)),
1944 hir::GenericParamKind::Const { ty, default, synthetic: false },
1945 )
1946 }
1947 }
1948 }
1949
1950 fn lower_trait_ref(
1951 &mut self,
1952 modifiers: ast::TraitBoundModifiers,
1953 p: &TraitRef,
1954 itctx: ImplTraitContext,
1955 ) -> hir::TraitRef<'hir> {
1956 let path = match self.lower_qpath(
1957 p.ref_id,
1958 &None,
1959 &p.path,
1960 ParamMode::Explicit,
1961 AllowReturnTypeNotation::No,
1962 itctx,
1963 Some(modifiers),
1964 ) {
1965 hir::QPath::Resolved(None, path) => path,
1966 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
1967 };
1968 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1969 }
1970
1971 #[instrument(level = "debug", skip(self))]
1972 fn lower_poly_trait_ref(
1973 &mut self,
1974 p: &PolyTraitRef,
1975 itctx: ImplTraitContext,
1976 ) -> hir::PolyTraitRef<'hir> {
1977 let bound_generic_params =
1978 self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
1979 let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
1980 let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
1981 hir::PolyTraitRef {
1982 bound_generic_params,
1983 modifiers,
1984 trait_ref,
1985 span: self.lower_span(p.span),
1986 }
1987 }
1988
1989 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1990 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1991 }
1992
1993 #[instrument(level = "debug", skip(self), ret)]
1994 fn lower_param_bounds(
1995 &mut self,
1996 bounds: &[GenericBound],
1997 itctx: ImplTraitContext,
1998 ) -> hir::GenericBounds<'hir> {
1999 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2000 }
2001
2002 fn lower_param_bounds_mut(
2003 &mut self,
2004 bounds: &[GenericBound],
2005 itctx: ImplTraitContext,
2006 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2007 bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2008 }
2009
2010 #[instrument(level = "debug", skip(self), ret)]
2011 fn lower_universal_param_and_bounds(
2012 &mut self,
2013 node_id: NodeId,
2014 span: Span,
2015 ident: Ident,
2016 bounds: &[GenericBound],
2017 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2018 let def_id = self.local_def_id(node_id);
2020 let span = self.lower_span(span);
2021
2022 let param = hir::GenericParam {
2024 hir_id: self.lower_node_id(node_id),
2025 def_id,
2026 name: ParamName::Plain(self.lower_ident(ident)),
2027 pure_wrt_drop: false,
2028 span,
2029 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2030 colon_span: None,
2031 source: hir::GenericParamSource::Generics,
2032 };
2033
2034 let preds = self.lower_generic_bound_predicate(
2035 ident,
2036 node_id,
2037 &GenericParamKind::Type { default: None },
2038 bounds,
2039 None,
2040 span,
2041 ImplTraitContext::Universal,
2042 hir::PredicateOrigin::ImplTrait,
2043 );
2044
2045 let hir_id = self.next_id();
2046 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2047 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2048 None,
2049 self.arena.alloc(hir::Path {
2050 span,
2051 res,
2052 segments:
2053 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2054 }),
2055 ));
2056
2057 (param, preds, ty)
2058 }
2059
2060 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2063 let block = self.lower_block(b, false);
2064 self.expr_block(block)
2065 }
2066
2067 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2068 match c.value.peel_parens().kind {
2071 ExprKind::Underscore => {
2072 if !self.tcx.features().generic_arg_infer() {
2073 feature_err(
2074 &self.tcx.sess,
2075 sym::generic_arg_infer,
2076 c.value.span,
2077 fluent_generated::ast_lowering_underscore_array_length_unstable,
2078 )
2079 .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2080 }
2081 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2082 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2083 }
2084 _ => self.lower_anon_const_to_const_arg(c),
2085 }
2086 }
2087
2088 #[instrument(level = "debug", skip(self))]
2092 fn lower_const_path_to_const_arg(
2093 &mut self,
2094 path: &Path,
2095 res: Res<NodeId>,
2096 ty_id: NodeId,
2097 span: Span,
2098 ) -> &'hir hir::ConstArg<'hir> {
2099 let tcx = self.tcx;
2100
2101 let ct_kind = if path
2102 .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2103 && (tcx.features().min_generic_const_args()
2104 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2105 {
2106 let qpath = self.lower_qpath(
2107 ty_id,
2108 &None,
2109 path,
2110 ParamMode::Optional,
2111 AllowReturnTypeNotation::No,
2112 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2114 None,
2115 );
2116 hir::ConstArgKind::Path(qpath)
2117 } else {
2118 let node_id = self.next_node_id();
2120 let span = self.lower_span(span);
2121
2122 let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2127 let hir_id = self.lower_node_id(node_id);
2128
2129 let path_expr = Expr {
2130 id: ty_id,
2131 kind: ExprKind::Path(None, path.clone()),
2132 span,
2133 attrs: AttrVec::new(),
2134 tokens: None,
2135 };
2136
2137 let ct = self.with_new_scopes(span, |this| {
2138 self.arena.alloc(hir::AnonConst {
2139 def_id,
2140 hir_id,
2141 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2142 span,
2143 })
2144 });
2145 hir::ConstArgKind::Anon(ct)
2146 };
2147
2148 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2149 }
2150
2151 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2154 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2155 }
2156
2157 #[instrument(level = "debug", skip(self))]
2158 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2159 let tcx = self.tcx;
2160 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2163 && let [stmt] = block.stmts.as_slice()
2164 && let StmtKind::Expr(expr) = &stmt.kind
2165 && let ExprKind::Path(..) = &expr.kind
2166 {
2167 expr
2168 } else {
2169 &anon.value
2170 };
2171 let maybe_res =
2172 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2173 if let ExprKind::Path(qself, path) = &expr.kind
2174 && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2175 && (tcx.features().min_generic_const_args()
2176 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2177 {
2178 let qpath = self.lower_qpath(
2179 expr.id,
2180 qself,
2181 path,
2182 ParamMode::Optional,
2183 AllowReturnTypeNotation::No,
2184 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2186 None,
2187 );
2188
2189 return ConstArg {
2190 hir_id: self.lower_node_id(anon.id),
2191 kind: hir::ConstArgKind::Path(qpath),
2192 };
2193 }
2194
2195 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2196 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2197 }
2198
2199 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2202 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2203 let def_id = this.local_def_id(c.id);
2204 let hir_id = this.lower_node_id(c.id);
2205 hir::AnonConst {
2206 def_id,
2207 hir_id,
2208 body: this.lower_const_body(c.value.span, Some(&c.value)),
2209 span: this.lower_span(c.value.span),
2210 }
2211 }))
2212 }
2213
2214 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2215 match u {
2216 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2217 UserProvided => hir::UnsafeSource::UserProvided,
2218 }
2219 }
2220
2221 fn lower_trait_bound_modifiers(
2222 &mut self,
2223 modifiers: TraitBoundModifiers,
2224 ) -> hir::TraitBoundModifiers {
2225 hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2226 }
2227
2228 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2231 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2232 }
2233
2234 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2235 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2236 }
2237
2238 fn stmt_let_pat(
2239 &mut self,
2240 attrs: Option<&'hir [hir::Attribute]>,
2241 span: Span,
2242 init: Option<&'hir hir::Expr<'hir>>,
2243 pat: &'hir hir::Pat<'hir>,
2244 source: hir::LocalSource,
2245 ) -> hir::Stmt<'hir> {
2246 let hir_id = self.next_id();
2247 if let Some(a) = attrs {
2248 debug_assert!(!a.is_empty());
2249 self.attrs.insert(hir_id.local_id, a);
2250 }
2251 let local = hir::LetStmt {
2252 super_: None,
2253 hir_id,
2254 init,
2255 pat,
2256 els: None,
2257 source,
2258 span: self.lower_span(span),
2259 ty: None,
2260 };
2261 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2262 }
2263
2264 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2265 self.block_all(expr.span, &[], Some(expr))
2266 }
2267
2268 fn block_all(
2269 &mut self,
2270 span: Span,
2271 stmts: &'hir [hir::Stmt<'hir>],
2272 expr: Option<&'hir hir::Expr<'hir>>,
2273 ) -> &'hir hir::Block<'hir> {
2274 let blk = hir::Block {
2275 stmts,
2276 expr,
2277 hir_id: self.next_id(),
2278 rules: hir::BlockCheckMode::DefaultBlock,
2279 span: self.lower_span(span),
2280 targeted_by_break: false,
2281 };
2282 self.arena.alloc(blk)
2283 }
2284
2285 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2286 let field = self.single_pat_field(span, pat);
2287 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2288 }
2289
2290 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2291 let field = self.single_pat_field(span, pat);
2292 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2293 }
2294
2295 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2296 let field = self.single_pat_field(span, pat);
2297 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2298 }
2299
2300 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2301 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2302 }
2303
2304 fn single_pat_field(
2305 &mut self,
2306 span: Span,
2307 pat: &'hir hir::Pat<'hir>,
2308 ) -> &'hir [hir::PatField<'hir>] {
2309 let field = hir::PatField {
2310 hir_id: self.next_id(),
2311 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2312 is_shorthand: false,
2313 pat,
2314 span: self.lower_span(span),
2315 };
2316 arena_vec![self; field]
2317 }
2318
2319 fn pat_lang_item_variant(
2320 &mut self,
2321 span: Span,
2322 lang_item: hir::LangItem,
2323 fields: &'hir [hir::PatField<'hir>],
2324 ) -> &'hir hir::Pat<'hir> {
2325 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2326 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2327 }
2328
2329 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2330 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2331 }
2332
2333 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2334 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2335 }
2336
2337 fn pat_ident_binding_mode(
2338 &mut self,
2339 span: Span,
2340 ident: Ident,
2341 bm: hir::BindingMode,
2342 ) -> (&'hir hir::Pat<'hir>, HirId) {
2343 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2344 (self.arena.alloc(pat), hir_id)
2345 }
2346
2347 fn pat_ident_binding_mode_mut(
2348 &mut self,
2349 span: Span,
2350 ident: Ident,
2351 bm: hir::BindingMode,
2352 ) -> (hir::Pat<'hir>, HirId) {
2353 let hir_id = self.next_id();
2354
2355 (
2356 hir::Pat {
2357 hir_id,
2358 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2359 span: self.lower_span(span),
2360 default_binding_modes: true,
2361 },
2362 hir_id,
2363 )
2364 }
2365
2366 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2367 self.arena.alloc(hir::Pat {
2368 hir_id: self.next_id(),
2369 kind,
2370 span: self.lower_span(span),
2371 default_binding_modes: true,
2372 })
2373 }
2374
2375 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2376 hir::Pat {
2377 hir_id: self.next_id(),
2378 kind,
2379 span: self.lower_span(span),
2380 default_binding_modes: false,
2381 }
2382 }
2383
2384 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2385 let kind = match qpath {
2386 hir::QPath::Resolved(None, path) => {
2387 match path.res {
2389 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2390 let principal = hir::PolyTraitRef {
2391 bound_generic_params: &[],
2392 modifiers: hir::TraitBoundModifiers::NONE,
2393 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2394 span: self.lower_span(span),
2395 };
2396
2397 hir_id = self.next_id();
2400 hir::TyKind::TraitObject(
2401 arena_vec![self; principal],
2402 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2403 )
2404 }
2405 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2406 }
2407 }
2408 _ => hir::TyKind::Path(qpath),
2409 };
2410
2411 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2412 }
2413
2414 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2419 let r = hir::Lifetime::new(
2420 self.next_id(),
2421 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2422 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2423 LifetimeSource::Other,
2424 LifetimeSyntax::Hidden,
2425 );
2426 debug!("elided_dyn_bound: r={:?}", r);
2427 self.arena.alloc(r)
2428 }
2429}
2430
2431struct GenericArgsCtor<'hir> {
2433 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2434 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2435 parenthesized: hir::GenericArgsParentheses,
2436 span: Span,
2437}
2438
2439impl<'hir> GenericArgsCtor<'hir> {
2440 fn is_empty(&self) -> bool {
2441 self.args.is_empty()
2442 && self.constraints.is_empty()
2443 && self.parenthesized == hir::GenericArgsParentheses::No
2444 }
2445
2446 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2447 let ga = hir::GenericArgs {
2448 args: this.arena.alloc_from_iter(self.args),
2449 constraints: self.constraints,
2450 parenthesized: self.parenthesized,
2451 span_ext: this.lower_span(self.span),
2452 };
2453 this.arena.alloc(ga)
2454 }
2455}