From 4edf33e8ad4604218899e3900901ecb9816de689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Aug 2020 14:01:46 -0700 Subject: [PATCH 01/17] Add tests for turbofish suggestions --- .../appropriate-type-param-turbofish.rs | 45 ++++++++ .../appropriate-type-param-turbofish.stderr | 101 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/test/ui/suggestions/appropriate-type-param-turbofish.rs create mode 100644 src/test/ui/suggestions/appropriate-type-param-turbofish.stderr diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs new file mode 100644 index 0000000000000..5150a3196b989 --- /dev/null +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs @@ -0,0 +1,45 @@ +mod a { + fn foo() { + vec![1, 2, 3].into_iter().collect(); //~ ERROR type annotations needed + } + fn bar() { + vec!["a", "b", "c"].into_iter().collect(); //~ ERROR type annotations needed + } + fn qux() { + vec!['a', 'b', 'c'].into_iter().collect(); //~ ERROR type annotations needed + } +} +mod b { + fn foo() { + let _ = vec![1, 2, 3].into_iter().collect(); //~ ERROR type annotations needed + } + fn bar() { + let _ = vec!["a", "b", "c"].into_iter().collect(); //~ ERROR type annotations needed + } + fn qux() { + let _ = vec!['a', 'b', 'c'].into_iter().collect(); //~ ERROR type annotations needed + } +} + +trait T: Sized { + fn new() -> Self; +} +fn x() -> X { + T::new() +} +struct S; +impl T for S { + fn new() -> Self { + S + } +} + +fn foo() { + x(); //~ ERROR type annotations needed +} + +fn bar() { + let _ = x(); //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr new file mode 100644 index 0000000000000..6a83acbfbd3ee --- /dev/null +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -0,0 +1,101 @@ +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:3:35 + | +LL | vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: std::iter::FromIterator` +help: consider specifying the type argument in the method call + | +LL | vec![1, 2, 3].into_iter().collect::(); + | ^^^^^ + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:6:41 + | +LL | vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: std::iter::FromIterator<&str>` +help: consider specifying the type argument in the method call + | +LL | vec!["a", "b", "c"].into_iter().collect::(); + | ^^^^^ + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:9:41 + | +LL | vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: std::iter::FromIterator` +help: consider specifying the type argument in the method call + | +LL | vec!['a', 'b', 'c'].into_iter().collect::(); + | ^^^^^ + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:14:43 + | +LL | let _ = vec![1, 2, 3].into_iter().collect(); + | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | | + | consider giving this pattern a type + | + = note: cannot satisfy `_: std::iter::FromIterator` + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:17:49 + | +LL | let _ = vec!["a", "b", "c"].into_iter().collect(); + | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | | + | consider giving this pattern a type + | + = note: cannot satisfy `_: std::iter::FromIterator<&str>` + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:20:49 + | +LL | let _ = vec!['a', 'b', 'c'].into_iter().collect(); + | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | | + | consider giving this pattern a type + | + = note: cannot satisfy `_: std::iter::FromIterator` + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:38:5 + | +LL | fn x() -> X { + | - required by this bound in `x` +... +LL | x(); + | ^ cannot infer type for type parameter `X` declared on the function `x` + | + = note: cannot satisfy `_: T` +help: consider specifying the type argument in the function call + | +LL | x::(); + | ^^^^^ + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:42:13 + | +LL | fn x() -> X { + | - required by this bound in `x` +... +LL | let _ = x(); + | - ^ cannot infer type for type parameter `X` declared on the function `x` + | | + | consider giving this pattern a type + | + = note: cannot satisfy `_: T` +help: consider specifying the type argument in the function call + | +LL | let _ = x::(); + | ^^^^^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0283`. From 401560c52d0b4351095e38c8f1f4dd026e1c1ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Aug 2020 14:18:35 -0700 Subject: [PATCH 02/17] Probe for types that might be appropriate in a turbofish suggestion When encountering a situation where extra type annotations are needed, we sometimes suggest using turbofish. When we do so, previously we used either the `fn`'s type parameter names or `_` as placeholders. Now, we probe for all types that implement the traits the type parameter is bounded by and provide a structured suggestion for them. --- .../infer/error_reporting/need_type_info.rs | 57 ++++++--- .../src/traits/error_reporting/mod.rs | 77 +++++++++---- .../src/traits/error_reporting/suggestions.rs | 109 +++++++++++++++++- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- compiler/rustc_typeck/src/check/writeback.rs | 2 + .../appropriate-type-param-turbofish.stderr | 37 ++++-- 6 files changed, 233 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 21023a06bb2d9..1c32d5aa69541 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -342,6 +342,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span: Span, arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, + turbofish_suggestions: Vec, ) -> DiagnosticBuilder<'tcx> { let arg = self.resolve_vars_if_possible(&arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); @@ -527,7 +528,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | this method call resolves to `std::option::Option<&T>` // | // = note: type must be known at this point - self.annotate_method_call(segment, e, &mut err); + self.annotate_method_call(segment, e, &mut err, turbofish_suggestions); } } else if let Some(pattern) = local_visitor.found_arg_pattern { // We don't want to show the default label for closures. @@ -591,7 +592,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | this method call resolves to `std::option::Option<&T>` // | // = note: type must be known at this point - self.annotate_method_call(segment, e, &mut err); + self.annotate_method_call(segment, e, &mut err, turbofish_suggestions); } } // Instead of the following: @@ -641,29 +642,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { segment: &hir::PathSegment<'_>, e: &Expr<'_>, err: &mut DiagnosticBuilder<'_>, + turbofish_suggestions: Vec, ) { if let (Some(typeck_results), None) = (self.in_progress_typeck_results, &segment.args) { let borrow = typeck_results.borrow(); if let Some((DefKind::AssocFn, did)) = borrow.type_dependent_def(e.hir_id) { let generics = self.tcx.generics_of(did); if !generics.params.is_empty() { - err.span_suggestion_verbose( - segment.ident.span.shrink_to_hi(), - &format!( - "consider specifying the type argument{} in the method call", - pluralize!(generics.params.len()), - ), - format!( - "::<{}>", - generics - .params - .iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ") - ), - Applicability::HasPlaceholders, + let msg = format!( + "consider specifying the type argument{} in the method call", + pluralize!(generics.params.len()), ); + if turbofish_suggestions.is_empty() { + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi(), + &msg, + format!( + "::<{}>", + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") + ), + Applicability::HasPlaceholders, + ); + } else { + if turbofish_suggestions.len() == 1 { + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi(), + &msg, + format!("::<{}>", turbofish_suggestions[0]), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestions( + segment.ident.span.shrink_to_hi(), + &msg, + turbofish_suggestions.into_iter().map(|ty| format!("::<{}>", ty)), + Applicability::MaybeIncorrect, + ); + } + } } else { let sig = self.tcx.fn_sig(did); let bound_output = sig.output(); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f8bd3ab96e254..219ffe56ec5be 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -34,7 +34,7 @@ use crate::traits::query::normalize::AtExt as _; use on_unimplemented::InferCtxtExt as _; use suggestions::InferCtxtExt as _; -pub use rustc_infer::traits::error_reporting::*; +pub use rustc_infer::traits::{self, error_reporting::*}; pub trait InferCtxtExt<'tcx> { fn report_fulfillment_errors( @@ -1505,12 +1505,23 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // check upstream for type errors and don't add the obligations to // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282).emit(); + self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, vec![]) + .emit(); return; } - let mut err = - self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283); + // Try to find possible types that would satisfy the bounds in the type param to + // give an appropriate turbofish suggestion. + let turbofish_suggestions = + self.get_turbofish_suggestions(obligation, data, self_ty); + let mut err = self.emit_inference_failure_err( + body_id, + span, + subst, + ErrorCode::E0283, + turbofish_suggestions.clone(), + ); err.note(&format!("cannot satisfy `{}`", predicate)); + if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); } else if let ( @@ -1544,23 +1555,44 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // | // = note: cannot satisfy `_: Tt` - err.span_suggestion_verbose( - span.shrink_to_hi(), - &format!( - "consider specifying the type argument{} in the function call", - pluralize!(generics.params.len()), - ), - format!( - "::<{}>", - generics - .params - .iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ") - ), - Applicability::HasPlaceholders, + let msg = format!( + "consider specifying the type argument{} in the function call", + pluralize!(generics.params.len()), ); + if turbofish_suggestions.is_empty() { + err.span_suggestion_verbose( + span.shrink_to_hi(), + &msg, + format!( + "::<{}>", + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") + ), + Applicability::HasPlaceholders, + ); + } else { + if turbofish_suggestions.len() == 1 { + err.span_suggestion_verbose( + span.shrink_to_hi(), + &msg, + format!("::<{}>", turbofish_suggestions[0]), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestions( + span.shrink_to_hi(), + &msg, + turbofish_suggestions + .into_iter() + .map(|ty| format!("::<{}>", ty)), + Applicability::MaybeIncorrect, + ); + } + } } } err @@ -1573,7 +1605,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282) + self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, vec![]) } ty::PredicateAtom::Subtype(data) => { @@ -1584,7 +1616,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let SubtypePredicate { a_is_expected: _, a, b } = data; // both must be type variables, or the other would've been instantiated assert!(a.is_ty_var() && b.is_ty_var()); - self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282) + self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, vec![]) } ty::PredicateAtom::Projection(data) => { let trait_ref = bound_predicate.rebind(data).to_poly_trait_ref(self.tcx); @@ -1600,6 +1632,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { span, self_ty.into(), ErrorCode::E0284, + vec![], ); err.note(&format!("cannot satisfy `{}`", predicate)); err diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index efa9bd633ba8c..c0542c82f3a9d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4,9 +4,11 @@ use super::{ }; use crate::autoderef::Autoderef; -use crate::infer::InferCtxt; -use crate::traits::normalize_projection_type; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{InferCtxt, InferOk}; +use crate::traits::{self, normalize_projection_type}; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style}; use rustc_hir as hir; @@ -15,6 +17,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; +use rustc_middle::ty::subst::{GenericArgKind, Subst}; use rustc_middle::ty::{ self, suggest_constraining_type_param, AdtKind, DefIdTree, Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, @@ -23,6 +26,7 @@ use rustc_middle::ty::{TypeAndMut, TypeckResults}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; +use std::cmp::Ordering; use std::fmt; use super::InferCtxtPrivExt; @@ -38,6 +42,13 @@ pub enum GeneratorInteriorOrUpvar { // This trait is public to expose the diagnostics methods to clippy. pub trait InferCtxtExt<'tcx> { + fn get_turbofish_suggestions( + &self, + obligation: &PredicateObligation<'tcx>, + data: ty::TraitPredicate<'tcx>, + self_ty: Ty<'tcx>, + ) -> Vec; + fn suggest_restricting_param_bound( &self, err: &mut DiagnosticBuilder<'_>, @@ -317,6 +328,100 @@ fn suggest_restriction( } impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { + /// Try to find possible types that would satisfy the bounds in the type param to give an + /// appropriate turbofish suggestion. + fn get_turbofish_suggestions( + &self, + obligation: &PredicateObligation<'tcx>, + data: ty::TraitPredicate<'tcx>, + self_ty: Ty<'tcx>, + ) -> Vec { + let mut turbofish_suggestions = FxHashSet::default(); + self.tcx.for_each_relevant_impl(data.trait_ref.def_id, self_ty, |impl_def_id| { + let param_env = ty::ParamEnv::empty(); + let param_env = param_env.subst(self.tcx, data.trait_ref.substs); + let ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::NormalizeProjectionType, + span: DUMMY_SP, + }); + + let impl_substs = self.fresh_substs_for_item(obligation.cause.span, impl_def_id); + let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = trait_ref.subst(self.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = self.at(&cause, param_env).eq(trait_ref.self_ty(), ty); + if let Ok(InferOk { value: (), obligations }) = eq_result { + // FIXME: ignoring `obligations` might cause false positives. + drop(obligations); + + let can_impl = match self.evaluate_obligation(&Obligation::new( + cause, + obligation.param_env, + trait_ref.without_const().to_predicate(self.tcx), + )) { + Ok(eval_result) => eval_result.may_apply(), + Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no + }; + if can_impl + && data.trait_ref.substs.iter().zip(trait_ref.substs.iter()).all(|(l, r)| { + // FIXME: ideally we would use `can_coerce` here instead, but `typeck` + // comes *after* in the dependency graph. + match (l.unpack(), r.unpack()) { + (GenericArgKind::Type(left_ty), GenericArgKind::Type(right_ty)) => { + match (&left_ty.peel_refs().kind(), &right_ty.peel_refs().kind()) { + (Infer(_), _) | (_, Infer(_)) => true, + (left_kind, right_kind) => left_kind == right_kind, + } + } + (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) + | (GenericArgKind::Const(_), GenericArgKind::Const(_)) => true, + _ => false, + } + }) + && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) + { + turbofish_suggestions.insert(trait_ref.self_ty()); + } + } + }); + // Sort types by always suggesting `Vec<_>` and `String` first, as they are the + // most likely desired types. + let mut turbofish_suggestions = turbofish_suggestions.into_iter().collect::>(); + turbofish_suggestions.sort_by(|left, right| { + let vec_type = self.tcx.get_diagnostic_item(sym::vec_type); + let string_type = self.tcx.get_diagnostic_item(sym::string_type); + match (&left.kind(), &right.kind()) { + ( + ty::Adt(ty::AdtDef { did: left, .. }, _), + ty::Adt(ty::AdtDef { did: right, .. }, _), + ) if left == right => Ordering::Equal, + ( + ty::Adt(ty::AdtDef { did: left, .. }, _), + ty::Adt(ty::AdtDef { did: right, .. }, _), + ) if Some(*left) == vec_type && Some(*right) == string_type => Ordering::Less, + ( + ty::Adt(ty::AdtDef { did: left, .. }, _), + ty::Adt(ty::AdtDef { did: right, .. }, _), + ) if Some(*right) == vec_type && Some(*left) == string_type => Ordering::Greater, + (ty::Adt(ty::AdtDef { did, .. }, _), _) + if Some(*did) == vec_type || Some(*did) == string_type => + { + Ordering::Less + } + (_, ty::Adt(ty::AdtDef { did, .. }, _)) + if Some(*did) == vec_type || Some(*did) == string_type => + { + Ordering::Greater + } + _ => left.cmp(right), + } + }); + turbofish_suggestions.into_iter().map(|ty| ty.to_string()).collect() + } + fn suggest_restricting_param_bound( &self, mut err: &mut DiagnosticBuilder<'_>, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 017b0abd1d607..2a37795acbafe 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1396,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } else { if !self.is_tainted_by_errors() { - self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282) + self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, vec![]) .note("type must be known at this point") .emit(); } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 5363702a5be6d..562e010cba365 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -656,6 +656,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.span.to_span(self.tcx), t.into(), E0282, + vec![], ) .emit(); } @@ -669,6 +670,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.span.to_span(self.tcx), c.into(), E0282, + vec![], ) .emit(); } diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 6a83acbfbd3ee..2ac96bfbb9f85 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -7,8 +7,15 @@ LL | vec![1, 2, 3].into_iter().collect(); = note: cannot satisfy `_: std::iter::FromIterator` help: consider specifying the type argument in the method call | -LL | vec![1, 2, 3].into_iter().collect::(); - | ^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::(); + | ^^^^^^^^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + and 8 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:6:41 @@ -19,8 +26,15 @@ LL | vec!["a", "b", "c"].into_iter().collect(); = note: cannot satisfy `_: std::iter::FromIterator<&str>` help: consider specifying the type argument in the method call | -LL | vec!["a", "b", "c"].into_iter().collect::(); - | ^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::(); + | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::(); + | ^^^^^^^^^^^^^^^^^^^^^^ + and 10 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:9:41 @@ -31,8 +45,15 @@ LL | vec!['a', 'b', 'c'].into_iter().collect(); = note: cannot satisfy `_: std::iter::FromIterator` help: consider specifying the type argument in the method call | -LL | vec!['a', 'b', 'c'].into_iter().collect::(); - | ^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::(); + | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::(); + | ^^^^^^^^^^^^^^^^^^^^^^ + and 10 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:14:43 @@ -76,7 +97,7 @@ LL | x(); = note: cannot satisfy `_: T` help: consider specifying the type argument in the function call | -LL | x::(); +LL | x::(); | ^^^^^ error[E0283]: type annotations needed @@ -93,7 +114,7 @@ LL | let _ = x(); = note: cannot satisfy `_: T` help: consider specifying the type argument in the function call | -LL | let _ = x::(); +LL | let _ = x::(); | ^^^^^ error: aborting due to 8 previous errors From bb83e155bc5d8eff986fea81c855fb8b9277cd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Aug 2020 14:55:14 -0700 Subject: [PATCH 03/17] Suggest specifying local binding types --- .../infer/error_reporting/need_type_info.rs | 80 +++++++++--- .../ui/array-slice-vec/infer_array_len.stderr | 6 +- src/test/ui/error-codes/E0282.stderr | 7 +- src/test/ui/error-codes/E0661.stderr | 7 +- ...r-async-enabled-impl-trait-bindings.stderr | 7 +- .../ui/inference/cannot-infer-async.stderr | 7 +- src/test/ui/issues/issue-12187-1.stderr | 10 +- src/test/ui/issues/issue-12187-2.stderr | 10 +- src/test/ui/issues/issue-17551.stderr | 9 +- src/test/ui/issues/issue-18159.stderr | 7 +- src/test/ui/issues/issue-2151.stderr | 6 +- src/test/ui/issues/issue-25368.stderr | 8 +- src/test/ui/issues/issue-72690.stderr | 12 ++ src/test/ui/issues/issue-7813.stderr | 9 +- .../ui/match/match-unresolved-one-arm.stderr | 7 +- ...od-ambig-one-trait-unknown-int-type.stderr | 9 +- src/test/ui/pattern/pat-tuple-bad-type.stderr | 7 +- .../rest-pat-semantic-disallowed.stderr | 7 +- src/test/ui/question-mark-type-infer.stderr | 11 +- .../issue-42234-unknown-receiver-type.stderr | 6 +- .../method-and-field-eager-resolution.stderr | 12 +- .../appropriate-type-param-turbofish.stderr | 119 +++++++++++------- ...needing-specified-return-type-param.stderr | 9 +- .../cannot_infer_local_or_array.stderr | 9 +- .../cannot_infer_local_or_vec.stderr | 8 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 8 +- ...oxed-closures-failed-recursive-fn-2.stderr | 7 +- src/test/ui/vector-no-ann.stderr | 9 +- 28 files changed, 289 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 1c32d5aa69541..425ed63be00c0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -449,7 +449,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { error_code, ); - let suffix = match local_visitor.found_node_ty { + let (suffix, sugg_ty) = match local_visitor.found_node_ty { Some(ty) if ty.is_closure() => { let substs = if let ty::Closure(_, substs) = *ty.kind() { substs } else { unreachable!() }; @@ -484,20 +484,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // This suggestion is incomplete, as the user will get further type inference // errors due to the `_` placeholders and the introduction of `Box`, but it does // nudge them in the right direction. - format!("a boxed closure type like `Box {}>`", args, ret) + ( + format!("a boxed closure type like `Box {}>`", args, ret), + format!("Box {}>", args, ret), + ) } Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => { let ty = ty_to_string(ty); - format!("the explicit type `{}`, with the type parameters specified", ty) + ( + format!("the explicit type `{}`, with the type parameters specified", ty), + ty.to_string(), + ) } Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => { let ty = ty_to_string(ty); - format!( - "the explicit type `{}`, where the type parameter `{}` is specified", - ty, arg_data.name, + ( + format!( + "the explicit type `{}`, where the type parameter `{}` is specified", + ty, arg_data.name, + ), + ty.to_string(), ) } - _ => "a type".to_string(), + _ if turbofish_suggestions.len() == 1 => ( + format!("the explicit type `{}`", turbofish_suggestions[0]), + turbofish_suggestions[0].clone(), + ), + _ => ("a type".to_string(), "Type".to_string()), }; if let Some(e) = local_visitor.found_exact_method_call { @@ -552,18 +565,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("consider giving this closure parameter {}", suffix), ); } else if let Some(pattern) = local_visitor.found_local_pattern { - let msg = if let Some(simple_ident) = pattern.simple_ident() { - match pattern.span.desugaring_kind() { - None => format!("consider giving `{}` {}", simple_ident, suffix), - Some(DesugaringKind::ForLoop(_)) => { - "the element type for this iterator is not specified".to_string() - } - _ => format!("this needs {}", suffix), - } + if let (hir::Node::Local(local), None) = ( + self.tcx.hir().get(self.tcx.hir().get_parent_node(pattern.hir_id)), + pattern.span.desugaring_kind(), + ) { + let (span, prefix) = match local.ty { + Some(ty) => (ty.span, ""), + None => (local.pat.span.shrink_to_hi(), ": "), + }; + let msg = format!("consider giving this binding {}", suffix); + match &turbofish_suggestions[..] { + [] => err.span_suggestion_verbose( + span, + &msg, + format!("{}{}", prefix, sugg_ty), + Applicability::HasPlaceholders, + ), + [ty] => err.span_suggestion_verbose( + span, + &msg, + format!("{}{}", prefix, ty), + Applicability::MachineApplicable, + ), + _ => err.span_suggestions( + span, + &msg, + turbofish_suggestions.into_iter().map(|ty| format!("{}{}", prefix, ty)), + Applicability::MaybeIncorrect, + ), + }; } else { - format!("consider giving this pattern {}", suffix) - }; - err.span_label(pattern.span, msg); + let msg = if let Some(simple_ident) = pattern.simple_ident() { + match pattern.span.desugaring_kind() { + None => format!("consider giving `{}` {}", simple_ident, suffix), + Some(DesugaringKind::ForLoop(_)) => { + "the element type for this iterator is not specified".to_string() + } + _ => format!("this needs {}", suffix), + } + } else { + format!("consider giving this pattern {}", suffix) + }; + err.span_label(pattern.span, msg); + } } else if let Some(e) = local_visitor.found_method_call { if let ExprKind::MethodCall(segment, ..) = &e.kind { // Suggest specifying type params or point out the return type of the call: diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr index 6eed4ce4f0c01..3f5cabe2ba0a5 100644 --- a/src/test/ui/array-slice-vec/infer_array_len.stderr +++ b/src/test/ui/array-slice-vec/infer_array_len.stderr @@ -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 + | ^^^^^^ cannot infer type | = note: type must be known at this point +help: consider giving this binding a type + | +LL | let [_, _]: Type = a.into(); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr index 0f610a5e42f65..6fbb7494a3427 100644 --- a/src/test/ui/error-codes/E0282.stderr +++ b/src/test/ui/error-codes/E0282.stderr @@ -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 + | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let x: Type = "hello".chars().rev().collect(); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr index fe3887e72604d..2cb6b216e7607 100644 --- a/src/test/ui/error-codes/E0661.stderr +++ b/src/test/ui/error-codes/E0661.stderr @@ -8,7 +8,12 @@ error[E0282]: type annotations needed --> $DIR/E0661.rs:6:9 | LL | let a; - | ^ consider giving `a` a type + | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let a: Type; + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr index 2f630c2c9ad71..786038316f00a 100644 --- a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr +++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr @@ -10,10 +10,13 @@ LL | #![feature(impl_trait_in_bindings)] error[E0282]: type annotations needed for `impl Future` --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:13:20 | -LL | let fut = async { - | --- consider giving `fut` the explicit type `impl Future`, with the type parameters specified LL | make_unit()?; | ^ cannot infer type + | +help: consider giving this binding the explicit type `impl Future`, with the type parameters specified + | +LL | let fut: impl Future = async { + | ^^^^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/inference/cannot-infer-async.stderr b/src/test/ui/inference/cannot-infer-async.stderr index 92a9045f6db50..9c19bfae50973 100644 --- a/src/test/ui/inference/cannot-infer-async.stderr +++ b/src/test/ui/inference/cannot-infer-async.stderr @@ -1,10 +1,13 @@ error[E0282]: type annotations needed --> $DIR/cannot-infer-async.rs:11:20 | -LL | let fut = async { - | --- consider giving `fut` a type LL | make_unit()?; | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let fut: Type = async { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 3ea15439df25a..b4280834fd1a2 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -2,10 +2,12 @@ error[E0282]: type annotations needed for `&T` --> $DIR/issue-12187-1.rs:6:10 | LL | let &v = new(); - | -^ - | || - | |cannot infer type - | consider giving this pattern the explicit type `&T`, with the type parameters specified + | ^ cannot infer type + | +help: consider giving this binding the explicit type `&T`, with the type parameters specified + | +LL | let &v: &T = new(); + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index a5e65c65beb2f..ac5ea30a3c275 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -2,10 +2,12 @@ error[E0282]: type annotations needed for `&T` --> $DIR/issue-12187-2.rs:6:10 | LL | let &v = new(); - | -^ - | || - | |cannot infer type - | consider giving this pattern the explicit type `&T`, with the type parameters specified + | ^ cannot infer type + | +help: consider giving this binding the explicit type `&T`, with the type parameters specified + | +LL | let &v: &T = new(); + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 48405a292f3aa..13e90fa1422f8 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `B` --> $DIR/issue-17551.rs:6:15 | 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`, where the type parameter `T` is specified + | ^ cannot infer type for type parameter `T` declared on the struct `B` + | +help: consider giving this binding the explicit type `B`, where the type parameter `T` is specified + | +LL | let foo: B = B(marker::PhantomData); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18159.stderr b/src/test/ui/issues/issue-18159.stderr index 9b890be3c789b..e0b3593075a4e 100644 --- a/src/test/ui/issues/issue-18159.stderr +++ b/src/test/ui/issues/issue-18159.stderr @@ -2,7 +2,12 @@ error[E0282]: type annotations needed --> $DIR/issue-18159.rs:2:9 | LL | let x; - | ^ consider giving `x` a type + | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let x: Type; + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2151.stderr b/src/test/ui/issues/issue-2151.stderr index a2bcc8a8ceaf0..f6154a37a847c 100644 --- a/src/test/ui/issues/issue-2151.stderr +++ b/src/test/ui/issues/issue-2151.stderr @@ -1,12 +1,14 @@ error[E0282]: type annotations needed --> $DIR/issue-2151.rs:3:5 | -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 this binding a type + | +LL | let x: Type = panic!(); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index 6a970bc049491..e28201d75c426 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,11 +1,13 @@ error[E0282]: type annotations needed for `(Sender>, std::sync::mpsc::Receiver>)` --> $DIR/issue-25368.rs:11:17 | -LL | let (tx, rx) = channel(); - | -------- consider giving this pattern the explicit type `(Sender>, std::sync::mpsc::Receiver>)`, 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` + | +help: consider giving this binding the explicit type `(Sender>, std::sync::mpsc::Receiver>)`, where the type parameter `T` is specified + | +LL | let (tx, rx): (Sender>, std::sync::mpsc::Receiver>) = channel(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr index 3443cca5f3270..2bb0473bf1415 100644 --- a/src/test/ui/issues/issue-72690.stderr +++ b/src/test/ui/issues/issue-72690.stderr @@ -58,6 +58,10 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` +help: consider giving this binding the explicit type `String` + | +LL | let _: String = String::from("x"); + | ^^^^^^^^ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:47:5 @@ -67,6 +71,10 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` +help: consider giving this binding the explicit type `String` + | +LL | let _: String = String::from("x"); + | ^^^^^^^^ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:55:5 @@ -76,6 +84,10 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` +help: consider giving this binding the explicit type `String` + | +LL | let _: String = String::from("x"); + | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 59be0f3be11e6..96a967c7a7712 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `&[_; 0]` --> $DIR/issue-7813.rs:2:13 | LL | let v = &[]; - | - ^^^ cannot infer type - | | - | consider giving `v` the explicit type `&[_; 0]`, with the type parameters specified + | ^^^ cannot infer type + | +help: consider giving this binding the explicit type `&[_; 0]`, with the type parameters specified + | +LL | let v: &[_; 0] = &[]; + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr index 77df9921b754a..afedf05b5ef45 100644 --- a/src/test/ui/match/match-unresolved-one-arm.stderr +++ b/src/test/ui/match/match-unresolved-one-arm.stderr @@ -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 + | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let x: Type = match () { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 82660a7c41693..28212d70bb32e 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ----- ^^^^^^^^ cannot infer type for type parameter `T` - | | - | consider giving `x` the explicit type `Vec`, where the type parameter `T` is specified + | ^^^^^^^^ cannot infer type for type parameter `T` + | +help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified + | +LL | let mut x: Vec = Vec::new(); + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 diff --git a/src/test/ui/pattern/pat-tuple-bad-type.stderr b/src/test/ui/pattern/pat-tuple-bad-type.stderr index 598b6a3794ef7..e6e754f622742 100644 --- a/src/test/ui/pattern/pat-tuple-bad-type.stderr +++ b/src/test/ui/pattern/pat-tuple-bad-type.stderr @@ -1,13 +1,14 @@ error[E0282]: type annotations needed --> $DIR/pat-tuple-bad-type.rs:5:9 | -LL | let x; - | - consider giving `x` a type -... LL | (..) => {} | ^^^^ cannot infer type | = note: type must be known at this point +help: consider giving this binding a type + | +LL | let x: Type; + | ^^^^^^ error[E0308]: mismatched types --> $DIR/pat-tuple-bad-type.rs:10:9 diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index 95f6d53a9d40d..678029b3ef369 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -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 + | ^^^^^^ cannot infer type + | +help: consider giving this binding a type + | +LL | let x @ ..: Type; + | ^^^^^^ error: aborting due to 23 previous errors diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr index 381959b7ae4cd..9aab62db0248a 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/question-mark-type-infer.stderr @@ -8,8 +8,15 @@ LL | l.iter().map(f).collect()? = note: required by `into_result` help: consider specifying the type argument in the method call | -LL | l.iter().map(f).collect::()? - | ^^^^^ +LL | l.iter().map(f).collect::>()? + | ^^^^^^^^^^^^^^^^^^^^^ +LL | l.iter().map(f).collect::>()? + | ^^^^^^^^^^^^^ +LL | l.iter().map(f).collect::>()? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | l.iter().map(f).collect::>>()? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + and 1 other candidate error: aborting due to previous error diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr index c64c5b1c28f41..5501e439e0df2 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -1,12 +1,14 @@ error[E0282]: type annotations needed for `Option<_>` --> $DIR/issue-42234-unknown-receiver-type.rs:7:7 | -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` | = note: type must be known at this point +help: consider giving this binding the explicit type `Option<_>`, where the type parameter `T` is specified + | +LL | let x: Option<_> = None; + | ^^^^^^^^^ error[E0282]: type annotations needed --> $DIR/issue-42234-unknown-receiver-type.rs:13:10 diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr index 0ecbe4c136e00..cbdaca2c2e86a 100644 --- a/src/test/ui/span/method-and-field-eager-resolution.stderr +++ b/src/test/ui/span/method-and-field-eager-resolution.stderr @@ -1,22 +1,26 @@ error[E0282]: type annotations needed --> $DIR/method-and-field-eager-resolution.rs:5:5 | -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 this binding a type + | +LL | let mut x: Type = Default::default(); + | ^^^^^^ error[E0282]: type annotations needed --> $DIR/method-and-field-eager-resolution.rs:12:5 | -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 this binding a type + | +LL | let mut x: Type = Default::default(); + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 2ac96bfbb9f85..8e559c364441f 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -4,17 +4,17 @@ error[E0283]: type annotations needed LL | vec![1, 2, 3].into_iter().collect(); | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` | - = note: cannot satisfy `_: std::iter::FromIterator` + = note: cannot satisfy `_: FromIterator` help: consider specifying the type argument in the method call | -LL | vec![1, 2, 3].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::(); + | ^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^ and 8 other candidates error[E0283]: type annotations needed @@ -23,17 +23,17 @@ error[E0283]: type annotations needed LL | vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` | - = note: cannot satisfy `_: std::iter::FromIterator<&str>` + = note: cannot satisfy `_: FromIterator<&str>` help: consider specifying the type argument in the method call | -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::(); + | ^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::(); + | ^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -42,48 +42,75 @@ error[E0283]: type annotations needed LL | vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` | - = note: cannot satisfy `_: std::iter::FromIterator` + = note: cannot satisfy `_: FromIterator` help: consider specifying the type argument in the method call | -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::(); + | ^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::(); + | ^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:14:43 | LL | let _ = vec![1, 2, 3].into_iter().collect(); - | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` - | | - | consider giving this pattern a type - | - = note: cannot satisfy `_: std::iter::FromIterator` + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator` +help: consider giving this binding a type + | +LL | let _: Vec<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^ +LL | let _: HashSet<_, _> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^^^^^^ +LL | let _: PathBuf = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^ +LL | let _: Box<[_]> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^ + and 8 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:17:49 | LL | let _ = vec!["a", "b", "c"].into_iter().collect(); - | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` - | | - | consider giving this pattern a type - | - = note: cannot satisfy `_: std::iter::FromIterator<&str>` + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator<&str>` +help: consider giving this binding a type + | +LL | let _: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _: String = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _: HashSet<_, _> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^^^^^^ +LL | let _: PathBuf = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^ + and 10 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:20:49 | LL | let _ = vec!['a', 'b', 'c'].into_iter().collect(); - | - ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` - | | - | consider giving this pattern a type - | - = note: cannot satisfy `_: std::iter::FromIterator` + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator` +help: consider giving this binding a type + | +LL | let _: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _: String = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _: HashSet<_, _> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^^^^^^^ +LL | let _: PathBuf = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^ + and 10 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:38:5 @@ -107,11 +134,13 @@ LL | fn x() -> X { | - required by this bound in `x` ... LL | let _ = x(); - | - ^ cannot infer type for type parameter `X` declared on the function `x` - | | - | consider giving this pattern a type + | ^ cannot infer type for type parameter `X` declared on the function `x` | = note: cannot satisfy `_: T` +help: consider giving this binding the explicit type `S` + | +LL | let _: S = x(); + | ^^^ help: consider specifying the type argument in the function call | LL | let _ = x::(); diff --git a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr index b59a3818e7042..baaa5bcc57842 100644 --- a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr +++ b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `fn() -> A` --> $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 for type parameter `A` declared on the function `f` + | +help: consider giving this binding the explicit type `fn() -> A`, where the type parameter `A` is specified + | +LL | let _: fn() -> A = f; + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index 8edec6e0ea3fd..c44ae8363ef6b 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `[_; 0]` --> $DIR/cannot_infer_local_or_array.rs:2:13 | LL | let x = []; - | - ^^ cannot infer type - | | - | consider giving `x` the explicit type `[_; 0]`, with the type parameters specified + | ^^ cannot infer type + | +help: consider giving this binding the explicit type `[_; 0]`, with the type parameters specified + | +LL | let x: [_; 0] = []; + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 729a8c63b6240..0b8a1f2670e58 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -2,11 +2,13 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | - ^^^^^^ cannot infer type for type parameter `T` - | | - | consider giving `x` the explicit type `Vec`, where the type parameter `T` is specified + | ^^^^^^ cannot infer type for type parameter `T` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified + | +LL | let x: Vec = vec![]; + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index e24593a89b3bc..78128a266ef2d 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -2,11 +2,13 @@ error[E0282]: type annotations needed for `(Vec,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ----- ^^^^^^ cannot infer type for type parameter `T` - | | - | consider giving this pattern the explicit type `(Vec,)`, where the type parameter `T` is specified + | ^^^^^^ cannot infer type for type parameter `T` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider giving this binding the explicit type `(Vec,)`, where the type parameter `T` is specified + | +LL | let (x, ): (Vec,) = (vec![], ); + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index de20a38c44750..c42486514d79d 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,13 +1,14 @@ error[E0282]: type annotations needed for `Option` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | -LL | let mut closure0 = None; - | ------------ consider giving `closure0` the explicit type `Option`, with the type parameters specified -... LL | return c(); | ^^^ cannot infer type | = note: type must be known at this point +help: consider giving this binding the explicit type `Option`, with the type parameters specified + | +LL | let mut closure0: Option = None; + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index 8a7b8d22760a2..a45ac324f4a6b 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ---- ^^^^^^^^ cannot infer type for type parameter `T` - | | - | consider giving `_foo` the explicit type `Vec`, where the type parameter `T` is specified + | ^^^^^^^^ cannot infer type for type parameter `T` + | +help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified + | +LL | let _foo: Vec = Vec::new(); + | ^^^^^^^^ error: aborting due to previous error From 3f3459035d0fc7a80da61f6c21e9fa50f18e758b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 29 Aug 2020 16:12:11 -0700 Subject: [PATCH 04/17] Change type suggestion sorting heuristic and other cleanups --- .../infer/error_reporting/need_type_info.rs | 4 +- .../src/traits/error_reporting/mod.rs | 10 +- .../src/traits/error_reporting/suggestions.rs | 130 +++++++++++------- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- compiler/rustc_typeck/src/check/writeback.rs | 4 +- 5 files changed, 87 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 425ed63be00c0..fd30f3bc5ad93 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -342,7 +342,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span: Span, arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, - turbofish_suggestions: Vec, + turbofish_suggestions: &[String], ) -> DiagnosticBuilder<'tcx> { let arg = self.resolve_vars_if_possible(&arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); @@ -686,7 +686,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { segment: &hir::PathSegment<'_>, e: &Expr<'_>, err: &mut DiagnosticBuilder<'_>, - turbofish_suggestions: Vec, + turbofish_suggestions: &[String], ) { if let (Some(typeck_results), None) = (self.in_progress_typeck_results, &segment.args) { let borrow = typeck_results.borrow(); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 219ffe56ec5be..5dcb13df40404 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1505,7 +1505,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // check upstream for type errors and don't add the obligations to // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, vec![]) + self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, &[]) .emit(); return; } @@ -1518,7 +1518,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { span, subst, ErrorCode::E0283, - turbofish_suggestions.clone(), + &turbofish_suggestions, ); err.note(&format!("cannot satisfy `{}`", predicate)); @@ -1605,7 +1605,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { return; } - self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, vec![]) + self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, &[]) } ty::PredicateAtom::Subtype(data) => { @@ -1616,7 +1616,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let SubtypePredicate { a_is_expected: _, a, b } = data; // both must be type variables, or the other would've been instantiated assert!(a.is_ty_var() && b.is_ty_var()); - self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, vec![]) + self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, &[]) } ty::PredicateAtom::Projection(data) => { let trait_ref = bound_predicate.rebind(data).to_poly_trait_ref(self.tcx); @@ -1632,7 +1632,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { span, self_ty.into(), ErrorCode::E0284, - vec![], + &[], ); err.note(&format!("cannot satisfy `{}`", predicate)); err diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index c0542c82f3a9d..b394256c70139 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4,11 +4,10 @@ use super::{ }; use crate::autoderef::Autoderef; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk}; use crate::traits::{self, normalize_projection_type}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style}; use rustc_hir as hir; @@ -336,64 +335,80 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { data: ty::TraitPredicate<'tcx>, self_ty: Ty<'tcx>, ) -> Vec { - let mut turbofish_suggestions = FxHashSet::default(); + let mut turbofish_suggestions = FxHashMap::default(); self.tcx.for_each_relevant_impl(data.trait_ref.def_id, self_ty, |impl_def_id| { - let param_env = ty::ParamEnv::empty(); - let param_env = param_env.subst(self.tcx, data.trait_ref.substs); - let ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: DUMMY_SP, - }); - - let impl_substs = self.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); - let trait_ref = trait_ref.subst(self.tcx, impl_substs); - - // Require the type the impl is implemented on to match - // our type, and ignore the impl if there was a mismatch. - let cause = traits::ObligationCause::dummy(); - let eq_result = self.at(&cause, param_env).eq(trait_ref.self_ty(), ty); - if let Ok(InferOk { value: (), obligations }) = eq_result { - // FIXME: ignoring `obligations` might cause false positives. - drop(obligations); - - let can_impl = match self.evaluate_obligation(&Obligation::new( - cause, - obligation.param_env, - trait_ref.without_const().to_predicate(self.tcx), - )) { - Ok(eval_result) => eval_result.may_apply(), - Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no - }; - if can_impl - && data.trait_ref.substs.iter().zip(trait_ref.substs.iter()).all(|(l, r)| { - // FIXME: ideally we would use `can_coerce` here instead, but `typeck` - // comes *after* in the dependency graph. - match (l.unpack(), r.unpack()) { - (GenericArgKind::Type(left_ty), GenericArgKind::Type(right_ty)) => { - match (&left_ty.peel_refs().kind(), &right_ty.peel_refs().kind()) { - (Infer(_), _) | (_, Infer(_)) => true, - (left_kind, right_kind) => left_kind == right_kind, - } - } - (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) - | (GenericArgKind::Const(_), GenericArgKind::Const(_)) => true, - _ => false, + self.probe(|_| { + let impl_substs = self.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = trait_ref.subst(self.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = + self.at(&cause, obligation.param_env).eq(trait_ref.self_ty(), self_ty); + if let Ok(InferOk { value: (), obligations: _ }) = eq_result { + if let Ok(eval_result) = self.evaluate_obligation(&Obligation::new( + cause.clone(), + obligation.param_env, + trait_ref.without_const().to_predicate(self.tcx), + )) { + // FIXME: We will also suggest cases where `eval_result` is + // `EvaluatedToAmbig`, we just put them at the end of the sugg list. + // Ideally we would only suggest types that would always apply cleanly. + // This means that for `collect` we will suggest `PathBuf` as a valid type + // whereas that `impl` has an extra requirement `T: AsRef` which we + // don't evaluate. + if eval_result.may_apply() + && data.trait_ref.substs.iter().zip(trait_ref.substs.iter()).all( + // Here we'll have something like `[_, i32]` coming from our code + // and `[Vec<_>, _]` from the probe. For cases with + // inference variables we are left with ambiguous cases due to + // trait bounds we couldn't evaluate, but we *can* filter out cases + // like `[std::string::String, char]`, where we can `collect` a + // `String` only if we have an `IntoIterator`, which + // won't match the `i32` we have. + |(l, r)| { + // FIXME: ideally we would use `can_coerce` here instead, but `typeck` + // comes *after* in the dependency graph. + match (l.unpack(), r.unpack()) { + ( + GenericArgKind::Type(left_ty), + GenericArgKind::Type(right_ty), + ) => match ( + &left_ty.peel_refs().kind(), + &right_ty.peel_refs().kind(), + ) { + (Infer(_), _) | (_, Infer(_)) => true, + (left_kind, right_kind) => left_kind == right_kind, + }, + ( + GenericArgKind::Lifetime(_), + GenericArgKind::Lifetime(_), + ) + | (GenericArgKind::Const(_), GenericArgKind::Const(_)) => { + true + } + _ => false, + } + }, + ) + && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) + { + turbofish_suggestions.insert(trait_ref.self_ty(), eval_result); } - }) - && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) - { - turbofish_suggestions.insert(trait_ref.self_ty()); + }; } - } + }) }); // Sort types by always suggesting `Vec<_>` and `String` first, as they are the - // most likely desired types. + // most likely desired types. Otherwise sort first by `EvaluationResult` and then by their + // string representation. let mut turbofish_suggestions = turbofish_suggestions.into_iter().collect::>(); turbofish_suggestions.sort_by(|left, right| { let vec_type = self.tcx.get_diagnostic_item(sym::vec_type); let string_type = self.tcx.get_diagnostic_item(sym::string_type); - match (&left.kind(), &right.kind()) { + match (&left.0.kind(), &right.0.kind()) { ( ty::Adt(ty::AdtDef { did: left, .. }, _), ty::Adt(ty::AdtDef { did: right, .. }, _), @@ -416,10 +431,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { { Ordering::Greater } - _ => left.cmp(right), + _ => { + // We give preferential place in the suggestion list to types that will apply + // without doubt, to push types with abiguities (may or may not apply depending + // on other obligations we don't have access to here) later in the sugg list. + if left.1 == right.1 { + left.0.to_string().cmp(&right.0.to_string()) + } else { + left.1.cmp(&right.1) + } + } } }); - turbofish_suggestions.into_iter().map(|ty| ty.to_string()).collect() + turbofish_suggestions.into_iter().map(|(ty, _)| ty.to_string()).collect() } fn suggest_restricting_param_bound( diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 2a37795acbafe..c981188e49f2a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1396,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } else { if !self.is_tainted_by_errors() { - self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, vec![]) + self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, &[]) .note("type must be known at this point") .emit(); } diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 562e010cba365..055ee12e624b6 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -656,7 +656,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.span.to_span(self.tcx), t.into(), E0282, - vec![], + &[], ) .emit(); } @@ -670,7 +670,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.span.to_span(self.tcx), c.into(), E0282, - vec![], + &[], ) .emit(); } From 0d90b5949bcdcdd60d62e46ed4166f0dcd4161a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 29 Aug 2020 17:22:49 -0700 Subject: [PATCH 05/17] Tweak wording for "cannot infer type" main label --- .../infer/error_reporting/need_type_info.rs | 18 ++------ .../ui/async-await/unresolved_type_param.rs | 6 +-- .../const-generics/infer/issue-77092.stderr | 2 +- src/test/ui/question-mark-type-infer.stderr | 4 +- .../appropriate-type-param-turbofish.stderr | 46 +++++++++---------- src/test/ui/type/type-annotation-needed.rs | 2 +- 6 files changed, 35 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index fd30f3bc5ad93..2c4cf193ffff3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -783,18 +783,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> String { if type_name == "_" { format!("cannot infer {}", kind_str) - } else { - let parent_desc = if let Some(parent_name) = parent_name { - let parent_type_descr = if let Some(parent_descr) = parent_descr { - format!(" the {}", parent_descr) - } else { - "".into() - }; - - format!(" declared on{} `{}`", parent_type_descr, parent_name) - } else { - "".to_string() - }; + } else if let (Some(parent_name), Some(parent_descr)) = (parent_name, parent_descr) { + let parent_type_descr = format!(" the {}", parent_descr); + let parent_desc = format!(" declared on{} `{}`", parent_type_descr, parent_name); // FIXME: We really shouldn't be dealing with strings here // but instead use a sensible enum for cases like this. @@ -804,7 +795,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "cannot infer {} {} {} `{}`{}", kind_str, preposition, descr, type_name, parent_desc ) - .into() + } else { + format!("cannot infer type for {} `{}`", descr, type_name) } } } diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs index d313691b38857..46a7ccc569dd9 100644 --- a/src/test/ui/async-await/unresolved_type_param.rs +++ b/src/test/ui/async-await/unresolved_type_param.rs @@ -10,9 +10,9 @@ async fn foo() { //~^ ERROR type inside `async fn` body must be known in this context //~| ERROR type inside `async fn` body must be known in this context //~| ERROR type inside `async fn` body must be known in this context - //~| NOTE cannot infer type for type parameter `T` - //~| NOTE cannot infer type for type parameter `T` - //~| NOTE cannot infer type for type parameter `T` + //~| NOTE function `bar` has a type parameter `T` we couldn't infer + //~| NOTE function `bar` has a type parameter `T` we couldn't infer + //~| NOTE function `bar` has a type parameter `T` we couldn't infer //~| NOTE the type is part of the `async fn` body because of this `await` //~| NOTE the type is part of the `async fn` body because of this `await` //~| NOTE the type is part of the `async fn` body because of this `await` diff --git a/src/test/ui/const-generics/infer/issue-77092.stderr b/src/test/ui/const-generics/infer/issue-77092.stderr index e84ff8baeea53..16f371cb4c04c 100644 --- a/src/test/ui/const-generics/infer/issue-77092.stderr +++ b/src/test/ui/const-generics/infer/issue-77092.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-77092.rs:13:26 | LL | println!("{:?}", take_array_from_mut(&mut arr, i)); - | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}` + | ^^^^^^^^^^^^^^^^^^^ cannot infer type for the constant `{_: usize}` error: aborting due to previous error diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr index 9aab62db0248a..2fa8bceb3d0f0 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/question-mark-type-infer.stderr @@ -12,10 +12,10 @@ LL | l.iter().map(f).collect::>()? | ^^^^^^^^^^^^^^^^^^^^^ LL | l.iter().map(f).collect::>()? | ^^^^^^^^^^^^^ -LL | l.iter().map(f).collect::>()? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | l.iter().map(f).collect::>>()? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | l.iter().map(f).collect::>>>()? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ and 1 other candidate error: aborting due to previous error diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 8e559c364441f..6e9a60a60dc07 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -9,12 +9,12 @@ help: consider specifying the type argument in the method call | LL | vec![1, 2, 3].into_iter().collect::>(); | ^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::(); - | ^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); +LL | vec![1, 2, 3].into_iter().collect::>(); | ^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^^ and 8 other candidates error[E0283]: type annotations needed @@ -30,10 +30,10 @@ LL | vec!["a", "b", "c"].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!["a", "b", "c"].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::(); - | ^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -49,10 +49,10 @@ LL | vec!['a', 'b', 'c'].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!['a', 'b', 'c'].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); | ^^^^^^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::(); - | ^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -66,12 +66,12 @@ help: consider giving this binding a type | LL | let _: Vec<_> = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^ -LL | let _: HashSet<_, _> = vec![1, 2, 3].into_iter().collect(); - | ^^^^^^^^^^^^^^^ -LL | let _: PathBuf = vec![1, 2, 3].into_iter().collect(); - | ^^^^^^^^^ -LL | let _: Box<[_]> = vec![1, 2, 3].into_iter().collect(); +LL | let _: Arc<[_]> = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^^^ +LL | let _: BTreeSet<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^^^^ +LL | let _: BinaryHeap<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^^^^^^ and 8 other candidates error[E0283]: type annotations needed @@ -87,10 +87,10 @@ LL | let _: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ -LL | let _: HashSet<_, _> = vec!["a", "b", "c"].into_iter().collect(); +LL | let _: BinaryHeap<_> = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^^^^^^^^ -LL | let _: PathBuf = vec!["a", "b", "c"].into_iter().collect(); - | ^^^^^^^^^ +LL | let _: Cow<'_, [_]> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -106,10 +106,10 @@ LL | let _: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ -LL | let _: HashSet<_, _> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _: BinaryHeap<_> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^^^^^^^^ -LL | let _: PathBuf = vec!['a', 'b', 'c'].into_iter().collect(); - | ^^^^^^^^^ +LL | let _: Box<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs index 553318ecac6e2..1360abee978b3 100644 --- a/src/test/ui/type/type-annotation-needed.rs +++ b/src/test/ui/type/type-annotation-needed.rs @@ -4,6 +4,6 @@ fn foo>(x: i32) {} fn main() { foo(42); //~^ ERROR type annotations needed - //~| NOTE cannot infer type + //~| NOTE function `foo` has a type parameter `T` we couldn't infer //~| NOTE cannot satisfy } From 669a126e0ddaee18d61d3cbf60a96e0c20a6357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 29 Aug 2020 18:09:39 -0700 Subject: [PATCH 06/17] Use string sorting exclusively --- .../src/traits/error_reporting/suggestions.rs | 28 +++++------------ .../ui/async-await/unresolved_type_param.rs | 6 ++-- src/test/ui/question-mark-type-infer.stderr | 4 +-- .../appropriate-type-param-turbofish.stderr | 30 +++++++++---------- src/test/ui/type/type-annotation-needed.rs | 2 +- 5 files changed, 28 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index b394256c70139..d96f30124b54e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -7,7 +7,7 @@ use crate::autoderef::Autoderef; use crate::infer::{InferCtxt, InferOk}; use crate::traits::{self, normalize_projection_type}; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style}; use rustc_hir as hir; @@ -335,7 +335,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { data: ty::TraitPredicate<'tcx>, self_ty: Ty<'tcx>, ) -> Vec { - let mut turbofish_suggestions = FxHashMap::default(); + let mut turbofish_suggestions = FxHashSet::default(); self.tcx.for_each_relevant_impl(data.trait_ref.def_id, self_ty, |impl_def_id| { self.probe(|_| { let impl_substs = self.fresh_substs_for_item(DUMMY_SP, impl_def_id); @@ -395,24 +395,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) { - turbofish_suggestions.insert(trait_ref.self_ty(), eval_result); + turbofish_suggestions.insert(trait_ref.self_ty()); } }; } }) }); // Sort types by always suggesting `Vec<_>` and `String` first, as they are the - // most likely desired types. Otherwise sort first by `EvaluationResult` and then by their - // string representation. + // most likely desired types. let mut turbofish_suggestions = turbofish_suggestions.into_iter().collect::>(); turbofish_suggestions.sort_by(|left, right| { let vec_type = self.tcx.get_diagnostic_item(sym::vec_type); let string_type = self.tcx.get_diagnostic_item(sym::string_type); - match (&left.0.kind(), &right.0.kind()) { - ( - ty::Adt(ty::AdtDef { did: left, .. }, _), - ty::Adt(ty::AdtDef { did: right, .. }, _), - ) if left == right => Ordering::Equal, + match (&left.kind(), &right.kind()) { ( ty::Adt(ty::AdtDef { did: left, .. }, _), ty::Adt(ty::AdtDef { did: right, .. }, _), @@ -431,19 +426,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { { Ordering::Greater } - _ => { - // We give preferential place in the suggestion list to types that will apply - // without doubt, to push types with abiguities (may or may not apply depending - // on other obligations we don't have access to here) later in the sugg list. - if left.1 == right.1 { - left.0.to_string().cmp(&right.0.to_string()) - } else { - left.1.cmp(&right.1) - } - } + _ => left.to_string().cmp(&right.to_string()), } }); - turbofish_suggestions.into_iter().map(|(ty, _)| ty.to_string()).collect() + turbofish_suggestions.into_iter().map(|ty| ty.to_string()).collect() } fn suggest_restricting_param_bound( diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs index 46a7ccc569dd9..650502ab644d9 100644 --- a/src/test/ui/async-await/unresolved_type_param.rs +++ b/src/test/ui/async-await/unresolved_type_param.rs @@ -10,9 +10,9 @@ async fn foo() { //~^ ERROR type inside `async fn` body must be known in this context //~| ERROR type inside `async fn` body must be known in this context //~| ERROR type inside `async fn` body must be known in this context - //~| NOTE function `bar` has a type parameter `T` we couldn't infer - //~| NOTE function `bar` has a type parameter `T` we couldn't infer - //~| NOTE function `bar` has a type parameter `T` we couldn't infer + //~| NOTE cannot infer type for type parameter `T` declared on the function `bar + //~| NOTE cannot infer type for type parameter `T` declared on the function `bar + //~| NOTE cannot infer type for type parameter `T` declared on the function `bar //~| NOTE the type is part of the `async fn` body because of this `await` //~| NOTE the type is part of the `async fn` body because of this `await` //~| NOTE the type is part of the `async fn` body because of this `await` diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr index 2fa8bceb3d0f0..49ecb624d4eee 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/question-mark-type-infer.stderr @@ -12,10 +12,10 @@ LL | l.iter().map(f).collect::>()? | ^^^^^^^^^^^^^^^^^^^^^ LL | l.iter().map(f).collect::>()? | ^^^^^^^^^^^^^ -LL | l.iter().map(f).collect::>>()? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | l.iter().map(f).collect::>>>()? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | l.iter().map(f).collect::>>()? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ and 1 other candidate error: aborting due to previous error diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 6e9a60a60dc07..890408f36ddd9 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -30,10 +30,10 @@ LL | vec!["a", "b", "c"].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!["a", "b", "c"].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -49,10 +49,10 @@ LL | vec!['a', 'b', 'c'].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!['a', 'b', 'c'].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -87,10 +87,10 @@ LL | let _: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ -LL | let _: BinaryHeap<_> = vec!["a", "b", "c"].into_iter().collect(); - | ^^^^^^^^^^^^^^^ -LL | let _: Cow<'_, [_]> = vec!["a", "b", "c"].into_iter().collect(); - | ^^^^^^^^^^^^^^ +LL | let _: Arc<[_]> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^ +LL | let _: BTreeSet<_> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed @@ -106,10 +106,10 @@ LL | let _: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ -LL | let _: BinaryHeap<_> = vec!['a', 'b', 'c'].into_iter().collect(); - | ^^^^^^^^^^^^^^^ -LL | let _: Box<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _: Arc<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^^^ +LL | let _: BTreeSet<_> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^^^^^ and 10 other candidates error[E0283]: type annotations needed diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs index 1360abee978b3..17d9838049b44 100644 --- a/src/test/ui/type/type-annotation-needed.rs +++ b/src/test/ui/type/type-annotation-needed.rs @@ -4,6 +4,6 @@ fn foo>(x: i32) {} fn main() { foo(42); //~^ ERROR type annotations needed - //~| NOTE function `foo` has a type parameter `T` we couldn't infer + //~| NOTE cannot infer type for type parameter `T` declared on the function `foo` //~| NOTE cannot satisfy } From 40d36b1a6030eaa98a314d6d0051f578a5000500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 10 Oct 2020 22:36:52 -0700 Subject: [PATCH 07/17] Defer `?Sized` local binding error to get better suggestions --- compiler/rustc_typeck/src/check/expr.rs | 2 +- .../rustc_typeck/src/check/gather_locals.rs | 6 +- src/test/ui/error-codes/E0282.rs | 2 +- src/test/ui/error-codes/E0282.stderr | 11 +-- ...for-loop-unconstrained-element-type.stderr | 5 +- src/test/ui/issues/issue-12187-1.stderr | 6 +- src/test/ui/issues/issue-12187-2.stderr | 6 +- src/test/ui/issues/issue-24036.rs | 3 +- src/test/ui/issues/issue-24036.stderr | 11 ++- src/test/ui/issues/issue-5883.stderr | 26 ++--- src/test/ui/issues/issue-72690.stderr | 12 ++- src/test/ui/match/match-unresolved-one-arm.rs | 4 +- .../ui/match/match-unresolved-one-arm.stderr | 6 +- src/test/ui/str/str-array-assignment.stderr | 20 ++-- src/test/ui/str/str-mut-idx.rs | 18 ++-- src/test/ui/str/str-mut-idx.stderr | 17 +--- .../appropriate-type-param-turbofish.rs | 12 +++ .../appropriate-type-param-turbofish.stderr | 63 +++++++++++- src/test/ui/unsized6.rs | 12 --- src/test/ui/unsized6.stderr | 96 +++---------------- src/test/ui/unsized8.rs | 24 +++++ src/test/ui/unsized8.stderr | 45 +++++++++ 22 files changed, 229 insertions(+), 178 deletions(-) create mode 100644 src/test/ui/unsized8.rs create mode 100644 src/test/ui/unsized8.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 9990f86a36b13..2027b741abbdb 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -813,7 +813,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs)); - self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized); + self.require_type_is_sized_deferred(lhs_ty, lhs.span, traits::AssignmentLhsSized); if lhs_ty.references_error() || rhs_ty.references_error() { self.tcx.ty_error() diff --git a/compiler/rustc_typeck/src/check/gather_locals.rs b/compiler/rustc_typeck/src/check/gather_locals.rs index 1d505cfa69804..2bffdacfb2b1e 100644 --- a/compiler/rustc_typeck/src/check/gather_locals.rs +++ b/compiler/rustc_typeck/src/check/gather_locals.rs @@ -94,7 +94,11 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { let var_ty = self.assign(p.span, p.hir_id, None); if !self.fcx.tcx.features().unsized_locals { - self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id)); + self.fcx.require_type_is_sized_deferred( + var_ty, + p.span, + traits::VariableType(p.hir_id), + ); } debug!( diff --git a/src/test/ui/error-codes/E0282.rs b/src/test/ui/error-codes/E0282.rs index 9bd16abb7bb83..f3147572dbcc9 100644 --- a/src/test/ui/error-codes/E0282.rs +++ b/src/test/ui/error-codes/E0282.rs @@ -1,3 +1,3 @@ fn main() { - let x = "hello".chars().rev().collect(); //~ ERROR E0282 + None; //~ ERROR E0282 } diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr index 6fbb7494a3427..5ff0658339554 100644 --- a/src/test/ui/error-codes/E0282.stderr +++ b/src/test/ui/error-codes/E0282.stderr @@ -1,13 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/E0282.rs:2:9 + --> $DIR/E0282.rs:2:5 | -LL | let x = "hello".chars().rev().collect(); - | ^ cannot infer type - | -help: consider giving this binding a type - | -LL | let x: Type = "hello".chars().rev().collect(); - | ^^^^^^ +LL | None; + | ^^^^ cannot infer type for type parameter `T` declared on the enum `Option` error: aborting due to previous error diff --git a/src/test/ui/for/for-loop-unconstrained-element-type.stderr b/src/test/ui/for/for-loop-unconstrained-element-type.stderr index 0672014a92929..cba9fbd5cf4de 100644 --- a/src/test/ui/for/for-loop-unconstrained-element-type.stderr +++ b/src/test/ui/for/for-loop-unconstrained-element-type.stderr @@ -2,7 +2,10 @@ error[E0282]: type annotations needed --> $DIR/for-loop-unconstrained-element-type.rs:8:14 | LL | for i in Vec::new() { } - | ^^^^^^^^^^ the element type for this iterator is not specified + | ^^^^^^^^-- + | | + | the element type for this iterator is not specified + | cannot infer type for type parameter `T` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index b4280834fd1a2..b85ec65358401 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -1,10 +1,10 @@ error[E0282]: type annotations needed for `&T` - --> $DIR/issue-12187-1.rs:6:10 + --> $DIR/issue-12187-1.rs:6:14 | LL | let &v = new(); - | ^ cannot infer type + | ^^^ cannot infer type for type parameter `T` declared on the function `new` | -help: consider giving this binding the explicit type `&T`, with the type parameters specified +help: consider giving this binding the explicit type `&T`, where the type parameter `T` is specified | LL | let &v: &T = new(); | ^^^^ diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index ac5ea30a3c275..9cce75bf14189 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -1,10 +1,10 @@ error[E0282]: type annotations needed for `&T` - --> $DIR/issue-12187-2.rs:6:10 + --> $DIR/issue-12187-2.rs:6:14 | LL | let &v = new(); - | ^ cannot infer type + | ^^^ cannot infer type for type parameter `T` declared on the function `new` | -help: consider giving this binding the explicit type `&T`, with the type parameters specified +help: consider giving this binding the explicit type `&T`, where the type parameter `T` is specified | LL | let &v: &T = new(); | ^^^^ diff --git a/src/test/ui/issues/issue-24036.rs b/src/test/ui/issues/issue-24036.rs index 7df036c8e3a45..48352ac87fe8c 100644 --- a/src/test/ui/issues/issue-24036.rs +++ b/src/test/ui/issues/issue-24036.rs @@ -6,11 +6,10 @@ fn closure_to_loc() { fn closure_from_match() { let x = match 1usize { - 1 => |c| c + 1, + 1 => |c| c + 1, //~ ERROR type annotations needed 2 => |c| c - 1, _ => |c| c - 1 }; - //~^^^^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index e6b8367f74fb5..9bbbb4b3d6bee 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -11,11 +11,16 @@ LL | x = |c| c + 1; = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object -error[E0282]: type annotations needed - --> $DIR/issue-24036.rs:9:15 +error[E0282]: type annotations needed for `fn(_) -> _` + --> $DIR/issue-24036.rs:9:18 | LL | 1 => |c| c + 1, - | ^ consider giving this closure parameter a type + | ^ cannot infer type + | +help: consider giving this binding the explicit type `fn(_) -> _`, with the type parameters specified + | +LL | let x: fn(_) -> _ = match 1usize { + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-5883.stderr b/src/test/ui/issues/issue-5883.stderr index 8d639304ab6e7..c3681f63c574c 100644 --- a/src/test/ui/issues/issue-5883.stderr +++ b/src/test/ui/issues/issue-5883.stderr @@ -1,16 +1,3 @@ -error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/issue-5883.rs:7:15 - | -LL | fn new_struct(r: dyn A + 'static) - | ^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn A + 'static)` - = help: unsized locals are gated as an unstable feature -help: function arguments must have a statically known size, borrowed types always have a known size - | -LL | fn new_struct(r: &dyn A + 'static) - | ^ - error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time --> $DIR/issue-5883.rs:8:8 | @@ -24,6 +11,19 @@ LL | Struct { r: r } = note: required because it appears within the type `Struct` = note: the return type of a function must have a statically known size +error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time + --> $DIR/issue-5883.rs:7:15 + | +LL | fn new_struct(r: dyn A + 'static) + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn A + 'static)` + = help: unsized locals are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | fn new_struct(r: &dyn A + 'static) + | ^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr index 2bb0473bf1415..a8eb3f55e3a7b 100644 --- a/src/test/ui/issues/issue-72690.stderr +++ b/src/test/ui/issues/issue-72690.stderr @@ -7,11 +7,14 @@ LL | String::from("x".as_ref()); = note: cannot satisfy `String: From<&_>` = note: required by `from` -error[E0282]: type annotations needed - --> $DIR/issue-72690.rs:11:6 +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:11:9 | LL | |x| String::from("x".as_ref()); - | ^ consider giving this closure parameter a type + | ^^^^^^^^^^^^ cannot infer type for struct `String` + | + = note: cannot satisfy `String: From<&_>` + = note: required by `from` error[E0283]: type annotations needed for `&T` --> $DIR/issue-72690.rs:15:17 @@ -91,5 +94,4 @@ LL | let _: String = String::from("x"); error: aborting due to 9 previous errors -Some errors have detailed explanations: E0282, E0283. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/match/match-unresolved-one-arm.rs b/src/test/ui/match/match-unresolved-one-arm.rs index fa65d87b3abbd..09640a028f0c6 100644 --- a/src/test/ui/match/match-unresolved-one-arm.rs +++ b/src/test/ui/match/match-unresolved-one-arm.rs @@ -1,7 +1,7 @@ fn foo() -> T { panic!("Rocks for my pillow") } fn main() { - let x = match () { //~ ERROR type annotations needed - () => foo() // T here should be unresolved + let x = match () { + () => foo() //~ ERROR type annotations needed }; } diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr index afedf05b5ef45..430fa33bc33cd 100644 --- a/src/test/ui/match/match-unresolved-one-arm.stderr +++ b/src/test/ui/match/match-unresolved-one-arm.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/match-unresolved-one-arm.rs:4:9 + --> $DIR/match-unresolved-one-arm.rs:5:15 | -LL | let x = match () { - | ^ cannot infer type +LL | () => foo() + | ^^^ cannot infer type for type parameter `T` declared on the function `foo` | help: consider giving this binding a type | diff --git a/src/test/ui/str/str-array-assignment.stderr b/src/test/ui/str/str-array-assignment.stderr index 73c03f09f2ebc..8d74b4d53ee12 100644 --- a/src/test/ui/str/str-array-assignment.stderr +++ b/src/test/ui/str/str-array-assignment.stderr @@ -15,6 +15,16 @@ LL | let u: &str = if true { s[..2] } else { s }; | expected `&str`, found `str` | help: consider borrowing here: `&s[..2]` +error[E0308]: mismatched types + --> $DIR/str-array-assignment.rs:9:17 + | +LL | let w: &str = s[..2]; + | ---- ^^^^^^ + | | | + | | expected `&str`, found `str` + | | help: consider borrowing here: `&s[..2]` + | expected due to this + error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/str-array-assignment.rs:7:7 | @@ -29,16 +39,6 @@ help: consider borrowing here LL | let v = &s[..2]; | ^ -error[E0308]: mismatched types - --> $DIR/str-array-assignment.rs:9:17 - | -LL | let w: &str = s[..2]; - | ---- ^^^^^^ - | | | - | | expected `&str`, found `str` - | | help: consider borrowing here: `&s[..2]` - | expected due to this - error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308. diff --git a/src/test/ui/str/str-mut-idx.rs b/src/test/ui/str/str-mut-idx.rs index 575a9eae85946..c089faa8ef37a 100644 --- a/src/test/ui/str/str-mut-idx.rs +++ b/src/test/ui/str/str-mut-idx.rs @@ -1,17 +1,13 @@ fn bot() -> T { loop {} } fn mutate(s: &mut str) { - s[1..2] = bot(); - //~^ ERROR the size for values of type - //~| ERROR the size for values of type - s[1usize] = bot(); - //~^ ERROR the type `str` cannot be indexed by `usize` - s.get_mut(1); - //~^ ERROR the type `str` cannot be indexed by `{integer}` - s.get_unchecked_mut(1); - //~^ ERROR the type `str` cannot be indexed by `{integer}` - s['c']; - //~^ ERROR the type `str` cannot be indexed by `char` + s[1..2] = bot(); //~ ERROR the size for values of type + // A second error would happen due to `s[1..2]` but it isn't emitted because it is delayed and + // there are already other errors being emitted. + s[1usize] = bot(); //~ ERROR the type `str` cannot be indexed by `usize` + s.get_mut(1); //~ ERROR the type `str` cannot be indexed by `{integer}` + s.get_unchecked_mut(1); //~ ERROR the type `str` cannot be indexed by `{integer}` + s['c']; //~ ERROR the type `str` cannot be indexed by `char` } pub fn main() {} diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 405542820a394..dfe4b86fb3bdb 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -13,15 +13,6 @@ help: consider relaxing the implicit `Sized` restriction LL | fn bot() -> T { loop {} } | ^^^^^^^^ -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/str-mut-idx.rs:4:5 - | -LL | s[1..2] = bot(); - | ^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `str` - = note: the left-hand-side of an assignment must have a statically known size - error[E0277]: the type `str` cannot be indexed by `usize` --> $DIR/str-mut-idx.rs:7:5 | @@ -32,7 +23,7 @@ LL | s[1usize] = bot(); = note: required because of the requirements on the impl of `Index` for `str` error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:9:15 + --> $DIR/str-mut-idx.rs:8:15 | LL | s.get_mut(1); | ^ string indices are ranges of `usize` @@ -42,7 +33,7 @@ LL | s.get_mut(1); for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:11:25 + --> $DIR/str-mut-idx.rs:9:25 | LL | s.get_unchecked_mut(1); | ^ string indices are ranges of `usize` @@ -52,7 +43,7 @@ LL | s.get_unchecked_mut(1); for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `char` - --> $DIR/str-mut-idx.rs:13:5 + --> $DIR/str-mut-idx.rs:10:5 | LL | s['c']; | ^^^^^^ string indices are ranges of `usize` @@ -60,6 +51,6 @@ LL | s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required because of the requirements on the impl of `Index` for `str` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs index 5150a3196b989..52f3df34b8812 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs @@ -21,6 +21,18 @@ mod b { } } +mod c { + fn foo() { + let _x = vec![1, 2, 3].into_iter().collect(); //~ ERROR type annotations needed + } + fn bar() { + let _x = vec!["a", "b", "c"].into_iter().collect(); //~ ERROR type annotations needed + } + fn qux() { + let _x = vec!['a', 'b', 'c'].into_iter().collect(); //~ ERROR type annotations needed + } +} + trait T: Sized { fn new() -> Self; } diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 890408f36ddd9..d22d4a466d5e3 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -113,7 +113,64 @@ LL | let _: BTreeSet<_> = vec!['a', 'b', 'c'].into_iter().collect(); and 10 other candidates error[E0283]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:38:5 + --> $DIR/appropriate-type-param-turbofish.rs:26:44 + | +LL | let _x = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator` +help: consider giving this binding a type + | +LL | let _x: Vec<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: Arc<[_]> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^ +LL | let _x: BTreeSet<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^^^^ +LL | let _x: BinaryHeap<_> = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^^^^^^^^ + and 8 other candidates + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:29:50 + | +LL | let _x = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator<&str>` +help: consider giving this binding a type + | +LL | let _x: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: String = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: Arc<[_]> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^ +LL | let _x: BTreeSet<_> = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^^^^^^ + and 10 other candidates + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:32:50 + | +LL | let _x = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator` +help: consider giving this binding a type + | +LL | let _x: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: String = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: Arc<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^^ +LL | let _x: BTreeSet<_> = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^^^^^^ + and 10 other candidates + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:50:5 | LL | fn x() -> X { | - required by this bound in `x` @@ -128,7 +185,7 @@ LL | x::(); | ^^^^^ error[E0283]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:42:13 + --> $DIR/appropriate-type-param-turbofish.rs:54:13 | LL | fn x() -> X { | - required by this bound in `x` @@ -146,6 +203,6 @@ help: consider specifying the type argument in the function call LL | let _ = x::(); | ^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/unsized6.rs b/src/test/ui/unsized6.rs index 79133554d5472..d6898fa3dde6b 100644 --- a/src/test/ui/unsized6.rs +++ b/src/test/ui/unsized6.rs @@ -8,31 +8,19 @@ fn f1(x: &X) { //~^ ERROR the size for values of type let y: Y; //~^ ERROR the size for values of type - let y: (isize, (Z, usize)); - //~^ ERROR the size for values of type } fn f2(x: &X) { let y: X; //~^ ERROR the size for values of type - let y: (isize, (Y, isize)); - //~^ ERROR the size for values of type } fn f3(x1: Box, x2: Box, x3: Box) { let y: X = *x1; //~^ ERROR the size for values of type - let y = *x2; - //~^ ERROR the size for values of type - let (y, z) = (*x3, 4); - //~^ ERROR the size for values of type } fn f4(x1: Box, x2: Box, x3: Box) { let y: X = *x1; //~^ ERROR the size for values of type - let y = *x2; - //~^ ERROR the size for values of type - let (y, z) = (*x3, 4); - //~^ ERROR the size for values of type } fn g1(x: X) {} diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr index e85b73355e90f..2b01871f39671 100644 --- a/src/test/ui/unsized6.stderr +++ b/src/test/ui/unsized6.stderr @@ -1,15 +1,3 @@ -error[E0277]: the size for values of type `Y` cannot be known at compilation time - --> $DIR/unsized6.rs:9:9 - | -LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` -... -LL | let y: Y; - | ^ doesn't have a size known at compile-time - | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:7:12 | @@ -21,79 +9,34 @@ LL | let _: (isize, (X, isize)); | = note: only the last element of a tuple may have a dynamically sized type -error[E0277]: the size for values of type `Z` cannot be known at compilation time - --> $DIR/unsized6.rs:11:12 - | -LL | fn f1(x: &X) { - | - this type parameter needs to be `Sized` -... -LL | let y: (isize, (Z, usize)); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = note: only the last element of a tuple may have a dynamically sized type - -error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:15:9 - | -LL | fn f2(x: &X) { - | - this type parameter needs to be `Sized` -LL | let y: X; - | ^ doesn't have a size known at compile-time - | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - error[E0277]: the size for values of type `Y` cannot be known at compilation time - --> $DIR/unsized6.rs:17:12 + --> $DIR/unsized6.rs:9:9 | -LL | fn f2(x: &X) { - | - this type parameter needs to be `Sized` +LL | fn f1(x: &X) { + | - this type parameter needs to be `Sized` ... -LL | let y: (isize, (Y, isize)); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = note: only the last element of a tuple may have a dynamically sized type - -error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:22:9 - | -LL | fn f3(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` -LL | let y: X = *x1; +LL | let y: Y; | ^ doesn't have a size known at compile-time | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:24:9 + --> $DIR/unsized6.rs:13:9 | -LL | fn f3(x1: Box, x2: Box, x3: Box) { +LL | fn f2(x: &X) { | - this type parameter needs to be `Sized` -... -LL | let y = *x2; +LL | let y: X; | ^ doesn't have a size known at compile-time | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:26:10 + --> $DIR/unsized6.rs:18:9 | LL | fn f3(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` -... -LL | let (y, z) = (*x3, 4); - | ^ doesn't have a size known at compile-time - | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - -error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:30:9 - | -LL | fn f4(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | @@ -101,31 +44,18 @@ LL | let y: X = *x1; = help: unsized locals are gated as an unstable feature error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:32:9 + --> $DIR/unsized6.rs:22:9 | LL | fn f4(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` -... -LL | let y = *x2; +LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:34:10 - | -LL | fn f4(x1: Box, x2: Box, x3: Box) { - | - this type parameter needs to be `Sized` -... -LL | let (y, z) = (*x3, 4); - | ^ doesn't have a size known at compile-time - | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - -error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:38:18 + --> $DIR/unsized6.rs:26:18 | LL | fn g1(x: X) {} | - ^ doesn't have a size known at compile-time @@ -139,7 +69,7 @@ LL | fn g1(x: &X) {} | ^ error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:40:22 + --> $DIR/unsized6.rs:28:22 | LL | fn g2(x: X) {} | - ^ doesn't have a size known at compile-time @@ -152,6 +82,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn g2(x: &X) {} | ^ -error: aborting due to 13 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized8.rs b/src/test/ui/unsized8.rs new file mode 100644 index 0000000000000..80fc07b92bd4d --- /dev/null +++ b/src/test/ui/unsized8.rs @@ -0,0 +1,24 @@ +// Test `?Sized` local variables. + +trait T {} + +fn f1(x: &X) { + let y: (isize, (Z, usize)); + //~^ ERROR the size for values of type +} +fn f2(x: &X) { + let y: (isize, (Y, isize)); + //~^ ERROR the size for values of type +} + +fn f3(x1: Box, x2: Box, x3: Box) { + let (y, z) = (*x3, 4); + //~^ ERROR the size for values of type +} +fn f4(x1: Box, x2: Box, x3: Box) { + let (y, z) = (*x3, 4); + //~^ ERROR the size for values of type +} + +pub fn main() { +} diff --git a/src/test/ui/unsized8.stderr b/src/test/ui/unsized8.stderr new file mode 100644 index 0000000000000..a1e57db2ae27d --- /dev/null +++ b/src/test/ui/unsized8.stderr @@ -0,0 +1,45 @@ +error[E0277]: the size for values of type `Z` cannot be known at compilation time + --> $DIR/unsized8.rs:6:12 + | +LL | fn f1(x: &X) { + | - this type parameter needs to be `Sized` +LL | let y: (isize, (Z, usize)); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `Y` cannot be known at compilation time + --> $DIR/unsized8.rs:10:12 + | +LL | fn f2(x: &X) { + | - this type parameter needs to be `Sized` +LL | let y: (isize, (Y, isize)); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized8.rs:15:10 + | +LL | fn f3(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `Sized` +LL | let (y, z) = (*x3, 4); + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error[E0277]: the size for values of type `X` cannot be known at compilation time + --> $DIR/unsized8.rs:19:10 + | +LL | fn f4(x1: Box, x2: Box, x3: Box) { + | - this type parameter needs to be `Sized` +LL | let (y, z) = (*x3, 4); + | ^ doesn't have a size known at compile-time + | + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. From af13f34ffe9fdaba6ab51ded87ad2945ce8694f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 16:49:53 -0700 Subject: [PATCH 08/17] Modify turbofish suggestion probing logic --- .../src/traits/error_reporting/mod.rs | 12 +- .../src/traits/error_reporting/suggestions.rs | 99 +++++------- .../src/traits/select/mod.rs | 36 +++-- .../src/traits/specialize/mod.rs | 2 +- compiler/rustc_typeck/src/check/check.rs | 6 +- src/test/ui/closures/issue-41366.stderr | 22 +-- src/test/ui/question-mark-type-infer.stderr | 11 +- .../appropriate-type-param-turbofish.rs | 41 ++++- .../appropriate-type-param-turbofish.stderr | 150 ++++++++++++------ .../typeck_type_placeholder_item.stderr | 4 +- 10 files changed, 230 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 5dcb13df40404..d0aae2df58c8c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1462,8 +1462,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let bound_predicate = predicate.bound_atom(); let mut err = match bound_predicate.skip_binder() { ty::PredicateAtom::Trait(data, _) => { - let trait_ref = bound_predicate.rebind(data.trait_ref); - debug!("trait_ref {:?}", trait_ref); + let self_ty = data.trait_ref.self_ty(); if predicate.references_error() { return; @@ -1504,7 +1503,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. - if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { + if self.tcx.lang_items().sized_trait() == Some(data.trait_ref.def_id) { self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, &[]) .emit(); return; @@ -1523,7 +1522,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { err.note(&format!("cannot satisfy `{}`", predicate)); if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { - self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); + self.suggest_fully_qualified_path( + &mut err, + def_id, + span, + data.trait_ref.def_id, + ); } else if let ( Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d96f30124b54e..d3d120e715403 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::autoderef::Autoderef; -use crate::infer::{InferCtxt, InferOk}; +use crate::infer::InferCtxt; use crate::traits::{self, normalize_projection_type}; use rustc_data_structures::fx::FxHashSet; @@ -16,12 +16,11 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; -use rustc_middle::ty::subst::{GenericArgKind, Subst}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, suggest_constraining_type_param, AdtKind, DefIdTree, Infer, InferTy, ToPredicate, Ty, - TyCtxt, TypeFoldable, WithConstness, + TyCtxt, TypeAndMut, TypeFoldable, TypeckResults, WithConstness, }; -use rustc_middle::ty::{TypeAndMut, TypeckResults}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; @@ -338,67 +337,45 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut turbofish_suggestions = FxHashSet::default(); self.tcx.for_each_relevant_impl(data.trait_ref.def_id, self_ty, |impl_def_id| { self.probe(|_| { - let impl_substs = self.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_args = InternalSubsts::identity_for_item(self.tcx, data.trait_ref.def_id); + let impl_args = traits::specialize::fulfill_implication( + self, + obligation.param_env, + data.trait_ref, + impl_def_id, + ); + let substs = match impl_args { + Ok(impl_args) => trait_args.rebase_onto(self.tcx, impl_def_id, impl_args), + _ => return, + }; let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); - let trait_ref = trait_ref.subst(self.tcx, impl_substs); - // Require the type the impl is implemented on to match - // our type, and ignore the impl if there was a mismatch. let cause = traits::ObligationCause::dummy(); - let eq_result = - self.at(&cause, obligation.param_env).eq(trait_ref.self_ty(), self_ty); - if let Ok(InferOk { value: (), obligations: _ }) = eq_result { - if let Ok(eval_result) = self.evaluate_obligation(&Obligation::new( + let mut selcx = SelectionContext::new(&self); + let param_env = obligation.param_env.clone(); + let (target_trait_ref, obligations) = traits::util::impl_trait_ref_and_oblig( + &mut selcx, + param_env, + impl_def_id, + substs, + ); + self.resolve_vars_if_possible(&target_trait_ref); + if let Ok(eval_result) = selcx.evaluate_predicates( + Some(Obligation::new( cause.clone(), - obligation.param_env, - trait_ref.without_const().to_predicate(self.tcx), - )) { - // FIXME: We will also suggest cases where `eval_result` is - // `EvaluatedToAmbig`, we just put them at the end of the sugg list. - // Ideally we would only suggest types that would always apply cleanly. - // This means that for `collect` we will suggest `PathBuf` as a valid type - // whereas that `impl` has an extra requirement `T: AsRef` which we - // don't evaluate. - if eval_result.may_apply() - && data.trait_ref.substs.iter().zip(trait_ref.substs.iter()).all( - // Here we'll have something like `[_, i32]` coming from our code - // and `[Vec<_>, _]` from the probe. For cases with - // inference variables we are left with ambiguous cases due to - // trait bounds we couldn't evaluate, but we *can* filter out cases - // like `[std::string::String, char]`, where we can `collect` a - // `String` only if we have an `IntoIterator`, which - // won't match the `i32` we have. - |(l, r)| { - // FIXME: ideally we would use `can_coerce` here instead, but `typeck` - // comes *after* in the dependency graph. - match (l.unpack(), r.unpack()) { - ( - GenericArgKind::Type(left_ty), - GenericArgKind::Type(right_ty), - ) => match ( - &left_ty.peel_refs().kind(), - &right_ty.peel_refs().kind(), - ) { - (Infer(_), _) | (_, Infer(_)) => true, - (left_kind, right_kind) => left_kind == right_kind, - }, - ( - GenericArgKind::Lifetime(_), - GenericArgKind::Lifetime(_), - ) - | (GenericArgKind::Const(_), GenericArgKind::Const(_)) => { - true - } - _ => false, - } - }, - ) - && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) - { - turbofish_suggestions.insert(trait_ref.self_ty()); - } - }; - } + param_env, + target_trait_ref.without_const().to_predicate(self.tcx), + )) + .into_iter() + .chain(obligations), + ) { + debug!("get_turbofish_suggestions result {:?}", eval_result); + if eval_result.must_apply_modulo_regions() + && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) + { + turbofish_suggestions.insert(trait_ref.self_ty()); + } + }; }) }); // Sort types by always suggesting `Vec<_>` and `String` first, as they are the diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4cc4bc0acdab6..2eea2bb7cd564 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -403,20 +403,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) } + crate fn evaluate_predicates( + &mut self, + predicates: impl Iterator>, + ) -> Result { + self.evaluate_predicates_recursively( + TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), + predicates, + ) + } + /// Evaluates the predicates in `predicates` recursively. Note that /// this applies projections in the predicates, and therefore /// is run within an inference probe. - fn evaluate_predicates_recursively<'o, I>( + fn evaluate_predicates_recursively<'o>( &mut self, stack: TraitObligationStackList<'o, 'tcx>, - predicates: I, - ) -> Result - where - I: IntoIterator> + std::fmt::Debug, - { + predicates: impl Iterator>, + ) -> Result { let mut result = EvaluatedToOk; - debug!(?predicates, "evaluate_predicates_recursively"); for obligation in predicates { + debug!(?obligation, "evaluate_predicates_recursively obligation"); let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?; if let EvaluatedToErr = eval { // fast-path - EvaluatedToErr is the top of the lattice, @@ -484,7 +491,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) { Some(mut obligations) => { self.add_depth(obligations.iter_mut(), obligation.recursion_depth); - self.evaluate_predicates_recursively(previous_stack, obligations) + self.evaluate_predicates_recursively( + previous_stack, + obligations.into_iter(), + ) } None => Ok(EvaluatedToAmbig), }, @@ -508,8 +518,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match project::poly_project_and_unify_type(self, &project_obligation) { Ok(Ok(Some(mut subobligations))) => { self.add_depth(subobligations.iter_mut(), obligation.recursion_depth); - let result = self - .evaluate_predicates_recursively(previous_stack, subobligations); + let result = self.evaluate_predicates_recursively( + previous_stack, + subobligations.into_iter(), + ); if let Some(key) = ProjectionCacheKey::from_poly_projection_predicate(self, data) { @@ -1245,7 +1257,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result { self.evaluation_probe(|this| { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { - Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations), + Ok(obligations) => { + this.evaluate_predicates_recursively(stack.list(), obligations.into_iter()) + } Err(()) => Ok(EvaluatedToErr), } }) diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 4d81a3baa0edc..ef311dbef0aea 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -176,7 +176,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, /// generics of `target_impl`, including both those needed to unify with /// `source_trait_ref` and those whose identity is determined via a where /// clause in the impl. -fn fulfill_implication<'a, 'tcx>( +crate fn fulfill_implication<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, source_trait_ref: ty::TraitRef<'tcx>, diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 3d8653b4a6a47..f59842eea6e75 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -131,7 +131,11 @@ pub(super) fn check_fn<'a, 'tcx>( // for simple cases like `fn foo(x: Trait)`, // where we would error once on the parameter as a whole, and once on the binding `x`. if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals { - fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span)); + fcx.require_type_is_sized_deferred( + param_ty, + param.pat.span, + traits::SizedArgumentType(ty_span), + ); } fcx.write_ty(param.hir_id, param_ty); diff --git a/src/test/ui/closures/issue-41366.stderr b/src/test/ui/closures/issue-41366.stderr index 200d411b51194..1072a626c2ad1 100644 --- a/src/test/ui/closures/issue-41366.stderr +++ b/src/test/ui/closures/issue-41366.stderr @@ -1,14 +1,3 @@ -error[E0631]: type mismatch in closure arguments - --> $DIR/issue-41366.rs:10:5 - | -LL | (&|_| ()) as &dyn for<'x> Fn(>::V); - | ^^------^ - | | | - | | found signature of `fn(u16) -> _` - | expected signature of `fn(>::V) -> _` - | - = note: required for the cast to the object type `dyn for<'x> Fn(>::V)` - error[E0277]: the size for values of type `>::V` cannot be known at compilation time --> $DIR/issue-41366.rs:10:8 | @@ -26,6 +15,17 @@ help: function arguments must have a statically known size, borrowed types alway LL | (&|&_| ()) as &dyn for<'x> Fn(>::V); | ^ +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-41366.rs:10:5 + | +LL | (&|_| ()) as &dyn for<'x> Fn(>::V); + | ^^------^ + | | | + | | found signature of `fn(u16) -> _` + | expected signature of `fn(>::V) -> _` + | + = note: required for the cast to the object type `dyn for<'x> Fn(>::V)` + error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0631. diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr index 49ecb624d4eee..381959b7ae4cd 100644 --- a/src/test/ui/question-mark-type-infer.stderr +++ b/src/test/ui/question-mark-type-infer.stderr @@ -8,15 +8,8 @@ LL | l.iter().map(f).collect()? = note: required by `into_result` help: consider specifying the type argument in the method call | -LL | l.iter().map(f).collect::>()? - | ^^^^^^^^^^^^^^^^^^^^^ -LL | l.iter().map(f).collect::>()? - | ^^^^^^^^^^^^^ -LL | l.iter().map(f).collect::>>>()? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | l.iter().map(f).collect::>>()? - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - and 1 other candidate +LL | l.iter().map(f).collect::()? + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs index 52f3df34b8812..959a984043c84 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs @@ -36,6 +36,7 @@ mod c { trait T: Sized { fn new() -> Self; } + fn x() -> X { T::new() } @@ -46,6 +47,14 @@ impl T for S { } } +struct AAA { x: X, } + +impl std::iter::FromIterator for AAA { + fn from_iter>(_iter: I) -> AAA { + panic!() + } +} + fn foo() { x(); //~ ERROR type annotations needed } @@ -54,4 +63,34 @@ fn bar() { let _ = x(); //~ ERROR type annotations needed } -fn main() {} +fn qux() { + let x: Vec<&std::path::Path> = vec![]; + let y = x.into_iter().collect(); //~ ERROR type annotations needed +} + +trait Foo { + fn foo, K>(&self) -> T { + panic!() + } +} + +trait Bar {} + +struct R(X); +impl Bar for R {} +struct K(X); +impl Bar for K {} + +struct I; + +impl Foo for I {} + +// These two cases do not have good suggestions yet: +fn bat() { + let _ = I.foo(); //~ ERROR type annotations needed +} +fn bak>() {} + +fn main() { + bak(); //~ ERROR type annotations needed +} diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index d22d4a466d5e3..cb720b2f18ee5 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -7,15 +7,15 @@ LL | vec![1, 2, 3].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider specifying the type argument in the method call | -LL | vec![1, 2, 3].into_iter().collect::>(); +LL | vec![1, 2, 3].into_iter().collect::>(); | ^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); +LL | vec![1, 2, 3].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec![1, 2, 3].into_iter().collect::>(); | ^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); +LL | vec![1, 2, 3].into_iter().collect::>(); | ^^^^^^^^^^^^^^^ -LL | vec![1, 2, 3].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^^^ - and 8 other candidates + and 6 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:6:41 @@ -26,15 +26,15 @@ LL | vec!["a", "b", "c"].into_iter().collect(); = note: cannot satisfy `_: FromIterator<&str>` help: consider specifying the type argument in the method call | -LL | vec!["a", "b", "c"].into_iter().collect::>(); +LL | vec!["a", "b", "c"].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!["a", "b", "c"].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); +LL | vec!["a", "b", "c"].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec!["a", "b", "c"].into_iter().collect::>(); | ^^^^^^^^^^^^ -LL | vec!["a", "b", "c"].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^ - and 10 other candidates + and 9 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:9:41 @@ -45,15 +45,15 @@ LL | vec!['a', 'b', 'c'].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider specifying the type argument in the method call | -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); | ^^^^^^^^^^ LL | vec!['a', 'b', 'c'].into_iter().collect::(); | ^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); + | ^^^^^^^^^^ +LL | vec!['a', 'b', 'c'].into_iter().collect::>(); | ^^^^^^^^^^^^ -LL | vec!['a', 'b', 'c'].into_iter().collect::>(); - | ^^^^^^^^^^^^^^^ - and 10 other candidates + and 8 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:14:43 @@ -64,15 +64,15 @@ LL | let _ = vec![1, 2, 3].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider giving this binding a type | -LL | let _: Vec<_> = vec![1, 2, 3].into_iter().collect(); +LL | let _: Vec = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^ -LL | let _: Arc<[_]> = vec![1, 2, 3].into_iter().collect(); +LL | let _: AAA = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^ +LL | let _: Arc<[T]> = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^^^ -LL | let _: BTreeSet<_> = vec![1, 2, 3].into_iter().collect(); +LL | let _: BTreeSet = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^^^^^^ -LL | let _: BinaryHeap<_> = vec![1, 2, 3].into_iter().collect(); - | ^^^^^^^^^^^^^^^ - and 8 other candidates + and 6 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:17:49 @@ -83,15 +83,15 @@ LL | let _ = vec!["a", "b", "c"].into_iter().collect(); = note: cannot satisfy `_: FromIterator<&str>` help: consider giving this binding a type | -LL | let _: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); +LL | let _: Vec = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ -LL | let _: Arc<[_]> = vec!["a", "b", "c"].into_iter().collect(); +LL | let _: AAA = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _: Arc<[T]> = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^^^ -LL | let _: BTreeSet<_> = vec!["a", "b", "c"].into_iter().collect(); - | ^^^^^^^^^^^^^ - and 10 other candidates + and 9 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:20:49 @@ -102,15 +102,15 @@ LL | let _ = vec!['a', 'b', 'c'].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider giving this binding a type | -LL | let _: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _: Vec = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ LL | let _: String = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ -LL | let _: Arc<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _: AAA = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _: Arc<[T]> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^^^ -LL | let _: BTreeSet<_> = vec!['a', 'b', 'c'].into_iter().collect(); - | ^^^^^^^^^^^^^ - and 10 other candidates + and 8 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:26:44 @@ -121,15 +121,15 @@ LL | let _x = vec![1, 2, 3].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider giving this binding a type | -LL | let _x: Vec<_> = vec![1, 2, 3].into_iter().collect(); +LL | let _x: Vec = vec![1, 2, 3].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: AAA = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^ -LL | let _x: Arc<[_]> = vec![1, 2, 3].into_iter().collect(); +LL | let _x: Arc<[T]> = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^^^ -LL | let _x: BTreeSet<_> = vec![1, 2, 3].into_iter().collect(); +LL | let _x: BTreeSet = vec![1, 2, 3].into_iter().collect(); | ^^^^^^^^^^^^^ -LL | let _x: BinaryHeap<_> = vec![1, 2, 3].into_iter().collect(); - | ^^^^^^^^^^^^^^^ - and 8 other candidates + and 6 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:29:50 @@ -140,15 +140,15 @@ LL | let _x = vec!["a", "b", "c"].into_iter().collect(); = note: cannot satisfy `_: FromIterator<&str>` help: consider giving this binding a type | -LL | let _x: Vec<_> = vec!["a", "b", "c"].into_iter().collect(); +LL | let _x: Vec = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ LL | let _x: String = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^ -LL | let _x: Arc<[_]> = vec!["a", "b", "c"].into_iter().collect(); +LL | let _x: AAA = vec!["a", "b", "c"].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: Arc<[T]> = vec!["a", "b", "c"].into_iter().collect(); | ^^^^^^^^^^ -LL | let _x: BTreeSet<_> = vec!["a", "b", "c"].into_iter().collect(); - | ^^^^^^^^^^^^^ - and 10 other candidates + and 9 other candidates error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:32:50 @@ -159,18 +159,18 @@ LL | let _x = vec!['a', 'b', 'c'].into_iter().collect(); = note: cannot satisfy `_: FromIterator` help: consider giving this binding a type | -LL | let _x: Vec<_> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _x: Vec = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ LL | let _x: String = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^ -LL | let _x: Arc<[_]> = vec!['a', 'b', 'c'].into_iter().collect(); +LL | let _x: AAA = vec!['a', 'b', 'c'].into_iter().collect(); + | ^^^^^^^^ +LL | let _x: Arc<[T]> = vec!['a', 'b', 'c'].into_iter().collect(); | ^^^^^^^^^^ -LL | let _x: BTreeSet<_> = vec!['a', 'b', 'c'].into_iter().collect(); - | ^^^^^^^^^^^^^ - and 10 other candidates + and 8 other candidates error[E0283]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:50:5 + --> $DIR/appropriate-type-param-turbofish.rs:59:5 | LL | fn x() -> X { | - required by this bound in `x` @@ -185,7 +185,7 @@ LL | x::(); | ^^^^^ error[E0283]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:54:13 + --> $DIR/appropriate-type-param-turbofish.rs:63:13 | LL | fn x() -> X { | - required by this bound in `x` @@ -203,6 +203,52 @@ help: consider specifying the type argument in the function call LL | let _ = x::(); | ^^^^^ -error: aborting due to 11 previous errors +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:68:27 + | +LL | let y = x.into_iter().collect(); + | ^^^^^^^ cannot infer type for type parameter `B` declared on the associated function `collect` + | + = note: cannot satisfy `_: FromIterator<&Path>` +help: consider giving this binding a type + | +LL | let y: Vec = x.into_iter().collect(); + | ^^^^^^^^ +LL | let y: Arc<[T]> = x.into_iter().collect(); + | ^^^^^^^^^^ +LL | let y: BTreeSet = x.into_iter().collect(); + | ^^^^^^^^^^^^^ +LL | let y: BinaryHeap = x.into_iter().collect(); + | ^^^^^^^^^^^^^^^ + and 6 other candidates + +error[E0282]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:90:15 + | +LL | let _ = I.foo(); + | ^^^ cannot infer type for type parameter `T` declared on the associated function `foo` + | +help: consider giving this binding a type + | +LL | let _: Type = I.foo(); + | ^^^^^^ + +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:95:5 + | +LL | fn bak>() {} + | ------------ required by this bound in `bak` +... +LL | bak(); + | ^^^ cannot infer type for type parameter `T` declared on the function `bak` + | + = note: cannot satisfy `_: Into` +help: consider specifying the type argument in the function call + | +LL | bak::(); + | ^^^^^ + +error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 684f451b7c3f6..ecb74fa73f496 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -314,10 +314,10 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:128:18 + --> $DIR/typeck_type_placeholder_item.rs:128:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } - | ^ cannot infer type + | ^^^^^^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:128:28 From e9188795b902048a2559a82c6cebecda2ce6c119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 16:52:35 -0700 Subject: [PATCH 09/17] `collect` now triggers E0283 instad of E0282 --- compiler/rustc_error_codes/src/error_codes/E0282.md | 2 +- .../rustc_infer/src/infer/error_reporting/need_type_info.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0282.md b/compiler/rustc_error_codes/src/error_codes/E0282.md index 49d2205f92c2a..04381f2bed8c2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0282.md +++ b/compiler/rustc_error_codes/src/error_codes/E0282.md @@ -3,7 +3,7 @@ The compiler could not infer a type and asked for a type annotation. Erroneous code example: ```compile_fail,E0282 -let x = "hello".chars().rev().collect(); +let x = None; ``` This error indicates that type inference did not result in one unique possible diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 2c4cf193ffff3..96855fb6bba30 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -182,7 +182,7 @@ fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String { pub enum TypeAnnotationNeeded { /// ```compile_fail,E0282 - /// let x = "hello".chars().rev().collect(); + /// let _ = None; /// ``` E0282, /// An implementation cannot be chosen unambiguously because of lack of information. From 8ec1c382fab4ce886a9c2cea8b46c351e7f71f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 22:06:38 -0700 Subject: [PATCH 10/17] Remove unnecessary condition --- .../src/traits/error_reporting/suggestions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d3d120e715403..525a98ec55f98 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -369,10 +369,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .into_iter() .chain(obligations), ) { - debug!("get_turbofish_suggestions result {:?}", eval_result); - if eval_result.must_apply_modulo_regions() - && !matches!(trait_ref.self_ty().kind(), ty::Infer(_)) - { + if eval_result.must_apply_modulo_regions() { turbofish_suggestions.insert(trait_ref.self_ty()); } }; From ae5a239dcef859007629e572ca93ce1a0c7f6e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 22:38:33 -0700 Subject: [PATCH 11/17] Avoid `?Sized` local E0282 errors to provide better output and suggestions --- .../src/traits/error_reporting/mod.rs | 2 +- src/test/ui/async-await/issues/issue-65159.rs | 1 - .../ui/async-await/issues/issue-65159.stderr | 11 +-- src/test/ui/closures/issue-52437.rs | 1 - src/test/ui/closures/issue-52437.stderr | 11 +-- src/test/ui/consts/issue-52432.rs | 1 - src/test/ui/consts/issue-52432.stderr | 14 ++-- src/test/ui/consts/issue-64662.rs | 2 +- src/test/ui/consts/issue-64662.stderr | 8 +-- src/test/ui/error-codes/E0401.stderr | 17 +++-- src/test/ui/error-codes/E0661.rs | 2 +- src/test/ui/error-codes/E0661.stderr | 16 +---- ...for-loop-unconstrained-element-type.stderr | 2 +- src/test/ui/issues/issue-16966.stderr | 21 +++++- src/test/ui/issues/issue-24036.stderr | 11 +-- src/test/ui/issues/issue-25368.stderr | 4 +- src/test/ui/issues/issue-47486-2.rs | 3 + src/test/ui/issues/issue-47486-2.stderr | 9 +++ src/test/ui/issues/issue-47486.rs | 1 - src/test/ui/issues/issue-47486.stderr | 11 +-- src/test/ui/issues/issue-66706.rs | 1 - src/test/ui/issues/issue-66706.stderr | 21 ++---- ...od-ambig-one-trait-unknown-int-type.stderr | 2 +- ...377-invalid-syntax-in-enum-discriminant.rs | 2 - ...invalid-syntax-in-enum-discriminant.stderr | 23 ++---- .../pattern/rest-pat-semantic-disallowed.rs | 1 - .../rest-pat-semantic-disallowed.stderr | 42 ++++------- .../appropriate-type-param-turbofish.rs | 3 +- .../appropriate-type-param-turbofish.stderr | 16 ++--- ...traits-multidispatch-convert-ambig-dest.rs | 2 +- ...ts-multidispatch-convert-ambig-dest.stderr | 17 ++++- src/test/ui/type-inference/sort_by_key.stderr | 14 +++- .../cannot_infer_local_or_vec.stderr | 2 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- .../unknown_type_for_closure.stderr | 11 ++- .../ui/type/type-path-err-node-types-2.rs | 10 +++ .../ui/type/type-path-err-node-types-2.stderr | 14 ++++ src/test/ui/type/type-path-err-node-types.rs | 4 -- .../ui/type/type-path-err-node-types.stderr | 12 +--- .../ui/typeck/typeck_type_placeholder_item.rs | 1 - .../typeck_type_placeholder_item.stderr | 70 +++++++++---------- src/test/ui/unconstrained-ref.stderr | 4 +- src/test/ui/vector-no-ann.stderr | 2 +- 43 files changed, 205 insertions(+), 219 deletions(-) create mode 100644 src/test/ui/issues/issue-47486-2.rs create mode 100644 src/test/ui/issues/issue-47486-2.stderr create mode 100644 src/test/ui/type/type-path-err-node-types-2.rs create mode 100644 src/test/ui/type/type-path-err-node-types-2.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index d0aae2df58c8c..550af5fb11156 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1505,7 +1505,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(data.trait_ref.def_id) { self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, &[]) - .emit(); + .delay_as_bug(); return; } // Try to find possible types that would satisfy the bounds in the type param to diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs index 4f160fccc0113..b5fee061f277e 100644 --- a/src/test/ui/async-await/issues/issue-65159.rs +++ b/src/test/ui/async-await/issues/issue-65159.rs @@ -5,7 +5,6 @@ async fn copy() -> Result<()> //~ ERROR wrong number of type arguments { Ok(()) - //~^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr index 04cfa5249982e..56d2c38b302e9 100644 --- a/src/test/ui/async-await/issues/issue-65159.stderr +++ b/src/test/ui/async-await/issues/issue-65159.stderr @@ -4,13 +4,6 @@ error[E0107]: wrong number of type arguments: expected 2, found 1 LL | async fn copy() -> Result<()> | ^^^^^^^^^^ expected 2 type arguments -error[E0282]: type annotations needed - --> $DIR/issue-65159.rs:7:5 - | -LL | Ok(()) - | ^^ cannot infer type for type parameter `E` declared on the enum `Result` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/closures/issue-52437.rs b/src/test/ui/closures/issue-52437.rs index f79a0bd35486a..02ae1f86a4ba6 100644 --- a/src/test/ui/closures/issue-52437.rs +++ b/src/test/ui/closures/issue-52437.rs @@ -1,6 +1,5 @@ fn main() { [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //~^ ERROR: invalid label name `'static` - //~| ERROR: type annotations needed //~| ERROR mismatched types } diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr index 54825cb746d42..34707bc6f2fa1 100644 --- a/src/test/ui/closures/issue-52437.stderr +++ b/src/test/ui/closures/issue-52437.stderr @@ -4,12 +4,6 @@ error: invalid label name `'static` LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^^^^^^^ -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 - error[E0308]: mismatched types --> $DIR/issue-52437.rs:2:5 | @@ -18,7 +12,6 @@ LL | fn main() { LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[(); _]` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/issue-52432.rs b/src/test/ui/consts/issue-52432.rs index d719bf1b97161..eba4cde614b3b 100644 --- a/src/test/ui/consts/issue-52432.rs +++ b/src/test/ui/consts/issue-52432.rs @@ -3,7 +3,6 @@ fn main() { [(); &(static |x| {}) as *const _ as usize]; //~^ ERROR: closures cannot be static - //~| ERROR: type annotations needed [(); &(static || {}) as *const _ as usize]; //~^ ERROR: closures cannot be static //~| ERROR evaluation of constant value failed diff --git a/src/test/ui/consts/issue-52432.stderr b/src/test/ui/consts/issue-52432.stderr index e9539d24118a0..b53590551f72b 100644 --- a/src/test/ui/consts/issue-52432.stderr +++ b/src/test/ui/consts/issue-52432.stderr @@ -5,24 +5,18 @@ LL | [(); &(static |x| {}) as *const _ as usize]; | ^^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/issue-52432.rs:7:12 + --> $DIR/issue-52432.rs:6:12 | LL | [(); &(static || {}) as *const _ as usize]; | ^^^^^^^^^ -error[E0282]: type annotations needed - --> $DIR/issue-52432.rs:4:20 - | -LL | [(); &(static |x| {}) as *const _ as usize]; - | ^ consider giving this closure parameter a type - error[E0080]: evaluation of constant value failed - --> $DIR/issue-52432.rs:7:10 + --> $DIR/issue-52432.rs:6:10 | LL | [(); &(static || {}) as *const _ as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0282, E0697. +Some errors have detailed explanations: E0080, E0697. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/issue-64662.rs b/src/test/ui/consts/issue-64662.rs index e3a8c85830f73..ee583ab7722d8 100644 --- a/src/test/ui/consts/issue-64662.rs +++ b/src/test/ui/consts/issue-64662.rs @@ -1,6 +1,6 @@ enum Foo { A = foo(), //~ ERROR: type annotations needed - B = foo(), //~ ERROR: type annotations needed + B = foo(), // We don't emit an error here, but if the one above is fixed, we will. } const fn foo() -> isize { diff --git a/src/test/ui/consts/issue-64662.stderr b/src/test/ui/consts/issue-64662.stderr index dd281e911da96..c6eb63f7079a5 100644 --- a/src/test/ui/consts/issue-64662.stderr +++ b/src/test/ui/consts/issue-64662.stderr @@ -4,12 +4,6 @@ error[E0282]: type annotations needed LL | A = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` -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` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 8b1d4e6c07ceb..5ed90978117b5 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -32,13 +32,22 @@ LL | fn helper(sel: &Self) -> u8 { | use of generic parameter from outer function | use a type here instead -error[E0282]: type annotations needed +error[E0283]: type annotations needed --> $DIR/E0401.rs:11:5 | +LL | fn bfnr, W: Fn()>(y: T) { + | ------ required by this bound in `bfnr` +... LL | bfnr(x); - | ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr` + | ^^^^ cannot infer type for type parameter `V` declared on the function `bfnr` + | + = note: cannot satisfy `_: Baz<_>` +help: consider specifying the type arguments in the function call + | +LL | bfnr::(x); + | ^^^^^^^^^^^ error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0401. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0283, E0401. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs index 1099edd848b28..43a005db9dc45 100644 --- a/src/test/ui/error-codes/E0661.rs +++ b/src/test/ui/error-codes/E0661.rs @@ -3,7 +3,7 @@ #![feature(llvm_asm)] fn main() { - let a; //~ ERROR type annotations needed + let a; llvm_asm!("nop" : "r"(a)); //~^ ERROR E0661 } diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr index 2cb6b216e7607..c93e60a7181f5 100644 --- a/src/test/ui/error-codes/E0661.stderr +++ b/src/test/ui/error-codes/E0661.stderr @@ -4,18 +4,6 @@ error[E0661]: output operand constraint lacks '=' or '+' LL | llvm_asm!("nop" : "r"(a)); | ^^^ -error[E0282]: type annotations needed - --> $DIR/E0661.rs:6:9 - | -LL | let a; - | ^ cannot infer type - | -help: consider giving this binding a type - | -LL | let a: Type; - | ^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0282, E0661. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0661`. diff --git a/src/test/ui/for/for-loop-unconstrained-element-type.stderr b/src/test/ui/for/for-loop-unconstrained-element-type.stderr index cba9fbd5cf4de..2f5f4666e370a 100644 --- a/src/test/ui/for/for-loop-unconstrained-element-type.stderr +++ b/src/test/ui/for/for-loop-unconstrained-element-type.stderr @@ -5,7 +5,7 @@ LL | for i in Vec::new() { } | ^^^^^^^^-- | | | the element type for this iterator is not specified - | cannot infer type for type parameter `T` + | cannot infer type for type parameter `T` declared on the struct `Vec` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr index 30932a375b1f0..96898a55001ed 100644 --- a/src/test/ui/issues/issue-16966.stderr +++ b/src/test/ui/issues/issue-16966.stderr @@ -1,11 +1,28 @@ -error[E0282]: type annotations needed +error[E0283]: 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` + | + ::: $SRC_DIR/std/src/panicking.rs:LL:COL | +LL | pub fn begin_panic(msg: M) -> ! { + | ---- required by this bound in `begin_panic` + | + = note: cannot satisfy `_: Send` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider specifying the type argument in the function call + | +LL | ($msg:expr) => ({ $crate::rt::begin_panic::>($msg) }); + | ^^^^^^^^^^^^^^^ +LL | ($msg:expr) => ({ $crate::rt::begin_panic::>($msg) }); + | ^^^^^^^^^^^^^^^^^^ +LL | ($msg:expr) => ({ $crate::rt::begin_panic::($msg) }); + | ^^^^^^^^^^^^ +LL | ($msg:expr) => ({ $crate::rt::begin_panic::($msg) }); + | ^^^^^^^^^ + and 13 other candidates error: aborting due to previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index 9bbbb4b3d6bee..a45f21c73d6a3 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -11,12 +11,13 @@ LL | x = |c| c + 1; = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object -error[E0282]: type annotations needed for `fn(_) -> _` - --> $DIR/issue-24036.rs:9:18 +error[E0284]: type annotations needed for `fn(_) -> _` + --> $DIR/issue-24036.rs:9:20 | LL | 1 => |c| c + 1, - | ^ cannot infer type + | ^ cannot infer type | + = note: cannot satisfy `<_ as Add>::Output == _` help: consider giving this binding the explicit type `fn(_) -> _`, with the type parameters specified | LL | let x: fn(_) -> _ = match 1usize { @@ -24,5 +25,5 @@ LL | let x: fn(_) -> _ = match 1usize { error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index e28201d75c426..b4ec239085144 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed for `(Sender>, std::sync::mpsc::Receiver>)` - --> $DIR/issue-25368.rs:11:17 + --> $DIR/issue-25368.rs:11:27 | LL | tx.send(Foo{ foo: PhantomData }); - | ^^^ cannot infer type for type parameter `T` declared on the struct `Foo` + | ^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `PhantomData` | help: consider giving this binding the explicit type `(Sender>, std::sync::mpsc::Receiver>)`, where the type parameter `T` is specified | diff --git a/src/test/ui/issues/issue-47486-2.rs b/src/test/ui/issues/issue-47486-2.rs new file mode 100644 index 0000000000000..20e6a95e70bc3 --- /dev/null +++ b/src/test/ui/issues/issue-47486-2.rs @@ -0,0 +1,3 @@ +fn main() { + [0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed +} diff --git a/src/test/ui/issues/issue-47486-2.stderr b/src/test/ui/issues/issue-47486-2.stderr new file mode 100644 index 0000000000000..629983e4d724e --- /dev/null +++ b/src/test/ui/issues/issue-47486-2.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/issue-47486-2.rs:2:31 + | +LL | [0u8; std::mem::size_of::<_>()]; + | ^ cannot infer type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-47486.rs b/src/test/ui/issues/issue-47486.rs index d686f02a9fe39..a8b7bfc3ffca7 100644 --- a/src/test/ui/issues/issue-47486.rs +++ b/src/test/ui/issues/issue-47486.rs @@ -1,4 +1,3 @@ fn main() { () < std::mem::size_of::<_>(); //~ ERROR: mismatched types - [0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed } diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index cf95d309c6344..719bc68ed01e0 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -4,13 +4,6 @@ error[E0308]: mismatched types LL | () < std::mem::size_of::<_>(); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` -error[E0282]: type annotations needed - --> $DIR/issue-47486.rs:3:11 - | -LL | [0u8; std::mem::size_of::<_>()]; - | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-66706.rs b/src/test/ui/issues/issue-66706.rs index 4585bcc8cd57f..a1ba99cffe207 100644 --- a/src/test/ui/issues/issue-66706.rs +++ b/src/test/ui/issues/issue-66706.rs @@ -1,7 +1,6 @@ fn a() { [0; [|_: _ &_| ()].len()] //~^ ERROR expected `,`, found `&` - //~| ERROR type annotations needed //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr index f0b93ac91111a..9b960f1c0a339 100644 --- a/src/test/ui/issues/issue-66706.stderr +++ b/src/test/ui/issues/issue-66706.stderr @@ -7,13 +7,13 @@ LL | [0; [|_: _ &_| ()].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:9:20 + --> $DIR/issue-66706.rs:8:20 | LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; | ^ expected identifier, found reserved identifier error: expected `,`, found `&` - --> $DIR/issue-66706.rs:14:17 + --> $DIR/issue-66706.rs:13:17 | LL | [0; [|&_: _ &_| {}; 0 ].len()] | -^ expected `,` @@ -21,17 +21,11 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:20:26 + --> $DIR/issue-66706.rs:19:26 | LL | [0; match [|f @ &ref _| () ] {} ] | ^ expected identifier, found reserved identifier -error[E0282]: type annotations needed - --> $DIR/issue-66706.rs:2:11 - | -LL | [0; [|_: _ &_| ()].len()] - | ^ consider giving this closure parameter a type - error[E0308]: mismatched types --> $DIR/issue-66706.rs:2:5 | @@ -41,7 +35,7 @@ LL | [0; [|_: _ &_| ()].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` error[E0308]: mismatched types - --> $DIR/issue-66706.rs:14:5 + --> $DIR/issue-66706.rs:13:5 | LL | fn c() { | - help: try adding a return type: `-> [{integer}; _]` @@ -49,14 +43,13 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` error[E0308]: mismatched types - --> $DIR/issue-66706.rs:20:5 + --> $DIR/issue-66706.rs:19:5 | LL | fn d() { | - help: try adding a return type: `-> [{integer}; _]` LL | [0; match [|f @ &ref _| () ] {} ] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 28212d70bb32e..7d7c64c57eb84 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` | help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified | diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs index 87222ef4b5924..3f81b38c29f8f 100644 --- a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -17,7 +17,6 @@ mod b { //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` - //~| ERROR type annotations needed } } @@ -28,7 +27,6 @@ mod c { //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` - //~| ERROR type annotations needed } } diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr index f20ec75535354..cec8fe3887dfc 100644 --- a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -17,7 +17,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -44,7 +44,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -71,7 +71,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -98,7 +98,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -106,18 +106,5 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, | | unclosed delimiter | closing delimiter possibly meant for this -error[E0282]: type annotations needed - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 - | -LL | V = [Vec::new; { [].len() ].len() as isize, - | ^^^ cannot infer type for type parameter `T` - -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` - -error: aborting due to 14 previous errors +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 84552f2e73315..506c2301681c8 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -31,7 +31,6 @@ fn rest_patterns() { // Ident patterns: let x @ ..; //~ ERROR `..` patterns are not allowed here - //~^ ERROR type annotations needed let ref x @ ..; //~ ERROR `..` patterns are not allowed here let ref mut x @ ..; //~ ERROR `..` patterns are not allowed here diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index 678029b3ef369..1e26980cc23c3 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -59,7 +59,7 @@ LL | let x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:35:17 + --> $DIR/rest-pat-semantic-disallowed.rs:34:17 | LL | let ref x @ ..; | ^^ @@ -67,7 +67,7 @@ LL | let ref x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:36:21 + --> $DIR/rest-pat-semantic-disallowed.rs:35:21 | LL | let ref mut x @ ..; | ^^ @@ -75,7 +75,7 @@ LL | let ref mut x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:43:9 + --> $DIR/rest-pat-semantic-disallowed.rs:42:9 | LL | .., | -- previously used here @@ -83,7 +83,7 @@ LL | .., | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:44:9 + --> $DIR/rest-pat-semantic-disallowed.rs:43:9 | LL | .., | -- previously used here @@ -92,7 +92,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:49:9 + --> $DIR/rest-pat-semantic-disallowed.rs:48:9 | LL | .., | -- previously used here @@ -101,7 +101,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:59:9 + --> $DIR/rest-pat-semantic-disallowed.rs:58:9 | LL | .., | -- previously used here @@ -109,7 +109,7 @@ LL | .., | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:60:9 + --> $DIR/rest-pat-semantic-disallowed.rs:59:9 | LL | .., | -- previously used here @@ -118,7 +118,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:65:9 + --> $DIR/rest-pat-semantic-disallowed.rs:64:9 | LL | .., | -- previously used here @@ -127,7 +127,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:73:9 + --> $DIR/rest-pat-semantic-disallowed.rs:72:9 | LL | .., | -- previously used here @@ -135,7 +135,7 @@ LL | .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:74:9 + --> $DIR/rest-pat-semantic-disallowed.rs:73:9 | LL | .., | -- previously used here @@ -144,7 +144,7 @@ LL | .. | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:78:17 + --> $DIR/rest-pat-semantic-disallowed.rs:77:17 | LL | .., | -- previously used here @@ -152,7 +152,7 @@ LL | ref x @ .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:79:21 + --> $DIR/rest-pat-semantic-disallowed.rs:78:21 | LL | .., | -- previously used here @@ -161,7 +161,7 @@ LL | ref mut y @ .., | ^^ can only be used once per slice pattern error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:80:18 + --> $DIR/rest-pat-semantic-disallowed.rs:79:18 | LL | (ref z @ ..), | ^^ @@ -169,7 +169,7 @@ LL | (ref z @ ..), = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:81:9 + --> $DIR/rest-pat-semantic-disallowed.rs:80:9 | LL | .., | -- previously used here @@ -185,17 +185,5 @@ LL | fn foo(..: u8) {} | = note: only allowed in tuple, tuple struct, and slice patterns -error[E0282]: type annotations needed - --> $DIR/rest-pat-semantic-disallowed.rs:33:9 - | -LL | let x @ ..; - | ^^^^^^ cannot infer type - | -help: consider giving this binding a type - | -LL | let x @ ..: Type; - | ^^^^^^ - -error: aborting due to 23 previous errors +error: aborting due to 22 previous errors -For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs index 959a984043c84..0e58704d1d734 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.rs +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.rs @@ -85,10 +85,11 @@ struct I; impl Foo for I {} -// These two cases do not have good suggestions yet: fn bat() { let _ = I.foo(); //~ ERROR type annotations needed } + +// This case does not have a good suggestion yet: fn bak>() {} fn main() { diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index cb720b2f18ee5..480d0554a3974 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -222,19 +222,20 @@ LL | let y: BinaryHeap = x.into_iter().collect(); | ^^^^^^^^^^^^^^^ and 6 other candidates -error[E0282]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:90:15 +error[E0283]: type annotations needed + --> $DIR/appropriate-type-param-turbofish.rs:89:15 | LL | let _ = I.foo(); | ^^^ cannot infer type for type parameter `T` declared on the associated function `foo` | -help: consider giving this binding a type + = note: cannot satisfy `_: Bar<_>` +help: consider giving this binding the explicit type `K` | -LL | let _: Type = I.foo(); - | ^^^^^^ +LL | let _: K = I.foo(); + | ^^^^^^^^ error[E0283]: type annotations needed - --> $DIR/appropriate-type-param-turbofish.rs:95:5 + --> $DIR/appropriate-type-param-turbofish.rs:96:5 | LL | fn bak>() {} | ------------ required by this bound in `bak` @@ -250,5 +251,4 @@ LL | bak::(); error: aborting due to 14 previous errors -Some errors have detailed explanations: E0282, E0283. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.rs b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.rs index 58cb69a05b704..36e1e868fca13 100644 --- a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.rs +++ b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.rs @@ -24,7 +24,7 @@ where T : Convert fn a() { test(22, std::default::Default::default()); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr index 338c8cbf2e4f2..9f5caf1d9f74d 100644 --- a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr @@ -1,9 +1,20 @@ -error[E0282]: type annotations needed +error[E0283]: type annotations needed --> $DIR/traits-multidispatch-convert-ambig-dest.rs:26:5 | +LL | fn test(_: T, _: U) + | ---- required by a bound in this +LL | where T : Convert + | ---------- required by this bound in `test` +... LL | test(22, std::default::Default::default()); - | ^^^^ cannot infer type for type parameter `U` declared on the function `test` + | ^^^^ cannot infer type for type `i32` + | + = note: cannot satisfy `i32: Convert<_>` +help: consider specifying the type arguments in the function call + | +LL | test::(22, std::default::Default::default()); + | ^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type-inference/sort_by_key.stderr b/src/test/ui/type-inference/sort_by_key.stderr index 0b6630ec89423..9ae3b89c30bde 100644 --- a/src/test/ui/type-inference/sort_by_key.stderr +++ b/src/test/ui/type-inference/sort_by_key.stderr @@ -1,14 +1,22 @@ -error[E0282]: type annotations needed +error[E0283]: type annotations needed --> $DIR/sort_by_key.rs:3:9 | LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); | ^^^^^^^^^^^ cannot infer type for type parameter `K` declared on the associated function `sort_by_key` | + = note: cannot satisfy `_: Ord` help: consider specifying the type argument in the method call | -LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); + | ^^^^^^^^^^ +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); | ^^^^^ +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::<()>()); + | ^^^^^^ +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::<*const T>()); + | ^^^^^^^^^^^^ + and 99 other candidates error: aborting due to previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 0b8a1f2670e58..3016b82494082 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | ^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 78128a266ef2d..f4aa6da47a67c 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `(Vec,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider giving this binding the explicit type `(Vec,)`, where the type parameter `T` is specified diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr index 5971f56c97f7d..efbe3c2eddf5e 100644 --- a/src/test/ui/type/type-check/unknown_type_for_closure.stderr +++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr @@ -1,8 +1,13 @@ -error[E0282]: type annotations needed - --> $DIR/unknown_type_for_closure.rs:2:14 +error[E0282]: type annotations needed for the closure `fn(_) -> ()` + --> $DIR/unknown_type_for_closure.rs:2:13 | LL | let x = |_| { }; - | ^ consider giving this closure parameter a type + | ^^^^^^^^^^ cannot infer type for closure `[closure@$DIR/unknown_type_for_closure.rs:2:13: 2:23]` + | +help: give this closure an explicit return type without `_` placeholders + | +LL | let x = |_| -> () { }; + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-path-err-node-types-2.rs b/src/test/ui/type/type-path-err-node-types-2.rs new file mode 100644 index 0000000000000..a088ad6f195e6 --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types-2.rs @@ -0,0 +1,10 @@ +// Type arguments in unresolved entities (reporting errors before type checking) +// should have their types recorded. + +trait Tr {} + +fn closure() { + let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type/type-path-err-node-types-2.stderr b/src/test/ui/type/type-path-err-node-types-2.stderr new file mode 100644 index 0000000000000..a9f70cc718ec7 --- /dev/null +++ b/src/test/ui/type/type-path-err-node-types-2.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for the closure `fn(_, _) -> i32` + --> $DIR/type-path-err-node-types-2.rs:7:13 + | +LL | let _ = |a, b: _| -> _ { 0 }; + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for closure `[closure@$DIR/type-path-err-node-types-2.rs:7:13: 7:33]` + | +help: give this closure an explicit return type without `_` placeholders + | +LL | let _ = |a, b: _| -> i32 { 0 }; + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs index b3795772e6fe2..cfc8872c2791e 100644 --- a/src/test/ui/type/type-path-err-node-types.rs +++ b/src/test/ui/type/type-path-err-node-types.rs @@ -19,8 +19,4 @@ fn method() { nonexistent.nonexistent::(); //~ ERROR cannot find value `nonexistent` } -fn closure() { - let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed -} - fn main() {} diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr index baf218243c4c8..90f56655e2901 100644 --- a/src/test/ui/type/type-path-err-node-types.stderr +++ b/src/test/ui/type/type-path-err-node-types.stderr @@ -22,13 +22,7 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::(); | ^^^^^^^^^^^ not found in this scope -error[E0282]: type annotations needed - --> $DIR/type-path-err-node-types.rs:23:14 - | -LL | let _ = |a, b: _| -> _ { 0 }; - | ^ consider giving this closure parameter a type - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0412, E0425, E0433, E0576. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0412, E0425, E0433, E0576. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 2c8b1e76b1b82..fa76eeb3b799b 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -127,7 +127,6 @@ pub fn main() { fn fn_test11(_: _) -> (_, _) { panic!() } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures - //~| ERROR type annotations needed fn fn_test12(x: i32) -> (_, _) { (x, x) } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index ecb74fa73f496..9e8eef7a6c030 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:154:18 + --> $DIR/typeck_type_placeholder_item.rs:153:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:157:16 + --> $DIR/typeck_type_placeholder_item.rs:156:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:167:19 + --> $DIR/typeck_type_placeholder_item.rs:166:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:167:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:172:19 + --> $DIR/typeck_type_placeholder_item.rs:171:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:205:5 + --> $DIR/typeck_type_placeholder_item.rs:204:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,7 +37,7 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:167:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -313,12 +313,6 @@ LL | LL | b: (T, T), | -error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:128:27 - | -LL | fn fn_test11(_: _) -> (_, _) { panic!() } - | ^^^^^^ cannot infer type - error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:128:28 | @@ -328,7 +322,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:132:30 + --> $DIR/typeck_type_placeholder_item.rs:131:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -338,7 +332,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:135:33 + --> $DIR/typeck_type_placeholder_item.rs:134:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -347,7 +341,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:154:21 + --> $DIR/typeck_type_placeholder_item.rs:153:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -358,7 +352,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:159:15 + --> $DIR/typeck_type_placeholder_item.rs:158:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -371,13 +365,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:162:34 + --> $DIR/typeck_type_placeholder_item.rs:161:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:167:25 + --> $DIR/typeck_type_placeholder_item.rs:166:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -388,7 +382,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:172:25 + --> $DIR/typeck_type_placeholder_item.rs:171:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -399,19 +393,19 @@ LL | struct BadStruct2(U, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:176:14 + --> $DIR/typeck_type_placeholder_item.rs:175:14 | LL | type X = Box<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:182:21 + --> $DIR/typeck_type_placeholder_item.rs:181:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:140:31 + --> $DIR/typeck_type_placeholder_item.rs:139:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -422,7 +416,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:142:31 + --> $DIR/typeck_type_placeholder_item.rs:141:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -435,7 +429,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:144:31 + --> $DIR/typeck_type_placeholder_item.rs:143:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -446,7 +440,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:26 + --> $DIR/typeck_type_placeholder_item.rs:145:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -457,7 +451,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:148:26 + --> $DIR/typeck_type_placeholder_item.rs:147:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -470,7 +464,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:150:28 + --> $DIR/typeck_type_placeholder_item.rs:149:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -481,19 +475,19 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:190:14 + --> $DIR/typeck_type_placeholder_item.rs:189:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:192:14 + --> $DIR/typeck_type_placeholder_item.rs:191:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:194:14 + --> $DIR/typeck_type_placeholder_item.rs:193:14 | LL | const D: _ = 42; | ^ @@ -502,7 +496,7 @@ LL | const D: _ = 42; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:197:26 + --> $DIR/typeck_type_placeholder_item.rs:196:26 | LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures @@ -588,25 +582,25 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:201:14 + --> $DIR/typeck_type_placeholder_item.rs:200:14 | LL | type A = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:203:14 + --> $DIR/typeck_type_placeholder_item.rs:202:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:205:14 + --> $DIR/typeck_type_placeholder_item.rs:204:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:208:14 + --> $DIR/typeck_type_placeholder_item.rs:207:14 | LL | const D: _ = 42; | ^ @@ -614,7 +608,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 67 previous errors +error: aborting due to 66 previous errors -Some errors have detailed explanations: E0121, E0282, E0403. +Some errors have detailed explanations: E0121, E0403. For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/unconstrained-ref.stderr b/src/test/ui/unconstrained-ref.stderr index eb8ebb5165d18..bace41580a896 100644 --- a/src/test/ui/unconstrained-ref.stderr +++ b/src/test/ui/unconstrained-ref.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:5 + --> $DIR/unconstrained-ref.rs:6:13 | LL | S { o: &None }; - | ^ cannot infer type for type parameter `T` declared on the struct `S` + | ^^^^ cannot infer type for type parameter `T` declared on the enum `Option` error: aborting due to previous error diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index a45ac324f4a6b..dea532b32e4ee 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` | help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified | From 660480ac913a2e6173488e114a90bc04f07f64c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 23:16:00 -0700 Subject: [PATCH 12/17] Avoid suggesting inside macro call Specifically avoid non-sense suggestion when calling `panic!` with something `!Send`. --- .../src/traits/error_reporting/mod.rs | 1 + src/test/ui/issues/issue-16966.stderr | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 550af5fb11156..4eecd4eca40a4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1537,6 +1537,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let generics = self.tcx.generics_of(*def_id); if generics.params.iter().any(|p| p.name != kw::SelfUpper) && !snippet.ends_with('>') + && !span.from_expansion() { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr index 96898a55001ed..80ee6b8ca2319 100644 --- a/src/test/ui/issues/issue-16966.stderr +++ b/src/test/ui/issues/issue-16966.stderr @@ -11,17 +11,6 @@ LL | pub fn begin_panic(msg: M) -> ! { | = note: cannot satisfy `_: Send` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider specifying the type argument in the function call - | -LL | ($msg:expr) => ({ $crate::rt::begin_panic::>($msg) }); - | ^^^^^^^^^^^^^^^ -LL | ($msg:expr) => ({ $crate::rt::begin_panic::>($msg) }); - | ^^^^^^^^^^^^^^^^^^ -LL | ($msg:expr) => ({ $crate::rt::begin_panic::($msg) }); - | ^^^^^^^^^^^^ -LL | ($msg:expr) => ({ $crate::rt::begin_panic::($msg) }); - | ^^^^^^^^^ - and 13 other candidates error: aborting due to previous error From 15c74d57f01f30412b50cf50d72766f7b9724fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Oct 2020 19:17:44 -0700 Subject: [PATCH 13/17] Do not skip "type annotation needed"/`Sized` error --- .../src/traits/error_reporting/mod.rs | 18 ++--- src/test/ui/async-await/issues/issue-65159.rs | 1 + .../ui/async-await/issues/issue-65159.stderr | 11 ++- src/test/ui/closures/issue-52437.rs | 1 + src/test/ui/closures/issue-52437.stderr | 11 ++- src/test/ui/consts/issue-52432.rs | 1 + src/test/ui/consts/issue-52432.stderr | 14 ++-- src/test/ui/consts/issue-64662.rs | 2 +- src/test/ui/consts/issue-64662.stderr | 18 ++++- src/test/ui/error-codes/E0401.stderr | 12 ++-- src/test/ui/error-codes/E0661.rs | 2 +- src/test/ui/error-codes/E0661.stderr | 16 ++++- ...for-loop-unconstrained-element-type.stderr | 2 +- src/test/ui/issues/issue-12187-1.stderr | 4 ++ src/test/ui/issues/issue-12187-2.stderr | 4 ++ src/test/ui/issues/issue-16966.stderr | 10 +-- src/test/ui/issues/issue-24036.stderr | 11 ++- src/test/ui/issues/issue-25368.stderr | 4 +- src/test/ui/issues/issue-47486-2.rs | 3 - src/test/ui/issues/issue-47486-2.stderr | 9 --- src/test/ui/issues/issue-47486.rs | 1 + src/test/ui/issues/issue-47486.stderr | 11 ++- src/test/ui/issues/issue-6458-3.stderr | 5 ++ src/test/ui/issues/issue-6458.stderr | 5 ++ src/test/ui/issues/issue-66706.rs | 1 + src/test/ui/issues/issue-66706.stderr | 21 ++++-- .../ui/match/match-unresolved-one-arm.stderr | 4 ++ ...od-ambig-one-trait-unknown-int-type.stderr | 2 +- .../missing-type-parameter.stderr | 5 ++ ...377-invalid-syntax-in-enum-discriminant.rs | 2 + ...invalid-syntax-in-enum-discriminant.stderr | 23 ++++-- .../pattern/rest-pat-semantic-disallowed.rs | 1 + .../rest-pat-semantic-disallowed.stderr | 42 +++++++---- .../appropriate-type-param-turbofish.stderr | 12 ++-- ...needing-specified-return-type-param.stderr | 4 ++ ...ts-multidispatch-convert-ambig-dest.stderr | 16 ++--- src/test/ui/type-inference/sort_by_key.stderr | 14 +--- ...ed-type-param-in-fn-with-assoc-type.stderr | 5 ++ .../unbounded-type-param-in-fn.stderr | 5 ++ .../cannot_infer_local_or_vec.stderr | 2 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- .../unknown_type_for_closure.stderr | 11 +-- .../ui/type/type-path-err-node-types-2.stderr | 11 +-- .../ui/typeck/typeck_type_placeholder_item.rs | 1 + .../typeck_type_placeholder_item.stderr | 70 ++++++++++--------- src/test/ui/unconstrained-ref.stderr | 4 +- src/test/ui/vector-no-ann.stderr | 2 +- 47 files changed, 267 insertions(+), 169 deletions(-) delete mode 100644 src/test/ui/issues/issue-47486-2.rs delete mode 100644 src/test/ui/issues/issue-47486-2.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4eecd4eca40a4..c285fcd13239b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1503,11 +1503,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. - if self.tcx.lang_items().sized_trait() == Some(data.trait_ref.def_id) { - self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0282, &[]) - .delay_as_bug(); - return; - } + let is_sized = self.tcx.lang_items().sized_trait() == Some(data.trait_ref.def_id); + // Try to find possible types that would satisfy the bounds in the type param to // give an appropriate turbofish suggestion. let turbofish_suggestions = @@ -1516,11 +1513,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { body_id, span, subst, - ErrorCode::E0283, + if is_sized { ErrorCode::E0282 } else { ErrorCode::E0283 }, &turbofish_suggestions, ); - err.note(&format!("cannot satisfy `{}`", predicate)); - + if !is_sized { + err.note(&format!("cannot satisfy `{}`", predicate)); + } if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { self.suggest_fully_qualified_path( &mut err, @@ -1600,6 +1598,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } } } + if is_sized { + err.emit(); + return; + } err } diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs index b5fee061f277e..4f160fccc0113 100644 --- a/src/test/ui/async-await/issues/issue-65159.rs +++ b/src/test/ui/async-await/issues/issue-65159.rs @@ -5,6 +5,7 @@ async fn copy() -> Result<()> //~ ERROR wrong number of type arguments { Ok(()) + //~^ ERROR type annotations needed } fn main() { } diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr index 56d2c38b302e9..04cfa5249982e 100644 --- a/src/test/ui/async-await/issues/issue-65159.stderr +++ b/src/test/ui/async-await/issues/issue-65159.stderr @@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1 LL | async fn copy() -> Result<()> | ^^^^^^^^^^ expected 2 type arguments -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/issue-65159.rs:7:5 + | +LL | Ok(()) + | ^^ cannot infer type for type parameter `E` declared on the enum `Result` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0107, E0282. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/closures/issue-52437.rs b/src/test/ui/closures/issue-52437.rs index 02ae1f86a4ba6..f79a0bd35486a 100644 --- a/src/test/ui/closures/issue-52437.rs +++ b/src/test/ui/closures/issue-52437.rs @@ -1,5 +1,6 @@ fn main() { [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //~^ ERROR: invalid label name `'static` + //~| ERROR: type annotations needed //~| ERROR mismatched types } diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr index 34707bc6f2fa1..54825cb746d42 100644 --- a/src/test/ui/closures/issue-52437.stderr +++ b/src/test/ui/closures/issue-52437.stderr @@ -4,6 +4,12 @@ error: invalid label name `'static` LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^^^^^^^ +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 + error[E0308]: mismatched types --> $DIR/issue-52437.rs:2:5 | @@ -12,6 +18,7 @@ LL | fn main() { LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[(); _]` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/consts/issue-52432.rs b/src/test/ui/consts/issue-52432.rs index eba4cde614b3b..d719bf1b97161 100644 --- a/src/test/ui/consts/issue-52432.rs +++ b/src/test/ui/consts/issue-52432.rs @@ -3,6 +3,7 @@ fn main() { [(); &(static |x| {}) as *const _ as usize]; //~^ ERROR: closures cannot be static + //~| ERROR: type annotations needed [(); &(static || {}) as *const _ as usize]; //~^ ERROR: closures cannot be static //~| ERROR evaluation of constant value failed diff --git a/src/test/ui/consts/issue-52432.stderr b/src/test/ui/consts/issue-52432.stderr index b53590551f72b..e9539d24118a0 100644 --- a/src/test/ui/consts/issue-52432.stderr +++ b/src/test/ui/consts/issue-52432.stderr @@ -5,18 +5,24 @@ LL | [(); &(static |x| {}) as *const _ as usize]; | ^^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/issue-52432.rs:6:12 + --> $DIR/issue-52432.rs:7:12 | LL | [(); &(static || {}) as *const _ as usize]; | ^^^^^^^^^ +error[E0282]: type annotations needed + --> $DIR/issue-52432.rs:4:20 + | +LL | [(); &(static |x| {}) as *const _ as usize]; + | ^ consider giving this closure parameter a type + error[E0080]: evaluation of constant value failed - --> $DIR/issue-52432.rs:6:10 + --> $DIR/issue-52432.rs:7:10 | LL | [(); &(static || {}) as *const _ as usize]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0080, E0697. +Some errors have detailed explanations: E0080, E0282, E0697. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/issue-64662.rs b/src/test/ui/consts/issue-64662.rs index ee583ab7722d8..e3a8c85830f73 100644 --- a/src/test/ui/consts/issue-64662.rs +++ b/src/test/ui/consts/issue-64662.rs @@ -1,6 +1,6 @@ enum Foo { A = foo(), //~ ERROR: type annotations needed - B = foo(), // We don't emit an error here, but if the one above is fixed, we will. + B = foo(), //~ ERROR: type annotations needed } const fn foo() -> isize { diff --git a/src/test/ui/consts/issue-64662.stderr b/src/test/ui/consts/issue-64662.stderr index c6eb63f7079a5..be754ff78feed 100644 --- a/src/test/ui/consts/issue-64662.stderr +++ b/src/test/ui/consts/issue-64662.stderr @@ -3,7 +3,23 @@ error[E0282]: type annotations needed | LL | A = foo(), | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: consider specifying the type argument in the function call + | +LL | A = foo::(), + | ^^^^^ + +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` + | +help: consider specifying the type argument in the function call + | +LL | B = foo::(), + | ^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 5ed90978117b5..3d92d18e77ffe 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -32,16 +32,12 @@ LL | fn helper(sel: &Self) -> u8 { | use of generic parameter from outer function | use a type here instead -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/E0401.rs:11:5 | -LL | fn bfnr, W: Fn()>(y: T) { - | ------ required by this bound in `bfnr` -... LL | bfnr(x); - | ^^^^ cannot infer type for type parameter `V` declared on the function `bfnr` + | ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr` | - = note: cannot satisfy `_: Baz<_>` help: consider specifying the type arguments in the function call | LL | bfnr::(x); @@ -49,5 +45,5 @@ LL | bfnr::(x); error: aborting due to 4 previous errors -Some errors have detailed explanations: E0283, E0401. -For more information about an error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0282, E0401. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs index 43a005db9dc45..1099edd848b28 100644 --- a/src/test/ui/error-codes/E0661.rs +++ b/src/test/ui/error-codes/E0661.rs @@ -3,7 +3,7 @@ #![feature(llvm_asm)] fn main() { - let a; + let a; //~ ERROR type annotations needed llvm_asm!("nop" : "r"(a)); //~^ ERROR E0661 } diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr index c93e60a7181f5..2cb6b216e7607 100644 --- a/src/test/ui/error-codes/E0661.stderr +++ b/src/test/ui/error-codes/E0661.stderr @@ -4,6 +4,18 @@ error[E0661]: output operand constraint lacks '=' or '+' LL | llvm_asm!("nop" : "r"(a)); | ^^^ -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/E0661.rs:6:9 + | +LL | let a; + | ^ cannot infer type + | +help: consider giving this binding a type + | +LL | let a: Type; + | ^^^^^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0661`. +Some errors have detailed explanations: E0282, E0661. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/for/for-loop-unconstrained-element-type.stderr b/src/test/ui/for/for-loop-unconstrained-element-type.stderr index 2f5f4666e370a..cba9fbd5cf4de 100644 --- a/src/test/ui/for/for-loop-unconstrained-element-type.stderr +++ b/src/test/ui/for/for-loop-unconstrained-element-type.stderr @@ -5,7 +5,7 @@ LL | for i in Vec::new() { } | ^^^^^^^^-- | | | the element type for this iterator is not specified - | cannot infer type for type parameter `T` declared on the struct `Vec` + | cannot infer type for type parameter `T` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index b85ec65358401..6e5ddbbf96425 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -8,6 +8,10 @@ help: consider giving this binding the explicit type `&T`, where the type parame | LL | let &v: &T = new(); | ^^^^ +help: consider specifying the type argument in the function call + | +LL | let &v = new::(); + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 9cce75bf14189..811ed48dd6b20 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -8,6 +8,10 @@ help: consider giving this binding the explicit type `&T`, where the type parame | LL | let &v: &T = new(); | ^^^^ +help: consider specifying the type arguments in the function call + | +LL | let &v = new::<'r, T>(); + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16966.stderr b/src/test/ui/issues/issue-16966.stderr index 80ee6b8ca2319..30932a375b1f0 100644 --- a/src/test/ui/issues/issue-16966.stderr +++ b/src/test/ui/issues/issue-16966.stderr @@ -1,17 +1,11 @@ -error[E0283]: type annotations needed +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` - | - ::: $SRC_DIR/std/src/panicking.rs:LL:COL | -LL | pub fn begin_panic(msg: M) -> ! { - | ---- required by this bound in `begin_panic` - | - = note: cannot satisfy `_: Send` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index a45f21c73d6a3..9bbbb4b3d6bee 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -11,13 +11,12 @@ LL | x = |c| c + 1; = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object -error[E0284]: type annotations needed for `fn(_) -> _` - --> $DIR/issue-24036.rs:9:20 +error[E0282]: type annotations needed for `fn(_) -> _` + --> $DIR/issue-24036.rs:9:18 | LL | 1 => |c| c + 1, - | ^ cannot infer type + | ^ cannot infer type | - = note: cannot satisfy `<_ as Add>::Output == _` help: consider giving this binding the explicit type `fn(_) -> _`, with the type parameters specified | LL | let x: fn(_) -> _ = match 1usize { @@ -25,5 +24,5 @@ LL | let x: fn(_) -> _ = match 1usize { error: aborting due to 2 previous errors -Some errors have detailed explanations: E0284, E0308. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index b4ec239085144..e28201d75c426 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed for `(Sender>, std::sync::mpsc::Receiver>)` - --> $DIR/issue-25368.rs:11:27 + --> $DIR/issue-25368.rs:11:17 | LL | tx.send(Foo{ foo: PhantomData }); - | ^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `PhantomData` + | ^^^ cannot infer type for type parameter `T` declared on the struct `Foo` | help: consider giving this binding the explicit type `(Sender>, std::sync::mpsc::Receiver>)`, where the type parameter `T` is specified | diff --git a/src/test/ui/issues/issue-47486-2.rs b/src/test/ui/issues/issue-47486-2.rs deleted file mode 100644 index 20e6a95e70bc3..0000000000000 --- a/src/test/ui/issues/issue-47486-2.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - [0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed -} diff --git a/src/test/ui/issues/issue-47486-2.stderr b/src/test/ui/issues/issue-47486-2.stderr deleted file mode 100644 index 629983e4d724e..0000000000000 --- a/src/test/ui/issues/issue-47486-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-47486-2.rs:2:31 - | -LL | [0u8; std::mem::size_of::<_>()]; - | ^ cannot infer type - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-47486.rs b/src/test/ui/issues/issue-47486.rs index a8b7bfc3ffca7..d686f02a9fe39 100644 --- a/src/test/ui/issues/issue-47486.rs +++ b/src/test/ui/issues/issue-47486.rs @@ -1,3 +1,4 @@ fn main() { () < std::mem::size_of::<_>(); //~ ERROR: mismatched types + [0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed } diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index 719bc68ed01e0..cf95d309c6344 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -4,6 +4,13 @@ error[E0308]: mismatched types LL | () < std::mem::size_of::<_>(); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `usize` -error: aborting due to previous error +error[E0282]: type annotations needed + --> $DIR/issue-47486.rs:3:11 + | +LL | [0u8; std::mem::size_of::<_>()]; + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-6458-3.stderr b/src/test/ui/issues/issue-6458-3.stderr index a71c159db0b0e..162a94bffe698 100644 --- a/src/test/ui/issues/issue-6458-3.stderr +++ b/src/test/ui/issues/issue-6458-3.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | mem::transmute(0); | ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute` + | +help: consider specifying the type arguments in the function call + | +LL | mem::transmute::(0); + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-6458.stderr b/src/test/ui/issues/issue-6458.stderr index f1a982616a4a1..671624c57dbcf 100644 --- a/src/test/ui/issues/issue-6458.stderr +++ b/src/test/ui/issues/issue-6458.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | foo(TypeWithState(marker::PhantomData)); | ^^^ cannot infer type for type parameter `State` declared on the function `foo` + | +help: consider specifying the type argument in the function call + | +LL | foo::(TypeWithState(marker::PhantomData)); + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-66706.rs b/src/test/ui/issues/issue-66706.rs index a1ba99cffe207..4585bcc8cd57f 100644 --- a/src/test/ui/issues/issue-66706.rs +++ b/src/test/ui/issues/issue-66706.rs @@ -1,6 +1,7 @@ fn a() { [0; [|_: _ &_| ()].len()] //~^ ERROR expected `,`, found `&` + //~| ERROR type annotations needed //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr index 9b960f1c0a339..f0b93ac91111a 100644 --- a/src/test/ui/issues/issue-66706.stderr +++ b/src/test/ui/issues/issue-66706.stderr @@ -7,13 +7,13 @@ LL | [0; [|_: _ &_| ()].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:8:20 + --> $DIR/issue-66706.rs:9:20 | LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; | ^ expected identifier, found reserved identifier error: expected `,`, found `&` - --> $DIR/issue-66706.rs:13:17 + --> $DIR/issue-66706.rs:14:17 | LL | [0; [|&_: _ &_| {}; 0 ].len()] | -^ expected `,` @@ -21,11 +21,17 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:19:26 + --> $DIR/issue-66706.rs:20:26 | LL | [0; match [|f @ &ref _| () ] {} ] | ^ expected identifier, found reserved identifier +error[E0282]: type annotations needed + --> $DIR/issue-66706.rs:2:11 + | +LL | [0; [|_: _ &_| ()].len()] + | ^ consider giving this closure parameter a type + error[E0308]: mismatched types --> $DIR/issue-66706.rs:2:5 | @@ -35,7 +41,7 @@ LL | [0; [|_: _ &_| ()].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` error[E0308]: mismatched types - --> $DIR/issue-66706.rs:13:5 + --> $DIR/issue-66706.rs:14:5 | LL | fn c() { | - help: try adding a return type: `-> [{integer}; _]` @@ -43,13 +49,14 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` error[E0308]: mismatched types - --> $DIR/issue-66706.rs:19:5 + --> $DIR/issue-66706.rs:20:5 | LL | fn d() { | - help: try adding a return type: `-> [{integer}; _]` LL | [0; match [|f @ &ref _| () ] {} ] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` -error: aborting due to 7 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr index 430fa33bc33cd..30c638391a459 100644 --- a/src/test/ui/match/match-unresolved-one-arm.stderr +++ b/src/test/ui/match/match-unresolved-one-arm.stderr @@ -8,6 +8,10 @@ help: consider giving this binding a type | LL | let x: Type = match () { | ^^^^^^ +help: consider specifying the type argument in the function call + | +LL | () => foo::() + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 7d7c64c57eb84..28212d70bb32e 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` + | ^^^^^^^^ cannot infer type for type parameter `T` | help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified | diff --git a/src/test/ui/missing/missing-items/missing-type-parameter.stderr b/src/test/ui/missing/missing-items/missing-type-parameter.stderr index 1219badc5b3fc..baf9b2f9f3e58 100644 --- a/src/test/ui/missing/missing-items/missing-type-parameter.stderr +++ b/src/test/ui/missing/missing-items/missing-type-parameter.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `X` declared on the function `foo` + | +help: consider specifying the type argument in the function call + | +LL | foo::(); + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs index 3f81b38c29f8f..87222ef4b5924 100644 --- a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -17,6 +17,7 @@ mod b { //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed } } @@ -27,6 +28,7 @@ mod c { //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed } } diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr index cec8fe3887dfc..f20ec75535354 100644 --- a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -17,7 +17,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -44,7 +44,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -71,7 +71,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -98,7 +98,7 @@ LL | V = [Vec::new; { [].len() ].len() as isize, | closing delimiter possibly meant for this error: mismatched closing delimiter: `]` - --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:25:36 + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 | LL | V = [Vec::new; { [0].len() ].len() as isize, | - - ^ mismatched closing delimiter @@ -106,5 +106,18 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, | | unclosed delimiter | closing delimiter possibly meant for this -error: aborting due to 12 previous errors +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | ^^^ cannot infer type for type parameter `T` + +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` + +error: aborting due to 14 previous errors +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 506c2301681c8..84552f2e73315 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -31,6 +31,7 @@ fn rest_patterns() { // Ident patterns: let x @ ..; //~ ERROR `..` patterns are not allowed here + //~^ ERROR type annotations needed let ref x @ ..; //~ ERROR `..` patterns are not allowed here let ref mut x @ ..; //~ ERROR `..` patterns are not allowed here diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index 1e26980cc23c3..678029b3ef369 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -59,7 +59,7 @@ LL | let x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:34:17 + --> $DIR/rest-pat-semantic-disallowed.rs:35:17 | LL | let ref x @ ..; | ^^ @@ -67,7 +67,7 @@ LL | let ref x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:35:21 + --> $DIR/rest-pat-semantic-disallowed.rs:36:21 | LL | let ref mut x @ ..; | ^^ @@ -75,7 +75,7 @@ LL | let ref mut x @ ..; = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:42:9 + --> $DIR/rest-pat-semantic-disallowed.rs:43:9 | LL | .., | -- previously used here @@ -83,7 +83,7 @@ LL | .., | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:43:9 + --> $DIR/rest-pat-semantic-disallowed.rs:44:9 | LL | .., | -- previously used here @@ -92,7 +92,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple pattern - --> $DIR/rest-pat-semantic-disallowed.rs:48:9 + --> $DIR/rest-pat-semantic-disallowed.rs:49:9 | LL | .., | -- previously used here @@ -101,7 +101,7 @@ LL | .. | ^^ can only be used once per tuple pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:58:9 + --> $DIR/rest-pat-semantic-disallowed.rs:59:9 | LL | .., | -- previously used here @@ -109,7 +109,7 @@ LL | .., | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:59:9 + --> $DIR/rest-pat-semantic-disallowed.rs:60:9 | LL | .., | -- previously used here @@ -118,7 +118,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per tuple struct pattern - --> $DIR/rest-pat-semantic-disallowed.rs:64:9 + --> $DIR/rest-pat-semantic-disallowed.rs:65:9 | LL | .., | -- previously used here @@ -127,7 +127,7 @@ LL | .. | ^^ can only be used once per tuple struct pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:72:9 + --> $DIR/rest-pat-semantic-disallowed.rs:73:9 | LL | .., | -- previously used here @@ -135,7 +135,7 @@ LL | .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:73:9 + --> $DIR/rest-pat-semantic-disallowed.rs:74:9 | LL | .., | -- previously used here @@ -144,7 +144,7 @@ LL | .. | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:77:17 + --> $DIR/rest-pat-semantic-disallowed.rs:78:17 | LL | .., | -- previously used here @@ -152,7 +152,7 @@ LL | ref x @ .., | ^^ can only be used once per slice pattern error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:78:21 + --> $DIR/rest-pat-semantic-disallowed.rs:79:21 | LL | .., | -- previously used here @@ -161,7 +161,7 @@ LL | ref mut y @ .., | ^^ can only be used once per slice pattern error: `..` patterns are not allowed here - --> $DIR/rest-pat-semantic-disallowed.rs:79:18 + --> $DIR/rest-pat-semantic-disallowed.rs:80:18 | LL | (ref z @ ..), | ^^ @@ -169,7 +169,7 @@ LL | (ref z @ ..), = note: only allowed in tuple, tuple struct, and slice patterns error: `..` can only be used once per slice pattern - --> $DIR/rest-pat-semantic-disallowed.rs:80:9 + --> $DIR/rest-pat-semantic-disallowed.rs:81:9 | LL | .., | -- previously used here @@ -185,5 +185,17 @@ LL | fn foo(..: u8) {} | = note: only allowed in tuple, tuple struct, and slice patterns -error: aborting due to 22 previous errors +error[E0282]: type annotations needed + --> $DIR/rest-pat-semantic-disallowed.rs:33:9 + | +LL | let x @ ..; + | ^^^^^^ cannot infer type + | +help: consider giving this binding a type + | +LL | let x @ ..: Type; + | ^^^^^^ + +error: aborting due to 23 previous errors +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr index 480d0554a3974..b93664aa16204 100644 --- a/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr +++ b/src/test/ui/suggestions/appropriate-type-param-turbofish.stderr @@ -222,17 +222,16 @@ LL | let y: BinaryHeap = x.into_iter().collect(); | ^^^^^^^^^^^^^^^ and 6 other candidates -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:89:15 | LL | let _ = I.foo(); | ^^^ cannot infer type for type parameter `T` declared on the associated function `foo` | - = note: cannot satisfy `_: Bar<_>` -help: consider giving this binding the explicit type `K` +help: consider giving this binding a type | -LL | let _: K = I.foo(); - | ^^^^^^^^ +LL | let _: Type = I.foo(); + | ^^^^^^ error[E0283]: type annotations needed --> $DIR/appropriate-type-param-turbofish.rs:96:5 @@ -251,4 +250,5 @@ LL | bak::(); error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0283`. +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr index baaa5bcc57842..1b8756cb23de3 100644 --- a/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr +++ b/src/test/ui/suggestions/fn-needing-specified-return-type-param.stderr @@ -8,6 +8,10 @@ help: consider giving this binding the explicit type `fn() -> A`, where the type | LL | let _: fn() -> A = f; | ^^^^^^^^^^^ +help: consider specifying the type argument in the function call + | +LL | let _ = f::; + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr index 9f5caf1d9f74d..04400ff1893ee 100644 --- a/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr @@ -1,20 +1,14 @@ -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/traits-multidispatch-convert-ambig-dest.rs:26:5 | -LL | fn test(_: T, _: U) - | ---- required by a bound in this -LL | where T : Convert - | ---------- required by this bound in `test` -... LL | test(22, std::default::Default::default()); - | ^^^^ cannot infer type for type `i32` + | ^^^^ cannot infer type for type parameter `U` declared on the function `test` | - = note: cannot satisfy `i32: Convert<_>` help: consider specifying the type arguments in the function call | -LL | test::(22, std::default::Default::default()); - | ^^^^^^^ +LL | test::(22, std::default::Default::default()); + | ^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/sort_by_key.stderr b/src/test/ui/type-inference/sort_by_key.stderr index 9ae3b89c30bde..0b6630ec89423 100644 --- a/src/test/ui/type-inference/sort_by_key.stderr +++ b/src/test/ui/type-inference/sort_by_key.stderr @@ -1,22 +1,14 @@ -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/sort_by_key.rs:3:9 | LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); | ^^^^^^^^^^^ cannot infer type for type parameter `K` declared on the associated function `sort_by_key` | - = note: cannot satisfy `_: Ord` help: consider specifying the type argument in the method call | -LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); - | ^^^^^^^^^^ -LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); +LL | lst.sort_by_key(|&(v, _)| v.iter().sum::()); | ^^^^^ -LL | lst.sort_by_key(|&(v, _)| v.iter().sum::<()>()); - | ^^^^^^ -LL | lst.sort_by_key(|&(v, _)| v.iter().sum::<*const T>()); - | ^^^^^^^^^^^^ - and 99 other candidates error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr index d60ca4a49325c..c02cd65c49623 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: consider specifying the type arguments in the function call + | +LL | foo::(); + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr index 45d879d8d5670..4e0f2be1b112e 100644 --- a/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr +++ b/src/test/ui/type-inference/unbounded-type-param-in-fn.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | foo(); | ^^^ cannot infer type for type parameter `T` declared on the function `foo` + | +help: consider specifying the type argument in the function call + | +LL | foo::(); + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 3016b82494082..0b8a1f2670e58 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | ^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` + | ^^^^^^ cannot infer type for type parameter `T` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index f4aa6da47a67c..78128a266ef2d 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `(Vec,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` + | ^^^^^^ cannot infer type for type parameter `T` | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) help: consider giving this binding the explicit type `(Vec,)`, where the type parameter `T` is specified diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr index efbe3c2eddf5e..5971f56c97f7d 100644 --- a/src/test/ui/type/type-check/unknown_type_for_closure.stderr +++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr @@ -1,13 +1,8 @@ -error[E0282]: type annotations needed for the closure `fn(_) -> ()` - --> $DIR/unknown_type_for_closure.rs:2:13 +error[E0282]: type annotations needed + --> $DIR/unknown_type_for_closure.rs:2:14 | LL | let x = |_| { }; - | ^^^^^^^^^^ cannot infer type for closure `[closure@$DIR/unknown_type_for_closure.rs:2:13: 2:23]` - | -help: give this closure an explicit return type without `_` placeholders - | -LL | let x = |_| -> () { }; - | ^^^^^ + | ^ consider giving this closure parameter a type error: aborting due to previous error diff --git a/src/test/ui/type/type-path-err-node-types-2.stderr b/src/test/ui/type/type-path-err-node-types-2.stderr index a9f70cc718ec7..b7ddf24df1f54 100644 --- a/src/test/ui/type/type-path-err-node-types-2.stderr +++ b/src/test/ui/type/type-path-err-node-types-2.stderr @@ -1,13 +1,8 @@ -error[E0282]: type annotations needed for the closure `fn(_, _) -> i32` - --> $DIR/type-path-err-node-types-2.rs:7:13 +error[E0282]: type annotations needed + --> $DIR/type-path-err-node-types-2.rs:7:14 | LL | let _ = |a, b: _| -> _ { 0 }; - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for closure `[closure@$DIR/type-path-err-node-types-2.rs:7:13: 7:33]` - | -help: give this closure an explicit return type without `_` placeholders - | -LL | let _ = |a, b: _| -> i32 { 0 }; - | ^^^ + | ^ consider giving this closure parameter a type error: aborting due to previous error diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index fa76eeb3b799b..2c8b1e76b1b82 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -127,6 +127,7 @@ pub fn main() { fn fn_test11(_: _) -> (_, _) { panic!() } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR type annotations needed fn fn_test12(x: i32) -> (_, _) { (x, x) } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 9e8eef7a6c030..ecb74fa73f496 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:153:18 + --> $DIR/typeck_type_placeholder_item.rs:154:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:156:16 + --> $DIR/typeck_type_placeholder_item.rs:157:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:166:19 + --> $DIR/typeck_type_placeholder_item.rs:167:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:166:22 + --> $DIR/typeck_type_placeholder_item.rs:167:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:19 + --> $DIR/typeck_type_placeholder_item.rs:172:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:204:5 + --> $DIR/typeck_type_placeholder_item.rs:205:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,7 +37,7 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:166:22 + --> $DIR/typeck_type_placeholder_item.rs:167:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -313,6 +313,12 @@ LL | LL | b: (T, T), | +error[E0282]: type annotations needed + --> $DIR/typeck_type_placeholder_item.rs:128:27 + | +LL | fn fn_test11(_: _) -> (_, _) { panic!() } + | ^^^^^^ cannot infer type + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:128:28 | @@ -322,7 +328,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:131:30 + --> $DIR/typeck_type_placeholder_item.rs:132:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -332,7 +338,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:134:33 + --> $DIR/typeck_type_placeholder_item.rs:135:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -341,7 +347,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:153:21 + --> $DIR/typeck_type_placeholder_item.rs:154:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -352,7 +358,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:158:15 + --> $DIR/typeck_type_placeholder_item.rs:159:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -365,13 +371,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:161:34 + --> $DIR/typeck_type_placeholder_item.rs:162:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:166:25 + --> $DIR/typeck_type_placeholder_item.rs:167:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -382,7 +388,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:171:25 + --> $DIR/typeck_type_placeholder_item.rs:172:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -393,19 +399,19 @@ LL | struct BadStruct2(U, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:175:14 + --> $DIR/typeck_type_placeholder_item.rs:176:14 | LL | type X = Box<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:181:21 + --> $DIR/typeck_type_placeholder_item.rs:182:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:139:31 + --> $DIR/typeck_type_placeholder_item.rs:140:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -416,7 +422,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:141:31 + --> $DIR/typeck_type_placeholder_item.rs:142:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -429,7 +435,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:143:31 + --> $DIR/typeck_type_placeholder_item.rs:144:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -440,7 +446,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:145:26 + --> $DIR/typeck_type_placeholder_item.rs:146:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -451,7 +457,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:147:26 + --> $DIR/typeck_type_placeholder_item.rs:148:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -464,7 +470,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:149:28 + --> $DIR/typeck_type_placeholder_item.rs:150:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -475,19 +481,19 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:189:14 + --> $DIR/typeck_type_placeholder_item.rs:190:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:191:14 + --> $DIR/typeck_type_placeholder_item.rs:192:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:193:14 + --> $DIR/typeck_type_placeholder_item.rs:194:14 | LL | const D: _ = 42; | ^ @@ -496,7 +502,7 @@ LL | const D: _ = 42; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:196:26 + --> $DIR/typeck_type_placeholder_item.rs:197:26 | LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures @@ -582,25 +588,25 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:200:14 + --> $DIR/typeck_type_placeholder_item.rs:201:14 | LL | type A = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:202:14 + --> $DIR/typeck_type_placeholder_item.rs:203:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:204:14 + --> $DIR/typeck_type_placeholder_item.rs:205:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:207:14 + --> $DIR/typeck_type_placeholder_item.rs:208:14 | LL | const D: _ = 42; | ^ @@ -608,7 +614,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 66 previous errors +error: aborting due to 67 previous errors -Some errors have detailed explanations: E0121, E0403. +Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/unconstrained-ref.stderr b/src/test/ui/unconstrained-ref.stderr index bace41580a896..eb8ebb5165d18 100644 --- a/src/test/ui/unconstrained-ref.stderr +++ b/src/test/ui/unconstrained-ref.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/unconstrained-ref.rs:6:13 + --> $DIR/unconstrained-ref.rs:6:5 | LL | S { o: &None }; - | ^^^^ cannot infer type for type parameter `T` declared on the enum `Option` + | ^ cannot infer type for type parameter `T` declared on the struct `S` error: aborting due to previous error diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index dea532b32e4ee..a45ac324f4a6b 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `Vec` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `Vec` + | ^^^^^^^^ cannot infer type for type parameter `T` | help: consider giving this binding the explicit type `Vec`, where the type parameter `T` is specified | From 0d3f077ac723e2c679cadb97661d66f928ae0cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Oct 2020 19:31:11 -0700 Subject: [PATCH 14/17] Skip lifetimes in turbofish suggestions --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 5 +++++ src/test/ui/issues/issue-12187-2.stderr | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index c285fcd13239b..3631f710560dd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1571,6 +1571,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { generics .params .iter() + // Do not suggest `foo::<'a, T>()` + .filter(|p| !matches!( + p.kind, + ty::GenericParamDefKind::Lifetime + )) .map(|p| p.name.to_string()) .collect::>() .join(", ") diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 811ed48dd6b20..b01d5dc72b16f 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -10,8 +10,8 @@ LL | let &v: &T = new(); | ^^^^ help: consider specifying the type arguments in the function call | -LL | let &v = new::<'r, T>(); - | ^^^^^^^^^ +LL | let &v = new::(); + | ^^^^^ error: aborting due to previous error From 1ae1a1347280351dc31ce0628558b5d5bce2db97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Oct 2020 18:18:29 -0700 Subject: [PATCH 15/17] Fix new ICE caused by derred arg `Sized` check --- compiler/rustc_typeck/src/check/check.rs | 6 +---- src/test/ui/closures/issue-41366.stderr | 22 +++++++++---------- .../typeck_type_placeholder_item.stderr | 4 ++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index f59842eea6e75..3d8653b4a6a47 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -131,11 +131,7 @@ pub(super) fn check_fn<'a, 'tcx>( // for simple cases like `fn foo(x: Trait)`, // where we would error once on the parameter as a whole, and once on the binding `x`. if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals { - fcx.require_type_is_sized_deferred( - param_ty, - param.pat.span, - traits::SizedArgumentType(ty_span), - ); + fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span)); } fcx.write_ty(param.hir_id, param_ty); diff --git a/src/test/ui/closures/issue-41366.stderr b/src/test/ui/closures/issue-41366.stderr index 1072a626c2ad1..200d411b51194 100644 --- a/src/test/ui/closures/issue-41366.stderr +++ b/src/test/ui/closures/issue-41366.stderr @@ -1,3 +1,14 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-41366.rs:10:5 + | +LL | (&|_| ()) as &dyn for<'x> Fn(>::V); + | ^^------^ + | | | + | | found signature of `fn(u16) -> _` + | expected signature of `fn(>::V) -> _` + | + = note: required for the cast to the object type `dyn for<'x> Fn(>::V)` + error[E0277]: the size for values of type `>::V` cannot be known at compilation time --> $DIR/issue-41366.rs:10:8 | @@ -15,17 +26,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | (&|&_| ()) as &dyn for<'x> Fn(>::V); | ^ -error[E0631]: type mismatch in closure arguments - --> $DIR/issue-41366.rs:10:5 - | -LL | (&|_| ()) as &dyn for<'x> Fn(>::V); - | ^^------^ - | | | - | | found signature of `fn(u16) -> _` - | expected signature of `fn(>::V) -> _` - | - = note: required for the cast to the object type `dyn for<'x> Fn(>::V)` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0631. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index ecb74fa73f496..684f451b7c3f6 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -314,10 +314,10 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:128:27 + --> $DIR/typeck_type_placeholder_item.rs:128:18 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } - | ^^^^^^ cannot infer type + | ^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:128:28 From f26b748303f1795c86f4ee331551af8b8d0457ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 15 Oct 2020 22:50:50 -0700 Subject: [PATCH 16/17] Suggest `&[_]` instead of `&[_; N]` on inference error --- .../src/infer/error_reporting/need_type_info.rs | 17 +++++++++++++---- src/test/ui/issues/issue-7813.stderr | 8 ++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 96855fb6bba30..9c7802cfef2fd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -366,12 +366,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { None }; printer.name_resolver = Some(Box::new(&getter)); - let _ = if let ty::FnDef(..) = ty.kind() { + let _ = 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.fn_sig(self.tcx).print(printer) - } else { - ty.print(printer) + ty::FnDef(..) => ty.fn_sig(self.tcx).print(printer), + ty::Ref(_, ref_ty, mutability) => { + match ref_ty.kind() { + ty::Array(ty, _) => { + // Do not suggest `&[_; 0]`, instead suggest `&[_]`. + let _ = ty.print(printer); + return format!("&{}[{}]", mutability.prefix_str(), s); + } + _ => ty.print(printer), + } + } + _ => ty.print(printer), }; s }; diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 96a967c7a7712..7fb82a71ffedf 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -1,13 +1,13 @@ -error[E0282]: type annotations needed for `&[_; 0]` +error[E0282]: type annotations needed for `&[_]` --> $DIR/issue-7813.rs:2:13 | LL | let v = &[]; | ^^^ cannot infer type | -help: consider giving this binding the explicit type `&[_; 0]`, with the type parameters specified +help: consider giving this binding the explicit type `&[_]`, with the type parameters specified | -LL | let v: &[_; 0] = &[]; - | ^^^^^^^^^ +LL | let v: &[_] = &[]; + | ^^^^^^ error: aborting due to previous error From 654a4129159eaac624c84f2db3aaba2712e1b990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2020 13:41:00 -0700 Subject: [PATCH 17/17] Fix rebase --- ...er-vars-supply-ty-with-bound-region.stderr | 5 +++++ src/test/ui/issues/issue-23046.stderr | 5 +++++ src/test/ui/issues/issue-72690.stderr | 22 +++++-------------- src/test/ui/traits/issue-77982.stderr | 18 ++++++++++----- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr index 2005bd4dd5ca7..cd5539d2b9a6f 100644 --- a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr +++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed | LL | with_closure(|x: u32, y| {}); | ^ consider giving this closure parameter a type + | +help: consider specifying the type arguments in the function call + | +LL | with_closure::(|x: u32, y| {}); + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index 12b2eb48e7eaa..1b356e77f2f3a 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -3,6 +3,11 @@ error[E0282]: type annotations needed for `Expr<'_, VAR>` | LL | let ex = |x| { | ^ consider giving this closure parameter the explicit type `Expr<'_, VAR>`, where the type parameter `VAR` is specified + | +help: consider specifying the type arguments in the function call + | +LL | let_::(add(x,x), |y| { + | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr index a8eb3f55e3a7b..1e39bd66ee449 100644 --- a/src/test/ui/issues/issue-72690.stderr +++ b/src/test/ui/issues/issue-72690.stderr @@ -11,7 +11,7 @@ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:11:9 | LL | |x| String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for struct `String` + | ^^^^^^^^^^^^ cannot infer type for reference `&_` | = note: cannot satisfy `String: From<&_>` = note: required by `from` @@ -20,11 +20,13 @@ error[E0283]: type annotations needed for `&T` --> $DIR/issue-72690.rs:15:17 | 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 + | ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef` | = note: cannot satisfy `str: AsRef<_>` +help: consider giving this binding the explicit type `&T`, where the type parameter `T` is specified + | +LL | let _: str = "x".as_ref(); + | ^^^^^ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:19:5 @@ -61,10 +63,6 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` -help: consider giving this binding the explicit type `String` - | -LL | let _: String = String::from("x"); - | ^^^^^^^^ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:47:5 @@ -74,10 +72,6 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` -help: consider giving this binding the explicit type `String` - | -LL | let _: String = String::from("x"); - | ^^^^^^^^ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:55:5 @@ -87,10 +81,6 @@ LL | String::from("x".as_ref()); | = note: cannot satisfy `String: From<&_>` = note: required by `from` -help: consider giving this binding the explicit type `String` - | -LL | let _: String = String::from("x"); - | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index d788f1871ffac..d75b728e86078 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -23,21 +23,27 @@ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:35:16 | LL | let _ = ().foo(); - | - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo` - | | - | consider giving this pattern the explicit type `Box`, where the type parameter `T` is specified + | ^^^ cannot infer type for type parameter `T` declared on the trait `Foo` | = note: cannot satisfy `(): Foo<'_, _>` +help: consider giving this binding the explicit type `Box`, where the type parameter `T` is specified + | +LL | let _: () = ().foo(); + | ^^^^ error[E0283]: type annotations needed for `Box` --> $DIR/issue-77982.rs:39:19 | LL | let _ = (&()).bar(); - | - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar` - | | - | consider giving this pattern the explicit type `Box`, where the type parameter `T` is specified + | ^^^ cannot infer type for type parameter `T` declared on the trait `Bar` | = note: cannot satisfy `&(): Bar<'_, _>` +help: consider giving this binding the explicit type `Box`, where the type parameter `T` is specified + | +LL | let _: &'a () = (&()).bar(); + | ^^^^^^^^ +LL | let _: &'a () = (&()).bar(); + | ^^^^^^^^ error: aborting due to 4 previous errors