2024-02-11 08:22:52 +00:00
|
|
|
//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the
|
|
|
|
//! [`rustc_middle::ty`] form.
|
2020-08-19 17:07:03 +00:00
|
|
|
|
2022-12-26 04:19:27 +00:00
|
|
|
use rustc_hir::LangItem;
|
2024-05-15 14:05:25 +00:00
|
|
|
use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
|
2020-08-19 17:07:03 +00:00
|
|
|
use rustc_span::Span;
|
|
|
|
|
|
|
|
/// Collects together a list of type bounds. These lists of bounds occur in many places
|
|
|
|
/// in Rust's syntax:
|
|
|
|
///
|
|
|
|
/// ```text
|
|
|
|
/// trait Foo: Bar + Baz { }
|
|
|
|
/// ^^^^^^^^^ supertrait list bounding the `Self` type parameter
|
|
|
|
///
|
|
|
|
/// fn foo<T: Bar + Baz>() { }
|
|
|
|
/// ^^^^^^^^^ bounding the type parameter `T`
|
|
|
|
///
|
|
|
|
/// impl dyn Bar + Baz
|
2022-12-26 04:19:27 +00:00
|
|
|
/// ^^^^^^^^^ bounding the type-erased dynamic type
|
2020-08-19 17:07:03 +00:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Our representation is a bit mixed here -- in some cases, we
|
|
|
|
/// include the self type (e.g., `trait_bounds`) but in others we do not
|
|
|
|
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
|
|
|
pub struct Bounds<'tcx> {
|
2024-05-04 02:20:39 +00:00
|
|
|
clauses: Vec<(ty::Clause<'tcx>, Span)>,
|
2020-08-19 17:07:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> Bounds<'tcx> {
|
2022-12-26 04:19:27 +00:00
|
|
|
pub fn push_region_bound(
|
|
|
|
&mut self,
|
2023-06-16 06:27:41 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-12-26 04:19:27 +00:00
|
|
|
region: ty::PolyTypeOutlivesPredicate<'tcx>,
|
|
|
|
span: Span,
|
|
|
|
) {
|
2023-06-16 06:27:41 +00:00
|
|
|
self.clauses
|
2024-05-15 14:05:25 +00:00
|
|
|
.push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span));
|
2022-12-26 04:19:27 +00:00
|
|
|
}
|
2020-08-19 17:07:03 +00:00
|
|
|
|
2022-12-26 04:19:27 +00:00
|
|
|
pub fn push_trait_bound(
|
|
|
|
&mut self,
|
2023-06-16 06:27:41 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-12-26 04:19:27 +00:00
|
|
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
|
|
|
span: Span,
|
2024-03-21 19:45:28 +00:00
|
|
|
polarity: ty::PredicatePolarity,
|
2022-12-26 04:19:27 +00:00
|
|
|
) {
|
2024-03-31 21:20:00 +00:00
|
|
|
let clause = (
|
2023-06-16 06:27:41 +00:00
|
|
|
trait_ref
|
|
|
|
.map_bound(|trait_ref| {
|
2023-07-29 08:20:25 +00:00
|
|
|
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
|
2023-06-16 06:27:41 +00:00
|
|
|
})
|
2024-05-15 14:05:25 +00:00
|
|
|
.upcast(tcx),
|
2023-04-25 05:15:50 +00:00
|
|
|
span,
|
2024-03-31 21:20:00 +00:00
|
|
|
);
|
|
|
|
// FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands.
|
2024-06-14 18:46:32 +00:00
|
|
|
if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
|
2024-03-31 21:20:00 +00:00
|
|
|
self.clauses.insert(0, clause);
|
|
|
|
} else {
|
|
|
|
self.clauses.push(clause);
|
|
|
|
}
|
2022-12-26 04:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn push_projection_bound(
|
|
|
|
&mut self,
|
2023-06-16 06:27:41 +00:00
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-12-26 04:19:27 +00:00
|
|
|
projection: ty::PolyProjectionPredicate<'tcx>,
|
|
|
|
span: Span,
|
|
|
|
) {
|
2023-06-16 06:27:41 +00:00
|
|
|
self.clauses.push((
|
2024-05-15 14:05:25 +00:00
|
|
|
projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).upcast(tcx),
|
2023-06-16 06:27:41 +00:00
|
|
|
span,
|
|
|
|
));
|
2022-12-26 04:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
|
|
|
|
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
|
2023-04-26 11:48:17 +00:00
|
|
|
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
|
2023-04-10 20:02:52 +00:00
|
|
|
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
|
2024-05-15 14:05:25 +00:00
|
|
|
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
|
2022-12-26 04:19:27 +00:00
|
|
|
}
|
2021-07-30 08:56:45 +00:00
|
|
|
|
2023-06-16 06:27:41 +00:00
|
|
|
pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
|
|
|
|
self.clauses.iter().cloned()
|
2020-08-19 17:07:03 +00:00
|
|
|
}
|
|
|
|
}
|