1
Fork 0

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

View file

@ -3819,6 +3819,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pointing_at_return_type 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( fn suggest_fn_call(
&self, &self,
err: &mut DiagnosticBuilder<'tcx>, err: &mut DiagnosticBuilder<'tcx>,
@ -3826,48 +3832,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
) -> bool { ) -> bool {
if let ty::FnDef(..) | ty::FnPtr(_) = &found.sty { match found.sty {
let sig = found.fn_sig(self.tcx); ty::FnDef(..) | ty::FnPtr(_) => {}
let sig = self _ => return false,
.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig) }
.0;
let sig = self.normalize_associated_types_in(expr.span, &sig); let sig = found.fn_sig(self.tcx);
if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) { let sig = self
let (mut sugg_call, applicability) = if sig.inputs().is_empty() { .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
(String::new(), Applicability::MachineApplicable) .0;
} else { let sig = self.normalize_associated_types_in(expr.span, &sig);
("...".to_owned(), Applicability::HasPlaceholders) if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
}; let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
let mut msg = "call this function"; (String::new(), Applicability::MachineApplicable)
if let ty::FnDef(def_id, ..) = found.sty { } else {
match self.tcx.hir().get_if_local(def_id) { ("...".to_owned(), Applicability::HasPlaceholders)
Some(Node::Item(hir::Item { };
node: ItemKind::Fn(.., body_id), let mut msg = "call this function";
.. if let ty::FnDef(def_id, ..) = found.sty {
})) => { match self.tcx.hir().get_if_local(def_id) {
let body = self.tcx.hir().body(*body_id); Some(Node::Item(hir::Item {
sugg_call = body.arguments.iter() node: ItemKind::Fn(.., body_id),
.map(|arg| hir::print::to_string( ..
hir::print::NO_ANN, })) => {
|s| s.print_pat(&arg.pat), let body = self.tcx.hir().body(*body_id);
)).collect::<Vec<_>>().join(", "); sugg_call = body.arguments.iter()
} .map(|arg| hir::print::to_string(
Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => { hir::print::NO_ANN,
sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", "); |s| s.print_pat(&arg.pat),
msg = "instatiate this tuple struct"; )).collect::<Vec<_>>().join(", ");
}
_ => {}
} }
}; Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) { sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
err.span_suggestion( msg = "instatiate this tuple struct";
expr.span, }
&format!("use parentheses to {}", msg), _ => {}
format!("{}({})", code, sugg_call),
applicability,
);
return true;
} }
};
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 false