1
Fork 0

Handle type errors in closure/generator upvar_tys

Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
This commit is contained in:
Aman Arora 2020-10-27 03:10:41 -04:00
parent 28f03ac4c0
commit f0ae24e100
7 changed files with 74 additions and 7 deletions

View file

@ -3883,6 +3883,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chalk-ir", "chalk-ir",
"either",
"measureme 9.0.0", "measureme 9.0.0",
"polonius-engine", "polonius-engine",
"rustc-rayon-core", "rustc-rayon-core",

View file

@ -8,6 +8,7 @@ edition = "2018"
doctest = false doctest = false
[dependencies] [dependencies]
either = "1.5.0"
rustc_arena = { path = "../rustc_arena" } rustc_arena = { path = "../rustc_arena" }
bitflags = "1.2.1" bitflags = "1.2.1"
tracing = "0.1" tracing = "0.1"

View file

@ -5,6 +5,8 @@
use self::InferTy::*; use self::InferTy::*;
use self::TyKind::*; use self::TyKind::*;
use either::Either;
use crate::infer::canonical::Canonical; use crate::infer::canonical::Canonical;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef}; use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::{ use crate::ty::{
@ -388,9 +390,17 @@ impl<'tcx> ClosureSubsts<'tcx> {
self.split().parent_substs 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] #[inline]
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { 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. /// Returns the tuple type representing the upvars for this closure.
@ -515,9 +525,17 @@ impl<'tcx> GeneratorSubsts<'tcx> {
self.split().witness.expect_ty() 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] #[inline]
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { 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. /// Returns the tuple type representing the upvars for this generator.
@ -660,13 +678,15 @@ pub enum UpvarSubsts<'tcx> {
} }
impl<'tcx> 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] #[inline]
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
let tupled_upvars_ty = match self { match self {
UpvarSubsts::Closure(substs) => substs.as_closure().split().tupled_upvars_ty, UpvarSubsts::Closure(substs) => Either::Left(substs.as_closure().upvar_tys()),
UpvarSubsts::Generator(substs) => substs.as_generator().split().tupled_upvars_ty, UpvarSubsts::Generator(substs) => Either::Right(substs.as_generator().upvar_tys()),
}; }
tupled_upvars_ty.expect_ty().tuple_fields()
} }
#[inline] #[inline]

View file

@ -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() {}

View file

@ -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`.

View file

@ -0,0 +1,9 @@
// edition:2018
async fn test() -> Result<(), Box<dyn std::error::Error>> {
macro!();
//~^ ERROR expected identifier, found `!`
Ok(())
}
fn main() {}

View file

@ -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