Fix diagnostics for `@ ..` binding pattern in tuples and tuple structs
Fixes#72574
Associated https://github.com/rust-lang/rust/pull/72534https://github.com/rust-lang/rust/issues/72373
Includes a new suggestion with `Applicability::MaybeIncorrect` confidence level.
### Before
#### tuple
```
error: `..` patterns are not allowed here
--> src/main.rs:4:19
|
4 | (_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns
error[E0308]: mismatched types
--> src/main.rs:4:9
|
3 | match x {
| - this expression has type `({integer}, {integer}, {integer})`
4 | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_, _)`
error: aborting due to 2 previous errors
```
#### tuple struct
```
error: `..` patterns are not allowed here
--> src/main.rs:6:25
|
6 | Binder(_a, _x @ ..) => {}
| ^^
|
= note: only allowed in tuple, tuple struct, and slice patterns
error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
--> src/main.rs:6:9
|
1 | struct Binder(i32, i32, i32);
| ----------------------------- tuple struct defined here
...
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2
error: aborting due to 2 previous errors
```
### After
*Note: final output edited during source review discussion, see thread for details*
#### tuple
```
error: `_x @` is not allowed in a tuple
--> src/main.rs:4:14
|
4 | (_a, _x @ ..) => {}
| ^^^^^^^ is only allowed in a slice
|
help: replace with `..` or use a different valid pattern
|
4 | (_a, ..) => {}
| ^^
error[E0308]: mismatched types
--> src/main.rs:4:9
|
3 | match x {
| - this expression has type `({integer}, {integer}, {integer})`
4 | (_a, _x @ ..) => {}
| ^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 1 element
|
= note: expected tuple `({integer}, {integer}, {integer})`
found tuple `(_,)`
error: aborting due to 2 previous errors
```
#### tuple struct
```
error: `_x @` is not allowed in a tuple struct
--> src/main.rs:6:20
|
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^ is only allowed in a slice
|
help: replace with `..` or use a different valid pattern
|
6 | Binder(_a, ..) => {}
| ^^
error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
--> src/main.rs:6:9
|
1 | struct Binder(i32, i32, i32);
| ----------------------------- tuple struct defined here
...
6 | Binder(_a, _x @ ..) => {}
| ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 1
error: aborting due to 2 previous errors
```
r? @estebank
Don't bail out of trait selection when predicate references an error
Fixes#72590
With PR #70551, observing a `ty::Error` guarantees that compilation is
going to fail. Therefore, there are no soundness impliciations to
continuing on when we encounter a `ty::Error` - we can only affect
whether or not additional error messags are emitted.
By not bailing out, we avoid incorrectly determining that types are
`!Sized` when a type error is present, which allows us to avoid emitting
additional spurious error messages.
The original comment mentioned this code being shared by coherence -
howver, this change resulted in no diagnostic changes in any of the
existing tests.
Add Extend::{extend_one,extend_reserve}
This adds new optional methods on `Extend`: `extend_one` add a single
element to the collection, and `extend_reserve` pre-allocates space for
the predicted number of incoming elements. These are used in `Iterator`
for `partition` and `unzip` as they shuffle elements one-at-a-time into
their respective collections.
This adds new optional methods on `Extend`: `extend_one` add a single
element to the collection, and `extend_reserve` pre-allocates space for
the predicted number of incoming elements. These are used in `Iterator`
for `partition` and `unzip` as they shuffle elements one-at-a-time into
their respective collections.
impl Step for char (make Range*<char> iterable)
[[irlo thread]](https://internals.rust-lang.org/t/mini-rfc-make-range-char-work/12392?u=cad97) [[godbolt asm example]](https://rust.godbolt.org/z/fdveKo)
Add an implementation of the `Step` trait for `char`, which has the effect of making `RangeInclusive<char>` (and the other range types) iterable.
I've used the surrogate range magic numbers as magic numbers here rather than e.g. a `const SURROGATE_RANGE = 0xD800..0xE000` because these numbers appear to be used as magic numbers elsewhere and there doesn't exist constants for them yet. These files definitely aren't where surrogate range constants should live.
`ExactSizeIterator` is not implemented because `0x10FFFF` is bigger than fits in a `usize == u16`. However, given we already provide some `ExactSizeIterator` that are not correct on 16 bit targets, we might still want to consider providing it for `Range`[`Inclusive`]`<char>`, as it is definitely _very_ convenient. (At the very least, we want to make sure `.count()` doesn't bother iterating the range.)
The second commit in this PR changes a call to `Step::forward` to use `Step::forward_unchecked` in `RangeInclusive::next`. This is because without this patch, iteration over all codepoints (`'\0'..=char::MAX`) does not successfully optimize out the panicking branch. This was mentioned in the PR that updated `Step` to its current design, but was deemed not yet necessary as it did not impact codegen for integral types.
More of `Range*`'s implementations' calls to `Step` methods will probably want to see if they can use the `_unchecked` version as (if) we open up `Step` to being implemented on more types.
---
cc @rust-lang/libs, this is insta-stable and a fairly significant addition to `Range*`'s capabilities; this is the first instance of a noncontinuous domain being iterable with `Range` (or, well, anything other than primitive integers). I don't think this needs a full RFC, but it should definitely get some decent eyes on it.
Various minor improvements to Ipv6Addr::Display
Cleaned up `Ipv6Addr::Display`, especially with an eye towards simplifying and reducing duplicated logic. Also added a fast-path optimization, similar to #72399 and #72398.
- Defer to `Ipv4Addr::fmt` when printing an Ipv4 address
- Fast path: write directly to `f` without an intermediary buffer when there are no alignment options
- Simplify finding the inner zeroes-span
linker: Support `-static-pie` and `-static -shared`
This PR adds support for passing linker arguments for creating statically linked position-independent executables and "statically linked" shared libraries.
Therefore it incorporates the majority of https://github.com/rust-lang/rust/pull/70740 except for the linker rerun hack and actually flipping the "`static-pie` is supported" switch for musl targets.
Make pointer offset methods/intrinsics const
Implements #71499 using [the implementations from miri](52f5d202bd/src/shims/intrinsics.rs (L96-L112)).
I added some tests what's allowed and what's UB. Let me know if any other cases should be added.
CC: @RalfJung @oli-obk
We want to avoid exporting any symbols from Rust's version of libunwind,
and to do so we need to disable visibility annotations to make sure that
the -fvisibility=hidden has effect, and also hide global new/delete.
This matches the CMake build of libunwind.
librustc_middle: Rename upvar_list to closure_captures
As part of supporting RFC 2229, we will be capturing all the places that
are mentioned in a closure. Currently the `upvar_list` field gives access to a `FxIndexMap<HirId, Upvar>` map. Eventually this will change, with the `upvar_list` having a more general structure that expresses captured paths, not just the mentioned `upvars`. We will make those changes in subsequent PRs.
This commit modifies the name of the `upvar_list` map to `closure_captures` in `TypeckTables`.
r? @matthewjasper
Implement total_cmp for f32, f64
# Overview
* Implements method `total_cmp` on `f32` and `f64`. This method implements a float comparison that, unlike the standard `partial_cmp`, is total (defined on all values) in accordance to the IEEE 754 (rev 2008) §5.10 `totalOrder` predicate.
* The method has an API similar to `cmp`: `pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { ... }`.
* Implements tests.
* Has documentation.
# Justification for the API
* Total ordering for `f32` and `f64` has been discussed many time before:
* https://internals.rust-lang.org/t/pre-pre-rfc-range-restricting-wrappers-for-floating-point-types/6701
* https://github.com/rust-lang/rfcs/issues/1249
* https://github.com/rust-lang/rust/pull/53938
* https://github.com/rust-lang/rust/issues/5585
* The lack of total ordering leads to frequent complaints, especially from people new to Rust.
* This is an ergonomics issue that needs to be addressed.
* However, the default behaviour of implementing only `PartialOrd` is intentional, as relaxing it might lead to correctness issues.
* Most earlier implementations and discussions have been focusing on a wrapper type that implements trait `Ord`. Such a wrapper type is, however not easy to add because of the large API surface added.
* As a minimal step that hopefully proves uncontroversial, we can implement a stand-alone method `total_cmp` on floating point types.
* I expect adding such methods should be uncontroversial because...
* Similar methods on `f32` and `f64` would be warranted even in case stdlib would provide a wrapper type that implements `Ord` some day.
* It implements functionality that is standardised. (IEEE 754, 2008 rev. §5.10 Note, that the 2019 revision relaxes the ordering. The way we do ordering in this method conforms to the stricter 2008 standard.)
* With stdlib APIs such as `slice::sort_by` and `slice::binary_search_by` that allow users to provide a custom ordering criterion, providing additional helper methods is a minimal way of adding ordering functionality.
* Not also does it allow easily using aforementioned APIs, it also provides an easy and well-tested primitive for the users and library authors to implement an `Ord`-implementing wrapper, if needed.
Warn about unused captured variables
Include captured variables in liveness analysis. Warn when captured variables
are unused (but possibly read or written to). Warn about dead assignments to
captured variables.
Fixes#37707.
Fixes#47128.
Fixes#63220.
SocketAddr and friends now correctly pad its content
Currently, `IpAddr` and friends correctly respect formatting parameters when printing via `Display`. This PR makes SocketAddr and friends do the same thing.
Suggest using std::mem::drop function instead of explicit destructor call
I would prefer to give a better suggestion that includes code example, but I'm currently stuck on getting the correct span for that.
Closes#72322.
Add Peekable::next_if
Prior art:
`rust_analyzer` uses [`Parser::eat`](50f4ae798b/crates/ra_parser/src/parser.rs (L94)), which is `next_if` specialized to `|y| self.next_if(|x| x == y)`.
Basically every other parser I've run into in Rust has an equivalent of `Parser::eat`; see for example
- [cranelift](94190d5724/cranelift/reader/src/parser.rs (L498))
- [rcc](a8159c3904/src/parse/mod.rs (L231))
- [crunch](8521874fab/crates/crunch-parser/src/parser/mod.rs (L213-L241))
Possible extensions: A specialization of `next_if` to using `Eq::eq`. The only difficulty here is the naming - maybe `next_if_eq`?
Alternatives:
- Instead of `func: impl FnOnce(&I::Item) -> bool`, use `func: impl FnOnce(I::Item) -> Option<I::Item>`. This has the advantage that `func` can move the value if necessary, but means that there is no guarantee `func` will return the same value it was given.
- Instead of `fn next_if(...) -> Option<I::Item>`, use `fn next_if(...) -> bool`. This makes the common case of `iter.next_if(f).is_some()` easier, but makes the unusual case impossible.
Bikeshedding on naming:
- `next_if` could be renamed to `consume_if` (to match `eat`, but a little more formally)
- `next_if_eq` could be renamed to `consume`. This is more concise but less self-explanatory if you haven't written a lot of parsers.
- Both of the above, but with `consume` replaced by `eat`.