]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_infer/src/traits/mod.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / compiler / rustc_infer / src / traits / mod.rs
CommitLineData
ba9703b0 1//! Trait Resolution. See the [rustc-dev-guide] for more information on how this works.
74b04a01 2//!
ba9703b0 3//! [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
74b04a01 4
74b04a01
XL
5mod engine;
6pub mod error_reporting;
74b04a01 7mod project;
74b04a01 8mod structural_impls;
ba9703b0 9pub mod util;
74b04a01 10
74b04a01 11use rustc_hir as hir;
ba9703b0 12use rustc_middle::ty::error::{ExpectedFound, TypeError};
f9f354fc 13use rustc_middle::ty::{self, Const, Ty};
ba9703b0 14use rustc_span::Span;
74b04a01
XL
15
16pub use self::FulfillmentErrorCode::*;
f035d41b 17pub use self::ImplSource::*;
74b04a01
XL
18pub use self::ObligationCauseCode::*;
19pub use self::SelectionError::*;
74b04a01 20
74b04a01 21pub use self::engine::{TraitEngine, TraitEngineExt};
74b04a01 22pub use self::project::MismatchedProjectionTypes;
f9f354fc 23pub(crate) use self::project::UndoLog;
74b04a01 24pub use self::project::{
ba9703b0 25 Normalized, NormalizedTy, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey,
f9f354fc 26 ProjectionCacheStorage, Reveal,
74b04a01 27};
ba9703b0 28pub use rustc_middle::traits::*;
74b04a01 29
f035d41b
XL
30/// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for
31/// which the "impl_source" must be found. The process of finding a "impl_source" is
74b04a01 32/// called "resolving" the `Obligation`. This process consists of
f035d41b
XL
33/// either identifying an `impl` (e.g., `impl Eq for i32`) that
34/// satisfies the obligation, or else finding a bound that is in
74b04a01
XL
35/// scope. The eventual result is usually a `Selection` (defined below).
36#[derive(Clone, PartialEq, Eq, Hash)]
37pub struct Obligation<'tcx, T> {
38 /// The reason we have to prove this thing.
39 pub cause: ObligationCause<'tcx>,
40
41 /// The environment in which we should prove this thing.
42 pub param_env: ty::ParamEnv<'tcx>,
43
44 /// The thing we are trying to prove.
45 pub predicate: T,
46
47 /// If we started proving this as a result of trying to prove
48 /// something else, track the total depth to ensure termination.
49 /// If this goes over a certain threshold, we abort compilation --
50 /// in such cases, we can not say whether or not the predicate
51 /// holds for certain. Stupid halting problem; such a drag.
52 pub recursion_depth: usize,
53}
54
55pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
56pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
57
58// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
6a06907d 59#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1b1a35ee 60static_assert_size!(PredicateObligation<'_>, 32);
74b04a01 61
74b04a01 62pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
74b04a01 63
f035d41b 64pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
74b04a01
XL
65
66pub struct FulfillmentError<'tcx> {
67 pub obligation: PredicateObligation<'tcx>,
68 pub code: FulfillmentErrorCode<'tcx>,
69 /// Diagnostics only: we opportunistically change the `code.span` when we encounter an
70 /// obligation error caused by a call argument. When this is the case, we also signal that in
71 /// this field to ensure accuracy of suggestions.
72 pub points_at_arg_span: bool,
73}
74
75#[derive(Clone)]
76pub enum FulfillmentErrorCode<'tcx> {
77 CodeSelectionError(SelectionError<'tcx>),
78 CodeProjectionError(MismatchedProjectionTypes<'tcx>),
79 CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
f9f354fc 80 CodeConstEquateError(ExpectedFound<&'tcx Const<'tcx>>, TypeError<'tcx>),
74b04a01
XL
81 CodeAmbiguity,
82}
83
74b04a01
XL
84impl<'tcx, O> Obligation<'tcx, O> {
85 pub fn new(
86 cause: ObligationCause<'tcx>,
87 param_env: ty::ParamEnv<'tcx>,
88 predicate: O,
89 ) -> Obligation<'tcx, O> {
90 Obligation { cause, param_env, recursion_depth: 0, predicate }
91 }
92
ba9703b0 93 pub fn with_depth(
74b04a01
XL
94 cause: ObligationCause<'tcx>,
95 recursion_depth: usize,
96 param_env: ty::ParamEnv<'tcx>,
97 predicate: O,
98 ) -> Obligation<'tcx, O> {
99 Obligation { cause, param_env, recursion_depth, predicate }
100 }
101
102 pub fn misc(
103 span: Span,
104 body_id: hir::HirId,
105 param_env: ty::ParamEnv<'tcx>,
106 trait_ref: O,
107 ) -> Obligation<'tcx, O> {
108 Obligation::new(ObligationCause::misc(span, body_id), param_env, trait_ref)
109 }
110
111 pub fn with<P>(&self, value: P) -> Obligation<'tcx, P> {
112 Obligation {
113 cause: self.cause.clone(),
114 param_env: self.param_env,
115 recursion_depth: self.recursion_depth,
116 predicate: value,
117 }
118 }
119}
120
121impl<'tcx> FulfillmentError<'tcx> {
ba9703b0 122 pub fn new(
74b04a01
XL
123 obligation: PredicateObligation<'tcx>,
124 code: FulfillmentErrorCode<'tcx>,
125 ) -> FulfillmentError<'tcx> {
126 FulfillmentError { obligation, code, points_at_arg_span: false }
127 }
128}
129
130impl<'tcx> TraitObligation<'tcx> {
cdc7bbd5 131 pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
74b04a01
XL
132 self.predicate.map_bound(|p| p.self_ty())
133 }
134}