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