diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ddd146fe785e3..b57c248ed2bf1 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 91d30de74c7c0..11ec273fc4bf9 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(_y: impl Fn() -> T) -> Result { + 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() -> Result { + 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 6fdb548c4317a..9009d61793613 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 = 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 = 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 = 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 + = 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 + = 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 9d79dfb4099fb..2daf00f7804ff 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 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() -> Option { | ^^^^^^^ 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 { | ^^^^^^^^ 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 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 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 24e33ff6bf6b7..daafc526eff41 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(_y: impl Fn() -> T) -> Result { + 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() -> Result { + 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 b5b5d87e7dd06..8d08fb7f2a821 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