about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-03-16 01:11:04 +0000
committerMichael Goulet <michael@errs.io>2023-03-16 01:59:41 +0000
commitff7c3b854df3f61380261fa2d32cd4c0843ebc83 (patch)
tree26f558e576f0cc33aac1af6c456a980417fc6c93
parent0949da8f4e309ac5e5035250bd662dfdbd5c32b4 (diff)
downloadrust-ff7c3b854df3f61380261fa2d32cd4c0843ebc83.tar.gz
rust-ff7c3b854df3f61380261fa2d32cd4c0843ebc83.zip
Don't install default opaque projection predicates in RPITIT associated type's param-env
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs28
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs22
-rw-r--r--tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr (renamed from tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr (renamed from tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err-2.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr (renamed from tests/ui/impl-trait/in-trait/default-body-type-err.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/default-body.rs2
12 files changed, 78 insertions, 21 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 1687aff56d6..c063b766227 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1545,21 +1545,27 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
     if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
         && assoc_item.container == ty::AssocItemContainer::TraitContainer
     {
+        // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering
+        // strategy, we can't just call `check_associated_item` on the new RPITITs,
+        // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
+        // That's because we need to check that the bounds of the RPITIT hold using
+        // the special substs that we create during opaque type lowering, otherwise we're
+        // getting a bunch of early bound and free regions mixed up... Haven't looked too
+        // deep into this, though.
         for arg in fn_output.walk() {
             if let ty::GenericArgKind::Type(ty) = arg.unpack()
-                && let ty::Alias(ty::Opaque, proj) = ty.kind()
-                // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) we should just check
-                // `tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder`. Right now
-                // `check_associated_type_bounds` is not called for RPITITs synthesized as
-                // associated types. See `check_mod_type_wf` to see how synthesized associated
-                // types are missed due to iterating over HIR.
-                && tcx.is_impl_trait_in_trait(proj.def_id)
-                && tcx.impl_trait_in_trait_parent_fn(proj.def_id) == fn_def_id.to_def_id()
+                // RPITITs are always eagerly normalized into opaques, so always look for an
+                // opaque here.
+                && let ty::Alias(ty::Opaque, opaque_ty) = ty.kind()
+                && let Some(opaque_def_id) = opaque_ty.def_id.as_local()
+                && let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty()
+                && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin
+                && source == fn_def_id
             {
-                let span = tcx.def_span(proj.def_id);
-                let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id);
+                let span = tcx.def_span(opaque_ty.def_id);
+                let bounds = wfcx.tcx().explicit_item_bounds(opaque_ty.def_id);
                 let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
-                    let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
+                    let bound = ty::EarlyBinder(bound).subst(tcx, opaque_ty.substs);
                     let normalized_bound = wfcx.normalize(span, None, bound);
                     traits::wf::predicate_obligations(
                         wfcx.infcx,
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index df4b8543ba6..9fed1e57c92 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -117,16 +117,22 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
 
 /// See `ParamEnv` struct definition for details.
 fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
-    // When computing the param_env of an RPITIT, copy param_env of the containing function. The
-    // synthesized associated type doesn't have extra predicates to assume.
-    if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
-        return tcx.param_env(fn_def_id);
-    }
-
     // Compute the bounds on Self and the type parameters.
     let ty::InstantiatedPredicates { mut predicates, .. } =
         tcx.predicates_of(def_id).instantiate_identity(tcx);
 
+    // When computing the param_env of an RPITIT, use predicates of the containing function,
+    // *except* for the additional assumption that the RPITIT normalizes to the trait method's
+    // default opaque type. This is needed to properly check the item bounds of the assoc
+    // type hold (`check_type_bounds`), since that method already installs a similar projection
+    // bound, so they will conflict.
+    // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): I don't like this, we should
+    // at least be making sure that the generics in RPITITs and their parent fn don't
+    // get out of alignment, or else we do actually need to substitute these predicates.
+    if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
+        predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates;
+    }
+
     // Finally, we have to normalize the bounds in the environment, in
     // case they contain any associated type projections. This process
     // can yield errors if the put in illegal associated types, like
@@ -160,7 +166,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     }
 
     let local_did = def_id.as_local();
-    let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
+    // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This isn't correct for
+    // RPITITs in const trait fn.
+    let hir_id = local_did.and_then(|def_id| tcx.opt_local_def_id_to_hir_id(def_id));
 
     // FIXME(consts): This is not exactly in line with the constness query.
     let constness = match hir_id {
diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr
index d681ecf25e8..05c025cc169 100644
--- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr
+++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/box-coerce-span-in-default.rs:3:12
+  --> $DIR/box-coerce-span-in-default.rs:5:12
    |
 LL | #![feature(return_position_impl_trait_in_trait)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr
new file mode 100644
index 00000000000..05c025cc169
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/box-coerce-span-in-default.rs:5:12
+   |
+LL | #![feature(return_position_impl_trait_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs
index a4d483dee7a..163bb4fcf77 100644
--- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs
+++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 //~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr
index cc3bdf0e571..85450e3b0a0 100644
--- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/default-body-type-err-2.rs:8:9
+  --> $DIR/default-body-type-err-2.rs:10:9
    |
 LL |         42
    |         ^^- help: try using a conversion method: `.to_string()`
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr
new file mode 100644
index 00000000000..85450e3b0a0
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/default-body-type-err-2.rs:10:9
+   |
+LL |         42
+   |         ^^- help: try using a conversion method: `.to_string()`
+   |         |
+   |         expected `String`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs
index 45ae2b8ad3a..62323776310 100644
--- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs
@@ -1,4 +1,6 @@
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![allow(incomplete_features)]
 #![feature(async_fn_in_trait)]
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr
index 4742eb37d3e..c949168a377 100644
--- a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
-  --> $DIR/default-body-type-err.rs:7:22
+  --> $DIR/default-body-type-err.rs:10:22
    |
 LL |     fn lol(&self) -> impl Deref<Target = String> {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr
new file mode 100644
index 00000000000..c949168a377
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr
@@ -0,0 +1,12 @@
+error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
+  --> $DIR/default-body-type-err.rs:10:22
+   |
+LL |     fn lol(&self) -> impl Deref<Target = String> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
+LL |
+LL |         &1i32
+   |         ----- return type was inferred to be `&i32` here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.rs b/tests/ui/impl-trait/in-trait/default-body-type-err.rs
index ac9baf91cae..9bd5b777989 100644
--- a/tests/ui/impl-trait/in-trait/default-body-type-err.rs
+++ b/tests/ui/impl-trait/in-trait/default-body-type-err.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![allow(incomplete_features)]
 #![feature(return_position_impl_trait_in_trait)]
 
diff --git a/tests/ui/impl-trait/in-trait/default-body.rs b/tests/ui/impl-trait/in-trait/default-body.rs
index b0baf5bb10d..ab6a51c6bcb 100644
--- a/tests/ui/impl-trait/in-trait/default-body.rs
+++ b/tests/ui/impl-trait/in-trait/default-body.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]