about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-10-19 04:34:45 +0200
committerGitHub <noreply@github.com>2023-10-19 04:34:45 +0200
commit2dd1c8f693f5cc0cb75e151045bfe3f429ff8db4 (patch)
tree4d2b049836254696cafd49899fbbde18ab8743fe
parent89432aadcb3174a0d7611557fa9b1ef05c72b920 (diff)
parentea73f10867e104ec5bb0ef2e83c2e330adc16758 (diff)
downloadrust-2dd1c8f693f5cc0cb75e151045bfe3f429ff8db4.tar.gz
rust-2dd1c8f693f5cc0cb75e151045bfe3f429ff8db4.zip
Rollup merge of #116663 - compiler-errors:resolve-regions, r=lcnr
Don't ICE when encountering unresolved regions in `fully_resolve`

We can encounter unresolved regions due to unconstrained impl lifetime arguments because `collect_return_position_impl_trait_in_trait_tys` runs before WF actually checks that the impl is well-formed.

Fixes #116525
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs27
-rw-r--r--compiler/rustc_lint/src/async_fn_in_trait.rs1
-rw-r--r--tests/ui/async-await/in-trait/unconstrained-impl-region.rs19
-rw-r--r--tests/ui/async-await/in-trait/unconstrained-impl-region.stderr9
4 files changed, 48 insertions, 8 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index aeb3177af02..8ffcf1fce9c 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -36,7 +36,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtx
 use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
 use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
 use rustc_span::symbol::Symbol;
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 
 use std::cell::{Cell, RefCell};
 use std::fmt;
@@ -1422,12 +1422,25 @@ impl<'tcx> InferCtxt<'tcx> {
     /// This method is idempotent, but it not typically not invoked
     /// except during the writeback phase.
     pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> FixupResult<'tcx, T> {
-        let value = resolve::fully_resolve(self, value);
-        assert!(
-            value.as_ref().map_or(true, |value| !value.has_infer()),
-            "`{value:?}` is not fully resolved"
-        );
-        value
+        match resolve::fully_resolve(self, value) {
+            Ok(value) => {
+                if value.has_non_region_infer() {
+                    bug!("`{value:?}` is not fully resolved");
+                }
+                if value.has_infer_regions() {
+                    let guar = self
+                        .tcx
+                        .sess
+                        .delay_span_bug(DUMMY_SP, format!("`{value:?}` is not fully resolved"));
+                    Ok(self.tcx.fold_regions(value, |re, _| {
+                        if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
+                    }))
+                } else {
+                    Ok(value)
+                }
+            }
+            Err(e) => Err(e),
+        }
     }
 
     // Instantiates the bound variables in a given binder with fresh inference
diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs
index 2a49a003da1..51213647361 100644
--- a/compiler/rustc_lint/src/async_fn_in_trait.rs
+++ b/compiler/rustc_lint/src/async_fn_in_trait.rs
@@ -58,7 +58,6 @@ declare_lint! {
     ///
     ///
     /// ```rust
-    /// # #![feature(return_position_impl_trait_in_trait)]
     /// use core::future::Future;
     /// pub trait Trait {
     ///     fn method(&self) -> impl Future<Output = ()> + Send { async {} }
diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.rs b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs
new file mode 100644
index 00000000000..c06f9f005f1
--- /dev/null
+++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs
@@ -0,0 +1,19 @@
+// edition: 2021
+
+pub(crate) trait Inbox<M> {
+    async fn next(self) -> M;
+}
+
+pub(crate) trait Actor: Sized {
+    type Message;
+
+    async fn on_mount(self, _: impl Inbox<Self::Message>);
+}
+
+impl<'a> Actor for () {
+//~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+    type Message = &'a ();
+    async fn on_mount(self, _: impl Inbox<&'a ()>) {}
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr
new file mode 100644
index 00000000000..2cb0da2e8bc
--- /dev/null
+++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/unconstrained-impl-region.rs:13:6
+   |
+LL | impl<'a> Actor for () {
+   |      ^^ unconstrained lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.