Rollup merge of #105247 - cjgillot:issue-102682, r=compiler-errors

Use parent function WfCheckingContext to check RPITIT.

WF-check for RPITIT was done in the opaque type's param-env, so it could not benefit from assumed wf types from the function's parameters.

cc `@compiler-errors` since you chose that param-env in fd2766e7fd

Fixes https://github.com/rust-lang/rust/issues/102682
Fixes https://github.com/rust-lang/rust/issues/104908
Fixes https://github.com/rust-lang/rust/issues/102552
Fixes https://github.com/rust-lang/rust/issues/104529
This commit is contained in:
Matthias Krüger 2022-12-04 16:25:34 +01:00 committed by GitHub
commit d055d6ad5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 75 deletions

View File

@ -1544,7 +1544,7 @@ fn check_fn_or_method<'tcx>(
check_where_clauses(wfcx, span, def_id);
check_return_position_impl_trait_in_trait_bounds(
tcx,
wfcx,
def_id,
sig.output(),
hir_decl.output.span(),
@ -1580,13 +1580,14 @@ fn check_fn_or_method<'tcx>(
/// Basically `check_associated_type_bounds`, but separated for now and should be
/// deduplicated when RPITITs get lowered into real associated items.
#[tracing::instrument(level = "trace", skip(tcx))]
#[tracing::instrument(level = "trace", skip(wfcx))]
fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
wfcx: &WfCheckingCtxt<'_, 'tcx>,
fn_def_id: LocalDefId,
fn_output: Ty<'tcx>,
span: Span,
) {
let tcx = wfcx.tcx();
if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
{
@ -1596,22 +1597,20 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
{
// Create a new context, since we want the opaque's ParamEnv and not the parent's.
let span = tcx.def_span(proj.item_def_id);
enter_wf_checking_ctxt(tcx, span, proj.item_def_id.expect_local(), |wfcx| {
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_id,
normalized_bound,
bound_span,
)
});
wfcx.register_obligations(wf_obligations);
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_id,
normalized_bound,
bound_span,
)
});
wfcx.register_obligations(wf_obligations);
}
}
}

View File

@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^
|
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^
| ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:28
|
@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^
| ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:28
|

View File

@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^
|
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics.rs:9:18
|
LL | async fn foo(&self) -> &(T, U);
| ^
| ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:28
|
@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^
|
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics.rs:9:18
|
LL | async fn foo(&self) -> &(T, U);
| ^
| ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:28
|

View File

@ -1,5 +1,4 @@
// check-fail
// known-bug: #102682
// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]

View File

@ -1,23 +0,0 @@
error[E0309]: the parameter type `Self` may not live long enough
--> $DIR/async-lifetimes-and-bounds.rs:11:43
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `Self: 'a`...
= note: ...so that the reference type `&'a Self` does not outlive the data it points at
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/async-lifetimes-and-bounds.rs:11:43
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
| ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
LL | trait MyTrait<'a, 'b, T: 'b> {
| ++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0309`.

View File

@ -1,5 +1,4 @@
// check-fail
// known-bug: #102682
// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]

View File

@ -1,23 +0,0 @@
error[E0309]: the parameter type `Self` may not live long enough
--> $DIR/async-lifetimes.rs:9:43
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
| ^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `Self: 'a`...
= note: ...so that the reference type `&'a Self` does not outlive the data it points at
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/async-lifetimes.rs:9:43
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
| ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
LL | trait MyTrait<'a, 'b, T: 'b> {
| ++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0309`.

View File

@ -0,0 +1,13 @@
// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]
trait TcpStack {
type Connection<'a>: Sized where Self: 'a;
fn connect<'a>(&'a self) -> Self::Connection<'a>;
async fn async_connect<'a>(&'a self) -> Self::Connection<'a>;
}
fn main() {}

View File

@ -0,0 +1,24 @@
// check-pass
// edition: 2021
#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
use std::fmt::Debug;
trait Foo<Item> {
fn foo<'a>(&'a self) -> impl Debug
where
Item: 'a;
}
impl<Item, D: Debug + Clone> Foo<Item> for D {
fn foo<'a>(&'a self) -> impl Debug
where
Item: 'a,
{
self.clone()
}
}
fn main() {}