Auto merge of #65951 - estebank:type-inference-error, r=nikomatsakis

Point at method call when type annotations are needed

- Point at method call instead of whole expression when type annotations are needed.
- Suggest use of turbofish on function and methods.

Fix #49391, fix #46333, fix #48089. CC #58517, #63502, #63082.

Fixes https://github.com/rust-lang/rust/issues/40015

r? @nikomatsakis
This commit is contained in:
bors 2019-12-13 22:56:27 +00:00
commit 8843b28e64
63 changed files with 470 additions and 135 deletions

View File

@ -70,6 +70,7 @@
mod note;
mod need_type_info;
pub use need_type_info::TypeAnnotationNeeded;
pub mod nice_region_error;

View File

@ -1,4 +1,4 @@
use crate::hir::def::Namespace;
use crate::hir::def::{DefKind, Namespace};
use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat};
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::infer::InferCtxt;
@ -6,8 +6,10 @@
use crate::ty::{self, Ty, Infer, TyVar};
use crate::ty::print::Print;
use syntax::source_map::DesugaringKind;
use syntax::symbol::kw;
use syntax_pos::Span;
use errors::{Applicability, DiagnosticBuilder};
use std::borrow::Cow;
use rustc_error_codes::*;
@ -19,6 +21,7 @@ struct FindLocalByTypeVisitor<'a, 'tcx> {
found_arg_pattern: Option<&'tcx Pat>,
found_ty: Option<Ty<'tcx>>,
found_closure: Option<&'tcx ExprKind>,
found_method_call: Option<&'tcx Expr>,
}
impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> {
@ -35,6 +38,7 @@ fn new(
found_arg_pattern: None,
found_ty: None,
found_closure: None,
found_method_call: None,
}
}
@ -93,11 +97,12 @@ fn visit_body(&mut self, body: &'tcx Body) {
}
fn visit_expr(&mut self, expr: &'tcx Expr) {
if let (ExprKind::Closure(_, _fn_decl, _id, _sp, _), Some(_)) = (
&expr.kind,
self.node_matches_type(expr.hir_id),
) {
self.found_closure = Some(&expr.kind);
if self.node_matches_type(expr.hir_id).is_some() {
match expr.kind {
ExprKind::Closure(..) => self.found_closure = Some(&expr.kind),
ExprKind::MethodCall(..) => self.found_method_call = Some(&expr),
_ => {}
}
}
intravisit::walk_expr(self, expr);
}
@ -109,6 +114,7 @@ fn closure_return_type_suggestion(
err: &mut DiagnosticBuilder<'_>,
output: &FunctionRetTy,
body: &Body,
descr: &str,
name: &str,
ret: &str,
) {
@ -132,7 +138,7 @@ fn closure_return_type_suggestion(
suggestion,
Applicability::HasPlaceholders,
);
err.span_label(span, InferCtxt::missing_type_msg(&name));
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
}
/// Given a closure signature, return a `String` containing a list of all its argument types.
@ -147,17 +153,42 @@ fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String {
.unwrap_or_default()
}
pub enum TypeAnnotationNeeded {
E0282,
E0283,
E0284,
}
impl Into<errors::DiagnosticId> for TypeAnnotationNeeded {
fn into(self) -> errors::DiagnosticId {
syntax::diagnostic_used!(E0282);
syntax::diagnostic_used!(E0283);
syntax::diagnostic_used!(E0284);
errors::DiagnosticId::Error(match self {
Self::E0282 => "E0282".to_string(),
Self::E0283 => "E0283".to_string(),
Self::E0284 => "E0284".to_string(),
})
}
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn extract_type_name(
&self,
ty: Ty<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
) -> (String, Option<Span>) {
) -> (String, Option<Span>, Cow<'static, str>) {
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
let ty_vars = self.type_variables.borrow();
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));
if name != kw::SelfUpper {
return (
name.to_string(),
Some(var_origin.span),
"type parameter".into(),
);
}
}
}
@ -167,7 +198,7 @@ pub fn extract_type_name(
printer.region_highlight_mode = highlight;
}
let _ = ty.print(printer);
(s, None)
(s, None, ty.prefix_string())
}
pub fn need_type_info_err(
@ -175,9 +206,10 @@ pub fn need_type_info_err(
body_id: Option<hir::BodyId>,
span: Span,
ty: Ty<'tcx>,
error_code: TypeAnnotationNeeded,
) -> DiagnosticBuilder<'tcx> {
let ty = self.resolve_vars_if_possible(&ty);
let (name, name_sp) = self.extract_type_name(&ty, None);
let (name, name_sp, descr) = 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 {
@ -185,8 +217,8 @@ pub fn need_type_info_err(
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
let ty_vars = self.type_variables.borrow();
let getter = move |ty_vid| {
if let TypeVariableOriginKind::TypeParameterDefinition(name) =
ty_vars.var_origin(ty_vid).kind {
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
return Some(name.to_string());
}
None
@ -210,6 +242,22 @@ pub fn need_type_info_err(
// 3 | let _ = x.sum() as f64;
// | ^^^ cannot infer type for `S`
span
} else if let Some(
ExprKind::MethodCall(_, call_span, _),
) = local_visitor.found_method_call.map(|e| &e.kind) {
// Point at the call instead of the whole expression:
// error[E0284]: type annotations needed
// --> file.rs:2:5
// |
// 2 | vec![Ok(2)].into_iter().collect()?;
// | ^^^^^^^ cannot infer type
// |
// = note: cannot resolve `<_ as std::ops::Try>::Ok == _`
if span.contains(*call_span) {
*call_span
} else {
span
}
} else {
span
};
@ -247,12 +295,11 @@ pub fn need_type_info_err(
// | consider giving `b` the explicit type `std::result::Result<i32, E>`, where
// | the type parameter `E` is specified
// ```
let mut err = struct_span_err!(
self.tcx.sess,
let error_code = error_code.into();
let mut err = self.tcx.sess.struct_span_err_with_code(
err_span,
E0282,
"type annotations needed{}",
ty_msg,
&format!("type annotations needed{}", ty_msg),
error_code,
);
let suffix = match local_visitor.found_ty {
@ -267,6 +314,7 @@ pub fn need_type_info_err(
&mut err,
&decl.output,
&body,
&descr,
&name,
&ret,
);
@ -334,6 +382,36 @@ pub fn need_type_info_err(
format!("consider giving this pattern {}", suffix)
};
err.span_label(pattern.span, msg);
} else if let Some(e) = local_visitor.found_method_call {
if let ExprKind::MethodCall(segment, ..) = &e.kind {
// Suggest specifiying type params or point out the return type of the call:
//
// error[E0282]: type annotations needed
// --> $DIR/type-annotations-needed-expr.rs:2:39
// |
// LL | let _ = x.into_iter().sum() as f64;
// | ^^^
// | |
// | cannot infer type for `S`
// | help: consider specifying the type argument in
// | the method call: `sum::<S>`
// |
// = note: type must be known at this point
//
// or
//
// error[E0282]: type annotations needed
// --> $DIR/issue-65611.rs:59:20
// |
// LL | let x = buffer.last().unwrap().0.clone();
// | -------^^^^--
// | | |
// | | cannot infer type for `T`
// | this method call resolves to `std::option::Option<&T>`
// |
// = note: type must be known at this point
self.annotate_method_call(segment, e, &mut err);
}
}
// Instead of the following:
// error[E0282]: type annotations needed
@ -351,17 +429,66 @@ pub fn need_type_info_err(
// | ^^^ cannot infer type for `S`
// |
// = note: type must be known at this point
let span = name_sp.unwrap_or(span);
let span = name_sp.unwrap_or(err_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()
{ // Avoid multiple labels pointing at `span`.
err.span_label(span, InferCtxt::missing_type_msg(&name));
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
}
err
}
/// If the `FnSig` for the method call can be found and type arguments are identified as
/// needed, suggest annotating the call, otherwise point out the resulting type of the call.
fn annotate_method_call(
&self,
segment: &hir::ptr::P<hir::PathSegment>,
e: &Expr,
err: &mut DiagnosticBuilder<'_>,
) {
if let (Ok(snippet), Some(tables), None) = (
self.tcx.sess.source_map().span_to_snippet(segment.ident.span),
self.in_progress_tables,
&segment.args,
) {
let borrow = tables.borrow();
if let Some((DefKind::Method, did)) = borrow.type_dependent_def(e.hir_id) {
let generics = self.tcx.generics_of(did);
if !generics.params.is_empty() {
err.span_suggestion(
segment.ident.span,
&format!(
"consider specifying the type argument{} in the method call",
if generics.params.len() > 1 {
"s"
} else {
""
},
),
format!("{}::<{}>", snippet, generics.params.iter()
.map(|p| p.name.to_string())
.collect::<Vec<String>>()
.join(", ")),
Applicability::HasPlaceholders,
);
} else {
let sig = self.tcx.fn_sig(did);
let bound_output = sig.output();
let output = bound_output.skip_binder();
err.span_label(e.span, &format!("this method call resolves to `{:?}`", output));
let kind = &output.kind;
if let ty::Projection(proj) | ty::UnnormalizedProjection(proj) = kind {
if let Some(span) = self.tcx.hir().span_if_local(proj.item_def_id) {
err.span_label(span, &format!("`{:?}` defined here", output));
}
}
}
}
}
}
pub fn need_type_info_err_in_generator(
&self,
kind: hir::GeneratorKind,
@ -369,19 +496,19 @@ 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).0;
let (name, _, descr) = self.extract_type_name(&ty, None);
let mut err = struct_span_err!(
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
);
err.span_label(span, InferCtxt::missing_type_msg(&name));
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
err
}
fn missing_type_msg(type_name: &str) -> String {
fn missing_type_msg(type_name: &str, descr: &str) -> Cow<'static, str>{
if type_name == "_" {
"cannot infer type".to_owned()
"cannot infer type".into()
} else {
format!("cannot infer type for `{}`", type_name)
format!("cannot infer type for {} `{}`", descr, type_name).into()
}
}
}

View File

@ -22,6 +22,7 @@
use crate::hir::Node;
use crate::hir::def_id::DefId;
use crate::infer::{self, InferCtxt};
use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode;
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::session::DiagnosticMessageId;
use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
@ -1952,7 +1953,7 @@ fn maybe_report_ambiguity(
return;
}
match predicate {
let mut err = match predicate {
ty::Predicate::Trait(ref data) => {
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
@ -1986,59 +1987,109 @@ fn maybe_report_ambiguity(
// avoid inundating the user with unnecessary errors, but we now
// check upstream for type errors and dont add the obligations to
// begin with in those cases.
if
self.tcx.lang_items().sized_trait()
if self.tcx.lang_items().sized_trait()
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
{
self.need_type_info_err(body_id, span, self_ty).emit();
} else {
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0283,
"type annotations needed: cannot resolve `{}`",
predicate,
);
self.note_obligation_cause(&mut err, obligation);
err.emit();
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
return;
}
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
err.note(&format!("cannot resolve `{}`", predicate));
if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) = (
self.tcx.sess.source_map().span_to_snippet(span),
&obligation.cause.code,
) {
let generics = self.tcx.generics_of(*def_id);
if !generics.params.is_empty() && !snippet.ends_with('>'){
// FIXME: To avoid spurious suggestions in functions where type arguments
// where already supplied, we check the snippet to make sure it doesn't
// end with a turbofish. Ideally we would have access to a `PathSegment`
// instead. Otherwise we would produce the following output:
//
// error[E0283]: type annotations needed
// --> $DIR/issue-54954.rs:3:24
// |
// LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
// | ^^^^^^^^^^^^^^^^^^^^^^^^^^
// | |
// | cannot infer type
// | help: consider specifying the type argument
// | in the function call:
// | `Tt::const_val::<[i8; 123]>::<T>`
// ...
// LL | const fn const_val<T: Sized>() -> usize {
// | --------- - required by this bound in `Tt::const_val`
// |
// = note: cannot resolve `_: Tt`
err.span_suggestion(
span,
&format!(
"consider specifying the type argument{} in the function call",
if generics.params.len() > 1 {
"s"
} else {
""
},
),
format!("{}::<{}>", snippet, generics.params.iter()
.map(|p| p.name.to_string())
.collect::<Vec<String>>()
.join(", ")),
Applicability::HasPlaceholders,
);
}
}
err
}
ty::Predicate::WellFormed(ty) => {
// Same hacky approach as above to avoid deluging user
// with error messages.
if !ty.references_error() && !self.tcx.sess.has_errors() {
self.need_type_info_err(body_id, span, ty).emit();
if ty.references_error() || self.tcx.sess.has_errors() {
return;
}
self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
}
ty::Predicate::Subtype(ref data) => {
if data.references_error() || self.tcx.sess.has_errors() {
// no need to overload user in such cases
} else {
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
// both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var());
self.need_type_info_err(body_id,
obligation.cause.span,
a).emit();
return
}
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
// both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var());
self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
}
ty::Predicate::Projection(ref data) => {
let trait_ref = data.to_poly_trait_ref(self.tcx);
let self_ty = trait_ref.self_ty();
if predicate.references_error() {
return;
}
let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284);
err.note(&format!("cannot resolve `{}`", predicate));
err
}
_ => {
if !self.tcx.sess.has_errors() {
let mut err = struct_span_err!(
self.tcx.sess,
obligation.cause.span,
E0284,
"type annotations needed: cannot resolve `{}`",
predicate,
);
self.note_obligation_cause(&mut err, obligation);
err.emit();
if self.tcx.sess.has_errors() {
return;
}
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0284,
"type annotations needed: cannot resolve `{}`",
predicate,
);
err.span_label(span, &format!("cannot resolve `{}`", predicate));
err
}
}
};
self.note_obligation_cause(&mut err, obligation);
err.emit();
}
/// Returns `true` if the trait predicate may apply for *some* assignment

View File

@ -871,6 +871,9 @@ fn check_method_call(
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
Ok(method) => {
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
// trigger this codepath causing `structuraly_resolved_type` to emit an error.
self.write_method_call(expr.hir_id, method);
Ok(method)
}

View File

@ -103,6 +103,7 @@
use rustc_target::spec::abi::Abi;
use rustc::infer::opaque_types::OpaqueTypeDecl;
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc::middle::region;
use rustc::mir::interpret::{ConstValue, GlobalId};
@ -5359,7 +5360,7 @@ pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
ty
} else {
if !self.is_tainted_by_errors() {
self.need_type_info_err((**self).body_id, sp, ty)
self.need_type_info_err((**self).body_id, sp, ty, E0282)
.note("type must be known at this point")
.emit();
}

View File

@ -8,6 +8,7 @@
use rustc::hir::def_id::{DefId, DefIndex};
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::infer::InferCtxt;
use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc::ty::fold::{TypeFoldable, TypeFolder};
use rustc::ty::{self, Ty, TyCtxt};
@ -717,7 +718,7 @@ fn new(
fn report_error(&self, t: Ty<'tcx>) {
if !self.tcx.sess.has_errors() {
self.infcx
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t)
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282)
.emit();
}
}

View File

@ -2,8 +2,8 @@ trait A {
const C: usize;
fn f() -> ([u8; A::C], [u8; A::C]);
//~^ ERROR: type annotations needed: cannot resolve
//~| ERROR: type annotations needed: cannot resolve
//~^ ERROR: type annotations needed
//~| ERROR: type annotations needed
}
fn main() {}

View File

@ -1,20 +1,24 @@
error[E0283]: type annotations needed: cannot resolve `_: A`
error[E0283]: type annotations needed
--> $DIR/issue-63496.rs:4:21
|
LL | const C: usize;
| --------------- required by `A::C`
LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^
| ^^^^ cannot infer type
|
= note: cannot resolve `_: A`
error[E0283]: type annotations needed: cannot resolve `_: A`
error[E0283]: type annotations needed
--> $DIR/issue-63496.rs:4:33
|
LL | const C: usize;
| --------------- required by `A::C`
LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^
| ^^^^ cannot infer type
|
= note: cannot resolve `_: A`
error: aborting due to 2 previous errors

View File

@ -7,13 +7,15 @@ LL | const X: usize;
LL | impl dyn Bar {}
| ^^^^^^^ the trait `Bar` cannot be made into an object
error[E0283]: type annotations needed: cannot resolve `_: Bar`
error[E0283]: type annotations needed
--> $DIR/issue-48027.rs:3:32
|
LL | const X: usize;
| --------------- required by `Bar::X`
LL | fn return_n(&self) -> [u8; Bar::X];
| ^^^^^^
| ^^^^^^ cannot infer type
|
= note: cannot resolve `_: Bar`
error: aborting due to 2 previous errors

View File

@ -1,18 +1,23 @@
error[E0284]: type annotations needed: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
error[E0284]: type annotations needed
--> $DIR/associated-types-overridden-binding.rs:4:1
|
LL | trait Foo: Iterator<Item = i32> {}
| ------------------------------- required by `Foo`
LL | trait Bar: Foo<Item = u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
|
= note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
error[E0282]: type annotations needed
error[E0284]: type annotations needed
--> $DIR/associated-types-overridden-binding.rs:7:1
|
LL | trait I32Iterator = Iterator<Item = i32>;
| ----------------------------------------- required by `I32Iterator`
LL | trait U32Iterator = I32Iterator<Item = u32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
|
= note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0284.
For more information about an error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0284`.

View File

@ -1,8 +1,10 @@
error[E0284]: type annotations needed: cannot resolve `<_ as Foo>::A == _`
error[E0284]: type annotations needed
--> $DIR/associated-types-unconstrained.rs:14:20
|
LL | let x: isize = Foo::bar();
| ^^^^^^^^
| ^^^^^^^^ cannot infer type
|
= note: cannot resolve `<_ as Foo>::A == _`
error: aborting due to previous error

View File

@ -8,7 +8,7 @@ async fn bar<T>() -> () {}
async fn foo() {
bar().await;
//~^ ERROR type inside `async fn` body must be known in this context
//~| NOTE cannot infer type for `T`
//~| NOTE cannot infer type for type parameter `T`
//~| NOTE the type is part of the `async fn` body because of this `await`
//~| NOTE in this expansion of desugaring of `await`
}

View File

@ -2,7 +2,7 @@ error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5
|
LL | bar().await;
| ^^^ cannot infer type for `T`
| ^^^ cannot infer type for type parameter `T`
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5

View File

@ -10,7 +10,7 @@ error[E0282]: type annotations needed
--> $DIR/cannot-infer-const-args.rs:9:5
|
LL | foo();
| ^^^ cannot infer type for `fn() -> usize {foo::<_: usize>}`
| ^^^ cannot infer type for fn item `fn() -> usize {foo::<_: usize>}`
error: aborting due to previous error

View File

@ -30,7 +30,7 @@ error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:22:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type for `T`
| ^^^^^^^ cannot infer type for type parameter `T`
error[E0308]: mismatched types
--> $DIR/fn-const-param-infer.rs:25:40

View File

@ -2,13 +2,13 @@ error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:2:9
|
LL | A = foo(),
| ^^^ cannot infer type for `T`
| ^^^ cannot infer type for type parameter `T`
error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:3:9
|
LL | B = foo(),
| ^^^ cannot infer type for `T`
| ^^^ cannot infer type for type parameter `T`
error: aborting due to 2 previous errors

View File

@ -1,11 +1,13 @@
error[E0283]: type annotations needed: cannot resolve `_: Generator`
error[E0283]: type annotations needed
--> $DIR/E0283.rs:18:21
|
LL | fn create() -> u32;
| ------------------- required by `Generator::create`
...
LL | let cont: u32 = Generator::create();
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot resolve `_: Generator`
error: aborting due to previous error

View File

@ -36,7 +36,7 @@ error[E0282]: type annotations needed
--> $DIR/E0401.rs:11:5
|
LL | bfnr(x);
| ^^^^ cannot infer type for `U`
| ^^^^ cannot infer type for type parameter `U`
error: aborting due to 4 previous errors

View File

@ -1,8 +1,10 @@
error[E0284]: type annotations needed: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
error[E0284]: type annotations needed
--> $DIR/issue-12028.rs:27:14
|
LL | self.input_stream(&mut stream);
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ cannot infer type for type parameter `H`
|
= note: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-16966.rs:2:5
|
LL | panic!(std::default::Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `M`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M`
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `B<T>`
--> $DIR/issue-17551.rs:6:15
|
LL | let foo = B(marker::PhantomData);
| --- ^ cannot infer type for `T`
| --- ^ cannot infer type for type parameter `T`
| |
| consider giving `foo` the explicit type `B<T>`, where the type parameter `T` is specified

View File

@ -1,4 +1,4 @@
error[E0283]: type annotations needed: cannot resolve `&'a T: Foo`
error[E0283]: type annotations needed
--> $DIR/issue-21974.rs:10:1
|
LL | trait Foo {
@ -11,7 +11,9 @@ LL | | {
LL | | x.foo();
LL | | y.foo();
LL | | }
| |_^
| |_^ cannot infer type for reference `&'a T`
|
= note: cannot resolve `&'a T: Foo`
error: aborting due to previous error

View File

@ -2,6 +2,6 @@ trait Trait1<'l0, T0> {}
trait Trait0<'l0> {}
impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
//~^ ERROR type annotations needed: cannot resolve `T0: Trait0<'l0>`
//~^ ERROR type annotations needed
fn main() {}

View File

@ -1,11 +1,13 @@
error[E0283]: type annotations needed: cannot resolve `T0: Trait0<'l0>`
error[E0283]: type annotations needed
--> $DIR/issue-24424.rs:4:1
|
LL | trait Trait0<'l0> {}
| ----------------- required by `Trait0`
LL |
LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T0`
|
= note: cannot resolve `T0: Trait0<'l0>`
error: aborting due to previous error

View File

@ -5,7 +5,7 @@ LL | let (tx, rx) = channel();
| -------- consider giving this pattern the explicit type `(std::sync::mpsc::Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`, where the type parameter `T` is specified
...
LL | tx.send(Foo{ foo: PhantomData });
| ^^^ cannot infer type for `T`
| ^^^ cannot infer type for type parameter `T`
error: aborting due to previous error

View File

@ -18,5 +18,5 @@ impl Foo for S5<u32> { fn xxx(&self) {} }
impl Foo for S5<u64> { fn xxx(&self) {} }
fn main() {
let _ = <S5<_>>::xxx; //~ ERROR cannot resolve `S5<_>: Foo`
let _ = <S5<_>>::xxx; //~ ERROR type annotations needed
}

View File

@ -1,11 +1,13 @@
error[E0283]: type annotations needed: cannot resolve `S5<_>: Foo`
error[E0283]: type annotations needed
--> $DIR/issue-29147.rs:21:13
|
LL | trait Foo { fn xxx(&self); }
| -------------- required by `Foo::xxx`
...
LL | let _ = <S5<_>>::xxx;
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
|
= note: cannot resolve `S5<_>: Foo`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-5062.rs:1:29
|
LL | fn main() { format!("{:?}", None); }
| ^^^^ cannot infer type for `T`
| ^^^^ cannot infer type for type parameter `T`
error: aborting due to previous error

View File

@ -4,14 +4,16 @@ error[E0379]: trait fns cannot be declared const
LL | const fn const_val<T: Sized>() -> usize {
| ^^^^^ trait fns cannot be const
error[E0283]: type annotations needed: cannot resolve `_: Tt`
error[E0283]: type annotations needed
--> $DIR/issue-54954.rs:3:24
|
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
...
LL | const fn const_val<T: Sized>() -> usize {
| --------- - required by this bound in `Tt::const_val`
|
= note: cannot resolve `_: Tt`
error[E0080]: evaluation of constant value failed
--> $DIR/issue-54954.rs:13:15

View File

@ -2,7 +2,7 @@ pub trait Foo: Sized {
const SIZE: usize;
fn new(slice: &[u8; Foo::SIZE]) -> Self;
//~^ ERROR: type annotations needed: cannot resolve `_: Foo`
//~^ ERROR: type annotations needed
}
pub struct Bar<T: ?Sized>(T);

View File

@ -4,14 +4,16 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo
LL | Foo(Box::new(*slice))
| ^^^ not a function, tuple struct or tuple variant
error[E0283]: type annotations needed: cannot resolve `_: Foo`
error[E0283]: type annotations needed
--> $DIR/issue-58022.rs:4:25
|
LL | const SIZE: usize;
| ------------------ required by `Foo::SIZE`
LL |
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
| ^^^^^^^^^
| ^^^^^^^^^ cannot infer type
|
= note: cannot resolve `_: Foo`
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-6458-2.rs:3:21
|
LL | format!("{:?}", None);
| ^^^^ cannot infer type for `T`
| ^^^^ cannot infer type for type parameter `T`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-6458-3.rs:4:5
|
LL | mem::transmute(0);
| ^^^^^^^^^^^^^^ cannot infer type for `U`
| ^^^^^^^^^^^^^^ cannot infer type for type parameter `U`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-6458.rs:9:4
|
LL | foo(TypeWithState(marker::PhantomData));
| ^^^ cannot infer type for `State`
| ^^^ cannot infer type for type parameter `State`
error: aborting due to previous error

View File

@ -2,7 +2,10 @@ error[E0282]: type annotations needed
--> $DIR/issue-65611.rs:59:20
|
LL | let x = buffer.last().unwrap().0.clone();
| ^^^^ cannot infer type for `T`
| -------^^^^--
| | |
| | cannot infer type for type parameter `T`
| this method call resolves to `std::option::Option<&T>`
|
= note: type must be known at this point

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `std::vec::Vec<T>`
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17
|
LL | let mut x = Vec::new();
| ----- ^^^^^^^^ cannot infer type for `T`
| ----- ^^^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving `x` the explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/missing-type-parameter.rs:4:5
|
LL | foo();
| ^^^ cannot infer type for `X`
| ^^^ cannot infer type for type parameter `X`
error: aborting due to previous error

View File

@ -9,7 +9,7 @@ fn f(x: &i32) -> Result<i32, ()> {
fn g() -> Result<Vec<i32>, ()> {
let l = [1, 2, 3, 4];
l.iter().map(f).collect()? //~ ERROR type annotations needed: cannot resolve
l.iter().map(f).collect()? //~ ERROR type annotations needed
}
fn main() {

View File

@ -1,8 +1,13 @@
error[E0284]: type annotations needed: cannot resolve `<_ as std::ops::Try>::Ok == _`
--> $DIR/question-mark-type-infer.rs:12:5
error[E0284]: type annotations needed
--> $DIR/question-mark-type-infer.rs:12:21
|
LL | l.iter().map(f).collect()?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^
| |
| cannot infer type
| help: consider specifying the type argument in the method call: `collect::<B>`
|
= note: cannot resolve `<_ as std::ops::Try>::Ok == _`
error: aborting due to previous error

View File

@ -9,8 +9,8 @@ fn shines_a_beacon_through_the_darkness() {
}
fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
data.iter() //~ ERROR type annotations needed
.sum::<_>()
data.iter()
.sum::<_>() //~ ERROR type annotations needed
.to_string()
}

View File

@ -4,16 +4,15 @@ error[E0282]: type annotations needed for `std::option::Option<_>`
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 type parameter `T`
|
= note: type must be known at this point
error[E0282]: type annotations needed
--> $DIR/issue-42234-unknown-receiver-type.rs:12:5
--> $DIR/issue-42234-unknown-receiver-type.rs:13:10
|
LL | / data.iter()
LL | | .sum::<_>()
| |___________________^ cannot infer type
LL | .sum::<_>()
| ^^^ cannot infer type
|
= note: type must be known at this point

View File

@ -2,7 +2,10 @@ 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`
| ^^^
| |
| cannot infer type for type parameter `S`
| help: consider specifying the type argument in the method call: `sum::<S>`
|
= note: type must be known at this point

View File

@ -1,11 +1,13 @@
error[E0283]: type annotations needed: cannot resolve `_: base::HasNew<base::Foo>`
error[E0283]: type annotations needed
--> $DIR/trait-static-method-generic-inference.rs:24:25
|
LL | fn new() -> T;
| -------------- required by `base::HasNew::new`
...
LL | let _f: base::Foo = base::HasNew::new();
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot resolve `_: base::HasNew<base::Foo>`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/traits-multidispatch-convert-ambig-dest.rs:26:5
|
LL | test(22, std::default::Default::default());
| ^^^^ cannot infer type for `U`
| ^^^^ cannot infer type for type parameter `U`
error: aborting due to previous error

View File

@ -0,0 +1,10 @@
use std::process::{Command, Stdio};
fn main() {
let process = Command::new("wc")
.stdout(Stdio::piped())
.spawn()
.or_else(|err| { //~ ERROR type annotations needed
panic!("oh no: {:?}", err);
}).unwrap();
}

View File

@ -0,0 +1,12 @@
error[E0282]: type annotations needed
--> $DIR/or_else-multiple-type-params.rs:7:10
|
LL | .or_else(|err| {
| ^^^^^^^
| |
| cannot infer type for type parameter `F`
| help: consider specifying the type arguments in the method call: `or_else::<F, O>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -0,0 +1,5 @@
fn main() {
let mut lst: [([i32; 10], bool); 10] = [([0; 10], false); 10];
lst.sort_by_key(|&(v, _)| v.iter().sum()); //~ ERROR type annotations needed
println!("{:?}", lst);
}

View File

@ -0,0 +1,11 @@
error[E0282]: type annotations needed
--> $DIR/sort_by_key.rs:3:9
|
LL | lst.sort_by_key(|&(v, _)| v.iter().sum());
| ^^^^^^^^^^^ --- help: consider specifying the type argument in the method call: `sum::<S>`
| |
| cannot infer type for type parameter `K`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -0,0 +1,16 @@
trait T {
type A;
fn foo(&self) -> Self::A {
panic!()
}
}
struct S<X>(std::marker::PhantomData<X>);
impl<X> T for S<X> {
type A = X;
}
fn main() {
S(std::marker::PhantomData).foo(); //~ ERROR type annotations needed
}

View File

@ -0,0 +1,15 @@
error[E0282]: type annotations needed
--> $DIR/unbounded-associated-type.rs:15:5
|
LL | type A;
| ------- `<Self as T>::A` defined here
...
LL | S(std::marker::PhantomData).foo();
| ^--------------------------------
| |
| this method call resolves to `<Self as T>::A`
| cannot infer type for type parameter `X`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -0,0 +1,9 @@
#[allow(invalid_type_param_default)]
fn foo<T, U = u64>() -> (T, U) {
panic!()
}
fn main() {
foo(); //~ ERROR type annotations needed
}

View File

@ -0,0 +1,9 @@
error[E0282]: type annotations needed
--> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:8:5
|
LL | foo();
| ^^^ cannot infer type for type parameter `T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -0,0 +1,7 @@
fn foo<T>() -> T {
panic!()
}
fn main() {
foo(); //~ ERROR type annotations needed
}

View File

@ -0,0 +1,9 @@
error[E0282]: type annotations needed
--> $DIR/unbounded-type-param-in-fn.rs:6:5
|
LL | foo();
| ^^^ cannot infer type for type parameter `T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -5,4 +5,6 @@ fn foo<T: Into<String>>(x: i32) {}
fn main() {
foo(42);
//~^ ERROR type annotations needed
//~| NOTE cannot infer type
//~| NOTE cannot resolve
}

View File

@ -1,4 +1,4 @@
error[E0283]: type annotations needed: cannot resolve `_: std::convert::Into<std::string::String>`
error[E0283]: type annotations needed
--> $DIR/type-annotation-needed.rs:6:5
|
LL | fn foo<T: Into<String>>(x: i32) {}
@ -6,6 +6,11 @@ LL | fn foo<T: Into<String>>(x: i32) {}
...
LL | foo(42);
| ^^^
| |
| cannot infer type for type parameter `T`
| help: consider specifying the type argument in the function call: `foo::<T>`
|
= note: cannot resolve `_: std::convert::Into<std::string::String>`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `std::vec::Vec<T>`
--> $DIR/cannot_infer_local_or_vec.rs:2:13
|
LL | let x = vec![];
| - ^^^^^^ cannot infer type for `T`
| - ^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving `x` the explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified
|

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `(std::vec::Vec<T>,)`
--> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18
|
LL | let (x, ) = (vec![], );
| ----- ^^^^^^ cannot infer type for `T`
| ----- ^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving this pattern the explicit type `(std::vec::Vec<T>,)`, where the type parameter `T` is specified
|

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/issue-22897.rs:4:5
|
LL | [];
| ^^ cannot infer type for `[_; 0]`
| ^^ cannot infer type for array `[_; 0]`
error: aborting due to previous error

View File

@ -1,4 +1,4 @@
error[E0283]: type annotations needed: cannot resolve `&'a T: Foo`
error[E0283]: type annotations needed
--> $DIR/issue-40294.rs:5:1
|
LL | trait Foo: Sized {
@ -11,7 +11,9 @@ LL | | {
LL | | x.foo();
LL | | y.foo();
LL | | }
| |_^
| |_^ cannot infer type for reference `&'a T`
|
= note: cannot resolve `&'a T: Foo`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/unconstrained-none.rs:4:5
|
LL | None;
| ^^^^ cannot infer type for `T`
| ^^^^ cannot infer type for type parameter `T`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed
--> $DIR/unconstrained-ref.rs:6:5
|
LL | S { o: &None };
| ^ cannot infer type for `T`
| ^ cannot infer type for type parameter `T`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `std::vec::Vec<T>`
--> $DIR/vector-no-ann.rs:2:16
|
LL | let _foo = Vec::new();
| ---- ^^^^^^^^ cannot infer type for `T`
| ---- ^^^^^^^^ cannot infer type for type parameter `T`
| |
| consider giving `_foo` the explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified