about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-10-23 08:14:31 +0200
committerGitHub <noreply@github.com>2022-10-23 08:14:31 +0200
commitff689a1404081871afd31814f31db508bcd560dc (patch)
tree747856acd945f9fbd3dd5d3e1c844c0120888107
parentb656f5e9a64d6fe0f0b75e76e6350fb08cea562d (diff)
parent419fde7a38fab7c0355d4091ddafd8d775e63f3f (diff)
downloadrust-ff689a1404081871afd31814f31db508bcd560dc.tar.gz
rust-ff689a1404081871afd31814f31db508bcd560dc.zip
Rollup merge of #103355 - compiler-errors:rpitit-default-check, r=oli-obk
Handle return-position `impl Trait` in traits properly in `register_hidden_type`

The bounds that we get by calling `bound_explicit_item_bounds` from an RPITIT have projections, not opaques, but when we're *registering* an opaque, we want to treat it like an opaque.

Coincidentally fixes #102688 as well, which makes sense, since that was failing because we were inferring an opaque type to be equal to itself (opaque cycle error => "cannot resolve opaque type").

Fixes #103352

r? ```@oli-obk```
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs14
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-type-err-2.rs13
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-type-err-2.stderr11
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-type-err.rs13
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-type-err.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs2
-rw-r--r--src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr12
7 files changed, 63 insertions, 14 deletions
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 80ecd737829..0a4ecc4c033 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,6 +1,7 @@
 use crate::errors::OpaqueHiddenTypeDiag;
 use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
 use crate::traits;
+use hir::def::DefKind;
 use hir::def_id::{DefId, LocalDefId};
 use hir::{HirId, OpaqueTyOrigin};
 use rustc_data_structures::sync::Lrc;
@@ -549,7 +550,12 @@ impl<'tcx> InferCtxt<'tcx> {
                 ty_op: |ty| match *ty.kind() {
                     // We can't normalize associated types from `rustc_infer`,
                     // but we can eagerly register inference variables for them.
-                    ty::Projection(projection_ty) if !projection_ty.has_escaping_bound_vars() => {
+                    // FIXME(RPITIT): Don't replace RPITITs with inference vars.
+                    ty::Projection(projection_ty)
+                        if !projection_ty.has_escaping_bound_vars()
+                            && tcx.def_kind(projection_ty.item_def_id)
+                                != DefKind::ImplTraitPlaceholder =>
+                    {
                         self.infer_projection(
                             param_env,
                             projection_ty,
@@ -565,6 +571,12 @@ impl<'tcx> InferCtxt<'tcx> {
                     {
                         hidden_ty
                     }
+                    // FIXME(RPITIT): This can go away when we move to associated types
+                    ty::Projection(proj)
+                        if def_id.to_def_id() == proj.item_def_id && substs == proj.substs =>
+                    {
+                        hidden_ty
+                    }
                     _ => ty,
                 },
                 lt_op: |lt| lt,
diff --git a/src/test/ui/impl-trait/in-trait/default-body-type-err-2.rs b/src/test/ui/impl-trait/in-trait/default-body-type-err-2.rs
new file mode 100644
index 00000000000..45ae2b8ad3a
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-type-err-2.rs
@@ -0,0 +1,13 @@
+// edition:2021
+
+#![allow(incomplete_features)]
+#![feature(async_fn_in_trait)]
+
+pub trait Foo {
+    async fn woopsie_async(&self) -> String {
+        42
+        //~^ ERROR mismatched types
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/src/test/ui/impl-trait/in-trait/default-body-type-err-2.stderr
new file mode 100644
index 00000000000..142b1bff1a4
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-type-err-2.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/default-body-type-err-2.rs:8:9
+   |
+LL |         42
+   |         ^^- help: try using a conversion method: `.to_string()`
+   |         |
+   |         expected struct `String`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/in-trait/default-body-type-err.rs b/src/test/ui/impl-trait/in-trait/default-body-type-err.rs
new file mode 100644
index 00000000000..ac9baf91cae
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-type-err.rs
@@ -0,0 +1,13 @@
+#![allow(incomplete_features)]
+#![feature(return_position_impl_trait_in_trait)]
+
+use std::ops::Deref;
+
+pub trait Foo {
+    fn lol(&self) -> impl Deref<Target = String> {
+        //~^ type mismatch resolving `<&i32 as Deref>::Target == String`
+        &1i32
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/default-body-type-err.stderr b/src/test/ui/impl-trait/in-trait/default-body-type-err.stderr
new file mode 100644
index 00000000000..461247a3e3f
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/default-body-type-err.stderr
@@ -0,0 +1,12 @@
+error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
+  --> $DIR/default-body-type-err.rs:7:22
+   |
+LL |     fn lol(&self) -> impl Deref<Target = String> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `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/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
index f0d407cd527..ad3cc7c2524 100644
--- a/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
+++ b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.rs
@@ -1,4 +1,4 @@
-// known-bug: #102688
+// check-pass
 // edition:2021
 
 #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
diff --git a/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr b/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr
deleted file mode 100644
index 4529d301f9e..00000000000
--- a/src/test/ui/impl-trait/in-trait/default-body-with-rpit.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0720]: cannot resolve opaque type
-  --> $DIR/default-body-with-rpit.rs:10:28
-   |
-LL |     async fn baz(&self) -> impl Debug {
-   |                            ^^^^^^^^^^ cannot resolve opaque type
-   |
-   = note: these returned values have a concrete "never" type
-   = help: this error will resolve once the item's body returns a concrete type
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0720`.