]> git.proxmox.com Git - rustc.git/blame - src/librustc/infer/resolve.rs
New upstream version 1.12.1+dfsg1
[rustc.git] / src / librustc / infer / resolve.rs
CommitLineData
1a4d82fc
JJ
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.
4//
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.
10
c1a9b12d 11use super::{InferCtxt, FixupError, FixupResult};
54a0048b 12use ty::{self, Ty, TyCtxt, TypeFoldable};
a7813a04 13use ty::fold::TypeFolder;
1a4d82fc
JJ
14
15///////////////////////////////////////////////////////////////////////////
16// OPPORTUNISTIC TYPE RESOLVER
17
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.
a7813a04
XL
23pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
24 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
1a4d82fc
JJ
25}
26
a7813a04
XL
27impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
28 pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
1a4d82fc
JJ
29 OpportunisticTypeResolver { infcx: infcx }
30 }
31}
32
a7813a04
XL
33impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
34 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
1a4d82fc
JJ
35 self.infcx.tcx
36 }
37
38 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
c1a9b12d 39 if !t.has_infer_types() {
1a4d82fc
JJ
40 t // micro-optimize -- if there is nothing in this type that this fold affects...
41 } else {
42 let t0 = self.infcx.shallow_resolve(t);
9cc50fc6
SL
43 t0.super_fold_with(self)
44 }
45 }
46}
47
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.
a7813a04
XL
51pub struct OpportunisticTypeAndRegionResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
52 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
9cc50fc6
SL
53}
54
a7813a04
XL
55impl<'a, 'gcx, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'gcx, 'tcx> {
56 pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
9cc50fc6
SL
57 OpportunisticTypeAndRegionResolver { infcx: infcx }
58 }
59}
60
a7813a04
XL
61impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolver<'a, 'gcx, 'tcx> {
62 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
9cc50fc6
SL
63 self.infcx.tcx
64 }
65
66 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
67 if !t.needs_infer() {
68 t // micro-optimize -- if there is nothing in this type that this fold affects...
69 } else {
70 let t0 = self.infcx.shallow_resolve(t);
71 t0.super_fold_with(self)
72 }
73 }
74
75 fn fold_region(&mut self, r: ty::Region) -> ty::Region {
76 match r {
77 ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
78 _ => r,
1a4d82fc
JJ
79 }
80 }
81}
82
83///////////////////////////////////////////////////////////////////////////
84// FULL TYPE RESOLUTION
85
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.
a7813a04
XL
89pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
90 value: &T) -> FixupResult<T>
1a4d82fc
JJ
91 where T : TypeFoldable<'tcx>
92{
93 let mut full_resolver = FullTypeResolver { infcx: infcx, err: None };
94 let result = value.fold_with(&mut full_resolver);
95 match full_resolver.err {
96 None => Ok(result),
97 Some(e) => Err(e),
98 }
99}
100
101// N.B. This type is not public because the protocol around checking the
102// `err` field is not enforcable otherwise.
a7813a04
XL
103struct FullTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
104 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
c1a9b12d 105 err: Option<FixupError>,
1a4d82fc
JJ
106}
107
a7813a04
XL
108impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> {
109 fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
1a4d82fc
JJ
110 self.infcx.tcx
111 }
112
113 fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
c1a9b12d 114 if !t.needs_infer() {
1a4d82fc
JJ
115 t // micro-optimize -- if there is nothing in this type that this fold affects...
116 } else {
117 let t = self.infcx.shallow_resolve(t);
118 match t.sty {
62682a34 119 ty::TyInfer(ty::TyVar(vid)) => {
c1a9b12d 120 self.err = Some(FixupError::UnresolvedTy(vid));
1a4d82fc
JJ
121 self.tcx().types.err
122 }
62682a34 123 ty::TyInfer(ty::IntVar(vid)) => {
c1a9b12d 124 self.err = Some(FixupError::UnresolvedIntTy(vid));
1a4d82fc
JJ
125 self.tcx().types.err
126 }
62682a34 127 ty::TyInfer(ty::FloatVar(vid)) => {
c1a9b12d 128 self.err = Some(FixupError::UnresolvedFloatTy(vid));
1a4d82fc
JJ
129 self.tcx().types.err
130 }
62682a34 131 ty::TyInfer(_) => {
54a0048b 132 bug!("Unexpected type in full type resolver: {:?}", t);
1a4d82fc
JJ
133 }
134 _ => {
9cc50fc6 135 t.super_fold_with(self)
1a4d82fc
JJ
136 }
137 }
138 }
139 }
140
141 fn fold_region(&mut self, r: ty::Region) -> ty::Region {
142 match r {
e9174d1e 143 ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
1a4d82fc
JJ
144 _ => r,
145 }
146 }
147}