From cac63ffc0fe4d963f902311d5938e03a0a8437aa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Feb 2025 18:59:07 +0000 Subject: [PATCH 1/2] Only suggest unit for unit fallback when spans dont come from macro expansion --- compiler/rustc_hir_typeck/src/fallback.rs | 12 ++++++++-- .../dont-suggest-turbofish-from-expansion.rs | 20 +++++++++++++++++ ...nt-suggest-turbofish-from-expansion.stderr | 22 +++++++++++++++++++ ...-fallback-flowing-into-unsafe.e2015.stderr | 4 ---- ...-fallback-flowing-into-unsafe.e2024.stderr | 4 ---- 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs create mode 100644 tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 1f3f03b992997..b09649f006d79 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -651,6 +651,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { if let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(inf_id) && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) + && inf_span.can_be_used_for_suggestions() { return ControlFlow::Break(errors::SuggestAnnotation::Unit(inf_span)); } @@ -662,7 +663,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { &mut self, qpath: &'tcx rustc_hir::QPath<'tcx>, id: HirId, - _span: Span, + span: Span, ) -> Self::Result { let arg_segment = match qpath { hir::QPath::Resolved(_, path) => { @@ -674,7 +675,9 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { } }; // Alternatively, try to turbofish `::<_, (), _>`. - if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { + if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() + && span.can_be_used_for_suggestions() + { self.suggest_for_segment(arg_segment, def_id, id)?; } hir::intravisit::walk_qpath(self, qpath, id) @@ -691,17 +694,21 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { && let Some(vid) = self.fcx.root_vid(self_ty) && self.reachable_vids.contains(&vid) && let [.., trait_segment, _method_segment] = path.segments + && expr.span.can_be_used_for_suggestions() { let span = path.span.shrink_to_lo().to(trait_segment.ident.span); return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); } + // Or else, try suggesting turbofishing the method args. if let hir::ExprKind::MethodCall(segment, ..) = expr.kind && let Some(def_id) = self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + && expr.span.can_be_used_for_suggestions() { self.suggest_for_segment(segment, def_id, expr.hir_id)?; } + hir::intravisit::walk_expr(self, expr) } @@ -712,6 +719,7 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { && let Some(ty) = self.fcx.typeck_results.borrow().node_type_opt(local.hir_id) && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) + && local.span.can_be_used_for_suggestions() { return ControlFlow::Break(errors::SuggestAnnotation::Local( local.pat.span.shrink_to_hi(), diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs new file mode 100644 index 0000000000000..9a53358464d8c --- /dev/null +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs @@ -0,0 +1,20 @@ +#![deny(dependency_on_unit_never_type_fallback)] + +fn create_ok_default() -> Result +where + C: Default, +{ + Ok(C::default()) +} + +fn main() -> Result<(), ()> { + //~^ ERROR this function depends on never type fallback being `()` + //~| WARN this was previously accepted by the compiler but is being phased out + let (returned_value, _) = (|| { + let created = create_ok_default()?; + Ok((created, ())) + })()?; + + let _ = format_args!("{:?}", returned_value); + Ok(()) +} diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr new file mode 100644 index 0000000000000..b72324129e588 --- /dev/null +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr @@ -0,0 +1,22 @@ +error: this function depends on never type fallback being `()` + --> $DIR/dont-suggest-turbofish-from-expansion.rs:10:1 + | +LL | fn main() -> 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 + = help: specify the types explicitly +note: in edition 2024, the requirement `!: Default` will fail + --> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23 + | +LL | let created = create_ok_default()?; + | ^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/dont-suggest-turbofish-from-expansion.rs:1:9 + | +LL | #![deny(dependency_on_unit_never_type_fallback)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index 04cd2fcafd673..49b966f32ced5 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -130,10 +130,6 @@ LL | msg_send!(); = note: for more information, see = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use `()` annotations to avoid fallback changes - | -LL | match send_message::<() /* ?0 */>() { - | ~~ warning: 10 warnings emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 7adba2cc709c0..4d3692a7b0432 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -130,10 +130,6 @@ LL | msg_send!(); = note: for more information, see = help: specify the type explicitly = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use `()` annotations to avoid fallback changes - | -LL | match send_message::<() /* ?0 */>() { - | ~~ warning: the type `!` does not permit zero-initialization --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 From eb9bba879a33995ae6769cbb906d45370f0af018 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Feb 2025 19:01:26 +0000 Subject: [PATCH 2/2] Walk into nested bodies when suggesting unit for unit fallback --- compiler/rustc_hir_typeck/src/fallback.rs | 6 ++++++ .../never_type/dont-suggest-turbofish-from-expansion.stderr | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index b09649f006d79..4618c5d3849b3 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -684,6 +684,12 @@ impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + if let hir::ExprKind::Closure(&hir::Closure { body, .. }) + | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) = expr.kind + { + self.visit_body(self.fcx.tcx.hir().body(body))?; + } + // Try to suggest adding an explicit qself `()` to a trait method path. // i.e. changing `Default::default()` to `<() as Default>::default()`. if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr index b72324129e588..3fe642a8401a2 100644 --- a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr @@ -17,6 +17,10 @@ note: the lint level is defined here | LL | #![deny(dependency_on_unit_never_type_fallback)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | let created: () = create_ok_default()?; + | ++++ error: aborting due to 1 previous error