//! Bounds are restrictions applied to some types after they've been converted into the //! `ty` form from the HIR. use rustc_hir::LangItem; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; /// Collects together a list of type bounds. These lists of bounds occur in many places /// in Rust's syntax: /// /// ```text /// trait Foo: Bar + Baz { } /// ^^^^^^^^^ supertrait list bounding the `Self` type parameter /// /// fn foo() { } /// ^^^^^^^^^ bounding the type parameter `T` /// /// impl dyn Bar + Baz /// ^^^^^^^^^ bounding the type-erased dynamic type /// ``` /// /// Our representation is a bit mixed here -- in some cases, we /// include the self type (e.g., `trait_bounds`) but in others we do not #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { pub clauses: Vec<(ty::Clause<'tcx>, Span)>, } impl<'tcx> Bounds<'tcx> { pub fn push_region_bound( &mut self, tcx: TyCtxt<'tcx>, region: ty::PolyTypeOutlivesPredicate<'tcx>, span: Span, ) { self.clauses .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx), span)); } pub fn push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, constness: ty::BoundConstness, polarity: ty::ImplPolarity, ) { self.clauses.push(( trait_ref .map_bound(|trait_ref| { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity }) }) .to_predicate(tcx), span, )); } pub fn push_projection_bound( &mut self, tcx: TyCtxt<'tcx>, projection: ty::PolyProjectionPredicate<'tcx>, span: Span, ) { self.clauses.push(( projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx), span, )); } pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); // Preferable to put this obligation first, since we report better errors for sized ambiguity. self.clauses.insert(0, (trait_ref.to_predicate(tcx), span)); } pub fn clauses(&self) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() } }