Commit Graph

239254 Commits

Author SHA1 Message Date
Nadrieril
6ee51426a9 Respect split invariants for Opaques 2023-11-22 03:25:15 +01:00
Nadrieril
25696cc0e9 Abstract over the list of WitnessStacks 2023-11-22 03:25:10 +01:00
Nadrieril
8ad33a887f Tweak lower_pattern 2023-11-22 02:14:43 +01:00
Nadrieril
98ac114847 Add some tests 2023-11-22 02:14:42 +01:00
bors
fec80b4475 Auto merge of #118143 - Nilstrieb:only-borrow-what-you-need, r=compiler-errors
Fix `clippy::needless_borrow` in the compiler

`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`.

Then I had to remove a few unnecessary parens and muts that were exposed now.

r? `@compiler-errors` you told me you want to review this

I will do a self review first (which, for this, is easiest on GitHub once the PR is open) - did it
2023-11-21 22:34:19 +00:00
Nilstrieb
21a870515b Fix clippy::needless_borrow in the compiler
`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`.

Then I had to remove a few unnecessary parens and muts that were exposed
now.
2023-11-21 20:13:40 +01:00
bors
2f8d81f9db Auto merge of #118137 - roblabla:update-backtrace, r=ChrisDenton
Update backtrace submodule

This PR updates the backtrace submodule, avoiding panics when resolving backtraces on Windows 7:

- https://github.com/rust-lang/backtrace-rs/pull/578

Fixes #117941

I ran the std unit tests locally on a Windows7 machine, and can confirm that this indeed fixes #117941.
2023-11-21 17:23:25 +00:00
roblabla
08803eb4c8 Update backtrace submodule 2023-11-21 16:33:42 +01:00
bors
0ff8610964 Auto merge of #118134 - Nilstrieb:rollup-kyo1l6e, r=Nilstrieb
Rollup of 6 pull requests

Successful merges:

 - #116085 (rustdoc-search: add support for traits and associated types)
 - #117522 (Remove `--check-cfg` checking of command line `--cfg` args)
 - #118029 (Expand Miri's BorTag GC to a Provenance GC)
 - #118035 (Fix early param lifetimes in generic_const_exprs)
 - #118083 (Remove i686-apple-darwin cross-testing)
 - #118091 (Remove now deprecated target x86_64-sun-solaris.)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-11-21 15:08:24 +00:00
Nilstrieb
fa8878bdcc
Rollup merge of #118091 - psumbera:solaris-target, r=compiler-errors
Remove now deprecated target x86_64-sun-solaris.
2023-11-21 14:36:15 +01:00
Nilstrieb
61e06fe446
Rollup merge of #118083 - calebzulawski:remove-i686-apple-darwin, r=albertlarsan68
Remove i686-apple-darwin cross-testing

The Xcode SDK no longer ships with 32-bit Intel (i686-apple-darwin) support as of [Xcode 14](https://developer.apple.com/news/upcoming-requirements/?id=06062022a) (related, #112753).  On an up-to-date Intel Mac, `x.py test --bless` fails.

r? ``@rust-lang/bootstrap``
2023-11-21 14:36:14 +01:00
Nilstrieb
4bb3ae39b7
Rollup merge of #118035 - ouz-a:november_ice2, r=compiler-errors
Fix early param lifetimes in generic_const_exprs

In cases like below, we never actually be able to capture region name for two reasons, first `'static` becomes anonymous lifetime and second we never capture region if it doesn't have a name so this results in ICE.
```
struct DataWrapper<'static> {
    data: &'a [u8; Self::SIZE],
}

impl DataWrapper<'a> {
```

Fixes https://github.com/rust-lang/rust/issues/118021
2023-11-21 14:36:14 +01:00
Nilstrieb
cbadb2e1c0
Rollup merge of #118029 - saethlin:allocid-gc, r=RalfJung
Expand Miri's BorTag GC to a Provenance GC

As suggested in https://github.com/rust-lang/miri/issues/3080#issuecomment-1732505573

We previously solved memory growth issues associated with the Stacked Borrows and Tree Borrows runtimes with a GC. But of course we also have state accumulation associated with whole allocations elsewhere in the interpreter, and this PR starts tackling those.

To do this, we expand the visitor for the GC so that it can visit a BorTag or an AllocId. Instead of collecting all live AllocIds into a single HashSet, we just collect from the Machine itself then go through an accessor `InterpCx::is_alloc_live` which checks a number of allocation data structures in the core interpreter. This avoids the overhead of all the inserts that collecting their keys would require.

r? ``@RalfJung``
2023-11-21 14:36:13 +01:00
Nilstrieb
aff407eef5
Rollup merge of #117522 - Urgau:check-cfg-cli-own-lint, r=petrochenkov
Remove `--check-cfg` checking of command line `--cfg` args

Back in https://github.com/rust-lang/rust/pull/100574 we added to the `unexpected_cfgs` lint the checking of `--cfg` CLI arguments and emitted unexpected names and values for them.

The implementation works as expected, but it's usability in particular when using it in combination with Cargo+`RUSTFLAGS` as people who set `RUSTFLAGS=--cfg=tokio_unstable` (or whatever) have `unexpected_cfgs` warnings on all of their crates is debatable. ~~To fix this issue this PR proposes that we split the CLI argument checking into it's own separate allow-by-default lint: `unexpected_cli_cfgs`.~~

~~This has the advantage of letting people who want CLI warnings have them (although not by default anymore), while still linting on every unexpected cfg name and values in the code.~~

After some discussion with the Cargo team ([Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/check-cfg.20and.20RUSTFLAGS.20interaction)) and member of the compiler team (see below), I propose that we follow the suggestion from `@epage:` never check `--cfg` arguments, but still reserve us the possibility to do it later.

We would still lint on unexpected cfgs found in the source code no matter the `--cfg` args passed. This mean reverting https://github.com/rust-lang/rust/pull/100574 but NOT https://github.com/rust-lang/rust/pull/99519.

r? `@petrochenkov`
2023-11-21 14:36:13 +01:00
Nilstrieb
e62f7be638
Rollup merge of #116085 - notriddle:notriddle/search-associated-types, r=GuillaumeGomez
rustdoc-search: add support for traits and associated types

# Summary

Trait associated type queries work in rustdoc's type driven search. The data is included in the search-index.js file, and the queries are designed to "do what I mean" when users type them in, so, for example, `Iterator<Item=T> -> Option<T>` includes `Iterator::next` in the SERP[^SERP], and `Iterator<T> -> Option<T>` also includes `Iterator::next` in the SERP.

[^SERP]: search engine results page

## Sample searches

* [`iterator<Item=T>, fnmut -> T`][iterreduce]
* [`iterator<T>, fnmut -> T`][iterreduceterse]

[iterreduce]: http://notriddle.com/rustdoc-html-demo-5/associated-types/std/index.html?search=iterator%3CItem%3DT%3E%2C%20fnmut%20-%3E%20T&filter-crate=std
[iterreduceterse]: http://notriddle.com/rustdoc-html-demo-5/associated-types/std/index.html?search=iterator%3CT%3E%2C%20fnmut%20-%3E%20T&filter-crate=std

# Motivation

My primary motivation for working on search.js at all is to make it easier to use highly generic APIs, like the Iterator API. The type signature describes these functions pretty well, while the names are almost arbitrary.

Before this PR, type bindings were not consistently included in search-index.js at all (you couldn't find Iterator::next by typing in its function signature) and you couldn't explicitly search for them. This PR fixes both of these problems.

# Guide-level explanation

*Excerpt from [the Rustdoc book](http://notriddle.com/rustdoc-html-demo-5/associated-types/rustdoc/read-documentation/search.html), included in this PR.*

> Function signature searches can query generics, wrapped in angle brackets, and traits will be normalized like types in the search engine if no type parameters match them. For example, a function with the signature `fn my_function<I: Iterator<Item=u32>>(input: I) -> usize` can be matched with the following queries:
>
> * `Iterator<Item=u32> -> usize`
> * `Iterator<u32> -> usize` (you can leave out the `Item=` part)
> * `Iterator -> usize` (you can leave out iterator's generic entirely)
> * `T -> usize` (you can match with a generic parameter)
>
> Each of the above queries is progressively looser, except the last one would not match `dyn Iterator`, since that's not a type parameter.

# Reference-level explanation

Inside the angle brackets, you can choose whether to write a name before the parameter and the equal sign. This syntax is called [`GenericArgsBinding`](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions) in the Rust Reference, and it allows you to constrain a trait's associated type.

As a convenience, you don't actually have to put the name in (Rust requires it, but Rustdoc Search doesn't). This works about the same way unboxing already works in Search: the terse `Iterator<u32>` is a match for `Iterator<Item=u32>`, but the opposite is not true, just like `u32` is a match for `Iterator<u32>`.

When converting a trait method for the search index, the trait is substituted for `Self`, and all associated types are bound to generics. This way, if you have the following trait definition:

```rust
pub trait MyTrait {
    type Output;
    fn method(self) -> Self::Output;
}
```

The following queries will match its method:

  * `MyTrait<Output=T> -> T`
  * `MyTrait<T> -> T`
  * `MyTrait -> T`

But these queries will not match it:

  * <i>`MyTrait<Output=u32> -> u32`</i>
  * <i>`MyTrait<Output> -> Output`</i>
  * <i>`MyTrait -> MyTrait::Output`</i>

# Drawbacks

It's a little bit bigger:

```console
$ du before/search-index1.74.0.js after/search-index1.74.0.js
4020    before/search-index1.74.0.js
4068    after/search-index1.74.0.js
```

# Rationale and alternatives

I don't want to just not do this. On it's own, it's not terribly useful, but in addition to searching by normal traits, this is also intended as a desugaring target for closures. That's why it needs to actually distinguish the two: it allows the future desugaring to distinguish function output and input.

The other alternative would be to not allow users to leave out the name, so `iterator<u32>` doesn't work. That would be unfortunate, because mixing up which ones have out params and which ones are plain generics is an easy enough mistake that the Rust compiler itself helps people out with it.

# Prior art

  * <http://neilmitchell.blogspot.com/2020/06/hoogle-searching-overview.html>

    The current Rustdoc algorithm, both before this PR and after it, has a fairly expensive matching algorithm over a fairly simple file format. Luckily, we aren't trying to scale to all of crates.io, so it's usable, but it's not great when I throw it at docs.servo.org

# Unresolved questions

Okay, but *how do we want to handle closures?* I know the system will desugar `FnOnce(T) -> U` into `trait:FnOnce<Output=U, primitive:tuple<T>>`, but what if I don't know what trait I'm looking for? This PR can merge with nothing, but it'd be nice to have a plan.

Specifically, how should the special form used to handle all varieties of basic callable: primitive:fn (function pointers), and trait:Fn, trait:FnOnce, and trait:FnMut should all be searchable using a single syntax, because I'm always forgetting which one is used in the function I'm looking for.

The essential question is how closely we want to copy Rust's own syntax. The tersest way to expression Option::map might be:

    Option<T>, (T -> U) -> Option<U>

That's the approach I would prefer, but nobody's going to attempt it without being told, so maybe this would be better?

    Option<T>, (fn(T) -> U) -> Option<U>

It does require double parens, but at least it's mostly unambiguous. Unfortunately, it looks like the syntax you'd use for function pointers, implying that if you specifically wanted to limit your search to function pointers, you'd need to use `primitive:fn(T) -> U`. Then again, searching is normally case-insensitive, so you'd want that anyway to disambiguate from `trait:Fn(T) -> U`.

# Future possibilities

## This thing really needs a ranking algorithm

That is, this PR increases the number of matches for some type-based queries. They're usually pretty good matches, but there's still more of them, and it's evident that if you have two functions, `foo(MyTrait<u8>)` and `bar(MyTrait<Item=u8>)`, if the user typed `MyTrait<u8>` then `foo` should show up first.

A design choice that these PRs have followed is that adding more stuff to the search query always reduces the number of functions that get matched. The advantage of doing it that way is that you can rank them by just counting how many atoms are in the function's signature (lowest score goes on top). Since it's impossible for a matching function to have fewer atoms than the search query, if there's a function with exactly the same set of atoms in it, then that'll be on top.

More complicated ranking algos tend to penalize long documents anyway, if the [distance metrics](https://www.benfrederickson.com/distance-metrics/?utm_source=flipboard&utm_content=other) I found through [Flipboard](https://flipboard.com/`@arnie0426/building-recommender-systems-nvue3iqtgrn10t45)` (and postgresql's `ts_rank_cd`) are anything to go by. Real-world data sets tend to have weird outliers, like they have God Functions with zillions of arguments of all sorts of types, and Rustdoc ought to put such a function at the bottom.

The other natural choice would be interleaving with `unifyFunctionTypes` to count the number of unboxings and reorderings. This would compute a distance function, and would do a fine job of ranking the results, as [described here](https://ndmitchell.com/downloads/slides-hoogle_finding_functions_from_types-16_may_2011.pdf) by the Hoogle dev, but is more complicated than it sounds. The current algorithm returns when it finds a result that *exists at all*, but a distance function should find an *optimal solution* to find the smallest sequence of edits.

## This could also use a benchmark suite and some optimization

This approach also lends itself to layering a bloom filter in front of the backtracking unification engine.

* At load time, hash the typeNameIdMap ID for each atom and set the matching entry in a fixed-size byte array for each function to 1. Call it `fnType.bloomFilter`
* At search time, do the same for the atoms in the query (excluding special forms like `[]` that can match more than one thing). Call it `parsedQuery.bloomFilter`
* For each function, `if (fnType.bloomFilter | (~parsedQuery.bloomFilter) !== ~0) { return false; }`

There's also room to optimize the unification engine itself, by using stacks and persistent data structures instead of copying arrays around, or by using hashing instead of linear scans (the current algorithm was rewritten from one that tried to do that, but was too much to fit in my head and had a bunch of bugs). The advantage of Just Backtracking Better over the bloom filter is that it doesn't require the engine to retain any special algebraic properties.

But, first, we need a set of benchmarks to be able to judge if such a thing will actually help.

## Referring to associated types by path

*I don't want to implement this one, but if I did, this is how I'd do it.*

In Rust, this is represented by a structure called a qualified path, or QPath. They look like this:

    <Self as Iterator>::Item
    <F as FnOnce>::Output

They can also, if it's unambiguous, use a plain path and just let the system figure it out:

    Self::Item
    F::Output

In Rustdoc Type-Driven Search, we don't want to force people to be unambiguous. Instead, we should try *all reasonable interpretations*, return results whenever any of them match, and let users make their query more specific if too many results are matches.

To enable associated type path searches in Rustdoc, we need to:

1. When lowering a trait method to a search-index.js function signature, Self should be explicitly represented as a generic argument. It should always be assigned `-1`, so that if the user uses `Self` in their search query, we can ensure it always matches the real Self and not something else. Any functions that don't *have* a Self should drop a `0` into the first position of the where clause, to express that there isn't one and reserve the `-1` position.
   * Reminder: generics are negative, concrete types are positive, and zero is a reserved sentinel.
   * Right now, `Iterator::next` is lowered as if it were `fn next<T>(self: Iterator<Item=T>) -> Option<T>`.
     It should become `fn next<Self, T>(self: Self) -> Option<T> where Self: Iterator<Item=T>` instead.
3. Add another backtracking edge to the unification engine, so that when the user writes something like `some::thing`, the interpretation where `some` is a module and `thing` is a standalone item becomes one possible match candidate, while the interpretation where `some` is a trait and `thing` is an associated type is a separate match candidate. The backtracking engine is basically powerful enough to do this already, since unboxing generic type parameters into their traits already requires the ability to do this kind of thing.
   * When interpreting `some::thing` where `some` is a trait and `thing` is an associated type, it should be treated equivalently to `<self as some>::thing`. If you want to bind it to some generic parameter other than `Self`, you need to explicitly say so.
   * If no trait called `some` actually exists, treat it as a generic type parameter instead. Track every trait mentioned in the current working function signature, and add a match candidate for each one.
   * A user that explicitly wants the trait-associated-type interpretation could write a qpath (like `<self as trait>::type`), and a user that explicitly wants the module-item interpretation should use an item type filter (like `struct:module::type`).
4. To actually do the matching, maintain a `Map<(QueryGenericParamId, TraitId), FnGenericParamId>` alongside the existing `Map<QueryGenericParamId, FnGenericParamId>` that is already used to handle plain generic parameters. This works, because, when a trait function signature is lowered to search-index.js, the `rustdoc` backend always generates an FnGenericParamId for every trait associated type it sees mentioned in the function's signature.
5. Parse QPaths. Specifically,
   * QueryElem adds three new fields. `isQPath` is a boolean flag, and `traitNameId` contains an entry for `typeNameIdMap` corresponding to the trait part of a qpath, and `parentId` may contain either a concrete type ID or a negative number referring to a generic type parameter. The actual `id` of the query elem will always be a negative number, because this is essentially a funny way to add a generic type constraint.
   * If it's a QPath, then both of those IDs get filled in with the respective parts of the map. The unification engine will check the where clause to ensure the trait actually applies to the generic parameter in question, will check the type parameter constraint, and will add a mapping to `mgens` recording this as a solution.
   * If it's just a regular path, then `isQPath` is false, and the parser will fill in both `traitNameId` and `parentId` based on the same path. The unification engine, seeing isQPath is false and that these IDs were filled in, will try all three solutions: the path might be part of a concrete type name, or it might be referring to a trait, or it might be referring to a generic type parameter.

### Why not implement QPath searches?

I'm not sure if anybody really wants to write such complicated queries. You can do a pretty good job of describing the generic functions in the standard library without resorting to FQPs.

These two queries, for example, would both match the Iterator::map function if we added support for higher order function queries and a rule that allows a type to match its *notable traits*.

    // I like this version, because it's identical to how `Option::map` would be written.
    // There's a reason why Iterator::map and Option::map have the same name.
    Iterator<T>, (T -> U) -> Iterator<U>

    // This version explicitly uses the type parameter constraints.
    Iterator<Item=T>, (T -> U) -> Iterator<Item=U>

If I try to write this one using FQP, however, the results seem worse:

    // This one is less expressive than the versions that don't use associated type paths.
    // It matches `Iterator::filter`, while the above two example queries don't.
    Iterator, (Iterator::Item -> Iterator::Item) -> Iterator

    // This doesn't work, because the return type of `Iterator::map` is not a generic
    // parameter with an `Iterator` trait bound. It's a concrete type that
    // implements `Iterator`. Return-Position-Impl-Trait is the same way.
    //
    // There's a difference between something like `map`, whose return value
    // implements Iterator, and something like `collect`, where the caller
    // gets to decide what the concrete type is going to be.
    //Self, (Self::Item -> I::Item) -> I where Self: Iterator, I: Iterator

    // This works, but it seems subjectively ugly, complex, and counterintuitive to me.
    Self, (<Self as Iterator>::Item -> T) -> Iterator<Item=T>
2023-11-21 14:36:12 +01:00
bors
e24e5af787 Auto merge of #117619 - elomatreb:add-duration-abs-diff, r=thomcc
Add `Duration::abs_diff`

This adds a `Duration::abs_diff` method analogous to the existing one on the primitive integers.

ACP: https://github.com/rust-lang/libs-team/issues/291
Tracking Issue: https://github.com/rust-lang/rust/issues/117618
2023-11-21 13:09:49 +00:00
bors
7bd385dc37 Auto merge of #117580 - compiler-errors:hash-stable-simplify-rustc_type_ir, r=jackh726
Add `HashStable_NoContext` to simplify `HashStable` implementations in `rustc_type_ir`

adds `derive(HashStable_NoContext)` which is a derived `HashStable` implementation that has no `HashStableContext` bound, and which adds `where` bounds for `HashStable` based off of *fields* and not generics.

This means we can `derive(HashStable_NoContext)` in more places in `rustc_type_ir` rather than having to hand-roll implementations.
2023-11-21 11:13:15 +00:00
bors
c5af061019 Auto merge of #118126 - Nilstrieb:rollup-5ogh896, r=Nilstrieb
Rollup of 7 pull requests

Successful merges:

 - #117790 (CFI: Add missing use core::ffi::c_int)
 - #118059 (Explicitly unset $CARGO for compiletest)
 - #118081 (`rustc_ty_utils` cleanups)
 - #118094 (feat: specialize `SpecFromElem` for `()`)
 - #118097 (Update books)
 - #118115 (Fix occurrences of old fn names in comment and tracing)
 - #118121 (`rustc_hir` cleanups)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-11-21 08:40:39 +00:00
Nilstrieb
f13f980900
Rollup merge of #118121 - nnethercote:rustc_hir, r=compiler-errors
`rustc_hir` cleanups

Just some improvements I found while looking at this code.

r? `@WaffleLapkin`
2023-11-21 09:06:30 +01:00
Nilstrieb
90e4c2dc3a
Rollup merge of #118115 - spastorino:fix-old-fn-names, r=compiler-errors
Fix occurrences of old fn names in comment and tracing
2023-11-21 09:06:30 +01:00
Nilstrieb
69a5a893e4
Rollup merge of #118097 - rustbot:docs-update, r=ehuss
Update books

## rust-lang/book

2 commits in 5b6c1ceaa62ecbd6caef08df39b33b3938e99deb..71352deb20727b4dda9ebfe8182709d5bf17dfea
2023-11-09 14:49:45 UTC to 2023-11-09 14:49:16 UTC

- Fixed 'Devtools' link (rust-lang/book#3770)
- Fix mdBook links (rust-lang/book#3769)

## rust-lang/rust-by-example

7 commits in 311b84962016b28c75525c86e7b3f49fd9101a39..a6581246f96837113968c02187db24f742af3908
2023-11-18 21:45:20 UTC to 2023-11-07 22:32:53 UTC

- rename `y` to `_y` to get the correct compile error (rust-lang/rust-by-example#1769)
- fix test name in cargo/test.md (rust-lang/rust-by-example#1768)
- Various minor edits for typo fixes, formatting fixes, and clarifications (rust-lang/rust-by-example#1765)
- Update closures.md to correct a typo (rust-lang/rust-by-example#1763)
- Link to the Bulgarian translation (rust-lang/rust-by-example#1764)
- Fix asm example explanation for `inlateout` usage (22.1 Inline Assembly) (rust-lang/rust-by-example#1766)
- Update index.md: Added descriptions for the 'leftover' points (rust-lang/rust-by-example#1767)

## rust-lang/rustc-dev-guide

3 commits in 77dbe5782b2488af3bb489ad702eaff438f465bf..ddb8b1309f9e905804cea1e248a4572fed6b464b
2023-11-18 21:08:13 UTC to 2023-11-08 14:43:50 UTC

- Add link for unsize.md (rust-lang/rustc-dev-guide#1825)
- Fix typo in contribution walkthrough (rust-lang/rustc-dev-guide#1824)
- Update documentation for coverage tests (rust-lang/rustc-dev-guide#1823)
2023-11-21 09:06:29 +01:00
Nilstrieb
bfc2675362
Rollup merge of #118094 - JarvisCraft:SpecFromElem-for-empty-tuple, r=thomcc
feat: specialize `SpecFromElem` for `()`

# Description

This PR adds a specialization `SpecFromElem for ()` which allows to significantly reduce `vec![(), N]` time in debug builds (specifically, tests) turning it from observable $O(n)$ to $O(1)$.

# Observing the change

The problem this PR aims to fix explicitly is slow `vec![(), N]` on big `N`s which may appear in tests (see [Background section](#Background) for more details).

The minimal example to see the problem:

```rust
#![feature(test)]

extern crate test;

#[cfg(test)]
mod tests {
    const HUGE_SIZE: usize = i32::MAX as usize + 1;

    #[bench]
    fn bench_vec_literal(b: &mut test::Bencher) {
        b.iter(|| vec![(); HUGE_SIZE]);
    }

    #[bench]
    fn bench_vec_repeat(b: &mut test::Bencher) {
        b.iter(|| [(); 1].repeat(HUGE_SIZE));
    }
}
```
<details><summary>Output</summary>
<p>

```bash
cargo +nightly test -- --report-time -Zunstable-options
   Compiling huge-zst-vec-literal-bench v0.1.0 (/home/progrm_jarvis/RustroverProjects/huge-zst-vec-literal-bench)
    Finished test [unoptimized + debuginfo] target(s) in 0.31s
     Running unittests src/lib.rs (target/debug/deps/huge_zst_vec_literal_bench-e43b1ef287ba8b36)

running 2 tests
test tests::bench_vec_repeat  ... ok <0.000s>
test tests::bench_vec_literal ... ok <14.382s>

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 14.38s

   Doc-tests huge-zst-vec-literal-bench

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```
</p>
</details>

> [!IMPORTANT]
> This problem is only observable in Debug (unoptimized) builds, while Release (optimized) ones do not observe this problem. It still is worth fixing it, IMO, since the original scenario observes the problem in tests for which optimizations are disabled by default and it seems unreasonable to override this for the whole project while the problem is very local.

# Background

While working on a crate for a custom data format which has an `i32::MAX` limit on its list's sizes, I wrote the following test to ensure that this invariant is upheld:

```rust
#[test]
fn lists_should_have_i32_size() {
    assert!(
        RawNbtList::try_from(vec![(); i32::MAX as usize]).is_ok(),
        "lists should permit the size up to {}",
        i32::MAX
    );
    assert!(
        RawNbtList::try_from(vec![(); i32::MAX as usize + 1]).is_err(),
        "lists should have the size of at most {}",
        i32::MAX
    );
}
```

Soon I discovered that this takes $\approx 3--4s$ per assertion on my machine, almost all of which is spent on `vec![..]`.
While this would be logical for a non-ZST vector (which would require actual $O(n)$ allocation), here `()` was used intentionally considering that for ZSTs size-changing operations should anyway be $O(1)$ (at least from allocator perspective). Yet, this "overhead" is logical if we consider that in general case `clone()` (which is used by `Vec` literal) may have a non-trivial implementation and thus each element has to actually be visited (even if they occupy no space).

In my specific case, the following (contextual) equivalent solved the issue:

```rust
#[test]
fn lists_should_have_i32_size() {
    assert!(
        RawNbtList::try_from([(); 1].repeat(i32::MAX as usize)).is_ok(),
        "lists should permit the size up to {}",
        i32::MAX
    );
    assert!(
        RawNbtList::try_from([(); 1].repeat(i32::MAX as usize + 1)).is_err(),
        "lists should have the size of at most {}",
        i32::MAX
    );
}
```

which works since `repeat` explicitly uses `T: Copy` and so does not have to think about non-trivial `Clone`.

But it still may be counter-intuitive for users to observe such long time on the "canonical" vec literal thus the PR.

# Generic solution

This change is explicitly non-generic. Initially I considered it possible to implement in generically, but this would require the specialization to have the following type requirements:
-  the type must be a ZST: easily done via
  ```rust
  if core::mem::size_of::<T>() == 0 {
    todo!("specialization")
  }
  ```
  or
  ```rust
  use core::mem::SizedTypeProperties;
  if T::IS_ZST {
    todo!("specialization")
  }
  ```
- :white_check_mark`: the type must implement `Copy`: implementable non-conflictable via a separate specialization:
  ```rust
  trait IsCopyZst: Sized {
    fn is_copy_zst() -> bool;
  }
  impl<T> IsCopyZst for T {
    fn is_copy_zst() -> bool {
        false
    }
  }
  impl<T: Copy> IsCopyZst for T {
    fn is_copy_zst() -> bool {
        Self::IS_ZST
    }
  }
  ```
-  the type should have a trivial `Clone` implementation: since `vec![t; n]` is specified to use `clone()`, we can only use this "performance optimization" when we are guaranteed that `clone()` does nothing except for copying.

The latter is the real blocker for a generic fix since I am unaware of any way to get this information in a compiler-guaranteed way.

While there may be a fix for this (my friend `@CertainLach` has suggested a potential solution by an perma-unstable fn in `Clone` like `is_trivially_cloneable()` defaulting to `false` and only overridable by `rustc` on derive), this is surely out of this PRs scope.
2023-11-21 09:06:29 +01:00
Nilstrieb
675cba073e
Rollup merge of #118081 - nnethercote:rustc_ty_utils, r=compiler-errors
`rustc_ty_utils` cleanups

Minor improvements I found while looking at this code.

r? ``@lcnr``
2023-11-21 09:06:28 +01:00
Nilstrieb
187d44bfe3
Rollup merge of #118059 - Nilstrieb:unset-cargo, r=dtolnay
Explicitly unset $CARGO for compiletest

Some UI tests trigger behavior in rustc where it reads $CARGO and changes behavior if it exists. To make the tests work that rely on it not being set, make sure it is not set.

By default, this is not set, but people may do weird hacks that cause it to be set.

closes #118058
2023-11-21 09:06:28 +01:00
Nilstrieb
6bb671e7e8
Rollup merge of #117790 - rcvalle:rust-cfi-fix-000000, r=workingjubilee
CFI: Add missing use core::ffi::c_int

Adds missing use core::ffi::c_int for when sanitizer_cfi_normalize_integers is defined.
2023-11-21 09:06:27 +01:00
bors
85c42b751e Auto merge of #115691 - jsgf:typed-json-diags, r=est31,dtolnay
Add `$message_type` field to distinguish json diagnostic outputs

Currently the json-formatted outputs have no way to unambiguously determine which kind of message is being output. A consumer can look for specific fields in the json object (eg "message"), but there's no guarantee that in future some other kind of output will have a field of the same name.

This PR adds a `"type"` field to add json outputs which can be used to unambiguously determine which kind of output it is. The mapping is:

`diagnostic`: regular compiler diagnostics
`artifact`: artifact notifications
`future_incompat`: Future incompatibility report
`unused_extern`: Unused crate warnings/errors

This matches the "internally tagged" representation for serde enums.
2023-11-21 06:30:14 +00:00
Michael Goulet
c9143ea1d9 Unify HashStable implementations 2023-11-21 05:49:45 +00:00
Michael Goulet
426bc70ad6 Add HashStable_NoContext to simplify HashStable implementations in rustc_type_ir 2023-11-21 05:49:44 +00:00
Nicholas Nethercote
72653c1f50 Use macros to avoid expect_* boilerplate.
The majority of these aren't actually used, but I kept them anyway.
2023-11-21 15:36:15 +11:00
Nicholas Nethercote
ec10e3726c Remove some unused functions.
And remove `pub` from some local-only ones.
2023-11-21 15:35:59 +11:00
Nicholas Nethercote
c965a7608d Wrap a long line. 2023-11-21 15:34:41 +11:00
bors
390e3c8b66 Auto merge of #118015 - celinval:smir-place-ty, r=compiler-errors
Add place.ty() and Ty build from a kind to smir

Add a method to retrieve the type of a place and a few utility functions needed to build the projection type. I decided to return a result to avoid panicking if the user passes invalid inputs, such as wrong list of locals.

r? `@spastorino`
2023-11-21 04:32:03 +00:00
bors
baf4abff31 Auto merge of #118107 - matthiaskrgr:rollup-k5bfkfr, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #117327 (Add documentation for some queries)
 - #117835 (Note about object lifetime defaults in does not live long enough error)
 - #117851 (Uplift `InferConst` to `rustc_type_ir`)
 - #117973 (test: Add test for async-move in 2015 Rust proc macro)
 - #117992 (Don't require intercrate mode for negative coherence)
 - #118010 (Typeck break expr even if break is illegal)
 - #118026 (Don't consider regions in `deref_into_dyn_supertrait` lint)
 - #118089 (intercrate_ambiguity_causes: handle self ty infer + reservation impls)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-11-21 02:02:30 +00:00
Santiago Pastorino
8cf94c955f
Fix occurrences of old fn names in comment and tracing 2023-11-20 22:45:28 -03:00
bors
853492329c Auto merge of #116092 - compiler-errors:features-query, r=cjgillot
Unify `defined_lib_features` and `lib_features` queries

Extracts part of https://github.com/rust-lang/rust/pull/115623#discussion_r1318929750

I went with also introducing a `FeatureStability` enum, instead of using `Some(span)` to mean stable and `None` to mean unstable.

r? `@cjgillot`
2023-11-21 00:03:58 +00:00
David Tolnay
fe50c5359e
Update some more cases of "type" -> "$message_type" 2023-11-20 16:02:59 -08:00
bors
3a85a5cfe7 Auto merge of #118101 - dtolnay:cargo, r=weihanglo
Update cargo

9 commits in 9765a449d9b7341c2b49b88da41c2268ea599720..71cd3a926f0cf41eeaf9f2a7f2194b2aff85b0f6
2023-11-17 20:58:23 +0000 to 2023-11-20 15:30:57 +0000
- Handle $message_type in JSON diagnostics (rust-lang/cargo#13016)
- refactor(toml): Further clean up inheritance (rust-lang/cargo#13000)
- Fix `--check-cfg` invocations with zero features (rust-lang/cargo#13011)
- chore: bump `cargo-credential-*` crates as e58b84d broke stuff (rust-lang/cargo#13010)
- contrib docs: Update now that credential crates are published. (rust-lang/cargo#13006)
- Add more resources to the contrib docs. (rust-lang/cargo#13008)
- Respect `rust-lang/rust`'s `omit-git-hash` (rust-lang/cargo#12968)
- Fix clippy-wrapper test race condition. (rust-lang/cargo#12999)
- fix(resolver): Don't do git fetches when updating workspace members (rust-lang/cargo#12975)
2023-11-20 21:06:09 +00:00
Celina G. Val
d94df62398 Improve code per PR comments
- Simplified DefTy::internal
 - Break down place::ty() method
2023-11-20 12:46:14 -08:00
Celina G. Val
d3fa6a0e35 Add place.ty() and Ty build from a kind to smir 2023-11-20 12:43:39 -08:00
ouz-a
f68c6c9528 Fix early param lifetimes in generic_const_exprs 2023-11-20 23:13:36 +03:00
Matthias Krüger
6c62b42347
Rollup merge of #118089 - lcnr:intercrate-ambig-msg, r=compiler-errors
intercrate_ambiguity_causes: handle self ty infer + reservation impls

r? `@compiler-errors`
2023-11-20 20:56:43 +01:00
Matthias Krüger
ca246d32e6
Rollup merge of #118026 - compiler-errors:deref-into-dyn-regions, r=lcnr
Don't consider regions in `deref_into_dyn_supertrait` lint

I actually wonder if we should just warn on *any* deref impl with a target type that matches a supertrait by *def-id*.

cc #89460

r? types
2023-11-20 20:56:43 +01:00
Matthias Krüger
1936e2c938
Rollup merge of #118010 - gurry:117821-ice-no-type-for-local-var, r=compiler-errors
Typeck break expr even if break is illegal

Fixes #117821

We were returning immediately when encountering an illegal break. However, this caused problems later when the expr that the break was returning was evaluated during writeback. So now we don't return and instead simply set tainted by error. This lets typeck of break expr to occur even though we've encountered an illegal break.
2023-11-20 20:56:42 +01:00
Matthias Krüger
0270afee31
Rollup merge of #117992 - compiler-errors:sound-but-not-complete, r=lcnr,aliemjay
Don't require intercrate mode for negative coherence

Negative coherence needs to be *sound*, but does not need to be *complete*, since it's looking for the *existence* of a negative goal, not the non-existence of a positive goal.

This removes some trivial and annoying ambiguities when a negative impl has region constraints.

r? lcnr idk if this needs an fcp but if it does, pls kick it off
2023-11-20 20:56:42 +01:00
Matthias Krüger
7fd7dad07b
Rollup merge of #117973 - CohenArthur:fix-89699, r=lqd
test: Add test for async-move in 2015 Rust proc macro

Fixes #89699

Ran cargo bisect-rustc to find when this was fixed exactly, which is in 474709a9a2
2023-11-20 20:56:41 +01:00
Matthias Krüger
6258697445
Rollup merge of #117851 - compiler-errors:uplift-infer-const, r=spastorino
Uplift `InferConst` to `rustc_type_ir`

We need this in `rustc_type_ir` because the canonicalizer must understand the difference between a const vid and an effect vid. In that way, it's not an implementation detail of the representation of an infer const, but just part of the type ir.

If we find out later on that it's better to leave the representation up to the consumer of `rustc_type_ir`, we could abstract `InferConst` (and probably `InferTy` as well) with some traits, but I don't see the benefit of that indirection currently.
2023-11-20 20:56:41 +01:00
Matthias Krüger
87540879f4
Rollup merge of #117835 - Nilstrieb:note-object-lifetime-defaults, r=compiler-errors
Note about object lifetime defaults in does not live long enough error

This is a aspect of Rust that frequently trips up people who are not aware of it yet. This diagnostic attempts to explain what's happening and why the lifetime constraint, that was never mentioned in the source, arose.

The implementation feels a bit questionable, I'm not sure whether there are better ways to do this. There probably are.

fixes #117835

r? types
2023-11-20 20:56:40 +01:00
Matthias Krüger
da5eebf942
Rollup merge of #117327 - Nilstrieb:more-query-docs, r=compiler-errors
Add documentation for some queries
2023-11-20 20:56:40 +01:00
Michael Goulet
2d187d54fd Store feature stability un-split 2023-11-20 19:11:26 +00:00
Michael Goulet
86299a1247 Unify defined_lib_features and lib_features queries 2023-11-20 19:08:16 +00:00