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