| Age | Commit message (Collapse) | Author | Lines | |
|---|---|---|---|---|
| 2025-10-02 | Auto merge of #147138 - jackh726:split-canonical-bound, r=lcnr | bors | -3/+28 | |
| Split Bound index into Canonical and Bound See [#t-types/trait-system-refactor > perf `async-closures/post-mono-higher-ranked-hang.rs`](https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/perf.20.60async-closures.2Fpost-mono-higher-ranked-hang.2Ers.60/with/541535613) for context Things compile and tests pass, but not sure if this actually solves the perf issue (edit: it does). Opening up this to do a perf (and maybe crater) run. r? lcnr | ||||
| 2025-09-30 | Split Bound into Canonical and Bound | jackh726 | -3/+28 | |
| 2025-09-28 | reword note | Esteban Küber | -5/+5 | |
| 2025-09-28 | Point at lifetime requirement origin in more cases | Esteban Küber | -4/+10 | |
| 2025-09-28 | Point at fn bound that introduced lifetime obligation | Esteban Küber | -1/+70 | |
| ``` error[E0597]: `c` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:19:20 | LL | fn simple<'a>(x: &'a i32) { | -- lifetime `'a` defined here ... LL | let c = async move || { println!("{}", *x); }; | - binding `c` declared here LL | outlives::<'a>(c()); | ---------------^--- | | | | | borrowed value does not live long enough | argument requires that `c` is borrowed for `'a` LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed | note: requirement that `c` is borrowed for `'a` introduced here --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 | LL | fn outlives<'a>(_: impl Sized + 'a) {} | ^^ ``` When encountering a `ConstraintCategory::Predicate` in a funtion call, point at the `Span` for that `Predicate` to explain where the lifetime obligation originates from. | ||||
| 2025-08-19 | Pretty print the name of an future from calling async closure | Michael Goulet | -0/+18 | |
| 2025-07-31 | Remove the witness type from coroutine args | Michael Goulet | -2/+2 | |
| 2025-07-23 | Point at the type that doesn't impl `Clone` in more cases beyond closures | Esteban Küber | -5/+7 | |
| 2025-07-17 | Eagerly unify coroutine witness in old solver | Michael Goulet | -2/+2 | |
| 2025-06-09 | Make E0621 missing lifetime suggestion verbose | Esteban Küber | -6/+10 | |
| ``` error[E0621]: explicit lifetime required in the type of `x` --> $DIR/42701_one_named_and_one_anonymous.rs:10:9 | LL | &*x | ^^^ lifetime `'a` required | help: add explicit lifetime `'a` to the type of `x` | LL | fn foo2<'a>(a: &'a Foo, x: &'a i32) -> &'a i32 { | ++ ``` | ||||
| 2025-05-26 | Support opaque_types_defined_by for SyntheticCoroutineBody | Michael Goulet | -0/+13 | |
| 2025-05-21 | Fix FnOnce impl for AsyncFn/AsyncFnMut closures in new solver | Michael Goulet | -0/+15 | |
| 2025-05-05 | Do not gather local all together at the beginning of typeck | Michael Goulet | -2/+2 | |
| 2025-04-26 | Rollup merge of #140318 - compiler-errors:specialized-async-fn-kind-err, ↵ | Matthias Krüger | -0/+43 | |
| r=fee1-dead Simply try to unpeel AsyncFnKindHelper goal in `emit_specialized_closure_kind_error` Tweak the handling of `AsyncFnKindHelper` goals in `emit_specialized_closure_kind_error` to not be so special-casey, and just try to unpeel one or two layers of obligation causes to get to their underlying `AsyncFn*` goal. Fixes https://github.com/rust-lang/rust/issues/140292 | ||||
| 2025-04-26 | Simply try to unpeel AsyncFnKindHelper goal in ↵ | Michael Goulet | -0/+43 | |
| emit_specialized_closure_kind_error | ||||
| 2025-04-23 | More | Michael Goulet | -5/+4 | |
| 2025-04-10 | replace `//@ compile-flags: --edition` with `//@ edition` | Pietro Albini | -3/+4 | |
| 2025-03-31 | Feed HIR for by-move coroutine body def, since the inliner tries to read its ↵ | Michael Goulet | -0/+28 | |
| attrs | ||||
| 2025-03-14 | Improve upvar analysis for deref of child capture | Michael Goulet | -0/+109 | |
| 2025-03-03 | Improve error message for AsyncFn trait failure for RPIT | Michael Goulet | -0/+31 | |
| 2025-02-12 | Rollup merge of #134090 - veluca93:stable-tf11, r=oli-obk | Jacob Pratt | -7/+6 | |
| Stabilize target_feature_11 # Stabilization report This is an updated version of https://github.com/rust-lang/rust/pull/116114, which is itself a redo of https://github.com/rust-lang/rust/pull/99767. Most of this commit and report were copied from those PRs. Thanks ```@LeSeulArtichaut``` and ```@calebzulawski!``` ## Summary Allows for safe functions to be marked with `#[target_feature]` attributes. Functions marked with `#[target_feature]` are generally considered as unsafe functions: they are unsafe to call, cannot *generally* be assigned to safe function pointers, and don't implement the `Fn*` traits. However, calling them from other `#[target_feature]` functions with a superset of features is safe. ```rust // Demonstration function #[target_feature(enable = "avx2")] fn avx2() {} fn foo() { // Calling `avx2` here is unsafe, as we must ensure // that AVX is available first. unsafe { avx2(); } } #[target_feature(enable = "avx2")] fn bar() { // Calling `avx2` here is safe. avx2(); } ``` Moreover, once https://github.com/rust-lang/rust/pull/135504 is merged, they can be converted to safe function pointers in a context in which calling them is safe: ```rust // Demonstration function #[target_feature(enable = "avx2")] fn avx2() {} fn foo() -> fn() { // Converting `avx2` to fn() is a compilation error here. avx2 } #[target_feature(enable = "avx2")] fn bar() -> fn() { // `avx2` coerces to fn() here avx2 } ``` See the section "Closures" below for justification of this behaviour. ## Test cases Tests for this feature can be found in [`tests/ui/target_feature/`](https://github.com/rust-lang/rust/tree/f6cb952dc115fd1311b02b694933e31d8dc8b002/tests/ui/target-feature). ## Edge cases ### Closures * [target-feature 1.1: should closures inherit target-feature annotations? #73631](https://github.com/rust-lang/rust/issues/73631) Closures defined inside functions marked with #[target_feature] inherit the target features of their parent function. They can still be assigned to safe function pointers and implement the appropriate `Fn*` traits. ```rust #[target_feature(enable = "avx2")] fn qux() { let my_closure = || avx2(); // this call to `avx2` is safe let f: fn() = my_closure; } ``` This means that in order to call a function with #[target_feature], you must guarantee that the target-feature is available while the function, any closures defined inside it, as well as any safe function pointers obtained from target-feature functions inside it, execute. This is usually ensured because target features are assumed to never disappear, and: - on any unsafe call to a `#[target_feature]` function, presence of the target feature is guaranteed by the programmer through the safety requirements of the unsafe call. - on any safe call, this is guaranteed recursively by the caller. If you work in an environment where target features can be disabled, it is your responsibility to ensure that no code inside a target feature function (including inside a closure) runs after this (until the feature is enabled again). **Note:** this has an effect on existing code, as nowadays closures do not inherit features from the enclosing function, and thus this strengthens a safety requirement. It was originally proposed in #73631 to solve this by adding a new type of UB: “taking a target feature away from your process after having run code that uses that target feature is UB” . This was motivated by userspace code already assuming in a few places that CPU features never disappear from a program during execution (see i.e. https://github.com/rust-lang/stdarch/blob/2e29bdf90832931ea499755bb4ad7a6b0809295a/crates/std_detect/src/detect/arch/x86.rs); however, concerns were raised in the context of the Linux kernel; thus, we propose to relax that requirement to "causing the set of usable features to be reduced is unsafe; when doing so, the programmer is required to ensure that no closures or safe fn pointers that use removed features are still in scope". * [Fix #[inline(always)] on closures with target feature 1.1 #111836](https://github.com/rust-lang/rust/pull/111836) Closures accept `#[inline(always)]`, even within functions marked with `#[target_feature]`. Since these attributes conflict, `#[inline(always)]` wins out to maintain compatibility. ### ABI concerns * [The extern "C" ABI of SIMD vector types depends on target features #116558](https://github.com/rust-lang/rust/issues/116558) The ABI of some types can change when compiling a function with different target features. This could have introduced unsoundness with target_feature_11, but recent fixes (#133102, #132173) either make those situations invalid or make the ABI no longer dependent on features. Thus, those issues should no longer occur. ### Special functions The `#[target_feature]` attribute is forbidden from a variety of special functions, such as main, current and future lang items (e.g. `#[start]`, `#[panic_handler]`), safe default trait implementations and safe trait methods. This was not disallowed at the time of the first stabilization PR for target_features_11, and resulted in the following issues/PRs: * [`#[target_feature]` is allowed on `main` #108645](https://github.com/rust-lang/rust/issues/108645) * [`#[target_feature]` is allowed on default implementations #108646](https://github.com/rust-lang/rust/issues/108646) * [#[target_feature] is allowed on #[panic_handler] with target_feature 1.1 #109411](https://github.com/rust-lang/rust/issues/109411) * [Prevent using `#[target_feature]` on lang item functions #115910](https://github.com/rust-lang/rust/pull/115910) ## Documentation * Reference: [Document the `target_feature_11` feature reference#1181](https://github.com/rust-lang/reference/pull/1181) --- cc tracking issue https://github.com/rust-lang/rust/issues/69098 cc ```@workingjubilee``` cc ```@RalfJung``` r? ```@rust-lang/lang``` | ||||
| 2025-02-10 | Show diff suggestion format on verbose replacement | Esteban Küber | -2/+3 | |
| ``` error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields --> $DIR/attempted-access-non-fatal.rs:7:15 | LL | let _ = 2.l; | ^ | help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix | LL - let _ = 2.l; LL + let _ = 2.0f64; | ``` | ||||
| 2025-02-02 | Shorten error message for callable with wrong return type | Esteban Küber | -3/+3 | |
| ``` error: expected `{closure@...}` to return `Ret`, but it returns `Other` ``` instead of ``` error: expected `{closure@...}` to be a closure that returns `Ret`, but it returns `Other` ``` | ||||
| 2025-01-27 | Stabilize target_feature_11 | Caleb Zulawski | -7/+6 | |
| 2025-01-26 | Add cache to FoldEscapingRegions | Michael Goulet | -0/+125 | |
| 2025-01-22 | Use `structurally_normalize` instead of manual `normalizes-to` goals | Boxy | -5/+27 | |
| 2025-01-15 | Render fn defs with target_features attrs with the attribute | Oli Scherer | -2/+3 | |
| 2025-01-15 | Treat safe target_feature functions as unsafe by default | Oli Scherer | -2/+2 | |
| 2025-01-06 | `best_blame_constraint`: don't filter constraints by sup SCC | dianne | -24/+24 | |
| The SCCs of the region graph are not a reliable heuristic to use for blaming an interesting constraint for diagnostics. For region errors, if the outlived region is `'static`, or the involved types are invariant in their lifetiems, there will be cycles in the constraint graph containing both the target region and the most interesting constraints to blame. To get better diagnostics in these cases, this commit removes that heuristic. | ||||
| 2024-12-31 | Make sure we check the future type is Sized in AsyncFn* | Michael Goulet | -0/+51 | |
| 2024-12-25 | Actually print all the relevant parts of a coroutine in verbose mode | Michael Goulet | -2/+2 | |
| 2024-12-13 | Stabilize async closures | Michael Goulet | -173/+60 | |
| 2024-12-08 | Don't use AsyncFnOnce::CallOnceFuture bounds for signature deduction | Michael Goulet | -0/+14 | |
| 2024-12-05 | Stabilize noop_waker | Eric Holk | -3/+3 | |
| Co-authored-by: zachs18 <8355914+zachs18@users.noreply.github.com> | ||||
| 2024-12-02 | Move tests back to using AsyncFn | Michael Goulet | -53/+53 | |
| 2024-11-22 | Pretty print AsyncFn traits too | Michael Goulet | -6/+37 | |
| 2024-11-02 | Auto merge of #132147 - estebank:long-types-2, r=davidtwco | bors | -1/+2 | |
| Tweak E0277 output when a candidate is available *Follow up to #132086.* Go from ``` error[E0277]: the trait bound `Then<Ignored<chumsky::combinator::Filter<chumsky::primitive::Any<&str, chumsky::extra::Full<EmptyErr, (), ()>>, {closure@src/main.rs:9:17: 9:27}>, char>, chumsky::combinator::Map<impl CSTParser<'a, O>, O, {closure@src/main.rs:11:24: 11:27}>, (), (), chumsky::extra::Full<EmptyErr, (), ()>>: CSTParser<'a>` is not satisfied --> src/main.rs:7:50 | 7 | fn leaf<'a, O>(parser: impl CSTParser<'a, O>) -> impl CSTParser<'a, ()> { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `chumsky::private::ParserSealed<'_, &str, (), chumsky::extra::Full<EmptyErr, (), ()>>` is not implemented for `Then<Ignored<Filter<Any<&str, ...>, ...>, ...>, ..., ..., ..., ...>`, which is required by `Then<Ignored<chumsky::combinator::Filter<chumsky::primitive::Any<&str, chumsky::extra::Full<EmptyErr, (), ()>>, {closure@src/main.rs:9:17: 9:27}>, char>, chumsky::combinator::Map<impl CSTParser<'a, O>, O, {closure@src/main.rs:11:24: 11:27}>, (), (), chumsky::extra::Full<EmptyErr, (), ()>>: CSTParser<'a>` | = help: the trait `chumsky::private::ParserSealed<'_, &'a str, ((), ()), chumsky::extra::Full<EmptyErr, (), ()>>` is implemented for `Then<Ignored<chumsky::combinator::Filter<chumsky::primitive::Any<&str, chumsky::extra::Full<EmptyErr, (), ()>>, {closure@src/main.rs:9:17: 9:27}>, char>, chumsky::combinator::Map<impl CSTParser<'a, O>, O, {closure@src/main.rs:11:24: 11:27}>, (), (), chumsky::extra::Full<EmptyErr, (), ()>>` = help: for that trait implementation, expected `((), ())`, found `()` = note: required for `Then<Ignored<Filter<Any<&str, ...>, ...>, ...>, ..., ..., ..., ...>` to implement `Parser<'_, &str, ()>` note: required for `Then<Ignored<Filter<Any<&str, ...>, ...>, ...>, ..., ..., ..., ...>` to implement `CSTParser<'a>` --> src/main.rs:5:16 | 5 | impl<'a, O, T> CSTParser<'a, O> for T where T: Parser<'a, &'a str, O> {} | ^^^^^^^^^^^^^^^^ ^ ---------------------- unsatisfied trait bound introduced here = note: the full name for the type has been written to '/home/gh-estebank/longlong/target/debug/deps/longlong-0008f9a4f2023b08.long-type-13239977239800463552.txt' = note: consider using `--verbose` to print the full type name to the console = note: the full name for the type has been written to '/home/gh-estebank/longlong/target/debug/deps/longlong-0008f9a4f2023b08.long-type-13239977239800463552.txt' = note: consider using `--verbose` to print the full type name to the console ``` to ``` error[E0277]: the trait bound `Then<Ignored<chumsky::combinator::Filter<chumsky::primitive::Any<&str, chumsky::extra::Full<EmptyErr, (), ()>>, {closure@src/main.rs:9:17: 9:27}>, char>, chumsky::combinator::Map<impl CSTParser<'a, O>, O, {closure@src/main.rs:11:24: 11:27}>, (), (), chumsky::extra::Full<EmptyErr, (), ()>>: CSTParser<'a>` is not satisfied --> src/main.rs:7:50 | 7 | fn leaf<'a, O>(parser: impl CSTParser<'a, O>) -> impl CSTParser<'a, ()> { | ^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound ... 11 | ws.then(parser.map(|_| ())) | --------------------------- return type was inferred to be `Then<Ignored<..., ...>, ..., ..., ..., ...>` here | = help: the trait `ParserSealed<'_, &_, (), Full<_, _, _>>` is not implemented for `Then<Ignored<..., ...>, ..., ..., ..., ...>` but trait `ParserSealed<'_, &'a _, ((), ()), Full<_, _, _>>` is implemented for it = help: for that trait implementation, expected `((), ())`, found `()` = note: required for `Then<Ignored<..., ...>, ..., ..., ..., ...>` to implement `Parser<'_, &str, ()>` note: required for `Then<Ignored<..., ...>, ..., ..., ..., ...>` to implement `CSTParser<'a>` --> src/main.rs:5:16 | 5 | impl<'a, O, T> CSTParser<'a, O> for T where T: Parser<'a, &'a str, O> {} | ^^^^^^^^^^^^^^^^ ^ ---------------------- unsatisfied trait bound introduced here = note: the full name for the type has been written to '/home/gh-estebank/longlong/target/debug/deps/longlong-df9d52be87eada65.long-type-1337037744507305372.txt' = note: consider using `--verbose` to print the full type name to the console ``` * Remove redundant wording * Introduce trait diff highlighting logic and use it * Fix incorrect "long type written to path" logic (can be split off) * Point at tail expression in more cases in E0277 * Avoid long primary span labels in E0277 by moving them to a `help` Fix #132013. There are individual commits that can be their own PR. If the review load is too big, happy to split them off. | ||||
| 2024-11-02 | Remove or fix some FIXME(async_closure) | Michael Goulet | -15/+24 | |
| 2024-11-02 | On long E0277 primary span label, move it to a `help` | Esteban Küber | -1/+2 | |
| Long span labels don't read well. | ||||
| 2024-10-29 | Remove detail from label/note that is already available in other note | Esteban Küber | -1/+1 | |
| Remove the "which is required by `{root_obligation}`" post-script in "the trait `X` is not implemented for `Y`" explanation in E0277. This information is already conveyed in the notes explaining requirements, making it redundant while making the text (particularly in labels) harder to read. ``` error[E0277]: the trait bound `NotCopy: Copy` is not satisfied --> $DIR/wf-static-type.rs:10:13 | LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy` | = note: required for `Option<NotCopy>` to implement `Copy` note: required by a bound in `IsCopy` --> $DIR/wf-static-type.rs:7:17 | LL | struct IsCopy<T:Copy> { t: T } | ^^^^ required by this bound in `IsCopy` ``` vs the prior ``` error[E0277]: the trait bound `NotCopy: Copy` is not satisfied --> $DIR/wf-static-type.rs:10:13 | LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option<NotCopy>: Copy` | = note: required for `Option<NotCopy>` to implement `Copy` note: required by a bound in `IsCopy` --> $DIR/wf-static-type.rs:7:17 | LL | struct IsCopy<T:Copy> { t: T } | ^^^^ required by this bound in `IsCopy` ``` | ||||
| 2024-09-16 | Fix a couple more DefKind discrepancies between DefKind::Closure and ↵ | Michael Goulet | -0/+34 | |
| DefKind::SyntheticCoroutineBody | ||||
| 2024-09-16 | Encode coroutine_by_move_body_def_id in crate metadata | Michael Goulet | -0/+5 | |
| 2024-09-16 | Don't ICE when generating Fn shim for async closure with borrowck error | Michael Goulet | -0/+45 | |
| 2024-09-14 | Consider synthetic closure bodies to be typeck children | Michael Goulet | -0/+19 | |
| 2024-09-10 | Don't call closure_by_move_body_def_id on FnOnce async closures in MIR ↵ | Michael Goulet | -0/+20 | |
| validation | ||||
| 2024-09-07 | Rollup merge of #129847 - compiler-errors:async-cycle, r=davidtwco | Matthias Krüger | -0/+19 | |
| Do not call query to compute coroutine layout for synthetic body of async closure There is code in the MIR validator that attempts to prevent query cycles when inlining a coroutine into itself, and will use the coroutine layout directly from the body when it detects that's the same coroutine as the one that's being validated. After #128506, this logic didn't take into account the fact that the coroutine def id will differ if it's the "by-move body" of an async closure. This PR implements that. Fixes #129811 | ||||
| 2024-09-07 | Don't build by-move body when async closure is tainted | Michael Goulet | -0/+27 | |
| 2024-09-01 | Replace walk with visit so we dont skip outermost expr kind in def collector | Michael Goulet | -0/+12 | |
| 2024-09-01 | Do not call query to compute coroutine layout for synthetic body of async ↵ | Michael Goulet | -0/+19 | |
| closure | ||||
| 2024-08-15 | Rollup merge of #129101 - compiler-errors:deref-on-parent-by-ref, r=lcnr | Matthias Krüger | -0/+34 | |
| Fix projections when parent capture is by-ref but child capture is by-value in the `ByMoveBody` pass This fixes a somewhat strange bug where we build the incorrect MIR in #129074. This one is weird, but I don't expect it to actually matter in practice since it almost certainly results in a move error in borrowck. However, let's not ICE. Given the code: ``` #![feature(async_closure)] // NOT copy. struct Ty; fn hello(x: &Ty) { let c = async || { *x; //~^ ERROR cannot move out of `*x` which is behind a shared reference }; } fn main() {} ``` The parent coroutine-closure captures `x: &Ty` by-ref, resulting in an upvar of `&&Ty`. The child coroutine captures `x` by-value, resulting in an upvar of `&Ty`. When constructing the by-move body for the coroutine-closure, we weren't applying an additional deref projection to convert the parent capture into the child capture, resulting in an type error in assignment, which is a validation ICE. As I said above, this only occurs (AFAICT) in code that eventually results in an error, because it is only triggered by HIR that attempts to move a non-copy value out of a ref. This doesn't occur if `Ty` is `Copy`, since we'd instead capture `x` by-ref in the child coroutine. Fixes #129074 | ||||
