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

Add E0492 and E0498 errors explanation #29976

Merged
merged 2 commits into from
Nov 30, 2015
Merged

Conversation

GuillaumeGomez
Copy link
Member

#![plugin="foo")] // error: malformed plugin attribute
```

The plugin name must be written without quotes and within parenthesis. Example:
Copy link
Member

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.

Copy link
Member Author

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 ?

Copy link
Member

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: )".

Copy link
Member Author

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 ')'.

@GuillaumeGomez GuillaumeGomez changed the title Add E0498 error explanation Add E0492 and E0498 errors explanation Nov 21, 2015
@GuillaumeGomez
Copy link
Member Author

Updated.

@@ -1941,6 +1941,53 @@ you want. Example:
```
"##,

E0492: r##"
A constant borrow which contains interior mutability was attempted. Erroneous
Copy link
Member

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

@bors
Copy link
Contributor

bors commented Nov 22, 2015

☔ The latest upstream changes (presumably #29716) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez
Copy link
Member Author

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:
Copy link
Member

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.

```

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
Copy link
Member

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.

fn main() {}
```

To solve this error, either use statics or avoid using `cell` type. If you want
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

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() {}

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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)

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

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.)

@bors
Copy link
Contributor

bors commented Nov 26, 2015

☔ The latest upstream changes (presumably #30043) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez
Copy link
Member Author

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:
Copy link
Member

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.

@GuillaumeGomez
Copy link
Member Author

Updated.

static B: &'static AtomicUsize = &A; // ok!
```

You can also have this error while using a `cell type`:
Copy link
Member

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`.
Copy link
Member

Choose a reason for hiding this comment

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

same regarding code formatting

@GuillaumeGomez
Copy link
Member Author

Re-updated.

static B: &'static NotThreadSafe<usize> = &A; // ok!
```

Remember this solution is unsafe! You will have to ensute that accesses to the
Copy link
Member

Choose a reason for hiding this comment

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

ensure

@Manishearth
Copy link
Member

r=me after one spelling fix

@Manishearth
Copy link
Member

@bors delegate+

@Manishearth
Copy link
Member

Oh, that won't work on this bors.

@GuillaumeGomez
Copy link
Member Author

No it doesn't. :p (fixed)

@Manishearth
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Nov 29, 2015

📌 Commit 483656b has been approved by Manishearth

@bors
Copy link
Contributor

bors commented Nov 29, 2015

⌛ Testing commit 483656b with merge dc9fb96...

@bors
Copy link
Contributor

bors commented Nov 29, 2015

💔 Test failed - auto-mac-32-opt

@steveklabnik
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Nov 29, 2015

⌛ Testing commit 483656b with merge b22d7a5...

const F: &'static C = &D; // error
```

This is because cell types internally use `UnsafeCell`, which isn't `Sync`.
Copy link
Member

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.

@bors bors merged commit 483656b into rust-lang:master Nov 30, 2015
@GuillaumeGomez GuillaumeGomez deleted the patch-5 branch November 30, 2015 09:27
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.

7 participants