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