Add variances to RPITITs

This commit is contained in:
Michael Goulet 2024-09-29 13:41:13 -04:00 committed by Jubilee Young
parent b7297ac440
commit a7dc98733d
21 changed files with 242 additions and 169 deletions

View File

@ -5,6 +5,7 @@
use itertools::Itertools;
use rustc_arena::DroplessArena;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::Providers;
@ -63,8 +64,29 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
let crate_map = tcx.crate_variances(());
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
}
DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
return variance_of_opaque(
tcx,
opaque_def_id.expect_local(),
ForceCaptureTraitArgs::Yes,
);
}
None | Some(ty::ImplTraitInTraitData::Impl { .. }) => {}
},
DefKind::OpaqueTy => {
return variance_of_opaque(tcx, item_def_id);
let force_capture_trait_args = if let hir::OpaqueTyOrigin::FnReturn {
parent: _,
in_trait_or_impl: Some(hir::RpitContext::Trait),
} =
tcx.hir_node_by_def_id(item_def_id).expect_opaque_ty().origin
{
ForceCaptureTraitArgs::Yes
} else {
ForceCaptureTraitArgs::No
};
return variance_of_opaque(tcx, item_def_id, force_capture_trait_args);
}
_ => {}
}
@ -73,8 +95,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
}
#[derive(Debug, Copy, Clone)]
enum ForceCaptureTraitArgs {
Yes,
No,
}
#[instrument(level = "trace", skip(tcx), ret)]
fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
fn variance_of_opaque(
tcx: TyCtxt<'_>,
item_def_id: LocalDefId,
force_capture_trait_args: ForceCaptureTraitArgs,
) -> &[ty::Variance] {
let generics = tcx.generics_of(item_def_id);
// Opaque types may only use regions that are bound. So for
@ -115,9 +147,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
#[instrument(level = "trace", skip(self), ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::Alias(_, ty::AliasTy { def_id, args, .. })
if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) =>
{
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
self.visit_opaque(*def_id, args);
}
_ => t.super_visit_with(self),
@ -135,6 +165,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
let mut generics = generics;
while let Some(def_id) = generics.parent {
generics = tcx.generics_of(def_id);
// Don't mark trait params generic if we're in an RPITIT.
if matches!(force_capture_trait_args, ForceCaptureTraitArgs::Yes)
&& generics.parent.is_none()
{
debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
break;
}
for param in &generics.own_params {
match param.kind {
ty::GenericParamDefKind::Lifetime => {

View File

@ -1100,9 +1100,12 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
| DefKind::Fn
| DefKind::Ctor(..)
| DefKind::AssocFn => true,
DefKind::AssocTy => {
// Only encode variances for RPITITs (for traits)
matches!(tcx.opt_rpitit_info(def_id), Some(ty::ImplTraitInTraitData::Trait { .. }))
}
DefKind::Mod
| DefKind::Field
| DefKind::AssocTy
| DefKind::AssocConst
| DefKind::TyParam
| DefKind::ConstParam

View File

@ -539,6 +539,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.trait_def(trait_def_id).implement_via_object
}
fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
self.is_impl_trait_in_trait(def_id)
}
fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
}

View File

@ -261,6 +261,8 @@ pub trait Interner:
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;
fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;
fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool;

View File

@ -254,6 +254,16 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?,
ty::Projection if relation.cx().is_impl_trait_in_trait(a.def_id) => {
relate_args_with_variances(
relation,
a.def_id,
relation.cx().variances_of(a.def_id),
a.args,
b.args,
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
)?
}
ty::Projection | ty::Weak | ty::Inherent => {
relate_args_invariantly(relation, a.args, b.args)?
}

View File

@ -1,22 +1,25 @@
#![feature(rustc_attrs)]
#![feature(rustc_attrs, precise_capturing_in_traits)]
#![allow(internal_features)]
#![rustc_variance_of_opaques]
trait Captures<'a> {}
impl<T> Captures<'_> for T {}
trait Foo<'i> {
fn implicit_capture_early<'a: 'a>() -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
//~^ [Self: o, 'i: o, 'a: *, 'a: o, 'i: o]
fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {}
//~^ [Self: o, 'i: o, 'a: *, 'i: o, 'a: o]
fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {}
//~^ [Self: o, 'i: o, 'a: *, 'i: o]
fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
//~^ [Self: o, 'i: o, 'a: o, 'i: o]
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {}
//~^ [Self: o, 'i: o, 'i: o, 'a: o]
fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {}
//~^ [Self: o, 'i: o, 'i: o]
}
fn main() {}

View File

@ -1,26 +1,38 @@
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:9:44
error: [Self: o, 'i: o, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:6:44
|
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:12:44
error: [Self: o, 'i: o, 'a: *, 'i: o, 'a: o]
--> $DIR/variance.rs:9:44
|
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [Self: o, 'i: *, 'a: o, 'i: o]
error: [Self: o, 'i: o, 'a: *, 'i: o]
--> $DIR/variance.rs:12:40
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [Self: o, 'i: o, 'a: o, 'i: o]
--> $DIR/variance.rs:15:48
|
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [Self: o, 'i: *, 'a: o, 'i: o]
error: [Self: o, 'i: o, 'i: o, 'a: o]
--> $DIR/variance.rs:18:48
|
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
error: [Self: o, 'i: o, 'i: o]
--> $DIR/variance.rs:21:44
|
LL | fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors

View File

@ -1,10 +1,11 @@
#![feature(precise_capturing_in_traits)]
fn type_param<T>() -> impl Sized + use<> {}
//~^ ERROR `impl Trait` must mention all type parameters in scope
trait Foo {
fn bar() -> impl Sized + use<>;
//~^ ERROR `impl Trait` must mention the `Self` type of the trait
//~| ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}
fn main() {}

View File

@ -1,16 +1,5 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/forgot-to-capture-type.rs:5:30
|
LL | fn bar() -> impl Sized + use<>;
| ^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-type.rs:1:23
--> $DIR/forgot-to-capture-type.rs:3:23
|
LL | fn type_param<T>() -> impl Sized + use<> {}
| - ^^^^^^^^^^^^^^^^^^
@ -20,7 +9,7 @@ LL | fn type_param<T>() -> impl Sized + use<> {}
= note: currently, all type parameters are required to be mentioned in the precise captures list
error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
--> $DIR/forgot-to-capture-type.rs:5:17
--> $DIR/forgot-to-capture-type.rs:7:17
|
LL | trait Foo {
| --------- `Self` type parameter is implicitly captured by this `impl Trait`
@ -29,5 +18,5 @@ LL | fn bar() -> impl Sized + use<>;
|
= note: currently, all type parameters are required to be mentioned in the precise captures list
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

View File

@ -1,20 +0,0 @@
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:5:19
|
LL | fn hello<'a>() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
|
= note: `#[warn(impl_trait_redundant_captures)]` on by default
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:10:27
|
LL | fn inherent(&self) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
warning: 2 warnings emitted

View File

@ -1,24 +0,0 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/redundant.rs:16:35
|
LL | fn in_trait() -> impl Sized + use<'a, Self>;
| ^^^^^^^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/redundant.rs:21:35
|
LL | fn in_trait() -> impl Sized + use<'a> {}
| ^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors

View File

@ -1,25 +1,24 @@
//@ compile-flags: -Zunstable-options --edition=2024
//@ revisions: normal rpitit
//@[normal] check-pass
//@ check-pass
#![feature(precise_capturing_in_traits)]
fn hello<'a>() -> impl Sized + use<'a> {}
//[normal]~^ WARN all possible in-scope parameters are already captured
//~^ WARN all possible in-scope parameters are already captured
struct Inherent;
impl Inherent {
fn inherent(&self) -> impl Sized + use<'_> {}
//[normal]~^ WARN all possible in-scope parameters are already captured
//~^ WARN all possible in-scope parameters are already captured
}
#[cfg(rpitit)]
trait Test<'a> {
fn in_trait() -> impl Sized + use<'a, Self>;
//[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
//~^ WARN all possible in-scope parameters are already captured
}
#[cfg(rpitit)]
impl<'a> Test<'a> for () {
fn in_trait() -> impl Sized + use<'a> {}
//[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
//~^ WARN all possible in-scope parameters are already captured
}
fn main() {}

View File

@ -0,0 +1,36 @@
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:6:19
|
LL | fn hello<'a>() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
|
= note: `#[warn(impl_trait_redundant_captures)]` on by default
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:11:27
|
LL | fn inherent(&self) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:16:22
|
LL | fn in_trait() -> impl Sized + use<'a, Self>;
| ^^^^^^^^^^^^^-------------
| |
| help: remove the `use<...>` syntax
warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:20:22
|
LL | fn in_trait() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^-------
| |
| help: remove the `use<...>` syntax
warning: 4 warnings emitted

View File

@ -2,13 +2,14 @@
// trait definition, which is not allowed. Due to the default lifetime capture
// rules of RPITITs, this is only doable if we use precise capturing.
#![feature(precise_capturing_in_traits)]
pub trait Foo {
fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}
impl Foo for () {
fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
//~^ ERROR return type captures more lifetimes than trait definition
}

View File

@ -1,28 +1,17 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53
|
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
| ^^^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
--> $DIR/rpitit-captures-more-method-lifetimes.rs:12:40
|
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
| --- ^^^^^^^^^^^^^^^^
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
| --- ^^^^^^^^^^^^^^^^^^^^^
| |
| this lifetime was captured
|
note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
--> $DIR/rpitit-captures-more-method-lifetimes.rs:8:40
|
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^
= note: hidden type inferred to be `impl Sized + 'im`
= note: hidden type inferred to be `impl Sized`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error

View File

@ -0,0 +1,14 @@
#![feature(precise_capturing_in_traits)]
struct Invariant<'a>(&'a mut &'a mut ());
trait Trait {
fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
}
impl Trait for () {
fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
//~^ ERROR return type captures more lifetimes than trait definition
}
fn main() {}

View File

@ -0,0 +1,17 @@
error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-impl-captures-too-much.rs:10:39
|
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
| -- ^^^^^^^^^^^^^^^^^^^^
| |
| this lifetime was captured
|
note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-impl-captures-too-much.rs:6:39
|
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^
= note: hidden type inferred to be `impl Sized`
error: aborting due to 1 previous error

View File

@ -1,19 +1,34 @@
//@ known-bug: unknown
// RPITITs don't have variances in their GATs, so they always relate invariantly
// and act as if they capture all their args.
// To fix this soundly, we need to make sure that all the trait header args
// remain captured, since they affect trait selection.
trait Foo<'a> {
fn hello() -> impl PartialEq + use<Self>;
}
#![feature(precise_capturing_in_traits)]
fn test<'a, 'b, T: for<'r> Foo<'r>>() {
PartialEq::eq(
&<T as Foo<'a>>::hello(),
&<T as Foo<'b>>::hello(),
fn eq_types<T>(_: T, _: T) {}
trait TraitLt<'a: 'a> {
fn hello() -> impl Sized + use<Self>;
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
}
fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
eq_types(
//~^ ERROR lifetime may not live long enough
//~| ERROR lifetime may not live long enough
<T as TraitLt<'a>>::hello(),
<T as TraitLt<'b>>::hello(),
);
}
trait MethodLt {
fn hello<'a: 'a>() -> impl Sized + use<Self>;
}
fn method_lt<'a, 'b, T: MethodLt> () {
eq_types(
T::hello::<'a>(),
T::hello::<'b>(),
);
// Good!
}
fn main() {}

View File

@ -1,47 +1,40 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/rpitit.rs:9:36
|
LL | fn hello() -> impl PartialEq + use<Self>;
| ^^^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
--> $DIR/rpitit.rs:9:19
--> $DIR/rpitit.rs:11:19
|
LL | trait Foo<'a> {
LL | trait TraitLt<'a: 'a> {
| -- this lifetime parameter is captured
LL | fn hello() -> impl PartialEq + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
LL | fn hello() -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
error: lifetime may not live long enough
--> $DIR/rpitit.rs:13:5
--> $DIR/rpitit.rs:15:5
|
LL | fn test<'a, 'b, T: for<'r> Foo<'r>>() {
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | / PartialEq::eq(
LL | | &<T as Foo<'a>>::hello(),
LL | | &<T as Foo<'b>>::hello(),
LL | / eq_types(
LL | |
LL | |
LL | | <T as TraitLt<'a>>::hello(),
LL | | <T as TraitLt<'b>>::hello(),
LL | | );
| |_____^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/rpitit.rs:13:5
--> $DIR/rpitit.rs:15:5
|
LL | fn test<'a, 'b, T: for<'r> Foo<'r>>() {
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | / PartialEq::eq(
LL | | &<T as Foo<'a>>::hello(),
LL | | &<T as Foo<'b>>::hello(),
LL | / eq_types(
LL | |
LL | |
LL | | <T as TraitLt<'a>>::hello(),
LL | | <T as TraitLt<'b>>::hello(),
LL | | );
| |_____^ argument requires that `'b` must outlive `'a`
|
@ -49,5 +42,5 @@ LL | | );
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

View File

@ -1,6 +1,9 @@
//@ check-pass
#![feature(precise_capturing_in_traits)]
trait Foo {
fn bar<'a>() -> impl Sized + use<Self>;
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}
fn main() {}

View File

@ -1,13 +0,0 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/self-capture.rs:2:34
|
LL | fn bar<'a>() -> impl Sized + use<Self>;
| ^^^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error