Skip to content

Commit 4a0c5ec

Browse files
committed
Formatting
1 parent af68e2f commit 4a0c5ec

File tree

1 file changed

+135
-127
lines changed

1 file changed

+135
-127
lines changed

compiler/rustc_hir_typeck/src/demand.rs

+135-127
Original file line numberDiff line numberDiff line change
@@ -294,143 +294,151 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
294294
let id = map.get_parent_item(hir_id);
295295
let hir_id: hir::HirId = id.into();
296296

297-
if let Some(node) = map.find(hir_id) && let Some(body_id) = node.body_id() {
298-
let body = map.body(body_id);
299-
expr_finder.visit_expr(body.value);
300-
let mut eraser = TypeEraser { tcx };
301-
let mut prev = eraser.fold_ty(ty);
302-
let mut prev_span = None;
303-
304-
for binding in expr_finder.uses {
305-
// In every expression where the binding is referenced, we will look at that
306-
// expression's type and see if it is where the incorrect found type was fully
307-
// "materialized" and point at it. We will also try to provide a suggestion there.
308-
let parent = map.get_parent_node(binding.hir_id);
309-
if let Some(hir::Node::Expr(expr))
310-
| Some(hir::Node::Stmt(hir::Stmt {
311-
kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr),
312-
..
313-
})) = &map.find(parent)
314-
&& let hir::ExprKind::MethodCall(s, rcvr, args, _span) = expr.kind
315-
&& rcvr.hir_id == binding.hir_id
316-
&& let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
317-
{
318-
// We special case methods, because they can influence inference through the
319-
// call's arguments and we can provide a more explicit span.
320-
let sig = self.tcx.fn_sig(def_id);
321-
let def_self_ty = sig.input(0).skip_binder();
322-
let rcvr_ty = self.node_ty(rcvr.hir_id);
323-
// Get the evaluated type *after* calling the method call, so that the influence
324-
// of the arguments can be reflected in the receiver type. The receiver
325-
// expression has the type *before* theis analysis is done.
326-
let ty = match self.lookup_probe(s.ident, rcvr_ty, expr, probe::ProbeScope::TraitsInScope) {
327-
Ok(pick) => pick.self_ty,
328-
Err(_) => rcvr_ty,
329-
};
330-
// Remove one layer of references to account for `&mut self` and
331-
// `&self`, so that we can compare it against the binding.
332-
let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) {
333-
(ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty),
334-
_ => (ty, def_self_ty),
335-
};
336-
let mut param_args = FxHashMap::default();
337-
let mut param_expected = FxHashMap::default();
338-
let mut param_found = FxHashMap::default();
339-
if self.can_eq(self.param_env, ty, found).is_ok() {
340-
// We only point at the first place where the found type was inferred.
341-
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
342-
if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
343-
// We found an argument that references a type parameter in `Self`,
344-
// so we assume that this is the argument that caused the found
345-
// type, which we know already because of `can_eq` above was first
346-
// inferred in this method call.
347-
let arg = &args[i];
348-
let arg_ty = self.node_ty(arg.hir_id);
349-
err.span_label(
350-
arg.span,
351-
&format!(
352-
"this is of type `{arg_ty}`, which makes `{ident}` to be \
353-
inferred as `{ty}`",
354-
),
355-
);
356-
param_args.insert(param_ty, (arg, arg_ty));
357-
}
297+
let Some(node) = map.find(hir_id) else { return false; };
298+
let Some(body_id) = node.body_id() else { return false; };
299+
let body = map.body(body_id);
300+
expr_finder.visit_expr(body.value);
301+
let mut eraser = TypeEraser { tcx };
302+
let mut prev = eraser.fold_ty(ty);
303+
let mut prev_span = None;
304+
305+
for binding in expr_finder.uses {
306+
// In every expression where the binding is referenced, we will look at that
307+
// expression's type and see if it is where the incorrect found type was fully
308+
// "materialized" and point at it. We will also try to provide a suggestion there.
309+
let parent = map.get_parent_node(binding.hir_id);
310+
if let Some(hir::Node::Expr(expr))
311+
| Some(hir::Node::Stmt(hir::Stmt {
312+
kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr),
313+
..
314+
})) = &map.find(parent)
315+
&& let hir::ExprKind::MethodCall(segment, rcvr, args, _span) = expr.kind
316+
&& rcvr.hir_id == binding.hir_id
317+
&& let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
318+
{
319+
// We special case methods, because they can influence inference through the
320+
// call's arguments and we can provide a more explicit span.
321+
let sig = self.tcx.fn_sig(def_id);
322+
let def_self_ty = sig.input(0).skip_binder();
323+
let rcvr_ty = self.node_ty(rcvr.hir_id);
324+
// Get the evaluated type *after* calling the method call, so that the influence
325+
// of the arguments can be reflected in the receiver type. The receiver
326+
// expression has the type *before* theis analysis is done.
327+
let ty = match self.lookup_probe(
328+
segment.ident,
329+
rcvr_ty,
330+
expr,
331+
probe::ProbeScope::TraitsInScope,
332+
) {
333+
Ok(pick) => pick.self_ty,
334+
Err(_) => rcvr_ty,
335+
};
336+
// Remove one layer of references to account for `&mut self` and
337+
// `&self`, so that we can compare it against the binding.
338+
let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) {
339+
(ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty),
340+
_ => (ty, def_self_ty),
341+
};
342+
let mut param_args = FxHashMap::default();
343+
let mut param_expected = FxHashMap::default();
344+
let mut param_found = FxHashMap::default();
345+
if self.can_eq(self.param_env, ty, found).is_ok() {
346+
// We only point at the first place where the found type was inferred.
347+
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
348+
if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
349+
// We found an argument that references a type parameter in `Self`,
350+
// so we assume that this is the argument that caused the found
351+
// type, which we know already because of `can_eq` above was first
352+
// inferred in this method call.
353+
let arg = &args[i];
354+
let arg_ty = self.node_ty(arg.hir_id);
355+
err.span_label(
356+
arg.span,
357+
&format!(
358+
"this is of type `{arg_ty}`, which makes `{ident}` to be \
359+
inferred as `{ty}`",
360+
),
361+
);
362+
param_args.insert(param_ty, (arg, arg_ty));
358363
}
359364
}
365+
}
360366

361-
// Here we find, for a type param `T`, the type that `T` is in the current
362-
// method call *and* in the original expected type. That way, we can see if we
363-
// can give any structured suggestion for the function argument.
364-
let mut c = CollectAllMismatches {
365-
infcx: &self.infcx,
366-
param_env: self.param_env,
367-
errors: vec![],
368-
};
369-
let _ = c.relate(def_self_ty, ty);
370-
for error in c.errors {
371-
if let TypeError::Sorts(error) = error {
372-
param_found.insert(error.expected, error.found);
373-
}
374-
}
375-
c.errors = vec![];
376-
let _ = c.relate(def_self_ty, expected);
377-
for error in c.errors {
378-
if let TypeError::Sorts(error) = error {
379-
param_expected.insert(error.expected, error.found);
380-
}
367+
// Here we find, for a type param `T`, the type that `T` is in the current
368+
// method call *and* in the original expected type. That way, we can see if we
369+
// can give any structured suggestion for the function argument.
370+
let mut c = CollectAllMismatches {
371+
infcx: &self.infcx,
372+
param_env: self.param_env,
373+
errors: vec![],
374+
};
375+
let _ = c.relate(def_self_ty, ty);
376+
for error in c.errors {
377+
if let TypeError::Sorts(error) = error {
378+
param_found.insert(error.expected, error.found);
381379
}
382-
for (param, (arg,arg_ty)) in param_args.iter() {
383-
let Some(expected) = param_expected.get(param) else { continue; };
384-
let Some(found) = param_found.get(param) else { continue; };
385-
if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; }
386-
self.suggest_deref_ref_or_into(err, arg, *expected, *found, None);
380+
}
381+
c.errors = vec![];
382+
let _ = c.relate(def_self_ty, expected);
383+
for error in c.errors {
384+
if let TypeError::Sorts(error) = error {
385+
param_expected.insert(error.expected, error.found);
387386
}
387+
}
388+
for (param, (arg,arg_ty)) in param_args.iter() {
389+
let Some(expected) = param_expected.get(param) else { continue; };
390+
let Some(found) = param_found.get(param) else { continue; };
391+
if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; }
392+
self.suggest_deref_ref_or_into(err, arg, *expected, *found, None);
393+
}
388394

389-
let ty = eraser.fold_ty(ty);
390-
if ty.references_error() {
391-
break;
392-
}
393-
if ty != prev
394-
&& param_args.is_empty()
395-
&& self.can_eq(self.param_env, ty, found).is_ok()
396-
{
397-
// We only point at the first place where the found type was inferred.
398-
err.span_label(
399-
s.ident.span,
400-
with_forced_trimmed_paths!(format!(
401-
"here the type of `{ident}` is inferred to be `{ty}`",
402-
)),
403-
);
404-
break;
405-
}
406-
prev = ty;
407-
} else {
408-
let ty = eraser.fold_ty(self.node_ty(binding.hir_id));
409-
if ty.references_error() {
410-
break;
411-
}
412-
if ty != prev && let Some(span) = prev_span && self.can_eq(self.param_env, ty, found).is_ok() {
413-
// We only point at the first place where the found type was inferred.
414-
// We use the *previous* span because if the type is known *here* it means
415-
// it was *evaluated earlier*. We don't do this for method calls because we
416-
// evaluate the method's self type eagerly, but not in any other case.
417-
err.span_label(
418-
span,
419-
with_forced_trimmed_paths!(format!(
420-
"here the type of `{ident}` is inferred to be `{ty}`",
421-
)),
422-
);
423-
break;
424-
}
425-
prev = ty;
395+
let ty = eraser.fold_ty(ty);
396+
if ty.references_error() {
397+
break;
426398
}
427-
if binding.hir_id == expr.hir_id {
428-
// Do not look at expressions that come after the expression we were originally
429-
// evaluating and had a type error.
399+
if ty != prev
400+
&& param_args.is_empty()
401+
&& self.can_eq(self.param_env, ty, found).is_ok()
402+
{
403+
// We only point at the first place where the found type was inferred.
404+
err.span_label(
405+
segment.ident.span,
406+
with_forced_trimmed_paths!(format!(
407+
"here the type of `{ident}` is inferred to be `{ty}`",
408+
)),
409+
);
430410
break;
431411
}
432-
prev_span = Some(binding.span);
412+
prev = ty;
413+
} else {
414+
let ty = eraser.fold_ty(self.node_ty(binding.hir_id));
415+
if ty.references_error() {
416+
break;
417+
}
418+
if ty != prev
419+
&& let Some(span) = prev_span
420+
&& self.can_eq(self.param_env, ty, found).is_ok()
421+
{
422+
// We only point at the first place where the found type was inferred.
423+
// We use the *previous* span because if the type is known *here* it means
424+
// it was *evaluated earlier*. We don't do this for method calls because we
425+
// evaluate the method's self type eagerly, but not in any other case.
426+
err.span_label(
427+
span,
428+
with_forced_trimmed_paths!(format!(
429+
"here the type of `{ident}` is inferred to be `{ty}`",
430+
)),
431+
);
432+
break;
433+
}
434+
prev = ty;
435+
}
436+
if binding.hir_id == expr.hir_id {
437+
// Do not look at expressions that come after the expression we were originally
438+
// evaluating and had a type error.
439+
break;
433440
}
441+
prev_span = Some(binding.span);
434442
}
435443
true
436444
}

0 commit comments

Comments
 (0)