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 middle
::ty
::{self, Ty, HasTypeFlags}
;
13 use middle
::ty_fold
::{self, TypeFoldable}
;
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
, 'tcx
:'a
> {
24 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
27 impl<'a
, 'tcx
> OpportunisticTypeResolver
<'a
, 'tcx
> {
28 pub fn new(infcx
: &'a InferCtxt
<'a
, 'tcx
>) -> OpportunisticTypeResolver
<'a
, 'tcx
> {
29 OpportunisticTypeResolver { infcx: infcx }
33 impl<'a
, 'tcx
> ty_fold
::TypeFolder
<'tcx
> for OpportunisticTypeResolver
<'a
, 'tcx
> {
34 fn tcx(&self) -> &ty
::ctxt
<'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 ty_fold
::super_fold_ty(self, t0
)
48 ///////////////////////////////////////////////////////////////////////////
49 // FULL TYPE RESOLUTION
51 /// Full type resolution replaces all type and region variables with
52 /// their concrete results. If any variable cannot be replaced (never unified, etc)
53 /// then an `Err` result is returned.
54 pub fn fully_resolve
<'a
, 'tcx
, T
>(infcx
: &InferCtxt
<'a
,'tcx
>, value
: &T
) -> FixupResult
<T
>
55 where T
: TypeFoldable
<'tcx
>
57 let mut full_resolver
= FullTypeResolver { infcx: infcx, err: None }
;
58 let result
= value
.fold_with(&mut full_resolver
);
59 match full_resolver
.err
{
65 // N.B. This type is not public because the protocol around checking the
66 // `err` field is not enforcable otherwise.
67 struct FullTypeResolver
<'a
, 'tcx
:'a
> {
68 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
69 err
: Option
<FixupError
>,
72 impl<'a
, 'tcx
> ty_fold
::TypeFolder
<'tcx
> for FullTypeResolver
<'a
, 'tcx
> {
73 fn tcx(&self) -> &ty
::ctxt
<'tcx
> {
77 fn fold_ty(&mut self, t
: Ty
<'tcx
>) -> Ty
<'tcx
> {
79 t
// micro-optimize -- if there is nothing in this type that this fold affects...
81 let t
= self.infcx
.shallow_resolve(t
);
83 ty
::TyInfer(ty
::TyVar(vid
)) => {
84 self.err
= Some(FixupError
::UnresolvedTy(vid
));
87 ty
::TyInfer(ty
::IntVar(vid
)) => {
88 self.err
= Some(FixupError
::UnresolvedIntTy(vid
));
91 ty
::TyInfer(ty
::FloatVar(vid
)) => {
92 self.err
= Some(FixupError
::UnresolvedFloatTy(vid
));
96 self.infcx
.tcx
.sess
.bug(
97 &format
!("Unexpected type in full type resolver: {:?}",
101 ty_fold
::super_fold_ty(self, t
)
107 fn fold_region(&mut self, r
: ty
::Region
) -> ty
::Region
{
109 ty
::ReInfer(ty
::ReVar(rid
)) => self.infcx
.region_vars
.resolve_var(rid
),