1 //! Bounds are restrictions applied to some types after they've been converted into the
2 //! `ty` form from the HIR.
4 use rustc_hir::LangItem;
5 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
8 /// Collects together a list of type bounds. These lists of bounds occur in many places
12 /// trait Foo: Bar + Baz { }
13 /// ^^^^^^^^^ supertrait list bounding the `Self` type parameter
15 /// fn foo<T: Bar + Baz>() { }
16 /// ^^^^^^^^^ bounding the type parameter `T`
18 /// impl dyn Bar + Baz
19 /// ^^^^^^^^^ bounding the type-erased dynamic type
22 /// Our representation is a bit mixed here -- in some cases, we
23 /// include the self type (e.g., `trait_bounds`) but in others we do not
24 #[derive(Default, PartialEq, Eq, Clone, Debug)]
25 pub struct Bounds<'tcx> {
26 pub predicates: Vec<(ty::Predicate<'tcx>, Span)>,
29 impl<'tcx> Bounds<'tcx> {
30 pub fn push_region_bound(
33 region: ty::PolyTypeOutlivesPredicate<'tcx>,
36 self.predicates.push((region.to_predicate(tcx), span));
39 pub fn push_trait_bound(
42 trait_ref: ty::PolyTraitRef<'tcx>,
44 constness: ty::BoundConstness,
46 self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span));
49 pub fn push_projection_bound(
52 projection: ty::PolyProjectionPredicate<'tcx>,
55 self.predicates.push((projection.to_predicate(tcx), span));
58 pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
59 let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
60 let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty]));
61 // Preferrable to put this obligation first, since we report better errors for sized ambiguity.
62 self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span));
65 pub fn predicates(&self) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + '_ {
66 self.predicates.iter().cloned()