about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-02-04 19:42:11 +0100
committerGitHub <noreply@github.com>2024-02-04 19:42:11 +0100
commitc2ad283f4eaee2f478872cf05383c035b3a4406e (patch)
tree8d2067b6bd024a30c6a9fbfed3c6ede430cb4e82
parentfa7d3e9af16e31de475d0bdc76de60b5ebccb270 (diff)
parent0f21e45e95ea879ec13a690390c9d0bd327bfe58 (diff)
downloadrust-c2ad283f4eaee2f478872cf05383c035b3a4406e.tar.gz
rust-c2ad283f4eaee2f478872cf05383c035b3a4406e.zip
Rollup merge of #120552 - GuillaumeGomez:never-type-feature-gate, r=compiler-errors
Correctly check `never_type` feature gating

Fixes #120542.

The feature wasn't tested on return type of a generic function type, so it got under the radar in https://github.com/rust-lang/rust/pull/120316.

r? ```@compiler-errors```
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-never_type.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-never_type.stderr32
-rw-r--r--tests/ui/never_type/never-type-in-nested-fn-decl.rs7
4 files changed, 60 insertions, 1 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 82236d2e306..409aef9185d 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -362,6 +362,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         }
     }
 
+    fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) {
+        // This check needs to happen here because the never type can be returned from a function,
+        // but cannot be used in any other context. If this check was in `visit_fn_ret_ty`, it
+        // include both functions and generics like `impl Fn() -> !`.
+        if let ast::GenericArgs::Parenthesized(generic_args) = args
+            && let ast::FnRetTy::Ty(ref ty) = generic_args.output
+            && matches!(ty.kind, ast::TyKind::Never)
+        {
+            gate!(&self, never_type, ty.span, "the `!` type is experimental");
+        }
+        visit::walk_generic_args(self, args);
+    }
+
     fn visit_expr(&mut self, e: &'a ast::Expr) {
         match e.kind {
             ast::ExprKind::TryBlock(_) => {
diff --git a/tests/ui/feature-gates/feature-gate-never_type.rs b/tests/ui/feature-gates/feature-gate-never_type.rs
index be8c27dbb1b..f5d28a4877f 100644
--- a/tests/ui/feature-gates/feature-gate-never_type.rs
+++ b/tests/ui/feature-gates/feature-gate-never_type.rs
@@ -13,5 +13,14 @@ impl Foo for Meeshka {
     type Wub = !; //~ ERROR type is experimental
 }
 
+fn look_ma_no_feature_gate<F: FnOnce() -> !>() {} //~ ERROR type is experimental
+fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental
+fn panic() -> ! {
+    panic!();
+}
+fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental
+    panic
+}
+
 fn main() {
 }
diff --git a/tests/ui/feature-gates/feature-gate-never_type.stderr b/tests/ui/feature-gates/feature-gate-never_type.stderr
index 0fca58519ce..33e4e019b18 100644
--- a/tests/ui/feature-gates/feature-gate-never_type.stderr
+++ b/tests/ui/feature-gates/feature-gate-never_type.stderr
@@ -48,6 +48,36 @@ LL |     type Wub = !;
    = help: add `#![feature(never_type)]` 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 5 previous errors
+error[E0658]: the `!` type is experimental
+  --> $DIR/feature-gate-never_type.rs:16:43
+   |
+LL | fn look_ma_no_feature_gate<F: FnOnce() -> !>() {}
+   |                                           ^
+   |
+   = note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
+   = help: add `#![feature(never_type)]` 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[E0658]: the `!` type is experimental
+  --> $DIR/feature-gate-never_type.rs:17:26
+   |
+LL | fn tadam(f: &dyn Fn() -> !) {}
+   |                          ^
+   |
+   = note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
+   = help: add `#![feature(never_type)]` 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[E0658]: the `!` type is experimental
+  --> $DIR/feature-gate-never_type.rs:21:30
+   |
+LL | fn toudoum() -> impl Fn() -> ! {
+   |                              ^
+   |
+   = note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
+   = help: add `#![feature(never_type)]` 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 8 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/never_type/never-type-in-nested-fn-decl.rs b/tests/ui/never_type/never-type-in-nested-fn-decl.rs
new file mode 100644
index 00000000000..df546c4717e
--- /dev/null
+++ b/tests/ui/never_type/never-type-in-nested-fn-decl.rs
@@ -0,0 +1,7 @@
+// build-pass
+
+trait X<const N: i32> {}
+
+fn hello<T: X<{ fn hello() -> ! { loop {} } 1 }>>() {}
+
+fn main() {}