Commit Graph

632 Commits

Author SHA1 Message Date
bors
481d45abec Auto merge of #115822 - compiler-errors:stabilize-rpitit, r=jackh726
Stabilize `async fn` and return-position `impl Trait` in trait

# Stabilization report

This report proposes the stabilization of `#![feature(return_position_impl_trait_in_trait)]` ([RPITIT][RFC 3425]) and `#![feature(async_fn_in_trait)]` ([AFIT][RFC 3185]). These are both long awaited features that increase the expressiveness of the Rust language and trait system.

Closes #91611

[RFC 3185]: https://rust-lang.github.io/rfcs/3185-static-async-fn-in-trait.html
[RFC 3425]: https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html

## Updates from thread

The thread has covered two major concerns:

* [Given that we don't have RTN, what should we stabilize?](https://github.com/rust-lang/rust/pull/115822#issuecomment-1731149475) -- proposed resolution is [adding a lint](https://github.com/rust-lang/rust/pull/115822#issuecomment-1728354622) and [careful messaging](https://github.com/rust-lang/rust/pull/115822#issuecomment-1731136169)
* [Interaction between outlives bounds and capture semantics](https://github.com/rust-lang/rust/pull/115822#issuecomment-1731153952) -- This is fixable in a forwards-compatible way via #116040, and also eventually via ATPIT.

## Stabilization Summary

This stabilization allows the following examples to work.

### Example of return-position `impl Trait` in trait definition

```rust
trait Bar {
    fn bar(self) -> impl Send;
}
```

This declares a trait method that returns *some* type that implements `Send`.  It's similar to writing the following using an associated type, except that the associated type is anonymous.

```rust
trait Bar {
    type _0: Send;
    fn bar(self) -> Self::_0;
}
```

### Example of return-position `impl Trait` in trait implementation

```rust
impl Bar for () {
    fn bar(self) -> impl Send {}
}
```

This defines a method implementation that returns an opaque type, just like [RPIT][RFC 1522] does, except that all in-scope lifetimes are captured in the opaque type (as is already true for `async fn` and as is expected to be true for RPIT in Rust Edition 2024), as described below.

[RFC 1522]: https://rust-lang.github.io/rfcs/1522-conservative-impl-trait.html

### Example of `async fn` in trait

```rust
trait Bar {
    async fn bar(self);
}

impl Bar for () {
    async fn bar(self) {}
}
```

This declares a trait method that returns *some* [`Future`](https://doc.rust-lang.org/core/future/trait.Future.html) and a corresponding method implementation.  This is equivalent to writing the following using RPITIT.

```rust
use core::future::Future;

trait Bar {
    fn bar(self) -> impl Future<Output = ()>;
}

impl Bar for () {
    fn bar(self) -> impl Future<Output = ()> { async {} }
}
```

The desirability of this desugaring being available is part of why RPITIT and AFIT are being proposed for stabilization at the same time.

## Motivation

Long ago, Rust added [RPIT][RFC 1522] and [`async`/`await`][RFC 2394].  These are major features that are widely used in the ecosystem.  However, until now, these feature could not be used in *traits* and trait implementations.  This left traits as a kind of second-class citizen of the language.  This stabilization fixes that.

[RFC 2394]: https://rust-lang.github.io/rfcs/2394-async_await.html

### `async fn` in trait

Async/await allows users to write asynchronous code much easier than they could before. However, it doesn't play nice with other core language features that make Rust the great language it is, like traits. Support for `async fn` in traits has been long anticipated and was not added before due to limitations in the compiler that have now been lifted.

`async fn` in traits will unblock a lot of work in the ecosystem and the standard library. It is not currently possible to write a trait that is implemented using `async fn`. The workarounds that exist are undesirable because they require allocation and dynamic dispatch, and any trait that uses them will become obsolete once native `async fn` in trait is stabilized.

We also have ample evidence that there is demand for this feature from the [`async-trait` crate][async-trait], which emulates the feature using dynamic dispatch. The async-trait crate is currently the #5 async crate on crates.io ranked by recent downloads, receiving over 78M all-time downloads. According to a [recent analysis][async-trait-analysis], 4% of all crates use the `#[async_trait]` macro it provides, representing 7% of all function and method signatures in trait definitions on crates.io. We think this is a *lower bound* on demand for the feature, because users are unlikely to use `#[async_trait]` on public traits on crates.io for the reasons already given.

[async-trait]: https://crates.io/crates/async-trait
[async-trait-analysis]: https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/RPIT.20capture.20rules.20.28capturing.20everything.29/near/389496292

### Return-position `impl Trait` in trait

`async fn` always desugars to a function that returns `impl Future`.

```rust!
async fn foo() -> i32 { 100 }

// Equivalent to:
fn foo() -> impl Future<Output = i32> { async { 100 } }
```

All `async fn`s today can be rewritten this way. This is useful because it allows adding behavior that runs at the time of the function call, before the first `.await` on the returned future.

In the spirit of supporting the same set of features on `async fn` in traits that we do outside of traits, it makes sense to stabilize this as well. As described by the [RPITIT RFC][rpitit-rfc], this includes the ability to mix and match the equivalent forms in traits and their corresponding impls:

```rust!
trait Foo {
    async fn foo(self) -> i32;
}

// Can be implemented as:
impl Foo for MyType {
    fn foo(self) -> impl Future<Output = i32> {
        async { 100 }
    }
}
```

Return-position `impl Trait` in trait is useful for cases beyond async, just as regular RPIT is. As a simple example, the RFC showed an alternative way of writing the `IntoIterator` trait with one fewer associated type.

```rust!
trait NewIntoIterator {
    type Item;
    fn new_into_iter(self) -> impl Iterator<Item = Self::Item>;
}

impl<T> NewIntoIterator for Vec<T> {
    type Item = T;
    fn new_into_iter(self) -> impl Iterator<Item = T> {
        self.into_iter()
    }
}
```

[rpitit-rfc]: https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html

## Major design decisions

This section describes the major design decisions that were reached after the RFC was accepted:

- EDIT: Lint against async fn in trait definitions

    - Until the [send bound problem](https://smallcultfollowing.com/babysteps/blog/2023/02/01/async-trait-send-bounds-part-1-intro/) is resolved, the use of `async fn` in trait definitions could lead to a bad experience for people using work-stealing executors (by far the most popular choice). However, there are significant use cases for which the current support is all that is needed (single-threaded executors, such as those used in embedded use cases, as well as thread-per-core setups). We are prioritizing serving users well over protecting people from misuse, and therefore, we opt to stabilize the full range of functionality; however, to help steer people correctly, we are will issue a warning on the use of `async fn` in trait definitions that advises users about the limitations. (See [this summary comment](https://github.com/rust-lang/rust/pull/115822#issuecomment-1731149475) for the details of the concern, and [this comment](https://github.com/rust-lang/rust/pull/115822#issuecomment-1728354622) for more details about the reasoning that led to this conclusion.)

- Capture rules:

    - The RFC's initial capture rules for lifetimes in impls/traits were found to be imprecisely precise and to introduce various inconsistencies. After much discussion, the decision was reached to make `-> impl Trait` in traits/impls capture *all* in-scope parameters, including both lifetimes and types. This is a departure from the behavior of RPITs in other contexts; an RFC is currently being authored to change the behavior of RPITs in other contexts in a future edition.

    - Major discussion links:

        - [Lang team design meeting from 2023-07-26](https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ?view)

- Refinement:

    - The [refinement RFC] initially proposed that impl signatures that are more specific than their trait are not allowed unless the `#[refine]` attribute was included, but left it as an open question how to implement this. The stabilized proposal is that it is not a hard error to omit `#[refine]`, but there is a lint which fires if the impl's return type is more precise than the trait. This greatly simplified the desugaring and implementation while still achieving the original goal of ensuring that users do not accidentally commit to a more specific return type than they intended.

    - Major discussion links:

        - [Zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/.60.23.5Brefine.5D.60.20as.20a.20lint)

[refinement RFC]: https://rust-lang.github.io/rfcs/3245-refined-impls.html

## What is stabilized

### Async functions in traits and trait implementations

* `async fn` are now supported in traits and trait implementations.
* Associated functions in traits that are `async` may have default bodies.

### Return-position impl trait in traits and trait implementations

* Return-position `impl Trait`s are now supported in traits and trait implementations.
    * Return-position `impl Trait` in implementations are treated like regular return-position `impl Trait`s, and therefore behave according to the same inference rules for hidden type inference and well-formedness.
* Associated functions in traits that name return-position `impl Trait`s may have default bodies.
* Implementations may provide either concrete types or `impl Trait` for each corresponding `impl Trait` in the trait method signature.

For a detailed exploration of the technical implementation of return-position `impl Trait` in traits, see [the dev guide](https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html).

### Mixing `async fn` in trait and return-position `impl Trait` in trait

A trait function declaration that is `async fn ..() -> T` may be satisfied by an implementation function that returns `impl Future<Output = T>`, or vice versa.

```rust
trait Async {
    async fn hello();
}

impl Async for () {
    fn hello() -> impl Future<Output = ()> {
        async {}
    }
}

trait RPIT {
    fn hello() -> impl Future<Output = String>;
}

impl RPIT for () {
    async fn hello() -> String {
        "hello".to_string()
    }
}
```

### Return-position `impl Trait` in traits and trait implementations capture all in-scope lifetimes

Described above in "major design decisions".

### Return-position `impl Trait` in traits are "always revealing"

When a trait uses `-> impl Trait` in return position, it logically desugars to an associated type that represents the return (the actual implementation in the compiler is different, as described below). The value of this associated type is determined by the actual return type written in the impl; if the impl also uses `-> impl Trait` as the return type, then the value of the associated type is an opaque type scoped to the impl method (similar to what you would get when calling an inherent function returning `-> impl Trait`). As with any associated type, the value of this special associated type can be revealed by the compiler if the compiler can figure out what impl is being used.

For example, given this trait:

```rust
trait AsDebug {
    fn as_debug(&self) -> impl Debug;
}
```

A function working with the trait generically is only able to see that the return value is `Debug`:

```rust
fn foo<T: AsDebug>(t: &T) {
    let u = t.as_debug();
    println!("{}", u); // ERROR: `u` is not known to implement `Display`
}
```

But if a function calls `as_debug` on a known type (say, `u32`), it may be able to resolve the return type more specifically, if that implementation specifies a concrete type as well:

```rust
impl AsDebug for u32 {
    fn as_debug(&self) -> u32 {
        *self
    }
}

fn foo(t: &u32) {
    let u: u32 = t.as_debug(); // OK!
    println!("{}",  t.as_debug()); // ALSO OK (since `u32: Display`).
}
```

The return type used in the impl therefore represents a **semver binding** promise from the impl author that the return type of `<u32 as AsDebug>::as_debug` will not change. This could come as a surprise to users, who might expect that they are free to change the return type to any other type that implements `Debug`. To address this, we include a [`refining_impl_trait` lint](https://github.com/rust-lang/rust/pull/115582) that warns if the impl uses a specific type -- the `impl AsDebug for u32` above, for example, would toggle the lint.

The lint message explains what is going on and encourages users to `allow` the lint to indicate that they meant to refine the return type:

```rust
impl AsDebug for u32 {
    #[allow(refining_impl_trait)]
    fn as_debug(&self) -> u32 {
        *self
    }
}
```

[RFC #3245](https://github.com/rust-lang/rfcs/pull/3245) proposed a new attribute, `#[refine]`, that could also be used to "opt-in" to refinements like this (and which would then silence the lint). That RFC is not currently implemented -- the `#[refine]` attribute is also expected to reveal other details from the signature and has not yet been fully implemented.

### Return-position `impl Trait` and `async fn` in traits are opted-out of object safety checks when the parent function has `Self: Sized`

```rust
trait IsObjectSafe {
    fn rpit() -> impl Sized where Self: Sized;
    async fn afit() where Self: Sized;
}
```

Traits that mention return-position `impl Trait` or `async fn` in trait when the associated function includes a `Self: Sized` bound will remain object safe. That is because the associated function that defines them will be opted-out of the vtable of the trait, and the associated types will be unnameable from any trait object.

This can alternatively be seen as a consequence of https://github.com/rust-lang/rust/pull/112319#issue-1742251747 and the desugaring of return-position `impl Trait` in traits to associated types which inherit the where-clauses of the associated function that defines them.

## What isn't stabilized (aka, potential future work)

### Dynamic dispatch

As stabilized, traits containing RPITIT and AFIT are **not dyn compatible**. This means that you cannot create `dyn Trait` objects from them and can only use static dispatch. The reason for this limitation is that dynamic dispatch support for RPITIT and AFIT is more complex than static dispatch, as described on the [async fundamentals page](https://rust-lang.github.io/async-fundamentals-initiative/evaluation/challenges/dyn_traits.html). The primary challenge to using `dyn Trait` in today's Rust is that **`dyn Trait` today must list the values of all associated types**. This means you would have to write `dyn for<'s> Trait<Foo<'s> = XXX>` where `XXX` is the future type defined by the impl, such as `F_A`. This is not only verbose (or impossible), it also uniquely ties the `dyn Trait` to a particular impl, defeating the whole point of `dyn Trait`.

The precise design for handling dynamic dispatch is not yet determined. Top candidates include:

- [callee site selection][], in which we permit unsized return values so that the return type for an `-> impl Foo` method be can be `dyn Foo`, but then users must specify the type of wide pointer at the call-site in some fashion.

- [`dyn*`][], where we create a built-in encapsulation of a "wide pointer" and map the associated type corresponding to an RPITIT to the corresponding `dyn*` type (`dyn*` itself is not exposed to users as a type in this proposal, though that could be a future extension).

[callee site selection]: https://smallcultfollowing.com/babysteps/blog/2022/09/21/dyn-async-traits-part-9-callee-site-selection/

[`dyn*`]: https://smallcultfollowing.com/babysteps/blog/2022/03/29/dyn-can-we-make-dyn-sized/

### Where-clause bounds on return-position `impl Trait` in traits or async futures (RTN/ART)

One limitation of async fn in traits and RPITIT as stabilized is that there is no way for users to write code that adds additional bounds beyond those listed in the `-> impl Trait`. The most common example is wanting to write a generic function that requires that the future returned from an `async fn` be `Send`:

```rust
trait Greet {
    async fn greet(&self);
}

fn greet_in_parallel<G: Greet>(g: &G) {
    runtime::spawn(async move {
        g.greet().await; //~ ERROR: future returned by `greet` may not be `Send`
    })
}
```

Currently, since the associated types added for the return type are anonymous, there is no where-clause that could be added to make this code compile.

There have been various proposals for how to address this problem (e.g., [return type notation][rtn] or having an annotation to give a name to the associated type), but we leave the selection of one of those mechanisms to future work.

[rtn]: https://smallcultfollowing.com/babysteps/blog/2023/02/13/return-type-notation-send-bounds-part-2/

In the meantime, there are workarounds that one can use to address this problem, listed below.

#### Require all futures to be `Send`

For many users, the trait may only ever be used with `Send` futures, in which case one can write an explicit `impl Future + Send`:

```rust
trait Greet {
    fn greet(&self) -> impl Future<Output = ()> + Send;
}
```

The nice thing about this is that it is still compatible with using `async fn` in the trait impl. In the async working group case studies, we found that this could work for the [builder provider API](https://rust-lang.github.io/async-fundamentals-initiative/evaluation/case-studies/builder-provider-api.html). This is also the default approach used by the `#[async_trait]` crate which, as we have noted, has seen widespread adoption.

#### Avoid generics

This problem only applies when the `Self` type is generic. If the `Self` type is known, then the precise return type from an `async fn` is revealed, and the `Send` bound can be inferred thanks to auto-trait leakage. Even in cases where generics may appear to be required, it is sometimes possible to rewrite the code to avoid them. The [socket handler refactor](https://rust-lang.github.io/async-fundamentals-initiative/evaluation/case-studies/socket-handler.html) case study provides one such example.

### Unify capture behavior for `-> impl Trait` in inherent methods and traits

As stabilized, the capture behavior for `-> impl Trait` in a trait (whether as part of an async fn or a RPITIT) captures all types and lifetimes, whereas the existing behavior for inherent methods only captures types and lifetimes that are explicitly referenced. Capturing all lifetimes in traits was necessary to avoid various surprising inconsistencies; the expressed intent of the lang team is to extend that behavior so that we also capture all lifetimes in inherent methods, which would create more consistency and also address a common source of user confusion, but that will have to happen over the 2024 edition. The RFC is in progress. Should we opt not to accept that RFC, we can bring the capture behavior for `-> impl Trait` into alignment in other ways as part of the 2024 edition.

### `impl_trait_projections`

Orthgonal to `async_fn_in_trait` and `return_position_impl_trait_in_trait`, since it can be triggered on stable code. This will be stabilized separately in [#115659](https://github.com/rust-lang/rust/pull/115659).

<details>
If we try to write this code without `impl_trait_projections`, we will get an error:

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

trait Foo {
    type Error;
    async fn foo(&mut self) -> Result<(), Self::Error>;
}

impl<T: Foo> Foo for &mut T {
    type Error = T::Error;
    async fn foo(&mut self) -> Result<(), Self::Error> {
        T::foo(self).await
    }
}
```

The error relates to the use of `Self` in a trait impl when the self type has a lifetime. It can be worked around by rewriting the impl not to use `Self`:

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

trait Foo {
    type Error;
    async fn foo(&mut self) -> Result<(), Self::Error>;
}

impl<T: Foo> Foo for &mut T {
    type Error = T::Error;
    async fn foo(&mut self) -> Result<(), <&mut T as Foo>::Error> {
        T::foo(self).await
    }
}
```
</details>

## Tests

Tests are generally organized between return-position `impl Trait` and `async fn` in trait, when the distinction matters.
* RPITIT: https://github.com/rust-lang/rust/tree/master/tests/ui/impl-trait/in-trait
* AFIT: https://github.com/rust-lang/rust/tree/master/tests/ui/async-await/in-trait

## Remaining bugs and open issues

* #112047: Indirection introduced by `async fn` and return-position `impl Trait` in traits may hide cycles in opaque types, causing overflow errors that can only be discovered by monomorphization.
* #111105 - `async fn` in trait is susceptible to issues with checking auto traits on futures' generators, like regular `async`. This is a manifestation of #110338.
    * This was deemed not blocking because fixing it is forwards-compatible, and regular `async` is subject to the same issues.
* #104689: `async fn` and return-position `impl Trait` in trait requires the late-bound lifetimes in a trait and impl function signature to be equal.
    * This can be relaxed in the future with a smarter lexical region resolution algorithm.
* #102527: Nesting return-position `impl Trait` in trait deeply may result in slow compile times.
    * This has only been reported once, and can be fixed in the future.
* #108362: Inference between return types and generics of a function may have difficulties when there's an `.await`.
    * This isn't related to AFIT (https://github.com/rust-lang/rust/issues/108362#issuecomment-1717927918) -- using traits does mean that there's possibly easier ways to hit it.
* #112626: Because `async fn` and return-position `impl Trait` in traits lower to associated types, users may encounter strange behaviors when implementing circularly dependent traits.
    * This is not specific to RPITIT, and is a limitation of associated types: https://github.com/rust-lang/rust/issues/112626#issuecomment-1603405105
* **(Nightly)** #108309: `async fn` and return-position `impl Trait` in trait do not support specialization. This was deemed not blocking, since it can be fixed in the future (e.g. #108321) and specialization is a nightly feature.

#### (Nightly) Return type notation bugs

RTN is not being stabilized here, but there are some interesting outstanding bugs. None of them are blockers for AFIT/RPITIT, but I'm noting them for completeness.

<details>

* #109924 is a bug that occurs when a higher-ranked trait bound has both inference variables and associated types. This is pre-existing -- RTN just gives you a more convenient way of producing them. This should be fixed by the new trait solver.
* #109924 is a manifestation of a more general issue with `async` and auto-trait bounds: #110338. RTN does not cause this issue, just allows us to put `Send` bounds on the anonymous futures that we have in traits.
* #112569 is a bug similar to associated type bounds, where nested bounds are not implied correctly.

</details>

## Alternatives

### Do nothing

We could choose not to stabilize these features. Users that can use the `#[async_trait]` macro would continue to do so. Library maintainers would continue to avoid async functions in traits, potentially blocking the stable release of many useful crates.

### Stabilize `impl Trait` in associated type instead

AFIT and RPITIT solve the problem of returning unnameable types from trait methods. It is also possible to solve this by using another unstable feature, `impl Trait` in an associated type. Users would need to define an associated type in both the trait and trait impl:

```rust!
trait Foo {
    type Fut<'a>: Future<Output = i32> where Self: 'a;
    fn foo(&self) -> Self::Fut<'_>;
}

impl Foo for MyType {
    type Fut<'a> where Self: 'a = impl Future<Output = i32>;
    fn foo(&self) -> Self::Fut<'_> {
        async { 42 }
    }
}
```

This also has the advantage of allowing generic code to bound the associated type. However, it is substantially less ergonomic than either `async fn` or `-> impl Future`, and users still expect to be able to use those features in traits. **Even if this feature were stable, we would still want to stabilize AFIT and RPITIT.**

That said, we can have both. `impl Trait` in associated types is desireable because it can be used in existing traits with explicit associated types, among other reasons. We *should* stabilize this feature once it is ready, but that's outside the scope of this proposal.

### Use the old capture semantics for RPITIT

We could choose to make the capture rules for RPITIT consistent with the existing rules for RPIT. However, there was strong consensus in a recent [lang team meeting](https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ?view) that we should *change* these rules, and furthermore that new features should adopt the new rules.

This is consistent with the tenet in RFC 3085 of favoring ["Uniform behavior across editions"](https://rust-lang.github.io/rfcs/3085-edition-2021.html#uniform-behavior-across-editions) when possible. It greatly reduces the complexity of the feature by not requiring us to answer, or implement, the design questions that arise out of the interaction between the current capture rules and traits. This reduction in complexity – and eventual technical debt – is exactly in line with the motivation listed in the aforementioned RFC.

### Make refinement a hard error

Refinement (`refining_impl_trait`) is only a concern for library authors, and therefore doesn't really warrant making into a deny-by-default warning or an error.

Additionally, refinement is currently checked via a lint that compares bounds in the `impl Trait`s in the trait and impl syntactically. This is good enough for a warning that can be opted-out, but not if this were a hard error, which would ideally be implemented using fully semantic, implicational logic. This was implemented (#111931), but also is an unnecessary burden on the type system for little pay-off.

## History

- Dec 7, 2021: [RFC #3185: Static async fn in traits](https://rust-lang.github.io/rfcs/3185-static-async-fn-in-trait.html) merged
- Sep 9, 2022: [Initial implementation](https://github.com/rust-lang/rust/pull/101224) of AFIT and RPITIT landed
- Jun 13, 2023: [RFC #3425: Return position `impl Trait` in traits](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html) merged

<!--These will render pretty when pasted into github-->
Non-exhaustive list of PRs that are particularly relevant to the implementation:

- #101224
- #103491
- #104592
- #108141
- #108319
- #108672
- #112988
- #113182 (later made redundant by #114489)
- #113215
- #114489
- #115467
- #115582

Doc co-authored by `@nikomatsakis,` `@tmandry,` `@traviscross.` Thanks also to `@spastorino,` `@cjgillot` (for changes to opaque captures!), `@oli-obk` for many reviews, and many other contributors and issue-filers. Apologies if I left your name off 😺
2023-10-14 07:29:08 +00:00
bors
39acbed8d6 Auto merge of #116407 - Mark-Simulacrum:bootstrap-bump, r=onur-ozkan
Bump bootstrap compiler to just-released beta

https://forge.rust-lang.org/release/process.html#master-bootstrap-update-t-2-day-tuesday
2023-10-14 05:44:48 +00:00
Michael Goulet
59315b8a63 Stabilize AFIT and RPITIT 2023-10-13 21:01:36 +00:00
Nicholas Nethercote
81d1f7ea9d Use a closure when setting State::Active. 2023-10-05 19:56:19 +11:00
Nicholas Nethercote
9d4e49b386 Use declared_features to avoid two lookups. 2023-10-05 18:01:11 +11:00
Nicholas Nethercote
56fd2531ac Add two setter functions to Features. 2023-10-05 18:01:11 +11:00
Nicholas Nethercote
4602d9257d Rename Features::active_features.
The word "active" is currently used in two different and confusing ways:
- `ACTIVE_FEATURES` actually means "available unstable features"
- `Features::active_features` actually means "features declared in the
  crate's code", which can include feature within `ACTIVE_FEATURES` but
  also others.

(This is also distinct from "enabled" features which includes declared
features but also some edition-specific features automatically enabled
depending on the edition in use.)

This commit changes the `Features::active_features` to
`Features::declared_features` which actually matches its meaning.
Likewise, `Features::active` becomes `Features::declared`.
2023-10-05 18:01:11 +11:00
Nicholas Nethercote
8ba9137840 Merge STABLE_REMOVED_FEATURES list into REMOVED_FEATURES.
There is a single features (`no_stack_check`) in
`STABLE_REMOVED_FEATURES`. But the treatment of
`STABLE_REMOVED_FEATURES` and `REMOVED_FEATURES` is actually identical.
So this commit just merges them, and uses a comment to record
`no_stack_check`'s unique "stable removed" status.

This also lets `State::Stabilized` (which was a terrible name) be
removed.
2023-10-05 11:42:32 +11:00
Nicholas Nethercote
1ddb2872dd Streamline find_lang_feature_issue.
It currently processes `ACTIVE_FEATURES` separately from
`ACCEPTED_FEATURES`, `REMOVED_FEATURES`, and `STABLE_REMOVED_FEATURES`,
for no good reason. This commit treats them uniformly.
2023-10-05 10:23:26 +11:00
Nicholas Nethercote
3c1b60c1b4 Split declare_features!.
It's a macro with four clauses, three of which are doing one thing, and
the fourth is doing something completely different. This commit splits
it into two macros, which is more sensible.
2023-10-05 10:23:20 +11:00
Nicholas Nethercote
043a9873b9 Remove set! macro.
It has a single call site.
2023-10-05 10:23:20 +11:00
Nicholas Nethercote
53fe37de2e Remove unused Span from the set function in State::Active. 2023-10-05 10:18:29 +11:00
Mark Rousskov
787d32324c Bump version placeholders 2023-10-03 20:26:36 -04:00
bors
8fa7bdf191 Auto merge of #115670 - Zoxc:outline-panic-macro-1, r=Mark-Simulacrum
Partially outline code inside the panic! macro

This outlines code inside the panic! macro in some cases. This is split out from https://github.com/rust-lang/rust/pull/115562 to exclude changes to rustc.
2023-10-01 05:56:47 +00:00
bors
56ada88e7e Auto merge of #113301 - Be-ing:stabilize_bundle_whole-archive, r=petrochenkov
stabilize combining +bundle and +whole-archive link modifiers

Per discussion on https://github.com/rust-lang/rust/issues/108081 combining +bundle and +whole-archive already works and can be stabilized independently of other aspects of the packed_bundled_libs feature. There is no risk of regression because this was not previously allowed.

r? `@petrochenkov`
2023-09-29 15:51:48 +00:00
bors
7b4d9e155f Auto merge of #115659 - compiler-errors:itp, r=cjgillot
Stabilize `impl_trait_projections`

Closes #115659

## TL;DR:

This allows us to mention `Self` and `T::Assoc` in async fn and return-position `impl Trait`, as you would expect you'd be able to.

Some examples:
```rust
#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
// (just needed for final tests below)

// ---------------------------------------- //

struct Wrapper<'a, T>(&'a T);

impl Wrapper<'_, ()> {
    async fn async_fn() -> Self {
        //^ Previously rejected because it returns `-> Self`, not `-> Wrapper<'_, ()>`.
        Wrapper(&())
    }

    fn impl_trait() -> impl Iterator<Item = Self> {
        //^ Previously rejected because it mentions `Self`, not `Wrapper<'_, ()>`.
        std::iter::once(Wrapper(&()))
    }
}

// ---------------------------------------- //

trait Trait<'a> {
    type Assoc;
    fn new() -> Self::Assoc;
}
impl Trait<'_> for () {
    type Assoc = ();
    fn new() {}
}

impl<'a, T: Trait<'a>> Wrapper<'a, T> {
    async fn mk_assoc() -> T::Assoc {
        //^ Previously rejected because `T::Assoc` doesn't mention `'a` in the HIR,
        //  but ends up resolving to `<T as Trait<'a>>::Assoc`, which does rely on `'a`.
        // That's the important part -- the elided trait.
        T::new()
    }

    fn a_few_assocs() -> impl Iterator<Item = T::Assoc> {
        //^ Previously rejected for the same reason
        [T::new(), T::new(), T::new()].into_iter()
    }
}

// ---------------------------------------- //

trait InTrait {
    async fn async_fn() -> Self;

    fn impl_trait() -> impl Iterator<Item = Self>;
}

impl InTrait for &() {
    async fn async_fn() -> Self { &() }
    //^ Previously rejected just like inherent impls

    fn impl_trait() -> impl Iterator<Item = Self> {
        //^ Previously rejected just like inherent impls
        [&()].into_iter()
    }
}
```

## Technical:

Lifetimes in return-position `impl Trait` (and `async fn`) are duplicated as early-bound generics local to the opaque in order to make sure we are able to substitute any late-bound lifetimes from the function in the opaque's hidden type. (The [dev guide](https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html#aside-opaque-lifetime-duplication) has a small section about why this is necessary -- this was written for RPITITs, but it applies to all RPITs)

Prior to #103491, all of the early-bound lifetimes not local to the opaque were replaced with `'static` to avoid issues where relating opaques caused their *non-captured* lifetimes to be related. This `'static` replacement led to strange and possibly unsound behaviors (https://github.com/rust-lang/rust/issues/61949#issuecomment-508836314) (https://github.com/rust-lang/rust/issues/53613) when referencing the `Self` type alias in an impl or indirectly referencing a lifetime parameter via a projection type (via a `T::Assoc` projection without an explicit trait), since lifetime resolution is performed on the HIR, when neither `T::Assoc`-style projections or `Self` in impls are expanded.

Therefore an error was implemented in #62849 to deny this subtle behavior as a known limitation of the compiler. It was attempted by `@cjgillot` to fix this in #91403, which was subsequently unlanded. Then it was re-attempted to much success (🎉) in #103491, which is where we currently are in the compiler.

The PR above (#103491) fixed this issue technically by *not* replacing the opaque's parent lifetimes with `'static`, but instead using variance to properly track which lifetimes are captured and are not. The PR gated any of the "side-effects" of the PR behind a feature gate (`impl_trait_projections`) presumably to avoid having to involve T-lang or T-types in the PR as well. `@cjgillot` can clarify this if I'm misunderstanding what their intention was with the feature gate.

Since we're not replacing (possibly *invariant*!) lifetimes with `'static` anymore, there are no more soundness concerns here. Therefore, this PR removes the feature gate.

Tests:
* `tests/ui/async-await/feature-self-return-type.rs`
* `tests/ui/impl-trait/feature-self-return-type.rs`
* `tests/ui/async-await/issues/issue-78600.rs`
* `tests/ui/impl-trait/capture-lifetime-not-in-hir.rs`

---

r? cjgillot on the impl (not much, just removing the feature gate)

I'm gonna mark this as FCP for T-lang and T-types.
2023-09-28 21:35:18 +00:00
bors
92009f217a Auto merge of #116093 - RalfJung:link_llvm_intrinsics, r=oli-obk
make link_llvm_intrinsics and platform_intrinsics features internal

These are both a lot like `feature(intrinsics)`, just slightly different syntax, so IMO it should be treated the same (also in terms of: if you get ICEs with this feature, that's on you -- we are not doing "nice" type-checking for intrinsics).
2023-09-27 11:28:36 +00:00
León Orell Valerian Liehr
f54db7c3a9
Gate and validate #[rustc_safe_intrinsic] 2023-09-25 22:33:15 +02:00
Ralf Jung
ab8307331a also make platform_intrinsics internal 2023-09-23 21:30:45 +02:00
Ralf Jung
37acbbb4b5 make link_llvm_intrinsics feature internal 2023-09-23 08:39:36 +02:00
bors
327e6cf55c Auto merge of #114452 - weiznich:feature/diagnostic_on_unimplemented, r=compiler-errors
`#[diagnostic::on_unimplemented]` without filters

This commit adds support for a `#[diagnostic::on_unimplemented]` attribute with the following options:

* `message` to customize the primary error message
* `note` to add a customized note message to an error message
* `label` to customize the label part of the error message

The relevant behavior is specified in [RFC-3366](https://rust-lang.github.io/rfcs/3366-diagnostic-attribute-namespace.html)
2023-09-17 10:00:15 +00:00
bors
41bafc4ff3 Auto merge of #110800 - GuillaumeGomez:custom_code_classes_in_docs, r=t-rustdoc
Accept additional user-defined syntax classes in fenced code blocks

Part of #79483.

This is a re-opening of https://github.com/rust-lang/rust/pull/79454 after a big update/cleanup. I also converted the syntax to pandoc as suggested by `@notriddle:` the idea is to be as compatible as possible with the existing instead of having our own syntax.

## Motivation

From the original issue: https://github.com/rust-lang/rust/issues/78917

> The technique used by `inline-c-rs` can be ported to other languages. It's just super fun to see C code inside Rust documentation that is also tested by `cargo doc`. I'm sure this technique can be used by other languages in the future.

Having custom CSS classes for syntax highlighting will allow tools like `highlight.js` to be used in order to provide highlighting for languages other than Rust while not increasing technical burden on rustdoc.

## What is the feature about?

In short, this PR changes two things, both related to codeblocks in doc comments in Rust documentation:

 * Allow to disable generation of `language-*` CSS classes with the `custom` attribute.
 * Add your own CSS classes to a code block so that you can use other tools to highlight them.

#### The `custom` attribute

Let's start with the new `custom` attribute: it will disable the generation of the `language-*` CSS class on the generated HTML code block. For example:

```rust
/// ```custom,c
/// int main(void) {
///     return 0;
/// }
/// ```
```

The generated HTML code block will not have `class="language-c"` because the `custom` attribute has been set. The `custom` attribute becomes especially useful with the other thing added by this feature: adding your own CSS classes.

#### Adding your own CSS classes

The second part of this feature is to allow users to add CSS classes themselves so that they can then add a JS library which will do it (like `highlight.js` or `prism.js`), allowing to support highlighting for other languages than Rust without increasing burden on rustdoc. To disable the automatic `language-*` CSS class generation, you need to use the `custom` attribute as well.

This allow users to write the following:

```rust
/// Some code block with `{class=language-c}` as the language string.
///
/// ```custom,{class=language-c}
/// int main(void) {
///     return 0;
/// }
/// ```
fn main() {}
```

This will notably produce the following HTML:

```html
<pre class="language-c">
int main(void) {
    return 0;
}</pre>
```

Instead of:

```html
<pre class="rust rust-example-rendered">
<span class="ident">int</span> <span class="ident">main</span>(<span class="ident">void</span>) {
    <span class="kw">return</span> <span class="number">0</span>;
}
</pre>
```

To be noted, we could have written `{.language-c}` to achieve the same result. `.` and `class=` have the same effect.

One last syntax point: content between parens (`(like this)`) is now considered as comment and is not taken into account at all.

In addition to this, I added an `unknown` field into `LangString` (the parsed code block "attribute") because of cases like this:

```rust
/// ```custom,class:language-c
/// main;
/// ```
pub fn foo() {}
```

Without this `unknown` field, it would generate in the DOM: `<pre class="language-class:language-c language-c">`, which is quite bad. So instead, it now stores all unknown tags into the `unknown` field and use the first one as "language". So in this case, since there is no unknown tag, it'll simply generate `<pre class="language-c">`. I added tests to cover this.

Finally, I added a parser for the codeblock attributes to make it much easier to maintain. It'll be pretty easy to extend.

As to why this syntax for adding attributes was picked: it's [Pandoc's syntax](https://pandoc.org/MANUAL.html#extension-fenced_code_attributes). Even if it seems clunkier in some cases, it's extensible, and most third-party Markdown renderers are smart enough to ignore Pandoc's brace-delimited attributes (from [this comment](https://github.com/rust-lang/rust/pull/110800#issuecomment-1522044456)).

## Raised concerns

#### It's not obvious when the `language-*` attribute generation will be added or not.

It is added by default. If you want to disable it, you will need to use the `custom` attribute.

#### Why not using HTML in markdown directly then?

Code examples in most languages are likely to contain `<`, `>`, `&` and `"` characters. These characters [require escaping](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre) when written inside the `<pre>` element. Using the \`\`\` code blocks allows rustdoc to take care of escaping, which means doc authors can paste code samples directly without manually converting them to HTML.

cc `@poliorcetics`
r? `@notriddle`
2023-09-16 13:10:11 +00:00
bors
635c4a5e61 Auto merge of #114494 - est31:extend_useless_ptr_null_checks, r=jackh726
Make useless_ptr_null_checks smarter about some std functions

This teaches the `useless_ptr_null_checks` lint that some std functions can't ever return null pointers, because they need to point to valid data, get references as input, etc.

This is achieved by introducing an `#[rustc_never_returns_null_ptr]` attribute and adding it to these std functions (gated behind bootstrap `cfg_attr`).

Later on, the attribute could maybe be used to tell LLVM that the returned pointer is never null. I don't expect much impact of that though, as the functions are pretty shallow and usually the input data is already never null.

Follow-up of PR #113657

Fixes #114442
2023-09-16 03:40:20 +00:00
Guillaume Gomez
5515fc88dc Implement custom classes for rustdoc code blocks with custom_code_classes_in_docs feature 2023-09-15 21:32:27 +02:00
Zalathar
c397ca0677 Fix the error message for #![feature(no_coverage)] 2023-09-14 13:01:54 +10:00
Georg Semmler
5b8a7a0917
#[diagnostic::on_unimplemented] without filters
This commit adds support for a `#[diagnostic::on_unimplemented]`
attribute with the following options:

* `message` to customize the primary error message
* `note` to add a customized note message to an error message
* `label` to customize the label part of the error message

Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
Co-authored-by: Michael Goulet <michael@errs.io>
2023-09-12 20:03:18 +02:00
John Kåre Alsaker
6a02baaa3d Partially outline code inside the panic! macro 2023-09-08 14:05:57 +02:00
Andy Caldwell
679267f2ac
Rename the feature, but not the attribute, to coverage_attribute 2023-09-08 12:46:09 +01:00
Andy Caldwell
de1600d110
Add no_coverage to the 'removed features' list 2023-09-08 12:46:08 +01:00
Andy Caldwell
8e03371fc3
Rework no_coverage to coverage(off) 2023-09-08 12:46:06 +01:00
Michael Goulet
e4af4e5083 Stabilize impl_trait_projections 2023-09-08 03:45:36 +00:00
klensy
355ba433ee fix version for abi_thiscall to 1.73.0, which was forgotten to change when stabilized 2023-09-01 19:46:09 +03:00
Michael Goulet
690bcc6619 Test variances of opaque captures 2023-08-28 01:05:34 +00:00
Ralf Jung
abe2148aee add rustc_abi debugging attribute 2023-08-27 11:55:49 +02:00
bors
18be2728bd Auto merge of #115131 - frank-king:feature/unnamed-fields-lite, r=petrochenkov
Parse unnamed fields and anonymous structs or unions (no-recovery)

It is part of #114782 which implements #49804. Only parse anonymous structs or unions in struct field definition positions.

r? `@petrochenkov`
2023-08-24 12:52:35 +00:00
Frank King
868706d9b5 Parse unnamed fields and anonymous structs or unions
Anonymous structs or unions are only allowed in struct field
definitions.

Co-authored-by: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com>
2023-08-24 11:17:54 +08:00
Mark Rousskov
c8522adb97 Replace version placeholders with 1.73.0 2023-08-22 06:57:00 -04:00
Luca Barbato
c0394c8ac0 Add the relocation_model to the cfg
This way is possible to write inline assembly code aware of it.
2023-08-18 19:57:28 +02:00
Be Wilson
72e29da3ec stabilize combining +bundle and +whole-archive link modifiers
Currently, combining +bundle and +whole-archive works only with
 #![feature(packed_bundled_libs)]
This crate feature is independent of the -Zpacked-bundled-libs
command line option.

This commit stabilizes the #![feature(packed_bundled_libs)] crate
feature and implicitly enables it only when the +bundle and
+whole-archive link modifiers are combined. This allows rlib
crates to use the +whole-archive link modifier with native
libraries and have all symbols included in the linked library
to be included in downstream staticlib crates that use the rlib as
a dependency. Other cases requiring the packed_bundled_libs
behavior still require the -Zpacked-bundled-libs command line
option, which can be stabilized independently in the future.

Per discussion on https://github.com/rust-lang/rust/issues/108081
there is no risk of regression stabilizing the crate feature in
this way because the combination of +bundle,+whole-archive link
modifiers was previously not allowed.
2023-08-15 15:51:18 -05:00
Dirreck
ded88c6e81
Update compiler/rustc_feature/src/active.rs
Co-authored-by: klensy <klensy@users.noreply.github.com>
2023-08-15 02:13:17 +08:00
Dirreke
8c51e28bd5 add rustc_codegen_ssa support for csky and correct some code 2023-08-14 23:02:36 +08:00
Seth Pellegrino
897c7bb23b feat: riscv-interrupt-{m,s} calling conventions
Similar to prior support added for the mips430, avr, and x86 targets
this change implements the rough equivalent of clang's
[`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling
e.g.

```rust
static mut CNT: usize = 0;

pub extern "riscv-interrupt-m" fn isr_m() {
    unsafe {
        CNT += 1;
    }
}
```

to produce highly effective assembly like:

```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0:       1141                    addi    sp,sp,-16
    unsafe {
        CNT += 1;
420003a2:       c62a                    sw      a0,12(sp)
420003a4:       c42e                    sw      a1,8(sp)
420003a6:       3fc80537                lui     a0,0x3fc80
420003aa:       63c52583                lw      a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae:       0585                    addi    a1,a1,1
420003b0:       62b52e23                sw      a1,1596(a0)
    }
}
420003b4:       4532                    lw      a0,12(sp)
420003b6:       45a2                    lw      a1,8(sp)
420003b8:       0141                    addi    sp,sp,16
420003ba:       30200073                mret
```

(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)

This outcome is superior to hand-coded interrupt routines which, lacking
visibility into any non-assembly body of the interrupt handler, have to
be very conservative and save the [entire CPU state to the stack
frame][full-frame-save]. By instead asking LLVM to only save the
registers that it uses, we defer the decision to the tool with the best
context: it can more accurately account for the cost of spills if it
knows that every additional register used is already at the cost of an
implicit spill.

At the LLVM level, this is apparently [implemented by] marking every
register as "[callee-save]," matching the semantics of an interrupt
handler nicely (it has to leave the CPU state just as it found it after
its `{m|s}ret`).

This approach is not suitable for every interrupt handler, as it makes
no attempt to e.g. save the state in a user-accessible stack frame. For
a full discussion of those challenges and tradeoffs, please refer to
[the interrupt calling conventions RFC][rfc].

Inside rustc, this implementation differs from prior art because LLVM
does not expose the "all-saved" function flavor as a calling convention
directly, instead preferring to use an attribute that allows for
differentiating between "machine-mode" and "superivsor-mode" interrupts.

Finally, some effort has been made to guide those who may not yet be
aware of the differences between machine-mode and supervisor-mode
interrupts as to why no `riscv-interrupt` calling convention is exposed
through rustc, and similarly for why `riscv-interrupt-u` makes no
appearance (as it would complicate future LLVM upgrades).

[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
2023-08-08 18:09:56 -07:00
Matthias Krüger
06daa9e263
Rollup merge of #114562 - Trolldemorted:thiscall, r=oli-obk
stabilize abi_thiscall

Closes https://github.com/rust-lang/rust/issues/42202, stabilizing the use of the "thiscall" ABI.

FCP was substituted by a poll, and the poll has been accepted.
2023-08-07 16:47:57 +02:00
Benedikt Radtke
3f3262e592 stabilize abi_thiscall 2023-08-07 14:11:03 +02:00
Martin Nordholts
2b9876bd6d Issue numbers are enforced on active features; remove FIXME 2023-08-06 20:01:23 +02:00
est31
8cfa4fe6b2 Add #[rustc_never_returns_null_ptr]
And look for it in the useless_ptr_null_checks lint
2023-08-05 05:16:44 +02:00
bors
e173a8e663 Auto merge of #112117 - bryangarza:track-caller-feature-gate, r=compiler-errors
Add separate feature gate for async fn track caller

This patch adds a feature gate `async_fn_track_caller` that is separate from `closure_track_caller`. This is to allow enabling `async_fn_track_caller` separately.

Fixes #110009
2023-08-04 22:17:59 +00:00
Nilstrieb
5830ca216d Add internal_features lint
It lints against features that are inteded to be internal to the
compiler and standard library. Implements MCP #596.

We allow `internal_features` in the standard library and compiler as those
use many features and this _is_ the standard library from the "internal to the compiler and
standard library" after all.

Marking some features as internal wasn't exactly the most scientific approach, I just marked some
mostly obvious features. While there is a categorization in the macro,
it's not very well upheld (should probably be fixed in another PR).

We always pass `-Ainternal_features` in the testsuite
About 400 UI tests and several other tests use internal features.
Instead of throwing the attribute on each one, just always allow them.
There's nothing wrong with testing internal features^^
2023-08-03 14:50:50 +02:00
Bryan Garza
673ab17c7f Add separate feature gate for async fn track caller
This patch adds a feature gate `async_fn_track_caller` that is separate from `closure_track_caller`. This is to allow enabling `async_fn_track_caller` separately.

Fixes #110009
2023-08-02 14:18:21 -07:00
Michael Goulet
4b58ae0bb8 Mark lazy_type_alias as incomplete 2023-07-29 19:47:15 +00:00
León Orell Valerian Liehr
afd009a8d8
Parse generic const items 2023-07-28 22:21:33 +02:00
Georg Semmler
5b576665e5
Introduce the #[diagnostic] attribute namespace
Co-authored-by: est31 <est31@users.noreply.github.com>

Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com>

Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
2023-07-28 13:28:02 +02:00
许杰友 Jieyou Xu (Joe)
08c77a6eb4
Add infrastructure #[rustc_confusables] attribute to allow targeted
"no method" errors on standard library types

The standard library developer can annotate methods on e.g.
`BTreeSet::push` with `#[rustc_confusables("insert")]`. When the user
mistypes `btreeset.push()`, `BTreeSet::insert` will be suggested if
there are no other candidates to suggest.
2023-07-16 19:22:03 +08:00
Mahdi Dibaiee
e55583c4b8 refactor(rustc_middle): Substs -> GenericArg 2023-07-14 13:27:35 +01:00
Mark Rousskov
0d93d787ba Replace version placeholder to 1.72 2023-07-12 21:24:05 -04:00
Deadbeef
2d5d56bb59 Add feature and attribute definition 2023-07-04 11:47:45 +00:00
Matthias Krüger
42a495da7e
Rollup merge of #112670 - petrochenkov:typriv, r=eholk
privacy: Type privacy lints fixes and cleanups

See individual commits.
Follow up to https://github.com/rust-lang/rust/pull/111801.
2023-06-29 05:48:39 +02:00
Guillaume Gomez
009d72b3ae
Rollup merge of #112853 - GuillaumeGomez:type_alias_type, r=oli-obk
Add `lazy_type_alias` feature gate

Add the `type_alias_type` to be able to have the weak alias used without restrictions.

Part of #112792.

cc `@compiler-errors`
r? `@oli-obk`
2023-06-21 15:45:16 +02:00
Guillaume Gomez
60ec8405eb Add lazy_type_alias feature gate 2023-06-21 13:45:00 +02:00
Nilstrieb
c6710d15f1
Rollup merge of #112790 - WaffleLapkin:syntactically, r=Nilstrieb
Syntactically accept `become` expressions (explicit tail calls experiment)

This adds `ast::ExprKind::Become`, implements parsing and properly gates the feature.

cc `@scottmcm`
2023-06-21 07:37:02 +02:00
Michael Goulet
ca68cf0d46 Merge attrs, better validation 2023-06-20 04:38:55 +00:00
Michael Goulet
91e5c3f2e5 Make rustc_deny_explicit_impl only local as well 2023-06-20 04:38:46 +00:00
Michael Goulet
657d3f43a9 Add rustc_do_not_implement_via_object 2023-06-20 04:38:46 +00:00
Maybe Waffle
d7713feb99 Syntatically accept become expressions 2023-06-19 12:54:34 +00:00
Vadim Petrochenkov
d326aed46f privacy: Feature gate new type privacy lints 2023-06-15 21:25:47 +03:00
bors
23f93a1266 Auto merge of #103877 - oli-obk:const_eval_step_limit, r=fee1-dead
Replace const eval limit by a lint and add an exponential backoff warning

The lint triggers at the first power of 2 that comes after 1 million function calls or traversed back-edges (takes less than a second on usual programs). After the first emission, an unsilenceable warning is repeated at every following power of 2 terminators, causing it to get reported less and less the longer the evaluation runs.

cc `@rust-lang/wg-const-eval`

fixes #93481
closes #67217
2023-06-01 05:32:00 +00:00
Oli Scherer
05eae08233 Remove const eval limit and implement an exponential backoff lint instead 2023-05-31 10:24:17 +00:00
Mark Rousskov
4f9b394c8a Swap out CURRENT_RUSTC_VERSION to 1.71.0 2023-05-30 07:54:29 -04:00
Maybe Waffle
307799a711 Use is_some_and/is_ok_and in less obvious spots 2023-05-24 14:33:43 +00:00
Maybe Waffle
fb0f74a8c9 Use Option::is_some_and and Result::is_ok_and in the compiler 2023-05-24 14:20:41 +00:00
klensy
9799fb1ddc fixup version placeholder for cfi_encoding feature 2023-05-15 19:19:13 +03:00
AngelicosPhosphoros
7c263adb2a Add support for cfg(overflow_checks)
This PR adds support for detecting if overflow checks are enabled in similar fashion as debug_assertions are detected.
Possible use-case of this, for example, if we want to use checked integer casts in builds with overflow checks, e.g.

```rust
pub fn cast(val: usize)->u16 {
    if cfg!(overflow_checks) {
        val.try_into().unwrap()
    }
    else{
        vas as _
    }
}
```

Resolves #91130.
Tracking issue: #111466.
2023-05-11 18:06:31 +04:00
Dylan DPC
dbd090c655
Rollup merge of #110694 - est31:builtin, r=petrochenkov
Implement builtin # syntax and use it for offset_of!(...)

Add `builtin #` syntax to the parser, as well as a generic infrastructure to support both item and expression position builtin syntaxes. The PR also uses this infrastructure for the implementation of the `offset_of!` macro, added by #106934.

cc `@petrochenkov` `@DrMeepster`

cc #110680 `builtin #` tracking issue
cc #106655 `offset_of!` tracking issue
2023-05-09 12:33:45 +05:30
Yuki Okushi
923a5a2ca7
Rollup merge of #109677 - dpaoliello:rawdylib, r=michaelwoerister,wesleywiser
Stabilize raw-dylib, link_ordinal, import_name_type and -Cdlltool

This stabilizes the `raw-dylib` feature (#58713) for all architectures (i.e., `x86` as it is already stable for all other architectures).

Changes:
* Permit the use of the `raw-dylib` link kind for x86, the `link_ordinal` attribute and the `import_name_type` key for the `link` attribute.
* Mark the `raw_dylib` feature as stable.
* Stabilized the `-Zdlltool` argument as `-Cdlltool`.
* Note the path to `dlltool` if invoking it failed (we don't need to do this if `dlltool` returns an error since it prints its path in the error message).
* Adds tests for `-Cdlltool`.
* Adds tests for being unable to find the dlltool executable, and dlltool failing.
* Fixes a bug where we were checking the exit code of dlltool to see if it failed, but dlltool always returns 0 (indicating success), so instead we need to check if anything was written to `stderr`.

NOTE: As previously noted (https://github.com/rust-lang/rust/pull/104218#issuecomment-1315895618) using dlltool within rustc is temporary, but this is not the first time that Rust has added a temporary tool use and argument: https://github.com/rust-lang/rust/pull/104218#issuecomment-1318720482

Big thanks to ``````@tbu-`````` for the first version of this PR (#104218)
2023-05-06 09:09:30 +09:00
est31
83b4df4e61 Add feature gate 2023-05-05 21:44:48 +02:00
Dylan DPC
4891f02cff
Rollup merge of #108801 - fee1-dead-contrib:c-str, r=compiler-errors
Implement RFC 3348, `c"foo"` literals

RFC: https://github.com/rust-lang/rfcs/pull/3348
Tracking issue: #105723
2023-05-05 18:40:33 +05:30
Manish Goregaokar
38bbc39895
Rollup merge of #105452 - rcvalle:rust-cfi-3, r=bjorn3
Add cross-language LLVM CFI support to the Rust compiler

This PR adds cross-language LLVM Control Flow Integrity (CFI) support to the Rust compiler by adding the `-Zsanitizer-cfi-normalize-integers` option to be used with Clang `-fsanitize-cfi-icall-normalize-integers` for normalizing integer types (see https://reviews.llvm.org/D139395).

It provides forward-edge control flow protection for C or C++ and Rust -compiled code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code share the same virtual address space). For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, see design document in the tracking issue #89653.

Cross-language LLVM CFI can be enabled with -Zsanitizer=cfi and -Zsanitizer-cfi-normalize-integers, and requires proper (i.e., non-rustc) LTO (i.e., -Clinker-plugin-lto).

Thank you again, ``@bjorn3,`` ``@nikic,`` ``@samitolvanen,`` and the Rust community for all the help!
2023-05-03 16:42:48 -07:00
Ramon de C Valle
004aa15b47 Add cross-language LLVM CFI support to the Rust compiler
This commit adds cross-language LLVM Control Flow Integrity (CFI)
support to the Rust compiler by adding the
`-Zsanitizer-cfi-normalize-integers` option to be used with Clang
`-fsanitize-cfi-icall-normalize-integers` for normalizing integer types
(see https://reviews.llvm.org/D139395).

It provides forward-edge control flow protection for C or C++ and Rust
-compiled code "mixed binaries" (i.e., for when C or C++ and Rust
-compiled code share the same virtual address space). For more
information about LLVM CFI and cross-language LLVM CFI support for the
Rust compiler, see design document in the tracking issue #89653.

Cross-language LLVM CFI can be enabled with -Zsanitizer=cfi and
-Zsanitizer-cfi-normalize-integers, and requires proper (i.e.,
non-rustc) LTO (i.e., -Clinker-plugin-lto).
2023-05-03 22:41:29 +00:00
Michael Goulet
6e01e910cb Implement negative bounds 2023-05-02 22:36:24 +00:00
Deadbeef
a49570fd20 fix TODO comments 2023-05-02 10:32:07 +00:00
Deadbeef
76d1f93896 update and add a few tests 2023-05-02 10:30:09 +00:00
Dylan DPC
2e3373c231
Rollup merge of #111048 - compiler-errors:rpitit-not-incomplete, r=jackh726
Mark`feature(return_position_impl_trait_in_trait)` and`feature(async_fn_in_trait)` as not incomplete

I think they've graduated, since as far as I'm aware, they don't cause compiler crashes or unsoundness anymore.
2023-05-02 11:44:53 +05:30
Dylan DPC
f379a58bf2
Rollup merge of #108668 - gibbyfree:stabilizedebuggervisualizer, r=wesleywiser
Stabilize debugger_visualizer

This stabilizes the `debugger_visualizer` attribute (#95939).

* Marks the `debugger_visualizer` feature as `accepted`.
* Marks the `debugger_visualizer` attribute as `ungated`.
* Deletes feature gate test, removes feature gate from other tests.

Closes #95939
2023-05-02 11:44:51 +05:30
Michael Goulet
7411468ff8 Mark RPITIT and AFIT as no longer incomplete 2023-05-02 05:04:50 +00:00
bors
1cb63572d2 Auto merge of #106075 - nbdd0121:ffi-unwind, r=joshtriplett
Partial stabilisation of `c_unwind`

The stabilisation report is at https://github.com/rust-lang/rust/issues/74990#issuecomment-1363473645

cc `@rust-lang/wg-ffi-unwind`
2023-05-02 00:45:04 +00:00
Gary Guo
723aee2e56 Partial stabilisation of c_unwind 2023-04-29 13:01:44 +01:00
Guillaume Gomez
344dd0e828 Make repr attribute local_only 2023-04-29 11:50:16 +02:00
bors
572c0d553f Auto merge of #110643 - pietroalbini:pa-bump-stage0, r=Mark-Simulacrum
[master] Bump stage0

r? `@Mark-Simulacrum`
2023-04-29 02:29:14 +00:00
bors
f495605381 Auto merge of #110901 - GuillaumeGomez:inlined-repr-rustdoc, r=notriddle
rustdoc: Fix missing `repr` attribute in doc(inline) on foreign items

Fixes https://github.com/rust-lang/rust/issues/110698.

r? `@notriddle`
2023-04-28 20:33:33 +00:00
Pietro Albini
4e04da6183 replace version placeholders 2023-04-28 08:47:55 -07:00
Guillaume Gomez
adee37a080 repr attribute needs to be stored to be used in doc(inline) by rustdoc 2023-04-27 16:40:59 +02:00
Matthias Krüger
f54dbe6e31 Revert "Remove #[alloc_error_handler] from the compiler and library"
This reverts commit abc0660118.
2023-04-25 00:08:35 +02:00
bors
39cf520299 Auto merge of #109507 - Amanieu:panic-oom-payload, r=davidtwco
Report allocation errors as panics

OOM is now reported as a panic but with a custom payload type (`AllocErrorPanicPayload`) which holds the layout that was passed to `handle_alloc_error`.

This should be review one commit at a time:
- The first commit adds `AllocErrorPanicPayload` and changes allocation errors to always be reported as panics.
- The second commit removes `#[alloc_error_handler]` and the `alloc_error_hook` API.

ACP: https://github.com/rust-lang/libs-team/issues/192

Closes #51540
Closes #51245
2023-04-22 12:27:45 +00:00
Daniel Paoliello
1ece1ea48c Stablize raw-dylib, link_ordinal and -Cdlltool 2023-04-18 11:01:07 -07:00
Josh Soref
e09d0d2a29 Spelling - compiler
* account
* achieved
* advising
* always
* ambiguous
* analysis
* annotations
* appropriate
* build
* candidates
* cascading
* category
* character
* clarification
* compound
* conceptually
* constituent
* consts
* convenience
* corresponds
* debruijn
* debug
* debugable
* debuggable
* deterministic
* discriminant
* display
* documentation
* doesn't
* ellipsis
* erroneous
* evaluability
* evaluate
* evaluation
* explicitly
* fallible
* fulfill
* getting
* has
* highlighting
* illustrative
* imported
* incompatible
* infringing
* initialized
* into
* intrinsic
* introduced
* javascript
* liveness
* metadata
* monomorphization
* nonexistent
* nontrivial
* obligation
* obligations
* offset
* opaque
* opportunities
* opt-in
* outlive
* overlapping
* paragraph
* parentheses
* poisson
* precisely
* predecessors
* predicates
* preexisting
* propagated
* really
* reentrant
* referent
* responsibility
* rustonomicon
* shortcircuit
* simplifiable
* simplifications
* specify
* stabilized
* structurally
* suggestibility
* translatable
* transmuting
* two
* unclosed
* uninhabited
* visibility
* volatile
* workaround

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-04-17 16:09:18 -04:00
Amanieu d'Antras
abc0660118 Remove #[alloc_error_handler] from the compiler and library 2023-04-16 08:35:50 -07:00
Matthias Krüger
214e4ef4ef
Rollup merge of #110237 - oli-obk:impl_trait_in_assoc_tys, r=jackh726
Split out a separate feature gate for impl trait in associated types

in https://github.com/rust-lang/rust/issues/107645 it was decided that we'll take a new route for type alias impl trait. The exact route isn't clear yet, so while I'm working on implementing some of these proposed changes (e.g. in https://github.com/rust-lang/rust/pull/110010) to be able to experiment with them, I will also work on stabilizing another sugar version first: impl trait in associated types. Similarly I'll look into creating feature gates for impl trait in const/static types.

This PR does nothing but split the feature gate, so that you need to enable a different feature gate for

```rust
impl Trait for Type {
    type Assoc = impl SomeTrait;
}
```

than what you need for `type Foo = impl SomeTrait;`
2023-04-12 20:56:24 +02:00
Oli Scherer
f263f88bea Split out a separate feature gate for impl trait in associated types 2023-04-12 16:17:31 +00:00
DaniPopes
677357d32b
Fix typos in compiler 2023-04-10 22:02:52 +02:00
bors
af06dce64b Auto merge of #106281 - JulianKnodt:transmute_const_generics, r=b-naber
Add ability to transmute (somewhat) with generic consts in arrays

Previously if the expression contained generic consts and did not have a directly equivalent type, transmuting the type in this way was forbidden, despite the two sizes being identical. Instead, we should be able to lazily tell if the two consts are identical, and if so allow them to be transmuted.

This is done by normalizing the forms of expressions into sorted order of multiplied terms, which is not generic over all expressions, but should handle most cases.

This allows for some _basic_ transmutations between types that are equivalent in size without requiring additional stack space at runtime.

I only see one other location at which `SizeSkeleton` is being used, and it checks for equality so this shouldn't affect anywhere else that I can tell.

See [this Stackoverflow post](https://stackoverflow.com/questions/73085012/transmute-nested-const-generic-array-rust) for what was previously necessary to convert between types. This PR makes converting nested `T -> [T; 1]` transmutes possible, and `[uB*2; N] -> [uB; N * 2]` possible as well.

I'm not sure whether this is something that would be wanted, and if it is it definitely should not be insta-stable, so I'd add a feature gate.
2023-04-08 19:47:22 +00:00