Invert diagnostic lints.
That is, change `diagnostic_outside_of_impl` and `untranslatable_diagnostic` from `allow` to `deny`, because more than half of the compiler has been converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow` attributes, which proves that this change is warranted.
r? ````@davidtwco````
core/time: avoid divisions in Duration::new
In our (decently large) code base, we use `SystemTime::UNIX_EPOCH.elapsed()` in a lot of places & often in a loop or in the hot path. On [Unix](https://github.com/rust-lang/rust/blob/1.75.0/library/std/src/sys/unix/time.rs#L153-L162) at least, it seems we do calculations before hand to ensure that nanos is within the valid range, yet `Duration::new()` still checks it again, using 2 divisions. It seems like adding a branch can make this function 33% faster on ARM64 in the cases where nanos is already in the valid range & seems to have no effect in the other case.
Benchmarks:
M1 Pro (14-inch base model):
```
duration/current/checked
time: [1.5945 ns 1.6167 ns 1.6407 ns]
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) high mild
3 (3.00%) high severe
duration/current/unchecked
time: [1.5941 ns 1.6051 ns 1.6179 ns]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
duration/branched/checked
time: [1.1997 ns 1.2048 ns 1.2104 ns]
Found 8 outliers among 100 measurements (8.00%)
4 (4.00%) high mild
4 (4.00%) high severe
duration/branched/unchecked
time: [1.5881 ns 1.5957 ns 1.6039 ns]
Found 6 outliers among 100 measurements (6.00%)
3 (3.00%) high mild
3 (3.00%) high severe
```
EC2 c7gd.16xlarge (Graviton 3):
```
duration/current/checked
time: [2.7996 ns 2.8000 ns 2.8003 ns]
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) low severe
3 (3.00%) low mild
duration/current/unchecked
time: [2.9922 ns 2.9925 ns 2.9928 ns]
Found 7 outliers among 100 measurements (7.00%)
4 (4.00%) low severe
1 (1.00%) low mild
2 (2.00%) high mild
duration/branched/checked
time: [2.0830 ns 2.0843 ns 2.0857 ns]
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) low severe
1 (1.00%) low mild
1 (1.00%) high mild
duration/branched/unchecked
time: [2.9879 ns 2.9886 ns 2.9893 ns]
Found 5 outliers among 100 measurements (5.00%)
3 (3.00%) low severe
2 (2.00%) low mild
```
EC2 r7iz.16xlarge (Intel Xeon Scalable-based (Sapphire Rapids)):
```
duration/current/checked
time: [980.60 ps 980.79 ps 980.99 ps]
Found 10 outliers among 100 measurements (10.00%)
4 (4.00%) low severe
2 (2.00%) low mild
3 (3.00%) high mild
1 (1.00%) high severe
duration/current/unchecked
time: [979.53 ps 979.74 ps 979.96 ps]
Found 6 outliers among 100 measurements (6.00%)
2 (2.00%) low severe
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
duration/branched/checked
time: [938.72 ps 938.96 ps 939.22 ps]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
1 (1.00%) high mild
2 (2.00%) high severe
duration/branched/unchecked
time: [1.0103 ns 1.0110 ns 1.0118 ns]
Found 10 outliers among 100 measurements (10.00%)
2 (2.00%) low mild
7 (7.00%) high mild
1 (1.00%) high severe
```
Bench code (ran using stable 1.75.0 & criterion latest 0.5.1):
I couldn't find any benches for `Duration` in this repo, so I just copied the relevant types & recreated it.
```rust
use criterion::{black_box, criterion_group, criterion_main, Criterion};
pub fn duration_bench(c: &mut Criterion) {
const NANOS_PER_SEC: u32 = 1_000_000_000;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
struct Nanoseconds(u32);
impl Default for Nanoseconds {
#[inline]
fn default() -> Self {
// SAFETY: 0 is within the valid range
unsafe { Nanoseconds(0) }
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Duration {
secs: u64,
nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC
}
impl Duration {
#[inline]
pub const fn new_current(secs: u64, nanos: u32) -> Duration {
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs,
None => panic!("overflow in Duration::new"),
};
let nanos = nanos % NANOS_PER_SEC;
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
}
#[inline]
pub const fn new_branched(secs: u64, nanos: u32) -> Duration {
if nanos < NANOS_PER_SEC {
// SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
} else {
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs,
None => panic!("overflow in Duration::new"),
};
let nanos = nanos % NANOS_PER_SEC;
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
}
}
}
let mut group = c.benchmark_group("duration/current");
group.bench_function("checked", |b| {
b.iter(|| black_box(Duration::new_current(black_box(1_000_000_000), black_box(1_000_000))));
});
group.bench_function("unchecked", |b| {
b.iter(|| {
black_box(Duration::new_current(black_box(1_000_000_000), black_box(2_000_000_000)))
});
});
drop(group);
let mut group = c.benchmark_group("duration/branched");
group.bench_function("checked", |b| {
b.iter(|| {
black_box(Duration::new_branched(black_box(1_000_000_000), black_box(1_000_000)))
});
});
group.bench_function("unchecked", |b| {
b.iter(|| {
black_box(Duration::new_branched(black_box(1_000_000_000), black_box(2_000_000_000)))
});
});
}
criterion_group!(duration_benches, duration_bench);
criterion_main!(duration_benches);
```
Make privacy visitor use types more (instead of HIR)
r? ``@petrochenkov``
This is a prerequisite to normalizing projections, as otherwise we have too many invalid bound vars (hir_ty_to_ty is creating types that have bound vars, but no binder).
The commits are still chaotic, I'm gonna clean them up, but I just wanted to let you know about the general direction and wondering if we could land this before adding normalization, as normalization is where behavioral changes happen, and I'd like to keep that part as minimal as possible.
[context can be found on zulip](https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/weak.20type.20aliases.20and.20privacy)
Always check the result of `pthread_mutex_lock`
Fixes#120147.
Instead of manually adding a list of "good" platforms, I've simply made the check unconditional. pthread's mutex is already quite slow on most platforms, so one single well-predictable branch shouldn't hurt performance too much.
Rollup of 9 pull requests
Successful merges:
- #120590 (Remove unused args from functions)
- #120750 (No need to take `ImplTraitContext` by ref)
- #120769 (make future diffs minimal)
- #120772 (Remove myself from review rotation.)
- #120775 (Make `min_exhaustive_patterns` match `exhaustive_patterns` better)
- #120778 (Deduplicate `tcx.instance_mir(instance)` calls in `try_instance_mir`)
- #120782 (Fix mir pass ICE in the presence of other errors)
- #120783 (Add release note for new ambiguous_wide_pointer_comparisons lint)
- #120801 (Avoid ICE in drop recursion check in case of invalid drop impls)
r? `@ghost`
`@rustbot` modify labels: rollup
Add release note for new ambiguous_wide_pointer_comparisons lint
I found out about this new lint in Rust because I had code allowing the Clippy lint. Clippy alerted me to the lint name change, and I went searching for the new lint's name in the release notes and was surprised there wasn't an item for it.
Fix mir pass ICE in the presence of other errors
fixes#120779
it is impossible to add a ui test for this, because it only reproduces in build-fail, but a test that also has errors in check-fail mode can't be made build-fail 🙃
I would have to add a run-make test or sth, which is overkill for such a tiny thing imo.
Make `min_exhaustive_patterns` match `exhaustive_patterns` better
Split off from https://github.com/rust-lang/rust/pull/120742.
There remained two edge cases where `min_exhaustive_patterns` wasn't behaving like `exhaustive_patterns`. This fixes them, and tests the feature in a bunch more cases. I essentially went through all uses of `exhaustive_patterns` to see which ones would be interesting to compare between the two features.
r? `@compiler-errors`
Remove myself from review rotation.
I've been unable to keep up with reviews. :(
Not sure if this helps much, considering there aren't many other libs reviewers on the rotation at the moment.
Hopefully I can add myself back again Soon™ when I can commit more time to reviewing.
No need to take `ImplTraitContext` by ref
We used to mutate `ImplTraitContext`, so it used to be `&mut` mutable ref. Then I think it used to have non-`Copy` data in it, so we took it by `&` ref. Now, none of that remains, so just copy it around.
Remove unused args from functions
`#[instrument]` suppresses the unused arguments from a function, *and* suppresses unused methods too! This PR removes things which are only used via `#[instrument]` calls, and fixes some other errors (privacy?) that I will comment inline.
It's possible that some of these arguments were being passed in for the purposes of being instrumented, but I am unconvinced by most of them.
Introduce `enter_forall` to supercede `instantiate_binder_with_placeholders`
r? `@lcnr`
Long term we'd like to experiment with decrementing the universe count after "exiting" binders so that we do not end up creating infer vars in non-root universes even when they logically reside in the root universe. The fact that we dont do this currently results in a number of issues in the new trait solver where we consider goals to be ambiguous because otherwise it would require lowering the universe of an infer var. i.e. the goal `?x.0 eq <T as Trait<?y.1>>::Assoc` where the alias is rigid would not be able to instantiate `?x` with the alias as there would be a universe error.
This PR is the first-ish sort of step towards being able to implement this as eventually we would want to decrement the universe in `enter_forall`. Unfortunately its Difficult to actually implement decrementing universes nicely so this is a separate step which moves us closer to the long term goal ✨
Rollup of 9 pull requests
Successful merges:
- #119592 (resolve: Unload speculatively resolved crates before freezing cstore)
- #120103 (Make it so that async-fn-in-trait is compatible with a concrete future in implementation)
- #120206 (hir: Make sure all `HirId`s have corresponding HIR `Node`s)
- #120214 (match lowering: consistently lower bindings deepest-first)
- #120688 (GVN: also turn moves into copies with projections)
- #120702 (docs: also check the inline stmt during redundant link check)
- #120727 (exhaustiveness: Prefer "`0..MAX` not covered" to "`_` not covered")
- #120734 (Add `SubdiagnosticMessageOp` as a trait alias.)
- #120739 (improve pretty printing for associated items in trait objects)
r? `@ghost`
`@rustbot` modify labels: rollup
Continue to borrowck even if there were previous errors
but only from the perspective of the whole compiler. Individual items should not get borrowcked if their MIR is tainted by errors.
r? `@estebank` `@nnethercote`
improve pretty printing for associated items in trait objects
* Don't print a binder in front of associated items, because it's not valid syntax.
* e.g. print `dyn for<'a> Trait<'a, Assoc = &'a u8>` instead of `dyn for<'a> Trait<'a, for<'a> Assoc = &'a u8>`.
* Don't print associated items that are implied by a supertrait bound.
* e.g. if we have `trait Sub: Super<Assoc = u8> {}`, then just print `dyn Sub` instead of `dyn Sub<Assoc = u8>`.
I've added the test in the first commit, so you can see the diff of the compiler output in the second commit.
exhaustiveness: Prefer "`0..MAX` not covered" to "`_` not covered"
There was an exception when reporting integer ranges as missing, it's been there for as long as I can remember. This PR removes it. I think it's nicer to report "`0..MAX` not covered" than "`_` not covered". This also makes it consistent with enums, where we report individual enum variants in this case (as showcased in the rest of the `empty-match.rs` test).
r? ``@estebank``
docs: also check the inline stmt during redundant link check
Fixes#120444
This issue was brought about by querying `root::webdavfs::A`, a key that doesn't exist in `doc_link_resolutions`. To avoid a panic, I've altered the gating mechanism to allow this lint pass to be skipped.
I'm not certain if this is the best solution. An alternative approach might be to leverage other info from the name resolutions instead of `doc_link_resolutions`. After all, all we need is to get the resolution from a combination of `(module, name)`. However, I believe they would yield the same outcome, both skipping this lint.
match lowering: consistently lower bindings deepest-first
Currently when lowering match expressions to MIR, we do a funny little dance with the order of bindings. I attempt to explain it in the third commit: we handle refutable (i.e. needing a test) patterns differently than irrefutable ones. This leads to inconsistencies, as reported in https://github.com/rust-lang/rust/issues/120210. The reason we need a dance at all is for situations like:
```rust
fn foo1(x: NonCopyStruct) {
let y @ NonCopyStruct { copy_field: z } = x;
// the above should turn into
let z = x.copy_field;
let y = x;
}
```
Here the `y ```````@```````` binding will move out of `x`, so we need to copy the field first.
I believe that the inconsistency came about when we fixed https://github.com/rust-lang/rust/issues/69971, and didn't notice that the fix didn't extend to refutable patterns. My guess then is that ordering bindings by "deepest-first, otherwise source order" is a sound choice. This PR implements that (at least I hope, match lowering is hard to follow 🥲).
Fixes https://github.com/rust-lang/rust/issues/120210
r? ```````@oli-obk``````` since you merged the original fix to https://github.com/rust-lang/rust/issues/69971
cc ```````@matthewjasper```````
Make it so that async-fn-in-trait is compatible with a concrete future in implementation
There's no technical reason why an AFIT like `async fn foo()` cannot be satisfied with an implementation signature like `fn foo() -> Pin<Box<dyn Future<Output = ()> + 'static>>`.
We rejected this previously because we were uncertain about how AFITs worked with refinement, but I don't believe this needs to be a restriction any longer.
r? oli-obk
resolve: Unload speculatively resolved crates before freezing cstore
Name resolution sometimes loads additional crates to improve diagnostics (e.g. suggest imports).
Not all of these diagnostics result in errors, sometimes they are just warnings, like in #117772.
If additional crates loaded speculatively stay and gets listed by things like `query crates` then they may produce further errors like duplicated lang items, because lang items from speculatively loaded crates are as good as from non-speculatively loaded crates.
They can probably do things like adding unintended impls from speculatively loaded crates to method resolution as well.
The extra crates will also get into the crate's metadata as legitimate dependencies.
In this PR I remove the speculative crates from cstore when name resolution is finished and cstore is frozen.
This is better than e.g. filtering away speculative crates in `query crates` because things like `DefId`s referring to these crates and leaking to later compilation stages can produce ICEs much easier, allowing to detect them.
The unloading could potentially be skipped if any errors were reported (to allow using `DefId`s from speculatively loaded crates for recovery), but I didn't do it in this PR because I haven't seen such cases of recovery. We can reconsider later if any relevant ICEs are reported.
Unblocks https://github.com/rust-lang/rust/pull/117772.
Prevent running some code if it is already in the map
I realized that a lot of duplicates were being run through this function. Might be better to prevent them from computing all the information if it's already in the cache.
r? `@notriddle`
Stop bailing out from compilation just because there were incoherent traits
fixes#120343
but also has a lot of "type annotations needed" fallout. Some are fixed in the second commit.
Make `NonZero` constructors generic.
This makes `NonZero` constructors generic, so that `NonZero::new` can be used without turbofish syntax.
Tracking issue: https://github.com/rust-lang/rust/issues/120257
~~I cannot figure out how to make this work with `const` traits. Not sure if I'm using it wrong or whether there's a bug:~~
```rust
101 | if n == T::ZERO {
| ^^^^^^^^^^^^ expected `host`, found `true`
|
= note: expected constant `host`
found constant `true`
```
r? `@dtolnay`
Reconstify `Add`
r? project-const-traits
I'm not happy with the ui test changes (or failures because I did not bless them and include the diffs in this PR). There is at least some bugs I need to look and try fix:
1. A third duplicated diagnostic when a consumer crate that does not have `effects` enabled has a trait selection error for an upstream const_trait trait. See tests/ui/ufcs/ufcs-qpath-self-mismatch.rs.
2. For some reason, making `Add` a const trait would stop us from suggesting `T: Add` when we try to add two `T`s without that bound. See tests/ui/suggestions/issue-97677.rs