about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-13 15:03:40 +0000
committerbors <bors@rust-lang.org>2020-08-13 15:03:40 +0000
commit0a49057dd35d9bd2fcc9760a054809c30eee2a58 (patch)
tree80aafda241509fe2dda8d2da018593c5d2b8f357
parenta0c290f951076d781b0ff08370445517446cee05 (diff)
parentd2398eee0fc6ae046c8cf28ae8bf6f0f52fabb09 (diff)
downloadrust-0a49057dd35d9bd2fcc9760a054809c30eee2a58.tar.gz
rust-0a49057dd35d9bd2fcc9760a054809c30eee2a58.zip
Auto merge of #75443 - lcnr:opaque-normalize, r=nikomatsakis
allow escaping bound vars when normalizing `ty::Opaque`

implements https://github.com/rust-lang/rust/issues/75313#issuecomment-672216146 and fixes #75313

cc @eddyb @RalfJung

r? @nikomatsakis
-rw-r--r--src/librustc_trait_selection/traits/project.rs7
-rw-r--r--src/librustc_trait_selection/traits/query/normalize.rs6
-rw-r--r--src/test/ui/mir/issue-75419-validation-impl-trait.rs13
3 files changed, 17 insertions, 9 deletions
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index 717b7e2fe57..316181ce7d4 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 59fa4c1598d..93652329305 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 00000000000..a8741befb0c
--- /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<Item = &'a T> {
+    xs.iter()
+}
+
+fn main() {
+    iter_slice::<()> as fn(_) -> _;
+}