Skip to content

Commit

Permalink
Properly consider APITs for never type fallback ascription fix
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 12, 2024
1 parent 21fe748 commit 2caada1
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 26 deletions.
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

0 comments on commit 2caada1

Please sign in to comment.