1#![feature(box_patterns)]
35#![feature(if_let_guard)]
36use std::mem;
39use std::sync::Arc;
40
41use rustc_ast::node_id::NodeMap;
42use rustc_ast::{self as ast, *};
43use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
44use rustc_data_structures::fingerprint::Fingerprint;
45use rustc_data_structures::sorted_map::SortedMap;
46use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
47use rustc_data_structures::sync::spawn;
48use rustc_data_structures::tagged_ptr::TaggedRef;
49use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};
50use rustc_hir::attrs::AttributeKind;
51use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
52use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
53use rustc_hir::definitions::{DefPathData, DisambiguatorState};
54use rustc_hir::lints::DelayedLint;
55use rustc_hir::{
56 self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
57 LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,
58};
59use rustc_index::{Idx, IndexSlice, IndexVec};
60use rustc_macros::extension;
61use rustc_middle::span_bug;
62use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
63use rustc_session::parse::add_feature_diagnostics;
64use rustc_span::symbol::{Ident, Symbol, kw, sym};
65use rustc_span::{DUMMY_SP, DesugaringKind, Span};
66use smallvec::SmallVec;
67use thin_vec::ThinVec;
68use tracing::{debug, instrument, trace};
69
70use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
71
72macro_rules! arena_vec {
73 ($this:expr; $($x:expr),*) => (
74 $this.arena.alloc_from_iter([$($x),*])
75 );
76}
77
78mod asm;
79mod block;
80mod contract;
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 disambiguator: DisambiguatorState,
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 try_block_scope: TryBlockScope,
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_contracts: Arc<[Symbol]>,
141 allow_try_trait: Arc<[Symbol]>,
142 allow_gen_future: Arc<[Symbol]>,
143 allow_pattern_type: Arc<[Symbol]>,
144 allow_async_gen: Arc<[Symbol]>,
145 allow_async_iterator: Arc<[Symbol]>,
146 allow_for_await: Arc<[Symbol]>,
147 allow_async_fn_traits: Arc<[Symbol]>,
148
149 delayed_lints: Vec<DelayedLint>,
150
151 attribute_parser: AttributeParser<'hir>,
152}
153
154impl<'a, 'hir> LoweringContext<'a, 'hir> {
155 fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
156 let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
157 Self {
158 tcx,
160 resolver,
161 disambiguator: DisambiguatorState::new(),
162 arena: tcx.hir_arena,
163
164 bodies: Vec::new(),
166 define_opaque: None,
167 attrs: SortedMap::default(),
168 children: Vec::default(),
169 contract_ensures: None,
170 current_hir_id_owner: hir::CRATE_OWNER_ID,
171 item_local_id_counter: hir::ItemLocalId::ZERO,
172 ident_and_label_to_local_id: Default::default(),
173 #[cfg(debug_assertions)]
174 node_id_to_local_id: Default::default(),
175 trait_map: Default::default(),
176
177 try_block_scope: TryBlockScope::Function,
179 loop_scope: None,
180 is_in_loop_condition: false,
181 is_in_dyn_type: false,
182 coroutine_kind: None,
183 task_context: None,
184 current_item: None,
185 impl_trait_defs: Vec::new(),
186 impl_trait_bounds: Vec::new(),
187 allow_contracts: [sym::contracts_internals].into(),
188 allow_try_trait: [
189 sym::try_trait_v2,
190 sym::try_trait_v2_residual,
191 sym::yeet_desugar_details,
192 ]
193 .into(),
194 allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
195 allow_gen_future: if tcx.features().async_fn_track_caller() {
196 [sym::gen_future, sym::closure_track_caller].into()
197 } else {
198 [sym::gen_future].into()
199 },
200 allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),
201 allow_async_fn_traits: [sym::async_fn_traits].into(),
202 allow_async_gen: [sym::async_gen_internals].into(),
203 allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
206
207 attribute_parser: AttributeParser::new(
208 tcx.sess,
209 tcx.features(),
210 registered_tools,
211 Late,
212 ),
213 delayed_lints: Vec::new(),
214 }
215 }
216
217 pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
218 self.tcx.dcx()
219 }
220}
221
222struct SpanLowerer {
223 is_incremental: bool,
224 def_id: LocalDefId,
225}
226
227impl SpanLowerer {
228 fn lower(&self, span: Span) -> Span {
229 if self.is_incremental {
230 span.with_parent(Some(self.def_id))
231 } else {
232 span
234 }
235 }
236}
237
238#[extension(trait ResolverAstLoweringExt)]
239impl ResolverAstLowering {
240 fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'_>) -> Option<Vec<usize>> {
241 let ExprKind::Path(None, path) = &expr.kind else {
242 return None;
243 };
244
245 if path.segments.last().unwrap().args.is_some() {
248 return None;
249 }
250
251 let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;
252
253 if def_id.is_local() {
257 return None;
258 }
259
260 find_attr!(
261 tcx.get_all_attrs(def_id),
263 AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes
264 )
265 .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())
266 }
267
268 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
269 self.partial_res_map.get(&id).copied()
270 }
271
272 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
274 self.import_res_map.get(&id).copied().unwrap_or_default()
275 }
276
277 fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
279 self.label_res_map.get(&id).copied()
280 }
281
282 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
284 self.lifetimes_res_map.get(&id).copied()
285 }
286
287 fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
295 self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
296 }
297}
298
299#[derive(Clone, Copy, Debug)]
304enum RelaxedBoundPolicy<'a> {
305 Allowed,
306 AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),
307 Forbidden(RelaxedBoundForbiddenReason),
308}
309
310#[derive(Clone, Copy, Debug)]
311enum RelaxedBoundForbiddenReason {
312 TraitObjectTy,
313 SuperTrait,
314 TraitAlias,
315 AssocTyBounds,
316 LateBoundVarsInScope,
317}
318
319#[derive(Debug, Copy, Clone, PartialEq, Eq)]
322enum ImplTraitContext {
323 Universal,
329
330 OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
335
336 InBinding,
341
342 FeatureGated(ImplTraitPosition, Symbol),
344 Disallowed(ImplTraitPosition),
346}
347
348#[derive(Debug, Copy, Clone, PartialEq, Eq)]
350enum ImplTraitPosition {
351 Path,
352 Variable,
353 Trait,
354 Bound,
355 Generic,
356 ExternFnParam,
357 ClosureParam,
358 PointerParam,
359 FnTraitParam,
360 ExternFnReturn,
361 ClosureReturn,
362 PointerReturn,
363 FnTraitReturn,
364 GenericDefault,
365 ConstTy,
366 StaticTy,
367 AssocTy,
368 FieldTy,
369 Cast,
370 ImplSelf,
371 OffsetOf,
372}
373
374impl std::fmt::Display for ImplTraitPosition {
375 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376 let name = match self {
377 ImplTraitPosition::Path => "paths",
378 ImplTraitPosition::Variable => "the type of variable bindings",
379 ImplTraitPosition::Trait => "traits",
380 ImplTraitPosition::Bound => "bounds",
381 ImplTraitPosition::Generic => "generics",
382 ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
383 ImplTraitPosition::ClosureParam => "closure parameters",
384 ImplTraitPosition::PointerParam => "`fn` pointer parameters",
385 ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
386 ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
387 ImplTraitPosition::ClosureReturn => "closure return types",
388 ImplTraitPosition::PointerReturn => "`fn` pointer return types",
389 ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
390 ImplTraitPosition::GenericDefault => "generic parameter defaults",
391 ImplTraitPosition::ConstTy => "const types",
392 ImplTraitPosition::StaticTy => "static types",
393 ImplTraitPosition::AssocTy => "associated types",
394 ImplTraitPosition::FieldTy => "field types",
395 ImplTraitPosition::Cast => "cast expression types",
396 ImplTraitPosition::ImplSelf => "impl headers",
397 ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
398 };
399
400 write!(f, "{name}")
401 }
402}
403
404#[derive(Copy, Clone, Debug, PartialEq, Eq)]
405enum FnDeclKind {
406 Fn,
407 Inherent,
408 ExternFn,
409 Closure,
410 Pointer,
411 Trait,
412 Impl,
413}
414
415#[derive(Copy, Clone)]
416enum AstOwner<'a> {
417 NonOwner,
418 Crate(&'a ast::Crate),
419 Item(&'a ast::Item),
420 AssocItem(&'a ast::AssocItem, visit::AssocCtxt),
421 ForeignItem(&'a ast::ForeignItem),
422}
423
424#[derive(Copy, Clone, Debug)]
425enum TryBlockScope {
426 Function,
428 Homogeneous(HirId),
431 Heterogeneous(HirId),
434}
435
436fn index_crate<'a>(
437 node_id_to_def_id: &NodeMap<LocalDefId>,
438 krate: &'a Crate,
439) -> IndexVec<LocalDefId, AstOwner<'a>> {
440 let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
441 *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
442 AstOwner::Crate(krate);
443 visit::walk_crate(&mut indexer, krate);
444 return indexer.index;
445
446 struct Indexer<'s, 'a> {
447 node_id_to_def_id: &'s NodeMap<LocalDefId>,
448 index: IndexVec<LocalDefId, AstOwner<'a>>,
449 }
450
451 impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> {
452 fn visit_attribute(&mut self, _: &'a Attribute) {
453 }
456
457 fn visit_item(&mut self, item: &'a ast::Item) {
458 let def_id = self.node_id_to_def_id[&item.id];
459 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
460 visit::walk_item(self, item)
461 }
462
463 fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
464 let def_id = self.node_id_to_def_id[&item.id];
465 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
466 AstOwner::AssocItem(item, ctxt);
467 visit::walk_assoc_item(self, item, ctxt);
468 }
469
470 fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
471 let def_id = self.node_id_to_def_id[&item.id];
472 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
473 AstOwner::ForeignItem(item);
474 visit::walk_item(self, item);
475 }
476 }
477}
478
479fn compute_hir_hash(
482 tcx: TyCtxt<'_>,
483 owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
484) -> Fingerprint {
485 let mut hir_body_nodes: Vec<_> = owners
486 .iter_enumerated()
487 .filter_map(|(def_id, info)| {
488 let info = info.as_owner()?;
489 let def_path_hash = tcx.hir_def_path_hash(def_id);
490 Some((def_path_hash, info))
491 })
492 .collect();
493 hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
494
495 tcx.with_stable_hashing_context(|mut hcx| {
496 let mut stable_hasher = StableHasher::new();
497 hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
498 stable_hasher.finish()
499 })
500}
501
502pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
503 let sess = tcx.sess;
504 tcx.ensure_done().output_filenames(());
506 tcx.ensure_done().early_lint_checks(());
507 tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
508 tcx.ensure_done().get_lang_items(());
509 let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
510
511 let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
512 let mut owners = IndexVec::from_fn_n(
513 |_| hir::MaybeOwner::Phantom,
514 tcx.definitions_untracked().def_index_count(),
515 );
516
517 let mut lowerer = item::ItemLowerer {
518 tcx,
519 resolver: &mut resolver,
520 ast_index: &ast_index,
521 owners: &mut owners,
522 };
523 for def_id in ast_index.indices() {
524 lowerer.lower_node(def_id);
525 }
526
527 drop(ast_index);
528
529 let prof = sess.prof.clone();
531 spawn(move || {
532 let _timer = prof.verbose_generic_activity("drop_ast");
533 drop(krate);
534 });
535
536 let opt_hir_hash =
538 if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
539 hir::Crate { owners, opt_hir_hash }
540}
541
542#[derive(Copy, Clone, PartialEq, Debug)]
543enum ParamMode {
544 Explicit,
546 Optional,
548}
549
550#[derive(Copy, Clone, Debug)]
551enum AllowReturnTypeNotation {
552 Yes,
554 No,
556}
557
558enum GenericArgsMode {
559 ParenSugar,
561 ReturnTypeNotation,
563 Err,
565 Silence,
567}
568
569impl<'a, 'hir> LoweringContext<'a, 'hir> {
570 fn create_def(
571 &mut self,
572 node_id: ast::NodeId,
573 name: Option<Symbol>,
574 def_kind: DefKind,
575 def_path_data: DefPathData,
576 span: Span,
577 ) -> LocalDefId {
578 let parent = self.current_hir_id_owner.def_id;
579 assert_ne!(node_id, ast::DUMMY_NODE_ID);
580 assert!(
581 self.opt_local_def_id(node_id).is_none(),
582 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
583 node_id,
584 def_kind,
585 self.tcx.hir_def_key(self.local_def_id(node_id)),
586 );
587
588 let def_id = self
589 .tcx
590 .at(span)
591 .create_def(parent, name, def_kind, Some(def_path_data), &mut self.disambiguator)
592 .def_id();
593
594 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
595 self.resolver.node_id_to_def_id.insert(node_id, def_id);
596
597 def_id
598 }
599
600 fn next_node_id(&mut self) -> NodeId {
601 let start = self.resolver.next_node_id;
602 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
603 self.resolver.next_node_id = ast::NodeId::from_u32(next);
604 start
605 }
606
607 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
610 self.resolver.node_id_to_def_id.get(&node).copied()
611 }
612
613 fn local_def_id(&self, node: NodeId) -> LocalDefId {
614 self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
615 }
616
617 fn owner_id(&self, node: NodeId) -> hir::OwnerId {
619 hir::OwnerId { def_id: self.local_def_id(node) }
620 }
621
622 #[instrument(level = "debug", skip(self, f))]
628 fn with_hir_id_owner(
629 &mut self,
630 owner: NodeId,
631 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
632 ) {
633 let owner_id = self.owner_id(owner);
634
635 let current_attrs = std::mem::take(&mut self.attrs);
636 let current_bodies = std::mem::take(&mut self.bodies);
637 let current_define_opaque = std::mem::take(&mut self.define_opaque);
638 let current_ident_and_label_to_local_id =
639 std::mem::take(&mut self.ident_and_label_to_local_id);
640
641 #[cfg(debug_assertions)]
642 let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
643 let current_trait_map = std::mem::take(&mut self.trait_map);
644 let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);
645 let current_local_counter =
646 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
647 let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
648 let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
649 let current_delayed_lints = std::mem::take(&mut self.delayed_lints);
650
651 #[cfg(debug_assertions)]
657 {
658 let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
659 debug_assert_eq!(_old, None);
660 }
661
662 let item = f(self);
663 assert_eq!(owner_id, item.def_id());
664 assert!(self.impl_trait_defs.is_empty());
666 assert!(self.impl_trait_bounds.is_empty());
667 let info = self.make_owner_info(item);
668
669 self.attrs = current_attrs;
670 self.bodies = current_bodies;
671 self.define_opaque = current_define_opaque;
672 self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
673
674 #[cfg(debug_assertions)]
675 {
676 self.node_id_to_local_id = current_node_id_to_local_id;
677 }
678 self.trait_map = current_trait_map;
679 self.current_hir_id_owner = current_owner;
680 self.item_local_id_counter = current_local_counter;
681 self.impl_trait_defs = current_impl_trait_defs;
682 self.impl_trait_bounds = current_impl_trait_bounds;
683 self.delayed_lints = current_delayed_lints;
684
685 debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
686 self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
687 }
688
689 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
690 let attrs = std::mem::take(&mut self.attrs);
691 let mut bodies = std::mem::take(&mut self.bodies);
692 let define_opaque = std::mem::take(&mut self.define_opaque);
693 let trait_map = std::mem::take(&mut self.trait_map);
694 let delayed_lints = std::mem::take(&mut self.delayed_lints).into_boxed_slice();
695
696 #[cfg(debug_assertions)]
697 for (id, attrs) in attrs.iter() {
698 if attrs.is_empty() {
700 panic!("Stored empty attributes for {:?}", id);
701 }
702 }
703
704 bodies.sort_by_key(|(k, _)| *k);
705 let bodies = SortedMap::from_presorted_elements(bodies);
706
707 let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash, delayed_lints_hash } =
709 self.tcx.hash_owner_nodes(node, &bodies, &attrs, &delayed_lints, define_opaque);
710 let num_nodes = self.item_local_id_counter.as_usize();
711 let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
712 let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
713 let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
714 let delayed_lints =
715 hir::lints::DelayedLints { lints: delayed_lints, opt_hash: delayed_lints_hash };
716
717 self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints })
718 }
719
720 #[instrument(level = "debug", skip(self), ret)]
726 fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
727 assert_ne!(ast_node_id, DUMMY_NODE_ID);
728
729 let owner = self.current_hir_id_owner;
730 let local_id = self.item_local_id_counter;
731 assert_ne!(local_id, hir::ItemLocalId::ZERO);
732 self.item_local_id_counter.increment_by(1);
733 let hir_id = HirId { owner, local_id };
734
735 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
736 self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
737 }
738
739 if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
740 self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
741 }
742
743 #[cfg(debug_assertions)]
745 {
746 let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
747 assert_eq!(old, None);
748 }
749
750 hir_id
751 }
752
753 #[instrument(level = "debug", skip(self), ret)]
755 fn next_id(&mut self) -> HirId {
756 let owner = self.current_hir_id_owner;
757 let local_id = self.item_local_id_counter;
758 assert_ne!(local_id, hir::ItemLocalId::ZERO);
759 self.item_local_id_counter.increment_by(1);
760 HirId { owner, local_id }
761 }
762
763 #[instrument(level = "trace", skip(self))]
764 fn lower_res(&mut self, res: Res<NodeId>) -> Res {
765 let res: Result<Res, ()> = res.apply_id(|id| {
766 let owner = self.current_hir_id_owner;
767 let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
768 Ok(HirId { owner, local_id })
769 });
770 trace!(?res);
771
772 res.unwrap_or(Res::Err)
778 }
779
780 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
781 self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
782 }
783
784 fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {
785 let per_ns = self.resolver.get_import_res(id);
786 let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));
787 if per_ns.is_empty() {
788 self.dcx().span_delayed_bug(span, "no resolution for an import");
790 let err = Some(Res::Err);
791 return PerNS { type_ns: err, value_ns: err, macro_ns: err };
792 }
793 per_ns
794 }
795
796 fn make_lang_item_qpath(
797 &mut self,
798 lang_item: hir::LangItem,
799 span: Span,
800 args: Option<&'hir hir::GenericArgs<'hir>>,
801 ) -> hir::QPath<'hir> {
802 hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
803 }
804
805 fn make_lang_item_path(
806 &mut self,
807 lang_item: hir::LangItem,
808 span: Span,
809 args: Option<&'hir hir::GenericArgs<'hir>>,
810 ) -> &'hir hir::Path<'hir> {
811 let def_id = self.tcx.require_lang_item(lang_item, span);
812 let def_kind = self.tcx.def_kind(def_id);
813 let res = Res::Def(def_kind, def_id);
814 self.arena.alloc(hir::Path {
815 span,
816 res,
817 segments: self.arena.alloc_from_iter([hir::PathSegment {
818 ident: Ident::new(lang_item.name(), span),
819 hir_id: self.next_id(),
820 res,
821 args,
822 infer_args: args.is_none(),
823 }]),
824 })
825 }
826
827 fn mark_span_with_reason(
830 &self,
831 reason: DesugaringKind,
832 span: Span,
833 allow_internal_unstable: Option<Arc<[Symbol]>>,
834 ) -> Span {
835 self.tcx.with_stable_hashing_context(|hcx| {
836 span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
837 })
838 }
839
840 fn span_lowerer(&self) -> SpanLowerer {
841 SpanLowerer {
842 is_incremental: self.tcx.sess.opts.incremental.is_some(),
843 def_id: self.current_hir_id_owner.def_id,
844 }
845 }
846
847 fn lower_span(&self, span: Span) -> Span {
850 self.span_lowerer().lower(span)
851 }
852
853 fn lower_ident(&self, ident: Ident) -> Ident {
854 Ident::new(ident.name, self.lower_span(ident.span))
855 }
856
857 #[instrument(level = "debug", skip(self))]
859 fn lifetime_res_to_generic_param(
860 &mut self,
861 ident: Ident,
862 node_id: NodeId,
863 res: LifetimeRes,
864 source: hir::GenericParamSource,
865 ) -> Option<hir::GenericParam<'hir>> {
866 let (name, kind) = match res {
867 LifetimeRes::Param { .. } => {
868 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
869 }
870 LifetimeRes::Fresh { param, kind, .. } => {
871 let _def_id = self.create_def(
873 param,
874 Some(kw::UnderscoreLifetime),
875 DefKind::LifetimeParam,
876 DefPathData::DesugaredAnonymousLifetime,
877 ident.span,
878 );
879 debug!(?_def_id);
880
881 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
882 }
883 LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
884 res => panic!(
885 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
886 res, ident, ident.span
887 ),
888 };
889 let hir_id = self.lower_node_id(node_id);
890 let def_id = self.local_def_id(node_id);
891 Some(hir::GenericParam {
892 hir_id,
893 def_id,
894 name,
895 span: self.lower_span(ident.span),
896 pure_wrt_drop: false,
897 kind: hir::GenericParamKind::Lifetime { kind },
898 colon_span: None,
899 source,
900 })
901 }
902
903 #[instrument(level = "debug", skip(self), ret)]
909 #[inline]
910 fn lower_lifetime_binder(
911 &mut self,
912 binder: NodeId,
913 generic_params: &[GenericParam],
914 ) -> &'hir [hir::GenericParam<'hir>] {
915 let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
918 debug!(?extra_lifetimes);
919 let extra_lifetimes: Vec<_> = extra_lifetimes
920 .into_iter()
921 .filter_map(|(ident, node_id, res)| {
922 self.lifetime_res_to_generic_param(
923 ident,
924 node_id,
925 res,
926 hir::GenericParamSource::Binder,
927 )
928 })
929 .collect();
930 let arena = self.arena;
931 let explicit_generic_params =
932 self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);
933 arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))
934 }
935
936 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
937 let was_in_dyn_type = self.is_in_dyn_type;
938 self.is_in_dyn_type = in_scope;
939
940 let result = f(self);
941
942 self.is_in_dyn_type = was_in_dyn_type;
943
944 result
945 }
946
947 fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
948 let current_item = self.current_item;
949 self.current_item = Some(scope_span);
950
951 let was_in_loop_condition = self.is_in_loop_condition;
952 self.is_in_loop_condition = false;
953
954 let old_contract = self.contract_ensures.take();
955
956 let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);
957 let loop_scope = self.loop_scope.take();
958 let ret = f(self);
959 self.try_block_scope = try_block_scope;
960 self.loop_scope = loop_scope;
961
962 self.contract_ensures = old_contract;
963
964 self.is_in_loop_condition = was_in_loop_condition;
965
966 self.current_item = current_item;
967
968 ret
969 }
970
971 fn lower_attrs(
972 &mut self,
973 id: HirId,
974 attrs: &[Attribute],
975 target_span: Span,
976 target: Target,
977 ) -> &'hir [hir::Attribute] {
978 self.lower_attrs_with_extra(id, attrs, target_span, target, &[])
979 }
980
981 fn lower_attrs_with_extra(
982 &mut self,
983 id: HirId,
984 attrs: &[Attribute],
985 target_span: Span,
986 target: Target,
987 extra_hir_attributes: &[hir::Attribute],
988 ) -> &'hir [hir::Attribute] {
989 if attrs.is_empty() && extra_hir_attributes.is_empty() {
990 &[]
991 } else {
992 let mut lowered_attrs =
993 self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);
994 lowered_attrs.extend(extra_hir_attributes.iter().cloned());
995
996 assert_eq!(id.owner, self.current_hir_id_owner);
997 let ret = self.arena.alloc_from_iter(lowered_attrs);
998
999 if ret.is_empty() {
1006 &[]
1007 } else {
1008 self.attrs.insert(id.local_id, ret);
1009 ret
1010 }
1011 }
1012 }
1013
1014 fn lower_attrs_vec(
1015 &mut self,
1016 attrs: &[Attribute],
1017 target_span: Span,
1018 target_hir_id: HirId,
1019 target: Target,
1020 ) -> Vec<hir::Attribute> {
1021 let l = self.span_lowerer();
1022 self.attribute_parser.parse_attribute_list(
1023 attrs,
1024 target_span,
1025 target_hir_id,
1026 target,
1027 OmitDoc::Lower,
1028 |s| l.lower(s),
1029 |l| {
1030 self.delayed_lints.push(DelayedLint::AttributeParsing(l));
1031 },
1032 )
1033 }
1034
1035 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
1036 assert_eq!(id.owner, self.current_hir_id_owner);
1037 assert_eq!(target_id.owner, self.current_hir_id_owner);
1038 if let Some(&a) = self.attrs.get(&target_id.local_id) {
1039 assert!(!a.is_empty());
1040 self.attrs.insert(id.local_id, a);
1041 }
1042 }
1043
1044 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
1045 args.clone()
1046 }
1047
1048 #[instrument(level = "debug", skip_all)]
1050 fn lower_assoc_item_constraint(
1051 &mut self,
1052 constraint: &AssocItemConstraint,
1053 itctx: ImplTraitContext,
1054 ) -> hir::AssocItemConstraint<'hir> {
1055 debug!(?constraint, ?itctx);
1056 let gen_args = if let Some(gen_args) = &constraint.gen_args {
1058 let gen_args_ctor = match gen_args {
1059 GenericArgs::AngleBracketed(data) => {
1060 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
1061 }
1062 GenericArgs::Parenthesized(data) => {
1063 if let Some(first_char) = constraint.ident.as_str().chars().next()
1064 && first_char.is_ascii_lowercase()
1065 {
1066 let err = match (&data.inputs[..], &data.output) {
1067 ([_, ..], FnRetTy::Default(_)) => {
1068 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
1069 }
1070 ([], FnRetTy::Default(_)) => {
1071 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
1072 }
1073 (_, FnRetTy::Ty(ty)) => {
1075 let span = data.inputs_span.shrink_to_hi().to(ty.span);
1076 errors::BadReturnTypeNotation::Output {
1077 span,
1078 suggestion: errors::RTNSuggestion {
1079 output: span,
1080 input: data.inputs_span,
1081 },
1082 }
1083 }
1084 };
1085 let mut err = self.dcx().create_err(err);
1086 if !self.tcx.features().return_type_notation()
1087 && self.tcx.sess.is_nightly_build()
1088 {
1089 add_feature_diagnostics(
1090 &mut err,
1091 &self.tcx.sess,
1092 sym::return_type_notation,
1093 );
1094 }
1095 err.emit();
1096 GenericArgsCtor {
1097 args: Default::default(),
1098 constraints: &[],
1099 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1100 span: data.span,
1101 }
1102 } else {
1103 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
1104 self.lower_angle_bracketed_parameter_data(
1107 &data.as_angle_bracketed_args(),
1108 ParamMode::Explicit,
1109 itctx,
1110 )
1111 .0
1112 }
1113 }
1114 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
1115 args: Default::default(),
1116 constraints: &[],
1117 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1118 span: *span,
1119 },
1120 };
1121 gen_args_ctor.into_generic_args(self)
1122 } else {
1123 self.arena.alloc(hir::GenericArgs::none())
1124 };
1125 let kind = match &constraint.kind {
1126 AssocItemConstraintKind::Equality { term } => {
1127 let term = match term {
1128 Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),
1129 Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),
1130 };
1131 hir::AssocItemConstraintKind::Equality { term }
1132 }
1133 AssocItemConstraintKind::Bound { bounds } => {
1134 if self.is_in_dyn_type {
1136 let suggestion = match itctx {
1137 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1138 let bound_end_span = constraint
1139 .gen_args
1140 .as_ref()
1141 .map_or(constraint.ident.span, |args| args.span());
1142 if bound_end_span.eq_ctxt(constraint.span) {
1143 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1144 } else {
1145 None
1146 }
1147 }
1148 _ => None,
1149 };
1150
1151 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1152 span: constraint.span,
1153 suggestion,
1154 });
1155 let err_ty =
1156 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1157 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1158 } else {
1159 let bounds = self.lower_param_bounds(
1160 bounds,
1161 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),
1162 itctx,
1163 );
1164 hir::AssocItemConstraintKind::Bound { bounds }
1165 }
1166 }
1167 };
1168
1169 hir::AssocItemConstraint {
1170 hir_id: self.lower_node_id(constraint.id),
1171 ident: self.lower_ident(constraint.ident),
1172 gen_args,
1173 kind,
1174 span: self.lower_span(constraint.span),
1175 }
1176 }
1177
1178 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1179 let sub = if data.inputs.is_empty() {
1181 let parentheses_span =
1182 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1183 AssocTyParenthesesSub::Empty { parentheses_span }
1184 }
1185 else {
1187 let open_param = data.inputs_span.shrink_to_lo().to(data
1189 .inputs
1190 .first()
1191 .unwrap()
1192 .span
1193 .shrink_to_lo());
1194 let close_param =
1196 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1197 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1198 };
1199 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1200 }
1201
1202 #[instrument(level = "debug", skip(self))]
1203 fn lower_generic_arg(
1204 &mut self,
1205 arg: &ast::GenericArg,
1206 itctx: ImplTraitContext,
1207 ) -> hir::GenericArg<'hir> {
1208 match arg {
1209 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1210 lt,
1211 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1212 lt.ident.into(),
1213 )),
1214 ast::GenericArg::Type(ty) => {
1215 if ty.is_maybe_parenthesised_infer() {
1218 return GenericArg::Infer(hir::InferArg {
1219 hir_id: self.lower_node_id(ty.id),
1220 span: self.lower_span(ty.span),
1221 });
1222 }
1223
1224 match &ty.kind {
1225 TyKind::Path(None, path) => {
1232 if let Some(res) = self
1233 .resolver
1234 .get_partial_res(ty.id)
1235 .and_then(|partial_res| partial_res.full_res())
1236 {
1237 if !res.matches_ns(Namespace::TypeNS)
1238 && path.is_potential_trivial_const_arg()
1239 {
1240 debug!(
1241 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1242 ty,
1243 );
1244
1245 let ct =
1246 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1247 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1248 }
1249 }
1250 }
1251 _ => {}
1252 }
1253 GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())
1254 }
1255 ast::GenericArg::Const(ct) => GenericArg::Const(
1256 self.lower_anon_const_to_const_arg_and_alloc(ct).try_as_ambig_ct().unwrap(),
1257 ),
1258 }
1259 }
1260
1261 #[instrument(level = "debug", skip(self))]
1262 fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1263 self.arena.alloc(self.lower_ty(t, itctx))
1264 }
1265
1266 fn lower_path_ty(
1267 &mut self,
1268 t: &Ty,
1269 qself: &Option<Box<QSelf>>,
1270 path: &Path,
1271 param_mode: ParamMode,
1272 itctx: ImplTraitContext,
1273 ) -> hir::Ty<'hir> {
1274 if qself.is_none()
1280 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1281 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1282 {
1283 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1284 let bound = this.lower_poly_trait_ref(
1285 &PolyTraitRef {
1286 bound_generic_params: ThinVec::new(),
1287 modifiers: TraitBoundModifiers::NONE,
1288 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1289 span: t.span,
1290 parens: ast::Parens::No,
1291 },
1292 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),
1293 itctx,
1294 );
1295 let bounds = this.arena.alloc_from_iter([bound]);
1296 let lifetime_bound = this.elided_dyn_bound(t.span);
1297 (bounds, lifetime_bound)
1298 });
1299 let kind = hir::TyKind::TraitObject(
1300 bounds,
1301 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1302 );
1303 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1304 }
1305
1306 let id = self.lower_node_id(t.id);
1307 let qpath = self.lower_qpath(
1308 t.id,
1309 qself,
1310 path,
1311 param_mode,
1312 AllowReturnTypeNotation::Yes,
1313 itctx,
1314 None,
1315 );
1316 self.ty_path(id, t.span, qpath)
1317 }
1318
1319 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1320 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1321 }
1322
1323 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1324 self.ty(span, hir::TyKind::Tup(tys))
1325 }
1326
1327 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1328 let kind = match &t.kind {
1329 TyKind::Infer => hir::TyKind::Infer(()),
1330 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1331 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),
1332 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1333 TyKind::Ref(region, mt) => {
1334 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1335 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1336 }
1337 TyKind::PinnedRef(region, mt) => {
1338 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1339 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1340 let span = self.lower_span(t.span);
1341 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1342 let args = self.arena.alloc(hir::GenericArgs {
1343 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1344 constraints: &[],
1345 parenthesized: hir::GenericArgsParentheses::No,
1346 span_ext: span,
1347 });
1348 let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));
1349 hir::TyKind::Path(path)
1350 }
1351 TyKind::FnPtr(f) => {
1352 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1353 hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {
1354 generic_params,
1355 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1356 abi: self.lower_extern(f.ext),
1357 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1358 param_idents: self.lower_fn_params_to_idents(&f.decl),
1359 }))
1360 }
1361 TyKind::UnsafeBinder(f) => {
1362 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1363 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1364 generic_params,
1365 inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),
1366 }))
1367 }
1368 TyKind::Never => hir::TyKind::Never,
1369 TyKind::Tup(tys) => hir::TyKind::Tup(
1370 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),
1371 ),
1372 TyKind::Paren(ty) => {
1373 return self.lower_ty(ty, itctx);
1374 }
1375 TyKind::Path(qself, path) => {
1376 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1377 }
1378 TyKind::ImplicitSelf => {
1379 let hir_id = self.next_id();
1380 let res = self.expect_full_res(t.id);
1381 let res = self.lower_res(res);
1382 hir::TyKind::Path(hir::QPath::Resolved(
1383 None,
1384 self.arena.alloc(hir::Path {
1385 res,
1386 segments: arena_vec![self; hir::PathSegment::new(
1387 Ident::with_dummy_span(kw::SelfUpper),
1388 hir_id,
1389 res
1390 )],
1391 span: self.lower_span(t.span),
1392 }),
1393 ))
1394 }
1395 TyKind::Array(ty, length) => hir::TyKind::Array(
1396 self.lower_ty_alloc(ty, itctx),
1397 self.lower_array_length_to_const_arg(length),
1398 ),
1399 TyKind::TraitObject(bounds, kind) => {
1400 let mut lifetime_bound = None;
1401 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1402 let bounds =
1403 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1404 GenericBound::Trait(ty) => {
1408 let trait_ref = this.lower_poly_trait_ref(
1409 ty,
1410 RelaxedBoundPolicy::Forbidden(
1411 RelaxedBoundForbiddenReason::TraitObjectTy,
1412 ),
1413 itctx,
1414 );
1415 Some(trait_ref)
1416 }
1417 GenericBound::Outlives(lifetime) => {
1418 if lifetime_bound.is_none() {
1419 lifetime_bound = Some(this.lower_lifetime(
1420 lifetime,
1421 LifetimeSource::Other,
1422 lifetime.ident.into(),
1423 ));
1424 }
1425 None
1426 }
1427 GenericBound::Use(_, span) => {
1429 this.dcx()
1430 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1431 None
1432 }
1433 }));
1434 let lifetime_bound =
1435 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1436 (bounds, lifetime_bound)
1437 });
1438 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1439 }
1440 TyKind::ImplTrait(def_node_id, bounds) => {
1441 let span = t.span;
1442 match itctx {
1443 ImplTraitContext::OpaqueTy { origin } => {
1444 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1445 }
1446 ImplTraitContext::Universal => {
1447 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1448 ast::GenericBound::Use(_, span) => Some(span),
1449 _ => None,
1450 }) {
1451 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1452 }
1453
1454 let def_id = self.local_def_id(*def_node_id);
1455 let name = self.tcx.item_name(def_id.to_def_id());
1456 let ident = Ident::new(name, span);
1457 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1458 *def_node_id,
1459 span,
1460 ident,
1461 bounds,
1462 );
1463 self.impl_trait_defs.push(param);
1464 if let Some(bounds) = bounds {
1465 self.impl_trait_bounds.push(bounds);
1466 }
1467 path
1468 }
1469 ImplTraitContext::InBinding => hir::TyKind::TraitAscription(
1470 self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),
1471 ),
1472 ImplTraitContext::FeatureGated(position, feature) => {
1473 let guar = self
1474 .tcx
1475 .sess
1476 .create_feature_err(
1477 MisplacedImplTrait {
1478 span: t.span,
1479 position: DiagArgFromDisplay(&position),
1480 },
1481 feature,
1482 )
1483 .emit();
1484 hir::TyKind::Err(guar)
1485 }
1486 ImplTraitContext::Disallowed(position) => {
1487 let guar = self.dcx().emit_err(MisplacedImplTrait {
1488 span: t.span,
1489 position: DiagArgFromDisplay(&position),
1490 });
1491 hir::TyKind::Err(guar)
1492 }
1493 }
1494 }
1495 TyKind::Pat(ty, pat) => {
1496 hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))
1497 }
1498 TyKind::MacCall(_) => {
1499 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1500 }
1501 TyKind::CVarArgs => {
1502 let guar = self.dcx().span_delayed_bug(
1503 t.span,
1504 "`TyKind::CVarArgs` should have been handled elsewhere",
1505 );
1506 hir::TyKind::Err(guar)
1507 }
1508 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1509 };
1510
1511 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1512 }
1513
1514 fn lower_ty_direct_lifetime(
1515 &mut self,
1516 t: &Ty,
1517 region: Option<Lifetime>,
1518 ) -> &'hir hir::Lifetime {
1519 let (region, syntax) = match region {
1520 Some(region) => (region, region.ident.into()),
1521
1522 None => {
1523 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1524 self.resolver.get_lifetime_res(t.id)
1525 {
1526 assert_eq!(start.plus(1), end);
1527 start
1528 } else {
1529 self.next_node_id()
1530 };
1531 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1532 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1533 (region, LifetimeSyntax::Implicit)
1534 }
1535 };
1536 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1537 }
1538
1539 #[instrument(level = "debug", skip(self), ret)]
1571 fn lower_opaque_impl_trait(
1572 &mut self,
1573 span: Span,
1574 origin: hir::OpaqueTyOrigin<LocalDefId>,
1575 opaque_ty_node_id: NodeId,
1576 bounds: &GenericBounds,
1577 itctx: ImplTraitContext,
1578 ) -> hir::TyKind<'hir> {
1579 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1585
1586 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1587 this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)
1588 })
1589 }
1590
1591 fn lower_opaque_inner(
1592 &mut self,
1593 opaque_ty_node_id: NodeId,
1594 origin: hir::OpaqueTyOrigin<LocalDefId>,
1595 opaque_ty_span: Span,
1596 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1597 ) -> hir::TyKind<'hir> {
1598 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1599 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1600 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1601
1602 let bounds = lower_item_bounds(self);
1603 let opaque_ty_def = hir::OpaqueTy {
1604 hir_id: opaque_ty_hir_id,
1605 def_id: opaque_ty_def_id,
1606 bounds,
1607 origin,
1608 span: self.lower_span(opaque_ty_span),
1609 };
1610 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1611
1612 hir::TyKind::OpaqueDef(opaque_ty_def)
1613 }
1614
1615 fn lower_precise_capturing_args(
1616 &mut self,
1617 precise_capturing_args: &[PreciseCapturingArg],
1618 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1619 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1620 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1621 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1622 ),
1623 PreciseCapturingArg::Arg(path, id) => {
1624 let [segment] = path.segments.as_slice() else {
1625 panic!();
1626 };
1627 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1628 partial_res.full_res().expect("no partial res expected for precise capture arg")
1629 });
1630 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1631 hir_id: self.lower_node_id(*id),
1632 ident: self.lower_ident(segment.ident),
1633 res: self.lower_res(res),
1634 })
1635 }
1636 }))
1637 }
1638
1639 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1640 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1641 PatKind::Missing => None,
1642 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1643 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1644 _ => {
1645 self.dcx().span_delayed_bug(
1646 param.pat.span,
1647 "non-missing/ident/wild param pat must trigger an error",
1648 );
1649 None
1650 }
1651 }))
1652 }
1653
1654 #[instrument(level = "debug", skip(self))]
1664 fn lower_fn_decl(
1665 &mut self,
1666 decl: &FnDecl,
1667 fn_node_id: NodeId,
1668 fn_span: Span,
1669 kind: FnDeclKind,
1670 coro: Option<CoroutineKind>,
1671 ) -> &'hir hir::FnDecl<'hir> {
1672 let c_variadic = decl.c_variadic();
1673
1674 let mut inputs = &decl.inputs[..];
1678 if c_variadic {
1679 inputs = &inputs[..inputs.len() - 1];
1680 }
1681 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1682 let itctx = match kind {
1683 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1684 ImplTraitContext::Universal
1685 }
1686 FnDeclKind::ExternFn => {
1687 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1688 }
1689 FnDeclKind::Closure => {
1690 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1691 }
1692 FnDeclKind::Pointer => {
1693 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1694 }
1695 };
1696 self.lower_ty(¶m.ty, itctx)
1697 }));
1698
1699 let output = match coro {
1700 Some(coro) => {
1701 let fn_def_id = self.local_def_id(fn_node_id);
1702 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)
1703 }
1704 None => match &decl.output {
1705 FnRetTy::Ty(ty) => {
1706 let itctx = match kind {
1707 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1708 origin: hir::OpaqueTyOrigin::FnReturn {
1709 parent: self.local_def_id(fn_node_id),
1710 in_trait_or_impl: None,
1711 },
1712 },
1713 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1714 origin: hir::OpaqueTyOrigin::FnReturn {
1715 parent: self.local_def_id(fn_node_id),
1716 in_trait_or_impl: Some(hir::RpitContext::Trait),
1717 },
1718 },
1719 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1720 origin: hir::OpaqueTyOrigin::FnReturn {
1721 parent: self.local_def_id(fn_node_id),
1722 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1723 },
1724 },
1725 FnDeclKind::ExternFn => {
1726 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1727 }
1728 FnDeclKind::Closure => {
1729 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1730 }
1731 FnDeclKind::Pointer => {
1732 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1733 }
1734 };
1735 hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx))
1736 }
1737 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1738 },
1739 };
1740
1741 self.arena.alloc(hir::FnDecl {
1742 inputs,
1743 output,
1744 c_variadic,
1745 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1746 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1747 let is_mutable_pat = matches!(
1748 arg.pat.kind,
1749 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1750 );
1751
1752 match &arg.ty.kind {
1753 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1754 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1755 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1759 if mt.ty.kind.is_implicit_self() =>
1760 {
1761 match mt.mutbl {
1762 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1763 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1764 }
1765 }
1766 _ => hir::ImplicitSelfKind::None,
1767 }
1768 }),
1769 })
1770 }
1771
1772 #[instrument(level = "debug", skip(self))]
1781 fn lower_coroutine_fn_ret_ty(
1782 &mut self,
1783 output: &FnRetTy,
1784 fn_def_id: LocalDefId,
1785 coro: CoroutineKind,
1786 fn_kind: FnDeclKind,
1787 ) -> hir::FnRetTy<'hir> {
1788 let span = self.lower_span(output.span());
1789
1790 let (opaque_ty_node_id, allowed_features) = match coro {
1791 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1792 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1793 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1794 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1795 }
1796 };
1797
1798 let opaque_ty_span =
1799 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1800
1801 let in_trait_or_impl = match fn_kind {
1802 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1803 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1804 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1805 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1806 };
1807
1808 let opaque_ty_ref = self.lower_opaque_inner(
1809 opaque_ty_node_id,
1810 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1811 opaque_ty_span,
1812 |this| {
1813 let bound = this.lower_coroutine_fn_output_type_to_bound(
1814 output,
1815 coro,
1816 opaque_ty_span,
1817 ImplTraitContext::OpaqueTy {
1818 origin: hir::OpaqueTyOrigin::FnReturn {
1819 parent: fn_def_id,
1820 in_trait_or_impl,
1821 },
1822 },
1823 );
1824 arena_vec![this; bound]
1825 },
1826 );
1827
1828 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1829 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1830 }
1831
1832 fn lower_coroutine_fn_output_type_to_bound(
1834 &mut self,
1835 output: &FnRetTy,
1836 coro: CoroutineKind,
1837 opaque_ty_span: Span,
1838 itctx: ImplTraitContext,
1839 ) -> hir::GenericBound<'hir> {
1840 let output_ty = match output {
1842 FnRetTy::Ty(ty) => {
1843 self.lower_ty_alloc(ty, itctx)
1847 }
1848 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1849 };
1850
1851 let (assoc_ty_name, trait_lang_item) = match coro {
1853 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1854 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1855 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1856 };
1857
1858 let bound_args = self.arena.alloc(hir::GenericArgs {
1859 args: &[],
1860 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1861 parenthesized: hir::GenericArgsParentheses::No,
1862 span_ext: DUMMY_SP,
1863 });
1864
1865 hir::GenericBound::Trait(hir::PolyTraitRef {
1866 bound_generic_params: &[],
1867 modifiers: hir::TraitBoundModifiers::NONE,
1868 trait_ref: hir::TraitRef {
1869 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1870 hir_ref_id: self.next_id(),
1871 },
1872 span: opaque_ty_span,
1873 })
1874 }
1875
1876 #[instrument(level = "trace", skip(self))]
1877 fn lower_param_bound(
1878 &mut self,
1879 tpb: &GenericBound,
1880 rbp: RelaxedBoundPolicy<'_>,
1881 itctx: ImplTraitContext,
1882 ) -> hir::GenericBound<'hir> {
1883 match tpb {
1884 GenericBound::Trait(p) => {
1885 hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))
1886 }
1887 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1888 lifetime,
1889 LifetimeSource::OutlivesBound,
1890 lifetime.ident.into(),
1891 )),
1892 GenericBound::Use(args, span) => hir::GenericBound::Use(
1893 self.lower_precise_capturing_args(args),
1894 self.lower_span(*span),
1895 ),
1896 }
1897 }
1898
1899 fn lower_lifetime(
1900 &mut self,
1901 l: &Lifetime,
1902 source: LifetimeSource,
1903 syntax: LifetimeSyntax,
1904 ) -> &'hir hir::Lifetime {
1905 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1906 }
1907
1908 fn lower_lifetime_hidden_in_path(
1909 &mut self,
1910 id: NodeId,
1911 span: Span,
1912 angle_brackets: AngleBrackets,
1913 ) -> &'hir hir::Lifetime {
1914 self.new_named_lifetime(
1915 id,
1916 id,
1917 Ident::new(kw::UnderscoreLifetime, span),
1918 LifetimeSource::Path { angle_brackets },
1919 LifetimeSyntax::Implicit,
1920 )
1921 }
1922
1923 #[instrument(level = "debug", skip(self))]
1924 fn new_named_lifetime(
1925 &mut self,
1926 id: NodeId,
1927 new_id: NodeId,
1928 ident: Ident,
1929 source: LifetimeSource,
1930 syntax: LifetimeSyntax,
1931 ) -> &'hir hir::Lifetime {
1932 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1933 let res = match res {
1934 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1935 LifetimeRes::Fresh { param, .. } => {
1936 assert_eq!(ident.name, kw::UnderscoreLifetime);
1937 let param = self.local_def_id(param);
1938 hir::LifetimeKind::Param(param)
1939 }
1940 LifetimeRes::Infer => {
1941 assert_eq!(ident.name, kw::UnderscoreLifetime);
1942 hir::LifetimeKind::Infer
1943 }
1944 LifetimeRes::Static { .. } => {
1945 assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1946 hir::LifetimeKind::Static
1947 }
1948 LifetimeRes::Error => hir::LifetimeKind::Error,
1949 LifetimeRes::ElidedAnchor { .. } => {
1950 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1951 }
1952 };
1953
1954 debug!(?res);
1955 self.arena.alloc(hir::Lifetime::new(
1956 self.lower_node_id(new_id),
1957 self.lower_ident(ident),
1958 res,
1959 source,
1960 syntax,
1961 ))
1962 }
1963
1964 fn lower_generic_params_mut(
1965 &mut self,
1966 params: &[GenericParam],
1967 source: hir::GenericParamSource,
1968 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1969 params.iter().map(move |param| self.lower_generic_param(param, source))
1970 }
1971
1972 fn lower_generic_params(
1973 &mut self,
1974 params: &[GenericParam],
1975 source: hir::GenericParamSource,
1976 ) -> &'hir [hir::GenericParam<'hir>] {
1977 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1978 }
1979
1980 #[instrument(level = "trace", skip(self))]
1981 fn lower_generic_param(
1982 &mut self,
1983 param: &GenericParam,
1984 source: hir::GenericParamSource,
1985 ) -> hir::GenericParam<'hir> {
1986 let (name, kind) = self.lower_generic_param_kind(param, source);
1987
1988 let hir_id = self.lower_node_id(param.id);
1989 let param_attrs = ¶m.attrs;
1990 let param_span = param.span();
1991 let param = hir::GenericParam {
1992 hir_id,
1993 def_id: self.local_def_id(param.id),
1994 name,
1995 span: self.lower_span(param.span()),
1996 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1997 kind,
1998 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1999 source,
2000 };
2001 self.lower_attrs(hir_id, param_attrs, param_span, Target::from_generic_param(¶m));
2002 param
2003 }
2004
2005 fn lower_generic_param_kind(
2006 &mut self,
2007 param: &GenericParam,
2008 source: hir::GenericParamSource,
2009 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
2010 match ¶m.kind {
2011 GenericParamKind::Lifetime => {
2012 let ident = self.lower_ident(param.ident);
2015 let param_name =
2016 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
2017 ParamName::Error(ident)
2018 } else {
2019 ParamName::Plain(ident)
2020 };
2021 let kind =
2022 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
2023
2024 (param_name, kind)
2025 }
2026 GenericParamKind::Type { default, .. } => {
2027 let default = default
2030 .as_ref()
2031 .filter(|_| match source {
2032 hir::GenericParamSource::Generics => true,
2033 hir::GenericParamSource::Binder => {
2034 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2035 span: param.span(),
2036 });
2037
2038 false
2039 }
2040 })
2041 .map(|def| {
2042 self.lower_ty_alloc(
2043 def,
2044 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
2045 )
2046 });
2047
2048 let kind = hir::GenericParamKind::Type { default, synthetic: false };
2049
2050 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
2051 }
2052 GenericParamKind::Const { ty, span: _, default } => {
2053 let ty = self.lower_ty_alloc(
2054 ty,
2055 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
2056 );
2057
2058 let default = default
2061 .as_ref()
2062 .filter(|_| match source {
2063 hir::GenericParamSource::Generics => true,
2064 hir::GenericParamSource::Binder => {
2065 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2066 span: param.span(),
2067 });
2068
2069 false
2070 }
2071 })
2072 .map(|def| self.lower_anon_const_to_const_arg_and_alloc(def));
2073
2074 (
2075 hir::ParamName::Plain(self.lower_ident(param.ident)),
2076 hir::GenericParamKind::Const { ty, default },
2077 )
2078 }
2079 }
2080 }
2081
2082 fn lower_trait_ref(
2083 &mut self,
2084 modifiers: ast::TraitBoundModifiers,
2085 p: &TraitRef,
2086 itctx: ImplTraitContext,
2087 ) -> hir::TraitRef<'hir> {
2088 let path = match self.lower_qpath(
2089 p.ref_id,
2090 &None,
2091 &p.path,
2092 ParamMode::Explicit,
2093 AllowReturnTypeNotation::No,
2094 itctx,
2095 Some(modifiers),
2096 ) {
2097 hir::QPath::Resolved(None, path) => path,
2098 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2099 };
2100 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2101 }
2102
2103 #[instrument(level = "debug", skip(self))]
2104 fn lower_poly_trait_ref(
2105 &mut self,
2106 PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2107 rbp: RelaxedBoundPolicy<'_>,
2108 itctx: ImplTraitContext,
2109 ) -> hir::PolyTraitRef<'hir> {
2110 let bound_generic_params =
2111 self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
2112 let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
2113 let modifiers = self.lower_trait_bound_modifiers(*modifiers);
2114
2115 if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2116 self.validate_relaxed_bound(trait_ref, *span, rbp);
2117 }
2118
2119 hir::PolyTraitRef {
2120 bound_generic_params,
2121 modifiers,
2122 trait_ref,
2123 span: self.lower_span(*span),
2124 }
2125 }
2126
2127 fn validate_relaxed_bound(
2128 &self,
2129 trait_ref: hir::TraitRef<'_>,
2130 span: Span,
2131 rbp: RelaxedBoundPolicy<'_>,
2132 ) {
2133 match rbp {
2143 RelaxedBoundPolicy::Allowed => return,
2144 RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2145 if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
2146 && let Res::Def(DefKind::TyParam, def_id) = res
2147 && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2148 {
2149 return;
2150 }
2151 }
2152 RelaxedBoundPolicy::Forbidden(reason) => {
2153 let gate = |context, subject| {
2154 let extended = self.tcx.features().more_maybe_bounds();
2155 let is_sized = trait_ref
2156 .trait_def_id()
2157 .is_some_and(|def_id| self.tcx.is_lang_item(def_id, hir::LangItem::Sized));
2158
2159 if extended && !is_sized {
2160 return;
2161 }
2162
2163 let prefix = if extended { "`Sized` " } else { "" };
2164 let mut diag = self.dcx().struct_span_err(
2165 span,
2166 format!("relaxed {prefix}bounds are not permitted in {context}"),
2167 );
2168 if is_sized {
2169 diag.note(format!(
2170 "{subject} are not implicitly bounded by `Sized`, \
2171 so there is nothing to relax"
2172 ));
2173 }
2174 diag.emit();
2175 };
2176
2177 match reason {
2178 RelaxedBoundForbiddenReason::TraitObjectTy => {
2179 gate("trait object types", "trait object types");
2180 return;
2181 }
2182 RelaxedBoundForbiddenReason::SuperTrait => {
2183 gate("supertrait bounds", "traits");
2184 return;
2185 }
2186 RelaxedBoundForbiddenReason::TraitAlias => {
2187 gate("trait alias bounds", "trait aliases");
2188 return;
2189 }
2190 RelaxedBoundForbiddenReason::AssocTyBounds
2191 | RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2192 };
2193 }
2194 }
2195
2196 self.dcx()
2197 .struct_span_err(span, "this relaxed bound is not permitted here")
2198 .with_note(
2199 "in this context, relaxed bounds are only allowed on \
2200 type parameters defined on the closest item",
2201 )
2202 .emit();
2203 }
2204
2205 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2206 hir::MutTy { ty: self.lower_ty_alloc(&mt.ty, itctx), mutbl: mt.mutbl }
2207 }
2208
2209 #[instrument(level = "debug", skip(self), ret)]
2210 fn lower_param_bounds(
2211 &mut self,
2212 bounds: &[GenericBound],
2213 rbp: RelaxedBoundPolicy<'_>,
2214 itctx: ImplTraitContext,
2215 ) -> hir::GenericBounds<'hir> {
2216 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
2217 }
2218
2219 fn lower_param_bounds_mut(
2220 &mut self,
2221 bounds: &[GenericBound],
2222 rbp: RelaxedBoundPolicy<'_>,
2223 itctx: ImplTraitContext,
2224 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2225 bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
2226 }
2227
2228 #[instrument(level = "debug", skip(self), ret)]
2229 fn lower_universal_param_and_bounds(
2230 &mut self,
2231 node_id: NodeId,
2232 span: Span,
2233 ident: Ident,
2234 bounds: &[GenericBound],
2235 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2236 let def_id = self.local_def_id(node_id);
2238 let span = self.lower_span(span);
2239
2240 let param = hir::GenericParam {
2242 hir_id: self.lower_node_id(node_id),
2243 def_id,
2244 name: ParamName::Plain(self.lower_ident(ident)),
2245 pure_wrt_drop: false,
2246 span,
2247 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2248 colon_span: None,
2249 source: hir::GenericParamSource::Generics,
2250 };
2251
2252 let preds = self.lower_generic_bound_predicate(
2253 ident,
2254 node_id,
2255 &GenericParamKind::Type { default: None },
2256 bounds,
2257 None,
2258 span,
2259 RelaxedBoundPolicy::Allowed,
2260 ImplTraitContext::Universal,
2261 hir::PredicateOrigin::ImplTrait,
2262 );
2263
2264 let hir_id = self.next_id();
2265 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2266 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2267 None,
2268 self.arena.alloc(hir::Path {
2269 span,
2270 res,
2271 segments:
2272 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2273 }),
2274 ));
2275
2276 (param, preds, ty)
2277 }
2278
2279 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2282 let block = self.lower_block(b, false);
2283 self.expr_block(block)
2284 }
2285
2286 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2287 match c.value.peel_parens().kind {
2290 ExprKind::Underscore => {
2291 let ct_kind = hir::ConstArgKind::Infer(());
2292 self.arena.alloc(hir::ConstArg {
2293 hir_id: self.lower_node_id(c.id),
2294 kind: ct_kind,
2295 span: self.lower_span(c.value.span),
2296 })
2297 }
2298 _ => self.lower_anon_const_to_const_arg_and_alloc(c),
2299 }
2300 }
2301
2302 #[instrument(level = "debug", skip(self))]
2306 fn lower_const_path_to_const_arg(
2307 &mut self,
2308 path: &Path,
2309 res: Res<NodeId>,
2310 ty_id: NodeId,
2311 span: Span,
2312 ) -> &'hir hir::ConstArg<'hir> {
2313 let tcx = self.tcx;
2314
2315 let is_trivial_path = path.is_potential_trivial_const_arg()
2316 && matches!(res, Res::Def(DefKind::ConstParam, _));
2317 let ct_kind = if is_trivial_path || tcx.features().min_generic_const_args() {
2318 let qpath = self.lower_qpath(
2319 ty_id,
2320 &None,
2321 path,
2322 ParamMode::Explicit,
2323 AllowReturnTypeNotation::No,
2324 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2326 None,
2327 );
2328 hir::ConstArgKind::Path(qpath)
2329 } else {
2330 let node_id = self.next_node_id();
2332 let span = self.lower_span(span);
2333
2334 let def_id = self.create_def(
2339 node_id,
2340 None,
2341 DefKind::AnonConst,
2342 DefPathData::LateAnonConst,
2343 span,
2344 );
2345 let hir_id = self.lower_node_id(node_id);
2346
2347 let path_expr = Expr {
2348 id: ty_id,
2349 kind: ExprKind::Path(None, path.clone()),
2350 span,
2351 attrs: AttrVec::new(),
2352 tokens: None,
2353 };
2354
2355 let ct = self.with_new_scopes(span, |this| {
2356 self.arena.alloc(hir::AnonConst {
2357 def_id,
2358 hir_id,
2359 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2360 span,
2361 })
2362 });
2363 hir::ConstArgKind::Anon(ct)
2364 };
2365
2366 self.arena.alloc(hir::ConstArg {
2367 hir_id: self.next_id(),
2368 kind: ct_kind,
2369 span: self.lower_span(span),
2370 })
2371 }
2372
2373 fn lower_const_item_rhs(
2374 &mut self,
2375 attrs: &[hir::Attribute],
2376 rhs: Option<&ConstItemRhs>,
2377 span: Span,
2378 ) -> hir::ConstItemRhs<'hir> {
2379 match rhs {
2380 Some(ConstItemRhs::TypeConst(anon)) => {
2381 hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon))
2382 }
2383 None if attr::contains_name(attrs, sym::type_const) => {
2384 let const_arg = ConstArg {
2385 hir_id: self.next_id(),
2386 kind: hir::ConstArgKind::Error(
2387 self.dcx().span_delayed_bug(DUMMY_SP, "no block"),
2388 ),
2389 span: DUMMY_SP,
2390 };
2391 hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg))
2392 }
2393 Some(ConstItemRhs::Body(body)) => {
2394 hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body)))
2395 }
2396 None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)),
2397 }
2398 }
2399
2400 #[instrument(level = "debug", skip(self), ret)]
2401 fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> {
2402 let span = self.lower_span(expr.span);
2403
2404 let overly_complex_const = |this: &mut Self| {
2405 let e = this.dcx().struct_span_err(
2406 expr.span,
2407 "complex const arguments must be placed inside of a `const` block",
2408 );
2409
2410 ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span }
2411 };
2412
2413 match &expr.kind {
2414 ExprKind::Call(func, args) if let ExprKind::Path(qself, path) = &func.kind => {
2415 let qpath = self.lower_qpath(
2416 func.id,
2417 qself,
2418 path,
2419 ParamMode::Explicit,
2420 AllowReturnTypeNotation::No,
2421 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2422 None,
2423 );
2424
2425 let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| {
2426 let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind {
2427 let def_id = self.local_def_id(anon_const.id);
2428 let def_kind = self.tcx.def_kind(def_id);
2429 assert_eq!(DefKind::AnonConst, def_kind);
2430 self.lower_anon_const_to_const_arg(anon_const)
2431 } else {
2432 self.lower_expr_to_const_arg_direct(arg)
2433 };
2434
2435 &*self.arena.alloc(const_arg)
2436 }));
2437
2438 ConstArg {
2439 hir_id: self.next_id(),
2440 kind: hir::ConstArgKind::TupleCall(qpath, lowered_args),
2441 span,
2442 }
2443 }
2444 ExprKind::Tup(exprs) => {
2445 let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
2446 let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
2447 let def_id = self.local_def_id(anon_const.id);
2448 let def_kind = self.tcx.def_kind(def_id);
2449 assert_eq!(DefKind::AnonConst, def_kind);
2450
2451 self.lower_anon_const_to_const_arg(anon_const)
2452 } else {
2453 self.lower_expr_to_const_arg_direct(&expr)
2454 };
2455
2456 &*self.arena.alloc(expr)
2457 }));
2458
2459 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(exprs), span }
2460 }
2461 ExprKind::Path(qself, path) => {
2462 let qpath = self.lower_qpath(
2463 expr.id,
2464 qself,
2465 path,
2466 ParamMode::Explicit,
2467 AllowReturnTypeNotation::No,
2468 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2470 None,
2471 );
2472
2473 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath), span }
2474 }
2475 ExprKind::Struct(se) => {
2476 let path = self.lower_qpath(
2477 expr.id,
2478 &se.qself,
2479 &se.path,
2480 ParamMode::Explicit,
2484 AllowReturnTypeNotation::No,
2485 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2486 None,
2487 );
2488
2489 let fields = self.arena.alloc_from_iter(se.fields.iter().map(|f| {
2490 let hir_id = self.lower_node_id(f.id);
2491 self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
2495
2496 let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind {
2497 let def_id = self.local_def_id(anon_const.id);
2498 let def_kind = self.tcx.def_kind(def_id);
2499 assert_eq!(DefKind::AnonConst, def_kind);
2500
2501 self.lower_anon_const_to_const_arg(anon_const)
2502 } else {
2503 self.lower_expr_to_const_arg_direct(&f.expr)
2504 };
2505
2506 &*self.arena.alloc(hir::ConstArgExprField {
2507 hir_id,
2508 field: self.lower_ident(f.ident),
2509 expr: self.arena.alloc(expr),
2510 span: self.lower_span(f.span),
2511 })
2512 }));
2513
2514 ConstArg {
2515 hir_id: self.next_id(),
2516 kind: hir::ConstArgKind::Struct(path, fields),
2517 span,
2518 }
2519 }
2520 ExprKind::Array(elements) => {
2521 let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
2522 let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
2523 let def_id = self.local_def_id(anon_const.id);
2524 assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
2525 self.lower_anon_const_to_const_arg(anon_const)
2526 } else {
2527 self.lower_expr_to_const_arg_direct(element)
2528 };
2529 &*self.arena.alloc(const_arg)
2530 }));
2531 let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
2532 span: self.lower_span(expr.span),
2533 elems: lowered_elems,
2534 });
2535
2536 ConstArg {
2537 hir_id: self.next_id(),
2538 kind: hir::ConstArgKind::Array(array_expr),
2539 span,
2540 }
2541 }
2542 ExprKind::Underscore => ConstArg {
2543 hir_id: self.lower_node_id(expr.id),
2544 kind: hir::ConstArgKind::Infer(()),
2545 span,
2546 },
2547 ExprKind::Block(block, _) => {
2548 if let [stmt] = block.stmts.as_slice()
2549 && let StmtKind::Expr(expr) = &stmt.kind
2550 && matches!(
2551 expr.kind,
2552 ExprKind::Block(..)
2553 | ExprKind::Path(..)
2554 | ExprKind::Struct(..)
2555 | ExprKind::Call(..)
2556 | ExprKind::Tup(..)
2557 | ExprKind::Array(..)
2558 )
2559 {
2560 return self.lower_expr_to_const_arg_direct(expr);
2561 }
2562
2563 overly_complex_const(self)
2564 }
2565 ExprKind::Lit(literal) => {
2566 let span = expr.span;
2567 let literal = self.lower_lit(literal, span);
2568
2569 ConstArg {
2570 hir_id: self.lower_node_id(expr.id),
2571 kind: hir::ConstArgKind::Literal(literal.node),
2572 span,
2573 }
2574 }
2575 _ => overly_complex_const(self),
2576 }
2577 }
2578
2579 fn lower_anon_const_to_const_arg_and_alloc(
2582 &mut self,
2583 anon: &AnonConst,
2584 ) -> &'hir hir::ConstArg<'hir> {
2585 self.arena.alloc(self.lower_anon_const_to_const_arg(anon))
2586 }
2587
2588 #[instrument(level = "debug", skip(self))]
2589 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2590 let tcx = self.tcx;
2591
2592 if tcx.features().min_generic_const_args() {
2598 return match anon.mgca_disambiguation {
2599 MgcaDisambiguation::AnonConst => {
2600 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2601 ConstArg {
2602 hir_id: self.next_id(),
2603 kind: hir::ConstArgKind::Anon(lowered_anon),
2604 span: lowered_anon.span,
2605 }
2606 }
2607 MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value),
2608 };
2609 }
2610
2611 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2614 && let [stmt] = block.stmts.as_slice()
2615 && let StmtKind::Expr(expr) = &stmt.kind
2616 && let ExprKind::Path(..) = &expr.kind
2617 {
2618 expr
2619 } else {
2620 &anon.value
2621 };
2622
2623 let maybe_res =
2624 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2625 if let ExprKind::Path(qself, path) = &expr.kind
2626 && path.is_potential_trivial_const_arg()
2627 && matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _)))
2628 {
2629 let qpath = self.lower_qpath(
2630 expr.id,
2631 qself,
2632 path,
2633 ParamMode::Explicit,
2634 AllowReturnTypeNotation::No,
2635 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2636 None,
2637 );
2638
2639 return ConstArg {
2640 hir_id: self.lower_node_id(anon.id),
2641 kind: hir::ConstArgKind::Path(qpath),
2642 span: self.lower_span(expr.span),
2643 };
2644 }
2645
2646 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2647 ConstArg {
2648 hir_id: self.next_id(),
2649 kind: hir::ConstArgKind::Anon(lowered_anon),
2650 span: self.lower_span(expr.span),
2651 }
2652 }
2653
2654 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2657 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2658 let def_id = this.local_def_id(c.id);
2659 let hir_id = this.lower_node_id(c.id);
2660 hir::AnonConst {
2661 def_id,
2662 hir_id,
2663 body: this.lower_const_body(c.value.span, Some(&c.value)),
2664 span: this.lower_span(c.value.span),
2665 }
2666 }))
2667 }
2668
2669 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2670 match u {
2671 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2672 UserProvided => hir::UnsafeSource::UserProvided,
2673 }
2674 }
2675
2676 fn lower_trait_bound_modifiers(
2677 &mut self,
2678 modifiers: TraitBoundModifiers,
2679 ) -> hir::TraitBoundModifiers {
2680 let constness = match modifiers.constness {
2681 BoundConstness::Never => BoundConstness::Never,
2682 BoundConstness::Always(span) => BoundConstness::Always(self.lower_span(span)),
2683 BoundConstness::Maybe(span) => BoundConstness::Maybe(self.lower_span(span)),
2684 };
2685 let polarity = match modifiers.polarity {
2686 BoundPolarity::Positive => BoundPolarity::Positive,
2687 BoundPolarity::Negative(span) => BoundPolarity::Negative(self.lower_span(span)),
2688 BoundPolarity::Maybe(span) => BoundPolarity::Maybe(self.lower_span(span)),
2689 };
2690 hir::TraitBoundModifiers { constness, polarity }
2691 }
2692
2693 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2696 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2697 }
2698
2699 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2700 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2701 }
2702
2703 fn stmt_let_pat(
2704 &mut self,
2705 attrs: Option<&'hir [hir::Attribute]>,
2706 span: Span,
2707 init: Option<&'hir hir::Expr<'hir>>,
2708 pat: &'hir hir::Pat<'hir>,
2709 source: hir::LocalSource,
2710 ) -> hir::Stmt<'hir> {
2711 let hir_id = self.next_id();
2712 if let Some(a) = attrs {
2713 assert!(!a.is_empty());
2714 self.attrs.insert(hir_id.local_id, a);
2715 }
2716 let local = hir::LetStmt {
2717 super_: None,
2718 hir_id,
2719 init,
2720 pat,
2721 els: None,
2722 source,
2723 span: self.lower_span(span),
2724 ty: None,
2725 };
2726 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2727 }
2728
2729 fn stmt_super_let_pat(
2730 &mut self,
2731 span: Span,
2732 pat: &'hir hir::Pat<'hir>,
2733 init: Option<&'hir hir::Expr<'hir>>,
2734 ) -> hir::Stmt<'hir> {
2735 let hir_id = self.next_id();
2736 let span = self.lower_span(span);
2737 let local = hir::LetStmt {
2738 super_: Some(span),
2739 hir_id,
2740 init,
2741 pat,
2742 els: None,
2743 source: hir::LocalSource::Normal,
2744 span,
2745 ty: None,
2746 };
2747 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2748 }
2749
2750 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2751 self.block_all(expr.span, &[], Some(expr))
2752 }
2753
2754 fn block_all(
2755 &mut self,
2756 span: Span,
2757 stmts: &'hir [hir::Stmt<'hir>],
2758 expr: Option<&'hir hir::Expr<'hir>>,
2759 ) -> &'hir hir::Block<'hir> {
2760 let blk = hir::Block {
2761 stmts,
2762 expr,
2763 hir_id: self.next_id(),
2764 rules: hir::BlockCheckMode::DefaultBlock,
2765 span: self.lower_span(span),
2766 targeted_by_break: false,
2767 };
2768 self.arena.alloc(blk)
2769 }
2770
2771 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2772 let field = self.single_pat_field(span, pat);
2773 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2774 }
2775
2776 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2777 let field = self.single_pat_field(span, pat);
2778 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2779 }
2780
2781 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2782 let field = self.single_pat_field(span, pat);
2783 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2784 }
2785
2786 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2787 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2788 }
2789
2790 fn single_pat_field(
2791 &mut self,
2792 span: Span,
2793 pat: &'hir hir::Pat<'hir>,
2794 ) -> &'hir [hir::PatField<'hir>] {
2795 let field = hir::PatField {
2796 hir_id: self.next_id(),
2797 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2798 is_shorthand: false,
2799 pat,
2800 span: self.lower_span(span),
2801 };
2802 arena_vec![self; field]
2803 }
2804
2805 fn pat_lang_item_variant(
2806 &mut self,
2807 span: Span,
2808 lang_item: hir::LangItem,
2809 fields: &'hir [hir::PatField<'hir>],
2810 ) -> &'hir hir::Pat<'hir> {
2811 let path = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
2812 self.pat(span, hir::PatKind::Struct(path, fields, None))
2813 }
2814
2815 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2816 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2817 }
2818
2819 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2820 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2821 }
2822
2823 fn pat_ident_binding_mode(
2824 &mut self,
2825 span: Span,
2826 ident: Ident,
2827 bm: hir::BindingMode,
2828 ) -> (&'hir hir::Pat<'hir>, HirId) {
2829 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2830 (self.arena.alloc(pat), hir_id)
2831 }
2832
2833 fn pat_ident_binding_mode_mut(
2834 &mut self,
2835 span: Span,
2836 ident: Ident,
2837 bm: hir::BindingMode,
2838 ) -> (hir::Pat<'hir>, HirId) {
2839 let hir_id = self.next_id();
2840
2841 (
2842 hir::Pat {
2843 hir_id,
2844 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2845 span: self.lower_span(span),
2846 default_binding_modes: true,
2847 },
2848 hir_id,
2849 )
2850 }
2851
2852 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2853 self.arena.alloc(hir::Pat {
2854 hir_id: self.next_id(),
2855 kind,
2856 span: self.lower_span(span),
2857 default_binding_modes: true,
2858 })
2859 }
2860
2861 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2862 hir::Pat {
2863 hir_id: self.next_id(),
2864 kind,
2865 span: self.lower_span(span),
2866 default_binding_modes: false,
2867 }
2868 }
2869
2870 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2871 let kind = match qpath {
2872 hir::QPath::Resolved(None, path) => {
2873 match path.res {
2875 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2876 let principal = hir::PolyTraitRef {
2877 bound_generic_params: &[],
2878 modifiers: hir::TraitBoundModifiers::NONE,
2879 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2880 span: self.lower_span(span),
2881 };
2882
2883 hir_id = self.next_id();
2886 hir::TyKind::TraitObject(
2887 arena_vec![self; principal],
2888 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2889 )
2890 }
2891 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2892 }
2893 }
2894 _ => hir::TyKind::Path(qpath),
2895 };
2896
2897 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2898 }
2899
2900 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2905 let r = hir::Lifetime::new(
2906 self.next_id(),
2907 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2908 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2909 LifetimeSource::Other,
2910 LifetimeSyntax::Implicit,
2911 );
2912 debug!("elided_dyn_bound: r={:?}", r);
2913 self.arena.alloc(r)
2914 }
2915}
2916
2917struct GenericArgsCtor<'hir> {
2919 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2920 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2921 parenthesized: hir::GenericArgsParentheses,
2922 span: Span,
2923}
2924
2925impl<'hir> GenericArgsCtor<'hir> {
2926 fn is_empty(&self) -> bool {
2927 self.args.is_empty()
2928 && self.constraints.is_empty()
2929 && self.parenthesized == hir::GenericArgsParentheses::No
2930 }
2931
2932 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2933 let ga = hir::GenericArgs {
2934 args: this.arena.alloc_from_iter(self.args),
2935 constraints: self.constraints,
2936 parenthesized: self.parenthesized,
2937 span_ext: this.lower_span(self.span),
2938 };
2939 this.arena.alloc(ga)
2940 }
2941}