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