rustc_hir_analysis/
bounds.rs
1use rustc_hir::LangItem;
5use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
6use rustc_span::Span;
7
8#[derive(Default, PartialEq, Eq, Clone, Debug)]
25pub(crate) struct Bounds<'tcx> {
26 clauses: Vec<(ty::Clause<'tcx>, Span)>,
27}
28
29impl<'tcx> Bounds<'tcx> {
30 pub(crate) fn push_region_bound(
31 &mut self,
32 tcx: TyCtxt<'tcx>,
33 region: ty::PolyTypeOutlivesPredicate<'tcx>,
34 span: Span,
35 ) {
36 self.clauses
37 .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span));
38 }
39
40 pub(crate) fn push_trait_bound(
41 &mut self,
42 tcx: TyCtxt<'tcx>,
43 bound_trait_ref: ty::PolyTraitRef<'tcx>,
44 span: Span,
45 polarity: ty::PredicatePolarity,
46 ) {
47 let clause = (
48 bound_trait_ref
49 .map_bound(|trait_ref| {
50 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
51 })
52 .upcast(tcx),
53 span,
54 );
55 if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) {
57 self.clauses.insert(0, clause);
58 } else {
59 self.clauses.push(clause);
60 }
61 }
62
63 pub(crate) fn push_projection_bound(
64 &mut self,
65 tcx: TyCtxt<'tcx>,
66 projection: ty::PolyProjectionPredicate<'tcx>,
67 span: Span,
68 ) {
69 self.clauses.push((
70 projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).upcast(tcx),
71 span,
72 ));
73 }
74
75 pub(crate) fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
76 let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
77 let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
78 self.clauses.insert(0, (trait_ref.upcast(tcx), span));
80 }
81
82 pub(crate) fn push_const_bound(
84 &mut self,
85 tcx: TyCtxt<'tcx>,
86 bound_trait_ref: ty::PolyTraitRef<'tcx>,
87 constness: ty::BoundConstness,
88 span: Span,
89 ) {
90 if tcx.is_const_trait(bound_trait_ref.def_id()) {
91 self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, constness), span));
92 } else {
93 tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait");
94 }
95 }
96
97 pub(crate) fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
98 self.clauses.iter().cloned()
99 }
100}