1#![allow(internal_features)]
35#![doc(rust_logo)]
36#![feature(box_patterns)]
37#![feature(if_let_guard)]
38#![feature(rustdoc_internals)]
39use std::sync::Arc;
42
43use rustc_ast::node_id::NodeMap;
44use rustc_ast::{self as ast, *};
45use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
46use rustc_data_structures::fingerprint::Fingerprint;
47use rustc_data_structures::sorted_map::SortedMap;
48use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
49use rustc_data_structures::sync::spawn;
50use rustc_data_structures::tagged_ptr::TaggedRef;
51use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};
52use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
53use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
54use rustc_hir::lints::DelayedLint;
55use rustc_hir::{
56 self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
57 LifetimeSyntax, ParamName, TraitCandidate,
58};
59use rustc_index::{Idx, IndexSlice, IndexVec};
60use rustc_macros::extension;
61use rustc_middle::span_bug;
62use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
63use rustc_session::parse::add_feature_diagnostics;
64use rustc_span::symbol::{Ident, Symbol, kw, sym};
65use rustc_span::{DUMMY_SP, DesugaringKind, Span};
66use smallvec::SmallVec;
67use thin_vec::ThinVec;
68use tracing::{debug, instrument, trace};
69
70use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
71
72macro_rules! arena_vec {
73 ($this:expr; $($x:expr),*) => (
74 $this.arena.alloc_from_iter([$($x),*])
75 );
76}
77
78mod asm;
79mod block;
80mod delegation;
81mod errors;
82mod expr;
83mod format;
84mod index;
85mod item;
86mod pat;
87mod path;
88pub mod stability;
89
90rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
91
92struct LoweringContext<'a, 'hir> {
93 tcx: TyCtxt<'hir>,
94 resolver: &'a mut ResolverAstLowering,
95
96 arena: &'hir hir::Arena<'hir>,
98
99 bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
101 define_opaque: Option<&'hir [(Span, LocalDefId)]>,
103 attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
105 children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
107
108 contract_ensures: Option<(Span, Ident, HirId)>,
109
110 coroutine_kind: Option<hir::CoroutineKind>,
111
112 task_context: Option<HirId>,
115
116 current_item: Option<Span>,
119
120 catch_scope: Option<HirId>,
121 loop_scope: Option<HirId>,
122 is_in_loop_condition: bool,
123 is_in_dyn_type: bool,
124
125 current_hir_id_owner: hir::OwnerId,
126 item_local_id_counter: hir::ItemLocalId,
127 trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
128
129 impl_trait_defs: Vec<hir::GenericParam<'hir>>,
130 impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
131
132 ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
134 #[cfg(debug_assertions)]
136 node_id_to_local_id: NodeMap<hir::ItemLocalId>,
137
138 allow_try_trait: Arc<[Symbol]>,
139 allow_gen_future: Arc<[Symbol]>,
140 allow_pattern_type: Arc<[Symbol]>,
141 allow_async_iterator: Arc<[Symbol]>,
142 allow_for_await: Arc<[Symbol]>,
143 allow_async_fn_traits: Arc<[Symbol]>,
144
145 delayed_lints: Vec<DelayedLint>,
146
147 attribute_parser: AttributeParser<'hir>,
148}
149
150impl<'a, 'hir> LoweringContext<'a, 'hir> {
151 fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
152 let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
153 Self {
154 tcx,
156 resolver,
157 arena: tcx.hir_arena,
158
159 bodies: Vec::new(),
161 define_opaque: None,
162 attrs: SortedMap::default(),
163 children: Vec::default(),
164 contract_ensures: None,
165 current_hir_id_owner: hir::CRATE_OWNER_ID,
166 item_local_id_counter: hir::ItemLocalId::ZERO,
167 ident_and_label_to_local_id: Default::default(),
168 #[cfg(debug_assertions)]
169 node_id_to_local_id: Default::default(),
170 trait_map: Default::default(),
171
172 catch_scope: None,
174 loop_scope: None,
175 is_in_loop_condition: false,
176 is_in_dyn_type: false,
177 coroutine_kind: None,
178 task_context: None,
179 current_item: None,
180 impl_trait_defs: Vec::new(),
181 impl_trait_bounds: Vec::new(),
182 allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
183 allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
184 allow_gen_future: if tcx.features().async_fn_track_caller() {
185 [sym::gen_future, sym::closure_track_caller].into()
186 } else {
187 [sym::gen_future].into()
188 },
189 allow_for_await: [sym::async_iterator].into(),
190 allow_async_fn_traits: [sym::async_fn_traits].into(),
191 allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
194
195 attribute_parser: AttributeParser::new(
196 tcx.sess,
197 tcx.features(),
198 registered_tools,
199 Late,
200 ),
201 delayed_lints: Vec::new(),
202 }
203 }
204
205 pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
206 self.tcx.dcx()
207 }
208}
209
210struct SpanLowerer {
211 is_incremental: bool,
212 def_id: LocalDefId,
213}
214
215impl SpanLowerer {
216 fn lower(&self, span: Span) -> Span {
217 if self.is_incremental {
218 span.with_parent(Some(self.def_id))
219 } else {
220 span
222 }
223 }
224}
225
226#[extension(trait ResolverAstLoweringExt)]
227impl ResolverAstLowering {
228 fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
229 if let ExprKind::Path(None, path) = &expr.kind {
230 if path.segments.last().unwrap().args.is_some() {
233 return None;
234 }
235
236 if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
237 if def_id.is_local() {
241 return None;
242 }
243
244 if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
245 return v.clone();
246 }
247 }
248 }
249
250 None
251 }
252
253 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
254 self.partial_res_map.get(&id).copied()
255 }
256
257 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
259 self.import_res_map.get(&id).copied().unwrap_or_default()
260 }
261
262 fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
264 self.label_res_map.get(&id).copied()
265 }
266
267 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
269 self.lifetimes_res_map.get(&id).copied()
270 }
271
272 fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
280 self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
281 }
282}
283
284#[derive(Clone, Copy, Debug)]
289enum RelaxedBoundPolicy<'a> {
290 Allowed,
291 AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),
292 Forbidden(RelaxedBoundForbiddenReason),
293}
294
295#[derive(Clone, Copy, Debug)]
296enum RelaxedBoundForbiddenReason {
297 TraitObjectTy,
298 SuperTrait,
299 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 ) -> &'hir [hir::Attribute] {
947 if attrs.is_empty() {
948 &[]
949 } else {
950 let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span), id);
951
952 assert_eq!(id.owner, self.current_hir_id_owner);
953 let ret = self.arena.alloc_from_iter(lowered_attrs);
954
955 if ret.is_empty() {
962 &[]
963 } else {
964 self.attrs.insert(id.local_id, ret);
965 ret
966 }
967 }
968 }
969
970 fn lower_attrs_vec(
971 &mut self,
972 attrs: &[Attribute],
973 target_span: Span,
974 target_hir_id: HirId,
975 ) -> Vec<hir::Attribute> {
976 let l = self.span_lowerer();
977 self.attribute_parser.parse_attribute_list(
978 attrs,
979 target_span,
980 target_hir_id,
981 OmitDoc::Lower,
982 |s| l.lower(s),
983 |l| {
984 self.delayed_lints.push(DelayedLint::AttributeParsing(l));
985 },
986 )
987 }
988
989 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
990 assert_eq!(id.owner, self.current_hir_id_owner);
991 assert_eq!(target_id.owner, self.current_hir_id_owner);
992 if let Some(&a) = self.attrs.get(&target_id.local_id) {
993 assert!(!a.is_empty());
994 self.attrs.insert(id.local_id, a);
995 }
996 }
997
998 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
999 args.clone()
1000 }
1001
1002 #[instrument(level = "debug", skip_all)]
1004 fn lower_assoc_item_constraint(
1005 &mut self,
1006 constraint: &AssocItemConstraint,
1007 itctx: ImplTraitContext,
1008 ) -> hir::AssocItemConstraint<'hir> {
1009 debug!(?constraint, ?itctx);
1010 let gen_args = if let Some(gen_args) = &constraint.gen_args {
1012 let gen_args_ctor = match gen_args {
1013 GenericArgs::AngleBracketed(data) => {
1014 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
1015 }
1016 GenericArgs::Parenthesized(data) => {
1017 if let Some(first_char) = constraint.ident.as_str().chars().next()
1018 && first_char.is_ascii_lowercase()
1019 {
1020 let err = match (&data.inputs[..], &data.output) {
1021 ([_, ..], FnRetTy::Default(_)) => {
1022 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
1023 }
1024 ([], FnRetTy::Default(_)) => {
1025 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
1026 }
1027 (_, FnRetTy::Ty(ty)) => {
1029 let span = data.inputs_span.shrink_to_hi().to(ty.span);
1030 errors::BadReturnTypeNotation::Output {
1031 span,
1032 suggestion: errors::RTNSuggestion {
1033 output: span,
1034 input: data.inputs_span,
1035 },
1036 }
1037 }
1038 };
1039 let mut err = self.dcx().create_err(err);
1040 if !self.tcx.features().return_type_notation()
1041 && self.tcx.sess.is_nightly_build()
1042 {
1043 add_feature_diagnostics(
1044 &mut err,
1045 &self.tcx.sess,
1046 sym::return_type_notation,
1047 );
1048 }
1049 err.emit();
1050 GenericArgsCtor {
1051 args: Default::default(),
1052 constraints: &[],
1053 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1054 span: data.span,
1055 }
1056 } else {
1057 self.emit_bad_parenthesized_trait_in_assoc_ty(data);
1058 self.lower_angle_bracketed_parameter_data(
1061 &data.as_angle_bracketed_args(),
1062 ParamMode::Explicit,
1063 itctx,
1064 )
1065 .0
1066 }
1067 }
1068 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
1069 args: Default::default(),
1070 constraints: &[],
1071 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1072 span: *span,
1073 },
1074 };
1075 gen_args_ctor.into_generic_args(self)
1076 } else {
1077 self.arena.alloc(hir::GenericArgs::none())
1078 };
1079 let kind = match &constraint.kind {
1080 AssocItemConstraintKind::Equality { term } => {
1081 let term = match term {
1082 Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1083 Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1084 };
1085 hir::AssocItemConstraintKind::Equality { term }
1086 }
1087 AssocItemConstraintKind::Bound { bounds } => {
1088 if self.is_in_dyn_type {
1090 let suggestion = match itctx {
1091 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1092 let bound_end_span = constraint
1093 .gen_args
1094 .as_ref()
1095 .map_or(constraint.ident.span, |args| args.span());
1096 if bound_end_span.eq_ctxt(constraint.span) {
1097 Some(self.tcx.sess.source_map().next_point(bound_end_span))
1098 } else {
1099 None
1100 }
1101 }
1102 _ => None,
1103 };
1104
1105 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1106 span: constraint.span,
1107 suggestion,
1108 });
1109 let err_ty =
1110 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1111 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1112 } else {
1113 let bounds = self.lower_param_bounds(
1114 bounds,
1115 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),
1116 itctx,
1117 );
1118 hir::AssocItemConstraintKind::Bound { bounds }
1119 }
1120 }
1121 };
1122
1123 hir::AssocItemConstraint {
1124 hir_id: self.lower_node_id(constraint.id),
1125 ident: self.lower_ident(constraint.ident),
1126 gen_args,
1127 kind,
1128 span: self.lower_span(constraint.span),
1129 }
1130 }
1131
1132 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1133 let sub = if data.inputs.is_empty() {
1135 let parentheses_span =
1136 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1137 AssocTyParenthesesSub::Empty { parentheses_span }
1138 }
1139 else {
1141 let open_param = data.inputs_span.shrink_to_lo().to(data
1143 .inputs
1144 .first()
1145 .unwrap()
1146 .span
1147 .shrink_to_lo());
1148 let close_param =
1150 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1151 AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1152 };
1153 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1154 }
1155
1156 #[instrument(level = "debug", skip(self))]
1157 fn lower_generic_arg(
1158 &mut self,
1159 arg: &ast::GenericArg,
1160 itctx: ImplTraitContext,
1161 ) -> hir::GenericArg<'hir> {
1162 match arg {
1163 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1164 lt,
1165 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1166 lt.ident.into(),
1167 )),
1168 ast::GenericArg::Type(ty) => {
1169 if ty.is_maybe_parenthesised_infer() {
1172 return GenericArg::Infer(hir::InferArg {
1173 hir_id: self.lower_node_id(ty.id),
1174 span: self.lower_span(ty.span),
1175 });
1176 }
1177
1178 match &ty.kind {
1179 TyKind::Path(None, path) => {
1186 if let Some(res) = self
1187 .resolver
1188 .get_partial_res(ty.id)
1189 .and_then(|partial_res| partial_res.full_res())
1190 {
1191 if !res.matches_ns(Namespace::TypeNS)
1192 && path.is_potential_trivial_const_arg(false)
1193 {
1194 debug!(
1195 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1196 ty,
1197 );
1198
1199 let ct =
1200 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1201 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1202 }
1203 }
1204 }
1205 _ => {}
1206 }
1207 GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1208 }
1209 ast::GenericArg::Const(ct) => {
1210 GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1211 }
1212 }
1213 }
1214
1215 #[instrument(level = "debug", skip(self))]
1216 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1217 self.arena.alloc(self.lower_ty_direct(t, itctx))
1218 }
1219
1220 fn lower_path_ty(
1221 &mut self,
1222 t: &Ty,
1223 qself: &Option<Box<QSelf>>,
1224 path: &Path,
1225 param_mode: ParamMode,
1226 itctx: ImplTraitContext,
1227 ) -> hir::Ty<'hir> {
1228 if qself.is_none()
1234 && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1235 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1236 {
1237 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1238 let bound = this.lower_poly_trait_ref(
1239 &PolyTraitRef {
1240 bound_generic_params: ThinVec::new(),
1241 modifiers: TraitBoundModifiers::NONE,
1242 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1243 span: t.span,
1244 parens: ast::Parens::No,
1245 },
1246 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),
1247 itctx,
1248 );
1249 let bounds = this.arena.alloc_from_iter([bound]);
1250 let lifetime_bound = this.elided_dyn_bound(t.span);
1251 (bounds, lifetime_bound)
1252 });
1253 let kind = hir::TyKind::TraitObject(
1254 bounds,
1255 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1256 );
1257 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1258 }
1259
1260 let id = self.lower_node_id(t.id);
1261 let qpath = self.lower_qpath(
1262 t.id,
1263 qself,
1264 path,
1265 param_mode,
1266 AllowReturnTypeNotation::Yes,
1267 itctx,
1268 None,
1269 );
1270 self.ty_path(id, t.span, qpath)
1271 }
1272
1273 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1274 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1275 }
1276
1277 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1278 self.ty(span, hir::TyKind::Tup(tys))
1279 }
1280
1281 fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1282 let kind = match &t.kind {
1283 TyKind::Infer => hir::TyKind::Infer(()),
1284 TyKind::Err(guar) => hir::TyKind::Err(*guar),
1285 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1286 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1287 TyKind::Ref(region, mt) => {
1288 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1289 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1290 }
1291 TyKind::PinnedRef(region, mt) => {
1292 let lifetime = self.lower_ty_direct_lifetime(t, *region);
1293 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1294 let span = self.lower_span(t.span);
1295 let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1296 let args = self.arena.alloc(hir::GenericArgs {
1297 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1298 constraints: &[],
1299 parenthesized: hir::GenericArgsParentheses::No,
1300 span_ext: span,
1301 });
1302 let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));
1303 hir::TyKind::Path(path)
1304 }
1305 TyKind::FnPtr(f) => {
1306 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1307 hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {
1308 generic_params,
1309 safety: self.lower_safety(f.safety, hir::Safety::Safe),
1310 abi: self.lower_extern(f.ext),
1311 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1312 param_idents: self.lower_fn_params_to_idents(&f.decl),
1313 }))
1314 }
1315 TyKind::UnsafeBinder(f) => {
1316 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1317 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1318 generic_params,
1319 inner_ty: self.lower_ty(&f.inner_ty, itctx),
1320 }))
1321 }
1322 TyKind::Never => hir::TyKind::Never,
1323 TyKind::Tup(tys) => hir::TyKind::Tup(
1324 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1325 ),
1326 TyKind::Paren(ty) => {
1327 return self.lower_ty_direct(ty, itctx);
1328 }
1329 TyKind::Path(qself, path) => {
1330 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1331 }
1332 TyKind::ImplicitSelf => {
1333 let hir_id = self.next_id();
1334 let res = self.expect_full_res(t.id);
1335 let res = self.lower_res(res);
1336 hir::TyKind::Path(hir::QPath::Resolved(
1337 None,
1338 self.arena.alloc(hir::Path {
1339 res,
1340 segments: arena_vec![self; hir::PathSegment::new(
1341 Ident::with_dummy_span(kw::SelfUpper),
1342 hir_id,
1343 res
1344 )],
1345 span: self.lower_span(t.span),
1346 }),
1347 ))
1348 }
1349 TyKind::Array(ty, length) => hir::TyKind::Array(
1350 self.lower_ty(ty, itctx),
1351 self.lower_array_length_to_const_arg(length),
1352 ),
1353 TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1354 TyKind::TraitObject(bounds, kind) => {
1355 let mut lifetime_bound = None;
1356 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1357 let bounds =
1358 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1359 GenericBound::Trait(ty) => {
1363 let trait_ref = this.lower_poly_trait_ref(
1364 ty,
1365 RelaxedBoundPolicy::Forbidden(
1366 RelaxedBoundForbiddenReason::TraitObjectTy,
1367 ),
1368 itctx,
1369 );
1370 Some(trait_ref)
1371 }
1372 GenericBound::Outlives(lifetime) => {
1373 if lifetime_bound.is_none() {
1374 lifetime_bound = Some(this.lower_lifetime(
1375 lifetime,
1376 LifetimeSource::Other,
1377 lifetime.ident.into(),
1378 ));
1379 }
1380 None
1381 }
1382 GenericBound::Use(_, span) => {
1384 this.dcx()
1385 .span_delayed_bug(*span, "use<> not allowed in dyn types");
1386 None
1387 }
1388 }));
1389 let lifetime_bound =
1390 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1391 (bounds, lifetime_bound)
1392 });
1393 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1394 }
1395 TyKind::ImplTrait(def_node_id, bounds) => {
1396 let span = t.span;
1397 match itctx {
1398 ImplTraitContext::OpaqueTy { origin } => {
1399 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1400 }
1401 ImplTraitContext::Universal => {
1402 if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1403 ast::GenericBound::Use(_, span) => Some(span),
1404 _ => None,
1405 }) {
1406 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1407 }
1408
1409 let def_id = self.local_def_id(*def_node_id);
1410 let name = self.tcx.item_name(def_id.to_def_id());
1411 let ident = Ident::new(name, span);
1412 let (param, bounds, path) = self.lower_universal_param_and_bounds(
1413 *def_node_id,
1414 span,
1415 ident,
1416 bounds,
1417 );
1418 self.impl_trait_defs.push(param);
1419 if let Some(bounds) = bounds {
1420 self.impl_trait_bounds.push(bounds);
1421 }
1422 path
1423 }
1424 ImplTraitContext::InBinding => hir::TyKind::TraitAscription(
1425 self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),
1426 ),
1427 ImplTraitContext::FeatureGated(position, feature) => {
1428 let guar = self
1429 .tcx
1430 .sess
1431 .create_feature_err(
1432 MisplacedImplTrait {
1433 span: t.span,
1434 position: DiagArgFromDisplay(&position),
1435 },
1436 feature,
1437 )
1438 .emit();
1439 hir::TyKind::Err(guar)
1440 }
1441 ImplTraitContext::Disallowed(position) => {
1442 let guar = self.dcx().emit_err(MisplacedImplTrait {
1443 span: t.span,
1444 position: DiagArgFromDisplay(&position),
1445 });
1446 hir::TyKind::Err(guar)
1447 }
1448 }
1449 }
1450 TyKind::Pat(ty, pat) => {
1451 hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1452 }
1453 TyKind::MacCall(_) => {
1454 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1455 }
1456 TyKind::CVarArgs => {
1457 let guar = self.dcx().span_delayed_bug(
1458 t.span,
1459 "`TyKind::CVarArgs` should have been handled elsewhere",
1460 );
1461 hir::TyKind::Err(guar)
1462 }
1463 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1464 };
1465
1466 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1467 }
1468
1469 fn lower_ty_direct_lifetime(
1470 &mut self,
1471 t: &Ty,
1472 region: Option<Lifetime>,
1473 ) -> &'hir hir::Lifetime {
1474 let (region, syntax) = match region {
1475 Some(region) => (region, region.ident.into()),
1476
1477 None => {
1478 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1479 self.resolver.get_lifetime_res(t.id)
1480 {
1481 assert_eq!(start.plus(1), end);
1482 start
1483 } else {
1484 self.next_node_id()
1485 };
1486 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1487 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1488 (region, LifetimeSyntax::Implicit)
1489 }
1490 };
1491 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)
1492 }
1493
1494 #[instrument(level = "debug", skip(self), ret)]
1526 fn lower_opaque_impl_trait(
1527 &mut self,
1528 span: Span,
1529 origin: hir::OpaqueTyOrigin<LocalDefId>,
1530 opaque_ty_node_id: NodeId,
1531 bounds: &GenericBounds,
1532 itctx: ImplTraitContext,
1533 ) -> hir::TyKind<'hir> {
1534 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1540
1541 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1542 this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)
1543 })
1544 }
1545
1546 fn lower_opaque_inner(
1547 &mut self,
1548 opaque_ty_node_id: NodeId,
1549 origin: hir::OpaqueTyOrigin<LocalDefId>,
1550 opaque_ty_span: Span,
1551 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1552 ) -> hir::TyKind<'hir> {
1553 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1554 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1555 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1556
1557 let bounds = lower_item_bounds(self);
1558 let opaque_ty_def = hir::OpaqueTy {
1559 hir_id: opaque_ty_hir_id,
1560 def_id: opaque_ty_def_id,
1561 bounds,
1562 origin,
1563 span: self.lower_span(opaque_ty_span),
1564 };
1565 let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1566
1567 hir::TyKind::OpaqueDef(opaque_ty_def)
1568 }
1569
1570 fn lower_precise_capturing_args(
1571 &mut self,
1572 precise_capturing_args: &[PreciseCapturingArg],
1573 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1574 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1575 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1576 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1577 ),
1578 PreciseCapturingArg::Arg(path, id) => {
1579 let [segment] = path.segments.as_slice() else {
1580 panic!();
1581 };
1582 let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1583 partial_res.full_res().expect("no partial res expected for precise capture arg")
1584 });
1585 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1586 hir_id: self.lower_node_id(*id),
1587 ident: self.lower_ident(segment.ident),
1588 res: self.lower_res(res),
1589 })
1590 }
1591 }))
1592 }
1593
1594 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1595 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1596 PatKind::Missing => None,
1597 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1598 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1599 _ => {
1600 self.dcx().span_delayed_bug(
1601 param.pat.span,
1602 "non-missing/ident/wild param pat must trigger an error",
1603 );
1604 None
1605 }
1606 }))
1607 }
1608
1609 #[instrument(level = "debug", skip(self))]
1619 fn lower_fn_decl(
1620 &mut self,
1621 decl: &FnDecl,
1622 fn_node_id: NodeId,
1623 fn_span: Span,
1624 kind: FnDeclKind,
1625 coro: Option<CoroutineKind>,
1626 ) -> &'hir hir::FnDecl<'hir> {
1627 let c_variadic = decl.c_variadic();
1628
1629 let mut inputs = &decl.inputs[..];
1633 if c_variadic {
1634 inputs = &inputs[..inputs.len() - 1];
1635 }
1636 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1637 let itctx = match kind {
1638 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1639 ImplTraitContext::Universal
1640 }
1641 FnDeclKind::ExternFn => {
1642 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1643 }
1644 FnDeclKind::Closure => {
1645 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1646 }
1647 FnDeclKind::Pointer => {
1648 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1649 }
1650 };
1651 self.lower_ty_direct(¶m.ty, itctx)
1652 }));
1653
1654 let output = match coro {
1655 Some(coro) => {
1656 let fn_def_id = self.local_def_id(fn_node_id);
1657 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1658 }
1659 None => match &decl.output {
1660 FnRetTy::Ty(ty) => {
1661 let itctx = match kind {
1662 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1663 origin: hir::OpaqueTyOrigin::FnReturn {
1664 parent: self.local_def_id(fn_node_id),
1665 in_trait_or_impl: None,
1666 },
1667 },
1668 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1669 origin: hir::OpaqueTyOrigin::FnReturn {
1670 parent: self.local_def_id(fn_node_id),
1671 in_trait_or_impl: Some(hir::RpitContext::Trait),
1672 },
1673 },
1674 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1675 origin: hir::OpaqueTyOrigin::FnReturn {
1676 parent: self.local_def_id(fn_node_id),
1677 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1678 },
1679 },
1680 FnDeclKind::ExternFn => {
1681 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1682 }
1683 FnDeclKind::Closure => {
1684 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1685 }
1686 FnDeclKind::Pointer => {
1687 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1688 }
1689 };
1690 hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1691 }
1692 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1693 },
1694 };
1695
1696 self.arena.alloc(hir::FnDecl {
1697 inputs,
1698 output,
1699 c_variadic,
1700 lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1701 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1702 let is_mutable_pat = matches!(
1703 arg.pat.kind,
1704 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1705 );
1706
1707 match &arg.ty.kind {
1708 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1709 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1710 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1714 if mt.ty.kind.is_implicit_self() =>
1715 {
1716 match mt.mutbl {
1717 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1718 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1719 }
1720 }
1721 _ => hir::ImplicitSelfKind::None,
1722 }
1723 }),
1724 })
1725 }
1726
1727 #[instrument(level = "debug", skip(self))]
1736 fn lower_coroutine_fn_ret_ty(
1737 &mut self,
1738 output: &FnRetTy,
1739 fn_def_id: LocalDefId,
1740 coro: CoroutineKind,
1741 fn_kind: FnDeclKind,
1742 fn_span: Span,
1743 ) -> hir::FnRetTy<'hir> {
1744 let span = self.lower_span(fn_span);
1745
1746 let (opaque_ty_node_id, allowed_features) = match coro {
1747 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1748 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1749 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1750 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1751 }
1752 };
1753
1754 let opaque_ty_span =
1755 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1756
1757 let in_trait_or_impl = match fn_kind {
1758 FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1759 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1760 FnDeclKind::Fn | FnDeclKind::Inherent => None,
1761 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1762 };
1763
1764 let opaque_ty_ref = self.lower_opaque_inner(
1765 opaque_ty_node_id,
1766 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1767 opaque_ty_span,
1768 |this| {
1769 let bound = this.lower_coroutine_fn_output_type_to_bound(
1770 output,
1771 coro,
1772 opaque_ty_span,
1773 ImplTraitContext::OpaqueTy {
1774 origin: hir::OpaqueTyOrigin::FnReturn {
1775 parent: fn_def_id,
1776 in_trait_or_impl,
1777 },
1778 },
1779 );
1780 arena_vec![this; bound]
1781 },
1782 );
1783
1784 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1785 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1786 }
1787
1788 fn lower_coroutine_fn_output_type_to_bound(
1790 &mut self,
1791 output: &FnRetTy,
1792 coro: CoroutineKind,
1793 opaque_ty_span: Span,
1794 itctx: ImplTraitContext,
1795 ) -> hir::GenericBound<'hir> {
1796 let output_ty = match output {
1798 FnRetTy::Ty(ty) => {
1799 self.lower_ty(ty, itctx)
1803 }
1804 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1805 };
1806
1807 let (assoc_ty_name, trait_lang_item) = match coro {
1809 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1810 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1811 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1812 };
1813
1814 let bound_args = self.arena.alloc(hir::GenericArgs {
1815 args: &[],
1816 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1817 parenthesized: hir::GenericArgsParentheses::No,
1818 span_ext: DUMMY_SP,
1819 });
1820
1821 hir::GenericBound::Trait(hir::PolyTraitRef {
1822 bound_generic_params: &[],
1823 modifiers: hir::TraitBoundModifiers::NONE,
1824 trait_ref: hir::TraitRef {
1825 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1826 hir_ref_id: self.next_id(),
1827 },
1828 span: opaque_ty_span,
1829 })
1830 }
1831
1832 #[instrument(level = "trace", skip(self))]
1833 fn lower_param_bound(
1834 &mut self,
1835 tpb: &GenericBound,
1836 rbp: RelaxedBoundPolicy<'_>,
1837 itctx: ImplTraitContext,
1838 ) -> hir::GenericBound<'hir> {
1839 match tpb {
1840 GenericBound::Trait(p) => {
1841 hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))
1842 }
1843 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1844 lifetime,
1845 LifetimeSource::OutlivesBound,
1846 lifetime.ident.into(),
1847 )),
1848 GenericBound::Use(args, span) => hir::GenericBound::Use(
1849 self.lower_precise_capturing_args(args),
1850 self.lower_span(*span),
1851 ),
1852 }
1853 }
1854
1855 fn lower_lifetime(
1856 &mut self,
1857 l: &Lifetime,
1858 source: LifetimeSource,
1859 syntax: LifetimeSyntax,
1860 ) -> &'hir hir::Lifetime {
1861 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1862 }
1863
1864 fn lower_lifetime_hidden_in_path(
1865 &mut self,
1866 id: NodeId,
1867 span: Span,
1868 angle_brackets: AngleBrackets,
1869 ) -> &'hir hir::Lifetime {
1870 self.new_named_lifetime(
1871 id,
1872 id,
1873 Ident::new(kw::UnderscoreLifetime, span),
1874 LifetimeSource::Path { angle_brackets },
1875 LifetimeSyntax::Implicit,
1876 )
1877 }
1878
1879 #[instrument(level = "debug", skip(self))]
1880 fn new_named_lifetime(
1881 &mut self,
1882 id: NodeId,
1883 new_id: NodeId,
1884 ident: Ident,
1885 source: LifetimeSource,
1886 syntax: LifetimeSyntax,
1887 ) -> &'hir hir::Lifetime {
1888 let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1889 let res = match res {
1890 LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1891 LifetimeRes::Fresh { param, .. } => {
1892 assert_eq!(ident.name, kw::UnderscoreLifetime);
1893 let param = self.local_def_id(param);
1894 hir::LifetimeKind::Param(param)
1895 }
1896 LifetimeRes::Infer => {
1897 assert_eq!(ident.name, kw::UnderscoreLifetime);
1898 hir::LifetimeKind::Infer
1899 }
1900 LifetimeRes::Static { .. } => {
1901 assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1902 hir::LifetimeKind::Static
1903 }
1904 LifetimeRes::Error => hir::LifetimeKind::Error,
1905 LifetimeRes::ElidedAnchor { .. } => {
1906 panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1907 }
1908 };
1909
1910 debug!(?res);
1911 self.arena.alloc(hir::Lifetime::new(
1912 self.lower_node_id(new_id),
1913 self.lower_ident(ident),
1914 res,
1915 source,
1916 syntax,
1917 ))
1918 }
1919
1920 fn lower_generic_params_mut(
1921 &mut self,
1922 params: &[GenericParam],
1923 source: hir::GenericParamSource,
1924 ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1925 params.iter().map(move |param| self.lower_generic_param(param, source))
1926 }
1927
1928 fn lower_generic_params(
1929 &mut self,
1930 params: &[GenericParam],
1931 source: hir::GenericParamSource,
1932 ) -> &'hir [hir::GenericParam<'hir>] {
1933 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1934 }
1935
1936 #[instrument(level = "trace", skip(self))]
1937 fn lower_generic_param(
1938 &mut self,
1939 param: &GenericParam,
1940 source: hir::GenericParamSource,
1941 ) -> hir::GenericParam<'hir> {
1942 let (name, kind) = self.lower_generic_param_kind(param, source);
1943
1944 let hir_id = self.lower_node_id(param.id);
1945 self.lower_attrs(hir_id, ¶m.attrs, param.span());
1946 hir::GenericParam {
1947 hir_id,
1948 def_id: self.local_def_id(param.id),
1949 name,
1950 span: self.lower_span(param.span()),
1951 pure_wrt_drop: attr::contains_name(¶m.attrs, sym::may_dangle),
1952 kind,
1953 colon_span: param.colon_span.map(|s| self.lower_span(s)),
1954 source,
1955 }
1956 }
1957
1958 fn lower_generic_param_kind(
1959 &mut self,
1960 param: &GenericParam,
1961 source: hir::GenericParamSource,
1962 ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1963 match ¶m.kind {
1964 GenericParamKind::Lifetime => {
1965 let ident = self.lower_ident(param.ident);
1968 let param_name =
1969 if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1970 ParamName::Error(ident)
1971 } else {
1972 ParamName::Plain(ident)
1973 };
1974 let kind =
1975 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1976
1977 (param_name, kind)
1978 }
1979 GenericParamKind::Type { default, .. } => {
1980 let default = default
1983 .as_ref()
1984 .filter(|_| match source {
1985 hir::GenericParamSource::Generics => true,
1986 hir::GenericParamSource::Binder => {
1987 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1988 span: param.span(),
1989 });
1990
1991 false
1992 }
1993 })
1994 .map(|def| {
1995 self.lower_ty(
1996 def,
1997 ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1998 )
1999 });
2000
2001 let kind = hir::GenericParamKind::Type { default, synthetic: false };
2002
2003 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
2004 }
2005 GenericParamKind::Const { ty, span: _, default } => {
2006 let ty = self
2007 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
2008
2009 let default = default
2012 .as_ref()
2013 .filter(|_| match source {
2014 hir::GenericParamSource::Generics => true,
2015 hir::GenericParamSource::Binder => {
2016 self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2017 span: param.span(),
2018 });
2019
2020 false
2021 }
2022 })
2023 .map(|def| self.lower_anon_const_to_const_arg(def));
2024
2025 (
2026 hir::ParamName::Plain(self.lower_ident(param.ident)),
2027 hir::GenericParamKind::Const { ty, default, synthetic: false },
2028 )
2029 }
2030 }
2031 }
2032
2033 fn lower_trait_ref(
2034 &mut self,
2035 modifiers: ast::TraitBoundModifiers,
2036 p: &TraitRef,
2037 itctx: ImplTraitContext,
2038 ) -> hir::TraitRef<'hir> {
2039 let path = match self.lower_qpath(
2040 p.ref_id,
2041 &None,
2042 &p.path,
2043 ParamMode::Explicit,
2044 AllowReturnTypeNotation::No,
2045 itctx,
2046 Some(modifiers),
2047 ) {
2048 hir::QPath::Resolved(None, path) => path,
2049 qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2050 };
2051 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2052 }
2053
2054 #[instrument(level = "debug", skip(self))]
2055 fn lower_poly_trait_ref(
2056 &mut self,
2057 PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2058 rbp: RelaxedBoundPolicy<'_>,
2059 itctx: ImplTraitContext,
2060 ) -> hir::PolyTraitRef<'hir> {
2061 let bound_generic_params =
2062 self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
2063 let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
2064 let modifiers = self.lower_trait_bound_modifiers(*modifiers);
2065
2066 if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2067 self.validate_relaxed_bound(trait_ref, *span, rbp);
2068 }
2069
2070 hir::PolyTraitRef {
2071 bound_generic_params,
2072 modifiers,
2073 trait_ref,
2074 span: self.lower_span(*span),
2075 }
2076 }
2077
2078 fn validate_relaxed_bound(
2079 &self,
2080 trait_ref: hir::TraitRef<'_>,
2081 span: Span,
2082 rbp: RelaxedBoundPolicy<'_>,
2083 ) {
2084 match rbp {
2092 RelaxedBoundPolicy::Allowed => return,
2093 RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2094 if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
2095 && let Res::Def(DefKind::TyParam, def_id) = res
2096 && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2097 {
2098 return;
2099 }
2100 if self.tcx.features().more_maybe_bounds() {
2101 return;
2102 }
2103 }
2104 RelaxedBoundPolicy::Forbidden(reason) => {
2105 if self.tcx.features().more_maybe_bounds() {
2106 return;
2107 }
2108
2109 match reason {
2110 RelaxedBoundForbiddenReason::TraitObjectTy => {
2111 self.dcx().span_err(
2112 span,
2113 "relaxed bounds are not permitted in trait object types",
2114 );
2115 return;
2116 }
2117 RelaxedBoundForbiddenReason::SuperTrait => {
2118 let mut diag = self.dcx().struct_span_err(
2119 span,
2120 "relaxed bounds are not permitted in supertrait bounds",
2121 );
2122 if let Some(def_id) = trait_ref.trait_def_id()
2123 && self.tcx.is_lang_item(def_id, hir::LangItem::Sized)
2124 {
2125 diag.note("traits are `?Sized` by default");
2126 }
2127 diag.emit();
2128 return;
2129 }
2130 RelaxedBoundForbiddenReason::AssocTyBounds
2131 | RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2132 };
2133 }
2134 }
2135
2136 self.dcx()
2137 .struct_span_err(span, "this relaxed bound is not permitted here")
2138 .with_note(
2139 "in this context, relaxed bounds are only allowed on \
2140 type parameters defined by the closest item",
2141 )
2142 .emit();
2143 }
2144
2145 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2146 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2147 }
2148
2149 #[instrument(level = "debug", skip(self), ret)]
2150 fn lower_param_bounds(
2151 &mut self,
2152 bounds: &[GenericBound],
2153 rbp: RelaxedBoundPolicy<'_>,
2154 itctx: ImplTraitContext,
2155 ) -> hir::GenericBounds<'hir> {
2156 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
2157 }
2158
2159 fn lower_param_bounds_mut(
2160 &mut self,
2161 bounds: &[GenericBound],
2162 rbp: RelaxedBoundPolicy<'_>,
2163 itctx: ImplTraitContext,
2164 ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2165 bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
2166 }
2167
2168 #[instrument(level = "debug", skip(self), ret)]
2169 fn lower_universal_param_and_bounds(
2170 &mut self,
2171 node_id: NodeId,
2172 span: Span,
2173 ident: Ident,
2174 bounds: &[GenericBound],
2175 ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2176 let def_id = self.local_def_id(node_id);
2178 let span = self.lower_span(span);
2179
2180 let param = hir::GenericParam {
2182 hir_id: self.lower_node_id(node_id),
2183 def_id,
2184 name: ParamName::Plain(self.lower_ident(ident)),
2185 pure_wrt_drop: false,
2186 span,
2187 kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2188 colon_span: None,
2189 source: hir::GenericParamSource::Generics,
2190 };
2191
2192 let preds = self.lower_generic_bound_predicate(
2193 ident,
2194 node_id,
2195 &GenericParamKind::Type { default: None },
2196 bounds,
2197 None,
2198 span,
2199 RelaxedBoundPolicy::Allowed,
2200 ImplTraitContext::Universal,
2201 hir::PredicateOrigin::ImplTrait,
2202 );
2203
2204 let hir_id = self.next_id();
2205 let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2206 let ty = hir::TyKind::Path(hir::QPath::Resolved(
2207 None,
2208 self.arena.alloc(hir::Path {
2209 span,
2210 res,
2211 segments:
2212 arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2213 }),
2214 ));
2215
2216 (param, preds, ty)
2217 }
2218
2219 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2222 let block = self.lower_block(b, false);
2223 self.expr_block(block)
2224 }
2225
2226 fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2227 match c.value.peel_parens().kind {
2230 ExprKind::Underscore => {
2231 let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2232 self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2233 }
2234 _ => self.lower_anon_const_to_const_arg(c),
2235 }
2236 }
2237
2238 #[instrument(level = "debug", skip(self))]
2242 fn lower_const_path_to_const_arg(
2243 &mut self,
2244 path: &Path,
2245 res: Res<NodeId>,
2246 ty_id: NodeId,
2247 span: Span,
2248 ) -> &'hir hir::ConstArg<'hir> {
2249 let tcx = self.tcx;
2250
2251 let ct_kind = if path
2252 .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2253 && (tcx.features().min_generic_const_args()
2254 || matches!(res, Res::Def(DefKind::ConstParam, _)))
2255 {
2256 let qpath = self.lower_qpath(
2257 ty_id,
2258 &None,
2259 path,
2260 ParamMode::Explicit,
2261 AllowReturnTypeNotation::No,
2262 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2264 None,
2265 );
2266 hir::ConstArgKind::Path(qpath)
2267 } else {
2268 let node_id = self.next_node_id();
2270 let span = self.lower_span(span);
2271
2272 let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2277 let hir_id = self.lower_node_id(node_id);
2278
2279 let path_expr = Expr {
2280 id: ty_id,
2281 kind: ExprKind::Path(None, path.clone()),
2282 span,
2283 attrs: AttrVec::new(),
2284 tokens: None,
2285 };
2286
2287 let ct = self.with_new_scopes(span, |this| {
2288 self.arena.alloc(hir::AnonConst {
2289 def_id,
2290 hir_id,
2291 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2292 span,
2293 })
2294 });
2295 hir::ConstArgKind::Anon(ct)
2296 };
2297
2298 self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2299 }
2300
2301 fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2304 self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2305 }
2306
2307 #[instrument(level = "debug", skip(self))]
2308 fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2309 let tcx = self.tcx;
2310 let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2313 && let [stmt] = block.stmts.as_slice()
2314 && let StmtKind::Expr(expr) = &stmt.kind
2315 && let ExprKind::Path(..) = &expr.kind
2316 {
2317 expr
2318 } else {
2319 &anon.value
2320 };
2321 let maybe_res =
2322 self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2323 if let ExprKind::Path(qself, path) = &expr.kind
2324 && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2325 && (tcx.features().min_generic_const_args()
2326 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2327 {
2328 let qpath = self.lower_qpath(
2329 expr.id,
2330 qself,
2331 path,
2332 ParamMode::Explicit,
2333 AllowReturnTypeNotation::No,
2334 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2336 None,
2337 );
2338
2339 return ConstArg {
2340 hir_id: self.lower_node_id(anon.id),
2341 kind: hir::ConstArgKind::Path(qpath),
2342 };
2343 }
2344
2345 let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2346 ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2347 }
2348
2349 fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2352 self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2353 let def_id = this.local_def_id(c.id);
2354 let hir_id = this.lower_node_id(c.id);
2355 hir::AnonConst {
2356 def_id,
2357 hir_id,
2358 body: this.lower_const_body(c.value.span, Some(&c.value)),
2359 span: this.lower_span(c.value.span),
2360 }
2361 }))
2362 }
2363
2364 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2365 match u {
2366 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2367 UserProvided => hir::UnsafeSource::UserProvided,
2368 }
2369 }
2370
2371 fn lower_trait_bound_modifiers(
2372 &mut self,
2373 modifiers: TraitBoundModifiers,
2374 ) -> hir::TraitBoundModifiers {
2375 let constness = match modifiers.constness {
2376 BoundConstness::Never => BoundConstness::Never,
2377 BoundConstness::Always(span) => BoundConstness::Always(self.lower_span(span)),
2378 BoundConstness::Maybe(span) => BoundConstness::Maybe(self.lower_span(span)),
2379 };
2380 let polarity = match modifiers.polarity {
2381 BoundPolarity::Positive => BoundPolarity::Positive,
2382 BoundPolarity::Negative(span) => BoundPolarity::Negative(self.lower_span(span)),
2383 BoundPolarity::Maybe(span) => BoundPolarity::Maybe(self.lower_span(span)),
2384 };
2385 hir::TraitBoundModifiers { constness, polarity }
2386 }
2387
2388 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2391 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2392 }
2393
2394 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2395 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2396 }
2397
2398 fn stmt_let_pat(
2399 &mut self,
2400 attrs: Option<&'hir [hir::Attribute]>,
2401 span: Span,
2402 init: Option<&'hir hir::Expr<'hir>>,
2403 pat: &'hir hir::Pat<'hir>,
2404 source: hir::LocalSource,
2405 ) -> hir::Stmt<'hir> {
2406 let hir_id = self.next_id();
2407 if let Some(a) = attrs {
2408 assert!(!a.is_empty());
2409 self.attrs.insert(hir_id.local_id, a);
2410 }
2411 let local = hir::LetStmt {
2412 super_: None,
2413 hir_id,
2414 init,
2415 pat,
2416 els: None,
2417 source,
2418 span: self.lower_span(span),
2419 ty: None,
2420 };
2421 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2422 }
2423
2424 fn stmt_super_let_pat(
2425 &mut self,
2426 span: Span,
2427 pat: &'hir hir::Pat<'hir>,
2428 init: Option<&'hir hir::Expr<'hir>>,
2429 ) -> hir::Stmt<'hir> {
2430 let hir_id = self.next_id();
2431 let span = self.lower_span(span);
2432 let local = hir::LetStmt {
2433 super_: Some(span),
2434 hir_id,
2435 init,
2436 pat,
2437 els: None,
2438 source: hir::LocalSource::Normal,
2439 span,
2440 ty: None,
2441 };
2442 self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2443 }
2444
2445 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2446 self.block_all(expr.span, &[], Some(expr))
2447 }
2448
2449 fn block_all(
2450 &mut self,
2451 span: Span,
2452 stmts: &'hir [hir::Stmt<'hir>],
2453 expr: Option<&'hir hir::Expr<'hir>>,
2454 ) -> &'hir hir::Block<'hir> {
2455 let blk = hir::Block {
2456 stmts,
2457 expr,
2458 hir_id: self.next_id(),
2459 rules: hir::BlockCheckMode::DefaultBlock,
2460 span: self.lower_span(span),
2461 targeted_by_break: false,
2462 };
2463 self.arena.alloc(blk)
2464 }
2465
2466 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2467 let field = self.single_pat_field(span, pat);
2468 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2469 }
2470
2471 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2472 let field = self.single_pat_field(span, pat);
2473 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2474 }
2475
2476 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2477 let field = self.single_pat_field(span, pat);
2478 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2479 }
2480
2481 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2482 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2483 }
2484
2485 fn single_pat_field(
2486 &mut self,
2487 span: Span,
2488 pat: &'hir hir::Pat<'hir>,
2489 ) -> &'hir [hir::PatField<'hir>] {
2490 let field = hir::PatField {
2491 hir_id: self.next_id(),
2492 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2493 is_shorthand: false,
2494 pat,
2495 span: self.lower_span(span),
2496 };
2497 arena_vec![self; field]
2498 }
2499
2500 fn pat_lang_item_variant(
2501 &mut self,
2502 span: Span,
2503 lang_item: hir::LangItem,
2504 fields: &'hir [hir::PatField<'hir>],
2505 ) -> &'hir hir::Pat<'hir> {
2506 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2507 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2508 }
2509
2510 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2511 self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2512 }
2513
2514 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2515 self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2516 }
2517
2518 fn pat_ident_binding_mode(
2519 &mut self,
2520 span: Span,
2521 ident: Ident,
2522 bm: hir::BindingMode,
2523 ) -> (&'hir hir::Pat<'hir>, HirId) {
2524 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2525 (self.arena.alloc(pat), hir_id)
2526 }
2527
2528 fn pat_ident_binding_mode_mut(
2529 &mut self,
2530 span: Span,
2531 ident: Ident,
2532 bm: hir::BindingMode,
2533 ) -> (hir::Pat<'hir>, HirId) {
2534 let hir_id = self.next_id();
2535
2536 (
2537 hir::Pat {
2538 hir_id,
2539 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2540 span: self.lower_span(span),
2541 default_binding_modes: true,
2542 },
2543 hir_id,
2544 )
2545 }
2546
2547 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2548 self.arena.alloc(hir::Pat {
2549 hir_id: self.next_id(),
2550 kind,
2551 span: self.lower_span(span),
2552 default_binding_modes: true,
2553 })
2554 }
2555
2556 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2557 hir::Pat {
2558 hir_id: self.next_id(),
2559 kind,
2560 span: self.lower_span(span),
2561 default_binding_modes: false,
2562 }
2563 }
2564
2565 fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2566 let kind = match qpath {
2567 hir::QPath::Resolved(None, path) => {
2568 match path.res {
2570 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2571 let principal = hir::PolyTraitRef {
2572 bound_generic_params: &[],
2573 modifiers: hir::TraitBoundModifiers::NONE,
2574 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2575 span: self.lower_span(span),
2576 };
2577
2578 hir_id = self.next_id();
2581 hir::TyKind::TraitObject(
2582 arena_vec![self; principal],
2583 TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2584 )
2585 }
2586 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2587 }
2588 }
2589 _ => hir::TyKind::Path(qpath),
2590 };
2591
2592 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2593 }
2594
2595 fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2600 let r = hir::Lifetime::new(
2601 self.next_id(),
2602 Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2603 hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2604 LifetimeSource::Other,
2605 LifetimeSyntax::Implicit,
2606 );
2607 debug!("elided_dyn_bound: r={:?}", r);
2608 self.arena.alloc(r)
2609 }
2610}
2611
2612struct GenericArgsCtor<'hir> {
2614 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2615 constraints: &'hir [hir::AssocItemConstraint<'hir>],
2616 parenthesized: hir::GenericArgsParentheses,
2617 span: Span,
2618}
2619
2620impl<'hir> GenericArgsCtor<'hir> {
2621 fn is_empty(&self) -> bool {
2622 self.args.is_empty()
2623 && self.constraints.is_empty()
2624 && self.parenthesized == hir::GenericArgsParentheses::No
2625 }
2626
2627 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2628 let ga = hir::GenericArgs {
2629 args: this.arena.alloc_from_iter(self.args),
2630 constraints: self.constraints,
2631 parenthesized: self.parenthesized,
2632 span_ext: this.lower_span(self.span),
2633 };
2634 this.arena.alloc(ga)
2635 }
2636}