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