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