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