about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-10 20:59:02 +0000
committerMichael Goulet <michael@errs.io>2024-12-12 00:32:18 +0000
commit2caada17c023ed6efedc2aa78d0233246e3adb16 (patch)
tree2c2479efc618289d3dac4b7c3329969f4c80a8b9
parent21fe748be15271ea5804e0507cd699b675efe038 (diff)
downloadrust-2caada17c023ed6efedc2aa78d0233246e3adb16.tar.gz
rust-2caada17c023ed6efedc2aa78d0233246e3adb16.zip
Properly consider APITs for never type fallback ascription fix
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs19
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.fixed28
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr52
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2024.stderr37
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs28
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr4
6 files changed, 142 insertions, 26 deletions
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index ddd146fe785..b57c248ed2b 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -613,19 +613,16 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
         if arg_segment.args.is_none()
             && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
             && let generics = self.fcx.tcx.generics_of(def_id)
-            && let args = &all_args[generics.parent_count..]
+            && let args = all_args[generics.parent_count..].iter().zip(&generics.own_params)
             // We can't turbofish consts :(
-            && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
+            && args.clone().all(|(_, param)| matches!(param.kind, ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Lifetime))
         {
-            let n_tys = args
-                .iter()
-                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
-                .count();
-            for (idx, arg) in args
-                .iter()
-                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
-                .enumerate()
-            {
+            // We filter out APITs, which are not turbofished.
+            let non_apit_type_args = args.filter(|(_, param)| {
+                matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: false, .. })
+            });
+            let n_tys = non_apit_type_args.clone().count();
+            for (idx, (arg, _)) in non_apit_type_args.enumerate() {
                 if let Some(ty) = arg.as_type()
                     && let Some(vid) = self.fcx.root_vid(ty)
                     && self.reachable_vids.contains(&vid)
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
index 91d30de74c7..11ec273fc4b 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
@@ -11,6 +11,8 @@ fn main() {
     m();
     q();
     let _ = meow();
+    let _ = fallback_return();
+    let _ = fully_apit();
 }
 
 fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
 }
+
+pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
+    Err(())
+}
+
+pub fn fallback_return() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit::<()>(|| Default::default())?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
+
+fn mk<T>() -> Result<T, ()> {
+    Err(())
+}
+
+fn takes_apit2(_x: impl Default) {}
+
+fn fully_apit() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit2(mk::<()>()?);
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 6fdb548c431..9009d617936 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -1,5 +1,5 @@
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:16:1
+  --> $DIR/never-type-fallback-breaking.rs:18:1
    |
 LL | fn m() {
    | ^^^^^^
@@ -8,7 +8,7 @@ LL | fn m() {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:20:17
+  --> $DIR/never-type-fallback-breaking.rs:22:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     let x: () = match true {
    |          ++++
 
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:28:1
+  --> $DIR/never-type-fallback-breaking.rs:30:1
    |
 LL | fn q() -> Option<()> {
    | ^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:35:5
+  --> $DIR/never-type-fallback-breaking.rs:37:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL |     deserialize::<()>()?;
    |                ++++++
 
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:45:1
+  --> $DIR/never-type-fallback-breaking.rs:47:1
    |
 LL | fn meow() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `(): From<!>` will fail
-  --> $DIR/never-type-fallback-breaking.rs:48:5
+  --> $DIR/never-type-fallback-breaking.rs:50:5
    |
 LL |     help(1)?;
    |     ^^^^^^^
@@ -56,5 +56,43 @@ help: use `()` annotations to avoid fallback changes
 LL |     help::<(), _>(1)?;
    |         +++++++++
 
-warning: 3 warnings emitted
+warning: this function depends on never type fallback being `()`
+  --> $DIR/never-type-fallback-breaking.rs:59:1
+   |
+LL | pub fn fallback_return() -> Result<(), ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: Default` will fail
+  --> $DIR/never-type-fallback-breaking.rs:62:19
+   |
+LL |     takes_apit(|| Default::default())?;
+   |                   ^^^^^^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     takes_apit::<()>(|| Default::default())?;
+   |               ++++++
+
+warning: this function depends on never type fallback being `()`
+  --> $DIR/never-type-fallback-breaking.rs:73:1
+   |
+LL | fn fully_apit() -> Result<(), ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: Default` will fail
+  --> $DIR/never-type-fallback-breaking.rs:76:17
+   |
+LL |     takes_apit2(mk()?);
+   |                 ^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     takes_apit2(mk::<()>()?);
+   |                   ++++++
+
+warning: 5 warnings emitted
 
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
index 9d79dfb4099..2daf00f7804 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:20:17
+  --> $DIR/never-type-fallback-breaking.rs:22:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -8,7 +8,7 @@ LL |         true => Default::default(),
    = help: did you intend to use the type `()` here instead?
 
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:35:5
+  --> $DIR/never-type-fallback-breaking.rs:37:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -16,13 +16,13 @@ LL |     deserialize()?;
    = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
    = help: did you intend to use the type `()` here instead?
 note: required by a bound in `deserialize`
-  --> $DIR/never-type-fallback-breaking.rs:31:23
+  --> $DIR/never-type-fallback-breaking.rs:33:23
    |
 LL |     fn deserialize<T: Default>() -> Option<T> {
    |                       ^^^^^^^ required by this bound in `deserialize`
 
 error[E0277]: the trait bound `(): From<!>` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:48:5
+  --> $DIR/never-type-fallback-breaking.rs:50:5
    |
 LL |     help(1)?;
    |     ^^^^^^^ the trait `From<!>` is not implemented for `()`
@@ -39,11 +39,36 @@ LL |     help(1)?;
            and 4 others
    = note: required for `!` to implement `Into<()>`
 note: required by a bound in `help`
-  --> $DIR/never-type-fallback-breaking.rs:42:20
+  --> $DIR/never-type-fallback-breaking.rs:44:20
    |
 LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
    |                    ^^^^^^^^ required by this bound in `help`
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:62:19
+   |
+LL |     takes_apit(|| Default::default())?;
+   |                   ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:76:17
+   |
+LL |     takes_apit2(mk()?);
+   |     ----------- ^^^^^ the trait `Default` is not implemented for `!`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+note: required by a bound in `takes_apit2`
+  --> $DIR/never-type-fallback-breaking.rs:71:25
+   |
+LL | fn takes_apit2(_x: impl Default) {}
+   |                         ^^^^^^^ required by this bound in `takes_apit2`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs
index 24e33ff6bf6..daafc526eff 100644
--- a/tests/ui/editions/never-type-fallback-breaking.rs
+++ b/tests/ui/editions/never-type-fallback-breaking.rs
@@ -11,6 +11,8 @@ fn main() {
     m();
     q();
     let _ = meow();
+    let _ = fallback_return();
+    let _ = fully_apit();
 }
 
 fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
 }
+
+pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
+    Err(())
+}
+
+pub fn fallback_return() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit(|| Default::default())?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
+
+fn mk<T>() -> Result<T, ()> {
+    Err(())
+}
+
+fn takes_apit2(_x: impl Default) {}
+
+fn fully_apit() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit2(mk()?);
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index b5b5d87e7dd..8d08fb7f2a8 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -15,8 +15,8 @@ LL |     foo(|| panic!());
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
 help: use `()` annotations to avoid fallback changes
    |
-LL |     foo::<(), _>(|| panic!());
-   |        +++++++++
+LL |     foo::<()>(|| panic!());
+   |        ++++++
 
 warning: 1 warning emitted