Point at overlapping impls when type annotations are needed

This commit is contained in:
Esteban Kuber 2021-10-01 13:05:17 +00:00
parent ed08a67566
commit ef212e7fb3
29 changed files with 629 additions and 88 deletions

View File

@ -440,16 +440,28 @@ pub struct DerivedObligationCause<'tcx> {
#[derive(Clone, Debug, TypeFoldable, Lift)]
pub enum SelectionError<'tcx> {
/// The trait is not implemented.
Unimplemented,
/// After a closure impl has selected, its "outputs" were evaluated
/// (which for closures includes the "input" type params) and they
/// didn't resolve. See `confirm_poly_trait_refs` for more.
OutputTypeParameterMismatch(
ty::PolyTraitRef<'tcx>,
ty::PolyTraitRef<'tcx>,
ty::error::TypeError<'tcx>,
),
/// The trait pointed by `DefId` is not object safe.
TraitNotObjectSafe(DefId),
/// A given constant couldn't be evaluated.
NotConstEvaluatable(NotConstEvaluatable),
/// Exceeded the recursion depth during type projection.
Overflow,
/// Signaling that an error has already been emitted, to avoid
/// multiple errors being shown.
ErrorReporting,
/// Multiple applicable `impl`s where found. The `DefId`s correspond to
/// all the `impl`s' Items.
Ambiguous(Vec<DefId>),
}
/// When performing resolution, it is typically the case that there

View File

@ -34,6 +34,7 @@ use std::iter;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::query::normalize::AtExt as _;
use crate::traits::specialize::to_pretty_impl_header;
use on_unimplemented::InferCtxtExt as _;
use suggestions::InferCtxtExt as _;
@ -241,6 +242,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let mut span = obligation.cause.span;
let mut err = match *error {
SelectionError::Ambiguous(ref impls) => {
let mut err = self.tcx.sess.struct_span_err(
obligation.cause.span,
&format!("multiple applicable `impl`s for `{}`", obligation.predicate),
);
self.annotate_source_of_ambiguity(&mut err, impls, obligation.predicate);
err.emit();
return;
}
SelectionError::Unimplemented => {
// If this obligation was generated as a result of well-formedness checking, see if we
// can get a better error message by performing HIR-based well-formedness checking.
@ -1138,6 +1148,13 @@ trait InferCtxtPrivExt<'tcx> {
obligation: &PredicateObligation<'tcx>,
);
fn annotate_source_of_ambiguity(
&self,
err: &mut DiagnosticBuilder<'tcx>,
impls: &[DefId],
predicate: ty::Predicate<'tcx>,
);
fn maybe_suggest_unsized_generics(
&self,
err: &mut DiagnosticBuilder<'tcx>,
@ -1549,11 +1566,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
?predicate, ?obligation.cause.code,
);
// Ambiguity errors are often caused as fallout from earlier
// errors. So just ignore them if this infcx is tainted.
if self.is_tainted_by_errors() {
return;
}
// Ambiguity errors are often caused as fallout from earlier errors.
// We ignore them if this `infcx` is tainted in some cases below.
let bound_predicate = predicate.kind();
let mut err = match bound_predicate.skip_binder() {
@ -1601,10 +1615,19 @@ 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, vec![], ErrorCode::E0282)
if !self.is_tainted_by_errors() {
self.emit_inference_failure_err(
body_id,
span,
subst,
vec![],
ErrorCode::E0282,
)
.emit();
}
return;
}
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
let mut err = self.emit_inference_failure_err(
body_id,
@ -1613,7 +1636,29 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
impl_candidates,
ErrorCode::E0283,
);
err.note(&format!("cannot satisfy `{}`", predicate));
let obligation = Obligation::new(
obligation.cause.clone(),
obligation.param_env,
trait_ref.to_poly_trait_predicate(),
);
let mut selcx = SelectionContext::with_query_mode(
&self,
crate::traits::TraitQueryMode::Standard,
);
match selcx.select_from_obligation(&obligation) {
Err(SelectionError::Ambiguous(impls)) if impls.len() > 1 => {
self.annotate_source_of_ambiguity(&mut err, &impls, predicate);
}
_ => {
if self.is_tainted_by_errors() {
err.cancel();
return;
}
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 (
@ -1674,7 +1719,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
ty::PredicateKind::WellFormed(arg) => {
// Same hacky approach as above to avoid deluging user
// with error messages.
if arg.references_error() || self.tcx.sess.has_errors() {
if arg.references_error()
|| self.tcx.sess.has_errors()
|| self.is_tainted_by_errors()
{
return;
}
@ -1682,7 +1730,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
}
ty::PredicateKind::Subtype(data) => {
if data.references_error() || self.tcx.sess.has_errors() {
if data.references_error()
|| self.tcx.sess.has_errors()
|| self.is_tainted_by_errors()
{
// no need to overload user in such cases
return;
}
@ -1694,7 +1745,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
ty::PredicateKind::Projection(data) => {
let self_ty = data.projection_ty.self_ty();
let ty = data.ty;
if predicate.references_error() {
if predicate.references_error() || self.is_tainted_by_errors() {
return;
}
if self_ty.needs_infer() && ty.needs_infer() {
@ -1722,7 +1773,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
}
_ => {
if self.tcx.sess.has_errors() {
if self.tcx.sess.has_errors() || self.is_tainted_by_errors() {
return;
}
let mut err = struct_span_err!(
@ -1740,6 +1791,96 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
err.emit();
}
fn annotate_source_of_ambiguity(
&self,
err: &mut DiagnosticBuilder<'tcx>,
impls: &[DefId],
predicate: ty::Predicate<'tcx>,
) {
let mut spans = vec![];
let mut crates = vec![];
let mut post = vec![];
for def_id in impls {
match self.tcx.span_of_impl(*def_id) {
Ok(span) => spans.push(self.tcx.sess.source_map().guess_head_span(span)),
Err(name) => {
crates.push(name);
if let Some(header) = to_pretty_impl_header(self.tcx, *def_id) {
post.push(header);
}
}
}
}
let msg = format!("multiple `impl`s satisfying `{}` found", predicate);
let mut crate_names: Vec<_> = crates.iter().map(|n| format!("`{}`", n)).collect();
crate_names.sort();
crate_names.dedup();
post.sort();
post.dedup();
if self.is_tainted_by_errors()
&& crate_names.len() == 1
&& crate_names[0] == "`core`"
&& spans.len() == 0
{
// Avoid complaining about other inference issues for expressions like
// `42 >> 1`, where the types are still `{integer}`, but we want to
// Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too?
err.cancel();
return;
}
let post = if post.len() > 4 {
format!(
":\n{}\nand {} more",
post.iter().map(|p| format!("- {}", p)).take(4).collect::<Vec<_>>().join("\n"),
post.len() - 4,
)
} else if post.len() > 1 || (post.len() == 1 && post[0].contains("\n")) {
format!(":\n{}", post.iter().map(|p| format!("- {}", p)).collect::<Vec<_>>().join("\n"),)
} else if post.len() == 1 {
format!(": `{}`", post[0])
} else {
String::new()
};
match (spans.len(), crates.len(), crate_names.len()) {
(0, 0, 0) => {
err.note(&format!("cannot satisfy `{}`", predicate));
}
(0, _, 1) => {
err.note(&format!("{} in the `{}` crate{}", msg, crates[0], post,));
}
(0, _, _) => {
err.note(&format!(
"{} in the following crates: {}{}",
msg,
crate_names.join(", "),
post,
));
}
(_, 0, 0) => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
}
(_, 1, 1) => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
err.note(
&format!("and another `impl` found in the `{}` crate{}", crates[0], post,),
);
}
_ => {
let span: MultiSpan = spans.into();
err.span_note(span, &msg);
err.note(&format!(
"and more `impl`s found in the following crates: {}{}",
crate_names.join(", "),
post,
));
}
}
}
/// Returns `true` if the trait predicate may apply for *some* assignment
/// to the type parameters.
fn predicate_can_apply(

View File

@ -299,18 +299,15 @@ fn suggest_restriction(
generics,
trait_ref.without_const().to_predicate(tcx).to_string(),
),
(None, Some((ident, []))) => (
ident.span.shrink_to_hi(),
format!(": {}", trait_ref.print_only_trait_path().to_string()),
),
(_, Some((_, [.., bounds]))) => (
bounds.span().shrink_to_hi(),
format!(" + {}", trait_ref.print_only_trait_path().to_string()),
),
(Some(_), Some((_, []))) => (
generics.span.shrink_to_hi(),
format!(": {}", trait_ref.print_only_trait_path().to_string()),
),
(None, Some((ident, []))) => {
(ident.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path()))
}
(_, Some((_, [.., bounds]))) => {
(bounds.span().shrink_to_hi(), format!(" + {}", trait_ref.print_only_trait_path()))
}
(Some(_), Some((_, []))) => {
(generics.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path()))
}
};
err.span_suggestion_verbose(

View File

@ -18,7 +18,7 @@ use crate::traits;
use crate::traits::coherence::Conflict;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{util, SelectionResult};
use crate::traits::{ErrorReporting, Overflow, Unimplemented};
use crate::traits::{Ambiguous, ErrorReporting, Overflow, Unimplemented};
use super::BuiltinImplConditions;
use super::IntercrateAmbiguityCause;
@ -197,7 +197,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// and report ambiguity.
if i > 1 {
debug!("multiple matches, ambig");
return Ok(None);
return Err(Ambiguous(
candidates
.into_iter()
.filter_map(|c| match c.candidate {
SelectionCandidate::ImplCandidate(def_id) => Some(def_id),
_ => None,
})
.collect(),
));
}
}
}

View File

@ -357,18 +357,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
debug_assert!(!obligation.predicate.has_escaping_bound_vars());
let pec = &ProvisionalEvaluationCache::default();
let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
let candidate = match self.candidate_from_obligation(&stack) {
let candidate = match self.select_from_obligation(obligation) {
Err(SelectionError::Overflow) => {
// In standard mode, overflow must have been caught and reported
// earlier.
assert!(self.query_mode == TraitQueryMode::Canonical);
return Err(SelectionError::Overflow);
}
Err(SelectionError::Ambiguous(_)) => {
return Ok(None);
}
Err(e) => {
return Err(e);
}
@ -391,6 +389,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
crate fn select_from_obligation(
&mut self,
obligation: &TraitObligation<'tcx>,
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
debug_assert!(!obligation.predicate.has_escaping_bound_vars());
let pec = &ProvisionalEvaluationCache::default();
let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
self.candidate_from_obligation(&stack)
}
///////////////////////////////////////////////////////////////////////////
// EVALUATION
//
@ -915,6 +925,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match self.candidate_from_obligation(stack) {
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig),
Ok(None) => Ok(EvaluatedToAmbig),
Err(Overflow) => Err(OverflowError::Canonical),
Err(ErrorReporting) => Err(OverflowError::ErrorReporting),

View File

@ -464,7 +464,7 @@ fn report_conflicting_impls(
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
/// string.
fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
crate fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
use std::fmt::Write;
let trait_ref = tcx.impl_trait_ref(impl_def_id)?;

View File

@ -185,9 +185,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
debug!("coerce: unsize not object safe");
return Err(TypeError::ObjectUnsafeCoercion(did));
}
Err(_) => {}
Err(error) => {
debug!(?error, "coerce: unsize failed");
}
}
debug!("coerce: unsize failed");
// Examine the supertype and consider auto-borrowing.
match *b.kind() {

View File

@ -4,7 +4,14 @@ error[E0283]: type annotations needed
LL | impl C for u32 {}
| ^ cannot infer type for type `u32`
|
= note: cannot satisfy `u32: C`
note: multiple `impl`s satisfying `u32: C` found
--> $DIR/coherence-overlap-trait-alias.rs:13:1
|
LL | impl<T: AB> C for T {}
| ^^^^^^^^^^^^^^^^^^^
LL | #[rustc_strict_coherence]
LL | impl C for u32 {}
| ^^^^^^^^^^^^^^
note: required by a bound in `C`
--> $DIR/coherence-overlap-trait-alias.rs:11:1
|

View File

@ -21,7 +21,14 @@ LL | let bar = foo_impl.into() * 1u32;
| this method call resolves to `T`
| help: use the fully qualified path for the potential candidate: `<Impl as Into<u32>>::into(foo_impl)`
|
= note: cannot satisfy `Impl: Into<_>`
note: multiple `impl`s satisfying `Impl: Into<_>` found
--> $DIR/E0283.rs:17:1
|
LL | impl Into<u32> for Impl {
| ^^^^^^^^^^^^^^^^^^^^^^^
= note: and another `impl` found in the `core` crate:
- impl<T, U> Into<U> for T
where U: From<T>;
error: aborting due to 2 previous errors

View File

@ -17,7 +17,7 @@ fn two(x: bool) -> impl Foo {
//~| expected `i32`, found `u32`
}
fn sum_to(n: u32) -> impl Foo {
fn sum_to(n: u32) -> impl Foo { //~ ERROR type annotations needed
if n == 0 {
0
} else {

View File

@ -34,7 +34,22 @@ LL | n + sum_to(n - 1)
|
= help: the trait `Add<impl Foo>` is not implemented for `u32`
error: aborting due to 2 previous errors; 1 warning emitted
error[E0283]: type annotations needed
--> $DIR/equality.rs:20:22
|
LL | fn sum_to(n: u32) -> impl Foo {
| ^^^^^^^^ cannot infer type for type `{integer}`
|
= note: multiple `impl`s satisfying `{integer}: ToString` found in the `alloc` crate:
- impl ToString for i8;
- impl ToString for u8;
note: required because of the requirements on the impl of `Foo` for `{integer}`
--> $DIR/equality.rs:5:26
|
LL | impl<T: Copy + ToString> Foo for T {}
| ^^^ ^
Some errors have detailed explanations: E0277, E0308.
error: aborting due to 3 previous errors; 1 warning emitted
Some errors have detailed explanations: E0277, E0283, E0308.
For more information about an error, try `rustc --explain E0277`.

View File

@ -6,7 +6,10 @@ LL | .get(&"key".into())
| |
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
= note: cannot satisfy `String: Borrow<_>`
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
- impl Borrow<str> for String;
- impl<T> Borrow<T> for T
where T: ?Sized;
error: aborting due to previous error

View File

@ -6,7 +6,11 @@ LL | if String::from("a") == "a".try_into().unwrap() {}
| |
| cannot infer type
|
= note: cannot satisfy `String: PartialEq<_>`
= note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate:
- impl PartialEq for String;
- impl<'a, 'b> PartialEq<&'a str> for String;
- impl<'a, 'b> PartialEq<Cow<'a, str>> for String;
- impl<'a, 'b> PartialEq<str> for String;
error: aborting due to previous error

View File

@ -4,7 +4,13 @@ error[E0283]: type annotations needed
LL | let _ = <S5<_>>::xxx;
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
|
= note: cannot satisfy `S5<_>: Foo`
note: multiple `impl`s satisfying `S5<_>: Foo` found
--> $DIR/issue-29147.rs:17:1
|
LL | impl Foo for S5<u32> { fn xxx(&self) {} }
| ^^^^^^^^^^^^^^^^^^^^
LL | impl Foo for S5<u64> { fn xxx(&self) {} }
| ^^^^^^^^^^^^^^^^^^^^
note: required by `Foo::xxx`
--> $DIR/issue-29147.rs:10:13
|

View File

@ -27,4 +27,5 @@ impl Test<u64> for u64 {
fn main() {
let xs: Vec<u64> = vec![1, 2, 3];
println!("{}", 23u64.test(xs.iter().sum())); //~ ERROR: type annotations needed
//~^ ERROR type annotations needed
}

View File

@ -4,6 +4,26 @@ error[E0284]: type annotations needed: cannot satisfy `<u64 as Test<_>>::Output
LL | println!("{}", 23u64.test(xs.iter().sum()));
| ^^^^ cannot satisfy `<u64 as Test<_>>::Output == _`
error: aborting due to previous error
error[E0283]: type annotations needed
--> $DIR/issue-69455.rs:29:26
|
LL | println!("{}", 23u64.test(xs.iter().sum()));
| ^^^^ cannot infer type for type parameter `Rhs` declared on the trait `Test`
|
note: multiple `impl`s satisfying `u64: Test<_>` found
--> $DIR/issue-69455.rs:11:1
|
LL | impl Test<u32> for u64 {
| ^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl Test<u64> for u64 {
| ^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying the type argument in the method call
|
LL | println!("{}", 23u64.test(xs.iter().sum::<S>()));
| +++++
For more information about this error, try `rustc --explain E0284`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0283, E0284.
For more information about an error, try `rustc --explain E0283`.

View File

@ -28,5 +28,6 @@ fn main() {
let b: [u8; 3] = [0u8; 3];
0u16.foo(b); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
//<u16 as Foo<[(); 3]>>::foo(0u16, b);
}

View File

@ -4,6 +4,22 @@ error[E0284]: type annotations needed: cannot satisfy `<u8 as Element<_>>::Array
LL | 0u16.foo(b);
| ^^^ cannot satisfy `<u8 as Element<_>>::Array == [u8; 3]`
error: aborting due to previous error
error[E0283]: type annotations needed
--> $DIR/issue-69683.rs:30:10
|
LL | 0u16.foo(b);
| ^^^ cannot infer type for type parameter `I` declared on the trait `Foo`
|
note: multiple `impl`s satisfying `u8: Element<_>` found
--> $DIR/issue-69683.rs:5:1
|
LL | impl<T> Element<()> for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl<T: Element<S>, S> Element<[S; 3]> for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0284`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0283, E0284.
For more information about an error, try `rustc --explain E0283`.

View File

@ -5,10 +5,13 @@ fn no_err() {
fn err() {
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
}
fn arg_pat_closure_err() {
|x| String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
//~| ERROR type annotations needed
}
fn local_pat_closure_err() {
@ -17,12 +20,14 @@ fn local_pat_closure_err() {
fn err_first_arg_pat() {
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
|x: String| x;
}
fn err_second_arg_pat() {
|x: String| x;
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
}
fn err_mid_arg_pat() {
@ -31,6 +36,7 @@ fn err_mid_arg_pat() {
|x: String| x;
|x: String| x;
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
|x: String| x;
|x: String| x;
|x: String| x;
@ -39,12 +45,14 @@ fn err_mid_arg_pat() {
fn err_first_local_pat() {
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
let _ = String::from("x");
}
fn err_second_local_pat() {
let _ = String::from("x");
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
}
fn err_mid_local_pat() {
@ -53,6 +61,7 @@ fn err_mid_local_pat() {
let _ = String::from("x");
let _ = String::from("x");
String::from("x".as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
let _ = String::from("x");
let _ = String::from("x");
let _ = String::from("x");

View File

@ -4,36 +4,89 @@ error[E0283]: type annotations needed
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:7:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0282]: type annotations needed
--> $DIR/issue-72690.rs:11:6
--> $DIR/issue-72690.rs:12:6
|
LL | |x| String::from("x".as_ref());
| ^ consider giving this closure parameter a type
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:12:9
|
LL | |x| String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:12:26
|
LL | |x| String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed for `&T`
--> $DIR/issue-72690.rs:15:17
--> $DIR/issue-72690.rs:18: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
|
= note: cannot satisfy `str: AsRef<_>`
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:19:5
--> $DIR/issue-72690.rs:22:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
@ -41,12 +94,29 @@ LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:25:5
--> $DIR/issue-72690.rs:22:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:29:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
@ -54,12 +124,29 @@ LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:33:5
--> $DIR/issue-72690.rs:29:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:38:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
@ -67,17 +154,19 @@ LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:41:5
--> $DIR/issue-72690.rs:38:22
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: cannot satisfy `String: From<&_>`
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:47:5
@ -85,7 +174,9 @@ error[E0283]: type annotations needed
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
@ -93,19 +184,81 @@ LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:55:5
--> $DIR/issue-72690.rs:47:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:54:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:54:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:63:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
- impl<> From<&str> for String;
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:63:22
|
LL | String::from("x".as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`:
- impl AsRef<OsStr> for str;
- impl AsRef<Path> for str;
- impl AsRef<[u8]> for str;
- impl AsRef<str> for str;
error: aborting due to 18 previous errors
Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.

View File

@ -4,7 +4,13 @@ error[E0283]: type annotations needed
LL | impl<'a> A for (&'static (), &'a ()) {}
| ^ cannot infer type for tuple `(&'static (), &'a ())`
|
= note: cannot satisfy `(&'static (), &'a ()): A`
note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found
--> $DIR/region-overlap.rs:5:1
|
LL | impl<'a> A for (&'static (), &'a ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<'a> A for (&'a (), &'static ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `A`
--> $DIR/region-overlap.rs:4:1
|
@ -17,7 +23,13 @@ error[E0283]: type annotations needed
LL | impl<'a> A for (&'a (), &'static ()) {}
| ^ cannot infer type for tuple `(&'a (), &'static ())`
|
= note: cannot satisfy `(&'a (), &'static ()): A`
note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found
--> $DIR/region-overlap.rs:5:1
|
LL | impl<'a> A for (&'static (), &'a ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<'a> A for (&'a (), &'static ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `A`
--> $DIR/region-overlap.rs:4:1
|

View File

@ -23,7 +23,7 @@ fn m1() {
// we couldn't infer the type of the vector just based on calling foo()...
let mut x = Vec::new();
//~^ ERROR type annotations needed
x.foo();
x.foo(); //~ ERROR type annotations needed
}
fn m2() {

View File

@ -6,6 +6,21 @@ LL | let mut x = Vec::new();
| |
| consider giving `x` the explicit type `Vec<T>`, where the type parameter `T` is specified
error[E0283]: type annotations needed
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7
|
LL | x.foo();
| ^^^ cannot infer type for struct `Vec<_>`
|
note: multiple `impl`s satisfying `Vec<_>: Foo` found
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1
|
LL | impl Foo for Vec<usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl Foo for Vec<isize> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20
|
@ -19,7 +34,7 @@ help: you can convert an `isize` to a `usize` and panic if the converted value d
LL | let y: usize = x.foo().try_into().unwrap();
| ++++++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0282, E0308.
Some errors have detailed explanations: E0282, E0283, E0308.
For more information about an error, try `rustc --explain E0282`.

View File

@ -6,6 +6,7 @@ fn what() {
let opt = String::new();
opts.get(opt.as_ref()); //~ ERROR type annotations needed
//~^ ERROR type annotations needed
}
fn main() {

View File

@ -6,17 +6,50 @@ LL | opts.get(opt.as_ref());
| |
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
= note: cannot satisfy `String: Borrow<_>`
= note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`:
- impl Borrow<str> for String;
- impl<T> Borrow<T> for T
where T: ?Sized;
error[E0283]: type annotations needed
--> $DIR/issue-77982.rs:12:44
--> $DIR/issue-77982.rs:8:18
|
LL | opts.get(opt.as_ref());
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`:
- impl AsRef<OsStr> for String;
- impl AsRef<Path> for String;
- impl AsRef<[u8]> for String;
- impl AsRef<str> for String;
help: use the fully qualified path for the potential candidates
|
LL | opts.get(<String as AsRef<OsStr>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | opts.get(<String as AsRef<Path>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | opts.get(<String as AsRef<str>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | opts.get(<String as AsRef<[u8]>>::as_ref(opt));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0283]: type annotations needed
--> $DIR/issue-77982.rs:13:44
|
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect();
| ^^^^^^^^^ ----------- this method call resolves to `T`
| |
| cannot infer type for type parameter `T` declared on the trait `From`
|
= note: 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;
and 3 more
note: required by `from`
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
@ -24,25 +57,37 @@ LL | fn from(_: T) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed for `Box<T>`
--> $DIR/issue-77982.rs:35:16
--> $DIR/issue-77982.rs:36:16
|
LL | let _ = ().foo();
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo`
| |
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
= note: cannot satisfy `(): Foo<'_, _>`
note: multiple `impl`s satisfying `(): Foo<'_, _>` found
--> $DIR/issue-77982.rs:29:1
|
LL | impl Foo<'static, u32> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<'a> Foo<'a, i16> for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed for `Box<T>`
--> $DIR/issue-77982.rs:39:19
--> $DIR/issue-77982.rs:40:19
|
LL | let _ = (&()).bar();
| - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar`
| |
| consider giving this pattern the explicit type `Box<T>`, where the type parameter `T` is specified
|
= note: cannot satisfy `&(): Bar<'_, _>`
note: multiple `impl`s satisfying `&(): Bar<'_, _>` found
--> $DIR/issue-77982.rs:32:1
|
LL | impl<'a> Bar<'static, u32> for &'a () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | impl<'a> Bar<'a, i16> for &'a () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0283`.

View File

@ -24,7 +24,8 @@ where T : Convert<U>
fn a() {
test(22, std::default::Default::default());
//~^ ERROR type annotations needed [E0282]
//~^ ERROR type annotations needed
//~| ERROR type annotations needed
}
fn main() {}

View File

@ -4,6 +4,33 @@ error[E0282]: type annotations needed
LL | test(22, std::default::Default::default());
| ^^^^ cannot infer type for type parameter `U` declared on the function `test`
error: aborting due to previous error
error[E0283]: type annotations needed
--> $DIR/multidispatch-convert-ambig-dest.rs:26:5
|
LL | test(22, std::default::Default::default());
| ^^^^ cannot infer type for type parameter `U` declared on the function `test`
|
note: multiple `impl`s satisfying `i32: Convert<_>` found
--> $DIR/multidispatch-convert-ambig-dest.rs:8:1
|
LL | impl Convert<i8> for i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl Convert<i16> for i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `test`
--> $DIR/multidispatch-convert-ambig-dest.rs:21:11
|
LL | fn test<T,U>(_: T, _: U)
| ---- required by a bound in this
LL | where T : Convert<U>
| ^^^^^^^^^^ required by this bound in `test`
help: consider specifying the type arguments in the function call
|
LL | test::<T, U>(22, std::default::Default::default());
| ++++++++
For more information about this error, try `rustc --explain E0282`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.

View File

@ -6,9 +6,9 @@ impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah<X>(&self) {} }
impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} }
fn main() {
10.dup::<i32>();
10.dup::<i32>(); //~ ERROR type annotations needed
//~^ ERROR this associated function takes 0 generic arguments but 1
10.blah::<i32, i32>();
10.blah::<i32, i32>(); //~ ERROR type annotations needed
//~^ ERROR this associated function takes 1 generic argument but 2
(Box::new(10) as Box<dyn bar>).dup();
//~^ ERROR E0038

View File

@ -79,7 +79,35 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn bar>>` for `Box<{integer}>`
= note: required by cast to type `Box<dyn bar>`
error: aborting due to 5 previous errors
error[E0283]: type annotations needed
--> $DIR/test-2.rs:9:8
|
LL | 10.dup::<i32>();
| ^^^ cannot infer type for type `{integer}`
|
note: multiple `impl`s satisfying `{integer}: bar` found
--> $DIR/test-2.rs:5:1
|
LL | impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah<X>(&self) {} }
| ^^^^^^^^^^^^^^^^
LL | impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} }
| ^^^^^^^^^^^^^^^^
Some errors have detailed explanations: E0038, E0107.
error[E0283]: type annotations needed
--> $DIR/test-2.rs:11:8
|
LL | 10.blah::<i32, i32>();
| ^^^^ cannot infer type for type `{integer}`
|
note: multiple `impl`s satisfying `{integer}: bar` found
--> $DIR/test-2.rs:5:1
|
LL | impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah<X>(&self) {} }
| ^^^^^^^^^^^^^^^^
LL | impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} }
| ^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0038, E0107, E0283.
For more information about an error, try `rustc --explain E0038`.