Skip to content

Commit 956f5a5

Browse files
authored
Rollup merge of rust-lang#132383 - compiler-errors:never-type-fallback-sugg, r=WaffleLapkin
Implement suggestion for never type fallback lints r? `@WaffleLapkin` Just opening this up for vibes; it's not done yet. I'd still like to make this suggestable in a few more cases before merge: - [x] Try to annotate `_` -> `()` - [x] Try to annotate local variables if they're un-annotated: `let x = ...` -> `let x: () = ...` - [x] Try to annotate the self type of a `Trait::method()` -> `<() as Trait>::method()`. The only other case we may want to suggest is a missing turbofish, like `f()` -> `f::<()>()`. That may be possible, but seems overly annoying. This partly addresses rust-lang#132358; the other half of fixing that would be to make the error message a bit better, perhaps just special casing the `?` operator 🤔 I don't think I'll do that part.
2 parents 4c71509 + b4248ae commit 956f5a5

11 files changed

+370
-24
lines changed

compiler/rustc_hir_typeck/src/errors.rs

+78-5
Original file line numberDiff line numberDiff line change
@@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange {
169169
pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
170170
#[help]
171171
#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
172-
Call,
172+
Call {
173+
#[subdiagnostic]
174+
sugg: SuggestAnnotations,
175+
},
173176
#[help]
174177
#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
175-
Method,
178+
Method {
179+
#[subdiagnostic]
180+
sugg: SuggestAnnotations,
181+
},
176182
#[help]
177183
#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
178-
Path,
184+
Path {
185+
#[subdiagnostic]
186+
sugg: SuggestAnnotations,
187+
},
179188
#[help]
180189
#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
181-
UnionField,
190+
UnionField {
191+
#[subdiagnostic]
192+
sugg: SuggestAnnotations,
193+
},
182194
#[help]
183195
#[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
184-
Deref,
196+
Deref {
197+
#[subdiagnostic]
198+
sugg: SuggestAnnotations,
199+
},
185200
}
186201

187202
#[derive(LintDiagnostic)]
@@ -191,6 +206,64 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
191206
#[note]
192207
pub obligation_span: Span,
193208
pub obligation: ty::Predicate<'tcx>,
209+
#[subdiagnostic]
210+
pub sugg: SuggestAnnotations,
211+
}
212+
213+
#[derive(Clone)]
214+
pub(crate) enum SuggestAnnotation {
215+
Unit(Span),
216+
Path(Span),
217+
Local(Span),
218+
Turbo(Span, usize, usize),
219+
}
220+
221+
#[derive(Clone)]
222+
pub(crate) struct SuggestAnnotations {
223+
pub suggestions: Vec<SuggestAnnotation>,
224+
}
225+
impl Subdiagnostic for SuggestAnnotations {
226+
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
227+
self,
228+
diag: &mut Diag<'_, G>,
229+
_: &F,
230+
) {
231+
if self.suggestions.is_empty() {
232+
return;
233+
}
234+
235+
let mut suggestions = vec![];
236+
for suggestion in self.suggestions {
237+
match suggestion {
238+
SuggestAnnotation::Unit(span) => {
239+
suggestions.push((span, "()".to_string()));
240+
}
241+
SuggestAnnotation::Path(span) => {
242+
suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
243+
suggestions.push((span.shrink_to_hi(), ">".to_string()));
244+
}
245+
SuggestAnnotation::Local(span) => {
246+
suggestions.push((span, ": ()".to_string()));
247+
}
248+
SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
249+
span,
250+
format!(
251+
"::<{}>",
252+
(0..n_args)
253+
.map(|i| if i == idx { "()" } else { "_" })
254+
.collect::<Vec<_>>()
255+
.join(", "),
256+
),
257+
)),
258+
}
259+
}
260+
261+
diag.multipart_suggestion_verbose(
262+
"use `()` annotations to avoid fallback changes",
263+
suggestions,
264+
Applicability::MachineApplicable,
265+
);
266+
}
194267
}
195268

196269
#[derive(Subdiagnostic)]

0 commit comments

Comments
 (0)