1
Fork 0

Properly consider APITs for never type fallback ascription fix

This commit is contained in:
Michael Goulet 2024-12-10 20:59:02 +00:00
parent 21fe748be1
commit 2caada17c0
6 changed files with 142 additions and 26 deletions

View file

@ -613,19 +613,16 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
if arg_segment.args.is_none() if arg_segment.args.is_none()
&& let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id) && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
&& let generics = self.fcx.tcx.generics_of(def_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 :( // 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() if let Some(ty) = arg.as_type()
&& let Some(vid) = self.fcx.root_vid(ty) && let Some(vid) = self.fcx.root_vid(ty)
&& self.reachable_vids.contains(&vid) && self.reachable_vids.contains(&vid)

View file

@ -11,6 +11,8 @@ fn main() {
m(); m();
q(); q();
let _ = meow(); let _ = meow();
let _ = fallback_return();
let _ = fully_apit();
} }
fn m() { fn m() {
@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
Ok(()) 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(())
}

View file

@ -1,5 +1,5 @@
warning: this function depends on never type fallback being `()` 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() { 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> = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly = help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail 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(), LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
@ -19,7 +19,7 @@ LL | let x: () = match true {
| ++++ | ++++
warning: this function depends on never type fallback being `()` 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<()> { 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> = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly = help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail 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()?; LL | deserialize()?;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -38,7 +38,7 @@ LL | deserialize::<()>()?;
| ++++++ | ++++++
warning: this function depends on never type fallback being `()` 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<(), ()> { 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> = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
= help: specify the types explicitly = help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail 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)?; LL | help(1)?;
| ^^^^^^^ | ^^^^^^^
@ -56,5 +56,43 @@ help: use `()` annotations to avoid fallback changes
LL | help::<(), _>(1)?; 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

View file

@ -1,5 +1,5 @@
error[E0277]: the trait bound `!: Default` is not satisfied 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(), LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` | ^^^^^^^^^^^^^^^^^^ 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? = help: did you intend to use the type `()` here instead?
error[E0277]: the trait bound `!: Default` is not satisfied 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()?; LL | deserialize()?;
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` | ^^^^^^^^^^^^^ 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) = 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? = help: did you intend to use the type `()` here instead?
note: required by a bound in `deserialize` 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> { LL | fn deserialize<T: Default>() -> Option<T> {
| ^^^^^^^ required by this bound in `deserialize` | ^^^^^^^ required by this bound in `deserialize`
error[E0277]: the trait bound `(): From<!>` is not satisfied 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)?; LL | help(1)?;
| ^^^^^^^ the trait `From<!>` is not implemented for `()` | ^^^^^^^ the trait `From<!>` is not implemented for `()`
@ -39,11 +39,36 @@ LL | help(1)?;
and 4 others and 4 others
= note: required for `!` to implement `Into<()>` = note: required for `!` to implement `Into<()>`
note: required by a bound in `help` 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, ()> { LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
| ^^^^^^^^ required by this bound in `help` | ^^^^^^^^ 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`. For more information about this error, try `rustc --explain E0277`.

View file

@ -11,6 +11,8 @@ fn main() {
m(); m();
q(); q();
let _ = meow(); let _ = meow();
let _ = fallback_return();
let _ = fully_apit();
} }
fn m() { fn m() {
@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
Ok(()) 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(())
}

View file

@ -15,8 +15,8 @@ LL | foo(|| panic!());
= note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
help: use `()` annotations to avoid fallback changes help: use `()` annotations to avoid fallback changes
| |
LL | foo::<(), _>(|| panic!()); LL | foo::<()>(|| panic!());
| +++++++++ | ++++++
warning: 1 warning emitted warning: 1 warning emitted