1 use crate::infer
::canonical
::OriginalQueryValues
;
2 use crate::infer
::InferCtxt
;
3 use crate::traits
::query
::NoSolution
;
4 use crate::traits
::{FulfillmentContext, ObligationCause, TraitEngine}
;
6 use rustc_infer
::traits
::TraitEngineExt
as _
;
7 use rustc_middle
::ty
::{self, Ty}
;
8 use rustc_span
::source_map
::Span
;
10 pub use rustc_middle
::traits
::query
::OutlivesBound
;
12 pub trait InferCtxtExt
<'tcx
> {
13 fn implied_outlives_bounds(
15 param_env
: ty
::ParamEnv
<'tcx
>,
19 ) -> Vec
<OutlivesBound
<'tcx
>>;
22 impl<'cx
, 'tcx
> InferCtxtExt
<'tcx
> for InferCtxt
<'cx
, 'tcx
> {
23 /// Implied bounds are region relationships that we deduce
24 /// automatically. The idea is that (e.g.) a caller must check that a
25 /// function's argument types are well-formed immediately before
26 /// calling that fn, and hence the *callee* can assume that its
27 /// argument types are well-formed. This may imply certain relationships
28 /// between generic parameters. For example:
30 /// fn foo<'a,T>(x: &'a T)
32 /// can only be called with a `'a` and `T` such that `&'a T` is WF.
33 /// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
37 /// - `param_env`, the where-clauses in scope
38 /// - `body_id`, the body-id to use when normalizing assoc types.
39 /// Note that this may cause outlives obligations to be injected
40 /// into the inference context with this body-id.
41 /// - `ty`, the type that we are supposed to assume is WF.
42 /// - `span`, a span to use when normalizing, hopefully not important,
43 /// might be useful if a `bug!` occurs.
44 fn implied_outlives_bounds(
46 param_env
: ty
::ParamEnv
<'tcx
>,
50 ) -> Vec
<OutlivesBound
<'tcx
>> {
51 debug
!("implied_outlives_bounds(ty = {:?})", ty
);
53 let mut orig_values
= OriginalQueryValues
::default();
54 let key
= self.canonicalize_query(¶m_env
.and(ty
), &mut orig_values
);
55 let result
= match self.tcx
.implied_outlives_bounds(key
) {
58 self.tcx
.sess
.delay_span_bug(
60 "implied_outlives_bounds failed to solve all obligations",
65 assert
!(result
.value
.is_proven());
67 let result
= self.instantiate_query_response_and_region_obligations(
68 &ObligationCause
::misc(span
, body_id
),
73 debug
!("implied_outlives_bounds for {:?}: {:#?}", ty
, result
);
74 let result
= match result
{
77 self.tcx
.sess
.delay_span_bug(span
, "implied_outlives_bounds failed to instantiate");
82 // Instantiation may have produced new inference variables and constraints on those
83 // variables. Process these constraints.
84 let mut fulfill_cx
= FulfillmentContext
::new();
85 fulfill_cx
.register_predicate_obligations(self, result
.obligations
);
86 if fulfill_cx
.select_all_or_error(self).is_err() {
87 self.tcx
.sess
.delay_span_bug(
89 "implied_outlives_bounds failed to solve obligations from instantiation",