]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir_analysis/src/bounds.rs
Rollup merge of #107519 - joboet:raw_os_error_ty, r=Amanieu
[rust.git] / compiler / rustc_hir_analysis / src / bounds.rs
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 predicates: Vec<(ty::Predicate<'tcx>, Span)>,
27 }
28
29 impl<'tcx> Bounds<'tcx> {
30     pub fn push_region_bound(
31         &mut self,
32         tcx: TyCtxt<'tcx>,
33         region: ty::PolyTypeOutlivesPredicate<'tcx>,
34         span: Span,
35     ) {
36         self.predicates.push((region.to_predicate(tcx), span));
37     }
38
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]));
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));
63     }
64
65     pub fn predicates(&self) -> impl Iterator<Item = (ty::Predicate<'tcx>, Span)> + '_ {
66         self.predicates.iter().cloned()
67     }
68 }