From f0ae24e100392dd9958f2717df364552d34d7914 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Tue, 27 Oct 2020 03:10:41 -0400 Subject: [PATCH 1/2] Handle type errors in closure/generator upvar_tys Co-authored-by: Roxane Fruytier --- Cargo.lock | 1 + compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/ty/sty.rs | 34 ++++++++++++++++++++----- src/test/ui/issues/issue-77993-1.rs | 12 +++++++++ src/test/ui/issues/issue-77993-1.stderr | 16 ++++++++++++ src/test/ui/issues/issue-77993-2.rs | 9 +++++++ src/test/ui/issues/issue-77993-2.stderr | 8 ++++++ 7 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/issues/issue-77993-1.rs create mode 100644 src/test/ui/issues/issue-77993-1.stderr create mode 100644 src/test/ui/issues/issue-77993-2.rs create mode 100644 src/test/ui/issues/issue-77993-2.stderr diff --git a/Cargo.lock b/Cargo.lock index 65d20190c0d..6f925b50533 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3883,6 +3883,7 @@ 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 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> + '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> + '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> + '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] diff --git a/src/test/ui/issues/issue-77993-1.rs b/src/test/ui/issues/issue-77993-1.rs new file mode 100644 index 00000000000..515b3bc09f0 --- /dev/null +++ b/src/test/ui/issues/issue-77993-1.rs @@ -0,0 +1,12 @@ +#[derive(Clone)] +struct InGroup { + it: It, + //~^ ERROR cannot find type `It` in this scope + f: F, +} +fn dates_in_year() -> impl Clone { + InGroup { f: |d| d } + //~^ ERROR missing field `it` in initializer of `InGroup<_>` +} + +fn main() {} diff --git a/src/test/ui/issues/issue-77993-1.stderr b/src/test/ui/issues/issue-77993-1.stderr new file mode 100644 index 00000000000..3dc78ba6f85 --- /dev/null +++ b/src/test/ui/issues/issue-77993-1.stderr @@ -0,0 +1,16 @@ +error[E0412]: cannot find type `It` in this scope + --> $DIR/issue-77993-1.rs:3:9 + | +LL | it: It, + | ^^ not found in this scope + +error[E0063]: missing field `it` in initializer of `InGroup<_>` + --> $DIR/issue-77993-1.rs:8:5 + | +LL | InGroup { f: |d| d } + | ^^^^^^^ missing `it` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0063, E0412. +For more information about an error, try `rustc --explain E0063`. diff --git a/src/test/ui/issues/issue-77993-2.rs b/src/test/ui/issues/issue-77993-2.rs new file mode 100644 index 00000000000..4d554a0a1d0 --- /dev/null +++ b/src/test/ui/issues/issue-77993-2.rs @@ -0,0 +1,9 @@ +// edition:2018 + +async fn test() -> Result<(), Box> { + macro!(); + //~^ ERROR expected identifier, found `!` + Ok(()) +} + +fn main() {} diff --git a/src/test/ui/issues/issue-77993-2.stderr b/src/test/ui/issues/issue-77993-2.stderr new file mode 100644 index 00000000000..64b378f83fc --- /dev/null +++ b/src/test/ui/issues/issue-77993-2.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `!` + --> $DIR/issue-77993-2.rs:4:10 + | +LL | macro!(); + | ^ expected identifier + +error: aborting due to previous error + From 5229571a059a21be2f4a1d87a6641ca855e31143 Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 27 Oct 2020 18:32:50 -0400 Subject: [PATCH 2/2] Address comments --- Cargo.lock | 1 - compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/ty/sty.rs | 29 ++++++++++++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) 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> + '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> + '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> + '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]