Skip to content

Commit b4248ae

Browse files
nits
1 parent df6f584 commit b4248ae

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

compiler/rustc_hir_typeck/src/fallback.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
565565
Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
566566
}
567567

568+
/// Given a set of diverging vids and coercions, walk the HIR to gather a
569+
/// set of suggestions which can be applied to preserve fallback to unit.
568570
fn try_to_suggest_annotations(
569571
&self,
570572
diverging_vids: &[ty::TyVid],
@@ -574,26 +576,34 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
574576
self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner");
575577
// For each diverging var, look through the HIR for a place to give it
576578
// a type annotation. We do this per var because we only really need one
577-
// per var.
579+
// suggestion to influence a var to be `()`.
578580
let suggestions = diverging_vids
579581
.iter()
580582
.copied()
581583
.filter_map(|vid| {
582584
let reachable_vids =
583585
graph::depth_first_search_as_undirected(coercions, vid).collect();
584-
VidVisitor { reachable_vids, fcx: self }.visit_expr(body.value).break_value()
586+
AnnotateUnitFallbackVisitor { reachable_vids, fcx: self }
587+
.visit_expr(body.value)
588+
.break_value()
585589
})
586590
.collect();
587591
errors::SuggestAnnotations { suggestions }
588592
}
589593
}
590594

591-
/// Try to collect a useful suggestion to preserve fallback to `()`.
592-
struct VidVisitor<'a, 'tcx> {
595+
/// Try to walk the HIR to find a place to insert a useful suggestion
596+
/// to preserve fallback to `()` in 2024.
597+
struct AnnotateUnitFallbackVisitor<'a, 'tcx> {
593598
reachable_vids: FxHashSet<ty::TyVid>,
594599
fcx: &'a FnCtxt<'a, 'tcx>,
595600
}
596-
impl<'tcx> VidVisitor<'_, 'tcx> {
601+
impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
602+
// For a given path segment, if it's missing a turbofish, try to suggest adding
603+
// one so we can constrain an argument to `()`. To keep the suggestion simple,
604+
// we want to simply suggest `_` for all the other args. This (for now) only
605+
// works when there are only type variables (and region variables, since we can
606+
// elide them)...
597607
fn suggest_for_segment(
598608
&self,
599609
arg_segment: &'tcx hir::PathSegment<'tcx>,
@@ -627,7 +637,7 @@ impl<'tcx> VidVisitor<'_, 'tcx> {
627637
ControlFlow::Continue(())
628638
}
629639
}
630-
impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> {
640+
impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
631641
type Result = ControlFlow<errors::SuggestAnnotation>;
632642

633643
fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result {
@@ -657,9 +667,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> {
657667
return hir::intravisit::walk_qpath(self, qpath, id);
658668
}
659669
};
660-
// Alternatively, try to turbofish `::<_, (), _>` (ignoring lifetimes,
661-
// since we don't need to turbofish those; they'll be inferred).
662-
// FIXME: Same logic could work for types...
670+
// Alternatively, try to turbofish `::<_, (), _>`.
663671
if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() {
664672
self.suggest_for_segment(arg_segment, def_id, id)?;
665673
}
@@ -668,6 +676,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> {
668676

669677
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
670678
// Try to suggest adding an explicit qself `()` to a trait method path.
679+
// i.e. changing `Default::default()` to `<() as Default>::default()`.
671680
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
672681
&& let Res::Def(DefKind::AssocFn, def_id) = path.res
673682
&& self.fcx.tcx.trait_of_item(def_id).is_some()
@@ -679,7 +688,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> {
679688
let span = path.span.shrink_to_lo().to(trait_segment.ident.span);
680689
return ControlFlow::Break(errors::SuggestAnnotation::Path(span));
681690
}
682-
// Or else turbofishing the method
691+
// Or else, try suggesting turbofishing the method args.
683692
if let hir::ExprKind::MethodCall(segment, ..) = expr.kind
684693
&& let Some(def_id) =
685694
self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
@@ -690,6 +699,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> {
690699
}
691700

692701
fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result {
702+
// For a local, try suggest annotating the type if it's missing.
693703
if let None = local.ty
694704
&& let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id)
695705
&& let Some(vid) = self.fcx.root_vid(ty)

0 commit comments

Comments
 (0)