mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Add variances to RPITITs
This commit is contained in:
parent
b7297ac440
commit
a7dc98733d
@ -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 => {
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)?
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
36
tests/ui/impl-trait/precise-capturing/redundant.stderr
Normal file
36
tests/ui/impl-trait/precise-capturing/redundant.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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> {
|
||||
| -- 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 | trait TraitLt<'a: 'a> {
|
||||
| -- this lifetime parameter is captured
|
||||
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>>() {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | / PartialEq::eq(
|
||||
LL | | &<T as Foo<'a>>::hello(),
|
||||
LL | | &<T as Foo<'b>>::hello(),
|
||||
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
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>>() {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | / PartialEq::eq(
|
||||
LL | | &<T as Foo<'a>>::hello(),
|
||||
LL | | &<T as Foo<'b>>::hello(),
|
||||
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user