Skip to content
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

Don't report numeric inference ambiguity when we have previous errors #95751

Merged
merged 1 commit into from
Apr 9, 2022
Merged
Show file tree
Hide file tree
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
22 changes: 19 additions & 3 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use rustc_span::symbol::{kw, sym};
use rustc_span::{ExpnKind, Span, DUMMY_SP};
use std::fmt;
use std::iter;
use std::ops::ControlFlow;

use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::query::normalize::AtExt as _;
Expand Down Expand Up @@ -2226,9 +2227,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
post.dedup();

if self.is_tainted_by_errors()
&& crate_names.len() == 1
&& ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
&& spans.len() == 0
&& (crate_names.len() == 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this check just be simplified to "if the self type is a numeric infer"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we need to check for int/float variables not just in self, but in the trait's substs as well, so we don't report the things that implement ConcreteType: Trait<{integer}>.

Also removing the core/alloc/std crate name check leads to some regressions in errors reported with simd stuff and when we're unable to infer const variables due to other errors :/

&& spans.len() == 0
&& ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
|| predicate.visit_with(&mut HasNumericInferVisitor).is_break())
{
// Avoid complaining about other inference issues for expressions like
// `42 >> 1`, where the types are still `{integer}`, but we want to
Expand Down Expand Up @@ -2666,3 +2668,17 @@ impl ArgKind {
}
}
}

struct HasNumericInferVisitor;

impl<'tcx> ty::TypeVisitor<'tcx> for HasNumericInferVisitor {
type BreakTy = ();

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) {
ControlFlow::Break(())
} else {
ControlFlow::CONTINUE
}
}
}
16 changes: 16 additions & 0 deletions src/test/ui/traits/no-fallback-multiple-impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
trait Fallback {
fn foo(&self) {}
}

impl Fallback for i32 {}

impl Fallback for u64 {}

impl Fallback for usize {}

fn main() {
missing();
//~^ ERROR cannot find function `missing` in this scope
0.foo();
// But then we shouldn't report an inference ambiguity here...
}
9 changes: 9 additions & 0 deletions src/test/ui/traits/no-fallback-multiple-impls.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0425]: cannot find function `missing` in this scope
--> $DIR/no-fallback-multiple-impls.rs:12:5
|
LL | missing();
| ^^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0425`.
4 changes: 2 additions & 2 deletions src/test/ui/traits/test-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(); //~ ERROR type annotations needed
10.dup::<i32>();
//~^ ERROR this associated function takes 0 generic arguments but 1
10.blah::<i32, i32>(); //~ ERROR type annotations needed
10.blah::<i32, i32>();
//~^ ERROR this associated function takes 1 generic argument but 2
(Box::new(10) as Box<dyn bar>).dup();
//~^ ERROR E0038
Expand Down
32 changes: 2 additions & 30 deletions src/test/ui/traits/test-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -79,35 +79,7 @@ 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[E0283]: type annotations needed
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hehe, wonderful to see this issue getting better too

--> $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) {} }
| ^^^^^^^^^^^^^^^^

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
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0038, E0107, E0283.
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.