1 use rustc_infer
::infer
::TyCtxtInferExt
;
2 use rustc_middle
::traits
::query
::NoSolution
;
3 use rustc_middle
::ty
::query
::Providers
;
4 use rustc_middle
::ty
::{self, ParamEnvAnd, TyCtxt, TypeFoldable}
;
5 use rustc_trait_selection
::traits
::query
::normalize
::AtExt
;
6 use rustc_trait_selection
::traits
::{Normalized, ObligationCause}
;
7 use std
::sync
::atomic
::Ordering
;
9 pub(crate) fn provide(p
: &mut Providers
) {
11 try_normalize_generic_arg_after_erasing_regions
: |tcx
, goal
| {
12 debug
!("try_normalize_generic_arg_after_erasing_regions(goal={:#?}", goal
);
16 .normalize_generic_arg_after_erasing_regions
17 .fetch_add(1, Ordering
::Relaxed
);
19 try_normalize_after_erasing_regions(tcx
, goal
)
21 try_normalize_mir_const_after_erasing_regions
: |tcx
, goal
| {
22 try_normalize_after_erasing_regions(tcx
, goal
)
28 fn try_normalize_after_erasing_regions
<'tcx
, T
: TypeFoldable
<'tcx
> + PartialEq
+ Copy
>(
30 goal
: ParamEnvAnd
<'tcx
, T
>,
31 ) -> Result
<T
, NoSolution
> {
32 let ParamEnvAnd { param_env, value }
= goal
;
33 tcx
.infer_ctxt().enter(|infcx
| {
34 let cause
= ObligationCause
::dummy();
35 match infcx
.at(&cause
, param_env
).normalize(value
) {
36 Ok(Normalized { value: normalized_value, obligations: normalized_obligations }
) => {
37 // We don't care about the `obligations`; they are
38 // always only region relations, and we are about to
39 // erase those anyway:
41 normalized_obligations
.iter().find(|p
| not_outlives_predicate(p
.predicate
)),
45 let resolved_value
= infcx
.resolve_vars_if_possible(normalized_value
);
46 // It's unclear when `resolve_vars` would have an effect in a
47 // fresh `InferCtxt`. If this assert does trigger, it will give
49 debug_assert_eq
!(normalized_value
, resolved_value
);
50 let erased
= infcx
.tcx
.erase_regions(resolved_value
);
51 debug_assert
!(!erased
.needs_infer(), "{:?}", erased
);
54 Err(NoSolution
) => Err(NoSolution
),
59 fn not_outlives_predicate
<'tcx
>(p
: ty
::Predicate
<'tcx
>) -> bool
{
60 match p
.kind().skip_binder() {
61 ty
::PredicateKind
::RegionOutlives(..) | ty
::PredicateKind
::TypeOutlives(..) => false,
62 ty
::PredicateKind
::Trait(..)
63 | ty
::PredicateKind
::Projection(..)
64 | ty
::PredicateKind
::WellFormed(..)
65 | ty
::PredicateKind
::ObjectSafe(..)
66 | ty
::PredicateKind
::ClosureKind(..)
67 | ty
::PredicateKind
::Subtype(..)
68 | ty
::PredicateKind
::Coerce(..)
69 | ty
::PredicateKind
::ConstEvaluatable(..)
70 | ty
::PredicateKind
::ConstEquate(..)
71 | ty
::PredicateKind
::TypeWellFormedFromEnv(..) => true,