about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs43
-rw-r--r--src/test/ui/issues/issue-77993-1.rs12
-rw-r--r--src/test/ui/issues/issue-77993-1.stderr16
-rw-r--r--src/test/ui/issues/issue-77993-2.rs9
-rw-r--r--src/test/ui/issues/issue-77993-2.stderr8
5 files changed, 82 insertions, 6 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 431fa30ed0f..384d08f8348 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -388,9 +388,19 @@ 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(_) => 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.
@@ -515,9 +525,19 @@ 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(_) => 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.
@@ -660,13 +680,24 @@ 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,
+        let tupled_tys = match self {
+            UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
+            UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
         };
-        tupled_upvars_ty.expect_ty().tuple_fields()
+
+        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]
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<F> {
+    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<dyn std::error::Error>> {
+    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
+