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

error causes subsequent spurious error about literal cast #35772

Closed
durka opened this issue Aug 18, 2016 · 7 comments
Closed

error causes subsequent spurious error about literal cast #35772

durka opened this issue Aug 18, 2016 · 7 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug.

Comments

@durka
Copy link
Contributor

durka commented Aug 18, 2016

See this code:

fn main() {
    error;
    1 as f32;
}

It has an error on the second line, obviously. But it also prints an error about the third line (illegal cast). But the cast is perfectly legal and removing the first error also "fixes" the second one.

@durka
Copy link
Contributor Author

durka commented Aug 18, 2016

I suspect this somehow has to do with the constant evaluator. @oli-obk?

@oli-obk
Copy link
Contributor

oli-obk commented Aug 18, 2016

nope, it's not const eval, it's typeck.

beta/nightly even produce "non-scalar cast: {integer} as f32", so it's not something weird like the error; turning the 1 into another type.

@durka
Copy link
Contributor Author

durka commented Aug 18, 2016

But it is a scalar cast. Maybe the first error leaves some kind of boolean flag around that "there was an error", and the casting code picks up on it?

@Detegr
Copy link
Contributor

Detegr commented Aug 18, 2016

I've investigated this a bit. Apologies if I've understood something wrong, I'm still a total compiler noob :)

Looks like the reason this happens is when there's an error before the cast, the type inference of 1 differs from the case when there's just the cast. These types are checked in src/librustc_typeck/check/cast.rs in a function called do_check.

In the working version self.expr_ty.sty looks like this (from rust-gdb):

TyS = {sty = TyInt = {I32}, flags = Cell<rustc::ty::TypeFlags> = {
  value = UnsafeCell<rustc::ty::TypeFlags> = {value = TypeFlags = {
    bits = 0}}}, region_depth = 0}

where in the version with the error it looks like this:

TyS = {sty = TyInfer = {IntVar = {IntVid = {index = 0}}},
  flags = Cell<rustc::ty::TypeFlags> = {
    value = UnsafeCell<rustc::ty::TypeFlags> = {value = TypeFlags = {
      bits = 3076}}}, region_depth = 0}

If do_check results in an error (it does if sty is TyInfer, see from_ty) the compiler reports the cast error.

Why the types are resolved differently I have no idea.

EDIT: I dug around a bit more and I think I found the root cause. The reason was what @durka was anticipating, default_type_parameters() treats all uninstantiated type variables as TyError if an error had been discovered earlier. This causes do_check to fail and the code handling the failure does not check if is_tainted_by_errors() is true or not but just outputs the error anyway.

Detegr added a commit to Detegr/rust that referenced this issue Aug 22, 2016
If `InferCtxt` is tainted by errors, the result of `CastCheck::do_check`
may fail even though the cast is valid. We don't want any wrong error
messages in those cases so checking `is_tainted_by_errors()` before
reporting cast errors.

Fixes rust-lang#35772
@durka
Copy link
Contributor Author

durka commented Aug 22, 2016

Nice detective work @Detegr.

@Detegr
Copy link
Contributor

Detegr commented Aug 22, 2016

Thanks, however my initial solution to the problem was too shortsighted and caused more harm than good. Anyway this has been a fun dive to the compiler internals so I'll keep trying.

@estebank
Copy link
Contributor

This is fixed in nightly and beta (probably due to #46732).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants