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}
;
14 ///////////////////////////////////////////////////////////////////////////
15 // OPPORTUNISTIC TYPE RESOLVER
17 /// The opportunistic type resolver can be used at any time. It simply replaces
18 /// type variables that have been unified with the things they have
19 /// been unified with (similar to `shallow_resolve`, but deep). This is
20 /// useful for printing messages etc but also required at various
21 /// points for correctness.
22 pub struct OpportunisticTypeResolver
<'a
, 'tcx
:'a
> {
23 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
26 impl<'a
, 'tcx
> OpportunisticTypeResolver
<'a
, 'tcx
> {
27 pub fn new(infcx
: &'a InferCtxt
<'a
, 'tcx
>) -> OpportunisticTypeResolver
<'a
, 'tcx
> {
28 OpportunisticTypeResolver { infcx: infcx }
32 impl<'a
, 'tcx
> ty
::fold
::TypeFolder
<'tcx
> for OpportunisticTypeResolver
<'a
, 'tcx
> {
33 fn tcx(&self) -> &TyCtxt
<'tcx
> {
37 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
38 if !t
.has_infer_types() {
39 t
// micro-optimize -- if there is nothing in this type that this fold affects...
41 let t0
= self.infcx
.shallow_resolve(t
);
42 t0
.super_fold_with(self)
47 /// The opportunistic type and region resolver is similar to the
48 /// opportunistic type resolver, but also opportunistly resolves
49 /// regions. It is useful for canonicalization.
50 pub struct OpportunisticTypeAndRegionResolver
<'a
, 'tcx
:'a
> {
51 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
54 impl<'a
, 'tcx
> OpportunisticTypeAndRegionResolver
<'a
, 'tcx
> {
55 pub fn new(infcx
: &'a InferCtxt
<'a
, 'tcx
>) -> Self {
56 OpportunisticTypeAndRegionResolver { infcx: infcx }
60 impl<'a
, 'tcx
> ty
::fold
::TypeFolder
<'tcx
> for OpportunisticTypeAndRegionResolver
<'a
, 'tcx
> {
61 fn tcx(&self) -> &TyCtxt
<'tcx
> {
65 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
67 t
// micro-optimize -- if there is nothing in this type that this fold affects...
69 let t0
= self.infcx
.shallow_resolve(t
);
70 t0
.super_fold_with(self)
74 fn fold_region(&mut self, r
: ty
::Region
) -> ty
::Region
{
76 ty
::ReVar(rid
) => self.infcx
.region_vars
.opportunistic_resolve_var(rid
),
82 ///////////////////////////////////////////////////////////////////////////
83 // FULL TYPE RESOLUTION
85 /// Full type resolution replaces all type and region variables with
86 /// their concrete results. If any variable cannot be replaced (never unified, etc)
87 /// then an `Err` result is returned.
88 pub fn fully_resolve
<'a
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
,'tcx
>, value
: &T
) -> FixupResult
<T
>
89 where T
: TypeFoldable
<'tcx
>
91 let mut full_resolver
= FullTypeResolver { infcx: infcx, err: None }
;
92 let result
= value
.fold_with(&mut full_resolver
);
93 match full_resolver
.err
{
99 // N.B. This type is not public because the protocol around checking the
100 // `err` field is not enforcable otherwise.
101 struct FullTypeResolver
<'a
, 'tcx
:'a
> {
102 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
103 err
: Option
<FixupError
>,
106 impl<'a
, 'tcx
> ty
::fold
::TypeFolder
<'tcx
> for FullTypeResolver
<'a
, 'tcx
> {
107 fn tcx(&self) -> &TyCtxt
<'tcx
> {
111 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
112 if !t
.needs_infer() {
113 t
// micro-optimize -- if there is nothing in this type that this fold affects...
115 let t
= self.infcx
.shallow_resolve(t
);
117 ty
::TyInfer(ty
::TyVar(vid
)) => {
118 self.err
= Some(FixupError
::UnresolvedTy(vid
));
121 ty
::TyInfer(ty
::IntVar(vid
)) => {
122 self.err
= Some(FixupError
::UnresolvedIntTy(vid
));
125 ty
::TyInfer(ty
::FloatVar(vid
)) => {
126 self.err
= Some(FixupError
::UnresolvedFloatTy(vid
));
130 bug
!("Unexpected type in full type resolver: {:?}", t
);
133 t
.super_fold_with(self)
139 fn fold_region(&mut self, r
: ty
::Region
) -> ty
::Region
{
141 ty
::ReVar(rid
) => self.infcx
.region_vars
.resolve_var(rid
),