]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/mod.rs
Auto merge of #61492 - RalfJung:const-qualif-comments, r=eddyb
[rust.git] / src / librustc_typeck / check / mod.rs
index 3ada80b3e8b7015e03df59364917ae815ec77cbd..0b558a20ed47e2a088984afbe59891221892acc5 100644 (file)
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_target::spec::abi::Abi;
 use rustc::infer::opaque_types::OpaqueTypeDecl;
-use rustc::infer::type_variable::{TypeVariableOrigin};
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc::middle::region;
 use rustc::mir::interpret::{ConstValue, GlobalId};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
 use rustc::ty::{
-    self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
+    self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
     ToPolyTraitRef, ToPredicate, RegionKind, UserType
 };
 use rustc::ty::adjustment::{
@@ -365,7 +366,12 @@ fn only_has_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>> {
     /// hard constraint exists, creates a fresh type variable.
     fn coercion_target_type(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, span: Span) -> Ty<'tcx> {
         self.only_has_type(fcx)
-            .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span)))
+            .unwrap_or_else(|| {
+                fcx.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span,
+                })
+            })
     }
 }
 
@@ -518,10 +524,10 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     /// eventually).
     param_env: ty::ParamEnv<'tcx>,
 
-    // Number of errors that had been reported when we started
-    // checking this function. On exit, if we find that *more* errors
-    // have been reported, we will skip regionck and other work that
-    // expects the types within the function to be consistent.
+    /// Number of errors that had been reported when we started
+    /// checking this function. On exit, if we find that *more* errors
+    /// have been reported, we will skip regionck and other work that
+    /// expects the types within the function to be consistent.
     err_count_on_creation: usize,
 
     ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
@@ -930,7 +936,10 @@ fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>)
         match ty_opt {
             None => {
                 // infer the variable's type
-                let var_ty = self.fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
+                let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span,
+                });
                 self.fcx.locals.borrow_mut().insert(nid, LocalTy {
                     decl_ty: var_ty,
                     revealed_ty: var_ty
@@ -1064,7 +1073,10 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     let span = body.value.span;
 
     if body.is_generator && can_be_generator.is_some() {
-        let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
+        let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::TypeInference,
+            span,
+        });
         fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
         fcx.yield_ty = Some(yield_ty);
     }
@@ -1098,7 +1110,10 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     // This ensures that all nested generators appear before the entry of this generator.
     // resolve_generator_interiors relies on this property.
     let gen_ty = if can_be_generator.is_some() && body.is_generator {
-        let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
+        let interior = fcx.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::MiscVariable,
+            span,
+        });
         fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
         Some(GeneratorTypes {
             yield_ty: fcx.yield_ty.unwrap(),
@@ -1136,7 +1151,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     let mut actual_return_ty = coercion.complete(&fcx);
     if actual_return_ty.is_never() {
         actual_return_ty = fcx.next_diverging_ty_var(
-            TypeVariableOrigin::DivergingFn(span));
+            TypeVariableOrigin {
+                kind: TypeVariableOriginKind::DivergingFn,
+                span,
+            },
+        );
     }
     fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
 
@@ -1920,8 +1939,11 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
         })
     }
 
-    fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
-                -> Option<ty::Region<'tcx>> {
+    fn re_infer(
+        &self,
+        def: Option<&ty::GenericParamDef>,
+        span: Span,
+    ) -> Option<ty::Region<'tcx>> {
         let v = match def {
             Some(def) => infer::EarlyBoundRegion(span, def.name),
             None => infer::MiscVariable(span)
@@ -1929,17 +1951,37 @@ fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
         Some(self.next_region_var(v))
     }
 
-    fn ty_infer(&self, span: Span) -> Ty<'tcx> {
-        self.next_ty_var(TypeVariableOrigin::TypeInference(span))
+    fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
+        if let Some(param) = param {
+            if let UnpackedKind::Type(ty) = self.var_for_def(span, param).unpack() {
+                return ty;
+            }
+            unreachable!()
+        } else {
+            self.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::TypeInference,
+                span,
+            })
+        }
     }
 
-    fn ty_infer_for_def(&self,
-                        ty_param_def: &ty::GenericParamDef,
-                        span: Span) -> Ty<'tcx> {
-        if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
-            return ty;
+    fn ct_infer(
+        &self,
+        ty: Ty<'tcx>,
+        param: Option<&ty::GenericParamDef>,
+        span: Span,
+    ) -> &'tcx Const<'tcx> {
+        if let Some(param) = param {
+            if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
+                return ct;
+            }
+            unreachable!()
+        } else {
+            self.next_const_var(ty, ConstVariableOrigin {
+                kind: ConstVariableOriginKind::ConstInference,
+                span,
+            })
         }
-        unreachable!()
     }
 
     fn projected_ty_from_poly_trait_ref(&self,
@@ -2638,7 +2680,10 @@ fn try_index_step(&self,
             // If some lookup succeeds, write callee into table and extract index/element
             // type from the method signature.
             // If some lookup succeeded, install method in table
-            let input_ty = self.next_ty_var(TypeVariableOrigin::AutoDeref(base_expr.span));
+            let input_ty = self.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::AutoDeref,
+                span: base_expr.span,
+            });
             let method = self.try_overloaded_place_op(
                 expr.span, self_ty, &[input_ty], needs, PlaceOp::Index);
 
@@ -3136,7 +3181,11 @@ fn check_expr_meets_expectation_or_error(&self,
             assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
                     "expression with never type wound up being adjusted");
             let adj_ty = self.next_diverging_ty_var(
-                TypeVariableOrigin::AdjustmentType(expr.span));
+                TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::AdjustmentType,
+                    span: expr.span,
+                },
+            );
             self.apply_adjustments(expr, vec![Adjustment {
                 kind: Adjust::NeverToAny,
                 target: adj_ty
@@ -4362,8 +4411,12 @@ fn check_expr_kind(
                 });
 
                 let element_ty = if !args.is_empty() {
-                    let coerce_to = uty.unwrap_or_else(
-                        || self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span)));
+                    let coerce_to = uty.unwrap_or_else(|| {
+                        self.next_ty_var(TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span: expr.span,
+                        })
+                    });
                     let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
                     assert_eq!(self.diverges.get(), Diverges::Maybe);
                     for e in args {
@@ -4373,7 +4426,10 @@ fn check_expr_kind(
                     }
                     coerce.complete(self)
                 } else {
-                    self.next_ty_var(TypeVariableOrigin::TypeInference(expr.span))
+                    self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::TypeInference,
+                        span: expr.span,
+                    })
                 };
                 tcx.mk_array(element_ty, args.len() as u64)
             }
@@ -4409,7 +4465,10 @@ fn check_expr_kind(
                         (uty, uty)
                     }
                     None => {
-                        let ty = self.next_ty_var(TypeVariableOrigin::MiscVariable(element.span));
+                        let ty = self.next_ty_var(TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::MiscVariable,
+                            span: element.span,
+                        });
                         let element_ty = self.check_expr_has_type_or_error(&element, ty);
                         (element_ty, ty)
                     }
@@ -5381,10 +5440,10 @@ pub fn instantiate_value_path(&self,
                     if !infer_args_for_err.contains(&index) {
                         // Check whether the user has provided generic arguments.
                         if let Some(ref data) = segments[index].args {
-                            return (Some(data), segments[index].infer_types);
+                            return (Some(data), segments[index].infer_args);
                         }
                     }
-                    return (None, segments[index].infer_types);
+                    return (None, segments[index].infer_args);
                 }
 
                 (None, true)
@@ -5405,13 +5464,13 @@ pub fn instantiate_value_path(&self,
                 }
             },
             // Provide substitutions for parameters for which arguments are inferred.
-            |substs, param, infer_types| {
+            |substs, param, infer_args| {
                 match param.kind {
                     GenericParamDefKind::Lifetime => {
-                        self.re_infer(span, Some(param)).unwrap().into()
+                        self.re_infer(Some(param), span).unwrap().into()
                     }
                     GenericParamDefKind::Type { has_default, .. } => {
-                        if !infer_types && has_default {
+                        if !infer_args && has_default {
                             // If we have a default, then we it doesn't matter that we're not
                             // inferring the type arguments: we provide the default where any
                             // is missing.