Make impl_trait_projections a feature gate.
This commit is contained in:
parent
47de11f1ed
commit
b77674d254
11 changed files with 216 additions and 16 deletions
|
@ -419,6 +419,8 @@ declare_features! (
|
||||||
(active, if_let_guard, "1.47.0", Some(51114), None),
|
(active, if_let_guard, "1.47.0", Some(51114), None),
|
||||||
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
|
/// 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),
|
(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
|
/// Allows using imported `main` function
|
||||||
(active, imported_main, "1.53.0", Some(28937), None),
|
(active, imported_main, "1.53.0", Some(28937), None),
|
||||||
/// Allows associated types in inherent impls.
|
/// Allows associated types in inherent impls.
|
||||||
|
|
|
@ -231,7 +231,9 @@ fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
|
let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
|
||||||
let span = tcx.def_span(item.owner_id.def_id);
|
let span = tcx.def_span(item.owner_id.def_id);
|
||||||
|
|
||||||
|
if !tcx.features().impl_trait_projections {
|
||||||
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
|
check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
|
||||||
|
}
|
||||||
if tcx.type_of(item.owner_id.def_id).references_error() {
|
if tcx.type_of(item.owner_id.def_id).references_error() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -424,15 +426,16 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut err = struct_span_err!(
|
let mut err = feature_err(
|
||||||
tcx.sess,
|
&tcx.sess.parse_sess,
|
||||||
|
sym::impl_trait_projections,
|
||||||
span,
|
span,
|
||||||
E0760,
|
&format!(
|
||||||
"`{}` return type cannot contain a projection or `Self` that references lifetimes from \
|
"`{}` return type cannot contain a projection or `Self` that references \
|
||||||
a parent scope",
|
lifetimes from a parent scope",
|
||||||
if is_async { "async fn" } else { "impl Trait" },
|
if is_async { "async fn" } else { "impl Trait" },
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (span, name) in visitor.selftys {
|
for (span, name) in visitor.selftys {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -816,6 +816,7 @@ symbols! {
|
||||||
impl_macros,
|
impl_macros,
|
||||||
impl_trait_in_bindings,
|
impl_trait_in_bindings,
|
||||||
impl_trait_in_fn_trait_return,
|
impl_trait_in_fn_trait_return,
|
||||||
|
impl_trait_projections,
|
||||||
implied_by,
|
implied_by,
|
||||||
import,
|
import,
|
||||||
import_name_type,
|
import_name_type,
|
||||||
|
|
28
src/test/ui/async-await/feature-self-return-type.rs
Normal file
28
src/test/ui/async-await/feature-self-return-type.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// 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() { }
|
15
src/test/ui/async-await/feature-self-return-type.stderr
Normal file
15
src/test/ui/async-await/feature-self-return-type.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
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`.
|
|
@ -1,4 +1,5 @@
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
// gate-test-impl_trait_projections
|
||||||
|
|
||||||
// This test checks that `Self` is prohibited as a return type. See #61949 for context.
|
// This test checks that `Self` is prohibited as a return type. See #61949 for context.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
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-61949-self-return-type.rs:10:40
|
--> $DIR/issue-61949-self-return-type.rs:11:40
|
||||||
|
|
|
|
||||||
LL | pub async fn new(_bar: &'a i32) -> Self {
|
LL | pub async fn new(_bar: &'a i32) -> Self {
|
||||||
| ^^^^ help: consider spelling out the type instead: `Foo<'a>`
|
| ^^^^ 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
|
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 = {
|
LL | let x = {
|
||||||
| - borrow later stored here
|
| - borrow later stored here
|
||||||
|
@ -18,5 +21,5 @@ LL | };
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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`.
|
For more information about an error, try `rustc --explain E0597`.
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
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
|
--> $DIR/issue-78600.rs:6:33
|
||||||
|
|
|
|
||||||
LL | async fn new(i: &'a i32) -> Result<Self, ()> {
|
LL | async fn new(i: &'a i32) -> Result<Self, ()> {
|
||||||
| ^^^^^^^----^^^^^
|
| ^^^^^^^----^^^^^
|
||||||
| |
|
| |
|
||||||
| help: consider spelling out the type instead: `S<'a>`
|
| 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
|
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`.
|
||||||
|
|
|
@ -19,11 +19,14 @@ help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc
|
||||||
LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
|
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
|
--> $DIR/bound-normalization-fail.rs:41:41
|
||||||
|
|
|
|
||||||
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
|
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`
|
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'a>>::Assoc`
|
||||||
--> $DIR/bound-normalization-fail.rs:41:41
|
--> $DIR/bound-normalization-fail.rs:41:41
|
||||||
|
@ -48,5 +51,5 @@ LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
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`.
|
For more information about an error, try `rustc --explain E0271`.
|
||||||
|
|
102
src/test/ui/impl-trait/feature-self-return-type.rs
Normal file
102
src/test/ui/impl-trait/feature-self-return-type.rs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// 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() { }
|
39
src/test/ui/impl-trait/feature-self-return-type.stderr
Normal file
39
src/test/ui/impl-trait/feature-self-return-type.stderr
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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`.
|
Loading…
Add table
Add a link
Reference in a new issue