• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Bounds are restrictions applied to some types after they've been converted into the
2 //! `ty` form from the HIR.
3 
4 use rustc_hir::LangItem;
5 use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
6 use rustc_span::Span;
7 
8 /// Collects together a list of type bounds. These lists of bounds occur in many places
9 /// in Rust's syntax:
10 ///
11 /// ```text
12 /// trait Foo: Bar + Baz { }
13 ///            ^^^^^^^^^ supertrait list bounding the `Self` type parameter
14 ///
15 /// fn foo<T: Bar + Baz>() { }
16 ///           ^^^^^^^^^ bounding the type parameter `T`
17 ///
18 /// impl dyn Bar + Baz
19 ///          ^^^^^^^^^ bounding the type-erased dynamic type
20 /// ```
21 ///
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 clauses: Vec<(ty::Clause<'tcx>, Span)>,
27 }
28 
29 impl<'tcx> Bounds<'tcx> {
push_region_bound( &mut self, tcx: TyCtxt<'tcx>, region: ty::PolyTypeOutlivesPredicate<'tcx>, span: Span, )30     pub 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)).to_predicate(tcx), span));
38     }
39 
push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, span: Span, constness: ty::BoundConstness, polarity: ty::ImplPolarity, )40     pub fn push_trait_bound(
41         &mut self,
42         tcx: TyCtxt<'tcx>,
43         trait_ref: ty::PolyTraitRef<'tcx>,
44         span: Span,
45         constness: ty::BoundConstness,
46         polarity: ty::ImplPolarity,
47     ) {
48         self.clauses.push((
49             trait_ref
50                 .map_bound(|trait_ref| {
51                     ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
52                 })
53                 .to_predicate(tcx),
54             span,
55         ));
56     }
57 
push_projection_bound( &mut self, tcx: TyCtxt<'tcx>, projection: ty::PolyProjectionPredicate<'tcx>, span: Span, )58     pub fn push_projection_bound(
59         &mut self,
60         tcx: TyCtxt<'tcx>,
61         projection: ty::PolyProjectionPredicate<'tcx>,
62         span: Span,
63     ) {
64         self.clauses.push((
65             projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx),
66             span,
67         ));
68     }
69 
push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span)70     pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
71         let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
72         let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
73         // Preferable to put this obligation first, since we report better errors for sized ambiguity.
74         self.clauses.insert(0, (trait_ref.to_predicate(tcx), span));
75     }
76 
clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_77     pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
78         self.clauses.iter().cloned()
79     }
80 }
81