Use fn ptr signature instead of {closure@..} in infer error

When suggesting a type on inference error, do not use `{closure@..}`.
Instead, replace with an appropriate `fn` ptr.

On the error message, use `short_ty_string` and write long types to
disk.

```
error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>`
  --> crates/lang/src/parser.rs:41:13
   |
41 |         let lit = select! {
   |             ^^^
42 |             Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
   |                                                                                                  ---- type must be known at this point
   |
   = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt'
   = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
   |
41 |         let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! {
   |                +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```

instead of

```
error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>`
  --> crates/lang/src/parser.rs:41:13
   |
41 |         let lit = select! {
   |             ^^^
42 |             Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()),
   |                                                                                                  ---- type must be known at this point
   |
   = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan`
help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified
   |
41 |         let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! {
   |                ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```

Fix #123630.
This commit is contained in:
Esteban Küber 2024-04-10 00:11:52 +00:00
parent e78913baef
commit 796be88062
29 changed files with 98 additions and 47 deletions

View file

@ -144,6 +144,9 @@ infer_fps_items_are_distinct = fn items are distinct from fn pointers
infer_fps_remove_ref = consider removing the reference infer_fps_remove_ref = consider removing the reference
infer_fps_use_ref = consider using a reference infer_fps_use_ref = consider using a reference
infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
infer_full_type_written = the full type name has been written to '{$path}'
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
infer_label_bad = {$bad_kind -> infer_label_bad = {$bad_kind ->

View file

@ -18,6 +18,8 @@
ObligationCauseAsDiagArg, ObligationCauseAsDiagArg,
}; };
use std::path::PathBuf;
pub mod note_and_explain; pub mod note_and_explain;
#[derive(Diagnostic)] #[derive(Diagnostic)]
@ -47,6 +49,9 @@ pub struct AnnotationRequired<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic] #[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
} }
// Copy of `AnnotationRequired` for E0283 // Copy of `AnnotationRequired` for E0283
@ -65,6 +70,9 @@ pub struct AmbiguousImpl<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic] #[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
} }
// Copy of `AnnotationRequired` for E0284 // Copy of `AnnotationRequired` for E0284
@ -83,6 +91,9 @@ pub struct AmbiguousReturn<'a> {
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>, pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic] #[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>, pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
} }
// Used when a better one isn't available // Used when a better one isn't available

View file

@ -18,13 +18,15 @@
}; };
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
use rustc_middle::ty::{self, InferConst}; use rustc_middle::ty::{
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt,
use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
};
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span, DUMMY_SP};
use std::borrow::Cow; use std::borrow::Cow;
use std::iter; use std::iter;
use std::path::PathBuf;
pub enum TypeAnnotationNeeded { pub enum TypeAnnotationNeeded {
/// ```compile_fail,E0282 /// ```compile_fail,E0282
@ -153,6 +155,29 @@ fn try_get_prefix(&self) -> Option<&str> {
} }
} }
struct ClosureEraser<'tcx> {
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
match ty.kind() {
ty::Closure(_, args) => {
let closure_sig = args.as_closure().sig();
Ty::new_fn_ptr(
self.tcx,
self.tcx.signature_unclosure(closure_sig, hir::Unsafety::Normal),
)
}
_ => ty.super_fold_with(self),
}
}
}
fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> { fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
let mut printer = FmtPrinter::new(infcx.tcx, ns); let mut printer = FmtPrinter::new(infcx.tcx, ns);
let ty_getter = move |ty_vid| { let ty_getter = move |ty_vid| {
@ -209,6 +234,10 @@ fn ty_to_string<'tcx>(
) -> String { ) -> String {
let mut printer = fmt_printer(infcx, Namespace::TypeNS); let mut printer = fmt_printer(infcx, Namespace::TypeNS);
let ty = infcx.resolve_vars_if_possible(ty); let ty = infcx.resolve_vars_if_possible(ty);
// We use `fn` ptr syntax for closures, but this only works when the closure
// does not capture anything.
let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx });
match (ty.kind(), called_method_def_id) { match (ty.kind(), called_method_def_id) {
// We don't want the regular output for `fn`s because it includes its path in // 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. // invalid pseudo-syntax, we want the `fn`-pointer output instead.
@ -223,11 +252,6 @@ fn ty_to_string<'tcx>(
"Vec<_>".to_string() "Vec<_>".to_string()
} }
_ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(), _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
// FIXME: The same thing for closures, but this only works when the closure
// does not capture anything.
//
// We do have to hide the `extern "rust-call"` ABI in that case though,
// which is too much of a bother for now.
_ => { _ => {
ty.print(&mut printer).unwrap(); ty.print(&mut printer).unwrap();
printer.into_buffer() printer.into_buffer()
@ -387,6 +411,8 @@ fn bad_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label, bad_label,
was_written: None,
path: Default::default(),
}), }),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span, span,
@ -396,6 +422,8 @@ fn bad_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label, bad_label,
was_written: None,
path: Default::default(),
}), }),
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
span, span,
@ -405,6 +433,8 @@ fn bad_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label, bad_label,
was_written: None,
path: Default::default(),
}), }),
} }
} }
@ -442,7 +472,7 @@ pub fn emit_inference_failure_err(
return self.bad_inference_failure_err(failure_span, arg_data, error_code); return self.bad_inference_failure_err(failure_span, arg_data, error_code);
}; };
let (source_kind, name) = kind.ty_localized_msg(self); let (source_kind, name, path) = kind.ty_localized_msg(self);
let failure_span = if should_label_span && !failure_span.overlaps(span) { let failure_span = if should_label_span && !failure_span.overlaps(span) {
Some(failure_span) Some(failure_span)
} else { } else {
@ -518,7 +548,7 @@ pub fn emit_inference_failure_err(
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
GenericArgKind::Type(_) => self GenericArgKind::Type(_) => self
.next_ty_var(TypeVariableOrigin { .next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP, span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
}) })
.into(), .into(),
@ -526,7 +556,7 @@ pub fn emit_inference_failure_err(
.next_const_var( .next_const_var(
arg.ty(), arg.ty(),
ConstVariableOrigin { ConstVariableOrigin {
span: rustc_span::DUMMY_SP, span: DUMMY_SP,
kind: ConstVariableOriginKind::MiscVariable, kind: ConstVariableOriginKind::MiscVariable,
}, },
) )
@ -547,7 +577,7 @@ pub fn emit_inference_failure_err(
} }
InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
let placeholder = Some(self.next_ty_var(TypeVariableOrigin { let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP, span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
})); }));
if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) { if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) {
@ -584,7 +614,7 @@ pub fn emit_inference_failure_err(
} }
InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
let placeholder = Some(self.next_ty_var(TypeVariableOrigin { let placeholder = Some(self.next_ty_var(TypeVariableOrigin {
span: rustc_span::DUMMY_SP, span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
})); }));
if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) { if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) {
@ -606,6 +636,8 @@ pub fn emit_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label: None, bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}), }),
TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
span, span,
@ -615,6 +647,8 @@ pub fn emit_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label: None, bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}), }),
TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
span, span,
@ -624,6 +658,8 @@ pub fn emit_inference_failure_err(
infer_subdiags, infer_subdiags,
multi_suggestions, multi_suggestions,
bad_label: None, bad_label: None,
was_written: path.as_ref().map(|_| ()),
path: path.unwrap_or_default(),
}), }),
} }
} }
@ -688,22 +724,23 @@ fn from_expansion(&self) -> bool {
} }
impl<'tcx> InferSourceKind<'tcx> { impl<'tcx> InferSourceKind<'tcx> {
fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) { fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
let mut path = None;
match *self { match *self {
InferSourceKind::LetBinding { ty, .. } InferSourceKind::LetBinding { ty, .. }
| InferSourceKind::ClosureArg { ty, .. } | InferSourceKind::ClosureArg { ty, .. }
| InferSourceKind::ClosureReturn { ty, .. } => { | InferSourceKind::ClosureReturn { ty, .. } => {
if ty.is_closure() { if ty.is_closure() {
("closure", closure_as_fn_str(infcx, ty)) ("closure", closure_as_fn_str(infcx, ty), path)
} else if !ty.is_ty_or_numeric_infer() { } else if !ty.is_ty_or_numeric_infer() {
("normal", ty_to_string(infcx, ty, None)) ("normal", infcx.tcx.short_ty_string(ty, &mut path), path)
} else { } else {
("other", String::new()) ("other", String::new(), path)
} }
} }
// FIXME: We should be able to add some additional info here. // FIXME: We should be able to add some additional info here.
InferSourceKind::GenericArg { .. } InferSourceKind::GenericArg { .. }
| InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()), | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path),
} }
} }
} }

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Vec<T>` error[E0282]: type annotations needed for `Vec<_>`
--> $DIR/vector-no-ann.rs:2:9 --> $DIR/vector-no-ann.rs:2:9
| |
LL | let _foo = Vec::new(); LL | let _foo = Vec::new();

View file

@ -9,5 +9,5 @@ fn foo() -> Self { loop {} }
fn main() { fn main() {
let foo = Foo::<1>::foo(); let foo = Foo::<1>::foo();
let foo = Foo::foo(); let foo = Foo::foo();
//~^ error: type annotations needed for `Foo<N>` //~^ ERROR type annotations needed for `Foo<_>`
} }

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Foo<N>` error[E0282]: type annotations needed for `Foo<_>`
--> $DIR/doesnt_infer.rs:11:9 --> $DIR/doesnt_infer.rs:11:9
| |
LL | let foo = Foo::foo(); LL | let foo = Foo::foo();

View file

@ -1,4 +1,4 @@
error[E0283]: type annotations needed for `Mask<_, N>` error[E0283]: type annotations needed for `Mask<_, _>`
--> $DIR/issue-91614.rs:6:9 --> $DIR/issue-91614.rs:6:9
| |
LL | let y = Mask::<_, _>::splat(false); LL | let y = Mask::<_, _>::splat(false);

View file

@ -18,7 +18,7 @@ help: try adding a `where` bound
LL | pub const fn new() -> Self where [(); Self::SIZE]: { LL | pub const fn new() -> Self where [(); Self::SIZE]: {
| +++++++++++++++++++++++ | +++++++++++++++++++++++
error[E0282]: type annotations needed for `ArrayHolder<X>` error[E0282]: type annotations needed for `ArrayHolder<_>`
--> $DIR/issue-62504.rs:26:9 --> $DIR/issue-62504.rs:26:9
| |
LL | let mut array = ArrayHolder::new(); LL | let mut array = ArrayHolder::new();

View file

@ -22,7 +22,7 @@ note: tuple struct defined here
LL | struct ArrayHolder<const X: usize>([u32; X]); LL | struct ArrayHolder<const X: usize>([u32; X]);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error[E0282]: type annotations needed for `ArrayHolder<X>` error[E0282]: type annotations needed for `ArrayHolder<_>`
--> $DIR/issue-62504.rs:26:9 --> $DIR/issue-62504.rs:26:9
| |
LL | let mut array = ArrayHolder::new(); LL | let mut array = ArrayHolder::new();

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Option<T>` error[E0282]: type annotations needed for `Option<_>`
--> $DIR/inference-failure.rs:8:9 --> $DIR/inference-failure.rs:8:9
| |
LL | let _ = NONE; LL | let _ = NONE;

View file

@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
LL | const NONE<T = ()>: Option<T> = None::<T>; LL | const NONE<T = ()>: Option<T> = None::<T>;
| ^^^^^^ | ^^^^^^
error[E0282]: type annotations needed for `Option<T>` error[E0282]: type annotations needed for `Option<_>`
--> $DIR/parameter-defaults.rs:13:9 --> $DIR/parameter-defaults.rs:13:9
| |
LL | let _ = NONE; LL | let _ = NONE;

View file

@ -4,7 +4,7 @@ fn main() {
// error handles this gracefully, and in particular doesn't generate an extra // error handles this gracefully, and in particular doesn't generate an extra
// note about the `?` operator in the closure body, which isn't relevant to // note about the `?` operator in the closure body, which isn't relevant to
// the inference. // the inference.
let x = |r| { //~ ERROR type annotations needed for `Result<(), E>` let x = |r| { //~ ERROR type annotations needed for `Result<(), _>`
let v = r?; let v = r?;
Ok(v) Ok(v)
}; };

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Result<(), E>` error[E0282]: type annotations needed for `Result<(), _>`
--> $DIR/cannot-infer-closure-circular.rs:7:14 --> $DIR/cannot-infer-closure-circular.rs:7:14
| |
LL | let x = |r| { LL | let x = |r| {

View file

@ -1,4 +1,4 @@
error[E0283]: type annotations needed for `Foo<i32, &str, W, Z>` error[E0283]: type annotations needed for `Foo<i32, &str, _, _>`
--> $DIR/erase-type-params-in-label.rs:2:9 --> $DIR/erase-type-params-in-label.rs:2:9
| |
LL | let foo = foo(1, ""); LL | let foo = foo(1, "");
@ -15,7 +15,7 @@ help: consider giving `foo` an explicit type, where the type for type parameter
LL | let foo: Foo<i32, &str, W, Z> = foo(1, ""); LL | let foo: Foo<i32, &str, W, Z> = foo(1, "");
| ++++++++++++++++++++++ | ++++++++++++++++++++++
error[E0283]: type annotations needed for `Bar<i32, &str, Z>` error[E0283]: type annotations needed for `Bar<i32, &str, _>`
--> $DIR/erase-type-params-in-label.rs:5:9 --> $DIR/erase-type-params-in-label.rs:5:9
| |
LL | let bar = bar(1, ""); LL | let bar = bar(1, "");

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>` error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), _>, Error>>`
--> $DIR/issue-104649.rs:24:9 --> $DIR/issue-104649.rs:24:9
| |
LL | let a = A(Result::Ok(Result::Ok(()))); LL | let a = A(Result::Ok(Result::Ok(())));

View file

@ -50,7 +50,7 @@ help: try using a fully qualified path to specify the expected types
LL | |x| String::from(<str as AsRef<T>>::as_ref("x")); LL | |x| String::from(<str as AsRef<T>>::as_ref("x"));
| ++++++++++++++++++++++++++ ~ | ++++++++++++++++++++++++++ ~
error[E0283]: type annotations needed for `&T` error[E0283]: type annotations needed for `&_`
--> $DIR/issue-72690.rs:17:9 --> $DIR/issue-72690.rs:17:9
| |
LL | let _ = "x".as_ref(); LL | let _ = "x".as_ref();

View file

@ -6,5 +6,5 @@
fn main() { fn main() {
let _ = foo("foo"); let _ = foo("foo");
//~^ ERROR: type annotations needed for `[usize; N]` //~^ ERROR type annotations needed for `[usize; _]`
} }

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `[usize; N]` error[E0282]: type annotations needed for `[usize; _]`
--> $DIR/issue-83606.rs:8:9 --> $DIR/issue-83606.rs:8:9
| |
LL | let _ = foo("foo"); LL | let _ = foo("foo");

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `&T` error[E0282]: type annotations needed for `&_`
--> $DIR/issue-12187-1.rs:6:9 --> $DIR/issue-12187-1.rs:6:9
| |
LL | let &v = new(); LL | let &v = new();

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `&T` error[E0282]: type annotations needed for `&_`
--> $DIR/issue-12187-2.rs:6:9 --> $DIR/issue-12187-2.rs:6:9
| |
LL | let &v = new(); LL | let &v = new();

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `B<T>` error[E0282]: type annotations needed for `B<_>`
--> $DIR/issue-17551.rs:6:9 --> $DIR/issue-17551.rs:6:9
| |
LL | let foo = B(marker::PhantomData); LL | let foo = B(marker::PhantomData);

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Expr<'_, VAR>` error[E0282]: type annotations needed for `Expr<'_, _>`
--> $DIR/issue-23046.rs:17:15 --> $DIR/issue-23046.rs:17:15
| |
LL | let ex = |x| { LL | let ex = |x| {

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `SmallCString<N>` error[E0282]: type annotations needed for `SmallCString<_>`
--> $DIR/issue-98299.rs:4:36 --> $DIR/issue-98299.rs:4:36
| |
LL | SmallCString::try_from(p).map(|cstr| cstr); LL | SmallCString::try_from(p).map(|cstr| cstr);

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Vec<T>` error[E0282]: type annotations needed for `Vec<_>`
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:9 --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:9
| |
LL | let mut x = Vec::new(); LL | let mut x = Vec::new();

View file

@ -18,7 +18,7 @@ fn assert_impls_fn<R,T: Fn()->R>(_: &T){}
fn main() { fn main() {
let n = None; let n = None;
//~^ ERROR type annotations needed for `Option<T>` //~^ ERROR type annotations needed for `Option<_>`
let e = S(&n); let e = S(&n);
let f = || { let f = || {
// S being copy is critical for this to work // S being copy is critical for this to work

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Option<T>` error[E0282]: type annotations needed for `Option<_>`
--> $DIR/copy-guessing.rs:20:9 --> $DIR/copy-guessing.rs:20:9
| |
LL | let n = None; LL | let n = None;

View file

@ -55,7 +55,7 @@ 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(); LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
| +++++++++++++++++++++++ ~ | +++++++++++++++++++++++ ~
error[E0283]: type annotations needed for `Box<T>` error[E0283]: type annotations needed for `Box<_>`
--> $DIR/issue-77982.rs:37:9 --> $DIR/issue-77982.rs:37:9
| |
LL | let _ = ().foo(); LL | let _ = ().foo();
@ -73,7 +73,7 @@ help: consider giving this pattern a type, where the type for type parameter `T`
LL | let _: Box<T> = ().foo(); LL | let _: Box<T> = ().foo();
| ++++++++ | ++++++++
error[E0283]: type annotations needed for `Box<T>` error[E0283]: type annotations needed for `Box<_>`
--> $DIR/issue-77982.rs:41:9 --> $DIR/issue-77982.rs:41:9
| |
LL | let _ = (&()).bar(); LL | let _ = (&()).bar();

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Result<Child, F>` error[E0282]: type annotations needed for `Result<Child, _>`
--> $DIR/or_else-multiple-type-params.rs:7:18 --> $DIR/or_else-multiple-type-params.rs:7:18
| |
LL | .or_else(|err| { LL | .or_else(|err| {

View file

@ -1,4 +1,4 @@
error[E0282]: type annotations needed for `Option<T>` error[E0282]: type annotations needed for `Option<_>`
--> $DIR/unboxed-closures-failed-recursive-fn-2.rs:8:9 --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:8:9
| |
LL | let mut closure0 = None; LL | let mut closure0 = None;