review comments
This commit is contained in:
parent
b7f7756566
commit
0d53f699ea
2 changed files with 56 additions and 46 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue