Auto merge of #63901 - estebank:unknown-receiver-type, r=zackmdavis

Point at method call on missing annotation error

Make it clearer where the type name that couldn't be inferred comes from.

Before:

```
error[E0282]: type annotations needed
 --> src/test/ui/span/type-annotations-needed-expr.rs:2:13
  |
2 |     let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `S`
  |
  = note: type must be known at this point
```
after
```
error[E0282]: type annotations needed
 --> src/test/ui/span/type-annotations-needed-expr.rs:2:39
  |
2 |     let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
  |                                       ^^^ cannot infer type for `S`
  |
  = note: type must be known at this point
```

CC #63852.
This commit is contained in:
bors 2019-08-26 17:33:50 +00:00
commit 9b91b9c10e
5 changed files with 51 additions and 12 deletions

View File

@ -150,12 +150,12 @@ pub fn extract_type_name(
&self,
ty: Ty<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> String {
) -> (String, Option<Span>) {
if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
let ty_vars = self.type_variables.borrow();
if let TypeVariableOriginKind::TypeParameterDefinition(name) =
ty_vars.var_origin(ty_vid).kind {
return name.to_string();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
return (name.to_string(), Some(var_origin.span));
}
}
@ -165,7 +165,7 @@ pub fn extract_type_name(
printer.region_highlight_mode = highlight;
}
let _ = ty.print(printer);
s
(s, None)
}
pub fn need_type_info_err(
@ -175,7 +175,7 @@ pub fn need_type_info_err(
ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let name = self.extract_type_name(&ty, None);
let (name, name_sp) = self.extract_type_name(&ty, None);
let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
let ty_to_string = |ty: Ty<'tcx>| -> String {
@ -200,6 +200,14 @@ pub fn need_type_info_err(
}
let err_span = if let Some(pattern) = local_visitor.found_arg_pattern {
pattern.span
} else if let Some(span) = name_sp {
// `span` here lets us point at `sum` instead of the entire right hand side expr:
// error[E0282]: type annotations needed
// --> file2.rs:3:15
// |
// 3 | let _ = x.sum() as f64;
// | ^^^ cannot infer type for `S`
span
} else {
span
};
@ -325,6 +333,23 @@ pub fn need_type_info_err(
};
err.span_label(pattern.span, msg);
}
// Instead of the following:
// error[E0282]: type annotations needed
// --> file2.rs:3:15
// |
// 3 | let _ = x.sum() as f64;
// | --^^^--------- cannot infer type for `S`
// |
// = note: type must be known at this point
// We want:
// error[E0282]: type annotations needed
// --> file2.rs:3:15
// |
// 3 | let _ = x.sum() as f64;
// | ^^^ cannot infer type for `S`
// |
// = note: type must be known at this point
let span = name_sp.unwrap_or(span);
if !err.span.span_labels().iter().any(|span_label| {
span_label.label.is_some() && span_label.span == span
}) && local_visitor.found_arg_pattern.is_none()
@ -342,7 +367,7 @@ pub fn need_type_info_err_in_generator(
ty: Ty<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let name = self.extract_type_name(&ty, None);
let name = self.extract_type_name(&ty, None).0;
let mut err = struct_span_err!(
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
);

View File

@ -413,7 +413,7 @@ fn give_name_if_we_cannot_match_hir_ty(
) -> Option<RegionName> {
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, *counter);
let type_name = infcx.extract_type_name(&argument_ty, Some(highlight));
let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)).0;
debug!(
"give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@ -695,7 +695,7 @@ fn give_name_if_anonymous_region_appears_in_output(
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *counter);
let type_name = infcx.extract_type_name(&return_ty, Some(highlight));
let type_name = infcx.extract_type_name(&return_ty, Some(highlight)).0;
let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
@ -758,7 +758,7 @@ fn give_name_if_anonymous_region_appears_in_yield_ty(
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(fr, *counter);
let type_name = infcx.extract_type_name(&yield_ty, Some(highlight));
let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)).0;
let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");

View File

@ -1,10 +1,10 @@
error[E0282]: type annotations needed for `std::option::Option<_>`
--> $DIR/issue-42234-unknown-receiver-type.rs:7:5
--> $DIR/issue-42234-unknown-receiver-type.rs:7:7
|
LL | let x: Option<_> = None;
| - consider giving `x` the explicit type `std::option::Option<_>`, where the type parameter `T` is specified
LL | x.unwrap().method_that_could_exist_on_some_type();
| ^^^^^^^^^^ cannot infer type for `T`
| ^^^^^^ cannot infer type for `T`
|
= note: type must be known at this point

View File

@ -0,0 +1,3 @@
fn main() {
let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
}

View File

@ -0,0 +1,11 @@
error[E0282]: type annotations needed
--> $DIR/type-annotations-needed-expr.rs:2:39
|
LL | let _ = (vec![1,2,3]).into_iter().sum() as f64;
| ^^^ cannot infer type for `S`
|
= note: type must be known at this point
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.