diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7daed74e9de83..b065ace6bf5e1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -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); } } } diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr index 5c8d64fc6cb4c..f1f0d7e5907d3 100644 --- a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -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 | diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr index 6ae73d9e3a601..2f05564564cd2 100644 --- a/src/test/ui/async-await/in-trait/async-generics.stderr +++ b/src/test/ui/async-await/in-trait/async-generics.stderr @@ -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 | diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs index 3f7448cecd157..d5481d277e40a 100644 --- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs +++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs @@ -1,5 +1,4 @@ -// check-fail -// known-bug: #102682 +// check-pass // edition: 2021 #![feature(async_fn_in_trait)] diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr deleted file mode 100644 index 0f02420274333..0000000000000 --- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs index acbac471cf7e8..f298e45d2390b 100644 --- a/src/test/ui/async-await/in-trait/async-lifetimes.rs +++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs @@ -1,5 +1,4 @@ -// check-fail -// known-bug: #102682 +// check-pass // edition: 2021 #![feature(async_fn_in_trait)] diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr deleted file mode 100644 index 9a7d294bb1766..0000000000000 --- a/src/test/ui/async-await/in-trait/async-lifetimes.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/async-await/in-trait/implied-bounds.rs b/src/test/ui/async-await/in-trait/implied-bounds.rs new file mode 100644 index 0000000000000..52bceb3cc5cd6 --- /dev/null +++ b/src/test/ui/async-await/in-trait/implied-bounds.rs @@ -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() {} diff --git a/src/test/ui/impl-trait/in-trait/where-clause.rs b/src/test/ui/impl-trait/in-trait/where-clause.rs new file mode 100644 index 0000000000000..87bac519cf304 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/where-clause.rs @@ -0,0 +1,24 @@ +// check-pass +// edition: 2021 + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait Foo { + fn foo<'a>(&'a self) -> impl Debug + where + Item: 'a; +} + +impl Foo for D { + fn foo<'a>(&'a self) -> impl Debug + where + Item: 'a, + { + self.clone() + } +} + +fn main() {}