Skip to content

Commit 2caada1

Browse files
Properly consider APITs for never type fallback ascription fix
1 parent 21fe748 commit 2caada1

6 files changed

+142
-26
lines changed

compiler/rustc_hir_typeck/src/fallback.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -613,19 +613,16 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
613613
if arg_segment.args.is_none()
614614
&& let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
615615
&& let generics = self.fcx.tcx.generics_of(def_id)
616-
&& let args = &all_args[generics.parent_count..]
616+
&& let args = all_args[generics.parent_count..].iter().zip(&generics.own_params)
617617
// We can't turbofish consts :(
618-
&& args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
618+
&& args.clone().all(|(_, param)| matches!(param.kind, ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Lifetime))
619619
{
620-
let n_tys = args
621-
.iter()
622-
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
623-
.count();
624-
for (idx, arg) in args
625-
.iter()
626-
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
627-
.enumerate()
628-
{
620+
// We filter out APITs, which are not turbofished.
621+
let non_apit_type_args = args.filter(|(_, param)| {
622+
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: false, .. })
623+
});
624+
let n_tys = non_apit_type_args.clone().count();
625+
for (idx, (arg, _)) in non_apit_type_args.enumerate() {
629626
if let Some(ty) = arg.as_type()
630627
&& let Some(vid) = self.fcx.root_vid(ty)
631628
&& self.reachable_vids.contains(&vid)

tests/ui/editions/never-type-fallback-breaking.e2021.fixed

+28
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ fn main() {
1111
m();
1212
q();
1313
let _ = meow();
14+
let _ = fallback_return();
15+
let _ = fully_apit();
1416
}
1517

1618
fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
4951
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
5052
Ok(())
5153
}
54+
55+
pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
56+
Err(())
57+
}
58+
59+
pub fn fallback_return() -> Result<(), ()> {
60+
//[e2021]~^ this function depends on never type fallback being `()`
61+
//[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!
62+
takes_apit::<()>(|| Default::default())?;
63+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
64+
Ok(())
65+
}
66+
67+
fn mk<T>() -> Result<T, ()> {
68+
Err(())
69+
}
70+
71+
fn takes_apit2(_x: impl Default) {}
72+
73+
fn fully_apit() -> Result<(), ()> {
74+
//[e2021]~^ this function depends on never type fallback being `()`
75+
//[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!
76+
takes_apit2(mk::<()>()?);
77+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
78+
Ok(())
79+
}

tests/ui/editions/never-type-fallback-breaking.e2021.stderr

+45-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: this function depends on never type fallback being `()`
2-
--> $DIR/never-type-fallback-breaking.rs:16:1
2+
--> $DIR/never-type-fallback-breaking.rs:18:1
33
|
44
LL | fn m() {
55
| ^^^^^^
@@ -8,7 +8,7 @@ LL | fn m() {
88
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
99
= help: specify the types explicitly
1010
note: in edition 2024, the requirement `!: Default` will fail
11-
--> $DIR/never-type-fallback-breaking.rs:20:17
11+
--> $DIR/never-type-fallback-breaking.rs:22:17
1212
|
1313
LL | true => Default::default(),
1414
| ^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL | let x: () = match true {
1919
| ++++
2020

2121
warning: this function depends on never type fallback being `()`
22-
--> $DIR/never-type-fallback-breaking.rs:28:1
22+
--> $DIR/never-type-fallback-breaking.rs:30:1
2323
|
2424
LL | fn q() -> Option<()> {
2525
| ^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
2828
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
2929
= help: specify the types explicitly
3030
note: in edition 2024, the requirement `!: Default` will fail
31-
--> $DIR/never-type-fallback-breaking.rs:35:5
31+
--> $DIR/never-type-fallback-breaking.rs:37:5
3232
|
3333
LL | deserialize()?;
3434
| ^^^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL | deserialize::<()>()?;
3838
| ++++++
3939

4040
warning: this function depends on never type fallback being `()`
41-
--> $DIR/never-type-fallback-breaking.rs:45:1
41+
--> $DIR/never-type-fallback-breaking.rs:47:1
4242
|
4343
LL | fn meow() -> Result<(), ()> {
4444
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> {
4747
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
4848
= help: specify the types explicitly
4949
note: in edition 2024, the requirement `(): From<!>` will fail
50-
--> $DIR/never-type-fallback-breaking.rs:48:5
50+
--> $DIR/never-type-fallback-breaking.rs:50:5
5151
|
5252
LL | help(1)?;
5353
| ^^^^^^^
@@ -56,5 +56,43 @@ help: use `()` annotations to avoid fallback changes
5656
LL | help::<(), _>(1)?;
5757
| +++++++++
5858

59-
warning: 3 warnings emitted
59+
warning: this function depends on never type fallback being `()`
60+
--> $DIR/never-type-fallback-breaking.rs:59:1
61+
|
62+
LL | pub fn fallback_return() -> Result<(), ()> {
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
64+
|
65+
= 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!
66+
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
67+
= help: specify the types explicitly
68+
note: in edition 2024, the requirement `!: Default` will fail
69+
--> $DIR/never-type-fallback-breaking.rs:62:19
70+
|
71+
LL | takes_apit(|| Default::default())?;
72+
| ^^^^^^^^^^^^^^^^^^
73+
help: use `()` annotations to avoid fallback changes
74+
|
75+
LL | takes_apit::<()>(|| Default::default())?;
76+
| ++++++
77+
78+
warning: this function depends on never type fallback being `()`
79+
--> $DIR/never-type-fallback-breaking.rs:73:1
80+
|
81+
LL | fn fully_apit() -> Result<(), ()> {
82+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
|
84+
= 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!
85+
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
86+
= help: specify the types explicitly
87+
note: in edition 2024, the requirement `!: Default` will fail
88+
--> $DIR/never-type-fallback-breaking.rs:76:17
89+
|
90+
LL | takes_apit2(mk()?);
91+
| ^^^^^
92+
help: use `()` annotations to avoid fallback changes
93+
|
94+
LL | takes_apit2(mk::<()>()?);
95+
| ++++++
96+
97+
warning: 5 warnings emitted
6098

tests/ui/editions/never-type-fallback-breaking.e2024.stderr

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the trait bound `!: Default` is not satisfied
2-
--> $DIR/never-type-fallback-breaking.rs:20:17
2+
--> $DIR/never-type-fallback-breaking.rs:22:17
33
|
44
LL | true => Default::default(),
55
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -8,21 +8,21 @@ LL | true => Default::default(),
88
= help: did you intend to use the type `()` here instead?
99

1010
error[E0277]: the trait bound `!: Default` is not satisfied
11-
--> $DIR/never-type-fallback-breaking.rs:35:5
11+
--> $DIR/never-type-fallback-breaking.rs:37:5
1212
|
1313
LL | deserialize()?;
1414
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
1515
|
1616
= 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)
1717
= help: did you intend to use the type `()` here instead?
1818
note: required by a bound in `deserialize`
19-
--> $DIR/never-type-fallback-breaking.rs:31:23
19+
--> $DIR/never-type-fallback-breaking.rs:33:23
2020
|
2121
LL | fn deserialize<T: Default>() -> Option<T> {
2222
| ^^^^^^^ required by this bound in `deserialize`
2323

2424
error[E0277]: the trait bound `(): From<!>` is not satisfied
25-
--> $DIR/never-type-fallback-breaking.rs:48:5
25+
--> $DIR/never-type-fallback-breaking.rs:50:5
2626
|
2727
LL | help(1)?;
2828
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
@@ -39,11 +39,36 @@ LL | help(1)?;
3939
and 4 others
4040
= note: required for `!` to implement `Into<()>`
4141
note: required by a bound in `help`
42-
--> $DIR/never-type-fallback-breaking.rs:42:20
42+
--> $DIR/never-type-fallback-breaking.rs:44:20
4343
|
4444
LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
4545
| ^^^^^^^^ required by this bound in `help`
4646

47-
error: aborting due to 3 previous errors
47+
error[E0277]: the trait bound `!: Default` is not satisfied
48+
--> $DIR/never-type-fallback-breaking.rs:62:19
49+
|
50+
LL | takes_apit(|| Default::default())?;
51+
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
52+
|
53+
= 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)
54+
= help: did you intend to use the type `()` here instead?
55+
56+
error[E0277]: the trait bound `!: Default` is not satisfied
57+
--> $DIR/never-type-fallback-breaking.rs:76:17
58+
|
59+
LL | takes_apit2(mk()?);
60+
| ----------- ^^^^^ the trait `Default` is not implemented for `!`
61+
| |
62+
| required by a bound introduced by this call
63+
|
64+
= 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)
65+
= help: did you intend to use the type `()` here instead?
66+
note: required by a bound in `takes_apit2`
67+
--> $DIR/never-type-fallback-breaking.rs:71:25
68+
|
69+
LL | fn takes_apit2(_x: impl Default) {}
70+
| ^^^^^^^ required by this bound in `takes_apit2`
71+
72+
error: aborting due to 5 previous errors
4873

4974
For more information about this error, try `rustc --explain E0277`.

tests/ui/editions/never-type-fallback-breaking.rs

+28
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ fn main() {
1111
m();
1212
q();
1313
let _ = meow();
14+
let _ = fallback_return();
15+
let _ = fully_apit();
1416
}
1517

1618
fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
4951
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
5052
Ok(())
5153
}
54+
55+
pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
56+
Err(())
57+
}
58+
59+
pub fn fallback_return() -> Result<(), ()> {
60+
//[e2021]~^ this function depends on never type fallback being `()`
61+
//[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!
62+
takes_apit(|| Default::default())?;
63+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
64+
Ok(())
65+
}
66+
67+
fn mk<T>() -> Result<T, ()> {
68+
Err(())
69+
}
70+
71+
fn takes_apit2(_x: impl Default) {}
72+
73+
fn fully_apit() -> Result<(), ()> {
74+
//[e2021]~^ this function depends on never type fallback being `()`
75+
//[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!
76+
takes_apit2(mk()?);
77+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
78+
Ok(())
79+
}

tests/ui/never_type/fallback-closure-ret.nofallback.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ LL | foo(|| panic!());
1515
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
1616
help: use `()` annotations to avoid fallback changes
1717
|
18-
LL | foo::<(), _>(|| panic!());
19-
| +++++++++
18+
LL | foo::<()>(|| panic!());
19+
| ++++++
2020

2121
warning: 1 warning emitted
2222

0 commit comments

Comments
 (0)