]>
Commit | Line | Data |
---|---|---|
3dfed10e XL |
1 | //! Bounds are restrictions applied to some types after they've been converted into the |
2 | //! `ty` form from the HIR. | |
3 | ||
9c376795 | 4 | use rustc_hir::LangItem; |
a2a8927a | 5 | use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; |
3dfed10e XL |
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 | |
9c376795 | 19 | /// ^^^^^^^^^ bounding the type-erased dynamic type |
3dfed10e XL |
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> { | |
fe692bf9 | 26 | pub clauses: Vec<(ty::Clause<'tcx>, Span)>, |
3dfed10e XL |
27 | } |
28 | ||
29 | impl<'tcx> Bounds<'tcx> { | |
9c376795 FG |
30 | pub fn push_region_bound( |
31 | &mut self, | |
3dfed10e | 32 | tcx: TyCtxt<'tcx>, |
9c376795 FG |
33 | region: ty::PolyTypeOutlivesPredicate<'tcx>, |
34 | span: Span, | |
35 | ) { | |
fe692bf9 FG |
36 | self.clauses |
37 | .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx), span)); | |
9c376795 | 38 | } |
3dfed10e | 39 | |
9c376795 FG |
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, | |
49aad941 | 46 | polarity: ty::ImplPolarity, |
9c376795 | 47 | ) { |
fe692bf9 | 48 | self.clauses.push(( |
49aad941 | 49 | trait_ref |
fe692bf9 FG |
50 | .map_bound(|trait_ref| { |
51 | ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity }) | |
52 | }) | |
49aad941 FG |
53 | .to_predicate(tcx), |
54 | span, | |
55 | )); | |
9c376795 FG |
56 | } |
57 | ||
58 | pub fn push_projection_bound( | |
59 | &mut self, | |
60 | tcx: TyCtxt<'tcx>, | |
61 | projection: ty::PolyProjectionPredicate<'tcx>, | |
62 | span: Span, | |
63 | ) { | |
fe692bf9 FG |
64 | self.clauses.push(( |
65 | projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx), | |
66 | span, | |
67 | )); | |
9c376795 FG |
68 | } |
69 | ||
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)); | |
49aad941 | 72 | let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); |
353b0b11 | 73 | // Preferable to put this obligation first, since we report better errors for sized ambiguity. |
fe692bf9 | 74 | self.clauses.insert(0, (trait_ref.to_predicate(tcx), span)); |
9c376795 | 75 | } |
5099ac24 | 76 | |
fe692bf9 FG |
77 | pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ { |
78 | self.clauses.iter().cloned() | |
3dfed10e XL |
79 | } |
80 | } |