Skip to content

Commit 8917cc0

Browse files
authored
Rollup merge of rust-lang#105332 - estebank:iterator-chains, r=oli-obk
Point out the type of associated types in every method call of iterator chains Partially address rust-lang#105184 by pointing out the type of associated types in every method call of iterator chains: ``` note: the expression is of type `Map<std::slice::Iter<'_, {integer}>, [closure@src/test/ui/iterators/invalid-iterator-chain.rs:12:18: 12:21]>` --> src/test/ui/iterators/invalid-iterator-chain.rs:12:14 | 10 | vec![0, 1] | ---------- this expression has type `Vec<{integer}>` 11 | .iter() | ------ associated type `std::iter::Iterator::Item` is `&{integer}` here 12 | .map(|x| { x; }) | ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `()` here ``` We also reduce the number of impls we mention when any of the candidates is an "exact match". This benefits the output of cases with numerics greatly. Outstanding work would be to provide a structured suggestion for appropriate changes, like in this case detecting the spurious `;` in the closure.
2 parents 6dbaf86 + f4ed2d1 commit 8917cc0

33 files changed

+744
-185
lines changed

compiler/rustc_errors/src/diagnostic.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,11 @@ impl Diagnostic {
370370
self.set_span(after);
371371
for span_label in before.span_labels() {
372372
if let Some(label) = span_label.label {
373-
self.span.push_span_label(after, label);
373+
if span_label.is_primary {
374+
self.span.push_span_label(after, label);
375+
} else {
376+
self.span.push_span_label(span_label.span, label);
377+
}
374378
}
375379
}
376380
self
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use crate::infer::InferCtxt;
2+
3+
use rustc_middle::ty::error::TypeError;
4+
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
5+
use rustc_middle::ty::{self, Ty, TyCtxt};
6+
7+
pub struct CollectAllMismatches<'a, 'tcx> {
8+
pub infcx: &'a InferCtxt<'tcx>,
9+
pub param_env: ty::ParamEnv<'tcx>,
10+
pub errors: Vec<TypeError<'tcx>>,
11+
}
12+
13+
impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
14+
fn tag(&self) -> &'static str {
15+
"CollectAllMismatches"
16+
}
17+
fn tcx(&self) -> TyCtxt<'tcx> {
18+
self.infcx.tcx
19+
}
20+
fn intercrate(&self) -> bool {
21+
false
22+
}
23+
fn param_env(&self) -> ty::ParamEnv<'tcx> {
24+
self.param_env
25+
}
26+
fn a_is_expected(&self) -> bool {
27+
true
28+
} // irrelevant
29+
fn mark_ambiguous(&mut self) {
30+
bug!()
31+
}
32+
fn relate_with_variance<T: Relate<'tcx>>(
33+
&mut self,
34+
_: ty::Variance,
35+
_: ty::VarianceDiagInfo<'tcx>,
36+
a: T,
37+
b: T,
38+
) -> RelateResult<'tcx, T> {
39+
self.relate(a, b)
40+
}
41+
fn regions(
42+
&mut self,
43+
a: ty::Region<'tcx>,
44+
_b: ty::Region<'tcx>,
45+
) -> RelateResult<'tcx, ty::Region<'tcx>> {
46+
Ok(a)
47+
}
48+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
49+
if a == b || matches!(a.kind(), ty::Infer(_)) || matches!(b.kind(), ty::Infer(_)) {
50+
return Ok(a);
51+
}
52+
relate::super_relate_tys(self, a, b).or_else(|e| {
53+
self.errors.push(e);
54+
Ok(a)
55+
})
56+
}
57+
fn consts(
58+
&mut self,
59+
a: ty::Const<'tcx>,
60+
b: ty::Const<'tcx>,
61+
) -> RelateResult<'tcx, ty::Const<'tcx>> {
62+
if a == b {
63+
return Ok(a);
64+
}
65+
relate::super_relate_consts(self, a, b) // could do something similar here for constants!
66+
}
67+
fn binders<T: Relate<'tcx>>(
68+
&mut self,
69+
a: ty::Binder<'tcx, T>,
70+
b: ty::Binder<'tcx, T>,
71+
) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
72+
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
73+
}
74+
}

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod ambiguity;
2+
pub mod method_chain;
23
pub mod on_unimplemented;
34
pub mod suggestions;
45

@@ -536,7 +537,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
536537
|err| {
537538
self.note_obligation_cause_code(
538539
err,
539-
&predicate,
540+
predicate,
540541
obligation.param_env,
541542
obligation.cause.code(),
542543
&mut vec![],
@@ -1587,7 +1588,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15871588
{
15881589
self.note_obligation_cause_code(
15891590
&mut diag,
1590-
&error.obligation.predicate,
1591+
error.obligation.predicate,
15911592
error.obligation.param_env,
15921593
code,
15931594
&mut vec![],
@@ -2602,7 +2603,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
26022603
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
26032604
self.note_obligation_cause_code(
26042605
err,
2605-
&obligation.predicate,
2606+
obligation.predicate,
26062607
obligation.param_env,
26072608
obligation.cause.code(),
26082609
&mut vec![],

0 commit comments

Comments
 (0)