| Age | Commit message (Collapse) | Author | Lines |
|
|
|
Ensure derive(PartialOrd) is no longer accidentally exponential
Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once, addressing https://github.com/rust-lang/rust/issues/49650#issuecomment-379467572.
Closes #49505.
r? @Manishearth (sorry for changing it again so soon!)
Close #50755
|
|
|
|
|
|
|
|
|
|
|
|
Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once.
|
|
Provide better names for builtin deriving-generated attributes
First attempt at fixing #49967
Not in love with any choices here, don't be shy if you aren't happy with anything :)
I've tested that this produces nicer names in documentation, and that it no longer has issues conflicting with constants with the same name. (I guess we _could_ make a test for that... unsure if that would be valuable)
In all cases I took the names from the methods as declared in the relevant trait.
In some cases I had to prepend the names with _ otherwise there were errors about un-used variables. I'm uneasy with the inconsistency... do they all need to be like that? Is there a way to generate an alternate impl or use a different name (`_`?) in the cases where the arguments are not used?
Lastly the gensym addition to Ident I implemented largely as suggested, but I want to point out it's a little circuitous (at least, as far as I understand it). `cx.ident_of(name)` is just `Ident::from_str`, so we create an Ident then another Ident from it. `Ident::with_empty_ctxt(Symbol::gensym(string))` may or may not be equivalent, I don't know if it's important to intern it _then_ gensym it. It seems like either we could use that, or if we do want a new method to make this convenient, it could be on Ident instead (`from_str_gensymed`?)
|
|
|
|
|
|
|
|
|
|
Fix derive(PartialOrd) and optimise final field operation
```rust
// Before (`lt` on 2-field struct)
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
(self.f2 < other.f2 || (!(other.f2 < self.f2) &&
(false)
))
)
// After
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
self.f2 < other.f2
)
// Before (`le` on 2-field struct)
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
(self.f2 < other.f2 || (!(other.f2 < self.f2) &&
(true)
))
)
// After
self.f1 < other.f1 || (self.f1 == other.f1 &&
self.f2 <= other.f2
)
```
(The big diff is mainly because of a past faulty rustfmt application that I corrected 😒)
Fixes #49650 and fixes #49505.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Retains the `stmt_expr_attributes` feature requirement for attributes on expressions.
closes #41475
cc #38356
|
|
|
|
lambda-building
This prevents explicit `-> _` return type annotations for closures generated by `lambda`.
|
|
|
|
The code for several of the core traits doesn't use hygenic macros.
This isn't a problem, except for the Debug trait, which is the only
one that uses a variable, named "builder".
Variables can't share names with unit structs, so attempting to
[derive(Debug)] on any type while a unit struct with the name
"builder" was in scope would result in an error.
This commit just changes the name of the variable to
"__debug_trait_builder", because I couldn't figure out how to get a
list of all unit structs in-scope from within the derive expansion
function. If someone wants to have a unit struct with
the exact name "__debug_trait_builder", they'll just have to do it
without a [derive(Debug)].
|
|
|
|
|
|
|
|
Add approximate suggestions for rustfix
This adds `span_approximate_suggestion()` that lets you emit a
suggestion marked as "non-machine applicable" in the JSON output. UI
users see no difference. This is for when rustc and clippy wish to
emit suggestions which will make sense to the reader (e.g. they may
have placeholders like `<type>`) but are not source-applicable, so that
rustfix/etc can ignore these.
fixes #39254
|
|
field only exist in the json if the flag is passed
|
|
|
|
errors
|
|
|
|
locals that mentioned "extern repr"
|
|
|
|
Do not emit type errors on recovered blocks
When a parse error occurs on a block, the parser will recover and create
a block with the statements collected until that point. Now a flag
stating that a recovery has been performed in this block is propagated
so that the type checker knows that the type of the block (which will be
identified as `()`) shouldn't be checked against the expectation to
reduce the amount of irrelevant diagnostic errors shown to the user.
Fix #44579.
|
|
When a parse error occurs on a block, the parser will recover and create
a block with the statements collected until that point. Now a flag
stating that a recovery has been performed in this block is propagated
so that the type checker knows that the type of the block (which will be
identified as `()`) shouldn't be checked against the expectation to
reduce the amount of irrelevant diagnostic errors shown to the user.
|
|
The Generics now contain one Vec of an enum for the generic parameters,
rather than two separate Vec's for lifetime and type parameters.
Additionally, places that previously used Vec<LifetimeDef> now use
Vec<GenericParam> instead.
|
|
|
|
Account for missing keyword in fn/struct definition
Fix #38911.
|
|
|
|
Fix the derive implementation for repr(packed) structs to move the
fields out instead of calling functions on references to each subfield.
That's it, `#[derive(PartialEq)]` on a packed struct now does:
```Rust
fn eq(&self, other: &Self) {
let field_0 = self.0;
let other_field_0 = other.0;
&field_0 == &other_field_0
}
```
Instead of
```Rust
fn eq(&self, other: &Self) {
let ref field_0 = self.0;
let ref other_field_0 = other.0;
&*field_0 == &*other_field_0
}
```
Taking (unaligned) references to each subfield is undefined, unsound and
is an error with MIR effectck, so it had to be prevented. This causes
a borrowck error when a `repr(packed)` struct has a non-Copy field (and
therefore is a [breaking-change]), but I don't see a sound way to avoid
that error.
|
|
|