]> git.proxmox.com Git - rustc.git/blame - src/librustc/traits/mod.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / librustc / traits / mod.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
0531ce1d
XL
11//! Trait Resolution. See [rustc guide] for more info on how this works.
12//!
8faf50e0 13//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
1a4d82fc
JJ
14
15pub use self::SelectionError::*;
16pub use self::FulfillmentErrorCode::*;
17pub use self::Vtable::*;
18pub use self::ObligationCauseCode::*;
19
94b46f34 20use chalk_engine;
476ff2be 21use hir;
54a0048b 22use hir::def_id::DefId;
ff7c6d11 23use infer::outlives::env::OutlivesEnvironment;
ea8adc8c 24use middle::region;
8faf50e0 25use mir::interpret::ConstEvalErr;
9e0c209e 26use ty::subst::Substs;
94b46f34 27use ty::{self, AdtKind, Slice, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
cc61c64b 28use ty::error::{ExpectedFound, TypeError};
94b46f34 29use ty::fold::{TypeFolder, TypeFoldable, TypeVisitor};
cc61c64b 30use infer::{InferCtxt};
e9174d1e 31
0531ce1d 32use rustc_data_structures::sync::Lrc;
94b46f34 33use std::fmt::Debug;
1a4d82fc
JJ
34use std::rc::Rc;
35use syntax::ast;
3157f602 36use syntax_pos::{Span, DUMMY_SP};
1a4d82fc 37
ea8adc8c 38pub use self::coherence::{orphan_check, overlapping_impls, OrphanCheckErr, OverlapResult};
0531ce1d 39pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
3157f602 40pub use self::project::MismatchedProjectionTypes;
0531ce1d
XL
41pub use self::project::{normalize, normalize_projection_type, poly_project_and_unify_type};
42pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal, Normalized};
1a4d82fc
JJ
43pub use self::object_safety::ObjectSafetyViolation;
44pub use self::object_safety::MethodViolationCode;
ea8adc8c 45pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
54a0048b 46pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
83c7162d 47pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
ea8adc8c 48pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
cc61c64b 49pub use self::specialize::{SpecializesCache, find_associated_item};
8faf50e0 50pub use self::engine::{TraitEngine, TraitEngineExt};
1a4d82fc 51pub use self::util::elaborate_predicates;
1a4d82fc
JJ
52pub use self::util::supertraits;
53pub use self::util::Supertraits;
c34b1796
AL
54pub use self::util::supertrait_def_ids;
55pub use self::util::SupertraitDefIds;
1a4d82fc 56pub use self::util::transitive_bounds;
1a4d82fc 57
94b46f34
XL
58#[allow(dead_code)]
59pub mod auto_trait;
1a4d82fc 60mod coherence;
0531ce1d
XL
61pub mod error_reporting;
62mod engine;
1a4d82fc
JJ
63mod fulfill;
64mod project;
65mod object_safety;
ea8adc8c 66mod on_unimplemented;
1a4d82fc 67mod select;
54a0048b 68mod specialize;
e9174d1e 69mod structural_impls;
94b46f34 70pub mod codegen;
1a4d82fc
JJ
71mod util;
72
0531ce1d
XL
73pub mod query;
74
ff7c6d11
XL
75// Whether to enable bug compatibility with issue #43355
76#[derive(Copy, Clone, PartialEq, Eq, Debug)]
77pub enum IntercrateMode {
78 Issue43355,
79 Fixed
80}
81
83c7162d
XL
82// The mode that trait queries run in
83#[derive(Copy, Clone, PartialEq, Eq, Debug)]
84pub enum TraitQueryMode {
85 // Standard/un-canonicalized queries get accurate
86 // spans etc. passed in and hence can do reasonable
87 // error reporting on their own.
88 Standard,
89 // Canonicalized queries get dummy spans and hence
90 // must generally propagate errors to
91 // pre-canonicalization callsites.
92 Canonical,
93}
94
1a4d82fc
JJ
95/// An `Obligation` represents some trait reference (e.g. `int:Eq`) for
96/// which the vtable must be found. The process of finding a vtable is
97/// called "resolving" the `Obligation`. This process consists of
98/// either identifying an `impl` (e.g., `impl Eq for int`) that
99/// provides the required vtable, or else finding a bound that is in
100/// scope. The eventual result is usually a `Selection` (defined below).
0531ce1d 101#[derive(Clone, PartialEq, Eq, Hash)]
1a4d82fc 102pub struct Obligation<'tcx, T> {
0531ce1d 103 /// Why do we have to prove this thing?
1a4d82fc 104 pub cause: ObligationCause<'tcx>,
0531ce1d
XL
105
106 /// In which environment should we prove this thing?
7cac9316 107 pub param_env: ty::ParamEnv<'tcx>,
0531ce1d
XL
108
109 /// What are we trying to prove?
1a4d82fc 110 pub predicate: T,
0531ce1d
XL
111
112 /// If we started proving this as a result of trying to prove
113 /// something else, track the total depth to ensure termination.
114 /// If this goes over a certain threshold, we abort compilation --
115 /// in such cases, we can not say whether or not the predicate
116 /// holds for certain. Stupid halting problem. Such a drag.
117 pub recursion_depth: usize,
1a4d82fc
JJ
118}
119
120pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
121pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
122
123/// Why did we incur this obligation? Used for error reporting.
0531ce1d 124#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1a4d82fc
JJ
125pub struct ObligationCause<'tcx> {
126 pub span: Span,
127
128 // The id of the fn body that triggered this obligation. This is
129 // used for region obligations to determine the precise
130 // environment in which the region obligation should be evaluated
131 // (in particular, closures can add new assumptions). See the
132 // field `region_obligations` of the `FulfillmentContext` for more
133 // information.
134 pub body_id: ast::NodeId,
135
136 pub code: ObligationCauseCode<'tcx>
137}
138
2c00a5a8
XL
139impl<'tcx> ObligationCause<'tcx> {
140 pub fn span<'a, 'gcx>(&self, tcx: &TyCtxt<'a, 'gcx, 'tcx>) -> Span {
141 match self.code {
142 ObligationCauseCode::CompareImplMethodObligation { .. } |
143 ObligationCauseCode::MainFunctionType |
144 ObligationCauseCode::StartFunctionType => {
145 tcx.sess.codemap().def_span(self.span)
146 }
147 _ => self.span,
148 }
149 }
150}
151
0531ce1d 152#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1a4d82fc
JJ
153pub enum ObligationCauseCode<'tcx> {
154 /// Not well classified or should be obvious from span.
155 MiscObligation,
156
a7813a04 157 /// A slice or array is WF only if `T: Sized`
e9174d1e
SL
158 SliceOrArrayElem,
159
a7813a04
XL
160 /// A tuple is WF only if its middle elements are Sized
161 TupleElem,
162
e9174d1e
SL
163 /// This is the trait reference from the given projection
164 ProjectionWf(ty::ProjectionTy<'tcx>),
165
1a4d82fc
JJ
166 /// In an impl of trait X for type Y, type Y must
167 /// also implement all supertraits of X.
e9174d1e
SL
168 ItemObligation(DefId),
169
170 /// A type like `&'a T` is WF only if `T: 'a`.
171 ReferenceOutlivesReferent(Ty<'tcx>),
1a4d82fc 172
c30ab7b3 173 /// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
7cac9316 174 ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
c30ab7b3 175
1a4d82fc
JJ
176 /// Obligation incurred due to an object cast.
177 ObjectCastObligation(/* Object type */ Ty<'tcx>),
178
041b39d2
XL
179 // Various cases where expressions must be sized/copy/etc:
180 /// L = X implies that L is Sized
181 AssignmentLhsSized,
182 /// (x1, .., xn) must be Sized
183 TupleInitializerSized,
184 /// S { ... } must be Sized
185 StructInitializerSized,
186 /// Type of each variable must be Sized
187 VariableType(ast::NodeId),
188 /// Return type must be Sized
189 SizedReturnType,
2c00a5a8
XL
190 /// Yield type must be Sized
191 SizedYieldType,
041b39d2
XL
192 /// [T,..n] --> T must be Copy
193 RepeatVec,
194
195 /// Types of fields (other than the last) in a struct must be sized.
3b2f2976 196 FieldSized(AdtKind),
1a4d82fc 197
041b39d2 198 /// Constant expressions must be sized.
3157f602
XL
199 ConstSized,
200
041b39d2 201 /// static items must have `Sync` type
1a4d82fc
JJ
202 SharedStatic,
203
204 BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
205
206 ImplDerivedObligation(DerivedObligationCause<'tcx>),
85aaf69f 207
041b39d2 208 /// error derived when matching traits/impls; see ObligationCause for more details
c30ab7b3
SL
209 CompareImplMethodObligation {
210 item_name: ast::Name,
211 impl_item_def_id: DefId,
212 trait_item_def_id: DefId,
c30ab7b3 213 },
476ff2be 214
041b39d2 215 /// Checking that this expression can be assigned where it needs to be
476ff2be
SL
216 // FIXME(eddyb) #11161 is the original Expr required?
217 ExprAssignable,
218
041b39d2 219 /// Computing common supertype in the arms of a match expression
476ff2be
SL
220 MatchExpressionArm { arm_span: Span,
221 source: hir::MatchSource },
222
041b39d2 223 /// Computing common supertype in an if expression
476ff2be
SL
224 IfExpression,
225
041b39d2 226 /// Computing common supertype of an if expression with no else counter-part
476ff2be
SL
227 IfExpressionWithNoElse,
228
041b39d2 229 /// `main` has wrong type
476ff2be
SL
230 MainFunctionType,
231
041b39d2 232 /// `start` has wrong type
476ff2be
SL
233 StartFunctionType,
234
041b39d2 235 /// intrinsic has wrong type
476ff2be
SL
236 IntrinsicType,
237
041b39d2 238 /// method receiver
476ff2be 239 MethodReceiver,
cc61c64b 240
041b39d2 241 /// `return` with no expression
cc61c64b 242 ReturnNoExpression,
041b39d2
XL
243
244 /// `return` with an expression
245 ReturnType(ast::NodeId),
246
247 /// Block implicit return
248 BlockTailExpression(ast::NodeId),
94b46f34
XL
249
250 /// #[feature(trivial_bounds)] is not enabled
251 TrivialBound,
1a4d82fc
JJ
252}
253
0531ce1d 254#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1a4d82fc
JJ
255pub struct DerivedObligationCause<'tcx> {
256 /// The trait reference of the parent obligation that led to the
257 /// current obligation. Note that only trait obligations lead to
258 /// derived obligations, so we just store the trait reference here
259 /// directly.
260 parent_trait_ref: ty::PolyTraitRef<'tcx>,
261
262 /// The parent trait had this cause
263 parent_code: Rc<ObligationCauseCode<'tcx>>
264}
265
62682a34
SL
266pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
267pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
268pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
1a4d82fc 269
0531ce1d 270/// The following types:
8faf50e0
XL
271/// * `WhereClause`
272/// * `WellFormed`
273/// * `FromEnv`
0531ce1d
XL
274/// * `DomainGoal`
275/// * `Goal`
276/// * `Clause`
277/// are used for representing the trait system in the form of
278/// logic programming clauses. They are part of the interface
279/// for the chalk SLG solver.
280#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
8faf50e0 281pub enum WhereClause<'tcx> {
0531ce1d
XL
282 Implemented(ty::TraitPredicate<'tcx>),
283 ProjectionEq(ty::ProjectionPredicate<'tcx>),
8faf50e0
XL
284 RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
285 TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
286}
287
288#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
289pub enum WellFormed<'tcx> {
290 Trait(ty::TraitPredicate<'tcx>),
291 Ty(Ty<'tcx>),
292}
293
294#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
295pub enum FromEnv<'tcx> {
296 Trait(ty::TraitPredicate<'tcx>),
297 Ty(Ty<'tcx>),
0531ce1d
XL
298}
299
300#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
301pub enum DomainGoal<'tcx> {
8faf50e0
XL
302 Holds(WhereClause<'tcx>),
303 WellFormed(WellFormed<'tcx>),
304 FromEnv(FromEnv<'tcx>),
83c7162d 305 Normalize(ty::ProjectionPredicate<'tcx>),
0531ce1d
XL
306}
307
83c7162d
XL
308pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
309
0531ce1d
XL
310#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
311pub enum QuantifierKind {
312 Universal,
313 Existential,
314}
315
83c7162d 316#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
0531ce1d 317pub enum Goal<'tcx> {
83c7162d
XL
318 Implies(Clauses<'tcx>, &'tcx Goal<'tcx>),
319 And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>),
320 Not(&'tcx Goal<'tcx>),
0531ce1d 321 DomainGoal(DomainGoal<'tcx>),
83c7162d
XL
322 Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>),
323 CannotProve,
0531ce1d
XL
324}
325
83c7162d
XL
326pub type Goals<'tcx> = &'tcx Slice<Goal<'tcx>>;
327
8faf50e0
XL
328impl<'tcx> DomainGoal<'tcx> {
329 pub fn into_goal(self) -> Goal<'tcx> {
330 Goal::DomainGoal(self)
331 }
332}
333
83c7162d
XL
334impl<'tcx> Goal<'tcx> {
335 pub fn from_poly_domain_goal<'a>(
336 domain_goal: PolyDomainGoal<'tcx>,
337 tcx: TyCtxt<'a, 'tcx, 'tcx>,
338 ) -> Goal<'tcx> {
339 match domain_goal.no_late_bound_regions() {
8faf50e0 340 Some(p) => p.into_goal(),
83c7162d
XL
341 None => Goal::Quantified(
342 QuantifierKind::Universal,
8faf50e0 343 domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
83c7162d
XL
344 ),
345 }
0531ce1d
XL
346 }
347}
348
0531ce1d
XL
349/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
350/// Harrop Formulas".
83c7162d 351#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
0531ce1d 352pub enum Clause<'tcx> {
83c7162d
XL
353 Implies(ProgramClause<'tcx>),
354 ForAll(ty::Binder<ProgramClause<'tcx>>),
355}
356
357/// Multiple clauses.
358pub type Clauses<'tcx> = &'tcx Slice<Clause<'tcx>>;
359
360/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying
361/// that the domain goal `D` is true if `G1...Gn` are provable. This
362/// is equivalent to the implication `G1..Gn => D`; we usually write
363/// it with the reverse implication operator `:-` to emphasize the way
364/// that programs are actually solved (via backchaining, which starts
365/// with the goal to solve and proceeds from there).
366#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
367pub struct ProgramClause<'tcx> {
368 /// This goal will be considered true...
369 pub goal: DomainGoal<'tcx>,
370
371 /// ...if we can prove these hypotheses (there may be no hypotheses at all):
372 pub hypotheses: Goals<'tcx>,
0531ce1d
XL
373}
374
1a4d82fc
JJ
375pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
376
85aaf69f 377#[derive(Clone,Debug)]
1a4d82fc
JJ
378pub enum SelectionError<'tcx> {
379 Unimplemented,
1a4d82fc
JJ
380 OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
381 ty::PolyTraitRef<'tcx>,
e9174d1e
SL
382 ty::error::TypeError<'tcx>),
383 TraitNotObjectSafe(DefId),
8faf50e0 384 ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
83c7162d 385 Overflow,
1a4d82fc
JJ
386}
387
388pub struct FulfillmentError<'tcx> {
389 pub obligation: PredicateObligation<'tcx>,
390 pub code: FulfillmentErrorCode<'tcx>
391}
392
393#[derive(Clone)]
394pub enum FulfillmentErrorCode<'tcx> {
395 CodeSelectionError(SelectionError<'tcx>),
396 CodeProjectionError(MismatchedProjectionTypes<'tcx>),
cc61c64b
XL
397 CodeSubtypeError(ExpectedFound<Ty<'tcx>>,
398 TypeError<'tcx>), // always comes from a SubtypePredicate
1a4d82fc
JJ
399 CodeAmbiguity,
400}
401
402/// When performing resolution, it is typically the case that there
403/// can be one of three outcomes:
404///
405/// - `Ok(Some(r))`: success occurred with result `r`
406/// - `Ok(None)`: could not definitely determine anything, usually due
407/// to inconclusive type inference.
408/// - `Err(e)`: error `e` occurred
409pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
410
411/// Given the successful resolution of an obligation, the `Vtable`
412/// indicates where the vtable comes from. Note that while we call this
413/// a "vtable", it does not necessarily indicate dynamic dispatch at
414/// runtime. `Vtable` instances just tell the compiler where to find
415/// methods, but in generic code those methods are typically statically
416/// dispatched -- only when an object is constructed is a `Vtable`
417/// instance reified into an actual vtable.
418///
419/// For example, the vtable may be tied to a specific impl (case A),
420/// or it may be relative to some bound that is in scope (case B).
421///
422///
423/// ```
424/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
425/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
426/// impl Clone for int { ... } // Impl_3
427///
428/// fn foo<T:Clone>(concrete: Option<Box<int>>,
429/// param: T,
430/// mixed: Option<T>) {
431///
432/// // Case A: Vtable points at a specific impl. Only possible when
433/// // type is concretely known. If the impl itself has bounded
434/// // type parameters, Vtable will carry resolutions for those as well:
435/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
436///
437/// // Case B: Vtable must be provided by caller. This applies when
438/// // type is a type parameter.
439/// param.clone(); // VtableParam
440///
441/// // Case C: A mix of cases A and B.
442/// mixed.clone(); // Vtable(Impl_1, [VtableParam])
443/// }
444/// ```
445///
446/// ### The type parameter `N`
447///
448/// See explanation on `VtableImplData`.
0531ce1d 449#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
1a4d82fc
JJ
450pub enum Vtable<'tcx, N> {
451 /// Vtable identifying a particular impl.
452 VtableImpl(VtableImplData<'tcx, N>),
453
abe05a73 454 /// Vtable for auto trait implementations
c34b1796 455 /// This carries the information and nested obligations with regards
abe05a73 456 /// to an auto implementation for a trait `Trait`. The nested obligations
c34b1796 457 /// ensure the trait implementation holds for all the constituent types.
abe05a73 458 VtableAutoImpl(VtableAutoImplData<N>),
c34b1796 459
1a4d82fc 460 /// Successful resolution to an obligation provided by the caller
85aaf69f
SL
461 /// for some type parameter. The `Vec<N>` represents the
462 /// obligations incurred from normalizing the where-clause (if
463 /// any).
464 VtableParam(Vec<N>),
1a4d82fc
JJ
465
466 /// Virtual calls through an object
a7813a04 467 VtableObject(VtableObjectData<'tcx, N>),
1a4d82fc
JJ
468
469 /// Successful resolution for a builtin trait.
470 VtableBuiltin(VtableBuiltinData<N>),
471
85aaf69f
SL
472 /// Vtable automatically generated for a closure. The def ID is the ID
473 /// of the closure expression. This is a `VtableImpl` in spirit, but the
474 /// impl is generated by the compiler and does not appear in the source.
62682a34 475 VtableClosure(VtableClosureData<'tcx, N>),
1a4d82fc
JJ
476
477 /// Same as above, but for a fn pointer type with the given signature.
a7813a04 478 VtableFnPointer(VtableFnPointerData<'tcx, N>),
ea8adc8c
XL
479
480 /// Vtable automatically generated for a generator
481 VtableGenerator(VtableGeneratorData<'tcx, N>),
1a4d82fc
JJ
482}
483
484/// Identifies a particular impl in the source, along with a set of
485/// substitutions from the impl's type/lifetime parameters. The
486/// `nested` vector corresponds to the nested obligations attached to
487/// the impl's type parameters.
488///
489/// The type parameter `N` indicates the type used for "nested
490/// obligations" that are required by the impl. During type check, this
94b46f34
XL
491/// is `Obligation`, as one might expect. During codegen, however, this
492/// is `()`, because codegen only requires a shallow resolution of an
1a4d82fc 493/// impl, and nested obligations are satisfied later.
ff7c6d11 494#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
1a4d82fc 495pub struct VtableImplData<'tcx, N> {
e9174d1e 496 pub impl_def_id: DefId,
9e0c209e 497 pub substs: &'tcx Substs<'tcx>,
62682a34
SL
498 pub nested: Vec<N>
499}
500
ff7c6d11 501#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
ea8adc8c 502pub struct VtableGeneratorData<'tcx, N> {
94b46f34
XL
503 pub generator_def_id: DefId,
504 pub substs: ty::GeneratorSubsts<'tcx>,
ea8adc8c
XL
505 /// Nested obligations. This can be non-empty if the generator
506 /// signature contains associated types.
507 pub nested: Vec<N>
508}
509
ff7c6d11 510#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
62682a34 511pub struct VtableClosureData<'tcx, N> {
e9174d1e 512 pub closure_def_id: DefId,
c1a9b12d 513 pub substs: ty::ClosureSubsts<'tcx>,
62682a34
SL
514 /// Nested obligations. This can be non-empty if the closure
515 /// signature contains associated types.
516 pub nested: Vec<N>
1a4d82fc
JJ
517}
518
0531ce1d 519#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
abe05a73 520pub struct VtableAutoImplData<N> {
e9174d1e 521 pub trait_def_id: DefId,
c34b1796
AL
522 pub nested: Vec<N>
523}
524
0531ce1d 525#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
1a4d82fc 526pub struct VtableBuiltinData<N> {
62682a34 527 pub nested: Vec<N>
1a4d82fc
JJ
528}
529
530/// A vtable for some object-safe trait `Foo` automatically derived
531/// for the object type `Foo`.
ff7c6d11 532#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable)]
a7813a04 533pub struct VtableObjectData<'tcx, N> {
c34b1796
AL
534 /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
535 pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
c1a9b12d
SL
536
537 /// The vtable is formed by concatenating together the method lists of
538 /// the base object trait and all supertraits; this is the start of
539 /// `upcast_trait_ref`'s methods in that vtable.
a7813a04
XL
540 pub vtable_base: usize,
541
542 pub nested: Vec<N>,
543}
544
ff7c6d11 545#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
a7813a04 546pub struct VtableFnPointerData<'tcx, N> {
ea8adc8c 547 pub fn_ty: Ty<'tcx>,
a7813a04 548 pub nested: Vec<N>
1a4d82fc
JJ
549}
550
1a4d82fc 551/// Creates predicate obligations from the generic bounds.
62682a34 552pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
7cac9316 553 param_env: ty::ParamEnv<'tcx>,
85aaf69f 554 generic_bounds: &ty::InstantiatedPredicates<'tcx>)
1a4d82fc
JJ
555 -> PredicateObligations<'tcx>
556{
7cac9316 557 util::predicates_for_generics(cause, 0, param_env, generic_bounds)
1a4d82fc
JJ
558}
559
560/// Determines whether the type `ty` is known to meet `bound` and
561/// returns true if so. Returns false if `ty` either does not meet
562/// `bound` or is not known to meet bound (note that this is
563/// conservative towards *no impl*, which is the opposite of the
564/// `evaluate` methods).
476ff2be 565pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
7cac9316 566 param_env: ty::ParamEnv<'tcx>,
476ff2be
SL
567 ty: Ty<'tcx>,
568 def_id: DefId,
569 span: Span)
570-> bool
1a4d82fc 571{
476ff2be 572 debug!("type_known_to_meet_bound(ty={:?}, bound={:?})",
62682a34 573 ty,
476ff2be
SL
574 infcx.tcx.item_path_str(def_id));
575
576 let trait_ref = ty::TraitRef {
041b39d2 577 def_id,
476ff2be 578 substs: infcx.tcx.mk_substs_trait(ty, &[]),
92a42be0 579 };
476ff2be 580 let obligation = Obligation {
7cac9316 581 param_env,
476ff2be
SL
582 cause: ObligationCause::misc(span, ast::DUMMY_NODE_ID),
583 recursion_depth: 0,
584 predicate: trait_ref.to_predicate(),
585 };
586
83c7162d 587 let result = infcx.predicate_must_hold(&obligation);
476ff2be
SL
588 debug!("type_known_to_meet_ty={:?} bound={} => {:?}",
589 ty, infcx.tcx.item_path_str(def_id), result);
92a42be0
SL
590
591 if result && (ty.has_infer_types() || ty.has_closure_types()) {
592 // Because of inference "guessing", selection can sometimes claim
593 // to succeed while the success requires a guess. To ensure
594 // this function's result remains infallible, we must confirm
595 // that guess. While imperfect, I believe this is sound.
596
ff7c6d11
XL
597 // The handling of regions in this area of the code is terrible,
598 // see issue #29149. We should be able to improve on this with
599 // NLL.
600 let mut fulfill_cx = FulfillmentContext::new_ignoring_regions();
92a42be0
SL
601
602 // We can use a dummy node-id here because we won't pay any mind
603 // to region obligations that arise (there shouldn't really be any
604 // anyhow).
605 let cause = ObligationCause::misc(span, ast::DUMMY_NODE_ID);
606
7cac9316 607 fulfill_cx.register_bound(infcx, param_env, ty, def_id, cause);
92a42be0
SL
608
609 // Note: we only assume something is `Copy` if we can
610 // *definitively* show that it implements `Copy`. Otherwise,
611 // assume it is move; linear is always ok.
612 match fulfill_cx.select_all_or_error(infcx) {
613 Ok(()) => {
476ff2be 614 debug!("type_known_to_meet_bound: ty={:?} bound={} success",
92a42be0 615 ty,
476ff2be 616 infcx.tcx.item_path_str(def_id));
92a42be0
SL
617 true
618 }
619 Err(e) => {
476ff2be 620 debug!("type_known_to_meet_bound: ty={:?} bound={} errors={:?}",
92a42be0 621 ty,
476ff2be 622 infcx.tcx.item_path_str(def_id),
92a42be0
SL
623 e);
624 false
625 }
1a4d82fc 626 }
92a42be0
SL
627 } else {
628 result
1a4d82fc
JJ
629 }
630}
631
c1a9b12d 632// FIXME: this is gonna need to be removed ...
c34b1796 633/// Normalizes the parameter environment, reporting errors if they occur.
a7813a04 634pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
7cac9316
XL
635 region_context: DefId,
636 unnormalized_env: ty::ParamEnv<'tcx>,
637 cause: ObligationCause<'tcx>)
638 -> ty::ParamEnv<'tcx>
85aaf69f 639{
c34b1796
AL
640 // I'm not wild about reporting errors here; I'd prefer to
641 // have the errors get reported at a defined place (e.g.,
642 // during typeck). Instead I have all parameter
643 // environments, in effect, going through this function
644 // and hence potentially reporting errors. This ensurse of
645 // course that we never forget to normalize (the
646 // alternative seemed like it would involve a lot of
647 // manual invocations of this fn -- and then we'd have to
648 // deal with the errors at each of those sites).
649 //
650 // In any case, in practice, typeck constructs all the
651 // parameter environments once for every fn as it goes,
652 // and errors will get reported then; so after typeck we
653 // can be sure that no errors should occur.
654
c34b1796 655 let span = cause.span;
c34b1796 656
62682a34
SL
657 debug!("normalize_param_env_or_error(unnormalized_env={:?})",
658 unnormalized_env);
659
660 let predicates: Vec<_> =
7cac9316 661 util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
62682a34
SL
662 .collect();
663
62682a34
SL
664 debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
665 predicates);
666
7cac9316
XL
667 let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
668 unnormalized_env.reveal);
669
041b39d2 670 tcx.infer_ctxt().enter(|infcx| {
ff7c6d11
XL
671 // FIXME. We should really... do something with these region
672 // obligations. But this call just continues the older
673 // behavior (i.e., doesn't cause any new bugs), and it would
674 // take some further refactoring to actually solve them. In
675 // particular, we would have to handle implied bounds
676 // properly, and that code is currently largely confined to
677 // regionck (though I made some efforts to extract it
678 // out). -nmatsakis
679 //
680 // @arielby: In any case, these obligations are checked
681 // by wfcheck anyway, so I'm not sure we have to check
682 // them here too, and we will remove this function when
683 // we move over to lazy normalization *anyway*.
684 let fulfill_cx = FulfillmentContext::new_ignoring_regions();
685
94b46f34 686 let predicates = match fully_normalize(
7cac9316 687 &infcx,
ff7c6d11 688 fulfill_cx,
7cac9316
XL
689 cause,
690 elaborated_env,
691 // You would really want to pass infcx.param_env.caller_bounds here,
692 // but that is an interned slice, and fully_normalize takes &T and returns T, so
693 // without further refactoring, a slice can't be used. Luckily, we still have the
694 // predicate vector from which we created the ParamEnv in infcx, so we
695 // can pass that instead. It's roundabout and a bit brittle, but this code path
696 // ought to be refactored anyway, and until then it saves us from having to copy.
697 &predicates,
698 ) {
a7813a04
XL
699 Ok(predicates) => predicates,
700 Err(errors) => {
0531ce1d 701 infcx.report_fulfillment_errors(&errors, None, false);
a7813a04 702 // An unnormalized env is better than nothing.
7cac9316 703 return elaborated_env;
a7813a04
XL
704 }
705 };
706
707 debug!("normalize_param_env_or_error: normalized predicates={:?}",
708 predicates);
709
ea8adc8c 710 let region_scope_tree = region::ScopeTree::default();
abe05a73 711
ff7c6d11
XL
712 // We can use the `elaborated_env` here; the region code only
713 // cares about declarations like `'a: 'b`.
714 let outlives_env = OutlivesEnvironment::new(elaborated_env);
715
716 infcx.resolve_regions_and_report_errors(region_context, &region_scope_tree, &outlives_env);
abe05a73 717
a7813a04
XL
718 let predicates = match infcx.fully_resolve(&predicates) {
719 Ok(predicates) => predicates,
720 Err(fixup_err) => {
721 // If we encounter a fixup error, it means that some type
722 // variable wound up unconstrained. I actually don't know
723 // if this can happen, and I certainly don't expect it to
724 // happen often, but if it did happen it probably
725 // represents a legitimate failure due to some kind of
726 // unconstrained variable, and it seems better not to ICE,
727 // all things considered.
728 tcx.sess.span_err(span, &fixup_err.to_string());
729 // An unnormalized env is better than nothing.
7cac9316 730 return elaborated_env;
a7813a04
XL
731 }
732 };
7453a54e 733
a7813a04
XL
734 let predicates = match tcx.lift_to_global(&predicates) {
735 Some(predicates) => predicates,
7cac9316 736 None => return elaborated_env,
a7813a04 737 };
85aaf69f 738
a7813a04 739 debug!("normalize_param_env_or_error: resolved predicates={:?}",
7cac9316 740 predicates);
7453a54e 741
7cac9316 742 ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal)
a7813a04 743 })
85aaf69f
SL
744}
745
94b46f34 746pub fn fully_normalize<'a, 'gcx, 'tcx, T>(
ff7c6d11
XL
747 infcx: &InferCtxt<'a, 'gcx, 'tcx>,
748 mut fulfill_cx: FulfillmentContext<'tcx>,
749 cause: ObligationCause<'tcx>,
750 param_env: ty::ParamEnv<'tcx>,
751 value: &T)
752 -> Result<T, Vec<FulfillmentError<'tcx>>>
753 where T : TypeFoldable<'tcx>
754{
755 debug!("fully_normalize_with_fulfillcx(value={:?})", value);
756 let selcx = &mut SelectionContext::new(infcx);
85aaf69f 757 let Normalized { value: normalized_value, obligations } =
7cac9316 758 project::normalize(selcx, param_env, cause, value);
7453a54e 759 debug!("fully_normalize: normalized_value={:?} obligations={:?}",
62682a34
SL
760 normalized_value,
761 obligations);
85aaf69f
SL
762 for obligation in obligations {
763 fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
764 }
c1a9b12d 765
7453a54e 766 debug!("fully_normalize: select_all_or_error start");
94b46f34 767 fulfill_cx.select_all_or_error(infcx)?;
7453a54e 768 debug!("fully_normalize: select_all_or_error complete");
85aaf69f 769 let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
7453a54e 770 debug!("fully_normalize: resolved_value={:?}", resolved_value);
85aaf69f
SL
771 Ok(resolved_value)
772}
773
7cac9316
XL
774/// Normalizes the predicates and checks whether they hold in an empty
775/// environment. If this returns false, then either normalize
776/// encountered an error or one of the predicates did not hold. Used
777/// when creating vtables to check for unsatisfiable methods.
2c00a5a8
XL
778fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
779 predicates: Vec<ty::Predicate<'tcx>>)
780 -> bool
9e0c209e
SL
781{
782 debug!("normalize_and_test_predicates(predicates={:?})",
783 predicates);
784
041b39d2 785 let result = tcx.infer_ctxt().enter(|infcx| {
0531ce1d 786 let param_env = ty::ParamEnv::reveal_all();
9e0c209e
SL
787 let mut selcx = SelectionContext::new(&infcx);
788 let mut fulfill_cx = FulfillmentContext::new();
789 let cause = ObligationCause::dummy();
790 let Normalized { value: predicates, obligations } =
7cac9316 791 normalize(&mut selcx, param_env, cause.clone(), &predicates);
9e0c209e
SL
792 for obligation in obligations {
793 fulfill_cx.register_predicate_obligation(&infcx, obligation);
794 }
795 for predicate in predicates {
7cac9316 796 let obligation = Obligation::new(cause.clone(), param_env, predicate);
9e0c209e
SL
797 fulfill_cx.register_predicate_obligation(&infcx, obligation);
798 }
799
800 fulfill_cx.select_all_or_error(&infcx).is_ok()
041b39d2
XL
801 });
802 debug!("normalize_and_test_predicates(predicates={:?}) = {:?}",
803 predicates, result);
804 result
9e0c209e
SL
805}
806
2c00a5a8
XL
807fn substitute_normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
808 key: (DefId, &'tcx Substs<'tcx>))
809 -> bool
810{
811 use ty::subst::Subst;
812 debug!("substitute_normalize_and_test_predicates(key={:?})",
813 key);
814
815 let predicates = tcx.predicates_of(key.0).predicates.subst(tcx, key.1);
816 let result = normalize_and_test_predicates(tcx, predicates);
817
818 debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
819 key, result);
820 result
821}
822
9e0c209e
SL
823/// Given a trait `trait_ref`, iterates the vtable entries
824/// that come from `trait_ref`, including its supertraits.
825#[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
abe05a73 826fn vtable_methods<'a, 'tcx>(
9e0c209e
SL
827 tcx: TyCtxt<'a, 'tcx, 'tcx>,
828 trait_ref: ty::PolyTraitRef<'tcx>)
0531ce1d 829 -> Lrc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>
9e0c209e 830{
abe05a73
XL
831 debug!("vtable_methods({:?})", trait_ref);
832
0531ce1d 833 Lrc::new(
abe05a73
XL
834 supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
835 let trait_methods = tcx.associated_items(trait_ref.def_id())
836 .filter(|item| item.kind == ty::AssociatedKind::Method);
837
838 // Now list each method's DefId and Substs (for within its trait).
839 // If the method can never be called from this object, produce None.
840 trait_methods.map(move |trait_method| {
841 debug!("vtable_methods: trait_method={:?}", trait_method);
842 let def_id = trait_method.def_id;
843
844 // Some methods cannot be called on an object; skip those.
845 if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
846 debug!("vtable_methods: not vtable safe");
847 return None;
848 }
849
850 // the method may have some early-bound lifetimes, add
851 // regions for those
83c7162d 852 let substs = trait_ref.map_bound(|trait_ref| {
94b46f34
XL
853 Substs::for_item(tcx, def_id, |param, _| {
854 match param.kind {
855 GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
856 GenericParamDefKind::Type {..} => {
857 trait_ref.substs[param.index as usize]
858 }
859 }
860 })
83c7162d 861 });
abe05a73
XL
862
863 // the trait type may have higher-ranked lifetimes in it;
864 // so erase them if they appear, so that we get the type
865 // at some particular call site
0531ce1d
XL
866 let substs = tcx.normalize_erasing_late_bound_regions(
867 ty::ParamEnv::reveal_all(),
83c7162d 868 &substs
0531ce1d 869 );
abe05a73
XL
870
871 // It's possible that the method relies on where clauses that
872 // do not hold for this particular set of type parameters.
873 // Note that this method could then never be called, so we
94b46f34 874 // do not want to try and codegen it, in that case (see #23435).
abe05a73
XL
875 let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
876 if !normalize_and_test_predicates(tcx, predicates.predicates) {
877 debug!("vtable_methods: predicates do not hold");
878 return None;
879 }
880
881 Some((def_id, substs))
882 })
883 }).collect()
884 )
9e0c209e
SL
885}
886
1a4d82fc
JJ
887impl<'tcx,O> Obligation<'tcx,O> {
888 pub fn new(cause: ObligationCause<'tcx>,
7cac9316
XL
889 param_env: ty::ParamEnv<'tcx>,
890 predicate: O)
1a4d82fc
JJ
891 -> Obligation<'tcx, O>
892 {
7cac9316 893 Obligation { cause, param_env, recursion_depth: 0, predicate }
1a4d82fc
JJ
894 }
895
896 fn with_depth(cause: ObligationCause<'tcx>,
c34b1796 897 recursion_depth: usize,
7cac9316
XL
898 param_env: ty::ParamEnv<'tcx>,
899 predicate: O)
1a4d82fc
JJ
900 -> Obligation<'tcx, O>
901 {
7cac9316 902 Obligation { cause, param_env, recursion_depth, predicate }
1a4d82fc
JJ
903 }
904
7cac9316
XL
905 pub fn misc(span: Span,
906 body_id: ast::NodeId,
907 param_env: ty::ParamEnv<'tcx>,
908 trait_ref: O)
909 -> Obligation<'tcx, O> {
910 Obligation::new(ObligationCause::misc(span, body_id), param_env, trait_ref)
1a4d82fc
JJ
911 }
912
913 pub fn with<P>(&self, value: P) -> Obligation<'tcx,P> {
914 Obligation { cause: self.cause.clone(),
7cac9316 915 param_env: self.param_env,
1a4d82fc
JJ
916 recursion_depth: self.recursion_depth,
917 predicate: value }
918 }
919}
920
921impl<'tcx> ObligationCause<'tcx> {
922 pub fn new(span: Span,
923 body_id: ast::NodeId,
924 code: ObligationCauseCode<'tcx>)
925 -> ObligationCause<'tcx> {
926 ObligationCause { span: span, body_id: body_id, code: code }
927 }
928
929 pub fn misc(span: Span, body_id: ast::NodeId) -> ObligationCause<'tcx> {
930 ObligationCause { span: span, body_id: body_id, code: MiscObligation }
931 }
932
933 pub fn dummy() -> ObligationCause<'tcx> {
9e0c209e 934 ObligationCause { span: DUMMY_SP, body_id: ast::CRATE_NODE_ID, code: MiscObligation }
1a4d82fc
JJ
935 }
936}
937
938impl<'tcx, N> Vtable<'tcx, N> {
62682a34 939 pub fn nested_obligations(self) -> Vec<N> {
1a4d82fc 940 match self {
62682a34
SL
941 VtableImpl(i) => i.nested,
942 VtableParam(n) => n,
943 VtableBuiltin(i) => i.nested,
abe05a73 944 VtableAutoImpl(d) => d.nested,
62682a34 945 VtableClosure(c) => c.nested,
ea8adc8c 946 VtableGenerator(c) => c.nested,
a7813a04
XL
947 VtableObject(d) => d.nested,
948 VtableFnPointer(d) => d.nested,
949 }
950 }
951
62682a34
SL
952 pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
953 match self {
954 VtableImpl(i) => VtableImpl(VtableImplData {
955 impl_def_id: i.impl_def_id,
956 substs: i.substs,
a7813a04 957 nested: i.nested.into_iter().map(f).collect(),
62682a34
SL
958 }),
959 VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
960 VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData {
a7813a04
XL
961 nested: i.nested.into_iter().map(f).collect(),
962 }),
963 VtableObject(o) => VtableObject(VtableObjectData {
964 upcast_trait_ref: o.upcast_trait_ref,
965 vtable_base: o.vtable_base,
966 nested: o.nested.into_iter().map(f).collect(),
62682a34 967 }),
abe05a73 968 VtableAutoImpl(d) => VtableAutoImpl(VtableAutoImplData {
62682a34 969 trait_def_id: d.trait_def_id,
a7813a04
XL
970 nested: d.nested.into_iter().map(f).collect(),
971 }),
972 VtableFnPointer(p) => VtableFnPointer(VtableFnPointerData {
973 fn_ty: p.fn_ty,
974 nested: p.nested.into_iter().map(f).collect(),
62682a34 975 }),
ea8adc8c 976 VtableGenerator(c) => VtableGenerator(VtableGeneratorData {
94b46f34 977 generator_def_id: c.generator_def_id,
ea8adc8c
XL
978 substs: c.substs,
979 nested: c.nested.into_iter().map(f).collect(),
980 }),
62682a34
SL
981 VtableClosure(c) => VtableClosure(VtableClosureData {
982 closure_def_id: c.closure_def_id,
983 substs: c.substs,
c1a9b12d 984 nested: c.nested.into_iter().map(f).collect(),
62682a34 985 })
1a4d82fc
JJ
986 }
987 }
988}
989
990impl<'tcx> FulfillmentError<'tcx> {
991 fn new(obligation: PredicateObligation<'tcx>,
992 code: FulfillmentErrorCode<'tcx>)
993 -> FulfillmentError<'tcx>
994 {
995 FulfillmentError { obligation: obligation, code: code }
996 }
1a4d82fc
JJ
997}
998
999impl<'tcx> TraitObligation<'tcx> {
c34b1796 1000 fn self_ty(&self) -> ty::Binder<Ty<'tcx>> {
83c7162d 1001 self.predicate.map_bound(|p| p.self_ty())
1a4d82fc
JJ
1002 }
1003}
7cac9316 1004
94b46f34
XL
1005pub fn provide(providers: &mut ty::query::Providers) {
1006 *providers = ty::query::Providers {
7cac9316
XL
1007 is_object_safe: object_safety::is_object_safe_provider,
1008 specialization_graph_of: specialize::specialization_graph_provider,
ea8adc8c 1009 specializes: specialize::specializes,
94b46f34 1010 codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
abe05a73 1011 vtable_methods,
2c00a5a8 1012 substitute_normalize_and_test_predicates,
7cac9316
XL
1013 ..*providers
1014 };
1015}
94b46f34 1016
94b46f34
XL
1017pub trait ExClauseFold<'tcx>
1018where
1019 Self: chalk_engine::context::Context + Clone,
1020{
1021 fn fold_ex_clause_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(
1022 ex_clause: &chalk_engine::ExClause<Self>,
1023 folder: &mut F,
1024 ) -> chalk_engine::ExClause<Self>;
1025
1026 fn visit_ex_clause_with<'gcx: 'tcx, V: TypeVisitor<'tcx>>(
1027 ex_clause: &chalk_engine::ExClause<Self>,
1028 visitor: &mut V,
1029 ) -> bool;
1030}
1031
1032pub trait ExClauseLift<'tcx>
1033where
1034 Self: chalk_engine::context::Context + Clone,
1035{
1036 type LiftedExClause: Debug + 'tcx;
1037
1038 fn lift_ex_clause_to_tcx<'a, 'gcx>(
1039 ex_clause: &chalk_engine::ExClause<Self>,
1040 tcx: TyCtxt<'a, 'gcx, 'tcx>,
1041 ) -> Option<Self::LiftedExClause>;
1042}