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 if attrs.is_empty() {
975 &[]
976 } else {
977 let lowered_attrs =
978 self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);
979
980 assert_eq!(id.owner, self.current_hir_id_owner);
981 let ret = self.arena.alloc_from_iter(lowered_attrs);
982
983 if ret.is_empty() {
990 &[]
991 } else {
992 self.attrs.insert(id.local_id, ret);
993 ret
994 }
995 }
996 }
997
998 fn lower_attrs_vec(
999 &mut self,
1000 attrs: &[Attribute],
1001 target_span: Span,
1002 target_hir_id: HirId,
1003 target: Target,
1004 ) -> Vec<hir::Attribute> {
1005 let l = self.span_lowerer();
1006 self.attribute_parser.parse_attribute_list(
1007 attrs,
1008 target_span,
1009 target_hir_id,
1010 target,
1011 OmitDoc::Lower,
1012 |s| l.lower(s),
1013 |l| {
1014 self.delayed_lints.push(DelayedLint::AttributeParsing(l));
1015 },
1016 )
1017 }
1018
1019 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
1020 assert_eq!(id.owner, self.current_hir_id_owner);
1021 assert_eq!(target_id.owner, self.current_hir_id_owner);
1022 if let Some(&a) = self.attrs.get(&target_id.local_id) {
1023 assert!(!a.is_empty());
1024 self.attrs.insert(id.local_id, a);
1025 }
1026 }
1027
1028 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
1029 args.clone()
1030 }
1031
1032 #[instrument(level = "debug", skip_all)]
1034 fn lower_assoc_item_constraint(
1035 &mut self,
1036 constraint: &AssocItemConstraint,
1037 itctx: ImplTraitContext,
1038 ) -> hir::AssocItemConstraint<'hir> {
1039 debug!(?constraint, ?itctx);
1040 let gen_args = if let Some(gen_args) = &constraint.gen_args {
1042 let gen_args_ctor = match gen_args {
1043 GenericArgs::AngleBracketed(data) => {
1044 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
1045 }
1046 GenericArgs::Parenthesized(data) => {
1047 if let Some(first_char) = constraint.ident.as_str().chars().next()
1048 && first_char.is_ascii_lowercase()
1049 {
1050 let err = match (&data.inputs[..], &data.output) {
1051 ([_, ..], FnRetTy::Default(_)) => {
1052 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
1053 }
1054 ([], FnRetTy::Default(_)) => {
1055 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
1056 }
1057 (_, FnRetTy::Ty(ty)) => {
1059 let span = data.inputs_span.shrink_to_hi().to(ty.span);
1060 errors::BadReturnTypeNotation::Output {
1061 span,
1062 suggestion: errors::RTNSuggestion {
1063 output: span,
1064 input: data.inputs_span,
1065 },
1066 }
1067 }
1068 };
1069 let mut err = self.dcx().create_err(err);
1070 if !self.tcx.features().return_type_notation()
1071 && self.tcx.sess.is_nightly_build()
1072 {
1073 add_feature_diagnostics(
1074 &mut err,
1075 &self.tcx.sess,
1076 sym::return_type_notation,
1077 );
1078 }
1079 err.emit();
1080 GenericArgsCtor {
1081 args: Default::default(),
1082 constraints: &[],
1083 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1084 span: data.span,
1085 }
1086 } else {
1087 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
1088 self.lower_angle_bracketed_parameter_data(
1091 &data.as_angle_bracketed_args(),
1092 ParamMode::Explicit,
1093 itctx,
1094 )
1095 .0
1096 }
1097 }
1098 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
1099 args: Default::default(),
1100 constraints: &[],
1101 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1102 span: *span,
1103 },
1104 };
1105 gen_args_ctor.into_generic_args(self)
1106 } else {
1107 self.arena.alloc(hir::GenericArgs::none())
1108 };
1109 let kind = match &constraint.kind {
1110 AssocItemConstraintKind::Equality { term } => {
1111 let term = match term {
1112 Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1113 Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1114 };
1115 hir::AssocItemConstraintKind::Equality { term }
1116 }
1117 AssocItemConstraintKind::Bound { bounds } => {
1118 if self.is_in_dyn_type {
1120 let suggestion = match itctx {
1121 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1122 let bound_end_span = constraint
1123 .gen_args
1124 .as_ref()
1125 .map_or(constraint.ident.span, |args| args.span());
1126 if bound_end_span.eq_ctxt(constraint.span) {
1127 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1128 } else {
1129 None
1130 }
1131 }
1132 _ => None,
1133 };
1134
1135 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1136 span: constraint.span,
1137 suggestion,
1138 });
1139 let err_ty =
1140 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1141 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1142 } else {
1143 let bounds = self.lower_param_bounds(
1144 bounds,
1145 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),
1146 itctx,
1147 );
1148 hir::AssocItemConstraintKind::Bound { bounds }
1149 }
1150 }
1151 };
1152
1153 hir::AssocItemConstraint {
1154 hir_id: self.lower_node_id(constraint.id),
1155 ident: self.lower_ident(constraint.ident),
1156 gen_args,
1157 kind,
1158 span: self.lower_span(constraint.span),
1159 }
1160 }
1161
1162 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1163 let sub = if data.inputs.is_empty() {
1165 let parentheses_span =
1166 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1167 AssocTyParenthesesSub::Empty { parentheses_span }
1168 }
1169 else {
1171 let open_param = data.inputs_span.shrink_to_lo().to(data
1173 .inputs
1174 .first()
1175 .unwrap()
1176 .span
1177 .shrink_to_lo());
1178 let close_param =
1180 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1181 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1182 };
1183 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1184 }
1185
1186 #[instrument(level = "debug", skip(self))]
1187 fn lower_generic_arg(
1188 &mut self,
1189 arg: &ast::GenericArg,
1190 itctx: ImplTraitContext,
1191 ) -> hir::GenericArg<'hir> {
1192 match arg {
1193 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1194 lt,
1195 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1196 lt.ident.into(),
1197 )),
1198 ast::GenericArg::Type(ty) => {
1199 if ty.is_maybe_parenthesised_infer() {
1202 return GenericArg::Infer(hir::InferArg {
1203 hir_id: self.lower_node_id(ty.id),
1204 span: self.lower_span(ty.span),
1205 });
1206 }
1207
1208 match &ty.kind {
1209 TyKind::Path(None, path) => {
1216 if let Some(res) = self
1217 .resolver
1218 .get_partial_res(ty.id)
1219 .and_then(|partial_res| partial_res.full_res())
1220 {
1221 if !res.matches_ns(Namespace::TypeNS)
1222 && path.is_potential_trivial_const_arg(false)
1223 {
1224 debug!(
1225 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1226 ty,
1227 );
1228
1229 let ct =
1230 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1231 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1232 }
1233 }
1234 }
1235 _ => {}
1236 }
1237 GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1238 }
1239 ast::GenericArg::Const(ct) => {
1240 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1241 }
1242 }
1243 }
1244
1245 #[instrument(level = "debug", skip(self))]
1246 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1247 self.arena.alloc(self.lower_ty_direct(t, itctx))
1248 }
1249
1250 fn lower_path_ty(
1251 &mut self,
1252 t: &Ty,
1253 qself: &Option<Box<QSelf>>,
1254 path: &Path,
1255 param_mode: ParamMode,
1256 itctx: ImplTraitContext,
1257 ) -> hir::Ty<'hir> {
1258 if qself.is_none()
1264 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1265 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1266 {
1267 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1268 let bound = this.lower_poly_trait_ref(
1269 &PolyTraitRef {
1270 bound_generic_params: ThinVec::new(),
1271 modifiers: TraitBoundModifiers::NONE,
1272 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1273 span: t.span,
1274 parens: ast::Parens::No,
1275 },
1276 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),
1277 itctx,
1278 );
1279 let bounds = this.arena.alloc_from_iter([bound]);
1280 let lifetime_bound = this.elided_dyn_bound(t.span);
1281 (bounds, lifetime_bound)
1282 });
1283 let kind = hir::TyKind::TraitObject(
1284 bounds,
1285 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1286 );
1287 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1288 }
1289
1290 let id = self.lower_node_id(t.id);
1291 let qpath = self.lower_qpath(
1292 t.id,
1293 qself,
1294 path,
1295 param_mode,
1296 AllowReturnTypeNotation::Yes,
1297 itctx,
1298 None,
1299 );
1300 self.ty_path(id, t.span, qpath)
1301 }
1302
1303 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1304 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1305 }
1306
1307 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1308 self.ty(span, hir::TyKind::Tup(tys))
1309 }
1310
1311 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1312 let kind = match &t.kind {
1313 TyKind::Infer => hir::TyKind::Infer(()),
1314 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1315 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1316 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1317 TyKind::Ref(region, mt) => {
1318 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1319 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1320 }
1321 TyKind::PinnedRef(region, mt) => {
1322 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1323 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1324 let span = self.lower_span(t.span);
1325 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1326 let args = self.arena.alloc(hir::GenericArgs {
1327 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1328 constraints: &[],
1329 parenthesized: hir::GenericArgsParentheses::No,
1330 span_ext: span,
1331 });
1332 let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));
1333 hir::TyKind::Path(path)
1334 }
1335 TyKind::FnPtr(f) => {
1336 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1337 hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {
1338 generic_params,
1339 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1340 abi: self.lower_extern(f.ext),
1341 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1342 param_idents: self.lower_fn_params_to_idents(&f.decl),
1343 }))
1344 }
1345 TyKind::UnsafeBinder(f) => {
1346 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1347 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1348 generic_params,
1349 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1350 }))
1351 }
1352 TyKind::Never => hir::TyKind::Never,
1353 TyKind::Tup(tys) => hir::TyKind::Tup(
1354 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1355 ),
1356 TyKind::Paren(ty) => {
1357 return self.lower_ty_direct(ty, itctx);
1358 }
1359 TyKind::Path(qself, path) => {
1360 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1361 }
1362 TyKind::ImplicitSelf => {
1363 let hir_id = self.next_id();
1364 let res = self.expect_full_res(t.id);
1365 let res = self.lower_res(res);
1366 hir::TyKind::Path(hir::QPath::Resolved(
1367 None,
1368 self.arena.alloc(hir::Path {
1369 res,
1370 segments: arena_vec![self; hir::PathSegment::new(
1371 Ident::with_dummy_span(kw::SelfUpper),
1372 hir_id,
1373 res
1374 )],
1375 span: self.lower_span(t.span),
1376 }),
1377 ))
1378 }
1379 TyKind::Array(ty, length) => hir::TyKind::Array(
1380 self.lower_ty(ty, itctx),
1381 self.lower_array_length_to_const_arg(length),
1382 ),
1383 TyKind::TraitObject(bounds, kind) => {
1384 let mut lifetime_bound = None;
1385 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1386 let bounds =
1387 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1388 GenericBound::Trait(ty) => {
1392 let trait_ref = this.lower_poly_trait_ref(
1393 ty,
1394 RelaxedBoundPolicy::Forbidden(
1395 RelaxedBoundForbiddenReason::TraitObjectTy,
1396 ),
1397 itctx,
1398 );
1399 Some(trait_ref)
1400 }
1401 GenericBound::Outlives(lifetime) => {
1402 if lifetime_bound.is_none() {
1403 lifetime_bound = Some(this.lower_lifetime(
1404 lifetime,
1405 LifetimeSource::Other,
1406 lifetime.ident.into(),
1407 ));
1408 }
1409 None
1410 }
1411 GenericBound::Use(_, span) => {
1413 this.dcx()
1414 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1415 None
1416 }
1417 }));
1418 let lifetime_bound =
1419 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1420 (bounds, lifetime_bound)
1421 });
1422 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1423 }
1424 TyKind::ImplTrait(def_node_id, bounds) => {
1425 let span = t.span;
1426 match itctx {
1427 ImplTraitContext::OpaqueTy { origin } => {
1428 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1429 }
1430 ImplTraitContext::Universal => {
1431 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1432 ast::GenericBound::Use(_, span) => Some(span),
1433 _ => None,
1434 }) {
1435 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1436 }
1437
1438 let def_id = self.local_def_id(*def_node_id);
1439 let name = self.tcx.item_name(def_id.to_def_id());
1440 let ident = Ident::new(name, span);
1441 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1442 *def_node_id,
1443 span,
1444 ident,
1445 bounds,
1446 );
1447 self.impl_trait_defs.push(param);
1448 if let Some(bounds) = bounds {
1449 self.impl_trait_bounds.push(bounds);
1450 }
1451 path
1452 }
1453 ImplTraitContext::InBinding => hir::TyKind::TraitAscription(
1454 self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),
1455 ),
1456 ImplTraitContext::FeatureGated(position, feature) => {
1457 let guar = self
1458 .tcx
1459 .sess
1460 .create_feature_err(
1461 MisplacedImplTrait {
1462 span: t.span,
1463 position: DiagArgFromDisplay(&position),
1464 },
1465 feature,
1466 )
1467 .emit();
1468 hir::TyKind::Err(guar)
1469 }
1470 ImplTraitContext::Disallowed(position) => {
1471 let guar = self.dcx().emit_err(MisplacedImplTrait {
1472 span: t.span,
1473 position: DiagArgFromDisplay(&position),
1474 });
1475 hir::TyKind::Err(guar)
1476 }
1477 }
1478 }
1479 TyKind::Pat(ty, pat) => {
1480 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1481 }
1482 TyKind::MacCall(_) => {
1483 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1484 }
1485 TyKind::CVarArgs => {
1486 let guar = self.dcx().span_delayed_bug(
1487 t.span,
1488 "`TyKind::CVarArgs` should have been handled elsewhere",
1489 );
1490 hir::TyKind::Err(guar)
1491 }
1492 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1493 };
1494
1495 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1496 }
1497
1498 fn lower_ty_direct_lifetime(
1499 &mut self,
1500 t: &Ty,
1501 region: Option<Lifetime>,
1502 ) -> &'hir hir::Lifetime {
1503 let (region, syntax) = match region {
1504 Some(region) => (region, region.ident.into()),
1505
1506 None => {
1507 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1508 self.resolver.get_lifetime_res(t.id)
1509 {
1510 assert_eq!(start.plus(1), end);
1511 start
1512 } else {
1513 self.next_node_id()
1514 };
1515 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1516 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1517 (region, LifetimeSyntax::Implicit)
1518 }
1519 };
1520 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1521 }
1522
1523 #[instrument(level = "debug", skip(self), ret)]
1555 fn lower_opaque_impl_trait(
1556 &mut self,
1557 span: Span,
1558 origin: hir::OpaqueTyOrigin<LocalDefId>,
1559 opaque_ty_node_id: NodeId,
1560 bounds: &GenericBounds,
1561 itctx: ImplTraitContext,
1562 ) -> hir::TyKind<'hir> {
1563 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1569
1570 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1571 this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)
1572 })
1573 }
1574
1575 fn lower_opaque_inner(
1576 &mut self,
1577 opaque_ty_node_id: NodeId,
1578 origin: hir::OpaqueTyOrigin<LocalDefId>,
1579 opaque_ty_span: Span,
1580 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1581 ) -> hir::TyKind<'hir> {
1582 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1583 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1584 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1585
1586 let bounds = lower_item_bounds(self);
1587 let opaque_ty_def = hir::OpaqueTy {
1588 hir_id: opaque_ty_hir_id,
1589 def_id: opaque_ty_def_id,
1590 bounds,
1591 origin,
1592 span: self.lower_span(opaque_ty_span),
1593 };
1594 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1595
1596 hir::TyKind::OpaqueDef(opaque_ty_def)
1597 }
1598
1599 fn lower_precise_capturing_args(
1600 &mut self,
1601 precise_capturing_args: &[PreciseCapturingArg],
1602 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1603 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1604 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1605 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1606 ),
1607 PreciseCapturingArg::Arg(path, id) => {
1608 let [segment] = path.segments.as_slice() else {
1609 panic!();
1610 };
1611 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1612 partial_res.full_res().expect("no partial res expected for precise capture arg")
1613 });
1614 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1615 hir_id: self.lower_node_id(*id),
1616 ident: self.lower_ident(segment.ident),
1617 res: self.lower_res(res),
1618 })
1619 }
1620 }))
1621 }
1622
1623 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1624 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1625 PatKind::Missing => None,
1626 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1627 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1628 _ => {
1629 self.dcx().span_delayed_bug(
1630 param.pat.span,
1631 "non-missing/ident/wild param pat must trigger an error",
1632 );
1633 None
1634 }
1635 }))
1636 }
1637
1638 #[instrument(level = "debug", skip(self))]
1648 fn lower_fn_decl(
1649 &mut self,
1650 decl: &FnDecl,
1651 fn_node_id: NodeId,
1652 fn_span: Span,
1653 kind: FnDeclKind,
1654 coro: Option<CoroutineKind>,
1655 ) -> &'hir hir::FnDecl<'hir> {
1656 let c_variadic = decl.c_variadic();
1657
1658 let mut inputs = &decl.inputs[..];
1662 if c_variadic {
1663 inputs = &inputs[..inputs.len() - 1];
1664 }
1665 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1666 let itctx = match kind {
1667 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1668 ImplTraitContext::Universal
1669 }
1670 FnDeclKind::ExternFn => {
1671 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1672 }
1673 FnDeclKind::Closure => {
1674 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1675 }
1676 FnDeclKind::Pointer => {
1677 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1678 }
1679 };
1680 self.lower_ty_direct(¶m.ty, itctx)
1681 }));
1682
1683 let output = match coro {
1684 Some(coro) => {
1685 let fn_def_id = self.local_def_id(fn_node_id);
1686 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)
1687 }
1688 None => match &decl.output {
1689 FnRetTy::Ty(ty) => {
1690 let itctx = match kind {
1691 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1692 origin: hir::OpaqueTyOrigin::FnReturn {
1693 parent: self.local_def_id(fn_node_id),
1694 in_trait_or_impl: None,
1695 },
1696 },
1697 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1698 origin: hir::OpaqueTyOrigin::FnReturn {
1699 parent: self.local_def_id(fn_node_id),
1700 in_trait_or_impl: Some(hir::RpitContext::Trait),
1701 },
1702 },
1703 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1704 origin: hir::OpaqueTyOrigin::FnReturn {
1705 parent: self.local_def_id(fn_node_id),
1706 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1707 },
1708 },
1709 FnDeclKind::ExternFn => {
1710 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1711 }
1712 FnDeclKind::Closure => {
1713 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1714 }
1715 FnDeclKind::Pointer => {
1716 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1717 }
1718 };
1719 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1720 }
1721 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1722 },
1723 };
1724
1725 self.arena.alloc(hir::FnDecl {
1726 inputs,
1727 output,
1728 c_variadic,
1729 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1730 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1731 let is_mutable_pat = matches!(
1732 arg.pat.kind,
1733 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1734 );
1735
1736 match &arg.ty.kind {
1737 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1738 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1739 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1743 if mt.ty.kind.is_implicit_self() =>
1744 {
1745 match mt.mutbl {
1746 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1747 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1748 }
1749 }
1750 _ => hir::ImplicitSelfKind::None,
1751 }
1752 }),
1753 })
1754 }
1755
1756 #[instrument(level = "debug", skip(self))]
1765 fn lower_coroutine_fn_ret_ty(
1766 &mut self,
1767 output: &FnRetTy,
1768 fn_def_id: LocalDefId,
1769 coro: CoroutineKind,
1770 fn_kind: FnDeclKind,
1771 ) -> hir::FnRetTy<'hir> {
1772 let span = self.lower_span(output.span());
1773
1774 let (opaque_ty_node_id, allowed_features) = match coro {
1775 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1776 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1777 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1778 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1779 }
1780 };
1781
1782 let opaque_ty_span =
1783 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1784
1785 let in_trait_or_impl = match fn_kind {
1786 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1787 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1788 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1789 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1790 };
1791
1792 let opaque_ty_ref = self.lower_opaque_inner(
1793 opaque_ty_node_id,
1794 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1795 opaque_ty_span,
1796 |this| {
1797 let bound = this.lower_coroutine_fn_output_type_to_bound(
1798 output,
1799 coro,
1800 opaque_ty_span,
1801 ImplTraitContext::OpaqueTy {
1802 origin: hir::OpaqueTyOrigin::FnReturn {
1803 parent: fn_def_id,
1804 in_trait_or_impl,
1805 },
1806 },
1807 );
1808 arena_vec![this; bound]
1809 },
1810 );
1811
1812 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1813 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1814 }
1815
1816 fn lower_coroutine_fn_output_type_to_bound(
1818 &mut self,
1819 output: &FnRetTy,
1820 coro: CoroutineKind,
1821 opaque_ty_span: Span,
1822 itctx: ImplTraitContext,
1823 ) -> hir::GenericBound<'hir> {
1824 let output_ty = match output {
1826 FnRetTy::Ty(ty) => {
1827 self.lower_ty(ty, itctx)
1831 }
1832 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1833 };
1834
1835 let (assoc_ty_name, trait_lang_item) = match coro {
1837 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1838 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1839 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1840 };
1841
1842 let bound_args = self.arena.alloc(hir::GenericArgs {
1843 args: &[],
1844 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1845 parenthesized: hir::GenericArgsParentheses::No,
1846 span_ext: DUMMY_SP,
1847 });
1848
1849 hir::GenericBound::Trait(hir::PolyTraitRef {
1850 bound_generic_params: &[],
1851 modifiers: hir::TraitBoundModifiers::NONE,
1852 trait_ref: hir::TraitRef {
1853 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1854 hir_ref_id: self.next_id(),
1855 },
1856 span: opaque_ty_span,
1857 })
1858 }
1859
1860 #[instrument(level = "trace", skip(self))]
1861 fn lower_param_bound(
1862 &mut self,
1863 tpb: &GenericBound,
1864 rbp: RelaxedBoundPolicy<'_>,
1865 itctx: ImplTraitContext,
1866 ) -> hir::GenericBound<'hir> {
1867 match tpb {
1868 GenericBound::Trait(p) => {
1869 hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))
1870 }
1871 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1872 lifetime,
1873 LifetimeSource::OutlivesBound,
1874 lifetime.ident.into(),
1875 )),
1876 GenericBound::Use(args, span) => hir::GenericBound::Use(
1877 self.lower_precise_capturing_args(args),
1878 self.lower_span(*span),
1879 ),
1880 }
1881 }
1882
1883 fn lower_lifetime(
1884 &mut self,
1885 l: &Lifetime,
1886 source: LifetimeSource,
1887 syntax: LifetimeSyntax,
1888 ) -> &'hir hir::Lifetime {
1889 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1890 }
1891
1892 fn lower_lifetime_hidden_in_path(
1893 &mut self,
1894 id: NodeId,
1895 span: Span,
1896 angle_brackets: AngleBrackets,
1897 ) -> &'hir hir::Lifetime {
1898 self.new_named_lifetime(
1899 id,
1900 id,
1901 Ident::new(kw::UnderscoreLifetime, span),
1902 LifetimeSource::Path { angle_brackets },
1903 LifetimeSyntax::Implicit,
1904 )
1905 }
1906
1907 #[instrument(level = "debug", skip(self))]
1908 fn new_named_lifetime(
1909 &mut self,
1910 id: NodeId,
1911 new_id: NodeId,
1912 ident: Ident,
1913 source: LifetimeSource,
1914 syntax: LifetimeSyntax,
1915 ) -> &'hir hir::Lifetime {
1916 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1917 let res = match res {
1918 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1919 LifetimeRes::Fresh { param, .. } => {
1920 assert_eq!(ident.name, kw::UnderscoreLifetime);
1921 let param = self.local_def_id(param);
1922 hir::LifetimeKind::Param(param)
1923 }
1924 LifetimeRes::Infer => {
1925 assert_eq!(ident.name, kw::UnderscoreLifetime);
1926 hir::LifetimeKind::Infer
1927 }
1928 LifetimeRes::Static { .. } => {
1929 assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1930 hir::LifetimeKind::Static
1931 }
1932 LifetimeRes::Error => hir::LifetimeKind::Error,
1933 LifetimeRes::ElidedAnchor { .. } => {
1934 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1935 }
1936 };
1937
1938 debug!(?res);
1939 self.arena.alloc(hir::Lifetime::new(
1940 self.lower_node_id(new_id),
1941 self.lower_ident(ident),
1942 res,
1943 source,
1944 syntax,
1945 ))
1946 }
1947
1948 fn lower_generic_params_mut(
1949 &mut self,
1950 params: &[GenericParam],
1951 source: hir::GenericParamSource,
1952 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1953 params.iter().map(move |param| self.lower_generic_param(param, source))
1954 }
1955
1956 fn lower_generic_params(
1957 &mut self,
1958 params: &[GenericParam],
1959 source: hir::GenericParamSource,
1960 ) -> &'hir [hir::GenericParam<'hir>] {
1961 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1962 }
1963
1964 #[instrument(level = "trace", skip(self))]
1965 fn lower_generic_param(
1966 &mut self,
1967 param: &GenericParam,
1968 source: hir::GenericParamSource,
1969 ) -> hir::GenericParam<'hir> {
1970 let (name, kind) = self.lower_generic_param_kind(param, source);
1971
1972 let hir_id = self.lower_node_id(param.id);
1973 self.lower_attrs(hir_id, ¶m.attrs, param.span(), Target::Param);
1974 hir::GenericParam {
1975 hir_id,
1976 def_id: self.local_def_id(param.id),
1977 name,
1978 span: self.lower_span(param.span()),
1979 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1980 kind,
1981 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1982 source,
1983 }
1984 }
1985
1986 fn lower_generic_param_kind(
1987 &mut self,
1988 param: &GenericParam,
1989 source: hir::GenericParamSource,
1990 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1991 match ¶m.kind {
1992 GenericParamKind::Lifetime => {
1993 let ident = self.lower_ident(param.ident);
1996 let param_name =
1997 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1998 ParamName::Error(ident)
1999 } else {
2000 ParamName::Plain(ident)
2001 };
2002 let kind =
2003 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
2004
2005 (param_name, kind)
2006 }
2007 GenericParamKind::Type { default, .. } => {
2008 let default = default
2011 .as_ref()
2012 .filter(|_| match source {
2013 hir::GenericParamSource::Generics => true,
2014 hir::GenericParamSource::Binder => {
2015 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2016 span: param.span(),
2017 });
2018
2019 false
2020 }
2021 })
2022 .map(|def| {
2023 self.lower_ty(
2024 def,
2025 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
2026 )
2027 });
2028
2029 let kind = hir::GenericParamKind::Type { default, synthetic: false };
2030
2031 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
2032 }
2033 GenericParamKind::Const { ty, span: _, default } => {
2034 let ty = self
2035 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
2036
2037 let default = default
2040 .as_ref()
2041 .filter(|_| match source {
2042 hir::GenericParamSource::Generics => true,
2043 hir::GenericParamSource::Binder => {
2044 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2045 span: param.span(),
2046 });
2047
2048 false
2049 }
2050 })
2051 .map(|def| self.lower_anon_const_to_const_arg(def));
2052
2053 (
2054 hir::ParamName::Plain(self.lower_ident(param.ident)),
2055 hir::GenericParamKind::Const { ty, default },
2056 )
2057 }
2058 }
2059 }
2060
2061 fn lower_trait_ref(
2062 &mut self,
2063 modifiers: ast::TraitBoundModifiers,
2064 p: &TraitRef,
2065 itctx: ImplTraitContext,
2066 ) -> hir::TraitRef<'hir> {
2067 let path = match self.lower_qpath(
2068 p.ref_id,
2069 &None,
2070 &p.path,
2071 ParamMode::Explicit,
2072 AllowReturnTypeNotation::No,
2073 itctx,
2074 Some(modifiers),
2075 ) {
2076 hir::QPath::Resolved(None, path) => path,
2077 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2078 };
2079 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2080 }
2081
2082 #[instrument(level = "debug", skip(self))]
2083 fn lower_poly_trait_ref(
2084 &mut self,
2085 PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2086 rbp: RelaxedBoundPolicy<'_>,
2087 itctx: ImplTraitContext,
2088 ) -> hir::PolyTraitRef<'hir> {
2089 let bound_generic_params =
2090 self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
2091 let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
2092 let modifiers = self.lower_trait_bound_modifiers(*modifiers);
2093
2094 if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2095 self.validate_relaxed_bound(trait_ref, *span, rbp);
2096 }
2097
2098 hir::PolyTraitRef {
2099 bound_generic_params,
2100 modifiers,
2101 trait_ref,
2102 span: self.lower_span(*span),
2103 }
2104 }
2105
2106 fn validate_relaxed_bound(
2107 &self,
2108 trait_ref: hir::TraitRef<'_>,
2109 span: Span,
2110 rbp: RelaxedBoundPolicy<'_>,
2111 ) {
2112 match rbp {
2122 RelaxedBoundPolicy::Allowed => return,
2123 RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2124 if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
2125 && let Res::Def(DefKind::TyParam, def_id) = res
2126 && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2127 {
2128 return;
2129 }
2130 }
2131 RelaxedBoundPolicy::Forbidden(reason) => {
2132 let gate = |context, subject| {
2133 let extended = self.tcx.features().more_maybe_bounds();
2134 let is_sized = trait_ref
2135 .trait_def_id()
2136 .is_some_and(|def_id| self.tcx.is_lang_item(def_id, hir::LangItem::Sized));
2137
2138 if extended && !is_sized {
2139 return;
2140 }
2141
2142 let prefix = if extended { "`Sized` " } else { "" };
2143 let mut diag = self.dcx().struct_span_err(
2144 span,
2145 format!("relaxed {prefix}bounds are not permitted in {context}"),
2146 );
2147 if is_sized {
2148 diag.note(format!(
2149 "{subject} are not implicitly bounded by `Sized`, \
2150 so there is nothing to relax"
2151 ));
2152 }
2153 diag.emit();
2154 };
2155
2156 match reason {
2157 RelaxedBoundForbiddenReason::TraitObjectTy => {
2158 gate("trait object types", "trait object types");
2159 return;
2160 }
2161 RelaxedBoundForbiddenReason::SuperTrait => {
2162 gate("supertrait bounds", "traits");
2163 return;
2164 }
2165 RelaxedBoundForbiddenReason::TraitAlias => {
2166 gate("trait alias bounds", "trait aliases");
2167 return;
2168 }
2169 RelaxedBoundForbiddenReason::AssocTyBounds
2170 | RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2171 };
2172 }
2173 }
2174
2175 self.dcx()
2176 .struct_span_err(span, "this relaxed bound is not permitted here")
2177 .with_note(
2178 "in this context, relaxed bounds are only allowed on \
2179 type parameters defined on the closest item",
2180 )
2181 .emit();
2182 }
2183
2184 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2185 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2186 }
2187
2188 #[instrument(level = "debug", skip(self), ret)]
2189 fn lower_param_bounds(
2190 &mut self,
2191 bounds: &[GenericBound],
2192 rbp: RelaxedBoundPolicy<'_>,
2193 itctx: ImplTraitContext,
2194 ) -> hir::GenericBounds<'hir> {
2195 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
2196 }
2197
2198 fn lower_param_bounds_mut(
2199 &mut self,
2200 bounds: &[GenericBound],
2201 rbp: RelaxedBoundPolicy<'_>,
2202 itctx: ImplTraitContext,
2203 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2204 bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
2205 }
2206
2207 #[instrument(level = "debug", skip(self), ret)]
2208 fn lower_universal_param_and_bounds(
2209 &mut self,
2210 node_id: NodeId,
2211 span: Span,
2212 ident: Ident,
2213 bounds: &[GenericBound],
2214 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2215 let def_id = self.local_def_id(node_id);
2217 let span = self.lower_span(span);
2218
2219 let param = hir::GenericParam {
2221 hir_id: self.lower_node_id(node_id),
2222 def_id,
2223 name: ParamName::Plain(self.lower_ident(ident)),
2224 pure_wrt_drop: false,
2225 span,
2226 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2227 colon_span: None,
2228 source: hir::GenericParamSource::Generics,
2229 };
2230
2231 let preds = self.lower_generic_bound_predicate(
2232 ident,
2233 node_id,
2234 &GenericParamKind::Type { default: None },
2235 bounds,
2236 None,
2237 span,
2238 RelaxedBoundPolicy::Allowed,
2239 ImplTraitContext::Universal,
2240 hir::PredicateOrigin::ImplTrait,
2241 );
2242
2243 let hir_id = self.next_id();
2244 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2245 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2246 None,
2247 self.arena.alloc(hir::Path {
2248 span,
2249 res,
2250 segments:
2251 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2252 }),
2253 ));
2254
2255 (param, preds, ty)
2256 }
2257
2258 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2261 let block = self.lower_block(b, false);
2262 self.expr_block(block)
2263 }
2264
2265 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2266 match c.value.peel_parens().kind {
2269 ExprKind::Underscore => {
2270 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2271 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2272 }
2273 _ => self.lower_anon_const_to_const_arg(c),
2274 }
2275 }
2276
2277 #[instrument(level = "debug", skip(self))]
2281 fn lower_const_path_to_const_arg(
2282 &mut self,
2283 path: &Path,
2284 res: Res<NodeId>,
2285 ty_id: NodeId,
2286 span: Span,
2287 ) -> &'hir hir::ConstArg<'hir> {
2288 let tcx = self.tcx;
2289
2290 let ct_kind = if path
2291 .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2292 && (tcx.features().min_generic_const_args()
2293 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2294 {
2295 let qpath = self.lower_qpath(
2296 ty_id,
2297 &None,
2298 path,
2299 ParamMode::Explicit,
2300 AllowReturnTypeNotation::No,
2301 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2303 None,
2304 );
2305 hir::ConstArgKind::Path(qpath)
2306 } else {
2307 let node_id = self.next_node_id();
2309 let span = self.lower_span(span);
2310
2311 let def_id = self.create_def(
2316 node_id,
2317 None,
2318 DefKind::AnonConst,
2319 DefPathData::LateAnonConst,
2320 span,
2321 );
2322 let hir_id = self.lower_node_id(node_id);
2323
2324 let path_expr = Expr {
2325 id: ty_id,
2326 kind: ExprKind::Path(None, path.clone()),
2327 span,
2328 attrs: AttrVec::new(),
2329 tokens: None,
2330 };
2331
2332 let ct = self.with_new_scopes(span, |this| {
2333 self.arena.alloc(hir::AnonConst {
2334 def_id,
2335 hir_id,
2336 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2337 span,
2338 })
2339 });
2340 hir::ConstArgKind::Anon(ct)
2341 };
2342
2343 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2344 }
2345
2346 fn lower_const_item_rhs(
2347 &mut self,
2348 attrs: &[hir::Attribute],
2349 rhs: Option<&ConstItemRhs>,
2350 span: Span,
2351 ) -> hir::ConstItemRhs<'hir> {
2352 match rhs {
2353 Some(ConstItemRhs::TypeConst(anon)) => {
2354 hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg(anon))
2355 }
2356 None if attr::contains_name(attrs, sym::type_const) => {
2357 let const_arg = ConstArg {
2358 hir_id: self.next_id(),
2359 kind: hir::ConstArgKind::Error(
2360 DUMMY_SP,
2361 self.dcx().span_delayed_bug(DUMMY_SP, "no block"),
2362 ),
2363 };
2364 hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg))
2365 }
2366 Some(ConstItemRhs::Body(body)) => {
2367 hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body)))
2368 }
2369 None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)),
2370 }
2371 }
2372
2373 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2376 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2377 }
2378
2379 #[instrument(level = "debug", skip(self))]
2380 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2381 let tcx = self.tcx;
2382 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2385 && let [stmt] = block.stmts.as_slice()
2386 && let StmtKind::Expr(expr) = &stmt.kind
2387 && let ExprKind::Path(..) = &expr.kind
2388 {
2389 expr
2390 } else {
2391 &anon.value
2392 };
2393 let maybe_res =
2394 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2395 if let ExprKind::Path(qself, path) = &expr.kind
2396 && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2397 && (tcx.features().min_generic_const_args()
2398 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2399 {
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 return ConstArg {
2412 hir_id: self.lower_node_id(anon.id),
2413 kind: hir::ConstArgKind::Path(qpath),
2414 };
2415 }
2416
2417 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2418 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2419 }
2420
2421 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2424 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2425 let def_id = this.local_def_id(c.id);
2426 let hir_id = this.lower_node_id(c.id);
2427 hir::AnonConst {
2428 def_id,
2429 hir_id,
2430 body: this.lower_const_body(c.value.span, Some(&c.value)),
2431 span: this.lower_span(c.value.span),
2432 }
2433 }))
2434 }
2435
2436 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2437 match u {
2438 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2439 UserProvided => hir::UnsafeSource::UserProvided,
2440 }
2441 }
2442
2443 fn lower_trait_bound_modifiers(
2444 &mut self,
2445 modifiers: TraitBoundModifiers,
2446 ) -> hir::TraitBoundModifiers {
2447 let constness = match modifiers.constness {
2448 BoundConstness::Never => BoundConstness::Never,
2449 BoundConstness::Always(span) => BoundConstness::Always(self.lower_span(span)),
2450 BoundConstness::Maybe(span) => BoundConstness::Maybe(self.lower_span(span)),
2451 };
2452 let polarity = match modifiers.polarity {
2453 BoundPolarity::Positive => BoundPolarity::Positive,
2454 BoundPolarity::Negative(span) => BoundPolarity::Negative(self.lower_span(span)),
2455 BoundPolarity::Maybe(span) => BoundPolarity::Maybe(self.lower_span(span)),
2456 };
2457 hir::TraitBoundModifiers { constness, polarity }
2458 }
2459
2460 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2463 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2464 }
2465
2466 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2467 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2468 }
2469
2470 fn stmt_let_pat(
2471 &mut self,
2472 attrs: Option<&'hir [hir::Attribute]>,
2473 span: Span,
2474 init: Option<&'hir hir::Expr<'hir>>,
2475 pat: &'hir hir::Pat<'hir>,
2476 source: hir::LocalSource,
2477 ) -> hir::Stmt<'hir> {
2478 let hir_id = self.next_id();
2479 if let Some(a) = attrs {
2480 assert!(!a.is_empty());
2481 self.attrs.insert(hir_id.local_id, a);
2482 }
2483 let local = hir::LetStmt {
2484 super_: None,
2485 hir_id,
2486 init,
2487 pat,
2488 els: None,
2489 source,
2490 span: self.lower_span(span),
2491 ty: None,
2492 };
2493 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2494 }
2495
2496 fn stmt_super_let_pat(
2497 &mut self,
2498 span: Span,
2499 pat: &'hir hir::Pat<'hir>,
2500 init: Option<&'hir hir::Expr<'hir>>,
2501 ) -> hir::Stmt<'hir> {
2502 let hir_id = self.next_id();
2503 let span = self.lower_span(span);
2504 let local = hir::LetStmt {
2505 super_: Some(span),
2506 hir_id,
2507 init,
2508 pat,
2509 els: None,
2510 source: hir::LocalSource::Normal,
2511 span,
2512 ty: None,
2513 };
2514 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2515 }
2516
2517 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2518 self.block_all(expr.span, &[], Some(expr))
2519 }
2520
2521 fn block_all(
2522 &mut self,
2523 span: Span,
2524 stmts: &'hir [hir::Stmt<'hir>],
2525 expr: Option<&'hir hir::Expr<'hir>>,
2526 ) -> &'hir hir::Block<'hir> {
2527 let blk = hir::Block {
2528 stmts,
2529 expr,
2530 hir_id: self.next_id(),
2531 rules: hir::BlockCheckMode::DefaultBlock,
2532 span: self.lower_span(span),
2533 targeted_by_break: false,
2534 };
2535 self.arena.alloc(blk)
2536 }
2537
2538 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2539 let field = self.single_pat_field(span, pat);
2540 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2541 }
2542
2543 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2544 let field = self.single_pat_field(span, pat);
2545 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2546 }
2547
2548 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2549 let field = self.single_pat_field(span, pat);
2550 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2551 }
2552
2553 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2554 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2555 }
2556
2557 fn single_pat_field(
2558 &mut self,
2559 span: Span,
2560 pat: &'hir hir::Pat<'hir>,
2561 ) -> &'hir [hir::PatField<'hir>] {
2562 let field = hir::PatField {
2563 hir_id: self.next_id(),
2564 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2565 is_shorthand: false,
2566 pat,
2567 span: self.lower_span(span),
2568 };
2569 arena_vec![self; field]
2570 }
2571
2572 fn pat_lang_item_variant(
2573 &mut self,
2574 span: Span,
2575 lang_item: hir::LangItem,
2576 fields: &'hir [hir::PatField<'hir>],
2577 ) -> &'hir hir::Pat<'hir> {
2578 let path = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
2579 self.pat(span, hir::PatKind::Struct(path, fields, None))
2580 }
2581
2582 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2583 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2584 }
2585
2586 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2587 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2588 }
2589
2590 fn pat_ident_binding_mode(
2591 &mut self,
2592 span: Span,
2593 ident: Ident,
2594 bm: hir::BindingMode,
2595 ) -> (&'hir hir::Pat<'hir>, HirId) {
2596 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2597 (self.arena.alloc(pat), hir_id)
2598 }
2599
2600 fn pat_ident_binding_mode_mut(
2601 &mut self,
2602 span: Span,
2603 ident: Ident,
2604 bm: hir::BindingMode,
2605 ) -> (hir::Pat<'hir>, HirId) {
2606 let hir_id = self.next_id();
2607
2608 (
2609 hir::Pat {
2610 hir_id,
2611 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2612 span: self.lower_span(span),
2613 default_binding_modes: true,
2614 },
2615 hir_id,
2616 )
2617 }
2618
2619 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2620 self.arena.alloc(hir::Pat {
2621 hir_id: self.next_id(),
2622 kind,
2623 span: self.lower_span(span),
2624 default_binding_modes: true,
2625 })
2626 }
2627
2628 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2629 hir::Pat {
2630 hir_id: self.next_id(),
2631 kind,
2632 span: self.lower_span(span),
2633 default_binding_modes: false,
2634 }
2635 }
2636
2637 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2638 let kind = match qpath {
2639 hir::QPath::Resolved(None, path) => {
2640 match path.res {
2642 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2643 let principal = hir::PolyTraitRef {
2644 bound_generic_params: &[],
2645 modifiers: hir::TraitBoundModifiers::NONE,
2646 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2647 span: self.lower_span(span),
2648 };
2649
2650 hir_id = self.next_id();
2653 hir::TyKind::TraitObject(
2654 arena_vec![self; principal],
2655 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2656 )
2657 }
2658 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2659 }
2660 }
2661 _ => hir::TyKind::Path(qpath),
2662 };
2663
2664 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2665 }
2666
2667 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2672 let r = hir::Lifetime::new(
2673 self.next_id(),
2674 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2675 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2676 LifetimeSource::Other,
2677 LifetimeSyntax::Implicit,
2678 );
2679 debug!("elided_dyn_bound: r={:?}", r);
2680 self.arena.alloc(r)
2681 }
2682}
2683
2684struct GenericArgsCtor<'hir> {
2686 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2687 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2688 parenthesized: hir::GenericArgsParentheses,
2689 span: Span,
2690}
2691
2692impl<'hir> GenericArgsCtor<'hir> {
2693 fn is_empty(&self) -> bool {
2694 self.args.is_empty()
2695 && self.constraints.is_empty()
2696 && self.parenthesized == hir::GenericArgsParentheses::No
2697 }
2698
2699 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2700 let ga = hir::GenericArgs {
2701 args: this.arena.alloc_from_iter(self.args),
2702 constraints: self.constraints,
2703 parenthesized: self.parenthesized,
2704 span_ext: this.lower_span(self.span),
2705 };
2706 this.arena.alloc(ga)
2707 }
2708}