Skip to content

Fix ICE when casting on constant expressions #9909

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

Closed
wants to merge 1 commit into from

Conversation

LeoTestard
Copy link
Contributor

This pull request fixes the bug I opened ( #9867 )
It also fixes a small issue that was causing Rustc build to fail on my setup, by removing a rusti target in the Makefile.

@alexcrichton
Copy link
Member

Can you add a test for this as well? Would just want to make sure that it doesn't regress in the future.

@LeoTestard
Copy link
Contributor Author

Done. Is this sufficient ? I'm not quite familiar with test suites... :/

@LeoTestard
Copy link
Contributor Author

Ok for the comment. For the second part, I'm not sure to understand. How do I do this ?

@alexcrichton
Copy link
Member

That looks good to me, thanks!

@thestinger
Copy link
Contributor

@LeoTestard: not sure what's wrong with the fix for constant expressions, so I sent in another pull request for the rusti issue

@LeoTestard
Copy link
Contributor Author

Should be ok now.
The "u64" type was hardcoded in the test suite instead of a native uint, which caused LLVM to fail to relocate expression at link time on 32 bits targets. Thanks to @eddyb for his help.

@huonw
Copy link
Member

huonw commented Oct 18, 2013

Could you rebase to remove the rusti commit (fixed in a separate PR) and to squash the second commit into the first, thanks?

@LeoTestard
Copy link
Contributor Author

We discussed this with @alexcrichton on IRC and decided this PR was not ready for merge yet, there are a couple of special cases to be handled if we want to avoid the weird LLVM error in the future.

@LeoTestard
Copy link
Contributor Author

Should be ok now.
I added a size check to ensure we're not relocating something impossible. I also added a test-suite that should fail to compile.
I think this PR is ready for merging now
(ping @alexcrichton who asked me to ping him)

// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
Copy link
Member

Choose a reason for hiding this comment

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

This will actually not run the test. You'll need to have //~ ERROR directives below, although you can't cfg-off error directives so you should probably just cast it to a u16 instead of having different cases for 32/64 bit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do I have to retype the exact error message in the //~ERROR directive ?

Copy link
Member

Choose a reason for hiding this comment

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

The problem is that if you have two ERROR directives the test harness will expect two errors to get emitted (which won't happen the way it's currently set up)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I see. I will use u16. But what must I type next to //~ERROR exactly ? The whole error message "cannot cast... " etc. ?

@LeoTestard
Copy link
Contributor Author

@alexcrichton I added the error message and the comment as you requested

@thestinger
Copy link
Contributor

If the value isn't known at compile-time, how can it be statically used in an array size? It doesn't seem like it would be meeting the requirements of Rust's static

@thestinger
Copy link
Contributor

FWIW, C++ doesn't permit this with the equivalent feature:

foo.cc:5:18: error: constexpr variable 'x' must be initialized by a constant expression
constexpr size_t x = (size_t)&foo;

It allows it in a immutable (const) global but not a true constant. Rust's static currently means a true constant and it seems like the expectation is going to be that it's evaluated at compile-time. If we ever added CTFE, I would expect it to leverage static - as in static x: T = foo(); would evaluate foo at compile-time.

@thestinger
Copy link
Contributor

I guess #9866 is related, since we are already doing stuff like this.

@brson
Copy link
Contributor

brson commented Oct 26, 2013

It does seem like this cast is just not valid.

@LeoTestard
Copy link
Contributor Author

@brson I don't think it is so simple. If we consider the current meaning of static (I.E. "must be known at compile-time"), then it is indeed, but foreign statics are not valid too. Just like mutable statics (though they require an unsafe block to be accessed.
Wether we decide this is a valid use of static or not, we must decide if we want to be able to write such things, like operations on values that won't be known until link or load time. That can be useful for FFI among other things (statically initialize a variable with a foreign pointer address, accessing foreign globals, etc. etc. etc.)

@catamorphism
Copy link
Contributor

@brson @LeoTestard Is there a semantic ambiguity that needs to be decided on here? Is it something that could become an RFC issue and/or be discussed in an upcoming meeting? Or can this go ahead and be merged?

@LeoTestard
Copy link
Contributor Author

@catamorphism I don't think this PR can be merged "as it". But yes, I think there is indeed a semantic ambiguity on the current meaning on static. If we allow this cast, static is not anymore a "fully compile time known constant".
But it is already the case with some examples:

  • Extern statics are not compile-time constants
  • Function pointers are not compile-time constants since they are not known till link-time, or even load-time (in the case of PIC or whatever). I think of this sort of code (compiles on master) : http://paste.placeholder.fr/show/489/
  • etc.

And whatever we decide about the semantics of static (here is already an issue about this, doing "statically" (by static I don't necessarily mean that I want this to be the meaning of "static" in Rust. I just mean "ahead of time") this kind of things with values that are only known at link (and/or load-time) may be useful in some cases, in particular with FFI or something like that (this issue is related too). I (and maybe other people on #rust-osdev) have use cases for this. We should decide if we allow this, and how.

@alexcrichton
Copy link
Member

Closing due to inactivity, it sounds like this needs more thought to see how much of this we're willing to allow. Feel free to reopen if progress is made, though!

flip1995 pushed a commit to flip1995/rust that referenced this pull request Jun 30, 2023
[`get_unwrap`]: include a borrow in the suggestion if argument is not an integer literal

Fixes rust-lang#9909

I have to say, I don't really understand what the previous logic was trying to do, but this fixes the linked bug.
It was checking if the argument passed to `.get()` can be parsed as a usize (i.e. if it's an integer literal, probably?), and if not, it wouldn't include a borrow? I don't know how we came to that conclusion, but that logic doesn't work:
```rs
let slice = &[1, 2];
let _r: &i32 = slice.get({ 1 }).unwrap();
// previous suggestion: slice[{ 1 }]
// the suggestion should be: &slice[{ 1 }]
```
Here the argument passed to it isn't an integer literal, but it should still include a borrow, because it would otherwise change the type from `&i32` to `i32`.

The exception is that if the parent of the `get().unwrap()` expr is a dereference or a method call or the like, we don't need an explicit borrow because it's automatically inserted by the compiler

changelog: [`get_unwrap`]: include a borrow in the suggestion if argument is not an integer literal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants