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