]>
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> { | |
9c376795 | 26 | pub predicates: Vec<(ty::Predicate<'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 | ) { | |
36 | self.predicates.push((region.to_predicate(tcx), span)); | |
37 | } | |
3dfed10e | 38 | |
9c376795 FG |
39 | pub fn push_trait_bound( |
40 | &mut self, | |
41 | tcx: TyCtxt<'tcx>, | |
42 | trait_ref: ty::PolyTraitRef<'tcx>, | |
43 | span: Span, | |
44 | constness: ty::BoundConstness, | |
45 | ) { | |
46 | self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span)); | |
47 | } | |
48 | ||
49 | pub fn push_projection_bound( | |
50 | &mut self, | |
51 | tcx: TyCtxt<'tcx>, | |
52 | projection: ty::PolyProjectionPredicate<'tcx>, | |
53 | span: Span, | |
54 | ) { | |
55 | self.predicates.push((projection.to_predicate(tcx), span)); | |
56 | } | |
57 | ||
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])); | |
353b0b11 | 61 | // Preferable to put this obligation first, since we report better errors for sized ambiguity. |
9c376795 FG |
62 | self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); |
63 | } | |
5099ac24 | 64 | |
9c376795 FG |
65 | pub fn predicates(&self) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + '_ { |
66 | self.predicates.iter().cloned() | |
3dfed10e XL |
67 | } |
68 | } |