From c930bba2836c1daa4ffa72ce3ec4d3e570ce188e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 16:05:42 +0000 Subject: [PATCH] And locals too --- compiler/rustc_hir_typeck/src/errors.rs | 4 ++++ compiler/rustc_hir_typeck/src/fallback.rs | 13 +++++++++++++ .../never-type-fallback-breaking.e2021.stderr | 4 ++-- .../defaulted-never-note.nofallback.stderr | 4 ++++ ...iverging-fallback-control-flow.nofallback.stderr | 8 ++++---- ...-fallback-unconstrained-return.nofallback.stderr | 4 ++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 2f09e5e163c15..fdeeed92565c3 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -214,6 +214,7 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { pub(crate) enum SuggestAnnotation { Unit(Span), Path(Span), + Local(Span), } #[derive(Clone)] @@ -240,6 +241,9 @@ impl Subdiagnostic for SuggestAnnotations { suggestions.push((span.shrink_to_lo(), "<() as ".to_string())); suggestions.push((span.shrink_to_hi(), ">".to_string())); } + SuggestAnnotation::Local(span) => { + suggestions.push((span, ": ()".to_string())); + } } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index d6be237acf4d6..cefc28b400f6e 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -620,6 +620,19 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { } hir::intravisit::walk_expr(self, expr) } + + fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result { + if let None = local.ty + && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Local( + local.pat.span.shrink_to_hi(), + )); + } + hir::intravisit::walk_local(self, local) + } } #[derive(Debug, Copy, Clone)] diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 703f3d6266cf6..1c6685261fb3e 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -15,8 +15,8 @@ LL | true => Default::default(), = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default help: use `()` annotations to avoid fallback changes | -LL | true => <() as Default>::default(), - | ++++++ + +LL | let x: () = match true { + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/never-type-fallback-breaking.rs:27:1 diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index d88615186dd63..6bc4501b6a375 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f LL | foo(_x); | ^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _x: () = return; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index dee112e245a76..d40d1da76f9ac 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -15,8 +15,8 @@ LL | x = UnitDefault::default(); = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default help: use `()` annotations to avoid fallback changes | -LL | x = <() as UnitDefault>::default(); - | ++++++ + +LL | let x: (); + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-control-flow.rs:42:1 @@ -34,8 +34,8 @@ LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ help: use `()` annotations to avoid fallback changes | -LL | x = <() as UnitDefault>::default(); - | ++++++ + +LL | let x: (); + | ++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index b485c94df4d6f..30a5e60a75848 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ warning: 1 warning emitted