1#![allow(internal_features)]
35#![doc(rust_logo)]
36#![feature(assert_matches)]
37#![feature(box_patterns)]
38#![feature(exact_size_is_empty)]
39#![feature(if_let_guard)]
40#![feature(rustdoc_internals)]
41use std::sync::Arc;
44
45use rustc_ast::node_id::NodeMap;
46use rustc_ast::{self as ast, *};
47use rustc_attr_parsing::{AttributeParser, OmitDoc};
48use rustc_data_structures::fingerprint::Fingerprint;
49use rustc_data_structures::sorted_map::SortedMap;
50use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
51use rustc_data_structures::sync::spawn;
52use rustc_data_structures::tagged_ptr::TaggedRef;
53use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
54use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
55use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
56use rustc_hir::{
57 self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem,
58 LifetimeSource, LifetimeSyntax, ParamName, TraitCandidate,
59};
60use rustc_index::{Idx, IndexSlice, IndexVec};
61use rustc_macros::extension;
62use rustc_middle::span_bug;
63use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
64use rustc_session::parse::{add_feature_diagnostics, feature_err};
65use rustc_span::symbol::{Ident, Symbol, kw, sym};
66use rustc_span::{DUMMY_SP, DesugaringKind, Span};
67use smallvec::SmallVec;
68use thin_vec::ThinVec;
69use tracing::{debug, instrument, trace};
70
71use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
72
73macro_rules! arena_vec {
74 ($this:expr; $($x:expr),*) => (
75 $this.arena.alloc_from_iter([$($x),*])
76 );
77}
78
79mod asm;
80mod block;
81mod delegation;
82mod errors;
83mod expr;
84mod format;
85mod index;
86mod item;
87mod pat;
88mod path;
89pub mod stability;
90
91rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
92
93struct LoweringContext<'a, 'hir> {
94 tcx: TyCtxt<'hir>,
95 resolver: &'a mut ResolverAstLowering,
96
97 arena: &'hir hir::Arena<'hir>,
99
100 bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
102 define_opaque: Option<&'hir [(Span, LocalDefId)]>,
104 attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
106 children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
108
109 contract_ensures: Option<(Span, Ident, HirId)>,
110
111 coroutine_kind: Option<hir::CoroutineKind>,
112
113 task_context: Option<HirId>,
116
117 current_item: Option<Span>,
120
121 catch_scope: Option<HirId>,
122 loop_scope: Option<HirId>,
123 is_in_loop_condition: bool,
124 is_in_dyn_type: bool,
125
126 current_hir_id_owner: hir::OwnerId,
127 item_local_id_counter: hir::ItemLocalId,
128 trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
129
130 impl_trait_defs: Vec<hir::GenericParam<'hir>>,
131 impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
132
133 ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
135 #[cfg(debug_assertions)]
137 node_id_to_local_id: NodeMap<hir::ItemLocalId>,
138
139 allow_try_trait: Arc<[Symbol]>,
140 allow_gen_future: Arc<[Symbol]>,
141 allow_pattern_type: Arc<[Symbol]>,
142 allow_async_iterator: Arc<[Symbol]>,
143 allow_for_await: Arc<[Symbol]>,
144 allow_async_fn_traits: Arc<[Symbol]>,
145
146 attribute_parser: AttributeParser<'hir>,
147}
148
149impl<'a, 'hir> LoweringContext<'a, 'hir> {
150 fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
151 let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
152 Self {
153 tcx,
155 resolver,
156 arena: tcx.hir_arena,
157
158 bodies: Vec::new(),
160 define_opaque: None,
161 attrs: SortedMap::default(),
162 children: Vec::default(),
163 contract_ensures: None,
164 current_hir_id_owner: hir::CRATE_OWNER_ID,
165 item_local_id_counter: hir::ItemLocalId::ZERO,
166 ident_and_label_to_local_id: Default::default(),
167 #[cfg(debug_assertions)]
168 node_id_to_local_id: Default::default(),
169 trait_map: Default::default(),
170
171 catch_scope: None,
173 loop_scope: None,
174 is_in_loop_condition: false,
175 is_in_dyn_type: false,
176 coroutine_kind: None,
177 task_context: None,
178 current_item: None,
179 impl_trait_defs: Vec::new(),
180 impl_trait_bounds: Vec::new(),
181 allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
182 allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
183 allow_gen_future: if tcx.features().async_fn_track_caller() {
184 [sym::gen_future, sym::closure_track_caller].into()
185 } else {
186 [sym::gen_future].into()
187 },
188 allow_for_await: [sym::async_iterator].into(),
189 allow_async_fn_traits: [sym::async_fn_traits].into(),
190 allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
193
194 attribute_parser: AttributeParser::new(tcx.sess, tcx.features(), registered_tools),
195 }
196 }
197
198 pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
199 self.tcx.dcx()
200 }
201}
202
203#[extension(trait ResolverAstLoweringExt)]
204impl ResolverAstLowering {
205 fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
206 if let ExprKind::Path(None, path) = &expr.kind {
207 if path.segments.last().unwrap().args.is_some() {
210 return None;
211 }
212
213 if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
214 if def_id.is_local() {
218 return None;
219 }
220
221 if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
222 return v.clone();
223 }
224 }
225 }
226
227 None
228 }
229
230 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
231 self.partial_res_map.get(&id).copied()
232 }
233
234 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
236 self.import_res_map.get(&id).copied().unwrap_or_default()
237 }
238
239 fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
241 self.label_res_map.get(&id).copied()
242 }
243
244 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
246 self.lifetimes_res_map.get(&id).copied()
247 }
248
249 fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
257 self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
258 }
259}
260
261#[derive(Debug, Copy, Clone, PartialEq, Eq)]
264enum ImplTraitContext {
265 Universal,
271
272 OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
277
278 InBinding,
283
284 FeatureGated(ImplTraitPosition, Symbol),
286 Disallowed(ImplTraitPosition),
288}
289
290#[derive(Debug, Copy, Clone, PartialEq, Eq)]
292enum ImplTraitPosition {
293 Path,
294 Variable,
295 Trait,
296 Bound,
297 Generic,
298 ExternFnParam,
299 ClosureParam,
300 PointerParam,
301 FnTraitParam,
302 ExternFnReturn,
303 ClosureReturn,
304 PointerReturn,
305 FnTraitReturn,
306 GenericDefault,
307 ConstTy,
308 StaticTy,
309 AssocTy,
310 FieldTy,
311 Cast,
312 ImplSelf,
313 OffsetOf,
314}
315
316impl std::fmt::Display for ImplTraitPosition {
317 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
318 let name = match self {
319 ImplTraitPosition::Path => "paths",
320 ImplTraitPosition::Variable => "the type of variable bindings",
321 ImplTraitPosition::Trait => "traits",
322 ImplTraitPosition::Bound => "bounds",
323 ImplTraitPosition::Generic => "generics",
324 ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
325 ImplTraitPosition::ClosureParam => "closure parameters",
326 ImplTraitPosition::PointerParam => "`fn` pointer parameters",
327 ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
328 ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
329 ImplTraitPosition::ClosureReturn => "closure return types",
330 ImplTraitPosition::PointerReturn => "`fn` pointer return types",
331 ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
332 ImplTraitPosition::GenericDefault => "generic parameter defaults",
333 ImplTraitPosition::ConstTy => "const types",
334 ImplTraitPosition::StaticTy => "static types",
335 ImplTraitPosition::AssocTy => "associated types",
336 ImplTraitPosition::FieldTy => "field types",
337 ImplTraitPosition::Cast => "cast expression types",
338 ImplTraitPosition::ImplSelf => "impl headers",
339 ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
340 };
341
342 write!(f, "{name}")
343 }
344}
345
346#[derive(Copy, Clone, Debug, PartialEq, Eq)]
347enum FnDeclKind {
348 Fn,
349 Inherent,
350 ExternFn,
351 Closure,
352 Pointer,
353 Trait,
354 Impl,
355}
356
357#[derive(Copy, Clone)]
358enum AstOwner<'a> {
359 NonOwner,
360 Crate(&'a ast::Crate),
361 Item(&'a ast::Item),
362 AssocItem(&'a ast::AssocItem, visit::AssocCtxt),
363 ForeignItem(&'a ast::ForeignItem),
364}
365
366fn index_crate<'a>(
367 node_id_to_def_id: &NodeMap<LocalDefId>,
368 krate: &'a Crate,
369) -> IndexVec<LocalDefId, AstOwner<'a>> {
370 let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
371 *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
372 AstOwner::Crate(krate);
373 visit::walk_crate(&mut indexer, krate);
374 return indexer.index;
375
376 struct Indexer<'s, 'a> {
377 node_id_to_def_id: &'s NodeMap<LocalDefId>,
378 index: IndexVec<LocalDefId, AstOwner<'a>>,
379 }
380
381 impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> {
382 fn visit_attribute(&mut self, _: &'a Attribute) {
383 }
386
387 fn visit_item(&mut self, item: &'a ast::Item) {
388 let def_id = self.node_id_to_def_id[&item.id];
389 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
390 visit::walk_item(self, item)
391 }
392
393 fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
394 let def_id = self.node_id_to_def_id[&item.id];
395 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
396 AstOwner::AssocItem(item, ctxt);
397 visit::walk_assoc_item(self, item, ctxt);
398 }
399
400 fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
401 let def_id = self.node_id_to_def_id[&item.id];
402 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
403 AstOwner::ForeignItem(item);
404 visit::walk_item(self, item);
405 }
406 }
407}
408
409fn compute_hir_hash(
412 tcx: TyCtxt<'_>,
413 owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
414) -> Fingerprint {
415 let mut hir_body_nodes: Vec<_> = owners
416 .iter_enumerated()
417 .filter_map(|(def_id, info)| {
418 let info = info.as_owner()?;
419 let def_path_hash = tcx.hir_def_path_hash(def_id);
420 Some((def_path_hash, info))
421 })
422 .collect();
423 hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
424
425 tcx.with_stable_hashing_context(|mut hcx| {
426 let mut stable_hasher = StableHasher::new();
427 hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
428 stable_hasher.finish()
429 })
430}
431
432pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
433 let sess = tcx.sess;
434 tcx.ensure_done().output_filenames(());
436 tcx.ensure_done().early_lint_checks(());
437 tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
438 tcx.ensure_done().get_lang_items(());
439 let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
440
441 let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
442 let mut owners = IndexVec::from_fn_n(
443 |_| hir::MaybeOwner::Phantom,
444 tcx.definitions_untracked().def_index_count(),
445 );
446
447 let mut lowerer = item::ItemLowerer {
448 tcx,
449 resolver: &mut resolver,
450 ast_index: &ast_index,
451 owners: &mut owners,
452 };
453 for def_id in ast_index.indices() {
454 lowerer.lower_node(def_id);
455 }
456
457 drop(ast_index);
458
459 let prof = sess.prof.clone();
461 spawn(move || {
462 let _timer = prof.verbose_generic_activity("drop_ast");
463 drop(krate);
464 });
465
466 let opt_hir_hash =
468 if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
469 hir::Crate { owners, opt_hir_hash }
470}
471
472#[derive(Copy, Clone, PartialEq, Debug)]
473enum ParamMode {
474 Explicit,
476 Optional,
478}
479
480#[derive(Copy, Clone, Debug)]
481enum AllowReturnTypeNotation {
482 Yes,
484 No,
486}
487
488enum GenericArgsMode {
489 ParenSugar,
491 ReturnTypeNotation,
493 Err,
495 Silence,
497}
498
499impl<'a, 'hir> LoweringContext<'a, 'hir> {
500 fn create_def(
501 &mut self,
502 node_id: ast::NodeId,
503 name: Option<Symbol>,
504 def_kind: DefKind,
505 span: Span,
506 ) -> LocalDefId {
507 let parent = self.current_hir_id_owner.def_id;
508 debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
509 assert!(
510 self.opt_local_def_id(node_id).is_none(),
511 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
512 node_id,
513 def_kind,
514 self.tcx.hir_def_key(self.local_def_id(node_id)),
515 );
516
517 let def_id = self
518 .tcx
519 .at(span)
520 .create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator)
521 .def_id();
522
523 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
524 self.resolver.node_id_to_def_id.insert(node_id, def_id);
525
526 def_id
527 }
528
529 fn next_node_id(&mut self) -> NodeId {
530 let start = self.resolver.next_node_id;
531 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
532 self.resolver.next_node_id = ast::NodeId::from_u32(next);
533 start
534 }
535
536 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
539 self.resolver.node_id_to_def_id.get(&node).copied()
540 }
541
542 fn local_def_id(&self, node: NodeId) -> LocalDefId {
543 self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
544 }
545
546 fn owner_id(&self, node: NodeId) -> hir::OwnerId {
548 hir::OwnerId { def_id: self.local_def_id(node) }
549 }
550
551 #[instrument(level = "debug", skip(self, f))]
557 fn with_hir_id_owner(
558 &mut self,
559 owner: NodeId,
560 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
561 ) {
562 let owner_id = self.owner_id(owner);
563
564 let current_attrs = std::mem::take(&mut self.attrs);
565 let current_bodies = std::mem::take(&mut self.bodies);
566 let current_define_opaque = std::mem::take(&mut self.define_opaque);
567 let current_ident_and_label_to_local_id =
568 std::mem::take(&mut self.ident_and_label_to_local_id);
569
570 #[cfg(debug_assertions)]
571 let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
572 let current_trait_map = std::mem::take(&mut self.trait_map);
573 let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);
574 let current_local_counter =
575 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
576 let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
577 let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
578
579 #[cfg(debug_assertions)]
585 {
586 let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
587 debug_assert_eq!(_old, None);
588 }
589
590 let item = f(self);
591 debug_assert_eq!(owner_id, item.def_id());
592 debug_assert!(self.impl_trait_defs.is_empty());
594 debug_assert!(self.impl_trait_bounds.is_empty());
595 let info = self.make_owner_info(item);
596
597 self.attrs = current_attrs;
598 self.bodies = current_bodies;
599 self.define_opaque = current_define_opaque;
600 self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
601
602 #[cfg(debug_assertions)]
603 {
604 self.node_id_to_local_id = current_node_id_to_local_id;
605 }
606 self.trait_map = current_trait_map;
607 self.current_hir_id_owner = current_owner;
608 self.item_local_id_counter = current_local_counter;
609 self.impl_trait_defs = current_impl_trait_defs;
610 self.impl_trait_bounds = current_impl_trait_bounds;
611
612 debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
613 self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
614 }
615
616 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
617 let attrs = std::mem::take(&mut self.attrs);
618 let mut bodies = std::mem::take(&mut self.bodies);
619 let define_opaque = std::mem::take(&mut self.define_opaque);
620 let trait_map = std::mem::take(&mut self.trait_map);
621
622 #[cfg(debug_assertions)]
623 for (id, attrs) in attrs.iter() {
624 if attrs.is_empty() {
626 panic!("Stored empty attributes for {:?}", id);
627 }
628 }
629
630 bodies.sort_by_key(|(k, _)| *k);
631 let bodies = SortedMap::from_presorted_elements(bodies);
632
633 let (opt_hash_including_bodies, attrs_hash) =
635 self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);
636 let num_nodes = self.item_local_id_counter.as_usize();
637 let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
638 let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
639 let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
640
641 self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
642 }
643
644 #[instrument(level = "debug", skip(self), ret)]
650 fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
651 assert_ne!(ast_node_id, DUMMY_NODE_ID);
652
653 let owner = self.current_hir_id_owner;
654 let local_id = self.item_local_id_counter;
655 assert_ne!(local_id, hir::ItemLocalId::ZERO);
656 self.item_local_id_counter.increment_by(1);
657 let hir_id = HirId { owner, local_id };
658
659 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
660 self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
661 }
662
663 if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
664 self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
665 }
666
667 #[cfg(debug_assertions)]
669 {
670 let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
671 assert_eq!(old, None);
672 }
673
674 hir_id
675 }
676
677 #[instrument(level = "debug", skip(self), ret)]
679 fn next_id(&mut self) -> HirId {
680 let owner = self.current_hir_id_owner;
681 let local_id = self.item_local_id_counter;
682 assert_ne!(local_id, hir::ItemLocalId::ZERO);
683 self.item_local_id_counter.increment_by(1);
684 HirId { owner, local_id }
685 }
686
687 #[instrument(level = "trace", skip(self))]
688 fn lower_res(&mut self, res: Res<NodeId>) -> Res {
689 let res: Result<Res, ()> = res.apply_id(|id| {
690 let owner = self.current_hir_id_owner;
691 let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
692 Ok(HirId { owner, local_id })
693 });
694 trace!(?res);
695
696 res.unwrap_or(Res::Err)
702 }
703
704 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
705 self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
706 }
707
708 fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {
709 let per_ns = self.resolver.get_import_res(id);
710 let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));
711 if per_ns.is_empty() {
712 self.dcx().span_delayed_bug(span, "no resolution for an import");
714 let err = Some(Res::Err);
715 return PerNS { type_ns: err, value_ns: err, macro_ns: err };
716 }
717 per_ns
718 }
719
720 fn make_lang_item_qpath(
721 &mut self,
722 lang_item: hir::LangItem,
723 span: Span,
724 args: Option<&'hir hir::GenericArgs<'hir>>,
725 ) -> hir::QPath<'hir> {
726 hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
727 }
728
729 fn make_lang_item_path(
730 &mut self,
731 lang_item: hir::LangItem,
732 span: Span,
733 args: Option<&'hir hir::GenericArgs<'hir>>,
734 ) -> &'hir hir::Path<'hir> {
735 let def_id = self.tcx.require_lang_item(lang_item, span);
736 let def_kind = self.tcx.def_kind(def_id);
737 let res = Res::Def(def_kind, def_id);
738 self.arena.alloc(hir::Path {
739 span,
740 res,
741 segments: self.arena.alloc_from_iter([hir::PathSegment {
742 ident: Ident::new(lang_item.name(), span),
743 hir_id: self.next_id(),
744 res,
745 args,
746 infer_args: args.is_none(),
747 }]),
748 })
749 }
750
751 fn mark_span_with_reason(
754 &self,
755 reason: DesugaringKind,
756 span: Span,
757 allow_internal_unstable: Option<Arc<[Symbol]>>,
758 ) -> Span {
759 self.tcx.with_stable_hashing_context(|hcx| {
760 span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
761 })
762 }
763
764 fn lower_span(&self, span: Span) -> Span {
767 if self.tcx.sess.opts.incremental.is_some() {
768 span.with_parent(Some(self.current_hir_id_owner.def_id))
769 } else {
770 span
772 }
773 }
774
775 fn lower_ident(&self, ident: Ident) -> Ident {
776 Ident::new(ident.name, self.lower_span(ident.span))
777 }
778
779 #[instrument(level = "debug", skip(self))]
781 fn lifetime_res_to_generic_param(
782 &mut self,
783 ident: Ident,
784 node_id: NodeId,
785 res: LifetimeRes,
786 source: hir::GenericParamSource,
787 ) -> Option<hir::GenericParam<'hir>> {
788 let (name, kind) = match res {
789 LifetimeRes::Param { .. } => {
790 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
791 }
792 LifetimeRes::Fresh { param, kind, .. } => {
793 let _def_id = self.create_def(
795 param,
796 Some(kw::UnderscoreLifetime),
797 DefKind::LifetimeParam,
798 ident.span,
799 );
800 debug!(?_def_id);
801
802 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
803 }
804 LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
805 res => panic!(
806 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
807 res, ident, ident.span
808 ),
809 };
810 let hir_id = self.lower_node_id(node_id);
811 let def_id = self.local_def_id(node_id);
812 Some(hir::GenericParam {
813 hir_id,
814 def_id,
815 name,
816 span: self.lower_span(ident.span),
817 pure_wrt_drop: false,
818 kind: hir::GenericParamKind::Lifetime { kind },
819 colon_span: None,
820 source,
821 })
822 }
823
824 #[instrument(level = "debug", skip(self))]
830 #[inline]
831 fn lower_lifetime_binder(
832 &mut self,
833 binder: NodeId,
834 generic_params: &[GenericParam],
835 ) -> &'hir [hir::GenericParam<'hir>] {
836 let mut generic_params: Vec<_> = self
837 .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
838 .collect();
839 let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
840 debug!(?extra_lifetimes);
841 generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
842 self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
843 }));
844 let generic_params = self.arena.alloc_from_iter(generic_params);
845 debug!(?generic_params);
846
847 generic_params
848 }
849
850 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
851 let was_in_dyn_type = self.is_in_dyn_type;
852 self.is_in_dyn_type = in_scope;
853
854 let result = f(self);
855
856 self.is_in_dyn_type = was_in_dyn_type;
857
858 result
859 }
860
861 fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
862 let current_item = self.current_item;
863 self.current_item = Some(scope_span);
864
865 let was_in_loop_condition = self.is_in_loop_condition;
866 self.is_in_loop_condition = false;
867
868 let old_contract = self.contract_ensures.take();
869
870 let catch_scope = self.catch_scope.take();
871 let loop_scope = self.loop_scope.take();
872 let ret = f(self);
873 self.catch_scope = catch_scope;
874 self.loop_scope = loop_scope;
875
876 self.contract_ensures = old_contract;
877
878 self.is_in_loop_condition = was_in_loop_condition;
879
880 self.current_item = current_item;
881
882 ret
883 }
884
885 fn lower_attrs(
886 &mut self,
887 id: HirId,
888 attrs: &[Attribute],
889 target_span: Span,
890 ) -> &'hir [hir::Attribute] {
891 if attrs.is_empty() {
892 &[]
893 } else {
894 let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span));
895
896 debug_assert_eq!(id.owner, self.current_hir_id_owner);
897 let ret = self.arena.alloc_from_iter(lowered_attrs);
898
899 if ret.is_empty() {
906 &[]
907 } else {
908 self.attrs.insert(id.local_id, ret);
909 ret
910 }
911 }
912 }
913
914 fn lower_attrs_vec(&self, attrs: &[Attribute], target_span: Span) -> Vec<hir::Attribute> {
915 self.attribute_parser
916 .parse_attribute_list(attrs, target_span, OmitDoc::Lower, |s| self.lower_span(s))
917 }
918
919 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
920 debug_assert_eq!(id.owner, self.current_hir_id_owner);
921 debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
922 if let Some(&a) = self.attrs.get(&target_id.local_id) {
923 debug_assert!(!a.is_empty());
924 self.attrs.insert(id.local_id, a);
925 }
926 }
927
928 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
929 args.clone()
930 }
931
932 #[instrument(level = "debug", skip_all)]
934 fn lower_assoc_item_constraint(
935 &mut self,
936 constraint: &AssocItemConstraint,
937 itctx: ImplTraitContext,
938 ) -> hir::AssocItemConstraint<'hir> {
939 debug!(?constraint, ?itctx);
940 let gen_args = if let Some(gen_args) = &constraint.gen_args {
942 let gen_args_ctor = match gen_args {
943 GenericArgs::AngleBracketed(data) => {
944 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
945 }
946 GenericArgs::Parenthesized(data) => {
947 if let Some(first_char) = constraint.ident.as_str().chars().next()
948 && first_char.is_ascii_lowercase()
949 {
950 let err = match (&data.inputs[..], &data.output) {
951 ([_, ..], FnRetTy::Default(_)) => {
952 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
953 }
954 ([], FnRetTy::Default(_)) => {
955 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
956 }
957 (_, FnRetTy::Ty(ty)) => {
959 let span = data.inputs_span.shrink_to_hi().to(ty.span);
960 errors::BadReturnTypeNotation::Output {
961 span,
962 suggestion: errors::RTNSuggestion {
963 output: span,
964 input: data.inputs_span,
965 },
966 }
967 }
968 };
969 let mut err = self.dcx().create_err(err);
970 if !self.tcx.features().return_type_notation()
971 && self.tcx.sess.is_nightly_build()
972 {
973 add_feature_diagnostics(
974 &mut err,
975 &self.tcx.sess,
976 sym::return_type_notation,
977 );
978 }
979 err.emit();
980 GenericArgsCtor {
981 args: Default::default(),
982 constraints: &[],
983 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
984 span: data.span,
985 }
986 } else {
987 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
988 self.lower_angle_bracketed_parameter_data(
991 &data.as_angle_bracketed_args(),
992 ParamMode::Explicit,
993 itctx,
994 )
995 .0
996 }
997 }
998 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
999 args: Default::default(),
1000 constraints: &[],
1001 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1002 span: *span,
1003 },
1004 };
1005 gen_args_ctor.into_generic_args(self)
1006 } else {
1007 self.arena.alloc(hir::GenericArgs::none())
1008 };
1009 let kind = match &constraint.kind {
1010 AssocItemConstraintKind::Equality { term } => {
1011 let term = match term {
1012 Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1013 Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1014 };
1015 hir::AssocItemConstraintKind::Equality { term }
1016 }
1017 AssocItemConstraintKind::Bound { bounds } => {
1018 if self.is_in_dyn_type {
1020 let suggestion = match itctx {
1021 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1022 let bound_end_span = constraint
1023 .gen_args
1024 .as_ref()
1025 .map_or(constraint.ident.span, |args| args.span());
1026 if bound_end_span.eq_ctxt(constraint.span) {
1027 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1028 } else {
1029 None
1030 }
1031 }
1032 _ => None,
1033 };
1034
1035 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1036 span: constraint.span,
1037 suggestion,
1038 });
1039 let err_ty =
1040 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1041 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1042 } else {
1043 let bounds = self.lower_param_bounds(bounds, itctx);
1046
1047 hir::AssocItemConstraintKind::Bound { bounds }
1048 }
1049 }
1050 };
1051
1052 hir::AssocItemConstraint {
1053 hir_id: self.lower_node_id(constraint.id),
1054 ident: self.lower_ident(constraint.ident),
1055 gen_args,
1056 kind,
1057 span: self.lower_span(constraint.span),
1058 }
1059 }
1060
1061 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1062 let sub = if data.inputs.is_empty() {
1064 let parentheses_span =
1065 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1066 AssocTyParenthesesSub::Empty { parentheses_span }
1067 }
1068 else {
1070 let open_param = data.inputs_span.shrink_to_lo().to(data
1072 .inputs
1073 .first()
1074 .unwrap()
1075 .span
1076 .shrink_to_lo());
1077 let close_param =
1079 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1080 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1081 };
1082 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1083 }
1084
1085 #[instrument(level = "debug", skip(self))]
1086 fn lower_generic_arg(
1087 &mut self,
1088 arg: &ast::GenericArg,
1089 itctx: ImplTraitContext,
1090 ) -> hir::GenericArg<'hir> {
1091 match arg {
1092 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1093 lt,
1094 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1095 lt.ident.into(),
1096 )),
1097 ast::GenericArg::Type(ty) => {
1098 if ty.is_maybe_parenthesised_infer() {
1101 return GenericArg::Infer(hir::InferArg {
1102 hir_id: self.lower_node_id(ty.id),
1103 span: self.lower_span(ty.span),
1104 });
1105 }
1106
1107 match &ty.kind {
1108 TyKind::Path(None, path) => {
1115 if let Some(res) = self
1116 .resolver
1117 .get_partial_res(ty.id)
1118 .and_then(|partial_res| partial_res.full_res())
1119 {
1120 if !res.matches_ns(Namespace::TypeNS)
1121 && path.is_potential_trivial_const_arg(false)
1122 {
1123 debug!(
1124 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1125 ty,
1126 );
1127
1128 let ct =
1129 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1130 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1131 }
1132 }
1133 }
1134 _ => {}
1135 }
1136 GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1137 }
1138 ast::GenericArg::Const(ct) => {
1139 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1140 }
1141 }
1142 }
1143
1144 #[instrument(level = "debug", skip(self))]
1145 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1146 self.arena.alloc(self.lower_ty_direct(t, itctx))
1147 }
1148
1149 fn lower_path_ty(
1150 &mut self,
1151 t: &Ty,
1152 qself: &Option<ptr::P<QSelf>>,
1153 path: &Path,
1154 param_mode: ParamMode,
1155 itctx: ImplTraitContext,
1156 ) -> hir::Ty<'hir> {
1157 if qself.is_none()
1163 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1164 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1165 {
1166 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1167 let bound = this.lower_poly_trait_ref(
1168 &PolyTraitRef {
1169 bound_generic_params: ThinVec::new(),
1170 modifiers: TraitBoundModifiers::NONE,
1171 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1172 span: t.span,
1173 },
1174 itctx,
1175 );
1176 let bounds = this.arena.alloc_from_iter([bound]);
1177 let lifetime_bound = this.elided_dyn_bound(t.span);
1178 (bounds, lifetime_bound)
1179 });
1180 let kind = hir::TyKind::TraitObject(
1181 bounds,
1182 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1183 );
1184 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1185 }
1186
1187 let id = self.lower_node_id(t.id);
1188 let qpath = self.lower_qpath(
1189 t.id,
1190 qself,
1191 path,
1192 param_mode,
1193 AllowReturnTypeNotation::Yes,
1194 itctx,
1195 None,
1196 );
1197 self.ty_path(id, t.span, qpath)
1198 }
1199
1200 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1201 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1202 }
1203
1204 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1205 self.ty(span, hir::TyKind::Tup(tys))
1206 }
1207
1208 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1209 let kind = match &t.kind {
1210 TyKind::Infer => hir::TyKind::Infer(()),
1211 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1212 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1213 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1214 TyKind::Ref(region, mt) => {
1215 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1216 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1217 }
1218 TyKind::PinnedRef(region, mt) => {
1219 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1220 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1221 let span = self.lower_span(t.span);
1222 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1223 let args = self.arena.alloc(hir::GenericArgs {
1224 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1225 constraints: &[],
1226 parenthesized: hir::GenericArgsParentheses::No,
1227 span_ext: span,
1228 });
1229 let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1230 hir::TyKind::Path(path)
1231 }
1232 TyKind::BareFn(f) => {
1233 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1234 hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1235 generic_params,
1236 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1237 abi: self.lower_extern(f.ext),
1238 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1239 param_idents: self.lower_fn_params_to_idents(&f.decl),
1240 }))
1241 }
1242 TyKind::UnsafeBinder(f) => {
1243 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1244 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1245 generic_params,
1246 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1247 }))
1248 }
1249 TyKind::Never => hir::TyKind::Never,
1250 TyKind::Tup(tys) => hir::TyKind::Tup(
1251 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1252 ),
1253 TyKind::Paren(ty) => {
1254 return self.lower_ty_direct(ty, itctx);
1255 }
1256 TyKind::Path(qself, path) => {
1257 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1258 }
1259 TyKind::ImplicitSelf => {
1260 let hir_id = self.next_id();
1261 let res = self.expect_full_res(t.id);
1262 let res = self.lower_res(res);
1263 hir::TyKind::Path(hir::QPath::Resolved(
1264 None,
1265 self.arena.alloc(hir::Path {
1266 res,
1267 segments: arena_vec![self; hir::PathSegment::new(
1268 Ident::with_dummy_span(kw::SelfUpper),
1269 hir_id,
1270 res
1271 )],
1272 span: self.lower_span(t.span),
1273 }),
1274 ))
1275 }
1276 TyKind::Array(ty, length) => hir::TyKind::Array(
1277 self.lower_ty(ty, itctx),
1278 self.lower_array_length_to_const_arg(length),
1279 ),
1280 TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1281 TyKind::TraitObject(bounds, kind) => {
1282 let mut lifetime_bound = None;
1283 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1284 let bounds =
1285 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1286 GenericBound::Trait(ty) => {
1290 let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1291 Some(trait_ref)
1292 }
1293 GenericBound::Outlives(lifetime) => {
1294 if lifetime_bound.is_none() {
1295 lifetime_bound = Some(this.lower_lifetime(
1296 lifetime,
1297 LifetimeSource::Other,
1298 lifetime.ident.into(),
1299 ));
1300 }
1301 None
1302 }
1303 GenericBound::Use(_, span) => {
1305 this.dcx()
1306 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1307 None
1308 }
1309 }));
1310 let lifetime_bound =
1311 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1312 (bounds, lifetime_bound)
1313 });
1314 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1315 }
1316 TyKind::ImplTrait(def_node_id, bounds) => {
1317 let span = t.span;
1318 match itctx {
1319 ImplTraitContext::OpaqueTy { origin } => {
1320 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1321 }
1322 ImplTraitContext::Universal => {
1323 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1324 ast::GenericBound::Use(_, span) => Some(span),
1325 _ => None,
1326 }) {
1327 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1328 }
1329
1330 let def_id = self.local_def_id(*def_node_id);
1331 let name = self.tcx.item_name(def_id.to_def_id());
1332 let ident = Ident::new(name, span);
1333 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1334 *def_node_id,
1335 span,
1336 ident,
1337 bounds,
1338 );
1339 self.impl_trait_defs.push(param);
1340 if let Some(bounds) = bounds {
1341 self.impl_trait_bounds.push(bounds);
1342 }
1343 path
1344 }
1345 ImplTraitContext::InBinding => {
1346 hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1347 }
1348 ImplTraitContext::FeatureGated(position, feature) => {
1349 let guar = self
1350 .tcx
1351 .sess
1352 .create_feature_err(
1353 MisplacedImplTrait {
1354 span: t.span,
1355 position: DiagArgFromDisplay(&position),
1356 },
1357 feature,
1358 )
1359 .emit();
1360 hir::TyKind::Err(guar)
1361 }
1362 ImplTraitContext::Disallowed(position) => {
1363 let guar = self.dcx().emit_err(MisplacedImplTrait {
1364 span: t.span,
1365 position: DiagArgFromDisplay(&position),
1366 });
1367 hir::TyKind::Err(guar)
1368 }
1369 }
1370 }
1371 TyKind::Pat(ty, pat) => {
1372 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1373 }
1374 TyKind::MacCall(_) => {
1375 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1376 }
1377 TyKind::CVarArgs => {
1378 let guar = self.dcx().span_delayed_bug(
1379 t.span,
1380 "`TyKind::CVarArgs` should have been handled elsewhere",
1381 );
1382 hir::TyKind::Err(guar)
1383 }
1384 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1385 };
1386
1387 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1388 }
1389
1390 fn lower_ty_direct_lifetime(
1391 &mut self,
1392 t: &Ty,
1393 region: Option<Lifetime>,
1394 ) -> &'hir hir::Lifetime {
1395 let (region, syntax) = match region {
1396 Some(region) => (region, region.ident.into()),
1397
1398 None => {
1399 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1400 self.resolver.get_lifetime_res(t.id)
1401 {
1402 debug_assert_eq!(start.plus(1), end);
1403 start
1404 } else {
1405 self.next_node_id()
1406 };
1407 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1408 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1409 (region, LifetimeSyntax::Implicit)
1410 }
1411 };
1412 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1413 }
1414
1415 #[instrument(level = "debug", skip(self), ret)]
1447 fn lower_opaque_impl_trait(
1448 &mut self,
1449 span: Span,
1450 origin: hir::OpaqueTyOrigin<LocalDefId>,
1451 opaque_ty_node_id: NodeId,
1452 bounds: &GenericBounds,
1453 itctx: ImplTraitContext,
1454 ) -> hir::TyKind<'hir> {
1455 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1461
1462 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1463 this.lower_param_bounds(bounds, itctx)
1464 })
1465 }
1466
1467 fn lower_opaque_inner(
1468 &mut self,
1469 opaque_ty_node_id: NodeId,
1470 origin: hir::OpaqueTyOrigin<LocalDefId>,
1471 opaque_ty_span: Span,
1472 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1473 ) -> hir::TyKind<'hir> {
1474 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1475 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1476 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1477
1478 let bounds = lower_item_bounds(self);
1479 let opaque_ty_def = hir::OpaqueTy {
1480 hir_id: opaque_ty_hir_id,
1481 def_id: opaque_ty_def_id,
1482 bounds,
1483 origin,
1484 span: self.lower_span(opaque_ty_span),
1485 };
1486 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1487
1488 hir::TyKind::OpaqueDef(opaque_ty_def)
1489 }
1490
1491 fn lower_precise_capturing_args(
1492 &mut self,
1493 precise_capturing_args: &[PreciseCapturingArg],
1494 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1495 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1496 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1497 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1498 ),
1499 PreciseCapturingArg::Arg(path, id) => {
1500 let [segment] = path.segments.as_slice() else {
1501 panic!();
1502 };
1503 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1504 partial_res.full_res().expect("no partial res expected for precise capture arg")
1505 });
1506 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1507 hir_id: self.lower_node_id(*id),
1508 ident: self.lower_ident(segment.ident),
1509 res: self.lower_res(res),
1510 })
1511 }
1512 }))
1513 }
1514
1515 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1516 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1517 PatKind::Missing => None,
1518 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1519 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1520 _ => {
1521 self.dcx().span_delayed_bug(
1522 param.pat.span,
1523 "non-missing/ident/wild param pat must trigger an error",
1524 );
1525 None
1526 }
1527 }))
1528 }
1529
1530 #[instrument(level = "debug", skip(self))]
1540 fn lower_fn_decl(
1541 &mut self,
1542 decl: &FnDecl,
1543 fn_node_id: NodeId,
1544 fn_span: Span,
1545 kind: FnDeclKind,
1546 coro: Option<CoroutineKind>,
1547 ) -> &'hir hir::FnDecl<'hir> {
1548 let c_variadic = decl.c_variadic();
1549
1550 let mut inputs = &decl.inputs[..];
1554 if c_variadic {
1555 inputs = &inputs[..inputs.len() - 1];
1556 }
1557 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1558 let itctx = match kind {
1559 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1560 ImplTraitContext::Universal
1561 }
1562 FnDeclKind::ExternFn => {
1563 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1564 }
1565 FnDeclKind::Closure => {
1566 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1567 }
1568 FnDeclKind::Pointer => {
1569 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1570 }
1571 };
1572 self.lower_ty_direct(¶m.ty, itctx)
1573 }));
1574
1575 let output = match coro {
1576 Some(coro) => {
1577 let fn_def_id = self.local_def_id(fn_node_id);
1578 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1579 }
1580 None => match &decl.output {
1581 FnRetTy::Ty(ty) => {
1582 let itctx = match kind {
1583 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1584 origin: hir::OpaqueTyOrigin::FnReturn {
1585 parent: self.local_def_id(fn_node_id),
1586 in_trait_or_impl: None,
1587 },
1588 },
1589 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1590 origin: hir::OpaqueTyOrigin::FnReturn {
1591 parent: self.local_def_id(fn_node_id),
1592 in_trait_or_impl: Some(hir::RpitContext::Trait),
1593 },
1594 },
1595 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1596 origin: hir::OpaqueTyOrigin::FnReturn {
1597 parent: self.local_def_id(fn_node_id),
1598 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1599 },
1600 },
1601 FnDeclKind::ExternFn => {
1602 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1603 }
1604 FnDeclKind::Closure => {
1605 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1606 }
1607 FnDeclKind::Pointer => {
1608 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1609 }
1610 };
1611 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1612 }
1613 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1614 },
1615 };
1616
1617 self.arena.alloc(hir::FnDecl {
1618 inputs,
1619 output,
1620 c_variadic,
1621 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1622 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1623 let is_mutable_pat = matches!(
1624 arg.pat.kind,
1625 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1626 );
1627
1628 match &arg.ty.kind {
1629 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1630 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1631 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1635 if mt.ty.kind.is_implicit_self() =>
1636 {
1637 match mt.mutbl {
1638 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1639 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1640 }
1641 }
1642 _ => hir::ImplicitSelfKind::None,
1643 }
1644 }),
1645 })
1646 }
1647
1648 #[instrument(level = "debug", skip(self))]
1657 fn lower_coroutine_fn_ret_ty(
1658 &mut self,
1659 output: &FnRetTy,
1660 fn_def_id: LocalDefId,
1661 coro: CoroutineKind,
1662 fn_kind: FnDeclKind,
1663 fn_span: Span,
1664 ) -> hir::FnRetTy<'hir> {
1665 let span = self.lower_span(fn_span);
1666
1667 let (opaque_ty_node_id, allowed_features) = match coro {
1668 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1669 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1670 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1671 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1672 }
1673 };
1674
1675 let opaque_ty_span =
1676 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1677
1678 let in_trait_or_impl = match fn_kind {
1679 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1680 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1681 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1682 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1683 };
1684
1685 let opaque_ty_ref = self.lower_opaque_inner(
1686 opaque_ty_node_id,
1687 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1688 opaque_ty_span,
1689 |this| {
1690 let bound = this.lower_coroutine_fn_output_type_to_bound(
1691 output,
1692 coro,
1693 opaque_ty_span,
1694 ImplTraitContext::OpaqueTy {
1695 origin: hir::OpaqueTyOrigin::FnReturn {
1696 parent: fn_def_id,
1697 in_trait_or_impl,
1698 },
1699 },
1700 );
1701 arena_vec![this; bound]
1702 },
1703 );
1704
1705 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1706 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1707 }
1708
1709 fn lower_coroutine_fn_output_type_to_bound(
1711 &mut self,
1712 output: &FnRetTy,
1713 coro: CoroutineKind,
1714 opaque_ty_span: Span,
1715 itctx: ImplTraitContext,
1716 ) -> hir::GenericBound<'hir> {
1717 let output_ty = match output {
1719 FnRetTy::Ty(ty) => {
1720 self.lower_ty(ty, itctx)
1724 }
1725 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1726 };
1727
1728 let (assoc_ty_name, trait_lang_item) = match coro {
1730 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1731 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1732 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1733 };
1734
1735 let bound_args = self.arena.alloc(hir::GenericArgs {
1736 args: &[],
1737 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1738 parenthesized: hir::GenericArgsParentheses::No,
1739 span_ext: DUMMY_SP,
1740 });
1741
1742 hir::GenericBound::Trait(hir::PolyTraitRef {
1743 bound_generic_params: &[],
1744 modifiers: hir::TraitBoundModifiers::NONE,
1745 trait_ref: hir::TraitRef {
1746 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1747 hir_ref_id: self.next_id(),
1748 },
1749 span: opaque_ty_span,
1750 })
1751 }
1752
1753 #[instrument(level = "trace", skip(self))]
1754 fn lower_param_bound(
1755 &mut self,
1756 tpb: &GenericBound,
1757 itctx: ImplTraitContext,
1758 ) -> hir::GenericBound<'hir> {
1759 match tpb {
1760 GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1761 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1762 lifetime,
1763 LifetimeSource::OutlivesBound,
1764 lifetime.ident.into(),
1765 )),
1766 GenericBound::Use(args, span) => hir::GenericBound::Use(
1767 self.lower_precise_capturing_args(args),
1768 self.lower_span(*span),
1769 ),
1770 }
1771 }
1772
1773 fn lower_lifetime(
1774 &mut self,
1775 l: &Lifetime,
1776 source: LifetimeSource,
1777 syntax: LifetimeSyntax,
1778 ) -> &'hir hir::Lifetime {
1779 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1780 }
1781
1782 fn lower_lifetime_hidden_in_path(
1783 &mut self,
1784 id: NodeId,
1785 span: Span,
1786 angle_brackets: AngleBrackets,
1787 ) -> &'hir hir::Lifetime {
1788 self.new_named_lifetime(
1789 id,
1790 id,
1791 Ident::new(kw::UnderscoreLifetime, span),
1792 LifetimeSource::Path { angle_brackets },
1793 LifetimeSyntax::Implicit,
1794 )
1795 }
1796
1797 #[instrument(level = "debug", skip(self))]
1798 fn new_named_lifetime(
1799 &mut self,
1800 id: NodeId,
1801 new_id: NodeId,
1802 ident: Ident,
1803 source: LifetimeSource,
1804 syntax: LifetimeSyntax,
1805 ) -> &'hir hir::Lifetime {
1806 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1807 let res = match res {
1808 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1809 LifetimeRes::Fresh { param, .. } => {
1810 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1811 let param = self.local_def_id(param);
1812 hir::LifetimeKind::Param(param)
1813 }
1814 LifetimeRes::Infer => {
1815 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1816 hir::LifetimeKind::Infer
1817 }
1818 LifetimeRes::Static { .. } => {
1819 debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1820 hir::LifetimeKind::Static
1821 }
1822 LifetimeRes::Error => hir::LifetimeKind::Error,
1823 LifetimeRes::ElidedAnchor { .. } => {
1824 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1825 }
1826 };
1827
1828 debug!(?res);
1829 self.arena.alloc(hir::Lifetime::new(
1830 self.lower_node_id(new_id),
1831 self.lower_ident(ident),
1832 res,
1833 source,
1834 syntax,
1835 ))
1836 }
1837
1838 fn lower_generic_params_mut(
1839 &mut self,
1840 params: &[GenericParam],
1841 source: hir::GenericParamSource,
1842 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1843 params.iter().map(move |param| self.lower_generic_param(param, source))
1844 }
1845
1846 fn lower_generic_params(
1847 &mut self,
1848 params: &[GenericParam],
1849 source: hir::GenericParamSource,
1850 ) -> &'hir [hir::GenericParam<'hir>] {
1851 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1852 }
1853
1854 #[instrument(level = "trace", skip(self))]
1855 fn lower_generic_param(
1856 &mut self,
1857 param: &GenericParam,
1858 source: hir::GenericParamSource,
1859 ) -> hir::GenericParam<'hir> {
1860 let (name, kind) = self.lower_generic_param_kind(param, source);
1861
1862 let hir_id = self.lower_node_id(param.id);
1863 self.lower_attrs(hir_id, ¶m.attrs, param.span());
1864 hir::GenericParam {
1865 hir_id,
1866 def_id: self.local_def_id(param.id),
1867 name,
1868 span: self.lower_span(param.span()),
1869 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1870 kind,
1871 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1872 source,
1873 }
1874 }
1875
1876 fn lower_generic_param_kind(
1877 &mut self,
1878 param: &GenericParam,
1879 source: hir::GenericParamSource,
1880 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1881 match ¶m.kind {
1882 GenericParamKind::Lifetime => {
1883 let ident = self.lower_ident(param.ident);
1886 let param_name =
1887 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1888 ParamName::Error(ident)
1889 } else {
1890 ParamName::Plain(ident)
1891 };
1892 let kind =
1893 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1894
1895 (param_name, kind)
1896 }
1897 GenericParamKind::Type { default, .. } => {
1898 let default = default
1901 .as_ref()
1902 .filter(|_| match source {
1903 hir::GenericParamSource::Generics => true,
1904 hir::GenericParamSource::Binder => {
1905 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1906 span: param.span(),
1907 });
1908
1909 false
1910 }
1911 })
1912 .map(|def| {
1913 self.lower_ty(
1914 def,
1915 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1916 )
1917 });
1918
1919 let kind = hir::GenericParamKind::Type { default, synthetic: false };
1920
1921 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1922 }
1923 GenericParamKind::Const { ty, kw_span: _, default } => {
1924 let ty = self
1925 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1926
1927 let default = default
1930 .as_ref()
1931 .filter(|_| match source {
1932 hir::GenericParamSource::Generics => true,
1933 hir::GenericParamSource::Binder => {
1934 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1935 span: param.span(),
1936 });
1937
1938 false
1939 }
1940 })
1941 .map(|def| self.lower_anon_const_to_const_arg(def));
1942
1943 (
1944 hir::ParamName::Plain(self.lower_ident(param.ident)),
1945 hir::GenericParamKind::Const { ty, default, synthetic: false },
1946 )
1947 }
1948 }
1949 }
1950
1951 fn lower_trait_ref(
1952 &mut self,
1953 modifiers: ast::TraitBoundModifiers,
1954 p: &TraitRef,
1955 itctx: ImplTraitContext,
1956 ) -> hir::TraitRef<'hir> {
1957 let path = match self.lower_qpath(
1958 p.ref_id,
1959 &None,
1960 &p.path,
1961 ParamMode::Explicit,
1962 AllowReturnTypeNotation::No,
1963 itctx,
1964 Some(modifiers),
1965 ) {
1966 hir::QPath::Resolved(None, path) => path,
1967 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
1968 };
1969 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1970 }
1971
1972 #[instrument(level = "debug", skip(self))]
1973 fn lower_poly_trait_ref(
1974 &mut self,
1975 p: &PolyTraitRef,
1976 itctx: ImplTraitContext,
1977 ) -> hir::PolyTraitRef<'hir> {
1978 let bound_generic_params =
1979 self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
1980 let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
1981 let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
1982 hir::PolyTraitRef {
1983 bound_generic_params,
1984 modifiers,
1985 trait_ref,
1986 span: self.lower_span(p.span),
1987 }
1988 }
1989
1990 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1991 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1992 }
1993
1994 #[instrument(level = "debug", skip(self), ret)]
1995 fn lower_param_bounds(
1996 &mut self,
1997 bounds: &[GenericBound],
1998 itctx: ImplTraitContext,
1999 ) -> hir::GenericBounds<'hir> {
2000 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2001 }
2002
2003 fn lower_param_bounds_mut(
2004 &mut self,
2005 bounds: &[GenericBound],
2006 itctx: ImplTraitContext,
2007 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2008 bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2009 }
2010
2011 #[instrument(level = "debug", skip(self), ret)]
2012 fn lower_universal_param_and_bounds(
2013 &mut self,
2014 node_id: NodeId,
2015 span: Span,
2016 ident: Ident,
2017 bounds: &[GenericBound],
2018 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2019 let def_id = self.local_def_id(node_id);
2021 let span = self.lower_span(span);
2022
2023 let param = hir::GenericParam {
2025 hir_id: self.lower_node_id(node_id),
2026 def_id,
2027 name: ParamName::Plain(self.lower_ident(ident)),
2028 pure_wrt_drop: false,
2029 span,
2030 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2031 colon_span: None,
2032 source: hir::GenericParamSource::Generics,
2033 };
2034
2035 let preds = self.lower_generic_bound_predicate(
2036 ident,
2037 node_id,
2038 &GenericParamKind::Type { default: None },
2039 bounds,
2040 None,
2041 span,
2042 ImplTraitContext::Universal,
2043 hir::PredicateOrigin::ImplTrait,
2044 );
2045
2046 let hir_id = self.next_id();
2047 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2048 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2049 None,
2050 self.arena.alloc(hir::Path {
2051 span,
2052 res,
2053 segments:
2054 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2055 }),
2056 ));
2057
2058 (param, preds, ty)
2059 }
2060
2061 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2064 let block = self.lower_block(b, false);
2065 self.expr_block(block)
2066 }
2067
2068 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2069 match c.value.peel_parens().kind {
2072 ExprKind::Underscore => {
2073 if !self.tcx.features().generic_arg_infer() {
2074 feature_err(
2075 &self.tcx.sess,
2076 sym::generic_arg_infer,
2077 c.value.span,
2078 fluent_generated::ast_lowering_underscore_array_length_unstable,
2079 )
2080 .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2081 }
2082 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2083 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2084 }
2085 _ => self.lower_anon_const_to_const_arg(c),
2086 }
2087 }
2088
2089 #[instrument(level = "debug", skip(self))]
2093 fn lower_const_path_to_const_arg(
2094 &mut self,
2095 path: &Path,
2096 res: Res<NodeId>,
2097 ty_id: NodeId,
2098 span: Span,
2099 ) -> &'hir hir::ConstArg<'hir> {
2100 let tcx = self.tcx;
2101
2102 let ct_kind = if path
2103 .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2104 && (tcx.features().min_generic_const_args()
2105 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2106 {
2107 let qpath = self.lower_qpath(
2108 ty_id,
2109 &None,
2110 path,
2111 ParamMode::Optional,
2112 AllowReturnTypeNotation::No,
2113 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2115 None,
2116 );
2117 hir::ConstArgKind::Path(qpath)
2118 } else {
2119 let node_id = self.next_node_id();
2121 let span = self.lower_span(span);
2122
2123 let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2128 let hir_id = self.lower_node_id(node_id);
2129
2130 let path_expr = Expr {
2131 id: ty_id,
2132 kind: ExprKind::Path(None, path.clone()),
2133 span,
2134 attrs: AttrVec::new(),
2135 tokens: None,
2136 };
2137
2138 let ct = self.with_new_scopes(span, |this| {
2139 self.arena.alloc(hir::AnonConst {
2140 def_id,
2141 hir_id,
2142 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2143 span,
2144 })
2145 });
2146 hir::ConstArgKind::Anon(ct)
2147 };
2148
2149 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2150 }
2151
2152 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2155 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2156 }
2157
2158 #[instrument(level = "debug", skip(self))]
2159 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2160 let tcx = self.tcx;
2161 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2164 && let [stmt] = block.stmts.as_slice()
2165 && let StmtKind::Expr(expr) = &stmt.kind
2166 && let ExprKind::Path(..) = &expr.kind
2167 {
2168 expr
2169 } else {
2170 &anon.value
2171 };
2172 let maybe_res =
2173 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2174 if let ExprKind::Path(qself, path) = &expr.kind
2175 && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2176 && (tcx.features().min_generic_const_args()
2177 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2178 {
2179 let qpath = self.lower_qpath(
2180 expr.id,
2181 qself,
2182 path,
2183 ParamMode::Optional,
2184 AllowReturnTypeNotation::No,
2185 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2187 None,
2188 );
2189
2190 return ConstArg {
2191 hir_id: self.lower_node_id(anon.id),
2192 kind: hir::ConstArgKind::Path(qpath),
2193 };
2194 }
2195
2196 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2197 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2198 }
2199
2200 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2203 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2204 let def_id = this.local_def_id(c.id);
2205 let hir_id = this.lower_node_id(c.id);
2206 hir::AnonConst {
2207 def_id,
2208 hir_id,
2209 body: this.lower_const_body(c.value.span, Some(&c.value)),
2210 span: this.lower_span(c.value.span),
2211 }
2212 }))
2213 }
2214
2215 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2216 match u {
2217 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2218 UserProvided => hir::UnsafeSource::UserProvided,
2219 }
2220 }
2221
2222 fn lower_trait_bound_modifiers(
2223 &mut self,
2224 modifiers: TraitBoundModifiers,
2225 ) -> hir::TraitBoundModifiers {
2226 hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2227 }
2228
2229 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2232 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2233 }
2234
2235 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2236 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2237 }
2238
2239 fn stmt_let_pat(
2240 &mut self,
2241 attrs: Option<&'hir [hir::Attribute]>,
2242 span: Span,
2243 init: Option<&'hir hir::Expr<'hir>>,
2244 pat: &'hir hir::Pat<'hir>,
2245 source: hir::LocalSource,
2246 ) -> hir::Stmt<'hir> {
2247 let hir_id = self.next_id();
2248 if let Some(a) = attrs {
2249 debug_assert!(!a.is_empty());
2250 self.attrs.insert(hir_id.local_id, a);
2251 }
2252 let local = hir::LetStmt {
2253 super_: None,
2254 hir_id,
2255 init,
2256 pat,
2257 els: None,
2258 source,
2259 span: self.lower_span(span),
2260 ty: None,
2261 };
2262 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2263 }
2264
2265 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2266 self.block_all(expr.span, &[], Some(expr))
2267 }
2268
2269 fn block_all(
2270 &mut self,
2271 span: Span,
2272 stmts: &'hir [hir::Stmt<'hir>],
2273 expr: Option<&'hir hir::Expr<'hir>>,
2274 ) -> &'hir hir::Block<'hir> {
2275 let blk = hir::Block {
2276 stmts,
2277 expr,
2278 hir_id: self.next_id(),
2279 rules: hir::BlockCheckMode::DefaultBlock,
2280 span: self.lower_span(span),
2281 targeted_by_break: false,
2282 };
2283 self.arena.alloc(blk)
2284 }
2285
2286 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2287 let field = self.single_pat_field(span, pat);
2288 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2289 }
2290
2291 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2292 let field = self.single_pat_field(span, pat);
2293 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2294 }
2295
2296 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2297 let field = self.single_pat_field(span, pat);
2298 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2299 }
2300
2301 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2302 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2303 }
2304
2305 fn single_pat_field(
2306 &mut self,
2307 span: Span,
2308 pat: &'hir hir::Pat<'hir>,
2309 ) -> &'hir [hir::PatField<'hir>] {
2310 let field = hir::PatField {
2311 hir_id: self.next_id(),
2312 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2313 is_shorthand: false,
2314 pat,
2315 span: self.lower_span(span),
2316 };
2317 arena_vec![self; field]
2318 }
2319
2320 fn pat_lang_item_variant(
2321 &mut self,
2322 span: Span,
2323 lang_item: hir::LangItem,
2324 fields: &'hir [hir::PatField<'hir>],
2325 ) -> &'hir hir::Pat<'hir> {
2326 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2327 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2328 }
2329
2330 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2331 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2332 }
2333
2334 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2335 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2336 }
2337
2338 fn pat_ident_binding_mode(
2339 &mut self,
2340 span: Span,
2341 ident: Ident,
2342 bm: hir::BindingMode,
2343 ) -> (&'hir hir::Pat<'hir>, HirId) {
2344 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2345 (self.arena.alloc(pat), hir_id)
2346 }
2347
2348 fn pat_ident_binding_mode_mut(
2349 &mut self,
2350 span: Span,
2351 ident: Ident,
2352 bm: hir::BindingMode,
2353 ) -> (hir::Pat<'hir>, HirId) {
2354 let hir_id = self.next_id();
2355
2356 (
2357 hir::Pat {
2358 hir_id,
2359 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2360 span: self.lower_span(span),
2361 default_binding_modes: true,
2362 },
2363 hir_id,
2364 )
2365 }
2366
2367 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2368 self.arena.alloc(hir::Pat {
2369 hir_id: self.next_id(),
2370 kind,
2371 span: self.lower_span(span),
2372 default_binding_modes: true,
2373 })
2374 }
2375
2376 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2377 hir::Pat {
2378 hir_id: self.next_id(),
2379 kind,
2380 span: self.lower_span(span),
2381 default_binding_modes: false,
2382 }
2383 }
2384
2385 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2386 let kind = match qpath {
2387 hir::QPath::Resolved(None, path) => {
2388 match path.res {
2390 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2391 let principal = hir::PolyTraitRef {
2392 bound_generic_params: &[],
2393 modifiers: hir::TraitBoundModifiers::NONE,
2394 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2395 span: self.lower_span(span),
2396 };
2397
2398 hir_id = self.next_id();
2401 hir::TyKind::TraitObject(
2402 arena_vec![self; principal],
2403 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2404 )
2405 }
2406 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2407 }
2408 }
2409 _ => hir::TyKind::Path(qpath),
2410 };
2411
2412 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2413 }
2414
2415 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2420 let r = hir::Lifetime::new(
2421 self.next_id(),
2422 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2423 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2424 LifetimeSource::Other,
2425 LifetimeSyntax::Implicit,
2426 );
2427 debug!("elided_dyn_bound: r={:?}", r);
2428 self.arena.alloc(r)
2429 }
2430}
2431
2432struct GenericArgsCtor<'hir> {
2434 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2435 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2436 parenthesized: hir::GenericArgsParentheses,
2437 span: Span,
2438}
2439
2440impl<'hir> GenericArgsCtor<'hir> {
2441 fn is_empty(&self) -> bool {
2442 self.args.is_empty()
2443 && self.constraints.is_empty()
2444 && self.parenthesized == hir::GenericArgsParentheses::No
2445 }
2446
2447 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2448 let ga = hir::GenericArgs {
2449 args: this.arena.alloc_from_iter(self.args),
2450 constraints: self.constraints,
2451 parenthesized: self.parenthesized,
2452 span_ext: this.lower_span(self.span),
2453 };
2454 this.arena.alloc(ga)
2455 }
2456}