Skip to content

Commit

Permalink
Rollup merge of #116663 - compiler-errors:resolve-regions, r=lcnr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fmease committed Oct 19, 2023
2 parents 89432aa + ea73f10 commit 2dd1c8f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
27 changes: 20 additions & 7 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_lint/src/async_fn_in_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {} }
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/async-await/in-trait/unconstrained-impl-region.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 2dd1c8f

Please sign in to comment.