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