Skip to content

Commit b4248ae

Browse files
nits
1 parent df6f584 commit b4248ae

1 file changed

Lines changed: 20 additions & 10 deletions

File tree

‎compiler/rustc_hir_typeck/src/fallback.rs‎

Lines changed: 20 additions & 10 deletions
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
fntry_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-
structVidVisitor<'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+
structAnnotateUnitFallbackVisitor<'a,'tcx>{
593598
reachable_vids:FxHashSet<ty::TyVid>,
594599
fcx:&'aFnCtxt<'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
fnsuggest_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>forVidVisitor<'_,'tcx>{
640+
impl<'tcx>Visitor<'tcx>forAnnotateUnitFallbackVisitor<'_,'tcx>{
631641
typeResult = ControlFlow<errors::SuggestAnnotation>;
632642

633643
fnvisit_ty(&mutself,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
ifletSome(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
fnvisit_expr(&mutself,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
iflet hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
672681
&& letRes::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
returnControlFlow::Break(errors::SuggestAnnotation::Path(span));
681690
}
682-
// Or elseturbofishing the method
691+
// Or else, try suggesting turbofishing the method args.
683692
iflet hir::ExprKind::MethodCall(segment, ..) = expr.kind
684693
&& letSome(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
fnvisit_local(&mutself,local:&'tcx hir::LetStmt<'tcx>) -> Self::Result{
702+
// For a local, try suggest annotating the type if it's missing.
693703
ifletNone = local.ty
694704
&& let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id)
695705
&& letSome(vid) = self.fcx.root_vid(ty)

0 commit comments

Comments
 (0)