-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add E0492 and E0498 errors explanation #29976
Conversation
#![plugin="foo")] // error: malformed plugin attribute | ||
``` | ||
|
||
The plugin name must be written without quotes and within parenthesis. Example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plural form of “parenthesis” is “parentheses”.
Also probably “between” instead of “within”, but either works for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, is there any preference for it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does #![plugin="foo")]
even parse?
EDIT: it doesn't: "error: incorrect close delimiter: )
".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well saw, my bad. I forgot the ')'.
Updated. |
@@ -1941,6 +1941,53 @@ you want. Example: | |||
``` | |||
"##, | |||
|
|||
E0492: r##" | |||
A constant borrow which contains interior mutability was attempted. Erroneous |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A borrow of a constant containing interior mutability
☔ The latest upstream changes (presumably #29716) made this pull request unmergeable. Please resolve the merge conflicts. |
61a9188
to
2c9a389
Compare
Updated. |
``` | ||
|
||
To solve this error, either use statics or avoid using `cell` type. If you want | ||
to use statics with a `cell` type, you will have to wrap it: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should encourage people to use a mutex here instead.
There should always be a safe suggestion.
2c9a389
to
718c1ee
Compare
``` | ||
|
||
To solve this error, either use statics or avoid using `cell` type. If you want | ||
to use statics with a `cell` type, you will have to wrap it, but this is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you will have to wrap it with something which manually implements Sync
, but this is unsafe and you will have to ensure that accesses to the cell are synchronized.
718c1ee
to
479f6bc
Compare
fn main() {} | ||
``` | ||
|
||
To solve this error, either use statics or avoid using `cell` type. If you want |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be great to have an example of these solutions, e.g. using one of the atomic types.
It'd also be nice to have an explanation of why this is an error: a const
represents a constant value that should never change. If one takes a &
reference to the constant, then one is taking a pointer to some memory location containing the value, normally this is perfectly fine: most values can't be changed via a shared &
pointer, but interior mutability would allow it. That is, a constant value could be mutated. On the other hand, a static
is explicitly a single memory location, which can be mutated at will.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an example, but an unsafe one so @Manishearth asked me to remove it. But I can totally add one, however it wouldn't really correspond to the previous example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with having the extra explanation about const
.
The issue with the statics solution is that there's no safe way to do it (statics can't have destructors), and getting the unsafe way correct depends on the exact situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue with the statics solution is that there's no safe way to do it (statics can't have destructors), and getting the unsafe way correct depends on the exact situation.
I don't understand your point, because destructors are entirely orthogonal: types with or without destructors can have (or not have) interior mutability.
Here's a before/after example that I was thinking of:
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
// before:
// const A: AtomicUsize = ATOMIC_USIZE_INIT;
// static B: &'static AtomicUsize = &A;
// after:
static A: AtomicUsize = ATOMIC_USIZE_INIT;
static B: &'static AtomicUsize = &A;
fn main() {}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I can totally add one, however it wouldn't really correspond to the previous example.
Adjust the previous example to include enough that examples of possible solutions follow from it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That only works for atomics, not for a cell holding a type of your choice. RefCell and Cell won't work because of UnsafeCell, and Mutex doesn't work because of destructors. So there's no safe way to place something like that in a static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So... I think we should have an example of a thing that does work, if we're going to suggest that thing as a solution. There can be text and/or more examples discussing why this solution doesn't work all the time, but that shouldn't be a reason to not go into more detail about it.
IMO, the goals for these sort of explanations are:
- making it clear exactly what the problem is
- explaining why something is an error (when it makes sense, like here)
- helping people with a solution, as much as possible (code examples are important)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RefCell and Cell won't work because of UnsafeCell
NB. these don't work because of Sync
, not UnsafeCell
: all interior mutability (including Mutex
and the atomics) go through UnsafeCell
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, yeah, UnsafeCell isn't Sync. This error diagnostic is about unsafecell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some types that contain UnsafeCell
do work fine, so UnsafeCell
can't be the underlying problem. You are correct that those two types do get their non-Sync
-ness by just letting UnsafeCell
's opt-out imply it, but the fundamental reason is the semantics of Cell
and RefCell
are not compatible with Sync
i.e. they can never be Sync
, no matter what their implementation details are.
(It's somewhat a bug that the error message focuses on UnsafeCell
rather than Cell
.)
☔ The latest upstream changes (presumably #30043) made this pull request unmergeable. Please resolve the merge conflicts. |
35c594d
to
bbf56d0
Compare
Updated. Not sure it is what you had in mind @huonw. |
it. That is, a constant value could be mutated. On the other hand, a `static` is | ||
explicitly a single memory location, which can be mutated at will. | ||
|
||
So, in order to solve this error, either use statics with a `Sync` type: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use statics which are Sync
.
bbf56d0
to
cd9811e
Compare
Updated. |
static B: &'static AtomicUsize = &A; // ok! | ||
``` | ||
|
||
You can also have this error while using a `cell type`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no code formatting around "cell type"
const F: &'static C = &D; // error | ||
``` | ||
|
||
This is because `cell types` internally use `UnsafeCell`, which isn't `Sync`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same regarding code formatting
cd9811e
to
79f1259
Compare
Re-updated. |
static B: &'static NotThreadSafe<usize> = &A; // ok! | ||
``` | ||
|
||
Remember this solution is unsafe! You will have to ensute that accesses to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ensure
r=me after one spelling fix |
@bors delegate+ |
Oh, that won't work on this bors. |
79f1259
to
483656b
Compare
No it doesn't. :p (fixed) |
@bors r+ rollup |
📌 Commit 483656b has been approved by |
⌛ Testing commit 483656b with merge dc9fb96... |
💔 Test failed - auto-mac-32-opt |
@bors: retry |
const F: &'static C = &D; // error | ||
``` | ||
|
||
This is because cell types internally use `UnsafeCell`, which isn't `Sync`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, as I said before, it isn't because the types use UnsafeCell
internally: there are Sync
types that use UnsafeCell
, like the atomics and Mutex<T>
. It would be better to just say:
This is because these types do operations that are not thread-safe, and hence do not implement
Sync
.
r? @Manishearth