]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/infer/resolve.rs
Remove ty::BrFresh and new_bound
[rust.git] / src / librustc / infer / resolve.rs
index 6adbf2bcef866931c2a1f65f41396030564029ed..95bae8f2bd1afb7b4326f18be4ecf1dd3f4f296e 100644 (file)
@@ -1,27 +1,28 @@
 use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
+use crate::mir::interpret::ConstValue;
+use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags};
 use crate::ty::fold::{TypeFolder, TypeVisitor};
 
 ///////////////////////////////////////////////////////////////////////////
-// OPPORTUNISTIC TYPE RESOLVER
+// OPPORTUNISTIC VAR RESOLVER
 
-/// The opportunistic type resolver can be used at any time. It simply replaces
-/// type variables that have been unified with the things they have
+/// The opportunistic resolver can be used at any time. It simply replaces
+/// type/const variables that have been unified with the things they have
 /// been unified with (similar to `shallow_resolve`, but deep). This is
 /// useful for printing messages etc but also required at various
 /// points for correctness.
-pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+pub struct OpportunisticVarResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> OpportunisticVarResolver<'a, 'gcx, 'tcx> {
     #[inline]
     pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
-        OpportunisticTypeResolver { infcx }
+        OpportunisticVarResolver { infcx }
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gcx, 'tcx> {
     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
         self.infcx.tcx
     }
@@ -30,8 +31,17 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         if !t.has_infer_types() {
             t // micro-optimize -- if there is nothing in this type that this fold affects...
         } else {
-            let t0 = self.infcx.shallow_resolve(t);
-            t0.super_fold_with(self)
+            let t = self.infcx.shallow_resolve(t);
+            t.super_fold_with(self)
+        }
+    }
+
+    fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
+        if !ct.has_type_flags(TypeFlags::HAS_CT_INFER) {
+            ct // micro-optimize -- if there is nothing in this const that this fold affects...
+        } else {
+            let ct = self.infcx.shallow_resolve(ct);
+            ct.super_fold_with(self)
         }
     }
 }
@@ -72,6 +82,15 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
                 r,
         }
     }
+
+    fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+        if !ct.needs_infer() {
+            ct // micro-optimize -- if there is nothing in this const that this fold affects...
+        } else {
+            let c0 = self.infcx.shallow_resolve(ct);
+            c0.super_fold_with(self)
+        }
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -136,7 +155,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
 /// their concrete results. If any variable cannot be replaced (never unified, etc)
 /// then an `Err` result is returned.
 pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                        value: &T) -> FixupResult<T>
+                                        value: &T) -> FixupResult<'tcx, T>
     where T : TypeFoldable<'tcx>
 {
     let mut full_resolver = FullTypeResolver { infcx: infcx, err: None };
@@ -151,7 +170,7 @@ pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 // `err` field is not enforcable otherwise.
 struct FullTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
-    err: Option<FixupError>,
+    err: Option<FixupError<'tcx>>,
 }
 
 impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> {
@@ -199,4 +218,25 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
             _ => r,
         }
     }
+
+    fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+        if !c.needs_infer() && !ty::keep_local(&c) {
+            c // micro-optimize -- if there is nothing in this const that this fold affects...
+              // ^ we need to have the `keep_local` check to un-default
+              // defaulted tuples.
+        } else {
+            let c = self.infcx.shallow_resolve(c);
+            match c.val {
+                ConstValue::Infer(InferConst::Var(vid)) => {
+                    self.err = Some(FixupError::UnresolvedConst(vid));
+                    return self.tcx().consts.err;
+                }
+                ConstValue::Infer(InferConst::Fresh(_)) => {
+                    bug!("Unexpected const in full const resolver: {:?}", c);
+                }
+                _ => {}
+            }
+            c.super_fold_with(self)
+        }
+    }
 }