1 //! Routines to check for relations between fully inferred types.
3 //! FIXME: Move this to a more general place. The utility of this extends to
4 //! other areas of the compiler as well.
6 use rustc_infer
::infer
::{DefiningAnchor, TyCtxtInferExt}
;
7 use rustc_infer
::traits
::ObligationCause
;
8 use rustc_middle
::ty
::{ParamEnv, Ty, TyCtxt}
;
9 use rustc_trait_selection
::traits
::ObligationCtxt
;
11 /// Returns whether the two types are equal up to subtyping.
13 /// This is used in case we don't know the expected subtyping direction
14 /// and still want to check whether anything is broken.
15 pub fn is_equal_up_to_subtyping
<'tcx
>(
17 param_env
: ParamEnv
<'tcx
>,
26 // Check for subtyping in either direction.
27 is_subtype(tcx
, param_env
, src
, dest
) || is_subtype(tcx
, param_env
, dest
, src
)
30 /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
32 /// This mostly ignores opaque types as it can be used in constraining contexts
33 /// while still computing the final underlying type.
34 pub fn is_subtype
<'tcx
>(
36 param_env
: ParamEnv
<'tcx
>,
45 tcx
.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor
::Bubble
);
46 let infcx
= builder
.build();
47 let ocx
= ObligationCtxt
::new(&infcx
);
48 let cause
= ObligationCause
::dummy();
49 let src
= ocx
.normalize(&cause
, param_env
, src
);
50 let dest
= ocx
.normalize(&cause
, param_env
, dest
);
51 match ocx
.sub(&cause
, param_env
, src
, dest
) {
53 Err(_
) => return false,
55 let errors
= ocx
.select_all_or_error();
56 // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing`
57 // we would get unification errors because we're unable to look into opaque types,
58 // even if they're constrained in our current function.
60 // It seems very unlikely that this hides any bugs.
61 let _
= infcx
.inner
.borrow_mut().opaque_type_storage
.take_opaque_types();