]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_hir_analysis/src/bounds.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / compiler / rustc_hir_analysis / src / bounds.rs
CommitLineData
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 4use rustc_hir::LangItem;
a2a8927a 5use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
3dfed10e
XL
6use 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)]
25pub struct Bounds<'tcx> {
fe692bf9 26 pub clauses: Vec<(ty::Clause<'tcx>, Span)>,
3dfed10e
XL
27}
28
29impl<'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}