Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly consider APITs for never type fallback ascription fix #134144

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/editions/never-type-fallback-breaking.e2021.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ fn main() {
m();
q();
let _ = meow();
let _ = fallback_return();
let _ = fully_apit();
}

fn m() {
Expand Down Expand Up @@ -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(())
}
52 changes: 45 additions & 7 deletions tests/ui/editions/never-type-fallback-breaking.e2021.stderr
Original file line number Diff line number Diff line change
@@ -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() {
| ^^^^^^
Expand All @@ -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(),
| ^^^^^^^^^^^^^^^^^^
Expand All @@ -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<()> {
| ^^^^^^^^^^^^^^^^^^^^
Expand All @@ -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()?;
| ^^^^^^^^^^^^^
Expand All @@ -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<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -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)?;
| ^^^^^^^
Expand All @@ -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

37 changes: 31 additions & 6 deletions tests/ui/editions/never-type-fallback-breaking.e2024.stderr
Original file line number Diff line number Diff line change
@@ -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 `!`
Expand All @@ -8,21 +8,21 @@ 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 `!`
|
= 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 `()`
Expand All @@ -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`.
28 changes: 28 additions & 0 deletions tests/ui/editions/never-type-fallback-breaking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ fn main() {
m();
q();
let _ = meow();
let _ = fallback_return();
let _ = fully_apit();
}

fn m() {
Expand Down Expand Up @@ -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(())
}
4 changes: 2 additions & 2 deletions tests/ui/never_type/fallback-closure-ret.nofallback.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Loading