Commit Graph

6112 Commits

Author SHA1 Message Date
bors 4fd68eb47b Auto merge of #117934 - Young-Flash:dev, r=petrochenkov
feat: make `let_binding_suggestion` more reasonable

This is my first PR for rustc, which trying to fix https://github.com/rust-lang/rust/issues/117894, I am not familiar with some internal api so maybe some modification here isn't the way to go, appreciated for any review suggestion.
2023-11-24 15:26:04 +00:00
Matthias Krüger 98bae8195d
Rollup merge of #118224 - dtolnay:rustdocsortunstable, r=fmease
Sort unstable items last in rustdoc, instead of first

As far as I can tell, this is a bug introduced inadvertently by https://github.com/rust-lang/rust/pull/77817 in Rust 1.49. Older toolchains used to sort unstable items last.

Notice how in the code before that PR, `(Unstable, Stable) => return Ordering::Greater` in src/librustdoc/html/render/mod.rs. Whereas after that PR, `(Unstable, Stable) => return Ordering::Less`.

Compare https://doc.rust-lang.org/1.48.0/std/marker/index.html vs https://doc.rust-lang.org/1.49.0/std/marker/index.html.
2023-11-24 08:23:54 +01:00
bors eab8c7d5fd Auto merge of #118105 - notriddle:master, r=fmease
rustdoc: rename `issue-\d+.rs` tests to have meaningful names (part 4)

Follow up

* https://github.com/rust-lang/rust/pull/116214
* https://github.com/rust-lang/rust/pull/116432
* https://github.com/rust-lang/rust/pull/116824
2023-11-24 02:23:31 +00:00
David Tolnay b77aa74a2d
Sort unstable items last in rustdoc, instead of first 2023-11-23 17:20:13 -08:00
David Tolnay a994f46421
Add test of rustdoc sort order for stable vs unstable item 2023-11-23 17:20:13 -08:00
Michael Howell 4f64ff171b rustdoc: move doctest tests to folder 2023-11-23 14:56:03 -07:00
Michael Howell fdde5c77a8 rustdoc: move ICE tests to ui 2023-11-23 14:54:19 -07:00
bors a4a5c976fe Auto merge of #118192 - Kyuuhachi:issue-118180, r=fmease
Don't print "private fields" on empty tuple structs

Closes #118180.

While working on this I also noticed that empty struct variants are also rendered rather awkwardly. I'll make another issue for that, since I don't know what the correct rendering would be.
2023-11-23 17:41:46 +00:00
Kyuuhachi a21d7713db Don't print "private fields" on empty tuple structs
Test for presence rather than absence

Remove redundant tests

Issues in those parts will likely be caught by other parts of the test suite.
2023-11-23 16:04:10 +01:00
Vadim Petrochenkov edf6c9c223 Add an experimental feature gate for function delegation
In accordance with the [process](https://github.com/rust-lang/lang-team/blob/master/src/how_to/experiment.md).

Detailed description of the feature can be found in the RFC repo - https://github.com/rust-lang/rfcs/pull/3530.
2023-11-23 17:27:31 +03:00
Young-Flash c710db8ea7 feat: make let_binding_suggestion more reasonable 2023-11-23 20:22:17 +08:00
Matthias Krüger add423bcf7
Rollup merge of #118146 - compiler-errors:deref-into-dyn-regions, r=lcnr
Rework supertrait lint once again

I accidentally pushed the wrong commits because I totally didn't check I was on the right computer when updating #118026.
Sorry, this should address all the nits in #118026.

r? lcnr
2023-11-23 07:06:30 +01:00
Matthias Krüger 82538b72c0
Rollup merge of #118131 - lukas-code:multi-default, r=wesleywiser
improve tool-only help for multiple `#[default]` variants

When defining an enum with multiple `#[default]` variants, we emit a tool-only suggestion for every `#[default]`ed variant to remove all other `#[default]`s. This PR improves the suggestion to correctly handle the cases where one variant has multiple `#[default]`s and where different `#[default]`s have the same span due to macro expansions.

fixes https://github.com/rust-lang/rust/issues/118119
2023-11-23 07:06:30 +01:00
bors 360bafad68 Auto merge of #118065 - estebank:core-not-found-404, r=TaKO8Ki
When failing to import `core`, suggest `std`
2023-11-23 02:26:52 +00:00
Michael Goulet 15fbcc3636 Rework supertrait lint once again 2023-11-22 21:51:39 +00:00
Esteban Küber ec50f1c90b When failing to import `core`, suggest `std` 2023-11-22 19:30:47 +00:00
bors 06d1afe518 Auto merge of #118178 - compiler-errors:rollup-0i11w85, r=compiler-errors
Rollup of 6 pull requests

Successful merges:

 - #118012 (Add support for global allocation in smir)
 - #118013 (Enable Rust to use the EHCont security feature of Windows)
 - #118100 (Enable profiler in dist-powerpc64-linux)
 - #118142 (Tighten up link attributes for llvm-wrapper bindings)
 - #118147 (Fix some unnecessary casts)
 - #118161 (Allow defining opaques in `check_coroutine_obligations`)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-11-22 18:49:51 +00:00
Michael Goulet 4ec548afbe
Rollup merge of #118161 - compiler-errors:coroutine-obligation-opaques, r=lcnr
Allow defining opaques in `check_coroutine_obligations`

In the new trait solver, when an obligation stalls on an unresolved coroutine witness, we will stash away the *root* obligation, even if the stalled obligation is only a distant descendent of the root obligation, since the new solver is purely recursive.

This means that we may need to reprocess alias-relate obligations (and others) which may define opaque types in the new solver. Currently, we use the coroutine's def id as the defining anchor in `check_coroutine_obligations`, which will allow defining no opaque types, resulting in errors like:

```
error[E0271]: type mismatch resolving `{coroutine@<source>:6:5: 6:17} <: impl Clone`
 --> <source>:6:5
  |
6 | /     move |_: ()| {
7 | |         let () = yield ();
8 | |     }
  | |_____^ types differ
```

So this PR fixes the defining anchor and does the same trick as `check_opaque_well_formed`, where we manually compare opaques that were defined against their hidden types to make sure they weren't defined differently when processing these stalled coroutine obligations.

r? `@lcnr` cc `@cjgillot`
2023-11-22 09:28:52 -08:00
Michael Goulet 1fb2624205
Rollup merge of #118013 - sivadeilra:user/ardavis/ehcont, r=wesleywiser
Enable Rust to use the EHCont security feature of Windows

In the future Windows will enable Control-flow Enforcement Technology (CET aka Shadow Stacks). To protect the path where the context is updated during exception handling, the binary is required to enumerate valid unwind entrypoints in a dedicated section which is validated when the context is being set during exception handling.

The required support for EHCONT Guard has already been merged into LLVM, long ago. This change simply adds the Rust codegen option to enable it.

Relevant LLVM change: https://reviews.llvm.org/D40223

This also adds a new `ehcont-guard` option to the bootstrap config which enables EHCont Guard when building std.

We at Microsoft have been using this feature for a significant period of time; we are confident that the LLVM feature, when enabled, generates well-formed code.

We currently enable EHCONT using a codegen feature, but I'm certainly open to refactoring this to be a target feature instead, or to use any appropriate mechanism to enable it.
2023-11-22 09:28:50 -08:00
Michael Goulet d58ded9058
Rollup merge of #118012 - celinval:smir-alloc, r=ouz-a
Add support for global allocation in smir

Add APIs to StableMir to support global allocation. Before this change, StableMir users had no API available to retrieve Allocation provenance information. They had to resource to internal APIs instead.

One example is retrieving the Allocation of an `&str`. See test for an example on how the API can be used.
2023-11-22 09:28:49 -08:00
bors 6d2b84b3ed Auto merge of #118133 - Urgau:stabilize_trait_upcasting, r=WaffleLapkin
Stabilize RFC3324 dyn upcasting coercion

This PR stabilize the `trait_upcasting` feature, aka https://github.com/rust-lang/rfcs/pull/3324.

The FCP was completed here: https://github.com/rust-lang/rust/issues/65991#issuecomment-1817552398.

~~And also remove the `deref_into_dyn_supertrait` lint which is now handled by dyn upcasting coercion.~~

Heavily inspired by https://github.com/rust-lang/rust/pull/101718
Fixes https://github.com/rust-lang/rust/issues/65991
2023-11-22 16:15:34 +00:00
bors 73bc12199e Auto merge of #112380 - jieyouxu:useless-bindings-lint, r=WaffleLapkin
Add allow-by-default lint for unit bindings

### Example

```rust
#![warn(unit_bindings)]

macro_rules! owo {
    () => {
        let whats_this = ();
    }
}

fn main() {
    // No warning if user explicitly wrote `()` on either side.
    let expr = ();
    let () = expr;
    let _ = ();

    let _ = expr; //~ WARN binding has unit type
    let pat = expr; //~ WARN binding has unit type
    let _pat = expr; //~ WARN binding has unit type

    // No warning for let bindings with unit type in macro expansions.
    owo!();

    // No warning if user explicitly annotates the unit type on the binding.
    let pat: () = expr;
}
```

outputs

```
warning: binding has unit type `()`
  --> $DIR/unit-bindings.rs:17:5
   |
LL |     let _ = expr;
   |     ^^^^-^^^^^^^^
   |         |
   |         this pattern is inferred to be the unit type `()`
   |
note: the lint level is defined here
  --> $DIR/unit-bindings.rs:3:9
   |
LL | #![warn(unit_bindings)]
   |         ^^^^^^^^^^^^^

warning: binding has unit type `()`
  --> $DIR/unit-bindings.rs:18:5
   |
LL |     let pat = expr;
   |     ^^^^---^^^^^^^^
   |         |
   |         this pattern is inferred to be the unit type `()`

warning: binding has unit type `()`
  --> $DIR/unit-bindings.rs:19:5
   |
LL |     let _pat = expr;
   |     ^^^^----^^^^^^^^
   |         |
   |         this pattern is inferred to be the unit type `()`

warning: 3 warnings emitted
```

This lint is not triggered if any of the following conditions are met:

- The user explicitly annotates the binding with the `()` type.
- The binding is from a macro expansion.
- The user explicitly wrote `let () = init;`
- The user explicitly wrote `let pat = ();`. This is allowed for local lifetimes.

### Known Issue

It is known that this lint can trigger on some proc-macro generated code whose span returns false for `Span::from_expansion` because e.g. the proc-macro simply forwards user code spans, and otherwise don't have distinguishing syntax context compared to non-macro-generated code. For those kind of proc-macros, I believe the correct way to fix them is to instead emit identifers with span like `Span::mixed_site().located_at(user_span)`.

Closes #71432.
2023-11-22 14:03:16 +00:00
Urgau 4c2d6de70e Stabilize RFC3324 dyn upcasting coercion
Aka trait_upcasting feature.

And also adjust the `deref_into_dyn_supertrait` lint.
2023-11-22 13:56:36 +01:00
bors a6b8ae582a Auto merge of #118086 - nnethercote:queries-cleanups, r=bjorn3
Queries cleanups

r? `@bjorn3`
2023-11-22 11:44:56 +00:00
bors 855c6836b7 Auto merge of #118071 - Urgau:check-cfg-cargo-feature, r=petrochenkov
Remove `feature` from the list of well known check-cfg name

This PR removes `feature` from the list of well known check-cfg.

This is done for multiple reasons:
 - Cargo is the source of truth, rustc shouldn't have any knowledge of it
 - It creates a conflict between Cargo and rustc when there are no features defined.
   In this case Cargo won't pass any `--check-cfg` for `feature` since no feature will ever be passed, but rustc by having in it's list adds a implicit `cfg(feature, values(any()))` which is completely wrong. Having any cfg `feature` is unexpected not allow any `feature` value.

While doing this, I took the opportunity to specialise the diagnostic a bit for the case above.

r? `@petrochenkov`
2023-11-22 07:31:13 +00:00
Michael Goulet 4f958a4802 Allow defining opaques in check_coroutine_obligations 2023-11-22 03:44:13 +00:00
Celina G. Val c07a6d5c9a Add allocation test and a bit more documentation 2023-11-21 19:16:58 -08:00
Nicholas Nethercote 971010ea5a Merge `Queries::{ongoing_codegen,linker}`.
There is no real need for them to be separate.
2023-11-22 13:22:49 +11:00
Nicholas Nethercote 3a4798c92d Make `Compiler::{sess,codegen_backend}` public.
And remove the relevant getters on `Compiler` and `Queries`.
2023-11-22 13:22:41 +11:00
Matthias Krüger 802f71b294
Rollup merge of #118112 - compiler-errors:index-ambiguity-ice, r=aliemjay
Don't ICE when ambiguity is found when selecting `Index` implementation in typeck

Fixes #118111

The problem here is when we're manually "selecting" an impl for `base_ty: Index<?0>`, we don't consider placeholder region errors (leak check) or ambiguous predicates. Those can lead to us not actually emitting any fulfillment errors on line 3131.
2023-11-21 23:46:20 +01:00
Arlie Davis 9429d68842 convert ehcont-guard to an unstable option 2023-11-21 14:24:23 -08:00
Arlie Davis e11d8d147b Add support for generating the EHCont section
In the future Windows will enable Control-flow Enforcement Technology
(CET aka Shadow Stacks). To protect the path where the context is
updated during exception handling, the binary is required to enumerate
valid unwind entrypoints in a dedicated section which is validated when
the context is being set during exception handling.

The required support for EHCONT has already been merged into LLVM,
long ago. This change adds the Rust codegen option to enable it.

Reference:

* https://reviews.llvm.org/D40223

This also adds a new `ehcont-guard` option to the bootstrap config which
enables EHCont Guard when building std.
2023-11-21 13:41:23 -08:00
Michael Howell 28f17d97a9 rustdoc-search: make primitives and keywords less special
The search sorting code already sorts by item type discriminant,
putting things with smaller discriminants first. There was
also a special case for sorting keywords and primitives earlier,
and this commit removes it by giving them lower discriminants.

The sorting code has another criteria where items with descriptions
appear earlier than items without, and that criteria has higher
priority than the item type. This shouldn't matter, though,
because primitives and keywords normally only appear in the
standard library, and it always gives them descriptions.
2023-11-21 13:59:26 -07:00
Urgau 1c37997fa7 Improve diagnostic for unexpected feature config name from Cargo 2023-11-21 19:06:58 +01:00
Urgau 9f15acec47 Remove `feature` from the list of well known check-cfg name 2023-11-21 19:06:58 +01: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 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 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
Lukas Markeffsky f697a00f76 improve help for multiple `#[default]` variants 2023-11-21 12:20:54 +00: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
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
Michael Goulet 273dc22b04 Don't ICE when ambiguity is found when selecting Index implementation in typeck 2023-11-20 23:37:04 +00: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