(active, if_let_guard, "1.47.0", Some(51114), None),
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
(active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None),
+ /// Allows referencing `Self` and projections in impl-trait.
+ (active, impl_trait_projections, "CURRENT_RUSTC_VERSION", None, None),
/// Allows using imported `main` function
(active, imported_main, "1.53.0", Some(28937), None),
/// Allows associated types in inherent impls.
let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
let span = tcx.def_span(item.owner_id.def_id);
- check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
+ if !tcx.features().impl_trait_projections {
+ check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
+ }
if tcx.type_of(item.owner_id.def_id).references_error() {
return;
}
_ => unreachable!(),
};
- let mut err = struct_span_err!(
- tcx.sess,
+ let mut err = feature_err(
+ &tcx.sess.parse_sess,
+ sym::impl_trait_projections,
span,
- E0760,
- "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
- a parent scope",
- if is_async { "async fn" } else { "impl Trait" },
+ &format!(
+ "`{}` return type cannot contain a projection or `Self` that references \
+ lifetimes from a parent scope",
+ if is_async { "async fn" } else { "impl Trait" },
+ ),
);
-
for (span, name) in visitor.selftys {
err.span_suggestion(
span,
impl_macros,
impl_trait_in_bindings,
impl_trait_in_fn_trait_return,
+ impl_trait_projections,
implied_by,
import,
import_name_type,
--- /dev/null
+// edition:2018
+#![feature(impl_trait_projections)]
+
+// This test checks that we emit the correct borrowck error when `Self` is used as a return type.
+// See #61949 for context.
+
+pub struct Foo<'a> {
+ pub bar: &'a i32,
+}
+
+impl<'a> Foo<'a> {
+ pub async fn new(_bar: &'a i32) -> Self {
+ Foo {
+ bar: &22
+ }
+ }
+}
+
+pub async fn foo() {
+ let x = {
+ let bar = 22;
+ Foo::new(&bar).await
+ //~^ ERROR `bar` does not live long enough
+ };
+ drop(x);
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `bar` does not live long enough
+ --> $DIR/feature-self-return-type.rs:22:18
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let bar = 22;
+LL | Foo::new(&bar).await
+ | ^^^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `bar` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
// edition:2018
+// gate-test-impl_trait_projections
// This test checks that `Self` is prohibited as a return type. See #61949 for context.
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
- --> $DIR/issue-61949-self-return-type.rs:10:40
+error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+ --> $DIR/issue-61949-self-return-type.rs:11:40
|
LL | pub async fn new(_bar: &'a i32) -> Self {
| ^^^^ help: consider spelling out the type instead: `Foo<'a>`
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
error[E0597]: `bar` does not live long enough
- --> $DIR/issue-61949-self-return-type.rs:21:18
+ --> $DIR/issue-61949-self-return-type.rs:22:18
|
LL | let x = {
| - borrow later stored here
error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0597, E0760.
+Some errors have detailed explanations: E0597, E0658.
For more information about an error, try `rustc --explain E0597`.
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
--> $DIR/issue-78600.rs:6:33
|
LL | async fn new(i: &'a i32) -> Result<Self, ()> {
| ^^^^^^^----^^^^^
| |
| help: consider spelling out the type instead: `S<'a>`
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0760`.
+For more information about this error, try `rustc --explain E0658`.
LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
| ++++++++++++
-error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+error[E0658]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
--> $DIR/bound-normalization-fail.rs:41:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'a>>::Assoc`
--> $DIR/bound-normalization-fail.rs:41:41
error: aborting due to 3 previous errors
-Some errors have detailed explanations: E0271, E0760.
+Some errors have detailed explanations: E0271, E0658.
For more information about an error, try `rustc --explain E0271`.
--- /dev/null
+// edition:2018
+#![feature(impl_trait_projections)]
+
+// This test checks that we emit the correct borrowck error when `Self` or a projection is used as
+// a return type. See #61949 for context.
+
+mod with_self {
+ pub struct Foo<'a> {
+ pub bar: &'a i32,
+ }
+
+ impl<'a> Foo<'a> {
+ pub fn new(_bar: &'a i32) -> impl Into<Self> {
+ Foo {
+ bar: &22
+ }
+ }
+ }
+
+ fn foo() {
+ let x = {
+ let bar = 22;
+ Foo::new(&bar).into()
+ //~^ ERROR `bar` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+struct Foo<T>(T);
+
+trait FooLike {
+ type Output;
+}
+
+impl<T> FooLike for Foo<T> {
+ type Output = T;
+}
+
+mod impl_trait {
+ use super::*;
+
+ trait Trait {
+ type Assoc;
+
+ fn make_assoc(self) -> Self::Assoc;
+ }
+
+ /// `T::Assoc` can't be normalized any further here.
+ fn foo<T: Trait>(x: T) -> impl FooLike<Output = T::Assoc> {
+ Foo(x.make_assoc())
+ }
+
+ impl<'a> Trait for &'a () {
+ type Assoc = &'a ();
+
+ fn make_assoc(self) -> &'a () { &() }
+ }
+
+ fn usage() {
+ let x = {
+ let y = ();
+ foo(&y)
+ //~^ ERROR `y` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+// Same with lifetimes in the trait
+
+mod lifetimes {
+ use super::*;
+
+ trait Trait<'a> {
+ type Assoc;
+
+ fn make_assoc(self) -> Self::Assoc;
+ }
+
+ /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
+ fn foo<'a, T: Trait<'a>>(x: T) -> impl FooLike<Output = T::Assoc> {
+ Foo(x.make_assoc())
+ }
+
+ impl<'a> Trait<'a> for &'a () {
+ type Assoc = &'a ();
+
+ fn make_assoc(self) -> &'a () { &() }
+ }
+
+ fn usage() {
+ let x = {
+ let y = ();
+ foo(&y)
+ //~^ ERROR `y` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `bar` does not live long enough
+ --> $DIR/feature-self-return-type.rs:23:22
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let bar = 22;
+LL | Foo::new(&bar).into()
+ | ^^^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `bar` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/feature-self-return-type.rs:63:17
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let y = ();
+LL | foo(&y)
+ | ^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `y` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/feature-self-return-type.rs:95:17
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let y = ();
+LL | foo(&y)
+ | ^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `y` dropped here while still borrowed
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.