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.
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.
11 //! Methods for normalizing when you don't care about regions (and
12 //! aren't doing type inference). If either of those things don't
13 //! apply to you, use `infcx.normalize(...)`.
15 //! The methods in this file use a `TypeFolder` to recursively process
16 //! contents, invoking the underlying
17 //! `normalize_ty_after_erasing_regions` query for each type found
18 //! within. (This underlying query is what is cached.)
20 use ty
::{self, Ty, TyCtxt}
;
21 use ty
::fold
::{TypeFoldable, TypeFolder}
;
23 impl<'cx
, 'tcx
> TyCtxt
<'cx
, 'tcx
, 'tcx
> {
24 /// Erase the regions in `value` and then fully normalize all the
25 /// types found within. The result will also have regions erased.
27 /// This is appropriate to use only after type-check: it assumes
28 /// that normalization will succeed, for example.
29 pub fn normalize_erasing_regions
<T
>(self, param_env
: ty
::ParamEnv
<'tcx
>, value
: T
) -> T
31 T
: TypeFoldable
<'tcx
>,
34 "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})",
35 unsafe { ::std::intrinsics::type_name::<T>() }
,
40 // Erase first before we do the real query -- this keeps the
41 // cache from being too polluted.
42 let value
= self.erase_regions(&value
);
43 if !value
.has_projections() {
46 value
.fold_with(&mut NormalizeAfterErasingRegionsFolder
{
53 /// If you have a `Binder<T>`, you can do this to strip out the
54 /// late-bound regions and then normalize the result, yielding up
55 /// a `T` (with regions erased). This is appropriate when the
56 /// binder is being instantiated at the call site.
58 /// NB. Currently, higher-ranked type bounds inhibit
59 /// normalization. Therefore, each time we erase them in
60 /// codegen, we need to normalize the contents.
61 pub fn normalize_erasing_late_bound_regions
<T
>(
63 param_env
: ty
::ParamEnv
<'tcx
>,
64 value
: &ty
::Binder
<T
>,
67 T
: TypeFoldable
<'tcx
>,
69 assert
!(!value
.needs_subst());
70 let value
= self.erase_late_bound_regions(value
);
71 self.normalize_erasing_regions(param_env
, value
)
75 struct NormalizeAfterErasingRegionsFolder
<'cx
, 'tcx
: 'cx
> {
76 tcx
: TyCtxt
<'cx
, 'tcx
, 'tcx
>,
77 param_env
: ty
::ParamEnv
<'tcx
>,
80 impl<'cx
, 'tcx
> TypeFolder
<'tcx
, 'tcx
> for NormalizeAfterErasingRegionsFolder
<'cx
, 'tcx
> {
81 fn tcx
<'a
>(&'a
self) -> TyCtxt
<'a
, 'tcx
, 'tcx
> {
85 fn fold_ty(&mut self, ty
: Ty
<'tcx
>) -> Ty
<'tcx
> {
86 self.tcx
.normalize_ty_after_erasing_regions(self.param_env
.and(ty
))