Skip to content

Commit f0ae24e

Browse files
arora-amanroxelo
andcommitted
Handle type errors in closure/generator upvar_tys
Co-authored-by: Roxane Fruytier <[email protected]>
1 parent 28f03ac commit f0ae24e

File tree

7 files changed

+74
-7
lines changed

7 files changed

+74
-7
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3883,6 +3883,7 @@ version = "0.0.0"
38833883
dependencies = [
38843884
"bitflags",
38853885
"chalk-ir",
3886+
"either",
38863887
"measureme 9.0.0",
38873888
"polonius-engine",
38883889
"rustc-rayon-core",

compiler/rustc_middle/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2018"
88
doctest = false
99

1010
[dependencies]
11+
either = "1.5.0"
1112
rustc_arena = { path = "../rustc_arena" }
1213
bitflags = "1.2.1"
1314
tracing = "0.1"

compiler/rustc_middle/src/ty/sty.rs

+27-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use self::InferTy::*;
66
use self::TyKind::*;
77

8+
use either::Either;
9+
810
use crate::infer::canonical::Canonical;
911
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
1012
use crate::ty::{
@@ -388,9 +390,17 @@ impl<'tcx> ClosureSubsts<'tcx> {
388390
self.split().parent_substs
389391
}
390392

393+
/// Returns an iterator over the list of types of captured paths by the closure.
394+
/// In case there was a type error in figuring out the types of the captured path, an
395+
/// empty iterator is returned.
391396
#[inline]
392397
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
393-
self.tupled_upvars_ty().tuple_fields()
398+
match self.tupled_upvars_ty().kind() {
399+
TyKind::Error(_) => Either::Left(std::iter::empty()),
400+
TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()),
401+
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
402+
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
403+
}
394404
}
395405

396406
/// Returns the tuple type representing the upvars for this closure.
@@ -515,9 +525,17 @@ impl<'tcx> GeneratorSubsts<'tcx> {
515525
self.split().witness.expect_ty()
516526
}
517527

528+
/// Returns an iterator over the list of types of captured paths by the generator.
529+
/// In case there was a type error in figuring out the types of the captured path, an
530+
/// empty iterator is returned.
518531
#[inline]
519532
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
520-
self.tupled_upvars_ty().tuple_fields()
533+
match self.tupled_upvars_ty().kind() {
534+
TyKind::Error(_) => Either::Left(std::iter::empty()),
535+
TyKind::Tuple(..) => Either::Right(self.tupled_upvars_ty().tuple_fields()),
536+
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
537+
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
538+
}
521539
}
522540

523541
/// Returns the tuple type representing the upvars for this generator.
@@ -660,13 +678,15 @@ pub enum UpvarSubsts<'tcx> {
660678
}
661679

662680
impl<'tcx> UpvarSubsts<'tcx> {
681+
/// Returns an iterator over the list of types of captured paths by the closure/generator.
682+
/// In case there was a type error in figuring out the types of the captured path, an
683+
/// empty iterator is returned.
663684
#[inline]
664685
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
665-
let tupled_upvars_ty = match self {
666-
UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty,
667-
UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty,
668-
};
669-
tupled_upvars_ty.expect_ty().tuple_fields()
686+
match self {
687+
UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()),
688+
UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()),
689+
}
670690
}
671691

672692
#[inline]

src/test/ui/issues/issue-77993-1.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#[derive(Clone)]
2+
struct InGroup<F> {
3+
it: It,
4+
//~^ ERROR cannot find type `It` in this scope
5+
f: F,
6+
}
7+
fn dates_in_year() -> impl Clone {
8+
InGroup { f: |d| d }
9+
//~^ ERROR missing field `it` in initializer of `InGroup<_>`
10+
}
11+
12+
fn main() {}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0412]: cannot find type `It` in this scope
2+
--> $DIR/issue-77993-1.rs:3:9
3+
|
4+
LL | it: It,
5+
| ^^ not found in this scope
6+
7+
error[E0063]: missing field `it` in initializer of `InGroup<_>`
8+
--> $DIR/issue-77993-1.rs:8:5
9+
|
10+
LL | InGroup { f: |d| d }
11+
| ^^^^^^^ missing `it`
12+
13+
error: aborting due to 2 previous errors
14+
15+
Some errors have detailed explanations: E0063, E0412.
16+
For more information about an error, try `rustc --explain E0063`.

src/test/ui/issues/issue-77993-2.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// edition:2018
2+
3+
async fn test() -> Result<(), Box<dyn std::error::Error>> {
4+
macro!();
5+
//~^ ERROR expected identifier, found `!`
6+
Ok(())
7+
}
8+
9+
fn main() {}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected identifier, found `!`
2+
--> $DIR/issue-77993-2.rs:4:10
3+
|
4+
LL | macro!();
5+
| ^ expected identifier
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)