1 // Copyright 2012 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 use super::{InferCtxt, FixupError, FixupResult}
;
12 use ty
::{self, Ty, TyCtxt, TypeFoldable}
;
13 use ty
::fold
::TypeFolder
;
15 ///////////////////////////////////////////////////////////////////////////
16 // OPPORTUNISTIC TYPE RESOLVER
18 /// The opportunistic type resolver can be used at any time. It simply replaces
19 /// type variables that have been unified with the things they have
20 /// been unified with (similar to `shallow_resolve`, but deep). This is
21 /// useful for printing messages etc but also required at various
22 /// points for correctness.
23 pub struct OpportunisticTypeResolver
<'a
, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
> {
24 infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>,
27 impl<'a
, 'gcx
, 'tcx
> OpportunisticTypeResolver
<'a
, 'gcx
, 'tcx
> {
28 pub fn new(infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>) -> Self {
29 OpportunisticTypeResolver { infcx: infcx }
33 impl<'a
, 'gcx
, 'tcx
> TypeFolder
<'gcx
, 'tcx
> for OpportunisticTypeResolver
<'a
, 'gcx
, 'tcx
> {
34 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'b
, 'gcx
, 'tcx
> {
38 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
39 if !t
.has_infer_types() {
40 t
// micro-optimize -- if there is nothing in this type that this fold affects...
42 let t0
= self.infcx
.shallow_resolve(t
);
43 t0
.super_fold_with(self)
48 /// The opportunistic type and region resolver is similar to the
49 /// opportunistic type resolver, but also opportunistly resolves
50 /// regions. It is useful for canonicalization.
51 pub struct OpportunisticTypeAndRegionResolver
<'a
, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
> {
52 infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>,
55 impl<'a
, 'gcx
, 'tcx
> OpportunisticTypeAndRegionResolver
<'a
, 'gcx
, 'tcx
> {
56 pub fn new(infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>) -> Self {
57 OpportunisticTypeAndRegionResolver { infcx: infcx }
61 impl<'a
, 'gcx
, 'tcx
> TypeFolder
<'gcx
, 'tcx
> for OpportunisticTypeAndRegionResolver
<'a
, 'gcx
, 'tcx
> {
62 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'b
, 'gcx
, 'tcx
> {
66 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
68 t
// micro-optimize -- if there is nothing in this type that this fold affects...
70 let t0
= self.infcx
.shallow_resolve(t
);
71 t0
.super_fold_with(self)
75 fn fold_region(&mut self, r
: ty
::Region
<'tcx
>) -> ty
::Region
<'tcx
> {
77 ty
::ReVar(rid
) => self.infcx
.region_vars
.opportunistic_resolve_var(rid
),
83 ///////////////////////////////////////////////////////////////////////////
84 // FULL TYPE RESOLUTION
86 /// Full type resolution replaces all type and region variables with
87 /// their concrete results. If any variable cannot be replaced (never unified, etc)
88 /// then an `Err` result is returned.
89 pub fn fully_resolve
<'a
, 'gcx
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
, 'gcx
, 'tcx
>,
90 value
: &T
) -> FixupResult
<T
>
91 where T
: TypeFoldable
<'tcx
>
93 let mut full_resolver
= FullTypeResolver { infcx: infcx, err: None }
;
94 let result
= value
.fold_with(&mut full_resolver
);
95 match full_resolver
.err
{
101 // N.B. This type is not public because the protocol around checking the
102 // `err` field is not enforcable otherwise.
103 struct FullTypeResolver
<'a
, 'gcx
: 'a
+'tcx
, 'tcx
: 'a
> {
104 infcx
: &'a InferCtxt
<'a
, 'gcx
, 'tcx
>,
105 err
: Option
<FixupError
>,
108 impl<'a
, 'gcx
, 'tcx
> TypeFolder
<'gcx
, 'tcx
> for FullTypeResolver
<'a
, 'gcx
, 'tcx
> {
109 fn tcx
<'b
>(&'b
self) -> TyCtxt
<'b
, 'gcx
, 'tcx
> {
113 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
114 if !t
.needs_infer() {
115 t
// micro-optimize -- if there is nothing in this type that this fold affects...
117 let t
= self.infcx
.shallow_resolve(t
);
119 ty
::TyInfer(ty
::TyVar(vid
)) => {
120 self.err
= Some(FixupError
::UnresolvedTy(vid
));
123 ty
::TyInfer(ty
::IntVar(vid
)) => {
124 self.err
= Some(FixupError
::UnresolvedIntTy(vid
));
127 ty
::TyInfer(ty
::FloatVar(vid
)) => {
128 self.err
= Some(FixupError
::UnresolvedFloatTy(vid
));
132 bug
!("Unexpected type in full type resolver: {:?}", t
);
135 t
.super_fold_with(self)
141 fn fold_region(&mut self, r
: ty
::Region
<'tcx
>) -> ty
::Region
<'tcx
> {
143 ty
::ReVar(rid
) => self.infcx
.region_vars
.resolve_var(rid
),