]> git.lizzy.rs Git - rust.git/commitdiff
Make impl_trait_projections a feature gate.
authorCamille GILLOT <gillot.camille@gmail.com>
Mon, 24 Oct 2022 16:06:25 +0000 (16:06 +0000)
committerCamille GILLOT <gillot.camille@gmail.com>
Sat, 12 Nov 2022 10:01:07 +0000 (10:01 +0000)
compiler/rustc_feature/src/active.rs
compiler/rustc_hir_analysis/src/check/check.rs
compiler/rustc_span/src/symbol.rs
src/test/ui/async-await/feature-self-return-type.rs [new file with mode: 0644]
src/test/ui/async-await/feature-self-return-type.stderr [new file with mode: 0644]
src/test/ui/async-await/issue-61949-self-return-type.rs
src/test/ui/async-await/issue-61949-self-return-type.stderr
src/test/ui/async-await/issues/issue-78600.stderr
src/test/ui/impl-trait/bound-normalization-fail.stderr
src/test/ui/impl-trait/feature-self-return-type.rs [new file with mode: 0644]
src/test/ui/impl-trait/feature-self-return-type.stderr [new file with mode: 0644]

index e94e038f9283b701a2d73d2481329b772ecf4ea1..56eaefc88e192adf43f58112688b4b377b064df3 100644 (file)
@@ -419,6 +419,8 @@ pub fn set(&self, features: &mut Features, span: Span) {
     (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.
index eddc7e0e0556c84306addfd1f67d710c43ec99a7..256ecc60516ec0a96a4bdc7f95eb35312dd7b6d8 100644 (file)
@@ -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 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;
     }
@@ -424,15 +426,16 @@ fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
                 _ => 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,
index 54a61483a11a326032c4dd4ddb7351d8e31cf7b9..fd7456e8c9d2aee67c2c31468e12bde8afab7694 100644 (file)
         impl_macros,
         impl_trait_in_bindings,
         impl_trait_in_fn_trait_return,
+        impl_trait_projections,
         implied_by,
         import,
         import_name_type,
diff --git a/src/test/ui/async-await/feature-self-return-type.rs b/src/test/ui/async-await/feature-self-return-type.rs
new file mode 100644 (file)
index 0000000..41f8874
--- /dev/null
@@ -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() { }
diff --git a/src/test/ui/async-await/feature-self-return-type.stderr b/src/test/ui/async-await/feature-self-return-type.stderr
new file mode 100644 (file)
index 0000000..8924683
--- /dev/null
@@ -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`.
index d7bf34a4795a3c164edff068f488c281f5ccf24f..d73dbc6e828f3879a7af56604062d8ee61448dd7 100644 (file)
@@ -1,4 +1,5 @@
 // edition:2018
+// gate-test-impl_trait_projections
 
 // This test checks that `Self` is prohibited as a return type. See #61949 for context.
 
index 5a7691159898b43b7ce3afefb65634fea3c6b49d..638b197bc022d6d5f68f8e2f96491d3682de5ec8 100644 (file)
@@ -1,11 +1,14 @@
-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
@@ -18,5 +21,5 @@ LL |     };
 
 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`.
index 92b66147106e1eae7ecf4b851d1f1975cf9af1c6..37eafa996c535863558e25f6d1a55f902eeb5a02 100644 (file)
@@ -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
    |
 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`.
index 2bccfd6cf11fefb6ea8db3d61ece8d6acaaca40e..a9fa2da569f85e08be827526537979842450d504 100644 (file)
@@ -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> {
    |                         ++++++++++++
 
-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
@@ -48,5 +51,5 @@ LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T
 
 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`.
diff --git a/src/test/ui/impl-trait/feature-self-return-type.rs b/src/test/ui/impl-trait/feature-self-return-type.rs
new file mode 100644 (file)
index 0000000..51877e9
--- /dev/null
@@ -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() { }
diff --git a/src/test/ui/impl-trait/feature-self-return-type.stderr b/src/test/ui/impl-trait/feature-self-return-type.stderr
new file mode 100644 (file)
index 0000000..601e53b
--- /dev/null
@@ -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`.