diff --git a/Cargo.lock b/Cargo.lock
index 6f925b50533..65d20190c0d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3883,7 +3883,6 @@ version = "0.0.0"
 dependencies = [
  "bitflags",
  "chalk-ir",
- "either",
  "measureme 9.0.0",
  "polonius-engine",
  "rustc-rayon-core",
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 0d5fbf16a58..66532ea02f3 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -8,7 +8,6 @@ edition = "2018"
 doctest = false
 
 [dependencies]
-either = "1.5.0"
 rustc_arena = { path = "../rustc_arena" }
 bitflags = "1.2.1"
 tracing = "0.1"
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 96a8902a76c..564028c33b1 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -5,8 +5,6 @@
 use self::InferTy::*;
 use self::TyKind::*;
 
-use either::Either;
-
 use crate::infer::canonical::Canonical;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
 use crate::ty::{
@@ -396,11 +394,13 @@ impl<'tcx> ClosureSubsts<'tcx> {
     #[inline]
     pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         match self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => Either::Left(std::iter::empty()),
-            TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Error(_) => None,
+            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
+        .into_iter()
+        .flatten()
     }
 
     /// Returns the tuple type representing the upvars for this closure.
@@ -531,11 +531,13 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     #[inline]
     pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         match self.tupled_upvars_ty().kind() {
-            TyKind::Error(_) => Either::Left(std::iter::empty()),
-            TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Error(_) => None,
+            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
             TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
             ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
+        .into_iter()
+        .flatten()
     }
 
     /// Returns the tuple type representing the upvars for this generator.
@@ -683,10 +685,19 @@ impl<'tcx> UpvarSubsts<'tcx> {
     /// empty iterator is returned.
     #[inline]
     pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
-        match self {
-            UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()),
-            UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()),
+        let tupled_tys = match self {
+            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
+            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
+        };
+
+        match tupled_tys.kind() {
+            TyKind::Error(_) => None,
+            TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
+            TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
+            ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
         }
+        .into_iter()
+        .flatten()
     }
 
     #[inline]