dropck: Remove `Copy` from special-cased traits
Fix#24895.
[breaking-change]
What does this break? Basically, code that implements `Drop` and is
using `T:Copy` for one of its type parameters and is relying on the
Drop Check rule not applying to it.
Here is an example:
```rust
#![allow(dead_code,unused_variables,unused_assignments)]
struct D<T:Copy>(T);
impl<T:Copy> Drop for D<T> { fn drop(&mut self) { } }
trait UserT { fn c(&self) { } }
impl<T:Copy> UserT for T { }
struct E<T:UserT>(T);
impl<T:UserT> Drop for E<T> { fn drop(&mut self) { } }
// This one will start breaking.
fn foo() { let (d2, d1); d1 = D(34); d2 = D(&d1); }
#[cfg(this_one_does_and_should_always_break)]
fn bar() { let (e2, e1); e1 = E(34); e2 = E(&e1); }
fn main() {
foo();
}
```
[breaking-change]
What does this break? Basically, code that implements `Drop` and is
using `T:Copy` for one of its type parameters and is relying on the
Drop Check rule not applying to it.
Here is an example:
```rust
#![allow(dead_code,unused_variables,unused_assignments)]
struct D<T:Copy>(T);
impl<T:Copy> Drop for D<T> { fn drop(&mut self) { } }
trait UserT { fn c(&self) { } }
impl<T:Copy> UserT for T { }
struct E<T:UserT>(T);
impl<T:UserT> Drop for E<T> { fn drop(&mut self) { } }
// This one will start breaking.
fn foo() { let (d2, d1); d1 = D(34); d2 = D(&d1); }
#[cfg(this_one_does_and_should_always_break)]
fn bar() { let (e2, e1); e1 = E(34); e2 = E(&e1); }
fn main() {
foo();
}
```
Inspecting the current thread's info may not always work due to the TLS value
having been destroyed (or is actively being destroyed). The code for printing
a panic message assumed, however, that it could acquire the thread's name
through this method.
Instead this commit propagates the `Option` outwards to allow the
`std::panicking` module to handle the case where the current thread isn't
present.
While it solves the immediate issue of #24313, there is still another underlying
issue of panicking destructors in thread locals will abort the process.
Closes#24313
Inspecting the current thread's info may not always work due to the TLS value
having been destroyed (or is actively being destroyed). The code for printing
a panic message assumed, however, that it could acquire the thread's name
through this method.
Instead this commit propagates the `Option` outwards to allow the
`std::panicking` module to handle the case where the current thread isn't
present.
While it solves the immediate issue of #24313, there is still another underlying
issue of panicking destructors in thread locals will abort the process.
Closes#24313
Instead of using the O(n) defaults, define O(1) shortcuts. I also copied (and slightly modified) the relevant tests from the iter tests into the slice tests just in case someone comes along and changes them in the future.
Partially implements #24214.
Inspect enum discriminant *after* calling its destructor
Includes some drive-by cleanup (e.g. changed some field and method names to reflect fill-on-drop; added comments about zero-variant enums being classified as `_match::Single`).
Probably the most invasive change was the expansion of the maps `available_drop_glues` and `drop_glues` to now hold two different kinds of drop glues; there is the (old) normal drop glue, and there is (new) drop-contents glue that jumps straight to dropping the contents of a struct or enum, skipping its destructor.
* For all types that do not have user-defined Drop implementations, the normal glue is generated as usual (i.e. recursively dropping the fields of the data structure).
(And this actually is exactly what the newly-added drop-contents glue does as well.)
* For types that have user-defined Drop implementations, the "normal" drop glue now schedules a cleanup before invoking the `Drop::drop` method that will call the drop-contents glue after that invocation returns.
Fix#23611.
----
Is this a breaking change? The prior behavior was totally unsound, and it seems unreasonable that anyone was actually relying on it.
Nonetheless, since there is a user-visible change to the language semantics, I guess I will conservatively mark this as a:
[breaking-change]
(To see an example of what sort of user-visible change this causes, see the comments in the regression test.)
Closes#17841.
The majority of the work should be done, e.g. trait and inherent impls, different forms of UFCS syntax, defaults, and cross-crate usage. It's probably enough to replace the constants in `f32`, `i8`, and so on, or close to good enough.
There is still some significant functionality missing from this commit:
- ~~Associated consts can't be used in match patterns at all. This is simply because I haven't updated the relevant bits in the parser or `resolve`, but it's *probably* not hard to get working.~~
- Since you can't select an impl for trait-associated consts until partway through type-checking, there are some problems with code that assumes that you can check constants earlier. Associated consts that are not in inherent impls cause ICEs if you try to use them in array sizes or match ranges. For similar reasons, `check_static_recursion` doesn't check them properly, so the stack goes ka-blooey if you use an associated constant that's recursively defined. That's a bit trickier to solve; I'm not entirely sure what the best approach is yet.
- Dealing with consts associated with type parameters will raise some new issues (e.g. if you have a `T: Int` type parameter and want to use `<T>::ZERO`). See rust-lang/rfcs#865.
- ~~Unused associated consts don't seem to trigger the `dead_code` lint when they should. Probably easy to fix.~~
Also, this is the first time I've been spelunking in rustc to such a large extent, so I've probably done some silly things in a couple of places.
Remove the name "multi-line string literal" since the rule appears to affect each line-break individually rather than the whole string literal. Re-word, and remove the stray reference to raw strings.
A user in IRC was having trouble because they used `main.rs` when they were trying
to migrate a library. The `[[lib]]` key is not easily found, and the `main.rs`/`lib.rs`
distinction doesn't seem to exist in trpl
r? @steveklabnik
Improve example for as_string and add example for as_vec
Provide a better example of `as_string` / `DerefString`'s unique capabilities.
Use an example where (for an unspecified reason) you need a &String, and
show how `as_string` solves the problem without needing an allocation.
The minus sign ‘−’ is the same width as the plus sign ‘+’, so the button’s transition between the two symbols will look slightly smoother.
If you don’t want to use literal Unicode characters, I can change ‘−’ to `\u2212`. I’m not starting with that suggestion because ‘−’ is easier to read and understand, and if I used `\u2212`, it would probably be necessary to also comment the usage on each line to explain what character is being used.
Kudos to dotdash for tracking down this fix.
Presumably the use of `ByRef` was because this value is a reference to
the drop-flag; but an Lvalue will serve just as well for that. dotdash
argues:
> since the drop_flag is in its "final home", Lvalue seems to be the
> correct choice.
That is, scheduled drops are executed in reverse order, so for
correctness, we *schedule* the lifetime end before we schedule the
drop, so that when they are executed, the drop will be executed
*before* the lifetime end.
Fix `make_command_line` for the case of backslashes at the end of an
argument requiring quotes. We must encode the command and arguments
such that `CommandLineToArgvW` recovers them in the spawned process.
Simplify the logic by using a running count of backslashes as they
are encountered instead of looking ahead for quotes following them.
Extend `test_make_command_line` to additionally cover:
* a leading quote in an argument that requires quotes,
* a backslash before a quote in an argument that requires quotes,
* a backslash at the end of an argument that requires quotes, and
* a backslash at the end of an argument that does not require quotes.
Remove the name "multi-line string literal" since the rule appears to affect each line-break individually rather than the whole string literal. Re-word, and remove the stray reference to raw strings.
So that if people accidentally delete the character, they won’t re-type it as a hyphen, which would cause bugs.
I changed ‘+’ too, even though it won’t be re-typed incorrectly, so that it is easier to see when plus is used as a symbol for the button, and when it is used as an operator in code. It also makes it clearer that the use of an entity for minus is on purpose, so people won’t be tempted to replace the entity incorrectly with a hyphen character.
I figure I'd start easy with fixing a simple documentation bug. This is also a test to see that I got everything right w r t the fork/pull request process.