Commit Graph

751 Commits

Author SHA1 Message Date
bors
5dfb4b0afa Auto merge of #104321 - Swatinem:async-gen, r=oli-obk
Avoid `GenFuture` shim when compiling async constructs

Previously, async constructs would be lowered to "normal" generators, with an additional `from_generator` / `GenFuture` shim in between to convert from `Generator` to `Future`.

The compiler will now special-case these generators internally so that async constructs will *directly* implement `Future` without the need to go through the `from_generator` / `GenFuture` shim.

The primary motivation for this change was hiding this implementation detail in stack traces and debuginfo, but it can in theory also help the optimizer as there is less abstractions to see through.

---

Given this demo code:

```rust
pub async fn a(arg: u32) -> Backtrace {
    let bt = b().await;
    let _arg = arg;
    bt
}

pub async fn b() -> Backtrace {
    Backtrace::force_capture()
}
```

I would get the following with the latest stable compiler (on Windows):

```
   4: async_codegen:🅱️:async_fn$0
             at .\src\lib.rs:10
   5: core::future::from_generator::impl$1::poll<enum2$<async_codegen:🅱️:async_fn_env$0> >
             at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\core\src\future\mod.rs:91
   6: async_codegen:🅰️:async_fn$0
             at .\src\lib.rs:4
   7: core::future::from_generator::impl$1::poll<enum2$<async_codegen:🅰️:async_fn_env$0> >
             at /rustc/897e37553bba8b42751c67658967889d11ecd120\library\core\src\future\mod.rs:91
```

whereas now I get a much cleaner stack trace:

```
   3: async_codegen:🅱️:async_fn$0
             at .\src\lib.rs:10
   4: async_codegen:🅰️:async_fn$0
             at .\src\lib.rs:4
```
2022-11-24 17:14:42 +00:00
Arpad Borsos
9f36f988ad
Avoid GenFuture shim when compiling async constructs
Previously, async constructs would be lowered to "normal" generators,
with an additional `from_generator` / `GenFuture` shim in between to
convert from `Generator` to `Future`.

The compiler will now special-case these generators internally so that
async constructs will *directly* implement `Future` without the need
to go through the `from_generator` / `GenFuture` shim.

The primary motivation for this change was hiding this implementation
detail in stack traces and debuginfo, but it can in theory also help
the optimizer as there is less abstractions to see through.
2022-11-24 10:04:27 +01:00
Esteban Küber
78b8d126db Fix rebase 2022-11-23 13:06:27 -08:00
Esteban Küber
9e72e35ceb Suggest .clone() or ref binding on E0382 2022-11-23 12:17:47 -08:00
Dylan DPC
c03026a7c6
Rollup merge of #104721 - WaffleLapkin:deref-harder, r=oli-obk
Remove more `ref` patterns from the compiler

r? `@oli-obk`
Previous PR: https://github.com/rust-lang/rust/pull/104500
2022-11-23 20:32:37 +05:30
Manish Goregaokar
36815c6e3b
Rollup merge of #104612 - Swatinem:async-ret-y, r=estebank
Lower return type outside async block creation

This allows feeding a different output type to async blocks with a different `ImplTraitContext`. Spotted this while working on #104321
2022-11-22 22:54:39 -05:00
Maybe Waffle
b97ec3924d rustc_ast_lowering: remove ref patterns 2022-11-22 18:49:29 +00:00
Dylan DPC
88542a3150
Rollup merge of #104615 - spastorino:create-async-def-id-in-lowering, r=compiler-errors
Create def_id for async fns during lowering

r? `@compiler-errors`
2022-11-22 16:36:37 +05:30
Nicholas Nethercote
3e3a4192d8 Split MacArgs in two.
`MacArgs` is an enum with three variants: `Empty`, `Delimited`, and `Eq`. It's
used in two ways:
- For representing attribute macro arguments (e.g. in `AttrItem`), where all
  three variants are used.
- For representing function-like macros (e.g. in `MacCall` and `MacroDef`),
  where only the `Delimited` variant is used.

In other words, `MacArgs` is used in two quite different places due to them
having partial overlap. I find this makes the code hard to read. It also leads
to various unreachable code paths, and allows invalid values (such as
accidentally using `MacArgs::Empty` in a `MacCall`).

This commit splits `MacArgs` in two:
- `DelimArgs` is a new struct just for the "delimited arguments" case. It is
  now used in `MacCall` and `MacroDef`.
- `AttrArgs` is a renaming of the old `MacArgs` enum for the attribute macro
  case. Its `Delimited` variant now contains a `DelimArgs`.

Various other related things are renamed as well.

These changes make the code clearer, avoids several unreachable paths, and
disallows the invalid values.
2022-11-22 09:04:15 +11:00
bors
7fe6f36224 Auto merge of #103491 - cjgillot:self-rpit, r=oli-obk
Support using `Self` or projections inside an RPIT/async fn

I reuse the same idea as https://github.com/rust-lang/rust/pull/103449 to use variances to encode whether a lifetime parameter is captured by impl-trait.

The current implementation of async and RPIT replace all lifetimes from the parent generics by `'static`.  This PR changes the scheme
```rust
impl<'a> Foo<'a> {
    fn foo<'b, T>() -> impl Into<Self> + 'b { ... }
}

opaque Foo::<'_a>::foo::<'_b, T>::opaque<'b>: Into<Foo<'_a>> + 'b;
impl<'a> Foo<'a> {
    // OLD
    fn foo<'b, T>() -> Foo::<'static>::foo::<'static, T>::opaque::<'b> { ... }
                             ^^^^^^^ the `Self` becomes `Foo<'static>`

    // NEW
    fn foo<'b, T>() -> Foo::<'a>::foo::<'b, T>::opaque::<'b> { ... }
                             ^^ the `Self` stays `Foo<'a>`
}
```

There is the same issue with projections. In the example, substitute `Self` by `<T as Trait<'b>>::Assoc` in the sugared version, and `Foo<'_a>` by `<T as Trait<'_b>>::Assoc` in the desugared one.

This allows to support `Self` in impl-trait, since we do not replace lifetimes by `'static` any more.  The same trick allows to use projections like `T::Assoc` where `Self` is allowed.  The feature is gated behind a `impl_trait_projections` feature gate.

The implementation relies on 2 tweaking rules for opaques in 2 places:
- we only relate substs that correspond to captured lifetimes during TypeRelation;
- we only list captured lifetimes in choice region computation.

For simplicity, I encoded the "capturedness" of lifetimes as a variance, `Bivariant` vs `Invariant` for unused vs captured lifetimes. The `variances_of` query used to ICE for opaques.

Impl-trait that do not reference `Self` or projections will have their variances as:
- `o` (invariant) for each parent type or const;
- `*` (bivariant) for each parent lifetime --> will not participate in borrowck;
- `o` (invariant) for each own lifetime.

Impl-trait that does reference `Self` and/or projections will have some parent lifetimes marked as `o` (as the example above), and participate in type relation and borrowck.  In the example above, `variances_of(opaque) = ['_a: o, '_b: *, T: o, 'b: o]`.

r? types
cc `@compiler-errors` , as you asked about the issue with `Self` and projections.
2022-11-21 12:17:03 +00:00
Santiago Pastorino
520fafe5c2
Create def_id for async fns during lowering 2022-11-19 19:17:14 -03:00
Arpad Borsos
b59090ebe3
Lower return type outside async block creation
This allows feeding a different output type to async blocks with a
different `ImplTraitContext`.
2022-11-19 18:23:32 +01:00
bors
70fe5f08ff Auto merge of #101562 - nnethercote:shrink-ast-Expr-harder, r=petrochenkov
Shrink `ast::Expr` harder

r? `@ghost`
2022-11-18 16:56:12 +00:00
bors
fd3bfb3551 Auto merge of #104330 - CastilloDel:ast_lowering, r=cjgillot
Remove allow(rustc::potential_query_instability) from rustc_ast_lowering

Related to https://github.com/rust-lang/rust/issues/84447.

`@cjgillot` Thanks for helping me!
2022-11-18 13:12:18 +00:00
bors
b6097f2e1b Auto merge of #104219 - bryangarza:async-track-caller-dup, r=eholk
Support `#[track_caller]` on async fns

Adds `#[track_caller]` to the generator that is created when we desugar the async fn.

Fixes #78840

Open questions:
- What is the performance impact of adding `#[track_caller]` to every `GenFuture`'s `poll(...)` function, even if it's unused (i.e., the parent span does not set `#[track_caller]`)? We might need to set it only conditionally, if the indirection causes overhead we don't want.
2022-11-17 13:47:03 +00:00
bors
7c75fe4c85 Auto merge of #104170 - cjgillot:hir-def-id, r=fee1-dead
Record `LocalDefId` in HIR nodes instead of a side table

This is part of an attempt to remove the `HirId -> LocalDefId` table from HIR.
This attempt is a prerequisite to creation of `LocalDefId` after HIR lowering (https://github.com/rust-lang/rust/pull/96840), by controlling how `def_id` information is accessed.

This first part adds the information to HIR nodes themselves instead of a table.
The second part is https://github.com/rust-lang/rust/pull/103902
The third part will be to make `hir::Visitor::visit_fn` take a `LocalDefId` as last parameter.
The fourth part will be to completely remove the side table.
2022-11-17 07:42:27 +00:00
Nicholas Nethercote
67d5cc0462 Use ThinVec in ast::Path. 2022-11-17 13:56:38 +11:00
Nicholas Nethercote
6b7ca2fcf2 Box ExprKind::{Closure,MethodCall}, and QSelf in expressions, types, and patterns. 2022-11-17 13:45:59 +11:00
Nicholas Nethercote
358a603f11 Use token::Lit in ast::ExprKind::Lit.
Instead of `ast::Lit`.

Literal lowering now happens at two different times. Expression literals
are lowered when HIR is crated. Attribute literals are lowered during
parsing.

This commit changes the language very slightly. Some programs that used
to not compile now will compile. This is because some invalid literals
that are removed by `cfg` or attribute macros will no longer trigger
errors. See this comment for more details:
https://github.com/rust-lang/rust/pull/102944#issuecomment-1277476773
2022-11-16 09:41:28 +11:00
Daniel del Castillo
557226348f Update compiler/rustc_ast_lowering/src/item.rs
Co-authored-by: Camille Gillot <gillot.camille@gmail.com>
2022-11-15 13:57:25 +01:00
CastilloDel
fdb5fe2ed8 Change LoweringContext.children to Vec 2022-11-15 13:57:24 +01:00
CastilloDel
d1eab51f47 Make clobber_abis use an FxIndexMap
It seems to be used more for lookup than iteration, so this could be a
perf hit
2022-11-15 13:57:24 +01:00
CastilloDel
769cc733b1 Remove allow(rustc::potential_query_instability) from rustc_ast_lowering 2022-11-15 13:57:24 +01:00
Camille GILLOT
9d20aca983 Store a LocalDefId in hir::Variant & hir::Field. 2022-11-13 14:06:51 +00:00
Camille GILLOT
607d0c2a14 Store a LocalDefId in hir::AnonConst. 2022-11-13 14:06:11 +00:00
Camille GILLOT
18482f7b23 Store a LocalDefId in hir::GenericParam. 2022-11-13 14:05:30 +00:00
Camille GILLOT
290f0781b4 Store LocalDefId in hir::Closure. 2022-11-13 14:04:02 +00:00
Camille GILLOT
c5949c8bee Create bidirectional bounds between original and duplicated parameters. 2022-11-13 09:01:29 +00:00
clubby789
b2da155a9a Introduce ExprKind::IncludedBytes 2022-11-11 16:31:32 +00:00
Bryan Garza
509b9478f5 Refactor nested for-loops into find() calls 2022-11-10 00:13:48 +00:00
Bryan Garza
fa99cb8269 Allow and add track_caller to generators
This patch allows the usage of the `track_caller` annotation on
generators, as well as sets them conditionally if the parent also has
`track_caller` set.

Also add this annotation on the `GenFuture`'s `poll()` function.
2022-11-09 23:27:14 +00:00
Michael Howell
03968a802c rustdoc: use ThinVec for cleaned generics 2022-11-02 16:17:22 -07:00
Manish Goregaokar
69e705564d
Rollup merge of #103575 - Xiretza:suggestions-style-attr, r=davidtwco
Change #[suggestion_*] attributes to use style="..."

As discussed [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/.23100717.20tool_only_span_suggestion), this changes `#[(multipart_)suggestion_{short,verbose,hidden}(...)]` attributes to plain `#[(multipart_)suggestion(...)]` attributes with a `style = "{short,verbose,hidden}"` parameter.

It also adds a new style, `tool-only`, that corresponds to `tool_only_span_suggestion`/`tool_only_multipart_suggestion` and causes the suggestion to not be shown in human-readable output at all.

Best reviewed commit-by-commit, there's a bit of noise in there.

cc #100717 `@compiler-errors`
r? `@davidtwco`
2022-11-01 20:00:38 -04:00
Dylan DPC
b4cf523cb5
Rollup merge of #93582 - WaffleLapkin:rpitirpit, r=compiler-errors
Allow `impl Fn() -> impl Trait` in return position

_This was originally proposed as part of #93082 which was [closed](https://github.com/rust-lang/rust/pull/93082#issuecomment-1027225715) due to allowing `impl Fn() -> impl Trait` in argument position._

This allows writing the following function signatures:
```rust
fn f0() -> impl Fn() -> impl Trait;
fn f3() -> &'static dyn Fn() -> impl Trait;
```

These signatures were already allowed for common traits and associated types, there is no reason why `Fn*` traits should be special in this regard.

`impl Trait` in both `f0` and `f3` means "new existential type", just like with `-> impl Iterator<Item = impl Trait>` and such.

Arrow in `impl Fn() ->` is right-associative and binds from right to left, it's tested by [this test](a819fecb8d/src/test/ui/impl-trait/impl_fn_associativity.rs).

There even is a test that `f0` compiles:
2f004d2d40/src/test/ui/impl-trait/nested_impl_trait.rs (L25-L28)

But it was changed in [PR 48084 (lines)](https://github.com/rust-lang/rust/pull/48084/files#diff-ccecca938872d65ffe8cd1c3ef1956e309fac83bcda547d8b16b89257e53a437R37)  to test the opposite, probably unintentionally given [PR 48084 (lines)](https://github.com/rust-lang/rust/pull/48084/files#diff-5a02f1ed43debed1fd24f7aad72490064f795b9420f15d847bac822aa4621a1cR476-R477).

r? `@nikomatsakis`

----

This limitation is especially annoying with async code, since it forces one to write this:
```rust
trait AsyncFn3<A, B, C>: Fn(A, B, C) -> <Self as AsyncFn3<A, B, C>>::Future {
    type Future: Future<Output = Self::Out>;

    type Out;
}

impl<A, B, C, Fut, F> AsyncFn3<A, B, C> for F
where
    F: Fn(A, B, C) -> Fut,
    Fut: Future,
{
    type Future = Fut;

    type Out = Fut::Output;
}

fn async_closure() -> impl AsyncFn3<i32, i32, i32, Out = u32> {
    |a, b, c| async move { (a + b + c) as u32 }
}
```
Instead of:
```rust
fn async_closure() -> impl Fn(i32, i32, i32) -> impl Future<Output = u32> {
    |a, b, c| async move { (a + b + c) as u32 }
}
```
2022-10-30 11:50:26 +05:30
Nicholas Nethercote
c8c25ce5a1 Rename some OwnerId fields.
spastorino noticed some silly expressions like `item_id.def_id.def_id`.

This commit renames several `def_id: OwnerId` fields as `owner_id`, so
those expressions become `item_id.owner_id.def_id`.

`item_id.owner_id.local_def_id` would be even clearer, but the use of
`def_id` for values of type `LocalDefId` is *very* widespread, so I left
that alone.
2022-10-29 20:28:38 +11:00
Xiretza
cd621be782 Convert all #[suggestion_*] attributes to #[suggestion(style = "...")]
Using the following command:

find compiler/ -type f -name '*.rs' -exec perl -i -gpe \
    's/(#\[\w*suggestion)_(short|verbose|hidden)\(\s*(\S+,)?/\1(\3style = "\2",/g' \
    '{}' +
2022-10-26 15:04:09 +02:00
Maybe Waffle
e93982a78f adopt to compiler changes 2022-10-25 13:47:43 +00:00
Maybe Waffle
cc752f5665 Feature gate impl_trait_in_fn_trait_return 2022-10-25 13:25:52 +00:00
Maybe Waffle
8b494f427c Allow impl Fn() -> impl Trait in return position
This allows writing the following function signatures:
```rust
fn f0() -> impl Fn() -> impl Trait;
fn f3() -> &'static dyn Fn() -> impl Trait;
```

These signatures were already allowed for common traits and associated
types, there is no reason why `Fn*` traits should be special in this
regard.
2022-10-25 13:25:51 +00:00
Nilstrieb
c65ebae221
Migrate all diagnostics 2022-10-23 10:09:44 +02:00
Dylan DPC
e11511dfa6
Rollup merge of #103051 - davidtwco:translation-tidying-up, r=compiler-errors
translation: doc comments with derives, subdiagnostic-less enum variants, more derive use

- Adds support for `doc` attributes in the diagnostic derives so that documentation comments don't result in the derive failing.
- Adds support for enum variants in the subdiagnostic derive to not actually correspond to an addition to a diagnostic.
- Made use of the derive in more places in the `rustc_ast_lowering`, `rustc_ast_passes`, `rustc_lint`, `rustc_session`, `rustc_infer` - taking advantage of recent additions like eager subdiagnostics, multispan suggestions, etc.

cc #100717
2022-10-21 17:29:58 +05:30
Santiago Pastorino
49ce8a22b0
Do anonymous lifetimes remapping correctly for nested rpits 2022-10-19 16:49:39 -03:00
Santiago Pastorino
fb5475887f
Extract orig_opt_local_def_id as a function 2022-10-19 16:49:39 -03:00
Yuki Okushi
6e7d206a7b
Rollup merge of #103168 - Amanieu:stable_asm_sym, r=davidtwco
Stabilize asm_sym

Tracking issue #93333

Reference PR: https://github.com/rust-lang/reference/pull/1270
2022-10-18 21:21:32 +09:00
Amanieu d'Antras
430bd6200d Stabilize asm_sym 2022-10-17 22:38:37 +01:00
David Wood
2a4b587a68 ast_lowering: use derive more
Signed-off-by: David Wood <david.wood@huawei.com>
2022-10-17 09:54:24 +01:00
Dylan DPC
b79ad57ad7
Rollup merge of #102998 - nathanwhit:let-chains-drop-order, r=eholk
Drop temporaries created in a condition, even if it's a let chain

Fixes #100513.

During the lowering from AST to HIR we wrap expressions acting as conditions in a `DropTemps` expression so that any temporaries created in the condition are dropped after the condition is executed. Effectively this means we transform

```rust
if Some(1).is_some() { .. }
```

into (roughly)

```rust
if { let _t = Some(1).is_some(); _t } { .. }
```

so that if we create any temporaries, they're lifted into the new scope surrounding the condition, so for example something along the lines of

```rust
if { let temp = Some(1); let _t = temp.is_some(); _t }.
```

Before this PR, if the condition contained any let expressions we would not introduce that new scope, instead leaving the condition alone. This meant that in a let-chain like

```rust
if get_drop("first").is_some() && let None = get_drop("last") {
        println!("second");
} else { .. }
```

the temporary created for `get_drop("first")` would be lifted into the _surrounding block_, which caused it to be dropped after the execution of the entire `if` expression.

After this PR, we wrap everything but the `let` expression in terminating scopes. The upside to this solution is that it's minimally invasive, but the downside is that in the worst case, an expression with `let` exprs interspersed like

```rust
if get_drop("first").is_some()
    && let Some(_a) = get_drop("fifth")
    && get_drop("second").is_some()
    && let Some(_b) = get_drop("fourth") { .. }
```

gets _multiple_ new scopes, roughly

```rust
if { let _t = get_drop("first").is_some(); _t }
    && let Some(_a) = get_drop("fifth")
    && { let _t = get_drop("second").is_some(); _t }
    && let Some(_b) = get_drop("fourth") { .. }
```

so instead of all of the temporaries being dropped at the end of the entire condition, they will be dropped right after they're evaluated (before the subsequent `let` expr). So while I'd say the drop behavior around let-chains is _less_ surprising after this PR, it still might not exactly match what people might expect.

For tests, I've just extended the drop order tests added in #100526. I'm not sure if that's the best way to go about it, though, so suggestions are welcome.
2022-10-15 15:45:32 +05:30
bors
46244f335b Auto merge of #99292 - Aaron1011:stability-use-tree, r=cjgillot
Correctly handle path stability for 'use tree' items

PR #95956 started checking the stability of path segments.
However, this was not applied to 'use tree' items
(e.g. 'use some::path::{ItemOne, ItemTwo}') due to the way
that we desugar these items in HIR lowering.

This PR modifies 'use tree' lowering to preserve resolution
information, which is needed by stability checking.
2022-10-15 04:27:15 +00:00
Nathan Whitaker
709a08ade6 Lower condition directly from AST to HIR 2022-10-13 18:20:39 -07:00
Nathan Whitaker
ad8b242724 Let chains should still drop temporaries
by the end of the condition's execution
2022-10-12 17:57:32 -07:00