]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/infer/mod.rs
split ty::util and ty::adjustment
[rust.git] / src / librustc / middle / infer / mod.rs
index 61c166e11d28023d115bce1ce913e8ea723f7508..ffb631e105b3a0bf05895ed4201ff67b4c76b6cb 100644 (file)
@@ -19,6 +19,8 @@
 pub use self::freshen::TypeFreshener;
 pub use self::region_inference::{GenericKind, VerifyBound};
 
+use middle::def_id::DefId;
+use rustc_front::hir;
 use middle::free_region::FreeRegionMap;
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
 use middle::subst::Subst;
 use middle::traits::{self, FulfillmentContext, Normalized,
                      SelectionContext, ObligationCause};
-use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
-use middle::ty::{self, Ty, TypeError, HasTypeFlags};
-use middle::ty_fold::{self, TypeFolder, TypeFoldable};
-use middle::ty_relate::{Relate, RelateResult, TypeRelation};
+use middle::ty::adjustment;
+use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
+use middle::ty::{self, Ty, HasTypeFlags};
+use middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
+use middle::ty::fold::{TypeFolder, TypeFoldable};
+use middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_data_structures::unify::{self, UnificationTable};
 use std::cell::{RefCell, Ref};
 use std::fmt;
@@ -169,9 +173,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(),fmt::Error> {
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
 pub enum ValuePairs<'tcx> {
-    Types(ty::ExpectedFound<Ty<'tcx>>),
-    TraitRefs(ty::ExpectedFound<ty::TraitRef<'tcx>>),
-    PolyTraitRefs(ty::ExpectedFound<ty::PolyTraitRef<'tcx>>),
+    Types(ExpectedFound<Ty<'tcx>>),
+    TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
+    PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
 }
 
 /// The trace designates the path through inference that we took to
@@ -189,6 +193,9 @@ pub struct TypeTrace<'tcx> {
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
 pub enum SubregionOrigin<'tcx> {
+    // Marker to indicate a constraint that only arises due to new
+    // provisions from RFC 1214. This will result in a warning, not an
+    // error.
     RFC1214Subregion(Rc<SubregionOrigin<'tcx>>),
 
     // Arose from a subtyping relation
@@ -474,12 +481,12 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
 fn expected_found<T>(a_is_expected: bool,
                      a: T,
                      b: T)
-                     -> ty::ExpectedFound<T>
+                     -> ExpectedFound<T>
 {
     if a_is_expected {
-        ty::ExpectedFound {expected: a, found: b}
+        ExpectedFound {expected: a, found: b}
     } else {
-        ty::ExpectedFound {expected: b, found: a}
+        ExpectedFound {expected: b, found: a}
     }
 }
 
@@ -578,7 +585,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
 /// Returns an equivalent value with all free regions removed (note
 /// that late-bound regions remain, because they are important for
 /// subtyping, but they are anonymized and normalized as well). This
-/// is a stronger, caching version of `ty_fold::erase_regions`.
+/// is a stronger, caching version of `ty::fold::erase_regions`.
 pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
     where T : TypeFoldable<'tcx>
 {
@@ -598,7 +605,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 Some(u) => return u
             }
 
-            let t_norm = ty_fold::super_fold_ty(self, ty);
+            let t_norm = ty::fold::super_fold_ty(self, ty);
             self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm);
             return t_norm;
         }
@@ -607,7 +614,7 @@ fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
             where T : TypeFoldable<'tcx>
         {
             let u = self.tcx().anonymize_late_bound_regions(t);
-            ty_fold::super_fold_binder(self, &u)
+            ty::fold::super_fold_binder(self, &u)
         }
 
         fn fold_region(&mut self, r: ty::Region) -> ty::Region {
@@ -651,7 +658,8 @@ pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
     }
 
     pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
-        use middle::ty::UnconstrainedNumeric::{Neither, UnconstrainedInt, UnconstrainedFloat};
+        use middle::ty::error::UnconstrainedNumeric::Neither;
+        use middle::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
         match ty.sty {
             ty::TyInfer(ty::IntVar(vid)) => {
                 if self.int_unification_table.borrow_mut().has_value(vid) {
@@ -944,15 +952,6 @@ pub fn sub_poly_trait_refs(&self,
         })
     }
 
-    pub fn construct_skolemized_subst(&self,
-                                      generics: &ty::Generics<'tcx>,
-                                      snapshot: &CombinedSnapshot)
-                                      -> (subst::Substs<'tcx>, SkolemizationMap) {
-        /*! See `higher_ranked::construct_skolemized_subst` */
-
-        higher_ranked::construct_skolemized_substs(self, generics, snapshot)
-    }
-
     pub fn skolemize_late_bound_regions<T>(&self,
                                            value: &ty::Binder<T>,
                                            snapshot: &CombinedSnapshot)
@@ -982,7 +981,7 @@ pub fn plug_leaks<T>(&self,
                          snapshot: &CombinedSnapshot,
                          value: &T)
                          -> T
-        where T : TypeFoldable<'tcx>
+        where T : TypeFoldable<'tcx> + HasTypeFlags
     {
         /*! See `higher_ranked::plug_leaks` */
 
@@ -1055,7 +1054,7 @@ pub fn next_float_var_id(&self) -> FloatVid {
     }
 
     pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
-        ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
+        ty::ReVar(self.region_vars.new_region_var(origin))
     }
 
     pub fn region_vars_for_defs(&self,
@@ -1152,8 +1151,8 @@ pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
 
     /// Apply `adjustment` to the type of `expr`
     pub fn adjust_expr_ty(&self,
-                          expr: &ast::Expr,
-                          adjustment: Option<&ty::AutoAdjustment<'tcx>>)
+                          expr: &hir::Expr,
+                          adjustment: Option<&adjustment::AutoAdjustment<'tcx>>)
                           -> Ty<'tcx>
     {
         let raw_ty = self.expr_ty(expr);
@@ -1184,7 +1183,7 @@ pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
         }
     }
 
-    pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
+    pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
         match self.tables.borrow().node_types.get(&ex.id) {
             Some(&t) => t,
             None => {
@@ -1253,7 +1252,9 @@ pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
         }
     }
 
-    pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) -> T {
+    pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
+        where T: TypeFoldable<'tcx> + HasTypeFlags
+    {
         /*!
          * Where possible, replaces type/int/float variables in
          * `value` with their final value. Note that region variables
@@ -1263,6 +1264,9 @@ pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) ->
          * at will.
          */
 
+        if !value.needs_infer() {
+            return value.clone(); // avoid duplicated subst-folding
+        }
         let mut r = resolve::OpportunisticTypeResolver::new(self);
         value.fold_with(&mut r)
     }
@@ -1311,7 +1315,7 @@ pub fn type_error_message_str<M>(&self,
                                      sp: Span,
                                      mk_msg: M,
                                      actual_ty: String,
-                                     err: Option<&ty::TypeError<'tcx>>) where
+                                     err: Option<&TypeError<'tcx>>) where
         M: FnOnce(Option<String>, String) -> String,
     {
         self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
@@ -1322,7 +1326,7 @@ pub fn type_error_message_str_with_expected<M>(&self,
                                                    mk_msg: M,
                                                    expected_ty: Option<Ty<'tcx>>,
                                                    actual_ty: String,
-                                                   err: Option<&ty::TypeError<'tcx>>) where
+                                                   err: Option<&TypeError<'tcx>>) where
         M: FnOnce(Option<String>, String) -> String,
     {
         debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
@@ -1348,7 +1352,7 @@ pub fn type_error_message<M>(&self,
                                  sp: Span,
                                  mk_msg: M,
                                  actual_ty: Ty<'tcx>,
-                                 err: Option<&ty::TypeError<'tcx>>) where
+                                 err: Option<&TypeError<'tcx>>) where
         M: FnOnce(String) -> String,
     {
         let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
@@ -1367,10 +1371,10 @@ pub fn report_mismatched_types(&self,
                                    span: Span,
                                    expected: Ty<'tcx>,
                                    actual: Ty<'tcx>,
-                                   err: &ty::TypeError<'tcx>) {
+                                   err: &TypeError<'tcx>) {
         let trace = TypeTrace {
             origin: Misc(span),
-            values: Types(ty::ExpectedFound {
+            values: Types(ExpectedFound {
                 expected: expected,
                 found: actual
             })
@@ -1384,14 +1388,14 @@ pub fn report_conflicting_default_types(&self,
                                             actual: type_variable::Default<'tcx>) {
         let trace = TypeTrace {
             origin: Misc(span),
-            values: Types(ty::ExpectedFound {
+            values: Types(ExpectedFound {
                 expected: expected.ty,
                 found: actual.ty
             })
         };
 
         self.report_and_explain_type_error(trace,
-            &TypeError::TyParamDefaultMismatch(ty::ExpectedFound {
+            &TypeError::TyParamDefaultMismatch(ExpectedFound {
                 expected: expected,
                 found: actual
         }));
@@ -1405,8 +1409,7 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
         -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
         where T : TypeFoldable<'tcx>
     {
-        ty_fold::replace_late_bound_regions(
-            self.tcx,
+        self.tcx.replace_late_bound_regions(
             value,
             |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
     }
@@ -1446,16 +1449,22 @@ pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(&ty)
     }
 
-    pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
+    pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
         let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
         self.resolve_type_vars_or_error(&ty)
     }
 
     pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
         let ty = self.resolve_type_vars_if_possible(&ty);
-        !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
-        // FIXME(@jroesch): should be able to use:
-        // ty.moves_by_default(&self.parameter_environment, span)
+        if ty.needs_infer() {
+            // this can get called from typeck (by euv), and moves_by_default
+            // rightly refuses to work with inference variables, but
+            // moves_by_default has a cache, which we want to use in other
+            // cases.
+            !traits::type_known_to_meet_builtin_bound(self, ty, ty::BoundCopy, span)
+        } else {
+            ty.moves_by_default(&self.parameter_environment, span)
+        }
     }
 
     pub fn node_method_ty(&self, method_call: ty::MethodCall)
@@ -1469,7 +1478,7 @@ pub fn node_method_ty(&self, method_call: ty::MethodCall)
     }
 
     pub fn node_method_id(&self, method_call: ty::MethodCall)
-                          -> Option<ast::DefId> {
+                          -> Option<DefId> {
         self.tables
             .borrow()
             .method_map
@@ -1477,9 +1486,9 @@ pub fn node_method_id(&self, method_call: ty::MethodCall)
             .map(|method| method.def_id)
     }
 
-    pub fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+    pub fn adjustments(&self) -> Ref<NodeMap<adjustment::AutoAdjustment<'tcx>>> {
         fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
-                                        -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+                                        -> &'a NodeMap<adjustment::AutoAdjustment<'tcx>> {
             &tables.adjustments
         }
 
@@ -1503,14 +1512,14 @@ pub fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
     }
 
     pub fn closure_kind(&self,
-                        def_id: ast::DefId)
+                        def_id: DefId)
                         -> Option<ty::ClosureKind>
     {
         self.tables.borrow().closure_kinds.get(&def_id).cloned()
     }
 
     pub fn closure_type(&self,
-                        def_id: ast::DefId,
+                        def_id: DefId,
                         substs: &ty::ClosureSubsts<'tcx>)
                         -> ty::ClosureTy<'tcx>
     {
@@ -1548,7 +1557,7 @@ pub fn types(origin: TypeOrigin,
     pub fn dummy(tcx: &ty::ctxt<'tcx>) -> TypeTrace<'tcx> {
         TypeTrace {
             origin: Misc(codemap::DUMMY_SP),
-            values: Types(ty::ExpectedFound {
+            values: Types(ExpectedFound {
                 expected: tcx.types.err,
                 found: tcx.types.err,
             })