Skip to content

Suggest collecting into Vec<_> #105523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 14, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 66 additions & 38 deletions compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
use rustc_middle::ty::{self, DefIdTree, InferConst};
use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
use rustc_span::symbol::{kw, Ident};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span};
use std::borrow::Cow;
use std::iter;
@@ -79,7 +79,7 @@ impl InferenceDiagnosticsData {

fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str {
if in_type.is_ty_infer() {
"empty"
""
} else if self.name == "_" {
// FIXME: Consider specializing this message if there is a single `_`
// in the type.
@@ -183,13 +183,24 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
printer
}

fn ty_to_string<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
fn ty_to_string<'tcx>(
infcx: &InferCtxt<'tcx>,
ty: Ty<'tcx>,
called_method_def_id: Option<DefId>,
) -> String {
let printer = fmt_printer(infcx, Namespace::TypeNS);
let ty = infcx.resolve_vars_if_possible(ty);
match ty.kind() {
match (ty.kind(), called_method_def_id) {
// We don't want the regular output for `fn`s because it includes its path in
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
ty::FnDef(..) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
(ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
(_, Some(def_id))
if ty.is_ty_infer()
&& infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
{
"Vec<_>".to_string()
}
_ if ty.is_ty_infer() => "/* Type */".to_string(),
// FIXME: The same thing for closures, but this only works when the closure
// does not capture anything.
//
@@ -213,15 +224,15 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
.map(|args| {
args.tuple_fields()
.iter()
.map(|arg| ty_to_string(infcx, arg))
.map(|arg| ty_to_string(infcx, arg, None))
.collect::<Vec<_>>()
.join(", ")
})
.unwrap_or_default();
let ret = if fn_sig.output().skip_binder().is_unit() {
String::new()
} else {
format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder()))
format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None))
};
format!("fn({}){}", args, ret)
}
@@ -368,6 +379,7 @@ impl<'tcx> InferCtxt<'tcx> {
}

impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[instrument(level = "debug", skip(self, error_code))]
pub fn emit_inference_failure_err(
&self,
body_id: Option<hir::BodyId>,
@@ -406,7 +418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let mut infer_subdiags = Vec::new();
let mut multi_suggestions = Vec::new();
match kind {
InferSourceKind::LetBinding { insert_span, pattern_name, ty } => {
InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => {
infer_subdiags.push(SourceKindSubdiag::LetLike {
span: insert_span,
name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
@@ -415,7 +427,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
arg_name: arg_data.name,
kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
type_name: ty_to_string(self, ty),
type_name: ty_to_string(self, ty, def_id),
});
}
InferSourceKind::ClosureArg { insert_span, ty } => {
@@ -427,7 +439,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
arg_name: arg_data.name,
kind: "closure",
type_name: ty_to_string(self, ty),
type_name: ty_to_string(self, ty, None),
});
}
InferSourceKind::GenericArg {
@@ -456,33 +468,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
parent_name,
});

let args = fmt_printer(self, Namespace::TypeNS)
.comma_sep(generic_args.iter().copied().map(|arg| {
if arg.is_suggestable(self.tcx, true) {
return arg;
}
let args = if self.infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn)
== Some(generics_def_id)
{
"Vec<_>".to_string()
} else {
fmt_printer(self, Namespace::TypeNS)
.comma_sep(generic_args.iter().copied().map(|arg| {
if arg.is_suggestable(self.tcx, true) {
return arg;
}

match arg.unpack() {
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
GenericArgKind::Type(_) => self
.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
})
.into(),
GenericArgKind::Const(arg) => self
.next_const_var(
arg.ty(),
ConstVariableOrigin {
match arg.unpack() {
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
GenericArgKind::Type(_) => self
.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP,
kind: ConstVariableOriginKind::MiscVariable,
},
)
.into(),
}
}))
.unwrap()
.into_buffer();
kind: TypeVariableOriginKind::MiscVariable,
})
.into(),
GenericArgKind::Const(arg) => self
.next_const_var(
arg.ty(),
ConstVariableOrigin {
span: rustc_span::DUMMY_SP,
kind: ConstVariableOriginKind::MiscVariable,
},
)
.into(),
}
}))
.unwrap()
.into_buffer()
};

if !have_turbofish {
infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
@@ -520,7 +538,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
));
}
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
let ty_info = ty_to_string(self, ty);
let ty_info = ty_to_string(self, ty, None);
multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return(
ty_info,
data,
@@ -608,6 +626,7 @@ enum InferSourceKind<'tcx> {
insert_span: Span,
pattern_name: Option<Ident>,
ty: Ty<'tcx>,
def_id: Option<DefId>,
},
ClosureArg {
insert_span: Span,
@@ -662,7 +681,7 @@ impl<'tcx> InferSourceKind<'tcx> {
if ty.is_closure() {
("closure", closure_as_fn_str(infcx, ty))
} else if !ty.is_ty_infer() {
("normal", ty_to_string(infcx, ty))
("normal", ty_to_string(infcx, ty, None))
} else {
("other", String::new())
}
@@ -788,10 +807,18 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
/// Uses `fn source_cost` to determine whether this inference source is preferable to
/// previous sources. We generally prefer earlier sources.
#[instrument(level = "debug", skip(self))]
fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
let cost = self.source_cost(&new_source) + self.attempt;
debug!(?cost);
self.attempt += 1;
if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source
&& let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind
&& ty.is_ty_infer()
{
// Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
// `let x: _ = iter.collect();`, as this is a very common case.
*def_id = Some(did);
}
if cost < self.infer_source_cost {
self.infer_source_cost = cost;
self.infer_source = Some(new_source);
@@ -1089,6 +1116,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
insert_span: local.pat.span.shrink_to_hi(),
pattern_name: local.pat.simple_ident(),
ty,
def_id: None,
},
})
}
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -827,6 +827,7 @@ symbols! {
item_like_imports,
iter,
iter_repeat,
iterator_collect_fn,
kcfi,
keyword,
kind,
79 changes: 23 additions & 56 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ use rustc_middle::ty::{
};
use rustc_session::Limit;
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::symbol::{kw, sym};
use rustc_span::symbol::sym;
use rustc_span::{ExpnKind, Span, DUMMY_SP};
use std::fmt;
use std::iter;
@@ -980,6 +980,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref,
obligation.cause.body_id,
&mut err,
true,
) {
// This is *almost* equivalent to
// `obligation.cause.code().peel_derives()`, but it gives us the
@@ -1015,6 +1016,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref,
obligation.cause.body_id,
&mut err,
true,
);
}
}
@@ -1432,6 +1434,7 @@ trait InferCtxtPrivExt<'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
body_id: hir::HirId,
err: &mut Diagnostic,
other: bool,
) -> bool;

/// Gets the parent trait chain start
@@ -1887,7 +1890,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
body_id: hir::HirId,
err: &mut Diagnostic,
other: bool,
) -> bool {
let other = if other { "other " } else { "" };
let report = |mut candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
candidates.sort();
candidates.dedup();
@@ -1938,7 +1943,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
candidates.dedup();
let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
err.help(&format!(
"the following other types implement trait `{}`:{}{}",
"the following {other}types implement trait `{}`:{}{}",
trait_ref.print_only_trait_path(),
candidates[..end].join(""),
if len > 9 { format!("\nand {} others", len - 8) } else { String::new() }
@@ -2179,14 +2184,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer());
// It doesn't make sense to talk about applicable impls if there are more
// than a handful of them.
if impls.len() > 1 && impls.len() < 5 && has_non_region_infer {
if impls.len() > 1 && impls.len() < 10 && has_non_region_infer {
self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
} else {
if self.tainted_by_errors().is_some() {
err.cancel();
return;
}
err.note(&format!("cannot satisfy `{}`", predicate));
let impl_candidates = self.find_similar_impl_candidates(
predicate.to_opt_poly_trait_pred().unwrap(),
);
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
body_id.map(|id| id.hir_id).unwrap_or(obligation.cause.body_id),
&mut err,
false,
);
}
}
}
_ => {
@@ -2198,60 +2215,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}

if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
} else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
&& let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
= *obligation.cause.code()
if let ObligationCauseCode::ItemObligation(def_id)
| ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code()
{
let generics = self.tcx.generics_of(def_id);
if generics.params.iter().any(|p| p.name != kw::SelfUpper)
&& !snippet.ends_with('>')
&& !generics.has_impl_trait()
&& !self.tcx.is_fn_trait(def_id)
{
// FIXME: To avoid spurious suggestions in functions where type arguments
// where already supplied, we check the snippet to make sure it doesn't
// end with a turbofish. Ideally we would have access to a `PathSegment`
// instead. Otherwise we would produce the following output:
//
// error[E0283]: type annotations needed
// --> $DIR/issue-54954.rs:3:24
// |
// LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
// | ^^^^^^^^^^^^^^^^^^^^^^^^^^
// | |
// | cannot infer type
// | help: consider specifying the type argument
// | in the function call:
// | `Tt::const_val::<[i8; 123]>::<T>`
// ...
// LL | const fn const_val<T: Sized>() -> usize {
// | - required by this bound in `Tt::const_val`
// |
// = note: cannot satisfy `_: Tt`

// Clear any more general suggestions in favor of our specific one
err.clear_suggestions();

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::<Vec<String>>()
.join(", ")
),
Applicability::HasPlaceholders,
);
}
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
}

if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) =
1 change: 1 addition & 0 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -1829,6 +1829,7 @@ pub trait Iterator {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
#[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")]
fn collect<B: FromIterator<Self::Item>>(self) -> B
where
Self: Sized,
4 changes: 2 additions & 2 deletions src/test/ui/array-slice-vec/infer_array_len.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | let [_, _] = a.into();
|
help: consider giving this pattern a type
|
LL | let [_, _]: _ = a.into();
| +++
LL | let [_, _]: /* Type */ = a.into();
| ++++++++++++

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | with_closure(|x: u32, y| {});
|
help: consider giving this closure parameter an explicit type
|
LL | with_closure(|x: u32, y: _| {});
| +++
LL | with_closure(|x: u32, y: /* Type */| {});
| ++++++++++++

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/closures/issue-52437.stderr
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
|
help: consider giving this closure parameter an explicit type
|
LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize]
| +++
LL | [(); &(&'static: loop { |x: /* Type */| {}; }) as *const _ as usize]
| ++++++++++++

error: aborting due to 2 previous errors

Original file line number Diff line number Diff line change
@@ -5,6 +5,12 @@ LL | let y = Mask::<_, _>::splat(false);
| ^ ------------------- type must be known at this point
|
= note: cannot satisfy `_: MaskElement`
= help: the following types implement trait `MaskElement`:
i16
i32
i64
i8
isize
note: required by a bound in `Mask::<T, LANES>::splat`
--> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
|
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ LL | IsLessOrEqual<I, 8>: True,
| ^^^^
|
= note: cannot satisfy `IsLessOrEqual<I, 8>: True`
= help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`

error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual<I, 8>: True`
--> $DIR/issue-72787.rs:21:26
@@ -49,6 +50,7 @@ LL | IsLessOrEqual<I, 8>: True,
| ^^^^
|
= note: cannot satisfy `IsLessOrEqual<I, 8>: True`
= help: the trait `True` is implemented for `IsLessOrEqual<LHS, RHS>`

error: aborting due to 6 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/const-generics/issues/issue-83249.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | let _ = foo([0; 1]);
|
help: consider giving this pattern a type
|
LL | let _: _ = foo([0; 1]);
| +++
LL | let _: /* Type */ = foo([0; 1]);
| ++++++++++++

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0282.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | let x = "hello".chars().rev().collect();
|
help: consider giving `x` an explicit type
|
LL | let x: _ = "hello".chars().rev().collect();
| +++
LL | let x: Vec<_> = "hello".chars().rev().collect();
| ++++++++

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0401.stderr
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ note: required by a bound in `bfnr`
|
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
| ^^^^ required by this bound in `bfnr`
help: consider specifying the type arguments in the function call
help: consider specifying the generic arguments
|
LL | bfnr::<U, V, W>(x);
| +++++++++++
4 changes: 2 additions & 2 deletions src/test/ui/impl-trait/issues/issue-86719.stderr
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ LL | |_| true
|
help: consider giving this closure parameter an explicit type
|
LL | |_: _| true
| +++
LL | |_: /* Type */| true
| ++++++++++++

error: aborting due to 3 previous errors

12 changes: 6 additions & 6 deletions src/test/ui/inference/erase-type-params-in-label.stderr
Original file line number Diff line number Diff line change
@@ -10,10 +10,10 @@ note: required by a bound in `foo`
|
LL | fn foo<T, K, W: Default, Z: Default>(t: T, k: K) -> Foo<T, K, W, Z> {
| ^^^^^^^ required by this bound in `foo`
help: consider specifying the type arguments in the function call
help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified
|
LL | let foo = foo::<T, K, W, Z>(1, "");
| ++++++++++++++
LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
| ++++++++++++++++++++++

error[E0283]: type annotations needed for `Bar<i32, &str, Z>`
--> $DIR/erase-type-params-in-label.rs:5:9
@@ -27,10 +27,10 @@ note: required by a bound in `bar`
|
LL | fn bar<T, K, Z: Default>(t: T, k: K) -> Bar<T, K, Z> {
| ^^^^^^^ required by this bound in `bar`
help: consider specifying the type arguments in the function call
help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified
|
LL | let bar = bar::<T, K, Z>(1, "");
| +++++++++++
LL | let bar: Bar<i32, &str, Z> = bar(1, "");
| +++++++++++++++++++

error: aborting due to 2 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/inference/issue-72690.stderr
Original file line number Diff line number Diff line change
@@ -32,8 +32,8 @@ LL | |x| String::from("x".as_ref());
|
help: consider giving this closure parameter an explicit type
|
LL | |x: _| String::from("x".as_ref());
| +++
LL | |x: /* Type */| String::from("x".as_ref());
| ++++++++++++

error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:12:26
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-18159.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | let x;
|
help: consider giving `x` an explicit type
|
LL | let x: _;
| +++
LL | let x: /* Type */;
| ++++++++++++

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-2151.stderr
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ LL | x.clone();
|
help: consider giving `x` an explicit type
|
LL | let x: _ = panic!();
| +++
LL | let x: /* Type */ = panic!();
| ++++++++++++

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-24036.stderr
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@ LL | 1 => |c| c + 1,
|
help: consider giving this closure parameter an explicit type
|
LL | 1 => |c: _| c + 1,
| +++
LL | 1 => |c: /* Type */| c + 1,
| ++++++++++++

error: aborting due to 2 previous errors

16 changes: 8 additions & 8 deletions src/test/ui/lazy-type-alias-impl-trait/branches3.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | |s| s.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |s: _| s.len()
| +++
LL | |s: /* Type */| s.len()
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/branches3.rs:15:10
@@ -17,8 +17,8 @@ LL | |s| s.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |s: _| s.len()
| +++
LL | |s: /* Type */| s.len()
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/branches3.rs:23:10
@@ -28,8 +28,8 @@ LL | |s| s.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |s: _| s.len()
| +++
LL | |s: /* Type */| s.len()
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/branches3.rs:30:10
@@ -39,8 +39,8 @@ LL | |s| s.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |s: _| s.len()
| +++
LL | |s: /* Type */| s.len()
| ++++++++++++

error: aborting due to 4 previous errors

1 change: 1 addition & 0 deletions src/test/ui/lifetimes/issue-34979.stderr
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ LL | &'a (): Foo,
| ^^^
|
= note: cannot satisfy `&'a (): Foo`
= help: the trait `Foo` is implemented for `&'a T`

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/match/match-unresolved-one-arm.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | let x = match () {
|
help: consider giving `x` an explicit type
|
LL | let x: _ = match () {
| +++
LL | let x: /* Type */ = match () {
| ++++++++++++

error: aborting due to previous error

4 changes: 2 additions & 2 deletions src/test/ui/pattern/pat-tuple-bad-type.stderr
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ LL | (..) => {}
|
help: consider giving `x` an explicit type
|
LL | let x: _;
| +++
LL | let x: /* Type */;
| ++++++++++++

error[E0308]: mismatched types
--> $DIR/pat-tuple-bad-type.rs:10:9
4 changes: 2 additions & 2 deletions src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
Original file line number Diff line number Diff line change
@@ -193,8 +193,8 @@ LL | let x @ ..;
|
help: consider giving this pattern a type
|
LL | let x @ ..: _;
| +++
LL | let x @ ..: /* Type */;
| ++++++++++++

error: aborting due to 23 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/resolve/issue-85348.stderr
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@ LL | let mut N;
|
help: consider giving `N` an explicit type
|
LL | let mut N: _;
| +++
LL | let mut N: /* Type */;
| ++++++++++++

error: aborting due to 3 previous errors

8 changes: 4 additions & 4 deletions src/test/ui/span/method-and-field-eager-resolution.stderr
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ LL | x.0;
|
help: consider giving `x` an explicit type
|
LL | let mut x: _ = Default::default();
| +++
LL | let mut x: /* Type */ = Default::default();
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/method-and-field-eager-resolution.rs:11:9
@@ -23,8 +23,8 @@ LL | x[0];
|
help: consider giving `x` an explicit type
|
LL | let mut x: _ = Default::default();
| +++
LL | let mut x: /* Type */ = Default::default();
| ++++++++++++

error: aborting due to 2 previous errors

10 changes: 9 additions & 1 deletion src/test/ui/traits/issue-77982.stderr
Original file line number Diff line number Diff line change
@@ -46,7 +46,15 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
| |
| required by a bound introduced by this call
|
= note: cannot satisfy `u32: From<_>`
= note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
- impl From<Ipv4Addr> for u32;
- impl From<NonZeroU32> for u32;
- impl From<bool> for u32;
- impl From<char> for u32;
- impl From<u16> for u32;
- impl From<u8> for u32;
- impl<T> From<!> for T;
- impl<T> From<T> for T;
help: try using a fully qualified path to specify the expected types
|
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
3 changes: 3 additions & 0 deletions src/test/ui/traits/issue-85735.stderr
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ LL | T: FnMut(&'a ()),
| ^^^^^^^^^^^^^
|
= note: cannot satisfy `T: FnMut<(&'a (),)>`
= help: the following types implement trait `FnMut<Args>`:
&F
&mut F

error: aborting due to previous error

8 changes: 4 additions & 4 deletions src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@ LL | |x| x.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |x: _| x.len()
| +++
LL | |x: /* Type */| x.len()
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/closures_in_branches.rs:21:10
@@ -17,8 +17,8 @@ LL | |x| x.len()
|
help: consider giving this closure parameter an explicit type
|
LL | |x: _| x.len()
| +++
LL | |x: /* Type */| x.len()
| ++++++++++++

error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/type/type-annotation-needed.stderr
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ note: required by a bound in `foo`
|
LL | fn foo<T: Into<String>>(x: i32) {}
| ^^^^^^^^^^^^ required by this bound in `foo`
help: consider specifying the type argument in the function call
help: consider specifying the generic argument
|
LL | foo::<T>(42);
| +++++
4 changes: 2 additions & 2 deletions src/test/ui/type/type-check/unknown_type_for_closure.stderr
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ LL | let x = |_| {};
|
help: consider giving this closure parameter an explicit type
|
LL | let x = |_: _| {};
| +++
LL | let x = |_: /* Type */| {};
| ++++++++++++

error[E0282]: type annotations needed
--> $DIR/unknown_type_for_closure.rs:10:14
4 changes: 2 additions & 2 deletions src/test/ui/type/type-path-err-node-types.stderr
Original file line number Diff line number Diff line change
@@ -30,8 +30,8 @@ LL | let _ = |a, b: _| -> _ { 0 };
|
help: consider giving this closure parameter an explicit type
|
LL | let _ = |a: _, b: _| -> _ { 0 };
| +++
LL | let _ = |a: /* Type */, b: _| -> _ { 0 };
| ++++++++++++

error: aborting due to 5 previous errors