mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
add new emit_inference_failure_err
This commit is contained in:
parent
721fc73208
commit
3fe346e7a3
@ -1,21 +1,22 @@
|
||||
use crate::infer::type_variable::TypeVariableOriginKind;
|
||||
use crate::infer::{InferCtxt, Symbol};
|
||||
use rustc_errors::{
|
||||
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
|
||||
};
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Namespace};
|
||||
use rustc_hir::def::{CtorOf, DefKind, Namespace};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, MatchSource, Pat};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::infer::unify_key::ConstVariableOriginKind;
|
||||
use rustc_middle::ty::print::Print;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||
use rustc_middle::ty::{self, Const, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst};
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
|
||||
pub enum TypeAnnotationNeeded {
|
||||
/// ```compile_fail,E0282
|
||||
@ -54,9 +55,8 @@ pub struct InferenceDiagnosticsData {
|
||||
|
||||
/// Data on the parent definition where a generic argument was declared.
|
||||
pub struct InferenceDiagnosticsParentData {
|
||||
pub prefix: &'static str,
|
||||
pub name: String,
|
||||
pub def_id: DefId,
|
||||
prefix: &'static str,
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub enum UnderspecifiedArgKind {
|
||||
@ -81,6 +81,18 @@ impl InferenceDiagnosticsData {
|
||||
// For example: "cannot infer type for type parameter `T`"
|
||||
format!("cannot infer {} `{}`{}", self.kind.prefix_string(), self.name, suffix)
|
||||
}
|
||||
|
||||
fn where_x_is_specified(&self, in_type: Ty<'_>) -> String {
|
||||
if in_type.is_ty_infer() {
|
||||
String::new()
|
||||
} else if self.name == "_" {
|
||||
// FIXME: Consider specializing this message if there is a single `_`
|
||||
// in the type.
|
||||
", where the placeholders `_` are specified".to_string()
|
||||
} else {
|
||||
format!(", where the {} `{}` is specified", self.kind.prefix_string(), self.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InferenceDiagnosticsParentData {
|
||||
@ -94,7 +106,6 @@ impl InferenceDiagnosticsParentData {
|
||||
Some(InferenceDiagnosticsParentData {
|
||||
prefix: tcx.def_kind(parent_def_id).descr(parent_def_id),
|
||||
name: parent_name,
|
||||
def_id: parent_def_id,
|
||||
})
|
||||
}
|
||||
|
||||
@ -117,6 +128,80 @@ impl UnderspecifiedArgKind {
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'_, 'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
|
||||
let mut printer = FmtPrinter::new(infcx.tcx, ns);
|
||||
let ty_getter = move |ty_vid| {
|
||||
if infcx.probe_ty_var(ty_vid).is_ok() {
|
||||
warn!("resolved ty var in error message");
|
||||
}
|
||||
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) =
|
||||
infcx.inner.borrow_mut().type_variables().var_origin(ty_vid).kind
|
||||
{
|
||||
Some(name.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
|
||||
let const_getter = move |ct_vid| {
|
||||
if infcx.probe_const_var(ct_vid).is_ok() {
|
||||
warn!("resolved const var in error message");
|
||||
}
|
||||
if let ConstVariableOriginKind::ConstParameterDefinition(name, _) =
|
||||
infcx.inner.borrow_mut().const_unification_table().probe_value(ct_vid).origin.kind
|
||||
{
|
||||
return Some(name.to_string());
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
printer.const_infer_name_resolver = Some(Box::new(const_getter));
|
||||
printer
|
||||
}
|
||||
|
||||
fn ty_to_string<'tcx>(infcx: &InferCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> String {
|
||||
let printer = fmt_printer(infcx, Namespace::TypeNS);
|
||||
let ty = infcx.resolve_vars_if_possible(ty);
|
||||
match ty.kind() {
|
||||
// We don't want the regular output for `fn`s because it includes its path in
|
||||
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
|
||||
ty::FnDef(..) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
|
||||
// FIXME: The same thing for closures, but this only works when the closure
|
||||
// does not capture anything.
|
||||
//
|
||||
// We do have to hide the `extern "rust-call"` ABI in that case though,
|
||||
// which is too much of a bother for now.
|
||||
_ => ty.print(printer).unwrap().into_buffer(),
|
||||
}
|
||||
}
|
||||
|
||||
/// We don't want to directly use `ty_to_string` for closures as their type isn't really
|
||||
/// something users are familar with. Directly printing the `fn_sig` of closures also
|
||||
/// doesn't work as they actually use the "rust-call" API.
|
||||
fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> String {
|
||||
let ty::Closure(_, substs) = ty.kind() else { unreachable!() };
|
||||
let fn_sig = substs.as_closure().sig();
|
||||
let args = fn_sig
|
||||
.inputs()
|
||||
.skip_binder()
|
||||
.iter()
|
||||
.next()
|
||||
.map(|args| {
|
||||
args.tuple_fields()
|
||||
.iter()
|
||||
.map(|arg| ty_to_string(infcx, arg))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let ret = if fn_sig.output().skip_binder().is_unit() {
|
||||
String::new()
|
||||
} else {
|
||||
format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder()))
|
||||
};
|
||||
format!("fn({}){}", args, ret)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
/// Extracts data used by diagnostic for either types or constants
|
||||
/// which were stuck during inference.
|
||||
@ -153,9 +238,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
if let Some(highlight) = highlight {
|
||||
printer.region_highlight_mode = highlight;
|
||||
}
|
||||
let name = ty.print(printer).unwrap().into_buffer();
|
||||
InferenceDiagnosticsData {
|
||||
name,
|
||||
name: ty.print(printer).unwrap().into_buffer(),
|
||||
span: None,
|
||||
kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) },
|
||||
parent: None,
|
||||
@ -177,8 +261,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
debug_assert!(!origin.span.is_dummy());
|
||||
let mut printer =
|
||||
ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
|
||||
let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
|
||||
if let Some(highlight) = highlight {
|
||||
printer.region_highlight_mode = highlight;
|
||||
}
|
||||
@ -189,7 +272,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
parent: None,
|
||||
}
|
||||
} else {
|
||||
bug!("unexpect const: {:?}", ct);
|
||||
// FIXME: This code seems a bit wrong, idk.
|
||||
let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
|
||||
if let Some(highlight) = highlight {
|
||||
printer.region_highlight_mode = highlight;
|
||||
}
|
||||
InferenceDiagnosticsData {
|
||||
name: ct.print(printer).unwrap().into_buffer(),
|
||||
span: None,
|
||||
kind: UnderspecifiedArgKind::Const { is_parameter: false },
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
|
||||
@ -201,17 +294,160 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
body_id: Option<hir::BodyId>,
|
||||
span: Span,
|
||||
arg: GenericArg<'tcx>,
|
||||
impl_candidates: Vec<ty::TraitRef<'tcx>>,
|
||||
// FIXME(#94483): Either use this or remove it.
|
||||
_impl_candidates: Vec<ty::TraitRef<'tcx>>,
|
||||
error_code: TypeAnnotationNeeded,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let arg = self.resolve_vars_if_possible(arg);
|
||||
let arg_data = self.extract_inference_diagnostics_data(arg, None);
|
||||
|
||||
let mut local_visitor = FindInferSourceVisitor::new(&self, arg);
|
||||
if let Some(body_id) = body_id {
|
||||
let expr = self.tcx.hir().expect_expr(body_id.hir_id);
|
||||
debug!(?expr);
|
||||
local_visitor.visit_expr(expr);
|
||||
}
|
||||
|
||||
let Some(InferSource { span, kind }) = local_visitor.infer_source else {
|
||||
let error_code = error_code.into();
|
||||
let mut err = self.tcx.sess.struct_span_err_with_code(
|
||||
span,
|
||||
&format!("type annotations needed"),
|
||||
error_code,
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
arg_data.cannot_infer_msg(),
|
||||
);
|
||||
return err;
|
||||
};
|
||||
|
||||
let error_code = error_code.into();
|
||||
let err = self.tcx.sess.struct_span_err_with_code(
|
||||
let mut err = self.tcx.sess.struct_span_err_with_code(
|
||||
span,
|
||||
&format!("type annotations needed"),
|
||||
&format!("type annotations needed{}", kind.ty_msg(self)),
|
||||
error_code,
|
||||
);
|
||||
match kind {
|
||||
InferSourceKind::LetBinding { insert_span, pattern_name, ty } => {
|
||||
let suggestion_msg = if let Some(name) = pattern_name {
|
||||
format!(
|
||||
"consider giving `{}` an explicit type{}",
|
||||
name,
|
||||
arg_data.where_x_is_specified(ty)
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"consider giving this pattern a type{}",
|
||||
arg_data.where_x_is_specified(ty)
|
||||
)
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
insert_span,
|
||||
&suggestion_msg,
|
||||
format!(": {}", ty_to_string(self, ty)),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
InferSourceKind::ClosureArg { insert_span, ty } => {
|
||||
err.span_suggestion_verbose(
|
||||
insert_span,
|
||||
&format!(
|
||||
"consider giving this closure parameter an explicit type{}",
|
||||
arg_data.where_x_is_specified(ty)
|
||||
),
|
||||
format!(": {}", ty_to_string(self, ty)),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
InferSourceKind::GenericArg {
|
||||
insert_span,
|
||||
argument_index,
|
||||
generics_def_id,
|
||||
def_id: _,
|
||||
generic_args,
|
||||
} => {
|
||||
let generics = self.tcx.generics_of(generics_def_id);
|
||||
let is_type = matches!(arg.unpack(), GenericArgKind::Type(_));
|
||||
|
||||
let cannot_infer_msg = format!(
|
||||
"cannot infer {} of the {} parameter `{}`{}",
|
||||
if is_type { "type" } else { "the value" },
|
||||
if is_type { "type" } else { "const" },
|
||||
generics.params[argument_index].name,
|
||||
// We use the `generics_def_id` here, as even when suggesting `None::<T>`,
|
||||
// the type parameter `T` was still declared on the enum, not on the
|
||||
// variant.
|
||||
InferenceDiagnosticsParentData::for_parent_def_id(self.tcx, generics_def_id)
|
||||
.map_or(String::new(), |parent| parent.suffix_string()),
|
||||
);
|
||||
|
||||
err.span_label(span, cannot_infer_msg);
|
||||
|
||||
let printer = fmt_printer(self, Namespace::TypeNS);
|
||||
let args = printer.comma_sep(generic_args.iter().copied()).unwrap().into_buffer();
|
||||
err.span_suggestion_verbose(
|
||||
insert_span,
|
||||
&format!("consider specifying the generic argument{}", pluralize!(args.len()),),
|
||||
format!("::<{}>", args),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
|
||||
let typeck_results = self.in_progress_typeck_results.unwrap();
|
||||
let typeck_results = typeck_results.borrow();
|
||||
let printer = fmt_printer(self, Namespace::ValueNS);
|
||||
let def_path = printer.print_def_path(def_id, substs).unwrap().into_buffer();
|
||||
|
||||
// We only care about whether we have to add `&` or `&mut ` for now.
|
||||
// This is the case if the last adjustment is a borrow and the
|
||||
// first adjustment was not a builtin deref.
|
||||
let adjustment = match typeck_results.expr_adjustments(receiver) {
|
||||
[
|
||||
Adjustment { kind: Adjust::Deref(None), target: _ },
|
||||
..,
|
||||
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), target: _ },
|
||||
] => "",
|
||||
[
|
||||
..,
|
||||
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), target: _ },
|
||||
] => match mut_ {
|
||||
AutoBorrowMutability::Mut { .. } => "&mut ",
|
||||
AutoBorrowMutability::Not => "&",
|
||||
},
|
||||
_ => "",
|
||||
};
|
||||
|
||||
let suggestion = vec![
|
||||
(receiver.span.shrink_to_lo(), format!("{def_path}({adjustment}")),
|
||||
(receiver.span.shrink_to_hi().with_hi(successor.1), successor.0.to_string()),
|
||||
];
|
||||
err.multipart_suggestion(
|
||||
"try using a fully qualified path to specify the expected types",
|
||||
suggestion,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
|
||||
let ret = ty_to_string(self, ty);
|
||||
let (arrow, post) = match data {
|
||||
FnRetTy::DefaultReturn(_) => ("-> ", " "),
|
||||
_ => ("", ""),
|
||||
};
|
||||
let suggestion = match should_wrap_expr {
|
||||
Some(end_span) => vec![
|
||||
(data.span(), format!("{}{}{}{{ ", arrow, ret, post)),
|
||||
(end_span, " }".to_string()),
|
||||
],
|
||||
None => vec![(data.span(), format!("{}{}{}", arrow, ret, post))],
|
||||
};
|
||||
err.multipart_suggestion(
|
||||
"try giving this closure an explicit return type",
|
||||
suggestion,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
@ -235,3 +471,550 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct InferSource<'tcx> {
|
||||
span: Span,
|
||||
kind: InferSourceKind<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum InferSourceKind<'tcx> {
|
||||
LetBinding {
|
||||
insert_span: Span,
|
||||
pattern_name: Option<Ident>,
|
||||
ty: Ty<'tcx>,
|
||||
},
|
||||
ClosureArg {
|
||||
insert_span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
},
|
||||
GenericArg {
|
||||
insert_span: Span,
|
||||
argument_index: usize,
|
||||
generics_def_id: DefId,
|
||||
def_id: DefId,
|
||||
generic_args: &'tcx [GenericArg<'tcx>],
|
||||
},
|
||||
FullyQualifiedMethodCall {
|
||||
receiver: &'tcx Expr<'tcx>,
|
||||
/// If the method has other arguments, this is ", " and the start of the first argument,
|
||||
/// while for methods without arguments this is ")" and the end of the method call.
|
||||
successor: (&'static str, BytePos),
|
||||
substs: SubstsRef<'tcx>,
|
||||
def_id: DefId,
|
||||
},
|
||||
ClosureReturn {
|
||||
ty: Ty<'tcx>,
|
||||
data: &'tcx FnRetTy<'tcx>,
|
||||
should_wrap_expr: Option<Span>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'tcx> InferSourceKind<'tcx> {
|
||||
fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String {
|
||||
match *self {
|
||||
InferSourceKind::LetBinding { ty, .. }
|
||||
| InferSourceKind::ClosureArg { ty, .. }
|
||||
| InferSourceKind::ClosureReturn { ty, .. } => {
|
||||
if ty.is_closure() {
|
||||
format!(" for the closure `{}`", closure_as_fn_str(infcx, ty))
|
||||
} else if !ty.is_ty_infer() {
|
||||
format!(" for `{}`", ty_to_string(infcx, ty))
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
// FIXME: We should be able to add some additional info here.
|
||||
InferSourceKind::GenericArg { .. }
|
||||
| InferSourceKind::FullyQualifiedMethodCall { .. } => String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InsertableGenericArgs<'tcx> {
|
||||
insert_span: Span,
|
||||
substs: SubstsRef<'tcx>,
|
||||
generics_def_id: DefId,
|
||||
def_id: DefId,
|
||||
}
|
||||
|
||||
/// A visitor which searches for the "best" spot to use in the inference error.
|
||||
///
|
||||
/// For this it walks over the hir body and tries to check all places where
|
||||
/// inference variables could be bound.
|
||||
///
|
||||
/// While doing so, the currently best spot is stored in `infer_source`.
|
||||
/// For details on how we rank spots, see [Self::source_cost]
|
||||
struct FindInferSourceVisitor<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
target: GenericArg<'tcx>,
|
||||
|
||||
attempt: usize,
|
||||
infer_source_cost: usize,
|
||||
infer_source: Option<InferSource<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
||||
fn new(infcx: &'a InferCtxt<'a, 'tcx>, target: GenericArg<'tcx>) -> Self {
|
||||
FindInferSourceVisitor {
|
||||
infcx,
|
||||
target,
|
||||
|
||||
attempt: 0,
|
||||
infer_source_cost: usize::MAX,
|
||||
infer_source: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes cost for the given source.
|
||||
///
|
||||
/// Sources with a small cost are prefer and should result
|
||||
/// in a clearer and idiomatic suggestion.
|
||||
fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
fn arg_cost<'tcx>(arg: GenericArg<'tcx>) -> usize {
|
||||
match arg.unpack() {
|
||||
GenericArgKind::Lifetime(_) => 0, // erased
|
||||
GenericArgKind::Type(ty) => ty_cost(ty),
|
||||
GenericArgKind::Const(_) => 3, // some non-zero value
|
||||
}
|
||||
}
|
||||
fn ty_cost<'tcx>(ty: Ty<'tcx>) -> usize {
|
||||
match ty.kind() {
|
||||
ty::Closure(..) => 100,
|
||||
ty::FnDef(..) => 20,
|
||||
ty::FnPtr(..) => 10,
|
||||
ty::Infer(..) => 0,
|
||||
_ => 1,
|
||||
}
|
||||
}
|
||||
|
||||
// The sources are listed in order of preference here.
|
||||
match source.kind {
|
||||
InferSourceKind::LetBinding { ty, .. } => ty_cost(ty),
|
||||
InferSourceKind::ClosureArg { ty, .. } => 5 + ty_cost(ty),
|
||||
InferSourceKind::GenericArg { def_id, generic_args, .. } => {
|
||||
let variant_cost = match tcx.def_kind(def_id) {
|
||||
DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15, // `None::<u32>` and friends are ugly.
|
||||
_ => 12,
|
||||
};
|
||||
variant_cost + generic_args.iter().map(|&arg| arg_cost(arg)).sum::<usize>()
|
||||
}
|
||||
InferSourceKind::FullyQualifiedMethodCall { substs, .. } => {
|
||||
// FIXME: We should also consider the cost of lifetimes and constants here.
|
||||
20 + substs.iter().map(|arg| arg_cost(arg)).sum::<usize>()
|
||||
}
|
||||
InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
|
||||
30 + ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Uses `fn source_cost` to determine whether this inference source is preferable to
|
||||
/// previous sources. We generally prefer earlier sources.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
|
||||
let cost = self.source_cost(&new_source) + self.attempt;
|
||||
self.attempt += 1;
|
||||
if cost < self.infer_source_cost {
|
||||
self.infer_source_cost = cost;
|
||||
self.infer_source = Some(new_source);
|
||||
}
|
||||
}
|
||||
|
||||
fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
|
||||
let ty = self.infcx.in_progress_typeck_results?.borrow().node_type_opt(hir_id);
|
||||
self.infcx.resolve_vars_if_possible(ty)
|
||||
}
|
||||
|
||||
// Check whether this generic argument is the inference variable we
|
||||
// are looking for.
|
||||
fn generic_arg_is_target(&self, arg: GenericArg<'tcx>) -> bool {
|
||||
if arg == self.target {
|
||||
return true;
|
||||
}
|
||||
|
||||
match (arg.unpack(), self.target.unpack()) {
|
||||
(GenericArgKind::Type(inner_ty), GenericArgKind::Type(target_ty)) => {
|
||||
use ty::{Infer, TyVar};
|
||||
match (inner_ty.kind(), target_ty.kind()) {
|
||||
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
|
||||
self.infcx.inner.borrow_mut().type_variables().sub_unified(a_vid, b_vid)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(GenericArgKind::Const(inner_ct), GenericArgKind::Const(target_ct)) => {
|
||||
use ty::InferConst::*;
|
||||
match (inner_ct.val(), target_ct.val()) {
|
||||
(ty::ConstKind::Infer(Var(a_vid)), ty::ConstKind::Infer(Var(b_vid))) => self
|
||||
.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.const_unification_table()
|
||||
.unioned(a_vid, b_vid),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Does this generic argument contain our target inference variable
|
||||
/// in a way which can be written by the user.
|
||||
fn generic_arg_contains_target(&self, arg: GenericArg<'tcx>) -> bool {
|
||||
let mut walker = arg.walk();
|
||||
while let Some(inner) = walker.next() {
|
||||
if self.generic_arg_is_target(inner) {
|
||||
return true;
|
||||
}
|
||||
match inner.unpack() {
|
||||
GenericArgKind::Lifetime(_) => {}
|
||||
GenericArgKind::Type(ty) => {
|
||||
if matches!(ty.kind(), ty::Opaque(..)) {
|
||||
// Opaque types can't be named by the user right now
|
||||
// FIXME(type_alias_impl_trait): These opaque types
|
||||
// can actually be named, so it would make sense to
|
||||
// adjust this case and add a test for it.
|
||||
walker.skip_current_subtree();
|
||||
}
|
||||
}
|
||||
GenericArgKind::Const(ct) => {
|
||||
if matches!(ct.val(), ty::ConstKind::Unevaluated(..)) {
|
||||
// You can't write the generic arguments for
|
||||
// unevaluated constants.
|
||||
walker.skip_current_subtree();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn expr_inferred_subst_iter(
|
||||
&self,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_results = self.infcx.in_progress_typeck_results.unwrap().borrow();
|
||||
match expr.kind {
|
||||
hir::ExprKind::Path(ref path) => {
|
||||
if let Some(substs) = typeck_results.node_substs_opt(expr.hir_id) {
|
||||
return self.path_inferred_subst_iter(expr.hir_id, substs, path);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Struct(path, _, _) => {
|
||||
if let Some(ty) = self.opt_node_type(expr.hir_id) {
|
||||
if let ty::Adt(_, substs) = ty.kind() {
|
||||
return self.path_inferred_subst_iter(expr.hir_id, substs, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ExprKind::MethodCall(segment, _, _) => {
|
||||
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let insertable: Option<_> = try {
|
||||
if generics.has_impl_trait() {
|
||||
None?
|
||||
}
|
||||
let substs = typeck_results.node_substs_opt(expr.hir_id)?;
|
||||
let span = tcx.hir().span(segment.hir_id?);
|
||||
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
|
||||
InsertableGenericArgs {
|
||||
insert_span,
|
||||
substs,
|
||||
generics_def_id: def_id,
|
||||
def_id,
|
||||
}
|
||||
};
|
||||
return Box::new(insertable.into_iter());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Box::new(iter::empty())
|
||||
}
|
||||
|
||||
fn resolved_path_inferred_subst_iter(
|
||||
&self,
|
||||
path: &'tcx hir::Path<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
|
||||
let tcx = self.infcx.tcx;
|
||||
// The last segment of a path often has `Res::Err` and the
|
||||
// correct `Res` is the one of the whole path.
|
||||
//
|
||||
// FIXME: We deal with that one separately for now,
|
||||
// would be good to remove this special case.
|
||||
let last_segment_using_path_data: Option<_> = try {
|
||||
let generics_def_id = tcx.res_generics_def_id(path.res)?;
|
||||
let generics = tcx.generics_of(generics_def_id);
|
||||
if generics.has_impl_trait() {
|
||||
None?
|
||||
}
|
||||
let insert_span =
|
||||
path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
|
||||
InsertableGenericArgs {
|
||||
insert_span,
|
||||
substs,
|
||||
generics_def_id,
|
||||
def_id: path.res.def_id(),
|
||||
}
|
||||
};
|
||||
|
||||
path.segments
|
||||
.iter()
|
||||
.filter_map(move |segment| {
|
||||
let res = segment.res?;
|
||||
let generics_def_id = tcx.res_generics_def_id(res)?;
|
||||
let generics = tcx.generics_of(generics_def_id);
|
||||
if generics.has_impl_trait() {
|
||||
return None;
|
||||
}
|
||||
let span = tcx.hir().span(segment.hir_id?);
|
||||
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
|
||||
Some(InsertableGenericArgs {
|
||||
insert_span,
|
||||
substs,
|
||||
generics_def_id,
|
||||
def_id: res.def_id(),
|
||||
})
|
||||
})
|
||||
.chain(last_segment_using_path_data)
|
||||
}
|
||||
|
||||
fn path_inferred_subst_iter(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
qpath: &'tcx hir::QPath<'tcx>,
|
||||
) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let typeck_results = self.infcx.in_progress_typeck_results.unwrap().borrow();
|
||||
match qpath {
|
||||
hir::QPath::Resolved(_self_ty, path) => {
|
||||
Box::new(self.resolved_path_inferred_subst_iter(path, substs))
|
||||
}
|
||||
hir::QPath::TypeRelative(ty, segment) => {
|
||||
let Some(def_id) = typeck_results.type_dependent_def_id(hir_id) else {
|
||||
return Box::new(iter::empty());
|
||||
};
|
||||
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let segment: Option<_> = try {
|
||||
if !segment.infer_args || generics.has_impl_trait() {
|
||||
None?;
|
||||
}
|
||||
let span = tcx.hir().span(segment.hir_id?);
|
||||
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
|
||||
InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id }
|
||||
};
|
||||
|
||||
let parent_def_id = generics.parent.unwrap();
|
||||
if tcx.def_kind(parent_def_id) == DefKind::Impl {
|
||||
let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs);
|
||||
match (parent_ty.kind(), &ty.kind) {
|
||||
(
|
||||
ty::Adt(def, substs),
|
||||
hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
|
||||
) => {
|
||||
if tcx.res_generics_def_id(path.res) != Some(def.did()) {
|
||||
bug!(
|
||||
"unexpected path: def={:?} substs={:?} path={:?}",
|
||||
def,
|
||||
substs,
|
||||
path,
|
||||
);
|
||||
} else {
|
||||
return Box::new(
|
||||
self.resolved_path_inferred_subst_iter(path, substs)
|
||||
.chain(segment),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
Box::new(segment.into_iter())
|
||||
}
|
||||
hir::QPath::LangItem(_, _, _) => Box::new(iter::empty()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
|
||||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.infcx.tcx.hir()
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &'tcx Local<'tcx>) {
|
||||
intravisit::walk_local(self, local);
|
||||
|
||||
if let Some(ty) = self.opt_node_type(local.hir_id) {
|
||||
if self.generic_arg_contains_target(ty.into()) {
|
||||
match local.source {
|
||||
LocalSource::Normal if local.ty.is_none() => {
|
||||
self.update_infer_source(InferSource {
|
||||
span: local.pat.span,
|
||||
kind: InferSourceKind::LetBinding {
|
||||
insert_span: local.pat.span.shrink_to_hi(),
|
||||
pattern_name: local.pat.simple_ident(),
|
||||
ty,
|
||||
},
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// For closures, we first visit the parameters and then the content,
|
||||
/// as we prefer those.
|
||||
fn visit_body(&mut self, body: &'tcx Body<'tcx>) {
|
||||
for param in body.params {
|
||||
debug!(
|
||||
"param: span {:?}, ty_span {:?}, pat.span {:?}",
|
||||
param.span, param.ty_span, param.pat.span
|
||||
);
|
||||
if param.ty_span != param.pat.span {
|
||||
debug!("skipping param: has explicit type");
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(param_ty) = self.opt_node_type(param.hir_id) else {
|
||||
continue
|
||||
};
|
||||
|
||||
if self.generic_arg_contains_target(param_ty.into()) {
|
||||
self.update_infer_source(InferSource {
|
||||
span: param.pat.span,
|
||||
kind: InferSourceKind::ClosureArg {
|
||||
insert_span: param.pat.span.shrink_to_hi(),
|
||||
ty: param_ty,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
intravisit::walk_body(self, body);
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
|
||||
let tcx = self.infcx.tcx;
|
||||
match expr.kind {
|
||||
// When encountering `func(arg)` first look into `arg` and then `func`,
|
||||
// as `arg` is "more specific".
|
||||
ExprKind::Call(func, args) => {
|
||||
for arg in args {
|
||||
self.visit_expr(arg);
|
||||
}
|
||||
self.visit_expr(func);
|
||||
}
|
||||
_ => intravisit::walk_expr(self, expr),
|
||||
}
|
||||
|
||||
for InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } in
|
||||
self.expr_inferred_subst_iter(expr)
|
||||
{
|
||||
let generics = tcx.generics_of(generics_def_id);
|
||||
if let Some(argument_index) =
|
||||
generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
|
||||
{
|
||||
let substs = self.infcx.resolve_vars_if_possible(substs);
|
||||
let num_args = generics
|
||||
.params
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|&p| !matches!(p.kind, GenericParamDefKind::Lifetime))
|
||||
.skip_while(|¶m| {
|
||||
if let Some(default) = param.default_value(tcx) {
|
||||
// FIXME: Using structural comparisions has a bunch of false negatives.
|
||||
//
|
||||
// We should instead try to replace inference variables with placeholders and
|
||||
// then use `infcx.can_eq`. That probably should be a separate method
|
||||
// generally used during error reporting.
|
||||
default.subst(tcx, substs) == substs[param.index as usize]
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.count();
|
||||
let generic_args =
|
||||
&generics.own_substs(substs)[generics.own_counts().lifetimes..][..num_args];
|
||||
let span = match expr.kind {
|
||||
ExprKind::MethodCall(path, _, _) => path.ident.span,
|
||||
_ => expr.span,
|
||||
};
|
||||
|
||||
self.update_infer_source(InferSource {
|
||||
span,
|
||||
kind: InferSourceKind::GenericArg {
|
||||
insert_span,
|
||||
argument_index,
|
||||
generics_def_id,
|
||||
def_id,
|
||||
generic_args,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
|
||||
if let (&ExprKind::Closure(_, decl, body_id, span, _), ty::Closure(_, substs)) =
|
||||
(&expr.kind, node_ty.kind())
|
||||
{
|
||||
let output = substs.as_closure().sig().output().skip_binder();
|
||||
if self.generic_arg_contains_target(output.into()) {
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) {
|
||||
None
|
||||
} else {
|
||||
Some(body.value.span.shrink_to_hi())
|
||||
};
|
||||
self.update_infer_source(InferSource {
|
||||
span,
|
||||
kind: InferSourceKind::ClosureReturn {
|
||||
ty: output,
|
||||
data: &decl.output,
|
||||
should_wrap_expr,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let has_impl_trait = |def_id| {
|
||||
iter::successors(Some(tcx.generics_of(def_id)), |generics| {
|
||||
generics.parent.map(|def_id| tcx.generics_of(def_id))
|
||||
})
|
||||
.any(|generics| generics.has_impl_trait())
|
||||
};
|
||||
if let ExprKind::MethodCall(path, args, span) = expr.kind
|
||||
&& let Some(typeck_results) = self.infcx.in_progress_typeck_results
|
||||
&& let Some(substs) = typeck_results.borrow().node_substs_opt(expr.hir_id)
|
||||
&& substs.iter().any(|arg| self.generic_arg_contains_target(arg))
|
||||
&& let Some(def_id) = typeck_results.borrow().type_dependent_def_id(expr.hir_id)
|
||||
&& self.infcx.tcx.trait_of_item(def_id).is_some()
|
||||
&& !has_impl_trait(def_id)
|
||||
{
|
||||
let successor =
|
||||
args.get(1).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
|
||||
let substs = self.infcx.resolve_vars_if_possible(substs);
|
||||
self.update_infer_source(InferSource {
|
||||
span: path.ident.span,
|
||||
kind: InferSourceKind::FullyQualifiedMethodCall {
|
||||
receiver: args.first().unwrap(),
|
||||
successor,
|
||||
substs,
|
||||
def_id,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#![feature(let_else)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(try_blocks)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
|
||||
#[macro_use]
|
||||
|
@ -983,7 +983,11 @@ impl<'hir> Map<'hir> {
|
||||
Node::AnonConst(constant) => self.body(constant.body).value.span,
|
||||
Node::Expr(expr) => expr.span,
|
||||
Node::Stmt(stmt) => stmt.span,
|
||||
Node::PathSegment(seg) => seg.ident.span,
|
||||
Node::PathSegment(seg) => {
|
||||
let ident_span = seg.ident.span;
|
||||
ident_span
|
||||
.with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
|
||||
}
|
||||
Node::Ty(ty) => ty.span,
|
||||
Node::TraitRef(tr) => tr.path.span,
|
||||
Node::Binding(pat) => pat.span,
|
||||
|
@ -63,6 +63,29 @@ impl GenericParamDef {
|
||||
bug!("cannot convert a non-lifetime parameter def to an early bound region")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_default(&self) -> bool {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Type { has_default, .. }
|
||||
| GenericParamDefKind::Const { has_default } => has_default,
|
||||
GenericParamDefKind::Lifetime => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_value<'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Type { has_default, .. } if has_default => {
|
||||
Some(EarlyBinder(tcx.type_of(self.def_id).into()))
|
||||
}
|
||||
GenericParamDefKind::Const { has_default } if has_default => {
|
||||
Some(EarlyBinder(tcx.const_param_default(self.def_id).into()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -204,6 +227,12 @@ impl<'tcx> Generics {
|
||||
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
|
||||
pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
|
||||
let own = &substs[self.parent_count..][..self.params.len()];
|
||||
if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
|
||||
}
|
||||
}
|
||||
|
||||
/// Bounds on generics.
|
||||
|
@ -2,9 +2,13 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/infer_array_len.rs:19:9
|
||||
|
|
||||
LL | let [_, _] = a.into();
|
||||
| ^^^^^^ consider giving this pattern a type
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider giving this pattern a type
|
||||
|
|
||||
LL | let [_, _]: _ = a.into();
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
--> $DIR/vector-no-ann.rs:2:16
|
||||
--> $DIR/vector-no-ann.rs:2:9
|
||||
|
|
||||
LL | let _foo = Vec::new();
|
||||
| ---- ^^^^^^^^ cannot infer type for type parameter `T`
|
||||
| |
|
||||
| consider giving `_foo` the explicit type `Vec<T>`, where the type parameter `T` is specified
|
||||
| ^^^^
|
||||
|
|
||||
help: consider giving `_foo` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let _foo: Vec<T> = Vec::new();
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27
|
||||
|
|
||||
LL | with_closure(|x: u32, y| {});
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type
|
||||
|
|
||||
LL | with_closure(|x: u32, y: B| {});
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,7 +8,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-52437.rs:2:30
|
||||
|
|
||||
LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type
|
||||
|
|
||||
LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
|
||||
| +++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-52437.rs:2:5
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `Foo<N>`
|
||||
--> $DIR/doesnt_infer.rs:11:15
|
||||
--> $DIR/doesnt_infer.rs:11:9
|
||||
|
|
||||
LL | let foo = Foo::foo();
|
||||
| --- ^^^^^^^^ cannot infer the value of const parameter `N`
|
||||
| |
|
||||
| consider giving `foo` the explicit type `Foo<N>`, where the const parameter `N` is specified
|
||||
| ^^^
|
||||
|
|
||||
help: consider giving `foo` an explicit type, where the the value of const parameter `N` is specified
|
||||
|
|
||||
LL | let foo: Foo<N> = Foo::foo();
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
error[E0283]: type annotations needed for `Mask<_, LANES>`
|
||||
--> $DIR/issue-91614.rs:6:13
|
||||
--> $DIR/issue-91614.rs:6:9
|
||||
|
|
||||
LL | let y = Mask::<_, _>::splat(false);
|
||||
| - ^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
|
||||
| |
|
||||
| consider giving `y` the explicit type `Mask<_, LANES>`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
= note: cannot satisfy `_: MaskElement`
|
||||
note: required by a bound in `Mask::<T, LANES>::splat`
|
||||
@ -12,6 +10,10 @@ note: required by a bound in `Mask::<T, LANES>::splat`
|
||||
|
|
||||
LL | T: MaskElement,
|
||||
| ^^^^^^^^^^^ required by this bound in `Mask::<T, LANES>::splat`
|
||||
help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let y: Mask<_, LANES> = Mask::<_, _>::splat(false);
|
||||
| ++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,13 +2,18 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/const_eval_resolve_canonical.rs:26:9
|
||||
|
|
||||
LL | let mut _q = Default::default();
|
||||
| ^^^^^^ consider giving `_q` a type
|
||||
| ^^^^^^
|
||||
|
|
||||
help: consider giving `_q` an explicit type
|
||||
|
|
||||
LL | let mut _q: _ = Default::default();
|
||||
| +++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/const_eval_resolve_canonical.rs:29:10
|
||||
|
|
||||
LL | _q = foo::<_, 2>(_q);
|
||||
| ^^^^^^^^^^^ cannot infer type
|
||||
| ^^^^^^^^^^^ cannot infer the value of the constant `{ N + 1 }`
|
||||
|
|
||||
note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found
|
||||
--> $DIR/const_eval_resolve_canonical.rs:8:1
|
||||
|
@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/cannot-infer-const-args.rs:6:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^ cannot infer the value of const parameter `X` declared on the function `foo`
|
||||
| ^^^ cannot infer the value of the const parameter `X` declared on the function `foo`
|
||||
|
|
||||
help: consider specifying the const argument
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | foo::<X>();
|
||||
| ~~~~~~~~
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-77092.rs:11:26
|
||||
|
|
||||
LL | println!("{:?}", take_array_from_mut(&mut arr, i));
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut`
|
||||
|
|
||||
help: consider specifying the const argument
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | println!("{:?}", take_array_from_mut::<N>(&mut arr, i));
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL | println!("{:?}", take_array_from_mut::<i32, N>(&mut arr, i));
|
||||
| ++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/method-chain.rs:15:33
|
||||
|
|
||||
LL | Foo.bar().bar().bar().bar().baz();
|
||||
| ^^^ cannot infer the value of const parameter `N` declared on the associated function `baz`
|
||||
| ^^^ cannot infer the value of the const parameter `N` declared on the associated function `baz`
|
||||
|
|
||||
help: consider specifying the const argument
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | Foo.bar().bar().bar().bar().baz::<N>();
|
||||
| ~~~~~~~~
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/one-param-uninferred.rs:9:23
|
||||
|
|
||||
LL | let _: [u8; 17] = foo();
|
||||
| ^^^ cannot infer the value of const parameter `M` declared on the function `foo`
|
||||
| ^^^ cannot infer the value of the const parameter `M` declared on the function `foo`
|
||||
|
|
||||
help: consider specifying the const argument
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | let _: [u8; 17] = foo::<M>();
|
||||
| ~~~~~~~~
|
||||
LL | let _: [u8; 17] = foo::<17_usize, M>();
|
||||
| +++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/uninferred-consts.rs:9:9
|
||||
|
|
||||
LL | Foo.foo();
|
||||
| ^^^ cannot infer the value of const parameter `A` declared on the associated function `foo`
|
||||
| ^^^ cannot infer the value of the const parameter `A` declared on the associated function `foo`
|
||||
|
|
||||
help: consider specifying the const argument
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | Foo.foo::<A>();
|
||||
| ~~~~~~~~
|
||||
LL | Foo.foo::<A, B>();
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,16 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-83249.rs:19:13
|
||||
--> $DIR/issue-83249.rs:19:9
|
||||
|
|
||||
LL | let _ = foo([0; 1]);
|
||||
| - ^^^ cannot infer type for type parameter `T` declared on the function `foo`
|
||||
| |
|
||||
| consider giving this pattern a type
|
||||
| ^
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-83249.rs:12:8
|
||||
help: consider giving this pattern a type
|
||||
|
|
||||
LL | fn foo<T: Foo>(_: [u8; T::N]) -> T {
|
||||
| ^
|
||||
LL | let _: _ = foo([0; 1]);
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,25 +2,23 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-64662.rs:2:9
|
||||
|
|
||||
LL | A = foo(),
|
||||
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
|
||||
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-64662.rs:6:14
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | const fn foo<T>() -> isize {
|
||||
| ^
|
||||
LL | A = foo::<T>(),
|
||||
| +++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-64662.rs:3:9
|
||||
|
|
||||
LL | B = foo(),
|
||||
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
|
||||
| ^^^ cannot infer type of the type parameter `T` declared on the function `foo`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-64662.rs:6:14
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | const fn foo<T>() -> isize {
|
||||
| ^
|
||||
LL | B = foo::<T>(),
|
||||
| +++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/E0282.rs:2:9
|
||||
|
|
||||
LL | let x = "hello".chars().rev().collect();
|
||||
| ^ consider giving `x` a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: _ = "hello".chars().rev().collect();
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,10 +10,7 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/E0283.rs:35:24
|
||||
|
|
||||
LL | let bar = foo_impl.into() * 1u32;
|
||||
| ---------^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `Into`
|
||||
| this method call resolves to `T`
|
||||
| ^^^^
|
||||
|
|
||||
note: multiple `impl`s satisfying `Impl: Into<_>` found
|
||||
--> $DIR/E0283.rs:17:1
|
||||
@ -23,10 +20,10 @@ LL | impl Into<u32> for Impl {
|
||||
= note: and another `impl` found in the `core` crate:
|
||||
- impl<T, U> Into<U> for T
|
||||
where U: From<T>;
|
||||
help: use the fully qualified path for the potential candidate
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | let bar = <Impl as Into<u32>>::into(foo_impl) * 1u32;
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
LL | let bar = <Impl as Into<T>>::into(foo_impl) * 1u32;
|
||||
| ++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -36,13 +36,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/E0401.rs:11:5
|
||||
|
|
||||
LL | bfnr(x);
|
||||
| ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr`
|
||||
| ^^^^ cannot infer type of the type parameter `U` declared on the function `bfnr`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/E0401.rs:4:13
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
|
||||
| ^
|
||||
LL | bfnr::<U, V, W>(x);
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/for-loop-unconstrained-element-type.rs:8:9
|
||||
--> $DIR/for-loop-unconstrained-element-type.rs:8:14
|
||||
|
|
||||
LL | for i in Vec::new() { }
|
||||
| ^ ---------- the element type for this iterator is not specified
|
||||
| |
|
||||
| cannot infer type
|
||||
| ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | for i in Vec::<T>::new() { }
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-91762.rs:25:15
|
||||
|
|
||||
LL | ret = <Self::Base as Functor>::fmap(arg);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `fmap`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `fmap`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | ret = <Self::Base as Functor>::fmap::<T, U>(arg);
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -29,17 +29,17 @@ fn baa(b: bool) -> impl std::fmt::Debug {
|
||||
}
|
||||
|
||||
fn muh() -> Result<(), impl std::fmt::Debug> {
|
||||
Err("whoops")?; //~^ ERROR type annotations needed
|
||||
Ok(())
|
||||
Err("whoops")?;
|
||||
Ok(()) //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn muh2() -> Result<(), impl std::fmt::Debug> {
|
||||
return Err(From::from("foo")); //~^ ERROR type annotations needed
|
||||
return Err(From::from("foo")); //~ ERROR type annotations needed
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn muh3() -> Result<(), impl std::fmt::Debug> {
|
||||
Err(From::from("foo")) //~^ ERROR type annotations needed
|
||||
Err(From::from("foo")) //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,20 +1,35 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cross-return-site-inference.rs:31:24
|
||||
--> $DIR/cross-return-site-inference.rs:33:5
|
||||
|
|
||||
LL | fn muh() -> Result<(), impl std::fmt::Debug> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
LL | Ok(())
|
||||
| ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | Ok::<(), E>(())
|
||||
| +++++++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cross-return-site-inference.rs:36:25
|
||||
--> $DIR/cross-return-site-inference.rs:37:12
|
||||
|
|
||||
LL | fn muh2() -> Result<(), impl std::fmt::Debug> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
LL | return Err(From::from("foo"));
|
||||
| ^^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | return Err::<(), E>(From::from("foo"));
|
||||
| +++++++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cross-return-site-inference.rs:41:25
|
||||
--> $DIR/cross-return-site-inference.rs:42:5
|
||||
|
|
||||
LL | fn muh3() -> Result<(), impl std::fmt::Debug> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
||||
LL | Err(From::from("foo"))
|
||||
| ^^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | Err::<(), E>(From::from("foo"))
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
trait Foo<T> {
|
||||
fn foo(self, f: impl FnOnce());
|
||||
}
|
||||
|
||||
impl<T> Foo<T> for () {
|
||||
fn foo(self, f: impl FnOnce()) {
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// FIXME: This should ideally use a fully qualified path
|
||||
// without mentioning the generic arguments of `foo`.
|
||||
().foo(|| ()) //~ ERROR type annotations needed
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/fully-qualified-path-impl-trait.rs:14:8
|
||||
|
|
||||
LL | ().foo(|| ())
|
||||
| ^^^ cannot infer type for type parameter `T` declared on the trait `Foo`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
@ -1,7 +1,7 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
fn weird() -> PhantomData<impl Sized> {
|
||||
PhantomData //~^ ERROR type annotations needed
|
||||
PhantomData //~ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/fallback_inference.rs:3:27
|
||||
--> $DIR/fallback_inference.rs:4:5
|
||||
|
|
||||
LL | fn weird() -> PhantomData<impl Sized> {
|
||||
| ^^^^^^^^^^ cannot infer type
|
||||
LL | PhantomData
|
||||
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | PhantomData::<T>
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
fn reify_as() -> Thunk<impl FnOnce(Continuation) -> Continuation> {
|
||||
Thunk::new(|mut cont| { //~ ERROR type annotations needed
|
||||
cont.reify_as();
|
||||
Thunk::new(|mut cont| {
|
||||
cont.reify_as(); //~ ERROR type annotations needed
|
||||
cont
|
||||
})
|
||||
}
|
||||
@ -14,8 +14,8 @@ fn reify_as() -> Thunk<impl FnOnce(Continuation) -> Continuation> {
|
||||
type Tait = impl FnOnce(Continuation) -> Continuation;
|
||||
|
||||
fn reify_as_tait() -> Thunk<Tait> {
|
||||
Thunk::new(|mut cont| { //~ ERROR type annotations needed
|
||||
cont.reify_as();
|
||||
Thunk::new(|mut cont| {
|
||||
cont.reify_as(); //~ ERROR type annotations needed
|
||||
cont
|
||||
})
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/hidden-type-is-opaque-2.rs:8:17
|
||||
--> $DIR/hidden-type-is-opaque-2.rs:9:9
|
||||
|
|
||||
LL | Thunk::new(|mut cont| {
|
||||
| ^^^^^^^^ consider giving this closure parameter a type
|
||||
LL | cont.reify_as();
|
||||
| ^^^^ cannot infer type
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/hidden-type-is-opaque-2.rs:17:17
|
||||
--> $DIR/hidden-type-is-opaque-2.rs:18:9
|
||||
|
|
||||
LL | Thunk::new(|mut cont| {
|
||||
| ^^^^^^^^ consider giving this closure parameter a type
|
||||
LL | cont.reify_as();
|
||||
| ^^^^ cannot infer type
|
||||
|
|
||||
= note: type must be known at this point
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed for `RaceBuilder<T, Never<T>>`
|
||||
--> $DIR/issue-84073.rs:32:16
|
||||
|
|
||||
LL | Race::new(|race| race.when());
|
||||
| ^^^^ consider giving this closure parameter the explicit type `RaceBuilder<T, Never<T>>`, where the type parameter `T` is specified
|
||||
| ^^^^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | Race::new(|race: RaceBuilder<T, Never<T>>| race.when());
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -16,7 +16,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-86719.rs:9:10
|
||||
|
|
||||
LL | |_| true
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type
|
||||
|
|
||||
LL | |_: _| true
|
||||
| +++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -18,7 +18,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-92305.rs:7:5
|
||||
|
|
||||
LL | iter::empty()
|
||||
| ^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the function `empty`
|
||||
| ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | iter::empty::<T>()
|
||||
| +++++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-92305.rs:10:35
|
||||
|
@ -3,12 +3,6 @@ error[E0282]: type annotations needed
|
||||
|
|
||||
LL | InMemoryStore.get_raw(&String::default());
|
||||
| ^^^^^^^ cannot infer type for type parameter `K`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/ambiguous_type_parameter.rs:9:6
|
||||
|
|
||||
LL | impl<K> Store<String, HashMap<K, String>> for InMemoryStore {
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cannot-infer-async.rs:13:9
|
||||
|
|
||||
LL | let fut = async {
|
||||
| --- consider giving `fut` a type
|
||||
...
|
||||
LL | Ok(())
|
||||
| ^^ cannot infer type for type parameter `E` declared on the enum `Result`
|
||||
| ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | Ok::<(), E>(())
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,8 +4,7 @@ fn main() {
|
||||
// error handles this gracefully, and in particular doesn't generate an extra
|
||||
// note about the `?` operator in the closure body, which isn't relevant to
|
||||
// the inference.
|
||||
let x = |r| {
|
||||
//~^ ERROR type annotations needed
|
||||
let x = |r| { //~ ERROR type annotations needed for `Result<(), E>`
|
||||
let v = r?;
|
||||
Ok(v)
|
||||
};
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed for `Result<(), E>`
|
||||
--> $DIR/cannot-infer-closure-circular.rs:7:14
|
||||
|
|
||||
LL | let x = |r| {
|
||||
| ^ consider giving this closure parameter the explicit type `Result<(), E>`, where the type parameter `E` is specified
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified
|
||||
|
|
||||
LL | let x = |r: Result<(), E>| {
|
||||
| +++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
fn main() {
|
||||
let x = |a: (), b: ()| {
|
||||
Err(a)?;
|
||||
Ok(b) //~ ERROR type annotations needed for the closure
|
||||
Ok(b) //~ ERROR type annotations needed
|
||||
};
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
error[E0282]: type annotations needed for the closure `fn((), ()) -> Result<(), _>`
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cannot-infer-closure.rs:4:9
|
||||
|
|
||||
LL | Ok(b)
|
||||
| ^^ cannot infer type for type parameter `E` declared on the enum `Result`
|
||||
| ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
|
||||
|
|
||||
help: give this closure an explicit return type without `_` placeholders
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | let x = |a: (), b: ()| -> Result<(), _> {
|
||||
| ++++++++++++++++
|
||||
LL | Ok::<(), E>(b)
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -16,7 +16,8 @@ fn infallible() -> Result<(), std::convert::Infallible> {
|
||||
|
||||
fn main() {
|
||||
let x = || -> Result<_, QualifiedError<_>> {
|
||||
infallible()?; //~ ERROR type annotations needed
|
||||
//~^ ERROR type annotations needed for `Result<(), QualifiedError<_>>`
|
||||
infallible()?;
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
error[E0282]: type annotations needed for the closure `fn() -> Result<(), QualifiedError<_>>`
|
||||
--> $DIR/cannot-infer-partial-try-return.rs:19:9
|
||||
error[E0282]: type annotations needed for `Result<(), QualifiedError<_>>`
|
||||
--> $DIR/cannot-infer-partial-try-return.rs:18:13
|
||||
|
|
||||
LL | infallible()?;
|
||||
| ^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
help: give this closure an explicit return type without `_` placeholders
|
||||
|
|
||||
LL | let x = || -> Result<(), QualifiedError<_>> {
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LL | let x = || -> Result<_, QualifiedError<_>> {
|
||||
| ^^^^^^----------------------------
|
||||
| |
|
||||
| help: try giving this closure an explicit return type: `Result<(), QualifiedError<_>>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,46 +1,40 @@
|
||||
error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>`
|
||||
--> $DIR/erase-type-params-in-label.rs:2:15
|
||||
--> $DIR/erase-type-params-in-label.rs:2:9
|
||||
|
|
||||
LL | let foo = foo(1, "");
|
||||
| --- ^^^ cannot infer type for type parameter `W` declared on the function `foo`
|
||||
| |
|
||||
| consider giving `foo` the explicit type `Foo<_, _, W, Z>`, where the type parameter `W` is specified
|
||||
| ^^^
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/erase-type-params-in-label.rs:25:14
|
||||
|
|
||||
LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
|
||||
| ^
|
||||
= note: cannot satisfy `_: Default`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/erase-type-params-in-label.rs:25:17
|
||||
|
|
||||
LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
|
||||
| ^^^^^^^ required by this bound in `foo`
|
||||
help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
|
||||
|
|
||||
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
|
||||
| ++++++++++++++++++++++
|
||||
help: consider specifying the type arguments in the function call
|
||||
|
|
||||
LL | let foo = foo::<T, K, W, Z>(1, "");
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
|
||||
--> $DIR/erase-type-params-in-label.rs:5:15
|
||||
--> $DIR/erase-type-params-in-label.rs:5:9
|
||||
|
|
||||
LL | let bar = bar(1, "");
|
||||
| --- ^^^ cannot infer type for type parameter `Z` declared on the function `bar`
|
||||
| |
|
||||
| consider giving `bar` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified
|
||||
| ^^^
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/erase-type-params-in-label.rs:14:14
|
||||
|
|
||||
LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
|
||||
| ^
|
||||
= note: cannot satisfy `_: Default`
|
||||
note: required by a bound in `bar`
|
||||
--> $DIR/erase-type-params-in-label.rs:14:17
|
||||
|
|
||||
LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
|
||||
| ^^^^^^^ required by this bound in `bar`
|
||||
help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
|
||||
|
|
||||
LL | let bar: Bar<i32, &str, Z> = bar(1, "");
|
||||
| +++++++++++++++++++
|
||||
help: consider specifying the type arguments in the function call
|
||||
|
|
||||
LL | let bar = bar::<T, K, Z>(1, "");
|
||||
|
@ -2,9 +2,7 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-71732.rs:18:10
|
||||
|
|
||||
LL | .get(&"key".into())
|
||||
| ^^^ ------------ this method call resolves to `T`
|
||||
| |
|
||||
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
||||
| ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get`
|
||||
|
|
||||
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
|
||||
- impl Borrow<str> for String;
|
||||
@ -15,6 +13,10 @@ note: required by a bound in `HashMap::<K, V, S>::get`
|
||||
|
|
||||
LL | K: Borrow<Q>,
|
||||
| ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get`
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | .get::<Q>(&"key".into())
|
||||
| +++++
|
||||
help: consider specifying the type argument in the function call
|
||||
|
|
||||
LL | .get::<Q>(&"key".into())
|
||||
|
@ -1,16 +1,18 @@
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72616.rs:20:30
|
||||
--> $DIR/issue-72616.rs:20:37
|
||||
|
|
||||
LL | if String::from("a") == "a".try_into().unwrap() {}
|
||||
| ^^ -------------- this method call resolves to `Result<T, <Self as TryInto<T>>::Error>`
|
||||
| |
|
||||
| cannot infer type
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate:
|
||||
- impl PartialEq for String;
|
||||
- impl<'a, 'b> PartialEq<&'a str> for String;
|
||||
- impl<'a, 'b> PartialEq<Cow<'a, str>> for String;
|
||||
- impl<'a, 'b> PartialEq<str> for String;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
|
||||
| +++++++++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `[usize; _]`
|
||||
--> $DIR/issue-83606.rs:8:13
|
||||
--> $DIR/issue-83606.rs:8:9
|
||||
|
|
||||
LL | let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
|
||||
| - ^^^ cannot infer the value of const parameter `N` declared on the function `foo`
|
||||
| |
|
||||
| consider giving this pattern the explicit type `[_; N]`, where the const parameter `N` is specified
|
||||
| ^
|
||||
|
|
||||
help: consider giving this pattern a type, where the the value of const parameter `N` is specified
|
||||
|
|
||||
LL | let _: [usize; _] = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,20 +1,19 @@
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-86162-1.rs:7:5
|
||||
--> $DIR/issue-86162-1.rs:7:9
|
||||
|
|
||||
LL | foo(gen()); //<- Do not suggest `foo::<impl Clone>()`!
|
||||
| ^^^ cannot infer type for type parameter `impl Clone` declared on the function `foo`
|
||||
| ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-86162-1.rs:3:11
|
||||
|
|
||||
LL | fn foo(x: impl Clone) {}
|
||||
| ^^^^^^^^^^
|
||||
= note: cannot satisfy `_: Clone`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/issue-86162-1.rs:3:16
|
||||
|
|
||||
LL | fn foo(x: impl Clone) {}
|
||||
| ^^^^^ required by this bound in `foo`
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | foo(gen::<T>()); //<- Do not suggest `foo::<impl Clone>()`!
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,20 +1,19 @@
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-86162-2.rs:12:5
|
||||
--> $DIR/issue-86162-2.rs:12:14
|
||||
|
|
||||
LL | Foo::bar(gen()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
|
||||
| ^^^^^^^^ cannot infer type for type parameter `impl Clone` declared on the associated function `bar`
|
||||
| ^^^ cannot infer type of the type parameter `T` declared on the function `gen`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-86162-2.rs:8:15
|
||||
|
|
||||
LL | fn bar(x: impl Clone) {}
|
||||
| ^^^^^^^^^^
|
||||
= note: cannot satisfy `_: Clone`
|
||||
note: required by a bound in `Foo::bar`
|
||||
--> $DIR/issue-86162-2.rs:8:20
|
||||
|
|
||||
LL | fn bar(x: impl Clone) {}
|
||||
| ^^^^^ required by this bound in `Foo::bar`
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | Foo::bar(gen::<T>()); //<- Do not suggest `Foo::bar::<impl Clone>()`!
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
error[E0282]: type annotations needed for `&T`
|
||||
--> $DIR/issue-12187-1.rs:6:10
|
||||
--> $DIR/issue-12187-1.rs:6:9
|
||||
|
|
||||
LL | let &v = new();
|
||||
| -^
|
||||
| ||
|
||||
| |cannot infer type
|
||||
| consider giving this pattern the explicit type `&T`, with the type parameters specified
|
||||
| ^^
|
||||
|
|
||||
help: consider giving this pattern a type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let &v: &T = new();
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
error[E0282]: type annotations needed for `&T`
|
||||
--> $DIR/issue-12187-2.rs:6:10
|
||||
--> $DIR/issue-12187-2.rs:6:9
|
||||
|
|
||||
LL | let &v = new();
|
||||
| -^
|
||||
| ||
|
||||
| |cannot infer type
|
||||
| consider giving this pattern the explicit type `&T`, with the type parameters specified
|
||||
| ^^
|
||||
|
|
||||
help: consider giving this pattern a type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let &v: &T = new();
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,9 +2,13 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-16966.rs:2:5
|
||||
|
|
||||
LL | panic!(std::default::Default::default());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `M` declared on the function `begin_panic`
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | $crate::rt::begin_panic::<M>($msg)
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `B<T>`
|
||||
--> $DIR/issue-17551.rs:6:15
|
||||
--> $DIR/issue-17551.rs:6:9
|
||||
|
|
||||
LL | let foo = B(marker::PhantomData);
|
||||
| --- ^ cannot infer type for type parameter `T` declared on the struct `B`
|
||||
| |
|
||||
| consider giving `foo` the explicit type `B<T>`, where the type parameter `T` is specified
|
||||
| ^^^
|
||||
|
|
||||
help: consider giving `foo` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let foo: B<T> = B(marker::PhantomData);
|
||||
| ++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-18159.rs:2:9
|
||||
|
|
||||
LL | let x;
|
||||
| ^ consider giving `x` a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: _;
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
error[E0282]: type annotations needed for `(_,)`
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-20261.rs:4:11
|
||||
|
|
||||
LL | for (ref i,) in [].iter() {
|
||||
| --------- this method call resolves to `std::slice::Iter<'_, T>`
|
||||
LL | i.clone();
|
||||
| ^^^^^ cannot infer type
|
||||
|
|
||||
|
@ -1,4 +1,4 @@
|
||||
fn main() {
|
||||
let x = panic!();
|
||||
x.clone(); //~ ERROR type annotations needed
|
||||
let x = panic!(); //~ ERROR type annotations needed
|
||||
x.clone();
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-2151.rs:3:5
|
||||
--> $DIR/issue-2151.rs:2:9
|
||||
|
|
||||
LL | let x = panic!();
|
||||
| - consider giving `x` a type
|
||||
LL | x.clone();
|
||||
| ^ cannot infer type
|
||||
| ^
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: _ = panic!();
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed for `Expr<'_, VAR>`
|
||||
--> $DIR/issue-23046.rs:17:15
|
||||
|
|
||||
LL | let ex = |x| {
|
||||
| ^ consider giving this closure parameter the explicit type `Expr<'_, VAR>`, where the type parameter `VAR` is specified
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type, where the type for type parameter `VAR` is specified
|
||||
|
|
||||
LL | let ex = |x: Expr<'_, VAR>| {
|
||||
| +++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -15,7 +15,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-24036.rs:9:15
|
||||
|
|
||||
LL | 1 => |c| c + 1,
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type
|
||||
|
|
||||
LL | 1 => |c: _| c + 1,
|
||||
| +++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -5,9 +5,10 @@ use std::marker::PhantomData;
|
||||
struct Foo<T> {foo: PhantomData<T>}
|
||||
|
||||
fn main() {
|
||||
let (tx, rx) = channel();
|
||||
|
||||
let (tx, rx) = //~ ERROR type annotations needed
|
||||
channel();
|
||||
// FIXME(#89862): Suggest adding a generic argument to `channel` instead
|
||||
spawn(move || {
|
||||
tx.send(Foo{ foo: PhantomData }); //~ ERROR E0282
|
||||
tx.send(Foo{ foo: PhantomData });
|
||||
});
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
error[E0282]: type annotations needed for `(Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`
|
||||
--> $DIR/issue-25368.rs:11:17
|
||||
--> $DIR/issue-25368.rs:8:9
|
||||
|
|
||||
LL | let (tx, rx) = channel();
|
||||
| -------- consider giving this pattern the explicit type `(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 type parameter `T` declared on the struct `Foo`
|
||||
LL | let (tx, rx) =
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let (tx, rx): (Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>) =
|
||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-47486.rs:3:31
|
||||
--> $DIR/issue-47486.rs:3:11
|
||||
|
|
||||
LL | [0u8; std::mem::size_of::<_>()];
|
||||
| ^ cannot infer type
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `size_of`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | [0u8; std::mem::size_of::<_>()];
|
||||
| ~~~~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-47486.rs:2:10
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-5062.rs:1:29
|
||||
|
|
||||
LL | fn main() { format!("{:?}", None); }
|
||||
| ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`
|
||||
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | fn main() { format!("{:?}", None::<T>); }
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,6 @@ fn main() {
|
||||
let tiles = Default::default();
|
||||
for row in &mut tiles {
|
||||
for tile in row {
|
||||
//~^ NOTE the element type for this iterator is not specified
|
||||
*tile = 0;
|
||||
//~^ ERROR type annotations needed
|
||||
//~| NOTE cannot infer type
|
||||
|
@ -1,9 +1,6 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-51116.rs:6:13
|
||||
--> $DIR/issue-51116.rs:5:13
|
||||
|
|
||||
LL | for tile in row {
|
||||
| --- the element type for this iterator is not specified
|
||||
LL |
|
||||
LL | *tile = 0;
|
||||
| ^^^^^ cannot infer type
|
||||
|
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-6458-2.rs:3:21
|
||||
|
|
||||
LL | format!("{:?}", None);
|
||||
| ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`
|
||||
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | format!("{:?}", None::<T>);
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-6458-3.rs:4:5
|
||||
|
|
||||
LL | mem::transmute(0);
|
||||
| ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute`
|
||||
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `transmute`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | mem::transmute::<i32, U>(0);
|
||||
| ++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-6458.rs:9:4
|
||||
--> $DIR/issue-6458.rs:9:22
|
||||
|
|
||||
LL | foo(TypeWithState(marker::PhantomData));
|
||||
| ^^^ cannot infer type for type parameter `State` declared on the function `foo`
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/issue-6458.rs:6:12
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | pub fn foo<State>(_: TypeWithState<State>) {}
|
||||
| ^^^^^
|
||||
LL | foo(TypeWithState(marker::PhantomData::<T>));
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -30,7 +30,7 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-66706.rs:2:11
|
||||
|
|
||||
LL | [0; [|_: _ &_| ()].len()]
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^ cannot infer type
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-66706.rs:2:5
|
||||
|
@ -1,22 +1,20 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-69455.rs:29:20
|
||||
|
|
||||
LL | type Output;
|
||||
| ------------ `<Self as Test<Rhs>>::Output` defined here
|
||||
...
|
||||
LL | println!("{}", 23u64.test(xs.iter().sum()));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this method call resolves to `<Self as Test<Rhs>>::Output`
|
||||
| cannot infer type for type parameter `T` declared on the associated function `new_display`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `new_display`
|
||||
|
|
||||
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | println!("{}", 23u64.test(xs.iter().sum())::<T>);
|
||||
| +++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-69455.rs:29:26
|
||||
--> $DIR/issue-69455.rs:29:41
|
||||
|
|
||||
LL | println!("{}", 23u64.test(xs.iter().sum()));
|
||||
| ^^^^ cannot infer type for type parameter `Rhs` declared on the trait `Test`
|
||||
| ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
|
||||
|
|
||||
note: multiple `impl`s satisfying `u64: Test<_>` found
|
||||
--> $DIR/issue-69455.rs:11:1
|
||||
@ -26,7 +24,7 @@ LL | impl Test<u32> for u64 {
|
||||
...
|
||||
LL | impl Test<u64> for u64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider specifying the type argument in the method call
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | println!("{}", 23u64.test(xs.iter().sum::<S>()));
|
||||
| +++++
|
||||
|
@ -8,7 +8,7 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-69683.rs:30:10
|
||||
|
|
||||
LL | 0u16.foo(b);
|
||||
| ^^^ cannot infer type for type parameter `I` declared on the trait `Foo`
|
||||
| ^^^
|
||||
|
|
||||
note: multiple `impl`s satisfying `u8: Element<_>` found
|
||||
--> $DIR/issue-69683.rs:5:1
|
||||
@ -26,6 +26,10 @@ LL | u8: Element<I>,
|
||||
LL | {
|
||||
LL | fn foo(self, x: <u8 as Element<I>>::Array);
|
||||
| --- required by a bound in this
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <u16 as Foo<I>>::foo(0u16, b);
|
||||
| +++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -12,51 +12,60 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:7:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:12:6
|
||||
|
|
||||
LL | |x| String::from("x".as_ref());
|
||||
| ^ consider giving this closure parameter a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving this closure parameter an explicit type
|
||||
|
|
||||
LL | |x: _| String::from("x".as_ref());
|
||||
| +++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:12:26
|
||||
|
|
||||
LL | |x| String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed for `&T`
|
||||
--> $DIR/issue-72690.rs:17:17
|
||||
--> $DIR/issue-72690.rs:17:9
|
||||
|
|
||||
LL | let _ = "x".as_ref();
|
||||
| - ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| |
|
||||
| consider giving this pattern the explicit type `&T`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let _: &T = "x".as_ref();
|
||||
| ++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:21:5
|
||||
@ -72,16 +81,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:21:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:28:5
|
||||
@ -97,16 +107,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:28:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:37:5
|
||||
@ -122,16 +133,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:37:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:46:5
|
||||
@ -147,16 +159,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:46:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:53:5
|
||||
@ -172,16 +185,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:53:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:62:5
|
||||
@ -197,16 +211,17 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-72690.rs:62:22
|
||||
|
|
||||
LL | String::from("x".as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
|
||||
- impl AsRef<OsStr> for str;
|
||||
- impl AsRef<Path> for str;
|
||||
- impl AsRef<[u8]> for str;
|
||||
- impl AsRef<str> for str;
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | String::from(<str as AsRef<T>>::as_ref("x"));
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `&[_; 0]`
|
||||
--> $DIR/issue-7813.rs:2:13
|
||||
--> $DIR/issue-7813.rs:2:9
|
||||
|
|
||||
LL | let v = &[];
|
||||
| - ^^^ cannot infer type
|
||||
| |
|
||||
| consider giving `v` the explicit type `&[_; 0]`, with the type parameters specified
|
||||
| ^
|
||||
|
|
||||
help: consider giving `v` an explicit type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let v: &[_; 0] = &[];
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/match-unresolved-one-arm.rs:4:9
|
||||
|
|
||||
LL | let x = match () {
|
||||
| ^ consider giving `x` a type
|
||||
| ^
|
||||
|
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: _ = match () {
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:9
|
||||
|
|
||||
LL | let mut x = Vec::new();
|
||||
| ----- ^^^^^^^^ cannot infer type for type parameter `T`
|
||||
| |
|
||||
| consider giving `x` the explicit type `Vec<T>`, where the type parameter `T` is specified
|
||||
| ^^^^^
|
||||
|
|
||||
help: consider giving `x` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let mut x: Vec<T> = Vec::new();
|
||||
| ++++++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7
|
||||
|
@ -2,13 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/missing-type-parameter.rs:4:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^ cannot infer type for type parameter `X` declared on the function `foo`
|
||||
| ^^^ cannot infer type of the type parameter `X` declared on the function `foo`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/missing-type-parameter.rs:1:8
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | fn foo<X>() { }
|
||||
| ^
|
||||
LL | foo::<X>();
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -116,7 +116,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14
|
||||
|
|
||||
LL | V = [Vec::new; { [0].len() ].len() as isize,
|
||||
| ^^^^^^^^ cannot infer type for type parameter `T`
|
||||
| ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Vec`
|
||||
|
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | V = [Vec::<T>::new; { [0].len() ].len() as isize,
|
||||
| +++++
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
@ -40,24 +40,26 @@ LL | let v : Vec<'a> = vec![];
|
||||
| +
|
||||
|
||||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:25
|
||||
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:7
|
||||
|
|
||||
LL | let v : Vec<(u32,_) = vec![];
|
||||
| - ^^^^^^ cannot infer type for type parameter `T`
|
||||
| |
|
||||
| consider giving `v` the explicit type `Vec<T>`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let v: Vec<T> : Vec<(u32,_) = vec![];
|
||||
| ++++++++
|
||||
|
||||
error[E0282]: type annotations needed for `Vec<T>`
|
||||
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:20
|
||||
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:7
|
||||
|
|
||||
LL | let v : Vec<'a = vec![];
|
||||
| - ^^^^^^ cannot infer type for type parameter `T`
|
||||
| |
|
||||
| consider giving `v` the explicit type `Vec<T>`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let v: Vec<T> : Vec<'a = vec![];
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
fn main() {
|
||||
let x;
|
||||
let x; //~ ERROR type annotations needed
|
||||
|
||||
match x {
|
||||
(..) => {} //~ ERROR type annotations needed
|
||||
(..) => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/pat-tuple-bad-type.rs:5:9
|
||||
--> $DIR/pat-tuple-bad-type.rs:2:9
|
||||
|
|
||||
LL | let x;
|
||||
| - consider giving `x` a type
|
||||
...
|
||||
LL | (..) => {}
|
||||
| ^^^^ cannot infer type
|
||||
| ^
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: _;
|
||||
| +++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-tuple-bad-type.rs:10:9
|
||||
|
@ -189,7 +189,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/rest-pat-semantic-disallowed.rs:33:9
|
||||
|
|
||||
LL | let x @ ..;
|
||||
| ^^^^^^ consider giving this pattern a type
|
||||
| ^^^^^^
|
||||
|
|
||||
help: consider giving this pattern a type
|
||||
|
|
||||
LL | let x @ ..: _;
|
||||
| +++
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
|
||||
|
@ -17,7 +17,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-85348.rs:6:13
|
||||
|
|
||||
LL | let mut N;
|
||||
| ^^^^^ consider giving `N` a type
|
||||
| ^^^^^
|
||||
|
|
||||
help: consider giving `N` an explicit type
|
||||
|
|
||||
LL | let mut N: _;
|
||||
| +++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,20 +1,26 @@
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:10:7
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:9:24
|
||||
|
|
||||
LL | let x: Option<_> = None;
|
||||
| - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified
|
||||
LL | x.unwrap().method_that_could_exist_on_some_type();
|
||||
| ^^^^^^ cannot infer type for type parameter `T`
|
||||
LL | let x: Option<_> = None::<_>;
|
||||
| ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | let x: Option<_> = None::<_>;
|
||||
| ~~~~~
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:16:10
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:15:10
|
||||
|
|
||||
LL | .sum::<_>()
|
||||
| ^^^ cannot infer type
|
||||
| ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | .sum::<_>()
|
||||
| ~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,20 +1,26 @@
|
||||
error[E0282]: type annotations needed for `Option<_>`
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:10:7
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:9:24
|
||||
|
|
||||
LL | let x: Option<_> = None;
|
||||
| - consider giving `x` the explicit type `Option<_>`, where the type parameter `T` is specified
|
||||
LL | x.unwrap().method_that_could_exist_on_some_type();
|
||||
| ^^^^^^ cannot infer type for type parameter `T`
|
||||
LL | let x: Option<_> = None::<_>;
|
||||
| ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | let x: Option<_> = None::<T>;
|
||||
| ~~~~~
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:16:16
|
||||
--> $DIR/issue-42234-unknown-receiver-type.rs:15:10
|
||||
|
|
||||
LL | .sum::<_>()
|
||||
| ^ cannot infer type for type parameter `S` declared on the associated function `sum`
|
||||
| ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | .sum::<S>()
|
||||
| ~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -6,9 +6,8 @@
|
||||
// the fix of which this tests).
|
||||
|
||||
fn shines_a_beacon_through_the_darkness() {
|
||||
let x: Option<_> = None;
|
||||
let x: Option<_> = None::<_>; //~ ERROR type annotations needed
|
||||
x.unwrap().method_that_could_exist_on_some_type();
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
||||
fn courier_to_des_moines_and_points_west(data: &[u32]) -> String {
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
fn main() {
|
||||
let mut x = Default::default();
|
||||
x.0;
|
||||
//~^ ERROR type annotations needed
|
||||
x.0;
|
||||
x = 1;
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let mut x = Default::default();
|
||||
x[0];
|
||||
//~^ ERROR type annotations needed
|
||||
x[0];
|
||||
x = 1;
|
||||
}
|
||||
|
@ -1,22 +1,26 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method-and-field-eager-resolution.rs:5:5
|
||||
--> $DIR/method-and-field-eager-resolution.rs:4:9
|
||||
|
|
||||
LL | let mut x = Default::default();
|
||||
| ----- consider giving `x` a type
|
||||
LL | x.0;
|
||||
| ^ cannot infer type
|
||||
| ^^^^^
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let mut x: _ = Default::default();
|
||||
| +++
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method-and-field-eager-resolution.rs:12:5
|
||||
--> $DIR/method-and-field-eager-resolution.rs:11:9
|
||||
|
|
||||
LL | let mut x = Default::default();
|
||||
| ----- consider giving `x` a type
|
||||
LL | x[0];
|
||||
| ^ cannot infer type
|
||||
| ^^^^^
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let mut x: _ = Default::default();
|
||||
| +++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,10 +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 type parameter `S` declared on the associated function `sum`
|
||||
| ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum`
|
||||
|
|
||||
= note: type must be known at this point
|
||||
help: consider specifying the type argument in the method call
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | let _ = (vec![1,2,3]).into_iter().sum::<S>() as f64;
|
||||
| +++++
|
||||
|
@ -1,5 +1,7 @@
|
||||
fn f<A>() -> A { unimplemented!() }
|
||||
fn foo() {
|
||||
let _ = f; //~ ERROR type annotations needed for `fn() -> A`
|
||||
let _ = f;
|
||||
//~^ ERROR type annotations needed
|
||||
//~| HELP consider specifying the generic argument
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -1,16 +1,13 @@
|
||||
error[E0282]: type annotations needed for `fn() -> A`
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/fn-needing-specified-return-type-param.rs:3:13
|
||||
|
|
||||
LL | let _ = f;
|
||||
| - ^ cannot infer type for type parameter `A` declared on the function `f`
|
||||
| |
|
||||
| consider giving this pattern the explicit type `fn() -> A`, where the type parameter `A` is specified
|
||||
| ^ cannot infer type of the type parameter `A` declared on the function `f`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/fn-needing-specified-return-type-param.rs:1:6
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | fn f<A>() -> A { unimplemented!() }
|
||||
| ^
|
||||
LL | let _ = f::<A>;
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
fn unbound_drop(_: impl Sized) {}
|
||||
|
||||
fn main() {
|
||||
let _v = || -> _ { [] }; //~ ERROR type annotations needed for the closure
|
||||
unbound_drop(|| -> _ { [] });
|
||||
//~^ ERROR type annotations needed for `[_; 0]`
|
||||
//~| HELP try giving this closure an explicit return type
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-1.rs:2:24
|
||||
error[E0282]: type annotations needed for `[_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-1.rs:4:18
|
||||
|
|
||||
LL | let _v = || -> _ { [] };
|
||||
| ^^ cannot infer type
|
||||
|
|
||||
help: give this closure an explicit return type without `_` placeholders
|
||||
|
|
||||
LL | let _v = || -> [_; 0] { [] };
|
||||
| ~~~~~~
|
||||
LL | unbound_drop(|| -> _ { [] });
|
||||
| ^^^^^^-
|
||||
| |
|
||||
| help: try giving this closure an explicit return type: `[_; 0]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
fn unbound_drop(_: impl Sized) {}
|
||||
|
||||
fn main() {
|
||||
let _v = || { [] }; //~ ERROR type annotations needed for the closure
|
||||
unbound_drop(|| { [] })
|
||||
//~^ ERROR type annotations needed for `[_; 0]`
|
||||
//~| HELP try giving this closure an explicit return type
|
||||
}
|
||||
|
@ -1,13 +1,8 @@
|
||||
error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-2.rs:2:19
|
||||
error[E0282]: type annotations needed for `[_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-2.rs:4:18
|
||||
|
|
||||
LL | let _v = || { [] };
|
||||
| ^^ cannot infer type
|
||||
|
|
||||
help: give this closure an explicit return type without `_` placeholders
|
||||
|
|
||||
LL | let _v = || -> [_; 0] { [] };
|
||||
| +++++++++
|
||||
LL | unbound_drop(|| { [] })
|
||||
| ^^ - help: try giving this closure an explicit return type: `-> [_; 0]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
fn unbound_drop(_: impl Sized) {}
|
||||
|
||||
fn main() {
|
||||
let _v = || []; //~ ERROR type annotations needed for the closure
|
||||
unbound_drop(|| []);
|
||||
//~^ ERROR type annotations needed for `[_; 0]`
|
||||
//~| HELP try giving this closure an explicit return type
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-3.rs:2:17
|
||||
error[E0282]: type annotations needed for `[_; 0]`
|
||||
--> $DIR/suggest-closure-return-type-3.rs:4:18
|
||||
|
|
||||
LL | let _v = || [];
|
||||
| ^^ cannot infer type
|
||||
LL | unbound_drop(|| []);
|
||||
| ^^
|
||||
|
|
||||
help: give this closure an explicit return type without `_` placeholders
|
||||
help: try giving this closure an explicit return type
|
||||
|
|
||||
LL | let _v = || -> [_; 0] { [] };
|
||||
| +++++++++++ +
|
||||
LL | unbound_drop(|| -> [_; 0] { [] });
|
||||
| +++++++++++ +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,19 +2,18 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11
|
||||
|
|
||||
LL | thing.method(42);
|
||||
| ------^^^^^^----
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `Method`
|
||||
| this method call resolves to `T`
|
||||
| ^^^^^^
|
||||
|
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <Thing<bool> as Method<T>>::method(thing, 42);
|
||||
| +++++++++++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11
|
||||
|
|
||||
LL | thing.method(42);
|
||||
| ------^^^^^^----
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `Method`
|
||||
| this method call resolves to `T`
|
||||
| ^^^^^^
|
||||
|
|
||||
note: multiple `impl`s satisfying `Thing<bool>: Method<_>` found
|
||||
--> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:7:1
|
||||
@ -24,12 +23,10 @@ LL | impl<X> Method<i32> for Thing<X> {
|
||||
...
|
||||
LL | impl<X> Method<u32> for Thing<X> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: use the fully qualified path for the potential candidates
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <Thing<_> as Method<i32>>::method(thing, 42);
|
||||
| ++++++++++++++++++++++++++++++++++ ~
|
||||
LL | <Thing<_> as Method<u32>>::method(thing, 42);
|
||||
| ++++++++++++++++++++++++++++++++++ ~
|
||||
LL | <Thing<bool> as Method<T>>::method(thing, 42);
|
||||
| +++++++++++++++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,9 +2,7 @@ error[E0283]: type annotations needed
|
||||
--> $DIR/issue-77982.rs:8:10
|
||||
|
|
||||
LL | opts.get(opt.as_ref());
|
||||
| ^^^ ------------ this method call resolves to `&T`
|
||||
| |
|
||||
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
||||
| ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get`
|
||||
|
|
||||
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
|
||||
- impl Borrow<str> for String;
|
||||
@ -15,44 +13,36 @@ note: required by a bound in `HashMap::<K, V, S>::get`
|
||||
|
|
||||
LL | K: Borrow<Q>,
|
||||
| ^^^^^^^^^ required by this bound in `HashMap::<K, V, S>::get`
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | opts.get::<Q>(opt.as_ref());
|
||||
| +++++
|
||||
help: consider specifying the type argument in the function call
|
||||
|
|
||||
LL | opts.get::<Q>(opt.as_ref());
|
||||
| +++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-77982.rs:8:18
|
||||
--> $DIR/issue-77982.rs:8:10
|
||||
|
|
||||
LL | opts.get(opt.as_ref());
|
||||
| ----^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
|
||||
| this method call resolves to `&T`
|
||||
| ^^^ cannot infer type of the type parameter `Q` declared on the associated function `get`
|
||||
|
|
||||
= note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`:
|
||||
- impl AsRef<OsStr> for String;
|
||||
- impl AsRef<Path> for String;
|
||||
- impl AsRef<[u8]> for String;
|
||||
- impl AsRef<str> for String;
|
||||
help: use the fully qualified path for the potential candidates
|
||||
help: consider specifying the generic argument
|
||||
|
|
||||
LL | opts.get(<String as AsRef<OsStr>>::as_ref(opt));
|
||||
| +++++++++++++++++++++++++++++++++ ~
|
||||
LL | opts.get(<String as AsRef<Path>>::as_ref(opt));
|
||||
| ++++++++++++++++++++++++++++++++ ~
|
||||
LL | opts.get(<String as AsRef<[u8]>>::as_ref(opt));
|
||||
| ++++++++++++++++++++++++++++++++ ~
|
||||
LL | opts.get(<String as AsRef<str>>::as_ref(opt));
|
||||
| +++++++++++++++++++++++++++++++ ~
|
||||
and 4 other candidates
|
||||
LL | opts.get::<Q>(opt.as_ref());
|
||||
| +++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/issue-77982.rs:13:44
|
||||
--> $DIR/issue-77982.rs:13:59
|
||||
|
|
||||
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
|
||||
| ^^^^^^^^^ ----------- this method call resolves to `T`
|
||||
| |
|
||||
| cannot infer type for type parameter `T` declared on the trait `From`
|
||||
| ^^^^
|
||||
|
|
||||
= note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
|
||||
- impl From<Ipv4Addr> for u32;
|
||||
@ -60,14 +50,16 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
|
||||
- impl From<bool> for u32;
|
||||
- impl From<char> for u32;
|
||||
and 3 more
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed for `Box<T>`
|
||||
--> $DIR/issue-77982.rs:36:16
|
||||
--> $DIR/issue-77982.rs:36:9
|
||||
|
|
||||
LL | let _ = ().foo();
|
||||
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo`
|
||||
| |
|
||||
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
note: multiple `impl`s satisfying `(): Foo<'_, _>` found
|
||||
--> $DIR/issue-77982.rs:29:1
|
||||
@ -76,14 +68,16 @@ LL | impl Foo<'static, u32> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<'a> Foo<'a, i16> for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let _: Box<T> = ().foo();
|
||||
| ++++++++
|
||||
|
||||
error[E0283]: type annotations needed for `Box<T>`
|
||||
--> $DIR/issue-77982.rs:40:19
|
||||
--> $DIR/issue-77982.rs:40:9
|
||||
|
|
||||
LL | let _ = (&()).bar();
|
||||
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar`
|
||||
| |
|
||||
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
||||
| ^
|
||||
|
|
||||
note: multiple `impl`s satisfying `&(): Bar<'_, _>` found
|
||||
--> $DIR/issue-77982.rs:32:1
|
||||
@ -92,6 +86,10 @@ LL | impl<'a> Bar<'static, u32> for &'a () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | impl<'a> Bar<'a, i16> for &'a () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider giving this pattern a type, where the type for type parameter `T` is specified
|
||||
|
|
||||
LL | let _: Box<T> = (&()).bar();
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -2,25 +2,19 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/multidispatch-convert-ambig-dest.rs:26:5
|
||||
|
|
||||
LL | test(22, std::default::Default::default());
|
||||
| ^^^^ cannot infer type for type parameter `U` declared on the function `test`
|
||||
| ^^^^ cannot infer type of the type parameter `U` declared on the function `test`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/multidispatch-convert-ambig-dest.rs:20:11
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | fn test<T,U>(_: T, _: U)
|
||||
| ^
|
||||
LL | test::<i32, U>(22, std::default::Default::default());
|
||||
| ++++++++++
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/multidispatch-convert-ambig-dest.rs:26:5
|
||||
|
|
||||
LL | test(22, std::default::Default::default());
|
||||
| ^^^^ cannot infer type for type parameter `U` declared on the function `test`
|
||||
| ^^^^ cannot infer type of the type parameter `U` declared on the function `test`
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/multidispatch-convert-ambig-dest.rs:20:11
|
||||
|
|
||||
LL | fn test<T,U>(_: T, _: U)
|
||||
| ^
|
||||
note: multiple `impl`s satisfying `i32: Convert<_>` found
|
||||
--> $DIR/multidispatch-convert-ambig-dest.rs:8:1
|
||||
|
|
||||
@ -36,6 +30,10 @@ LL | fn test<T,U>(_: T, _: U)
|
||||
| ---- required by a bound in this
|
||||
LL | where T : Convert<U>
|
||||
| ^^^^^^^^^^ required by this bound in `test`
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | test::<i32, U>(22, std::default::Default::default());
|
||||
| ++++++++++
|
||||
help: consider specifying the type arguments in the function call
|
||||
|
|
||||
LL | test::<T, U>(22, std::default::Default::default());
|
||||
|
@ -2,25 +2,19 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7
|
||||
|
|
||||
LL | a.method();
|
||||
| --^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `U` declared on the trait `V`
|
||||
| this method call resolves to `U`
|
||||
| ^^^^^^
|
||||
|
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <A<B> as V<U>>::method(a);
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:21:7
|
||||
|
|
||||
LL | a.method();
|
||||
| --^^^^^^--
|
||||
| | |
|
||||
| | cannot infer type for type parameter `U`
|
||||
| this method call resolves to `U`
|
||||
| ^^^^^^
|
||||
|
|
||||
help: type parameter declared here
|
||||
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:12:9
|
||||
|
|
||||
LL | impl<T, U> V<U> for A<T>
|
||||
| ^
|
||||
note: multiple `impl`s satisfying `B: I<_>` found
|
||||
--> $DIR/not-suggest-non-existing-fully-qualified-path.rs:5:1
|
||||
|
|
||||
@ -33,6 +27,10 @@ note: required because of the requirements on the impl of `V<_>` for `A<B>`
|
||||
|
|
||||
LL | impl<T, U> V<U> for A<T>
|
||||
| ^^^^ ^^^^
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | <A<B> as V<U>>::method(a);
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -0,0 +1,60 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
struct Thing;
|
||||
|
||||
trait Method<T> {
|
||||
fn method(&self) -> T;
|
||||
fn mut_method(&mut self) -> T;
|
||||
}
|
||||
|
||||
impl Method<i32> for Thing {
|
||||
fn method(&self) -> i32 { 0 }
|
||||
fn mut_method(&mut self) -> i32 { 0 }
|
||||
}
|
||||
|
||||
impl Method<u32> for Thing {
|
||||
fn method(&self) -> u32 { 0 }
|
||||
fn mut_method(&mut self) -> u32 { 0 }
|
||||
}
|
||||
trait MethodRef<T> {
|
||||
fn by_self(self);
|
||||
}
|
||||
impl MethodRef<i32> for &Thing {
|
||||
fn by_self(self) {}
|
||||
}
|
||||
impl MethodRef<u32> for &Thing {
|
||||
fn by_self(self) {}
|
||||
}
|
||||
|
||||
|
||||
struct DerefsTo<T>(T);
|
||||
impl<T> Deref for DerefsTo<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl<T> DerefMut for DerefsTo<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut thing = Thing;
|
||||
thing.method();
|
||||
//~^ ERROR type annotations needed
|
||||
//~| ERROR type annotations needed
|
||||
thing.mut_method(); //~ ERROR type annotations needed
|
||||
thing.by_self(); //~ ERROR type annotations needed
|
||||
|
||||
let mut deref_to = DerefsTo(Thing);
|
||||
deref_to.method(); //~ ERROR type annotations needed
|
||||
deref_to.mut_method(); //~ ERROR type annotations needed
|
||||
deref_to.by_self(); //~ ERROR type annotations needed
|
||||
|
||||
let mut deref_deref_to = DerefsTo(DerefsTo(Thing));
|
||||
deref_deref_to.method(); //~ ERROR type annotations needed
|
||||
deref_deref_to.mut_method(); //~ ERROR type annotations needed
|
||||
deref_deref_to.by_self(); //~ ERROR type annotations needed
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user