From d2398eee0fc6ae046c8cf28ae8bf6f0f52fabb09 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 12 Aug 2020 09:08:34 +0200 Subject: [PATCH] allow escaping bound vars when normalizing `ty::Opaque` --- src/librustc_trait_selection/traits/project.rs | 7 ++----- .../traits/query/normalize.rs | 6 ++---- .../ui/mir/issue-75419-validation-impl-trait.rs | 13 +++++++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/mir/issue-75419-validation-impl-trait.rs diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 717b7e2fe574..316181ce7d4a 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -324,8 +324,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let ty = ty.super_fold_with(self); match ty.kind { - ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { - // (*) + ty::Opaque(def_id, substs) => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, @@ -353,9 +352,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } ty::Projection(ref data) if !data.has_escaping_bound_vars() => { - // (*) - - // (*) This is kind of hacky -- we need to be able to + // This is kind of hacky -- we need to be able to // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs index 59fa4c1598d4..93652329305a 100644 --- a/src/librustc_trait_selection/traits/query/normalize.rs +++ b/src/librustc_trait_selection/traits/query/normalize.rs @@ -101,8 +101,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let ty = ty.super_fold_with(self); match ty.kind { - ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { - // (*) + ty::Opaque(def_id, substs) => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, @@ -140,8 +139,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { } ty::Projection(ref data) if !data.has_escaping_bound_vars() => { - // (*) - // (*) This is kind of hacky -- we need to be able to + // This is kind of hacky -- we need to be able to // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait diff --git a/src/test/ui/mir/issue-75419-validation-impl-trait.rs b/src/test/ui/mir/issue-75419-validation-impl-trait.rs new file mode 100644 index 000000000000..a8741befb0cf --- /dev/null +++ b/src/test/ui/mir/issue-75419-validation-impl-trait.rs @@ -0,0 +1,13 @@ +// build-pass + +// This used to fail MIR validation due to the types on both sides of +// an assignment not being equal. +// The failure doesn't occur with a check-only build. + +fn iter_slice<'a, T>(xs: &'a [T]) -> impl Iterator { + xs.iter() +} + +fn main() { + iter_slice::<()> as fn(_) -> _; +}