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:
commit
8843b28e64
@ -70,6 +70,7 @@
|
||||
mod note;
|
||||
|
||||
mod need_type_info;
|
||||
pub use need_type_info::TypeAnnotationNeeded;
|
||||
|
||||
pub mod nice_region_error;
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
10
src/test/ui/type-inference/or_else-multiple-type-params.rs
Normal file
10
src/test/ui/type-inference/or_else-multiple-type-params.rs
Normal 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();
|
||||
}
|
@ -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`.
|
5
src/test/ui/type-inference/sort_by_key.rs
Normal file
5
src/test/ui/type-inference/sort_by_key.rs
Normal 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);
|
||||
}
|
11
src/test/ui/type-inference/sort_by_key.stderr
Normal file
11
src/test/ui/type-inference/sort_by_key.stderr
Normal 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`.
|
16
src/test/ui/type-inference/unbounded-associated-type.rs
Normal file
16
src/test/ui/type-inference/unbounded-associated-type.rs
Normal 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
|
||||
}
|
15
src/test/ui/type-inference/unbounded-associated-type.stderr
Normal file
15
src/test/ui/type-inference/unbounded-associated-type.stderr
Normal 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`.
|
@ -0,0 +1,9 @@
|
||||
#[allow(invalid_type_param_default)]
|
||||
|
||||
fn foo<T, U = u64>() -> (T, U) {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(); //~ ERROR type annotations needed
|
||||
}
|
@ -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`.
|
7
src/test/ui/type-inference/unbounded-type-param-in-fn.rs
Normal file
7
src/test/ui/type-inference/unbounded-type-param-in-fn.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn foo<T>() -> T {
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(); //~ ERROR type annotations needed
|
||||
}
|
@ -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`.
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user