Skip to content

Commit 69d575e

Browse files
committed
eagerly fetch the typeck_results
1 parent bc0d12c commit 69d575e

File tree

1 file changed

+52
-28
lines changed

1 file changed

+52
-28
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+52-28
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMut
1212
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
1313
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
1414
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst};
15-
use rustc_middle::ty::{Ty, TyCtxt};
15+
use rustc_middle::ty::{Ty, TyCtxt, TypeckResults};
1616
use rustc_span::symbol::{kw, Ident};
1717
use rustc_span::{BytePos, Span};
1818
use std::borrow::Cow;
@@ -272,7 +272,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
272272
parent: None,
273273
}
274274
} else {
275-
// FIXME: This code seems a bit wrong, idk.
275+
// If we end up here the `FindInferSourceVisitor`
276+
// won't work, as its expected argument isn't an inference variable.
277+
//
278+
// FIXME: Ideally we should look into the generic constant
279+
// to figure out which inference var is actually unresolved so that
280+
// this path is unreachable.
276281
let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
277282
if let Some(highlight) = highlight {
278283
printer.region_highlight_mode = highlight;
@@ -289,6 +294,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
289294
}
290295
}
291296

297+
/// Used as a fallback in [InferCtxt::emit_inference_failure_err]
298+
/// in case we weren't able to get a better error.
299+
fn bad_inference_failure_err(
300+
&self,
301+
span: Span,
302+
arg_data: InferenceDiagnosticsData,
303+
error_code: TypeAnnotationNeeded,
304+
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
305+
let error_code = error_code.into();
306+
let mut err = self.tcx.sess.struct_span_err_with_code(
307+
span,
308+
&format!("type annotations needed"),
309+
error_code,
310+
);
311+
err.span_label(span, arg_data.cannot_infer_msg());
312+
err
313+
}
314+
292315
pub fn emit_inference_failure_err(
293316
&self,
294317
body_id: Option<hir::BodyId>,
@@ -301,25 +324,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
301324
let arg = self.resolve_vars_if_possible(arg);
302325
let arg_data = self.extract_inference_diagnostics_data(arg, None);
303326

304-
let mut local_visitor = FindInferSourceVisitor::new(&self, arg);
327+
let Some(typeck_results) = self.in_progress_typeck_results else {
328+
// If we don't have any typeck results we're outside
329+
// of a body, so we won't be able to get better info
330+
// here.
331+
return self.bad_inference_failure_err(span, arg_data, error_code);
332+
};
333+
let typeck_results = typeck_results.borrow();
334+
let typeck_results = &typeck_results;
335+
336+
let mut local_visitor = FindInferSourceVisitor::new(&self, typeck_results, arg);
305337
if let Some(body_id) = body_id {
306338
let expr = self.tcx.hir().expect_expr(body_id.hir_id);
307339
debug!(?expr);
308340
local_visitor.visit_expr(expr);
309341
}
310342

311343
let Some(InferSource { span, kind }) = local_visitor.infer_source else {
312-
let error_code = error_code.into();
313-
let mut err = self.tcx.sess.struct_span_err_with_code(
314-
span,
315-
&format!("type annotations needed"),
316-
error_code,
317-
);
318-
err.span_label(
319-
span,
320-
arg_data.cannot_infer_msg(),
321-
);
322-
return err;
344+
return self.bad_inference_failure_err(span, arg_data, error_code)
323345
};
324346

325347
let error_code = error_code.into();
@@ -394,8 +416,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
394416
);
395417
}
396418
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
397-
let typeck_results = self.in_progress_typeck_results.unwrap();
398-
let typeck_results = typeck_results.borrow();
399419
let printer = fmt_printer(self, Namespace::ValueNS);
400420
let def_path = printer.print_def_path(def_id, substs).unwrap().into_buffer();
401421

@@ -548,6 +568,8 @@ struct InsertableGenericArgs<'tcx> {
548568
/// For details on how we rank spots, see [Self::source_cost]
549569
struct FindInferSourceVisitor<'a, 'tcx> {
550570
infcx: &'a InferCtxt<'a, 'tcx>,
571+
typeck_results: &'a TypeckResults<'tcx>,
572+
551573
target: GenericArg<'tcx>,
552574

553575
attempt: usize,
@@ -556,9 +578,15 @@ struct FindInferSourceVisitor<'a, 'tcx> {
556578
}
557579

558580
impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
559-
fn new(infcx: &'a InferCtxt<'a, 'tcx>, target: GenericArg<'tcx>) -> Self {
581+
fn new(
582+
infcx: &'a InferCtxt<'a, 'tcx>,
583+
typeck_results: &'a TypeckResults<'tcx>,
584+
target: GenericArg<'tcx>,
585+
) -> Self {
560586
FindInferSourceVisitor {
561587
infcx,
588+
typeck_results,
589+
562590
target,
563591

564592
attempt: 0,
@@ -603,7 +631,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
603631
variant_cost + generic_args.iter().map(|&arg| arg_cost(arg)).sum::<usize>()
604632
}
605633
InferSourceKind::FullyQualifiedMethodCall { substs, .. } => {
606-
// FIXME: We should also consider the cost of lifetimes and constants here.
607634
20 + substs.iter().map(|arg| arg_cost(arg)).sum::<usize>()
608635
}
609636
InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
@@ -625,7 +652,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
625652
}
626653

627654
fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
628-
let ty = self.infcx.in_progress_typeck_results?.borrow().node_type_opt(hir_id);
655+
let ty = self.typeck_results.node_type_opt(hir_id);
629656
self.infcx.resolve_vars_if_possible(ty)
630657
}
631658

@@ -698,10 +725,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
698725
expr: &'tcx hir::Expr<'tcx>,
699726
) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
700727
let tcx = self.infcx.tcx;
701-
let typeck_results = self.infcx.in_progress_typeck_results.unwrap().borrow();
702728
match expr.kind {
703729
hir::ExprKind::Path(ref path) => {
704-
if let Some(substs) = typeck_results.node_substs_opt(expr.hir_id) {
730+
if let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id) {
705731
return self.path_inferred_subst_iter(expr.hir_id, substs, path);
706732
}
707733
}
@@ -713,13 +739,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
713739
}
714740
}
715741
hir::ExprKind::MethodCall(segment, _, _) => {
716-
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
742+
if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
717743
let generics = tcx.generics_of(def_id);
718744
let insertable: Option<_> = try {
719745
if generics.has_impl_trait() {
720746
None?
721747
}
722-
let substs = typeck_results.node_substs_opt(expr.hir_id)?;
748+
let substs = self.typeck_results.node_substs_opt(expr.hir_id)?;
723749
let span = tcx.hir().span(segment.hir_id?);
724750
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
725751
InsertableGenericArgs {
@@ -793,13 +819,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
793819
qpath: &'tcx hir::QPath<'tcx>,
794820
) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
795821
let tcx = self.infcx.tcx;
796-
let typeck_results = self.infcx.in_progress_typeck_results.unwrap().borrow();
797822
match qpath {
798823
hir::QPath::Resolved(_self_ty, path) => {
799824
Box::new(self.resolved_path_inferred_subst_iter(path, substs))
800825
}
801826
hir::QPath::TypeRelative(ty, segment) => {
802-
let Some(def_id) = typeck_results.type_dependent_def_id(hir_id) else {
827+
let Some(def_id) = self.typeck_results.type_dependent_def_id(hir_id) else {
803828
return Box::new(iter::empty());
804829
};
805830

@@ -996,10 +1021,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
9961021
.any(|generics| generics.has_impl_trait())
9971022
};
9981023
if let ExprKind::MethodCall(path, args, span) = expr.kind
999-
&& let Some(typeck_results) = self.infcx.in_progress_typeck_results
1000-
&& let Some(substs) = typeck_results.borrow().node_substs_opt(expr.hir_id)
1024+
&& let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id)
10011025
&& substs.iter().any(|arg| self.generic_arg_contains_target(arg))
1002-
&& let Some(def_id) = typeck_results.borrow().type_dependent_def_id(expr.hir_id)
1026+
&& let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
10031027
&& self.infcx.tcx.trait_of_item(def_id).is_some()
10041028
&& !has_impl_trait(def_id)
10051029
{

0 commit comments

Comments
 (0)