diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 34 |
2 files changed, 28 insertions, 7 deletions
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 66532ea02f3..0d5fbf16a58 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -8,6 +8,7 @@ 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 0fd48d09282..96a8902a76c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -5,6 +5,8 @@ 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::{ @@ -388,9 +390,17 @@ impl<'tcx> ClosureSubsts<'tcx> { self.split().parent_substs } + /// Returns an iterator over the list of types of captured paths by the closure. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - self.tupled_upvars_ty().tuple_fields() + match self.tupled_upvars_ty().kind() { + TyKind::Error(_) => Either::Left(std::iter::empty()), + TyKind::Tuple(..) => Either::Right(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), + } } /// Returns the tuple type representing the upvars for this closure. @@ -515,9 +525,17 @@ impl<'tcx> GeneratorSubsts<'tcx> { self.split().witness.expect_ty() } + /// Returns an iterator over the list of types of captured paths by the generator. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - self.tupled_upvars_ty().tuple_fields() + match self.tupled_upvars_ty().kind() { + TyKind::Error(_) => Either::Left(std::iter::empty()), + TyKind::Tuple(..) => Either::Right(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), + } } /// Returns the tuple type representing the upvars for this generator. @@ -660,13 +678,15 @@ pub enum UpvarSubsts<'tcx> { } impl<'tcx> UpvarSubsts<'tcx> { + /// Returns an iterator over the list of types of captured paths by the closure/generator. + /// In case there was a type error in figuring out the types of the captured path, an + /// empty iterator is returned. #[inline] pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { - let tupled_upvars_ty = match self { - UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty, - UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty, - }; - tupled_upvars_ty.expect_ty().tuple_fields() + match self { + UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()), + UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()), + } } #[inline] |
