Skip to content

Commit 98e0f7a

Browse files
committed
Improve diag when calling method on result of index op
1 parent 1689a5a commit 98e0f7a

File tree

4 files changed

+73
-10
lines changed

4 files changed

+73
-10
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use rustc_hir::lang_items::LangItem;
3636
use rustc_hir::{ExprKind, HirId, QPath};
3737
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
3838
use rustc_infer::infer;
39+
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
3940
use rustc_infer::infer::DefineOpaqueTypes;
4041
use rustc_infer::infer::InferOk;
4142
use rustc_infer::traits::query::NoSolution;
@@ -1330,7 +1331,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13301331
) -> Ty<'tcx> {
13311332
let rcvr_t = self.check_expr(rcvr);
13321333
// no need to check for bot/err -- callee does that
1333-
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
1334+
let rcvr_t = if let ExprKind::Index(_, index, _) = rcvr.kind {
1335+
let ty = self.try_structurally_resolve_type(rcvr.span, rcvr_t);
1336+
1337+
if !ty.is_ty_var() {
1338+
ty
1339+
} else {
1340+
let e = self
1341+
.tainted_by_errors()
1342+
.or_else(|| self.report_ambiguity_errors())
1343+
.unwrap_or_else(|| {
1344+
self.err_ctxt()
1345+
.emit_inference_failure_err(
1346+
self.body_id,
1347+
index.span,
1348+
ty.into(),
1349+
E0282,
1350+
true,
1351+
)
1352+
.emit()
1353+
});
1354+
1355+
let err = Ty::new_error(self.tcx, e);
1356+
self.demand_suptype(rcvr.span, err, ty);
1357+
err
1358+
}
1359+
} else {
1360+
self.structurally_resolve_type(rcvr.span, rcvr_t)
1361+
};
1362+
13341363
let span = segment.ident.span;
13351364

13361365
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -589,18 +589,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
589589
}
590590

591591
#[instrument(skip(self), level = "debug")]
592-
pub(crate) fn report_ambiguity_errors(&self) {
592+
pub(crate) fn report_ambiguity_errors(&self) -> Option<ErrorGuaranteed> {
593593
let mut errors = self.fulfillment_cx.borrow_mut().collect_remaining_errors(self);
594594

595-
if !errors.is_empty() {
596-
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
597-
let errors_causecode = errors
598-
.iter()
599-
.map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone()))
600-
.collect::<Vec<_>>();
601-
self.err_ctxt().report_fulfillment_errors(errors);
602-
self.collect_unused_stmts_for_coerce_return_ty(errors_causecode);
595+
if errors.is_empty() {
596+
return None;
603597
}
598+
599+
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
600+
let errors_causecode = errors
601+
.iter()
602+
.map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone()))
603+
.collect::<Vec<_>>();
604+
let e = self.err_ctxt().report_fulfillment_errors(errors);
605+
self.collect_unused_stmts_for_coerce_return_ty(errors_causecode);
606+
Some(e)
604607
}
605608

606609
/// Select as many obligations as we can at present.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
struct Foo;
2+
3+
impl Foo {
4+
fn foo(&self) {}
5+
}
6+
7+
fn main() {
8+
let thing: Vec<Foo> = vec![];
9+
10+
let foo = |i| { //~ ERROR type annotations needed
11+
thing[i].foo();
12+
};
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/calling-method-on-result-of-index-op-issue-125924.rs:10:16
3+
|
4+
LL | let foo = |i| {
5+
| ^
6+
LL | thing[i].foo();
7+
| -------- type must be known at this point
8+
|
9+
= note: cannot satisfy `_: SliceIndex<[Foo]>`
10+
= note: required for `Vec<Foo>` to implement `Index<_>`
11+
help: consider giving this closure parameter an explicit type
12+
|
13+
LL | let foo = |i: /* Type */| {
14+
| ++++++++++++
15+
16+
error: aborting due to 1 previous error
17+
18+
For more information about this error, try `rustc --explain E0283`.

0 commit comments

Comments
 (0)