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