1
Fork 0

review comments

This commit is contained in:
Esteban Küber 2019-08-13 11:24:08 -07:00
parent fb2511c3c5
commit 939c1cb349
6 changed files with 30 additions and 27 deletions

View file

@ -649,7 +649,9 @@ impl<'hir> Map<'hir> {
} }
} }
pub fn is_const_scope(&self, hir_id: HirId) -> bool { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
/// Used exclusively for diagnostics, to avoid suggestion function calls.
pub fn is_const_context(&self, hir_id: HirId) -> bool {
let parent_id = self.get_parent_item(hir_id); let parent_id = self.get_parent_item(hir_id);
match self.get(parent_id) { match self.get(parent_id) {
Node::Item(&Item { Node::Item(&Item {

View file

@ -153,7 +153,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let (ty_msg, suffix) = match &local_visitor.found_ty { let (ty_msg, suffix) = match &local_visitor.found_ty {
Some(ty) if &ty.to_string() != "_" && Some(ty) if &ty.to_string() != "_" &&
name == "_" && name == "_" &&
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. // FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) && (!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
!ty.is_closure() => // The suggestion doesn't make sense for closures. !ty.is_closure() => // The suggestion doesn't make sense for closures.
{ {
@ -163,7 +163,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
Some(ty) if &ty.to_string() != "_" && Some(ty) if &ty.to_string() != "_" &&
ty.to_string() != name && ty.to_string() != name &&
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. // FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) && (!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
!ty.is_closure() => // The suggestion doesn't make sense for closures. !ty.is_closure() => // The suggestion doesn't make sense for closures.
{ {
@ -185,12 +185,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.map(|args| args.tuple_fields() .map(|args| args.tuple_fields()
.map(|arg| arg.to_string()) .map(|arg| arg.to_string())
.collect::<Vec<_>>().join(", ")) .collect::<Vec<_>>().join(", "))
.unwrap_or_else(String::new); .unwrap_or_default();
// This suggestion is incomplete, as the user will get further type inference // This suggestion is incomplete, as the user will get further type inference
// errors due to the `_` placeholders and the introduction of `Box`, but it does // errors due to the `_` placeholders and the introduction of `Box`, but it does
// nudge them in the right direction. // nudge them in the right direction.
(msg, format!( (msg, format!(
"a boxed closure type like `Box<Fn({}) -> {}>`", "a boxed closure type like `Box<dyn Fn({}) -> {}>`",
args, args,
fn_sig.output().skip_binder().to_string(), fn_sig.output().skip_binder().to_string(),
)) ))

View file

@ -549,7 +549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
) -> bool { ) -> bool {
if self.tcx.hir().is_const_scope(expr.hir_id) { if self.tcx.hir().is_const_context(expr.hir_id) {
// Shouldn't suggest `.into()` on `const`s. // Shouldn't suggest `.into()` on `const`s.
// FIXME(estebank): modify once we decide to suggest `as` casts // FIXME(estebank): modify once we decide to suggest `as` casts
return false; return false;

View file

@ -3990,27 +3990,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
) { ) {
if self.tcx.hir().is_const_scope(expr.hir_id) { if self.tcx.hir().is_const_context(expr.hir_id) {
// Do not suggest `Box::new` in const context. // Do not suggest `Box::new` in const context.
return; return;
} }
if expected.is_box() && !found.is_box() { if !expected.is_box() || found.is_box() {
let boxed_found = self.tcx.mk_box(found); return;
if let (true, Ok(snippet)) = ( }
self.can_coerce(boxed_found, expected), let boxed_found = self.tcx.mk_box(found);
self.sess().source_map().span_to_snippet(expr.span), if let (true, Ok(snippet)) = (
) { self.can_coerce(boxed_found, expected),
err.span_suggestion( self.sess().source_map().span_to_snippet(expr.span),
expr.span, ) {
"you can store this in the heap calling `Box::new`", err.span_suggestion(
format!("Box::new({})", snippet), expr.span,
Applicability::MachineApplicable, "store this in the heap by calling `Box::new`",
); format!("Box::new({})", snippet),
err.note("for more information about the distinction between the stack and the \ Applicability::MachineApplicable,
heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \ );
https://doc.rust-lang.org/rust-by-example/std/box.html and \ err.note("for more on the distinction between the stack and the \
https://doc.rust-lang.org/std/boxed/index.html"); heap, read https://doc.rust-lang.org/book/ch15-01-box.html, \
} https://doc.rust-lang.org/rust-by-example/std/box.html, and \
https://doc.rust-lang.org/std/boxed/index.html");
} }
} }

View file

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for the closure
--> $DIR/cannot-infer-closure.rs:3:9 --> $DIR/cannot-infer-closure.rs:3:9
| |
LL | let x = |a: (), b: ()| { LL | let x = |a: (), b: ()| {
| - consider giving `x` a boxed closure type like `Box<Fn((), ()) -> std::result::Result<(), _>>` | - consider giving `x` a boxed closure type like `Box<dyn Fn((), ()) -> std::result::Result<(), _>>`
LL | Err(a)?; LL | Err(a)?;
| ^^^^^^^ cannot infer type | ^^^^^^^ cannot infer type

View file

@ -10,8 +10,8 @@ LL | | };
| |
= note: expected type `std::boxed::Box<dyn std::ops::Fn() -> std::result::Result<(), ()>>` = note: expected type `std::boxed::Box<dyn std::ops::Fn() -> std::result::Result<(), ()>>`
found type `[closure@$DIR/suggest-box.rs:4:47: 7:6]` found type `[closure@$DIR/suggest-box.rs:4:47: 7:6]`
= note: for more information about the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html and https://doc.rust-lang.org/std/boxed/index.html = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
help: you can store this in the heap calling `Box::new` help: store this in the heap by calling `Box::new`
| |
LL | let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| { LL | let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| {
LL | Err(())?; LL | Err(())?;