Skip to content

Commit

Permalink
Print type of every call in a method call chain
Browse files Browse the repository at this point in the history
```
error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
  --> $DIR/issue-33941.rs:6:36
   |
LL |     for _ in HashMap::new().iter().cloned() {}
   |              ------------   ----   ^^^^^^ expected reference, found tuple
   |              |              |
   |              |              this call is of type `std::collections::hash_map::Iter<'_, _, _>`
   |              this call is of type `&HashMap<_, _>`
   |
   = note: expected reference `&_`
                  found tuple `(&_, &_)`
note: required by a bound in `cloned`
  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
   |
LL |         Self: Sized + Iterator<Item = &'a T>,
   |                                ^^^^^^^^^^^^ required by this bound in `cloned`
```

Partially address #33941.
  • Loading branch information
estebank committed May 10, 2022
1 parent eead58e commit 458fdb3
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
51 changes: 51 additions & 0 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,36 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
"type mismatch resolving `{}`",
predicate
);
let mut v = HirFinder { needle: obligation.cause.span, found: None };
let body = self.tcx.hir().get(obligation.cause.body_id);
if let hir::Node::Expr(expr) = body {
v.visit_expr(expr);
}
if let Some(expr) = v.found {
// FIXME(estebank): look for method calls that can be applied on the previous
// element of the chain, that would make the next call to typeck.
let mut receiver = expr;
if let (Some(typeck_results), hir::ExprKind::MethodCall(..)) =
(self.in_progress_typeck_results, &receiver.kind)
{
let typeck_results = typeck_results.borrow();
while let hir::ExprKind::MethodCall(method_segment, args, _) = receiver.kind {
if let Some(ty) = typeck_results.expr_ty_adjusted_opt(receiver) {
diag.span_label(
method_segment.ident.span,
&format!("this call is of type `{ty}`"),
);
}
receiver = &args[0];
}
while let hir::ExprKind::Call(path, _args) = receiver.kind {
if let Some(ty) = typeck_results.expr_ty_adjusted_opt(receiver) {
diag.span_label(path.span, &format!("this call is of type `{ty}`"));
}
receiver = &path;
}
}
}
let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Projection(proj) => self
.tcx
Expand Down Expand Up @@ -2689,3 +2719,24 @@ impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor {
}
}
}

struct HirFinder<'tcx> {
needle: Span,
found: Option<&'tcx hir::Expr<'tcx>>,
}

impl<'v> Visitor<'v> for HirFinder<'v> {
fn visit_expr(&mut self, expr: &'v hir::Expr<'v>) {
if expr.span == self.needle {
self.found = Some(expr);
return;
}
if let hir::ExprKind::MethodCall(segment, _, _) = expr.kind {
if segment.ident.span == self.needle {
self.found = Some(expr);
return;
}
}
hir::intravisit::walk_expr(self, expr);
}
}
3 changes: 3 additions & 0 deletions src/test/ui/issues/issue-31173.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
error[E0271]: type mismatch resolving `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6]> as Iterator>::Item == &_`
--> $DIR/issue-31173.rs:10:10
|
LL | let temp: Vec<u8> = it.take_while(|&x| {
| ---------- this call is of type `TakeWhile<&mut std::vec::IntoIter<u8>, _>`
...
LL | .cloned()
| ^^^^^^ expected reference, found `u8`
|
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/issues/issue-33941.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _,
--> $DIR/issue-33941.rs:6:36
|
LL | for _ in HashMap::new().iter().cloned() {}
| ^^^^^^ expected reference, found tuple
| ------------ ---- ^^^^^^ expected reference, found tuple
| | |
| | this call is of type `std::collections::hash_map::Iter<'_, _, _>`
| this call is of type `&HashMap<_, _>`
|
= note: expected reference `&_`
found tuple `(&_, &_)`
Expand Down

0 comments on commit 458fdb3

Please sign in to comment.