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
::subst
::GenericArg
;
5 use rustc_middle
::ty
::{self, ParamEnvAnd, TyCtxt}
;
6 use rustc_trait_selection
::traits
::query
::normalize
::AtExt
;
7 use rustc_trait_selection
::traits
::{Normalized, ObligationCause}
;
8 use std
::sync
::atomic
::Ordering
;
10 crate fn provide(p
: &mut Providers
) {
11 *p
= Providers { normalize_generic_arg_after_erasing_regions, ..*p }
;
14 fn normalize_generic_arg_after_erasing_regions
<'tcx
>(
16 goal
: ParamEnvAnd
<'tcx
, GenericArg
<'tcx
>>,
17 ) -> GenericArg
<'tcx
> {
18 debug
!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal
);
20 let ParamEnvAnd { param_env, value }
= goal
;
21 tcx
.sess
.perf_stats
.normalize_generic_arg_after_erasing_regions
.fetch_add(1, Ordering
::Relaxed
);
22 tcx
.infer_ctxt().enter(|infcx
| {
23 let cause
= ObligationCause
::dummy();
24 match infcx
.at(&cause
, param_env
).normalize(&value
) {
25 Ok(Normalized { value: normalized_value, obligations: normalized_obligations }
) => {
26 // We don't care about the `obligations`; they are
27 // always only region relations, and we are about to
28 // erase those anyway:
30 normalized_obligations
.iter().find(|p
| not_outlives_predicate(&p
.predicate
)),
34 let normalized_value
= infcx
.resolve_vars_if_possible(&normalized_value
);
35 infcx
.tcx
.erase_regions(&normalized_value
)
37 Err(NoSolution
) => bug
!("could not fully normalize `{:?}`", value
),
42 fn not_outlives_predicate(p
: &ty
::Predicate
<'tcx
>) -> bool
{
43 match p
.skip_binders() {
44 ty
::PredicateAtom
::RegionOutlives(..) | ty
::PredicateAtom
::TypeOutlives(..) => false,
45 ty
::PredicateAtom
::Trait(..)
46 | ty
::PredicateAtom
::Projection(..)
47 | ty
::PredicateAtom
::WellFormed(..)
48 | ty
::PredicateAtom
::ObjectSafe(..)
49 | ty
::PredicateAtom
::ClosureKind(..)
50 | ty
::PredicateAtom
::Subtype(..)
51 | ty
::PredicateAtom
::ConstEvaluatable(..)
52 | ty
::PredicateAtom
::ConstEquate(..)
53 | ty
::PredicateAtom
::TypeWellFormedFromEnv(..) => true,