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(ty, itctx).into(),
1129 Term::Const(c) => self.lower_anon_const_to_const_arg(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(ty, itctx).try_as_ambig_ty().unwrap())
1254 }
1255 ast::GenericArg::Const(ct) => {
1256 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1257 }
1258 }
1259 }
1260
1261 #[instrument(level = "debug", skip(self))]
1262 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1263 self.arena.alloc(self.lower_ty_direct(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_direct(&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(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(&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_direct(ty, itctx))),
1371 ),
1372 TyKind::Paren(ty) => {
1373 return self.lower_ty_direct(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(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(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_direct(¶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(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(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 self.lower_attrs(hir_id, ¶m.attrs, param.span(), Target::Param);
1990 hir::GenericParam {
1991 hir_id,
1992 def_id: self.local_def_id(param.id),
1993 name,
1994 span: self.lower_span(param.span()),
1995 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1996 kind,
1997 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1998 source,
1999 }
2000 }
2001
2002 fn lower_generic_param_kind(
2003 &mut self,
2004 param: &GenericParam,
2005 source: hir::GenericParamSource,
2006 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
2007 match ¶m.kind {
2008 GenericParamKind::Lifetime => {
2009 let ident = self.lower_ident(param.ident);
2012 let param_name =
2013 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
2014 ParamName::Error(ident)
2015 } else {
2016 ParamName::Plain(ident)
2017 };
2018 let kind =
2019 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
2020
2021 (param_name, kind)
2022 }
2023 GenericParamKind::Type { default, .. } => {
2024 let default = default
2027 .as_ref()
2028 .filter(|_| match source {
2029 hir::GenericParamSource::Generics => true,
2030 hir::GenericParamSource::Binder => {
2031 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2032 span: param.span(),
2033 });
2034
2035 false
2036 }
2037 })
2038 .map(|def| {
2039 self.lower_ty(
2040 def,
2041 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
2042 )
2043 });
2044
2045 let kind = hir::GenericParamKind::Type { default, synthetic: false };
2046
2047 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
2048 }
2049 GenericParamKind::Const { ty, span: _, default } => {
2050 let ty = self
2051 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
2052
2053 let default = default
2056 .as_ref()
2057 .filter(|_| match source {
2058 hir::GenericParamSource::Generics => true,
2059 hir::GenericParamSource::Binder => {
2060 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2061 span: param.span(),
2062 });
2063
2064 false
2065 }
2066 })
2067 .map(|def| self.lower_anon_const_to_const_arg(def));
2068
2069 (
2070 hir::ParamName::Plain(self.lower_ident(param.ident)),
2071 hir::GenericParamKind::Const { ty, default },
2072 )
2073 }
2074 }
2075 }
2076
2077 fn lower_trait_ref(
2078 &mut self,
2079 modifiers: ast::TraitBoundModifiers,
2080 p: &TraitRef,
2081 itctx: ImplTraitContext,
2082 ) -> hir::TraitRef<'hir> {
2083 let path = match self.lower_qpath(
2084 p.ref_id,
2085 &None,
2086 &p.path,
2087 ParamMode::Explicit,
2088 AllowReturnTypeNotation::No,
2089 itctx,
2090 Some(modifiers),
2091 ) {
2092 hir::QPath::Resolved(None, path) => path,
2093 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2094 };
2095 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2096 }
2097
2098 #[instrument(level = "debug", skip(self))]
2099 fn lower_poly_trait_ref(
2100 &mut self,
2101 PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2102 rbp: RelaxedBoundPolicy<'_>,
2103 itctx: ImplTraitContext,
2104 ) -> hir::PolyTraitRef<'hir> {
2105 let bound_generic_params =
2106 self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
2107 let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
2108 let modifiers = self.lower_trait_bound_modifiers(*modifiers);
2109
2110 if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2111 self.validate_relaxed_bound(trait_ref, *span, rbp);
2112 }
2113
2114 hir::PolyTraitRef {
2115 bound_generic_params,
2116 modifiers,
2117 trait_ref,
2118 span: self.lower_span(*span),
2119 }
2120 }
2121
2122 fn validate_relaxed_bound(
2123 &self,
2124 trait_ref: hir::TraitRef<'_>,
2125 span: Span,
2126 rbp: RelaxedBoundPolicy<'_>,
2127 ) {
2128 match rbp {
2138 RelaxedBoundPolicy::Allowed => return,
2139 RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2140 if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
2141 && let Res::Def(DefKind::TyParam, def_id) = res
2142 && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2143 {
2144 return;
2145 }
2146 }
2147 RelaxedBoundPolicy::Forbidden(reason) => {
2148 let gate = |context, subject| {
2149 let extended = self.tcx.features().more_maybe_bounds();
2150 let is_sized = trait_ref
2151 .trait_def_id()
2152 .is_some_and(|def_id| self.tcx.is_lang_item(def_id, hir::LangItem::Sized));
2153
2154 if extended && !is_sized {
2155 return;
2156 }
2157
2158 let prefix = if extended { "`Sized` " } else { "" };
2159 let mut diag = self.dcx().struct_span_err(
2160 span,
2161 format!("relaxed {prefix}bounds are not permitted in {context}"),
2162 );
2163 if is_sized {
2164 diag.note(format!(
2165 "{subject} are not implicitly bounded by `Sized`, \
2166 so there is nothing to relax"
2167 ));
2168 }
2169 diag.emit();
2170 };
2171
2172 match reason {
2173 RelaxedBoundForbiddenReason::TraitObjectTy => {
2174 gate("trait object types", "trait object types");
2175 return;
2176 }
2177 RelaxedBoundForbiddenReason::SuperTrait => {
2178 gate("supertrait bounds", "traits");
2179 return;
2180 }
2181 RelaxedBoundForbiddenReason::TraitAlias => {
2182 gate("trait alias bounds", "trait aliases");
2183 return;
2184 }
2185 RelaxedBoundForbiddenReason::AssocTyBounds
2186 | RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2187 };
2188 }
2189 }
2190
2191 self.dcx()
2192 .struct_span_err(span, "this relaxed bound is not permitted here")
2193 .with_note(
2194 "in this context, relaxed bounds are only allowed on \
2195 type parameters defined on the closest item",
2196 )
2197 .emit();
2198 }
2199
2200 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2201 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2202 }
2203
2204 #[instrument(level = "debug", skip(self), ret)]
2205 fn lower_param_bounds(
2206 &mut self,
2207 bounds: &[GenericBound],
2208 rbp: RelaxedBoundPolicy<'_>,
2209 itctx: ImplTraitContext,
2210 ) -> hir::GenericBounds<'hir> {
2211 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
2212 }
2213
2214 fn lower_param_bounds_mut(
2215 &mut self,
2216 bounds: &[GenericBound],
2217 rbp: RelaxedBoundPolicy<'_>,
2218 itctx: ImplTraitContext,
2219 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2220 bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
2221 }
2222
2223 #[instrument(level = "debug", skip(self), ret)]
2224 fn lower_universal_param_and_bounds(
2225 &mut self,
2226 node_id: NodeId,
2227 span: Span,
2228 ident: Ident,
2229 bounds: &[GenericBound],
2230 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2231 let def_id = self.local_def_id(node_id);
2233 let span = self.lower_span(span);
2234
2235 let param = hir::GenericParam {
2237 hir_id: self.lower_node_id(node_id),
2238 def_id,
2239 name: ParamName::Plain(self.lower_ident(ident)),
2240 pure_wrt_drop: false,
2241 span,
2242 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2243 colon_span: None,
2244 source: hir::GenericParamSource::Generics,
2245 };
2246
2247 let preds = self.lower_generic_bound_predicate(
2248 ident,
2249 node_id,
2250 &GenericParamKind::Type { default: None },
2251 bounds,
2252 None,
2253 span,
2254 RelaxedBoundPolicy::Allowed,
2255 ImplTraitContext::Universal,
2256 hir::PredicateOrigin::ImplTrait,
2257 );
2258
2259 let hir_id = self.next_id();
2260 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2261 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2262 None,
2263 self.arena.alloc(hir::Path {
2264 span,
2265 res,
2266 segments:
2267 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2268 }),
2269 ));
2270
2271 (param, preds, ty)
2272 }
2273
2274 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2277 let block = self.lower_block(b, false);
2278 self.expr_block(block)
2279 }
2280
2281 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2282 match c.value.peel_parens().kind {
2285 ExprKind::Underscore => {
2286 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2287 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2288 }
2289 _ => self.lower_anon_const_to_const_arg(c),
2290 }
2291 }
2292
2293 #[instrument(level = "debug", skip(self))]
2297 fn lower_const_path_to_const_arg(
2298 &mut self,
2299 path: &Path,
2300 res: Res<NodeId>,
2301 ty_id: NodeId,
2302 span: Span,
2303 ) -> &'hir hir::ConstArg<'hir> {
2304 let tcx = self.tcx;
2305
2306 let is_trivial_path = path.is_potential_trivial_const_arg()
2307 && matches!(res, Res::Def(DefKind::ConstParam, _));
2308 let ct_kind = if is_trivial_path || tcx.features().min_generic_const_args() {
2309 let qpath = self.lower_qpath(
2310 ty_id,
2311 &None,
2312 path,
2313 ParamMode::Explicit,
2314 AllowReturnTypeNotation::No,
2315 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2317 None,
2318 );
2319 hir::ConstArgKind::Path(qpath)
2320 } else {
2321 let node_id = self.next_node_id();
2323 let span = self.lower_span(span);
2324
2325 let def_id = self.create_def(
2330 node_id,
2331 None,
2332 DefKind::AnonConst,
2333 DefPathData::LateAnonConst,
2334 span,
2335 );
2336 let hir_id = self.lower_node_id(node_id);
2337
2338 let path_expr = Expr {
2339 id: ty_id,
2340 kind: ExprKind::Path(None, path.clone()),
2341 span,
2342 attrs: AttrVec::new(),
2343 tokens: None,
2344 };
2345
2346 let ct = self.with_new_scopes(span, |this| {
2347 self.arena.alloc(hir::AnonConst {
2348 def_id,
2349 hir_id,
2350 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2351 span,
2352 })
2353 });
2354 hir::ConstArgKind::Anon(ct)
2355 };
2356
2357 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2358 }
2359
2360 fn lower_const_item_rhs(
2361 &mut self,
2362 attrs: &[hir::Attribute],
2363 rhs: Option<&ConstItemRhs>,
2364 span: Span,
2365 ) -> hir::ConstItemRhs<'hir> {
2366 match rhs {
2367 Some(ConstItemRhs::TypeConst(anon)) => {
2368 hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg(anon))
2369 }
2370 None if attr::contains_name(attrs, sym::type_const) => {
2371 let const_arg = ConstArg {
2372 hir_id: self.next_id(),
2373 kind: hir::ConstArgKind::Error(
2374 DUMMY_SP,
2375 self.dcx().span_delayed_bug(DUMMY_SP, "no block"),
2376 ),
2377 };
2378 hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg))
2379 }
2380 Some(ConstItemRhs::Body(body)) => {
2381 hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body)))
2382 }
2383 None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)),
2384 }
2385 }
2386
2387 #[instrument(level = "debug", skip(self), ret)]
2388 fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> {
2389 let overly_complex_const = |this: &mut Self| {
2390 let e = this.dcx().struct_span_err(
2391 expr.span,
2392 "complex const arguments must be placed inside of a `const` block",
2393 );
2394
2395 ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(expr.span, e.emit()) }
2396 };
2397
2398 match &expr.kind {
2399 ExprKind::Path(qself, path) => {
2400 let qpath = self.lower_qpath(
2401 expr.id,
2402 qself,
2403 path,
2404 ParamMode::Explicit,
2405 AllowReturnTypeNotation::No,
2406 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2408 None,
2409 );
2410
2411 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) }
2412 }
2413 ExprKind::Underscore => ConstArg {
2414 hir_id: self.lower_node_id(expr.id),
2415 kind: hir::ConstArgKind::Infer(expr.span, ()),
2416 },
2417 ExprKind::Block(block, _) => {
2418 if let [stmt] = block.stmts.as_slice()
2419 && let StmtKind::Expr(expr) = &stmt.kind
2420 && matches!(
2421 expr.kind,
2422 ExprKind::Block(..) | ExprKind::Path(..) | ExprKind::Struct(..)
2423 )
2424 {
2425 return self.lower_expr_to_const_arg_direct(expr);
2426 }
2427
2428 overly_complex_const(self)
2429 }
2430 _ => overly_complex_const(self),
2431 }
2432 }
2433
2434 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2437 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2438 }
2439
2440 #[instrument(level = "debug", skip(self))]
2441 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2442 let tcx = self.tcx;
2443
2444 if tcx.features().min_generic_const_args() {
2450 return match anon.mgca_disambiguation {
2451 MgcaDisambiguation::AnonConst => {
2452 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2453 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2454 }
2455 MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value),
2456 };
2457 }
2458
2459 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2462 && let [stmt] = block.stmts.as_slice()
2463 && let StmtKind::Expr(expr) = &stmt.kind
2464 && let ExprKind::Path(..) = &expr.kind
2465 {
2466 expr
2467 } else {
2468 &anon.value
2469 };
2470
2471 let maybe_res =
2472 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2473 if let ExprKind::Path(qself, path) = &expr.kind
2474 && path.is_potential_trivial_const_arg()
2475 && matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _)))
2476 {
2477 let qpath = self.lower_qpath(
2478 expr.id,
2479 qself,
2480 path,
2481 ParamMode::Explicit,
2482 AllowReturnTypeNotation::No,
2483 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2484 None,
2485 );
2486
2487 return ConstArg {
2488 hir_id: self.lower_node_id(anon.id),
2489 kind: hir::ConstArgKind::Path(qpath),
2490 };
2491 }
2492
2493 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2494 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2495 }
2496
2497 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2500 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2501 let def_id = this.local_def_id(c.id);
2502 let hir_id = this.lower_node_id(c.id);
2503 hir::AnonConst {
2504 def_id,
2505 hir_id,
2506 body: this.lower_const_body(c.value.span, Some(&c.value)),
2507 span: this.lower_span(c.value.span),
2508 }
2509 }))
2510 }
2511
2512 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2513 match u {
2514 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2515 UserProvided => hir::UnsafeSource::UserProvided,
2516 }
2517 }
2518
2519 fn lower_trait_bound_modifiers(
2520 &mut self,
2521 modifiers: TraitBoundModifiers,
2522 ) -> hir::TraitBoundModifiers {
2523 let constness = match modifiers.constness {
2524 BoundConstness::Never => BoundConstness::Never,
2525 BoundConstness::Always(span) => BoundConstness::Always(self.lower_span(span)),
2526 BoundConstness::Maybe(span) => BoundConstness::Maybe(self.lower_span(span)),
2527 };
2528 let polarity = match modifiers.polarity {
2529 BoundPolarity::Positive => BoundPolarity::Positive,
2530 BoundPolarity::Negative(span) => BoundPolarity::Negative(self.lower_span(span)),
2531 BoundPolarity::Maybe(span) => BoundPolarity::Maybe(self.lower_span(span)),
2532 };
2533 hir::TraitBoundModifiers { constness, polarity }
2534 }
2535
2536 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2539 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2540 }
2541
2542 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2543 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2544 }
2545
2546 fn stmt_let_pat(
2547 &mut self,
2548 attrs: Option<&'hir [hir::Attribute]>,
2549 span: Span,
2550 init: Option<&'hir hir::Expr<'hir>>,
2551 pat: &'hir hir::Pat<'hir>,
2552 source: hir::LocalSource,
2553 ) -> hir::Stmt<'hir> {
2554 let hir_id = self.next_id();
2555 if let Some(a) = attrs {
2556 assert!(!a.is_empty());
2557 self.attrs.insert(hir_id.local_id, a);
2558 }
2559 let local = hir::LetStmt {
2560 super_: None,
2561 hir_id,
2562 init,
2563 pat,
2564 els: None,
2565 source,
2566 span: self.lower_span(span),
2567 ty: None,
2568 };
2569 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2570 }
2571
2572 fn stmt_super_let_pat(
2573 &mut self,
2574 span: Span,
2575 pat: &'hir hir::Pat<'hir>,
2576 init: Option<&'hir hir::Expr<'hir>>,
2577 ) -> hir::Stmt<'hir> {
2578 let hir_id = self.next_id();
2579 let span = self.lower_span(span);
2580 let local = hir::LetStmt {
2581 super_: Some(span),
2582 hir_id,
2583 init,
2584 pat,
2585 els: None,
2586 source: hir::LocalSource::Normal,
2587 span,
2588 ty: None,
2589 };
2590 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2591 }
2592
2593 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2594 self.block_all(expr.span, &[], Some(expr))
2595 }
2596
2597 fn block_all(
2598 &mut self,
2599 span: Span,
2600 stmts: &'hir [hir::Stmt<'hir>],
2601 expr: Option<&'hir hir::Expr<'hir>>,
2602 ) -> &'hir hir::Block<'hir> {
2603 let blk = hir::Block {
2604 stmts,
2605 expr,
2606 hir_id: self.next_id(),
2607 rules: hir::BlockCheckMode::DefaultBlock,
2608 span: self.lower_span(span),
2609 targeted_by_break: false,
2610 };
2611 self.arena.alloc(blk)
2612 }
2613
2614 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2615 let field = self.single_pat_field(span, pat);
2616 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2617 }
2618
2619 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2620 let field = self.single_pat_field(span, pat);
2621 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2622 }
2623
2624 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2625 let field = self.single_pat_field(span, pat);
2626 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2627 }
2628
2629 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2630 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2631 }
2632
2633 fn single_pat_field(
2634 &mut self,
2635 span: Span,
2636 pat: &'hir hir::Pat<'hir>,
2637 ) -> &'hir [hir::PatField<'hir>] {
2638 let field = hir::PatField {
2639 hir_id: self.next_id(),
2640 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2641 is_shorthand: false,
2642 pat,
2643 span: self.lower_span(span),
2644 };
2645 arena_vec![self; field]
2646 }
2647
2648 fn pat_lang_item_variant(
2649 &mut self,
2650 span: Span,
2651 lang_item: hir::LangItem,
2652 fields: &'hir [hir::PatField<'hir>],
2653 ) -> &'hir hir::Pat<'hir> {
2654 let path = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
2655 self.pat(span, hir::PatKind::Struct(path, fields, None))
2656 }
2657
2658 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2659 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2660 }
2661
2662 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2663 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2664 }
2665
2666 fn pat_ident_binding_mode(
2667 &mut self,
2668 span: Span,
2669 ident: Ident,
2670 bm: hir::BindingMode,
2671 ) -> (&'hir hir::Pat<'hir>, HirId) {
2672 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2673 (self.arena.alloc(pat), hir_id)
2674 }
2675
2676 fn pat_ident_binding_mode_mut(
2677 &mut self,
2678 span: Span,
2679 ident: Ident,
2680 bm: hir::BindingMode,
2681 ) -> (hir::Pat<'hir>, HirId) {
2682 let hir_id = self.next_id();
2683
2684 (
2685 hir::Pat {
2686 hir_id,
2687 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2688 span: self.lower_span(span),
2689 default_binding_modes: true,
2690 },
2691 hir_id,
2692 )
2693 }
2694
2695 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2696 self.arena.alloc(hir::Pat {
2697 hir_id: self.next_id(),
2698 kind,
2699 span: self.lower_span(span),
2700 default_binding_modes: true,
2701 })
2702 }
2703
2704 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2705 hir::Pat {
2706 hir_id: self.next_id(),
2707 kind,
2708 span: self.lower_span(span),
2709 default_binding_modes: false,
2710 }
2711 }
2712
2713 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2714 let kind = match qpath {
2715 hir::QPath::Resolved(None, path) => {
2716 match path.res {
2718 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2719 let principal = hir::PolyTraitRef {
2720 bound_generic_params: &[],
2721 modifiers: hir::TraitBoundModifiers::NONE,
2722 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2723 span: self.lower_span(span),
2724 };
2725
2726 hir_id = self.next_id();
2729 hir::TyKind::TraitObject(
2730 arena_vec![self; principal],
2731 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2732 )
2733 }
2734 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2735 }
2736 }
2737 _ => hir::TyKind::Path(qpath),
2738 };
2739
2740 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2741 }
2742
2743 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2748 let r = hir::Lifetime::new(
2749 self.next_id(),
2750 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2751 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2752 LifetimeSource::Other,
2753 LifetimeSyntax::Implicit,
2754 );
2755 debug!("elided_dyn_bound: r={:?}", r);
2756 self.arena.alloc(r)
2757 }
2758}
2759
2760struct GenericArgsCtor<'hir> {
2762 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2763 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2764 parenthesized: hir::GenericArgsParentheses,
2765 span: Span,
2766}
2767
2768impl<'hir> GenericArgsCtor<'hir> {
2769 fn is_empty(&self) -> bool {
2770 self.args.is_empty()
2771 && self.constraints.is_empty()
2772 && self.parenthesized == hir::GenericArgsParentheses::No
2773 }
2774
2775 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2776 let ga = hir::GenericArgs {
2777 args: this.arena.alloc_from_iter(self.args),
2778 constraints: self.constraints,
2779 parenthesized: self.parenthesized,
2780 span_ext: this.lower_span(self.span),
2781 };
2782 this.arena.alloc(ga)
2783 }
2784}