diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 7c61db21e613a..42f53bf1e95e8 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -21,7 +21,8 @@
 //!
 //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
-use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, ConstVariableOrigin};
+use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
+use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
 use crate::mir::interpret::ConstValue;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_macros::HashStable;
@@ -365,7 +366,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
                 let ty = match ty_kind {
                     CanonicalTyVarKind::General(ui) => {
                         self.next_ty_var_in_universe(
-                            TypeVariableOrigin::MiscVariable(span),
+                            TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::MiscVariable,
+                                span,
+                            },
                             universe_map(ui)
                         )
                     }
@@ -403,10 +407,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
             CanonicalVarKind::Const(ui) => {
                 self.next_const_var_in_universe(
                     self.next_ty_var_in_universe(
-                        TypeVariableOrigin::MiscVariable(span),
+                        TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::MiscVariable,
+                            span,
+                        },
                         universe_map(ui),
                     ),
-                    ConstVariableOrigin::MiscVariable(span),
+                    ConstVariableOrigin {
+                        kind: ConstVariableOriginKind::MiscVariable,
+                        span,
+                    },
                     universe_map(ui),
                 ).into()
             }
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index 048c0a7a8fd0a..4e6d534b940c1 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -28,7 +28,8 @@ use super::{InferCtxt, MiscVariable, TypeTrace};
 use super::lub::Lub;
 use super::sub::Sub;
 use super::type_variable::TypeVariableValue;
-use super::unify_key::{ConstVarValue, ConstVariableValue, ConstVariableOrigin};
+use super::unify_key::{ConstVarValue, ConstVariableValue};
+use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 
 use crate::hir::def_id::DefId;
 use crate::mir::interpret::ConstValue;
@@ -165,7 +166,10 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
         self.const_unification_table
             .borrow_mut()
             .unify_var_value(vid, ConstVarValue {
-                origin: ConstVariableOrigin::ConstInference(DUMMY_SP),
+                origin: ConstVariableOrigin {
+                    kind: ConstVariableOriginKind::ConstInference,
+                    span: DUMMY_SP,
+                },
                 val: ConstVariableValue::Known { value },
             })
             .map_err(|e| const_unification_error(vid_is_expected, e))?;
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index b3ff25a695f2f..16b6792fde48f 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -2,7 +2,7 @@ use crate::hir::def::Namespace;
 use crate::hir::{self, Local, Pat, Body, HirId};
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::infer::InferCtxt;
-use crate::infer::type_variable::TypeVariableOrigin;
+use crate::infer::type_variable::TypeVariableOriginKind;
 use crate::ty::{self, Ty, Infer, TyVar};
 use crate::ty::print::Print;
 use syntax::source_map::CompilerDesugaringKind;
@@ -83,8 +83,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     ) -> String {
         if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
             let ty_vars = self.type_variables.borrow();
-            if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
-                *ty_vars.var_origin(ty_vid) {
+            if let TypeVariableOriginKind::TypeParameterDefinition(name) =
+                ty_vars.var_origin(ty_vid).kind {
                 return name.to_string();
             }
         }
@@ -122,8 +122,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
             let ty_vars = self.type_variables.borrow();
             let getter = move |ty_vid| {
-                if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
-                    *ty_vars.var_origin(ty_vid) {
+                if let TypeVariableOriginKind::TypeParameterDefinition(name) =
+                    ty_vars.var_origin(ty_vid).kind {
                     return Some(name.to_string());
                 }
                 None
diff --git a/src/librustc/infer/lattice.rs b/src/librustc/infer/lattice.rs
index e40bb97240763..0053b4c762118 100644
--- a/src/librustc/infer/lattice.rs
+++ b/src/librustc/infer/lattice.rs
@@ -20,7 +20,7 @@
 //! a lattice.
 
 use super::InferCtxt;
-use super::type_variable::TypeVariableOrigin;
+use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 use crate::traits::ObligationCause;
 use crate::ty::TyVar;
@@ -79,12 +79,18 @@ pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,
         // iterate on the subtype obligations that are returned, but I
         // think this suffices. -nmatsakis
         (&ty::Infer(TyVar(..)), _) => {
-            let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span));
+            let v = infcx.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::LatticeVariable,
+                span: this.cause().span,
+            });
             this.relate_bound(v, b, a)?;
             Ok(v)
         }
         (_, &ty::Infer(TyVar(..))) => {
-            let v = infcx.next_ty_var(TypeVariableOrigin::LatticeVariable(this.cause().span));
+            let v = infcx.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::LatticeVariable,
+                span: this.cause().span,
+            });
             this.relate_bound(v, a, b)?;
             Ok(v)
         }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 4414e677fb5b7..0a422c6643397 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -39,8 +39,8 @@ use self::lexical_region_resolve::LexicalRegionResolutions;
 use self::outlives::env::OutlivesEnvironment;
 use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound};
 use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
-use self::type_variable::TypeVariableOrigin;
-use self::unify_key::{ToType, ConstVariableOrigin};
+use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use self::unify_key::{ToType, ConstVariableOrigin, ConstVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
@@ -1110,13 +1110,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 let ty_var_id = self.type_variables.borrow_mut().new_var(
                     self.universe(),
                     false,
-                    TypeVariableOrigin::TypeParameterDefinition(span, param.name),
+                    TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::TypeParameterDefinition(param.name),
+                        span,
+                    },
                 );
 
                 self.tcx.mk_ty_var(ty_var_id).into()
             }
             GenericParamDefKind::Const { .. } => {
-                let origin = ConstVariableOrigin::ConstParameterDefinition(span, param.name);
+                let origin = ConstVariableOrigin {
+                    kind: ConstVariableOriginKind::ConstParameterDefinition(param.name),
+                    span,
+                };
                 let const_var_id =
                     self.const_unification_table
                         .borrow_mut()
@@ -1412,8 +1418,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         T: TypeFoldable<'tcx>
     {
         let fld_r = |br| self.next_region_var(LateBoundRegion(span, br, lbrct));
-        let fld_t = |_| self.next_ty_var(TypeVariableOrigin::MiscVariable(span));
-        let fld_c = |_, ty| self.next_const_var(ty, ConstVariableOrigin::MiscVariable(span));
+        let fld_t = |_| {
+            self.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::MiscVariable,
+                span,
+            })
+        };
+        let fld_c = |_, ty| self.next_const_var(ty, ConstVariableOrigin {
+            kind: ConstVariableOriginKind:: MiscVariable,
+            span,
+        });
         self.tcx.replace_bound_vars(value, fld_r, fld_t, fld_c)
     }
 
diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs
index a3800d8f0754e..c00fa9b1b09b3 100644
--- a/src/librustc/infer/nll_relate/mod.rs
+++ b/src/librustc/infer/nll_relate/mod.rs
@@ -270,15 +270,16 @@ where
         projection_ty: ty::ProjectionTy<'tcx>,
         value_ty: Ty<'tcx>,
     ) -> Ty<'tcx> {
-        use crate::infer::type_variable::TypeVariableOrigin;
+        use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
         use crate::traits::WhereClause;
         use syntax_pos::DUMMY_SP;
 
         match value_ty.sty {
             ty::Projection(other_projection_ty) => {
-                let var = self
-                    .infcx
-                    .next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP));
+                let var = self.infcx.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span: DUMMY_SP,
+                });
                 self.relate_projection_ty(projection_ty, var);
                 self.relate_projection_ty(other_projection_ty, var);
                 var
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index 220b7b5fa67fe..f90dc6ead41c7 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -4,7 +4,7 @@ use syntax_pos::Span;
 use crate::hir::def_id::DefId;
 use crate::hir;
 use crate::hir::Node;
-use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin};
+use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::outlives::free_region_map::FreeRegionRelations;
 use crate::traits::{self, PredicateObligation};
 use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind};
@@ -864,7 +864,10 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
             return opaque_defn.concrete_ty;
         }
         let span = tcx.def_span(def_id);
-        let ty_var = infcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
+        let ty_var = infcx.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::TypeInference,
+            span,
+        });
 
         let predicates_of = tcx.predicates_of(def_id);
         debug!(
diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs
index 95bae8f2bd1af..f487e7c8def0c 100644
--- a/src/librustc/infer/resolve.rs
+++ b/src/librustc/infer/resolve.rs
@@ -1,4 +1,5 @@
-use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin};
+use super::{InferCtxt, FixupError, FixupResult, Span};
+use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::mir::interpret::ConstValue;
 use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags};
 use crate::ty::fold::{TypeFolder, TypeVisitor};
@@ -123,8 +124,10 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx>
                 let ty_var_span =
                 if let ty::TyVar(ty_vid) = infer_ty {
                     let ty_vars = self.infcx.type_variables.borrow();
-                    if let TypeVariableOrigin::TypeParameterDefinition(span, _name)
-                        = *ty_vars.var_origin(ty_vid)
+                    if let TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::TypeParameterDefinition(_),
+                        span,
+                    } = *ty_vars.var_origin(ty_vid)
                     {
                         Some(span)
                     } else {
diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs
index 88933312b0d40..dcafb0f3976ff 100644
--- a/src/librustc/infer/type_variable.rs
+++ b/src/librustc/infer/type_variable.rs
@@ -37,25 +37,28 @@ pub struct TypeVariableTable<'tcx> {
     sub_relations: ut::UnificationTable<ut::InPlace<ty::TyVid>>,
 }
 
+#[derive(Copy, Clone, Debug)]
+pub struct TypeVariableOrigin {
+    pub kind: TypeVariableOriginKind,
+    pub span: Span,
+}
+
 /// Reasons to create a type inference variable
 #[derive(Copy, Clone, Debug)]
-pub enum TypeVariableOrigin {
-    MiscVariable(Span),
-    NormalizeProjectionType(Span),
-    TypeInference(Span),
-    TypeParameterDefinition(Span, InternedString),
-
-    /// one of the upvars or closure kind parameters in a `ClosureSubsts`
-    /// (before it has been determined)
-    ClosureSynthetic(Span),
-    SubstitutionPlaceholder(Span),
-    AutoDeref(Span),
-    AdjustmentType(Span),
-    DivergingStmt(Span),
-    DivergingBlockExpr(Span),
-    DivergingFn(Span),
-    LatticeVariable(Span),
-    Generalized(ty::TyVid),
+pub enum TypeVariableOriginKind {
+    MiscVariable,
+    NormalizeProjectionType,
+    TypeInference,
+    TypeParameterDefinition(InternedString),
+
+    /// One of the upvars or closure kind parameters in a `ClosureSubsts`
+    /// (before it has been determined).
+    ClosureSynthetic,
+    SubstitutionPlaceholder,
+    AutoDeref,
+    AdjustmentType,
+    DivergingFn,
+    LatticeVariable,
 }
 
 struct TypeVariableData {
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
index 678a45a84e9ea..287a666fc8043 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc/infer/unify_key.rs
@@ -79,13 +79,19 @@ impl ToType for FloatVarValue {
 
 // Generic consts.
 
+#[derive(Copy, Clone, Debug)]
+pub struct ConstVariableOrigin {
+    pub kind: ConstVariableOriginKind,
+    pub span: Span,
+}
+
 /// Reasons to create a const inference variable
 #[derive(Copy, Clone, Debug)]
-pub enum ConstVariableOrigin {
-    MiscVariable(Span),
-    ConstInference(Span),
-    ConstParameterDefinition(Span, InternedString),
-    SubstitutionPlaceholder(Span),
+pub enum ConstVariableOriginKind {
+    MiscVariable,
+    ConstInference,
+    ConstParameterDefinition(InternedString),
+    SubstitutionPlaceholder,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -159,7 +165,10 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
         }?;
 
         Ok(ConstVarValue {
-            origin: ConstVariableOrigin::ConstInference(DUMMY_SP),
+            origin: ConstVariableOrigin {
+                kind: ConstVariableOriginKind::ConstInference,
+                span: DUMMY_SP,
+            },
             val,
         })
     }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 95312d55b3be1..7cb7947ae412a 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -21,7 +21,7 @@ use crate::hir;
 use crate::hir::Node;
 use crate::hir::def_id::DefId;
 use crate::infer::{self, InferCtxt};
-use crate::infer::type_variable::TypeVariableOrigin;
+use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::session::DiagnosticMessageId;
 use crate::ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use crate::ty::GenericParamDefKind;
@@ -1464,7 +1464,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     let infcx = self.infcx;
                     self.var_map.entry(ty).or_insert_with(||
                         infcx.next_ty_var(
-                            TypeVariableOrigin::TypeParameterDefinition(DUMMY_SP, name)))
+                            TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::TypeParameterDefinition(name),
+                                span: DUMMY_SP,
+                            }
+                        )
+                    )
                 } else {
                     ty.super_fold_with(self)
                 }
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 88bb3172c5e79..3ee6d0cc67b45 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -14,7 +14,7 @@ use super::util;
 
 use crate::hir::def_id::DefId;
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
-use crate::infer::type_variable::TypeVariableOrigin;
+use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::mir::interpret::{GlobalId, ConstValue};
 use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
 use rustc_macros::HashStable;
@@ -475,7 +475,11 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
             let tcx = selcx.infcx().tcx;
             let def_id = projection_ty.item_def_id;
             let ty_var = selcx.infcx().next_ty_var(
-                TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
+                TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::NormalizeProjectionType,
+                    span: tcx.def_span(def_id),
+                },
+            );
             let projection = ty::Binder::dummy(ty::ProjectionPredicate {
                 projection_ty,
                 ty: ty_var
@@ -810,7 +814,11 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc
     let tcx = selcx.infcx().tcx;
     let def_id = projection_ty.item_def_id;
     let new_value = selcx.infcx().next_ty_var(
-        TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
+        TypeVariableOrigin {
+            kind: TypeVariableOriginKind::NormalizeProjectionType,
+            span: tcx.def_span(def_id),
+        },
+    );
     Normalized {
         value: new_value,
         obligations: vec![trait_obligation]
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index ad3b2f985d702..6a6ec8679018f 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -26,7 +26,7 @@ use rustc::hir::def_id::DefId;
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::outlives::env::RegionBoundPairs;
 use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
 use rustc::mir::tcx::PlaceTy;
 use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
@@ -2209,7 +2209,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.sty {
                     let ty_right = right.ty(mir, tcx);
                     let common_ty = self.infcx.next_ty_var(
-                        TypeVariableOrigin::MiscVariable(mir.source_info(location).span),
+                        TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::MiscVariable,
+                            span: mir.source_info(location).span,
+                        }
                     );
                     self.sub_types(
                         common_ty,
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 9607427baa9ec..3fea080f299e5 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -6,7 +6,7 @@ use rustc::hir::{self, PatKind, Pat, ExprKind};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::infer;
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{ObligationCause, ObligationCauseCode};
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::subst::Kind;
@@ -311,9 +311,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let max_len = cmp::max(expected_len, elements.len());
 
                 let element_tys_iter = (0..max_len).map(|_| {
-                    // FIXME: `MiscVariable` for now -- obtaining the span and name information
-                    // from all tuple elements isn't trivial.
-                    Kind::from(self.next_ty_var(TypeVariableOrigin::TypeInference(pat.span)))
+                    Kind::from(self.next_ty_var(
+                        // FIXME: `MiscVariable` for now -- obtaining the span and name information
+                        // from all tuple elements isn't trivial.
+                        TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span: pat.span,
+                        },
+                    ))
                 });
                 let element_tys = tcx.mk_substs(element_tys_iter);
                 let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
@@ -339,7 +344,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
             }
             PatKind::Box(ref inner) => {
-                let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));
+                let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span: inner.span,
+                });
                 let uniq_ty = tcx.mk_box(inner_ty);
 
                 if self.check_dereferencable(pat.span, expected, &inner) {
@@ -372,7 +380,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         }
                         _ => {
                             let inner_ty = self.next_ty_var(
-                                TypeVariableOrigin::TypeInference(inner.span));
+                                TypeVariableOrigin {
+                                    kind: TypeVariableOriginKind::TypeInference,
+                                    span: inner.span,
+                                }
+                            );
                             let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
                             let region = self.next_region_var(infer::PatternRegion(pat.span));
                             let rptr_ty = tcx.mk_ref(region, mt);
@@ -685,7 +697,10 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 // arm for inconsistent arms or to the whole match when a `()` type
                 // is required).
                 Expectation::ExpectHasType(ety) if ety != self.tcx.mk_unit() => ety,
-                _ => self.next_ty_var(TypeVariableOrigin::MiscVariable(expr.span)),
+                _ => self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span: expr.span,
+                }),
             };
             CoerceMany::with_coercion_sites(coerce_first, arms)
         };
@@ -994,7 +1009,10 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
             // ...but otherwise we want to use any supertype of the
             // discriminant. This is sort of a workaround, see note (*) in
             // `check_pat` for some details.
-            let discrim_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(discrim.span));
+            let discrim_ty = self.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::TypeInference,
+                span: discrim.span,
+            });
             self.check_expr_has_type_or_error(discrim, discrim_ty);
             discrim_ty
         }
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index a6cd157dc03de..8d32583da4b22 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -8,7 +8,7 @@ use hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::{infer, traits};
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_target::spec::abi;
 use syntax::ast::Ident;
 use syntax_pos::Span;
@@ -193,9 +193,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             let opt_input_types = opt_arg_exprs.map(|arg_exprs| [self.tcx.mk_tup(
                 arg_exprs
                 .iter()
-                .map(|e| self.next_ty_var(
-                    TypeVariableOrigin::TypeInference(e.span)
-                ))
+                .map(|e| {
+                    self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::TypeInference,
+                        span: e.span,
+                    })
+                })
             )]);
             let opt_input_types = opt_input_types.as_ref().map(AsRef::as_ref);
 
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 419f61b0ee2c0..4427a83562e9e 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -7,7 +7,7 @@ use crate::middle::region;
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferOk, InferResult};
 use rustc::infer::LateBoundRegionConversionTime;
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::Obligation;
 use rustc::traits::error_reporting::ArgKind;
 use rustc::ty::{self, Ty, GenericParamDefKind};
@@ -102,7 +102,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     span_bug!(expr.span, "closure has lifetime param")
                 }
                 GenericParamDefKind::Type { .. } => {
-                    self.infcx.next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)).into()
+                    self.infcx.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::ClosureSynthetic,
+                        span: expr.span,
+                    }).into()
                 }
                 GenericParamDefKind::Const => {
                     span_bug!(expr.span, "closure has const param")
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index d64be24f7538f..c35b43a5daeb5 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -55,7 +55,7 @@ use errors::DiagnosticBuilder;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::infer::{Coercion, InferResult, InferOk};
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 use rustc::ty::adjustment::{
     Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast
@@ -176,7 +176,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
                 // micro-optimization: no need for this if `b` is
                 // already resolved in some way.
                 let diverging_ty = self.next_diverging_ty_var(
-                    TypeVariableOrigin::AdjustmentType(self.cause.span));
+                    TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::AdjustmentType,
+                        span: self.cause.span,
+                    },
+                );
                 self.unify_and(&b, &diverging_ty, simple(Adjust::NeverToAny))
             } else {
                 success(simple(Adjust::NeverToAny)(b), b, vec![])
@@ -511,7 +515,10 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
         // the `CoerceUnsized` target type and the expected type.
         // We only have the latter, so we use an inference variable
         // for the former and let type inference do the rest.
-        let origin = TypeVariableOrigin::MiscVariable(self.cause.span);
+        let origin = TypeVariableOrigin {
+            kind: TypeVariableOriginKind::MiscVariable,
+            span: self.cause.span,
+        };
         let coerce_target = self.next_ty_var(origin);
         let mut coercion = self.unify_and(coerce_target, target, |target| {
             let unsize = Adjustment {
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 898c15fc77ff7..e55da40a4c21c 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -20,8 +20,8 @@ use rustc::traits::query::method_autoderef::{CandidateStep, MethodAutoderefSteps
 use rustc::traits::query::method_autoderef::{MethodAutoderefBadTy};
 use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable};
 use rustc::ty::GenericParamDefKind;
-use rustc::infer::type_variable::TypeVariableOrigin;
-use rustc::infer::unify_key::ConstVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc::util::nodemap::FxHashSet;
 use rustc::infer::{self, InferOk};
 use rustc::infer::canonical::{Canonical, QueryResponse};
@@ -1573,12 +1573,17 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
             match param.kind {
                 GenericParamDefKind::Lifetime => self.tcx.lifetimes.re_erased.into(),
                 GenericParamDefKind::Type { .. } => {
-                    self.next_ty_var(TypeVariableOrigin::SubstitutionPlaceholder(
-                        self.tcx.def_span(def_id))).into()
+                    self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::SubstitutionPlaceholder,
+                        span: self.tcx.def_span(def_id),
+                    }).into()
                 }
                 GenericParamDefKind::Const { .. } => {
                     let span = self.tcx.def_span(def_id);
-                    let origin = ConstVariableOrigin::SubstitutionPlaceholder(span);
+                    let origin = ConstVariableOrigin {
+                        kind: ConstVariableOriginKind::SubstitutionPlaceholder,
+                        span,
+                    };
                     self.next_const_var(self.tcx.type_of(param.def_id), origin).into()
                 }
             }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index f05e0d31582fa..82ccd3a866248 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -11,7 +11,7 @@ use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::hir::map as hir_map;
 use rustc::hir::print;
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::Obligation;
 use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
 use rustc::ty::print::with_crate_prefix;
@@ -43,7 +43,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 self.autoderef(span, ty).any(|(ty, _)| {
                     self.probe(|_| {
                         let fn_once_substs = tcx.mk_substs_trait(ty, &[
-                            self.next_ty_var(TypeVariableOrigin::MiscVariable(span)).into()
+                            self.next_ty_var(TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::MiscVariable,
+                                span,
+                            }).into()
                         ]);
                         let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
                         let poly_trait_ref = trait_ref.to_poly_trait_ref();
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3ada80b3e8b70..3286336c0f501 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -99,7 +99,7 @@ use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 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::middle::region;
 use rustc::mir::interpret::{ConstValue, GlobalId};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
@@ -365,7 +365,12 @@ impl<'a, 'gcx, 'tcx> Expectation<'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,
+                })
+            })
     }
 }
 
@@ -930,7 +935,10 @@ impl<'a, 'gcx, 'tcx> GatherLocalsVisitor<'a, 'gcx, '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 +1072,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 +1109,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 +1150,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);
 
@@ -1930,7 +1948,10 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn ty_infer(&self, span: Span) -> Ty<'tcx> {
-        self.next_ty_var(TypeVariableOrigin::TypeInference(span))
+        self.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::TypeInference,
+            span,
+        })
     }
 
     fn ty_infer_for_def(&self,
@@ -2638,7 +2659,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // 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 +3160,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             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 +4390,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 });
 
                 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 +4405,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     }
                     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 +4444,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         (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)
                     }
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 0bab63582aaa1..51a9103f73d8b 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -5,7 +5,7 @@ use super::method::MethodCallee;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::TyKind::{Ref, Adt, FnDef, Str, Uint, Never, Tuple, Char, Array};
 use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
-use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use errors::{self,Applicability};
 use syntax_pos::Span;
 use syntax::ast::Ident;
@@ -163,7 +163,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // e.g., adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
                 // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
                 let lhs_ty = self.check_expr_with_needs(lhs_expr, Needs::None);
-                let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
+                let fresh_var = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span: lhs_expr.span,
+                });
                 self.demand_coerce(lhs_expr, lhs_ty, fresh_var,  AllowTwoPhase::No)
             }
             IsAssign::Yes => {
@@ -182,7 +185,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // using this variable as the expected type, which sometimes lets
         // us do better coercions than we would be able to do otherwise,
         // particularly for things like `String + &String`.
-        let rhs_ty_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(rhs_expr.span));
+        let rhs_ty_var = self.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::MiscVariable,
+            span: rhs_expr.span,
+        });
 
         let result = self.lookup_op_method(lhs_ty, &[rhs_ty_var], Op::Binary(op, is_assign));