-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
A misdiagnosed case of type mismatch #11847
Comments
Interestingly, it works with |
the literal, like 22, is actually an |
Hmm, I don't think that's how rustc handles this. I think rustc doesn't even try to prove that the variable implements rust-analyzer/crates/hir-ty/src/infer/coerce.rs Lines 613 to 618 in 1f709d5
I think if we accepted any ambiguous result like the FIXME says this might work, though I'm not sure whether it would cause other problems (this requires at least testing on some codebases that it doesn't cause regressions). rustc does this in a more sophisticated way (it has its own trait solving loop specially for coercion), and I'm not sure whether this has any functional differences or is just for better diagnostics. |
I agree. so I found sth like this. rust-analyzer/crates/hir-ty/src/infer.rs Lines 431 to 440 in 1f709d5
in line 431, fallback some |
I don't think that's a good approach to fix this. The type mismatch is just one symptom of this bug; we need to correctly record the coercion. |
yes.
So I think. there are two ways to correctly record the coercion. one is use default i32, the other is |
This problem isn't really related to fallback, it can also happen if we later do find out the concrete type for the literal: fn main() {
let i = 22;
let f = print_me_later(&i);
let u: u64 = i;
f()
} The thing that matters is that it's a variable at the point where we need to coerce, and we can't go back later and change the decision. |
The mismatch's expected is decided. and the actual is not finally decided => When the variable's type is finally decided, the mismatch is finally decided. |
As I mentioned before, it's not just about the type mismatch, we need to decide the coercion correctly. Here's a more complicated example where this matters for type inference down the line: trait Foo<T> { fn get(&self) -> T; }
impl Foo<&'static str> for i32 {
fn get(&self) -> &'static str {
"ok"
}
}
impl Foo<u32> for u32 {
fn get(&self) -> u32 { *self }
}
fn test() {
let x = 2;
let d: &dyn Foo<_> = &x;
let _: i32 = x;
eprintln!("{}", d.get().len());
} |
oh. Just for a diagnostic. For this issue, no matter what the literal type is , the diagnostic should not show. So, I think, just check if some literal type matches. |
I also test |
…h726 Work around `rust-analyzer` false-positive type errors rust-analyzer incorrectly reports two type errors in `debug.rs`: > expected &dyn Display, found &i32 > expected &dyn Display, found &i32 This is due to a known bug in r-a: (rust-lang/rust-analyzer#11847). In these particular cases, changing `&0` to `&0i32` seems to be enough to avoid the bug.
This is marked as
S-actionable
|
Yes, this is probably blocked on the new trait solver. |
rust-analyzer version: bc08b8e 2022-03-28 stable
rustc version: 1.59.0 (9d1b2106e 2022-02-23)
I tried the example in https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/ and found that r-a gives wrong diagnostics.
The source code:
The text was updated successfully, but these errors were encountered: