Remove unnecessary code and account for turbofish suggestion
Remove previously existing fallback that tried to give a good turbofish suggestion, `need_type_info` is already good enough. Special case `::<Vec<_>` suggestion for `Iterator::collect`.
This commit is contained in:
parent
9d5e7d3c04
commit
b3fba5e18a
5 changed files with 43 additions and 87 deletions
|
@ -461,33 +461,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 {
|
||||
|
|
|
@ -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;
|
||||
|
@ -2198,60 +2198,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(_))) =
|
||||
|
|
|
@ -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);
|
||||
| +++++++++++
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
| +++++
|
||||
|
|
Loading…
Add table
Reference in a new issue