review comments

This commit is contained in:
Esteban Küber 2019-08-08 12:32:18 -07:00
parent b7f7756566
commit 0d53f699ea
2 changed files with 56 additions and 46 deletions

View file

@ -550,18 +550,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
assert!(e_ty.is_unit());
let ty = coerce.expected_ty();
coerce.coerce_forced_unit(self, &cause, &mut |err| {
let msg = "give it a value of the expected type";
let label = destination.label
.map(|l| format!(" {}", l.ident))
.unwrap_or_else(String::new);
let sugg = format!("break{} {}", label, match ty.sty {
let val = match ty.sty {
ty::Bool => "true",
ty::Char => "'a'",
ty::Int(_) | ty::Uint(_) => "42",
ty::Float(_) => "3.14159",
ty::Error | ty::Never => return,
_ => "value",
});
};
let msg = "give it a value of the expected type";
let label = destination.label
.map(|l| format!(" {}", l.ident))
.unwrap_or_else(String::new);
let sugg = format!("break{} {}", label, val);
err.span_suggestion(expr.span, msg, sugg, Applicability::HasPlaceholders);
}, false);
}

View file

@ -3819,6 +3819,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pointing_at_return_type
}
/// When encountering an fn-like ctor that needs to unify with a value, check whether calling
/// the ctor would successfully solve the type mismatch and if so, suggest it:
/// ```
/// fn foo(x: usize) -> usize { x }
/// let x: usize = foo; // suggest calling the `foo` function: `foo(42)`
/// ```
fn suggest_fn_call(
&self,
err: &mut DiagnosticBuilder<'tcx>,
@ -3826,48 +3832,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
found: Ty<'tcx>,
) -> bool {
if let ty::FnDef(..) | ty::FnPtr(_) = &found.sty {
let sig = found.fn_sig(self.tcx);
let sig = self
.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
.0;
let sig = self.normalize_associated_types_in(expr.span, &sig);
if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
(String::new(), Applicability::MachineApplicable)
} else {
("...".to_owned(), Applicability::HasPlaceholders)
};
let mut msg = "call this function";
if let ty::FnDef(def_id, ..) = found.sty {
match self.tcx.hir().get_if_local(def_id) {
Some(Node::Item(hir::Item {
node: ItemKind::Fn(.., body_id),
..
})) => {
let body = self.tcx.hir().body(*body_id);
sugg_call = body.arguments.iter()
.map(|arg| hir::print::to_string(
hir::print::NO_ANN,
|s| s.print_pat(&arg.pat),
)).collect::<Vec<_>>().join(", ");
}
Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
msg = "instatiate this tuple struct";
}
_ => {}
match found.sty {
ty::FnDef(..) | ty::FnPtr(_) => {}
_ => return false,
}
let sig = found.fn_sig(self.tcx);
let sig = self
.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
.0;
let sig = self.normalize_associated_types_in(expr.span, &sig);
if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
(String::new(), Applicability::MachineApplicable)
} else {
("...".to_owned(), Applicability::HasPlaceholders)
};
let mut msg = "call this function";
if let ty::FnDef(def_id, ..) = found.sty {
match self.tcx.hir().get_if_local(def_id) {
Some(Node::Item(hir::Item {
node: ItemKind::Fn(.., body_id),
..
})) => {
let body = self.tcx.hir().body(*body_id);
sugg_call = body.arguments.iter()
.map(|arg| hir::print::to_string(
hir::print::NO_ANN,
|s| s.print_pat(&arg.pat),
)).collect::<Vec<_>>().join(", ");
}
};
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
err.span_suggestion(
expr.span,
&format!("use parentheses to {}", msg),
format!("{}({})", code, sugg_call),
applicability,
);
return true;
Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
msg = "instatiate this tuple struct";
}
_ => {}
}
};
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
err.span_suggestion(
expr.span,
&format!("use parentheses to {}", msg),
format!("{}({})", code, sugg_call),
applicability,
);
return true;
}
}
false