about summary refs log tree commit diff
path: root/tests
AgeCommit message (Collapse)AuthorLines
2024-04-05Put non_local_definitions lint back to warn-by-defaultUrgau-61/+56
2024-04-05Update non-local impl definition lint rule noteUrgau-51/+51
2024-04-05Eliminate false-positives in the non-local lint with the type-systemUrgau-29/+158
2024-04-04Rollup merge of #123431 - ↵Matthias Krüger-49/+0
slanterns:literal_byte_character_c_string_stabilize, r=dtolnay Stabilize `proc_macro_byte_character` and `proc_macro_c_str_literals` This PR stabilizes `proc_macro_byte_character` and `proc_macro_c_str_literals`: ```rust // proc_macro::Literal impl Literal { pub fn byte_character(byte: u8) -> Literal; pub fn c_string(string: &CStr) -> Literal } ``` <br> Tracking issue: https://github.com/rust-lang/rust/issues/115268, https://github.com/rust-lang/rust/issues/119750. Implementation PR: https://github.com/rust-lang/rust/pull/112711, https://github.com/rust-lang/rust/pull/119651. FCPs already completed in their respective tracking issues. Closes https://github.com/rust-lang/rust/issues/115268. Closes https://github.com/rust-lang/rust/issues/119750. r? libs-api
2024-04-04Rollup merge of #123397 - krtab:foreign_fn_qualif_diag, r=petrochenkovMatthias Krüger-62/+57
Fix diagnostic for qualifier in extern block Closes: https://github.com/rust-lang/rust/issues/123306
2024-04-04Rollup merge of #123324 - Nadrieril:false-edges2, r=matthewjasperMatthias Krüger-72/+240
match lowering: make false edges more precise When lowering match expressions, we add false edges to hide details of the lowering from borrowck. Morally we pretend we're testing the patterns (and guards) one after the other in order. See the tests for examples. Problem is, the way we implement this today is too coarse for deref patterns. In deref patterns, a pattern like `deref [1, x]` matches on a `Vec` by creating a temporary to store the output of the call to `deref()` and then uses that to continue matching. Here the pattern has a binding, which we set up after the pre-binding block. Problem is, currently the false edges tell borrowck that the pre-binding block can be reached from a previous arm as well, so the `deref()` temporary may not be initialized. This triggers an error when we try to use the binding `x`. We could call `deref()` a second time, but this opens the door to soundness issues if the deref impl is weird. Instead in this PR I rework false edges a little bit. What we need from false edges is a (fake) path from each candidate to the next, specifically from candidate C's pre-binding block to next candidate D's pre-binding block. Today, we link the pre-binding blocks directly. In this PR, I link them indirectly by choosing an earlier node on D's success path. Specifically, I choose the earliest block on D's success path that doesn't make a loop (if I chose e.g. the start block of the whole match (which is on the success path of all candidates), that would make a loop). This turns out to be rather straightforward to implement. r? `@matthewjasper` if you have the bandwidth, otherwise let me know
2024-04-04Rollup merge of #123218 - compiler-errors:synthetic-hir-parent, r=petrochenkovMatthias Krüger-0/+38
Add test for getting parent HIR for synthetic HIR node Fixes #122991, which was actually fixed by #123415
2024-04-04Rollup merge of #122448 - high-cloud:move-hir-tree, r=oli-obkMatthias Krüger-11/+10
Port hir-tree run-make test to ui test As part of #121876 cc `@jieyouxu`
2024-04-04Rollup merge of #121546 - gurry:121473-ice-sizeof-mir-op, r=oli-obkMatthias Krüger-0/+185
Error out of layout calculation if a non-last struct field is unsized Fixes #121473 Fixes #123152
2024-04-04move hir-tree test from run-make to ui testYaodong Yang-11/+10
2024-04-04Error out of layout calculation if a non-last struct field is unsizedGurinder Singh-0/+185
Fixes an ICE that occurs when a struct with an unsized field at a non-last position is const evaluated.
2024-04-04Fix diagnostic for qualifier in extern blockArthur Carcano-62/+57
Closes: https://github.com/rust-lang/rust/issues/123306
2024-04-04Auto merge of #115538 - lcnr:fn-def-wf, r=compiler-errorsbors-38/+132
check `FnDef` return type for WF better version of #106807, fixes #84533 (mostly). It's not perfect given that we still ignore WF requirements involving bound regions but I wasn't able to quickly write an example, so even if theoretically exploitable, it should be far harder to trigger. This is strictly more restrictive than checking the return type for WF as part of the builtin `FnDef: FnOnce` impl (#106807) and moving to this approach in the future will not break any code. ~~It also agrees with my theoretical view of how this should behave~~ r? types
2024-04-04Auto merge of #123052 - maurer:addr-taken, r=compiler-errorsbors-10/+40
CFI: Support function pointers for trait methods Adds support for both CFI and KCFI for function pointers to trait methods by attaching both concrete and abstract types to functions. KCFI does this through generation of a `ReifyShim` on any function pointer for a method that could go into a vtable, and keeping this separate from `ReifyShim`s that are *intended* for vtable us by setting a `ReifyReason` on them. CFI does this by setting both the concrete and abstract type on every instance. This should land after #123024 or a similar PR, as it diverges the implementation of CFI vs KCFI. r? `@compiler-errors`
2024-04-04Auto merge of #119820 - lcnr:leak-check-2, r=jackh726bors-179/+804
instantiate higher ranked goals outside of candidate selection This PR modifies `evaluate` to more eagerly instantiate higher-ranked goals, preventing the `leak_check` during candidate selection from detecting placeholder errors involving that binder. For a general background regarding higher-ranked region solving and the leak check, see https://hackmd.io/qd9Wp03cQVy06yOLnro2Kg. > The first is something called the **leak check**. You can think of it as a "quick and dirty" approximation for the region check, which will come later. The leak check detects some kinds of errors early, essentially deciding between "this set of outlives constraints are guaranteed to result in an error eventually" or "this set of outlives constraints may be solvable". ## The ideal future We would like to end up with the following idealized design to handle universal binders: ```rust fn enter_forall<'tcx, T, R>( forall: Binder<'tcx, T>, f: impl FnOnce(T) -> R, ) -> R { let new_universe = infcx.increment_universe_index(); let value = instantiate_binder_with_placeholders_in(new_universe, forall); let result = f(value); eagerly_handle_higher_ranked_region_constraints_in(new_universe); infcx.decrement_universe_index(); assert!(!result.has_placeholders_in_or_above(new_universe)); result } ``` That is, when universally instantiating a binder, anything using the placeholders has to happen inside of a limited scope (the closure `f`). After this closure has completed, all constraints involving placeholders are known. We then handle any *external constraints* which name these placeholders. We destructure `TypeOutlives` constraints involving placeholders and eagerly handle any region constraints involving these placeholders. We do not return anything mentioning the placeholders created inside of this function to the caller. Being able to eagerly handle *all* region constraints involving placeholders will be difficult due to complex `TypeOutlives` constraints, involving inference variables or alias types, and higher ranked implied bounds. The exact issues and possible solutions are out of scope of this FCP. #### How does the leak check fit into this The `leak_check` is an underapproximation of `eagerly_handle_higher_ranked_region_constraints_in`. It detects some kinds of errors involving placeholders from `new_universe`, but not all of them. It only looks at region outlives constraints, ignoring `TypeOutlives`, and checks whether one of the following two conditions are met for **placeholders in or above `new_universe`**, in which case it results in an error: - `'!p1: '!p2` a placeholder `'!p2` outlives a different placeholder `'!p1` - `'!p1: '?2` an inference variable `'?2` outlives a placeholder `'!p1` *which it cannot name* It does not handle all higher ranked region constraints, so we still return constraints involving placeholders from `new_universe` which are then (re)checked by `lexical_region_resolve` or MIR borrowck. As we check higher ranked constraints in the full regionck anyways, the `leak_check` is not soundness critical. It's current only purpose is to move some higher ranked region errors earlier, enabling it to guide type inference and trait solving. Adding additional uses of the `leak_check` in the future would only strengthen inference and is therefore not breaking. ## Where do we use currently use the leak check The `leak_check` is currently used in two places: Coherence does not use a proper regionck, only relying on the `leak_check` called [at the end of the implicit negative overlap check](https://github.com/rust-lang/rust/blob/8b94152af68a0ed6d6af0b5ba57491e40481008e/compiler/rustc_trait_selection/src/traits/coherence.rs#L235-L238). During coherence all parameters are instantiated with inference variables, so the only possible region errors are higher-ranked. We currently also sometimes make guesses when destructuring `TypeOutlives` constraints which can theoretically result in incorrect errors. This could result in overlapping impls. We also use the `leak_check` [at the end of `fn evaluation_probe`](https://github.com/rust-lang/rust/blob/8b94152af68a0ed6d6af0b5ba57491e40481008e/compiler/rustc_trait_selection/src/traits/select/mod.rs#L607-L610). This function is used during candidate assembly for `Trait` goals. Most notably we use [inside of `evaluate_candidate` during winnowing](https://github.com/rust-lang/rust/blob/0e4243538b9119654c22dce688f8a63c81864de9/compiler/rustc_trait_selection/src/traits/select/mod.rs#L491-L502). Conceptionally, it is as if we compute each candidate in a separate `enter_forall`. ## The current use in `fn evaluation_probe` is undesirable Because we only instantiate a higher-ranked goal once inside of `fn evaluation_probe`, errors involving placeholders from that binder can impact selection. This results in inconsistent behavior ([playground]( *[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=dac60ebdd517201788899ffa77364831)*)): ```rust trait Leak<'a> {} impl Leak<'_> for Box<u32> {} impl Leak<'static> for Box<u16> {} fn impls_leak<T: for<'a> Leak<'a>>() {} trait IndirectLeak<'a> {} impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {} fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {} fn main() { // ok // // The `Box<u16>` impls fails the leak check, // meaning that we apply the `Box<u32>` impl. impls_leak::<Box<_>>(); // error: type annotations needed // // While the `Box<u16>` impl would fail the leak check // we have already instantiated the binder while applying // the generic `IndirectLeak` impl, so during candidate // selection of `Leak` we do not detect the placeholder error. // Evaluation of `Box<_>: Leak<'!a>` is therefore ambiguous, // resulting in `for<'a> Box<_>: Leak<'a>` also being ambiguous. impls_indirect_leak::<Box<_>>(); } ``` We generally prefer `where`-bounds over implementations during candidate selection, both for [trait goals](https://github.com/rust-lang/rust/blob/11f32b73e0dc9287e305b5b9980d24aecdc8c17f/compiler/rustc_trait_selection/src/traits/select/mod.rs#L1863-L1887) and during [normalization](https://github.com/rust-lang/rust/blob/11f32b73e0dc9287e305b5b9980d24aecdc8c17f/compiler/rustc_trait_selection/src/traits/project.rs#L184-L198). However, we currently **do not** use the `leak_check` during candidate assembly in normalizing. This can result in inconsistent behavior: ```rust trait Trait<'a> { type Assoc; } impl<'a, T> Trait<'a> for T { type Assoc = usize; } fn trait_bound<T: for<'a> Trait<'a>>() {} fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {} // A function with a trivial where-bound which is more // restrictive than the impl. fn function<T: Trait<'static, Assoc = usize>>() { // ok // // Proving `for<'a> T: Trait<'a>` using the where-bound results // in a leak check failure, so we use the more general impl, // causing this to succeed. trait_bound::<T>(); // error // // Proving the `Projection` goal `for<'a> T: Trait<'a, Assoc = usize>` // does not use the leak check when trying the where-bound, causing us // to prefer it over the impl, resulting in a placeholder error. projection_bound::<T>(); // error // // Trying to normalize the type `for<'a> fn(<T as Trait<'a>>::Assoc)` // only gets to `<T as Trait<'a>>::Assoc` once `'a` has been already // instantiated, causing us to prefer the where-bound over the impl // resulting in a placeholder error. Even if were were to also use the // leak check during candidate selection for normalization, this // case would still not compile. let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| (); } ``` This is also likely to be more performant. It enables more caching in the new trait solver by simply [recursively calling the canonical query][new solver] after instantiating the higher-ranked goal. It is also unclear how to add the leak check to normalization in the new solver. To handle https://github.com/rust-lang/trait-system-refactor-initiative/issues/1 `Projection` goals are implemented via `AliasRelate`. This again means that we instantiate the binder before ever normalizing any alias. Even if we were to avoid this, we lose the ability to [cache normalization by itself, ignoring the expected `term`](https://github.com/rust-lang/rust/blob/5bd5d214effd494f4bafb29b3a7a2f6c2070ca5c/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs#L34-L49). We cannot replace the `term` with an inference variable before instantiating the binder, as otherwise `for<'a> T: Trait<Assoc<'a> = &'a ()>` breaks. If we only replace the term after instantiating the binder, we cannot easily evaluate the goal in a separate context, as [we'd then lose the information necessary for the leak check](https://github.com/rust-lang/rust/blob/11f32b73e0dc9287e305b5b9980d24aecdc8c17f/compiler/rustc_next_trait_solver/src/canonicalizer.rs#L230-L232). Adding this information to the canonical input also seems non-trivial. ## Proposed solution I propose to instantiate the binder outside of candidate assembly, causing placeholders from higher-ranked goals to get ignored while selecting their candidate. This mostly[^1] matches the [current behavior of the new solver][new solver]. The impact of this change is therefore as follows: ```rust trait Leak<'a> {} impl Leak<'_> for Box<u32> {} impl Leak<'static> for Box<u16> {} fn impls_leak<T: for<'a> Leak<'a>>() {} trait IndirectLeak<'a> {} impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {} fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {} fn guide_selection() { // ok -> ambiguous impls_leak::<Box<_>>(); // ambiguous impls_indirect_leak::<Box<_>>(); } trait Trait<'a> { type Assoc; } impl<'a, T> Trait<'a> for T { type Assoc = usize; } fn trait_bound<T: for<'a> Trait<'a>>() {} fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {} // A function which a trivial where-bound which is more // restrictive than the impl. fn function<T: Trait<'static, Assoc = usize>>() { // ok -> error trait_bound::<T>(); // error projection_bound::<T>(); // error let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| (); } ``` This does not change the behavior if candidates have higher ranked nested goals, as in this case the `leak_check` causes the nested goal to result in an error ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a74c25300b23db9022226de99d8a2fa6)): ```rust trait LeakCheckFailure<'a> {} impl LeakCheckFailure<'static> for () {} trait Trait<T> {} impl Trait<u32> for () where for<'a> (): LeakCheckFailure<'a> {} impl Trait<u16> for () {} fn impls_trait<T: Trait<U>, U>() {} fn main() { // ok // // It does not matter whether candidate assembly // considers the placeholders from higher-ranked goal. // // Either `for<'a> (): LeakCheckFailure<'a>` has no // applicable candidate or it has a single applicable candidate // when then later results in an error. This allows us to // infer `U` to `u16`. impls_trait::<(), _>() } ``` ## Impact on existing crates This is a **breaking change**. [A crater run](https://github.com/rust-lang/rust/pull/119820#issuecomment-1926862174) found 17 regressed crates with 7 root causes. For a full analysis of all affected crates, see https://gist.github.com/lcnr/7c1c652f30567048ea240554a36ed95c. --- I believe this breakage to be acceptable and would merge this change. I am confident that the new position of the leak check matches our idealized future and cannot envision any other consistent alternative. Where possible, I intend to open PRs fixing/avoiding the regressions before landing this PR. I originally intended to remove the `coherence_leak_check` lint in the same PR. However, while I am confident in the *position* of the leak check, deciding on its exact behavior is left as future work, cc #112999. This PR therefore only moves the leak check while keeping the lint when relying on it in coherence. [new solver]: https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs#L479-L484 [^1]: the new solver has a separate cause of inconsistent behavior rn https://github.com/rust-lang/trait-system-refactor-initiative/issues/53#issuecomment-1914310171 r? `@nikomatsakis`
2024-04-04Auto merge of #123440 - jhpratt:rollup-yat6crk, r=jhprattbors-10/+146
Rollup of 4 pull requests Successful merges: - #122356 (std::rand: fix dragonflybsd after #121942.) - #123093 (Add a nice header to our README.md) - #123307 (Fix f16 and f128 feature gating on different editions) - #123401 (Check `x86_64` size assertions on `aarch64`, too) r? `@ghost` `@rustbot` modify labels: rollup
2024-04-04rebaseBoxy-6/+20
2024-04-04check `FnDef` return type for WFlcnr-37/+117
2024-04-03Rollup merge of #123307 - tgross35:f16-f128-feature-gate-fix, r=petrochenkovJacob Pratt-10/+146
Fix f16 and f128 feature gating on different editions Apply the fix from https://github.com/rust-lang/rust/issues/123282#issuecomment-2035063388 to correctly gates `f16` and `f128` in editions other than 2015
2024-04-04Auto merge of #123240 - compiler-errors:assert-args-compat, r=fmeasebors-1/+19
Assert that args are actually compatible with their generics, rather than just their count Right now we just check that the number of args is right, rather than actually checking the kinds. Uplift a helper fn that I wrote from trait selection to do just that. Found a couple bugs along the way. r? `@lcnr` or `@fmease` (or anyone really lol)
2024-04-03rebase oddityBoxy-40/+41
2024-04-03Tests for getting parent of synthetic HIRMichael Goulet-0/+38
2024-04-03move leak check out of candidate evaluationlcnr-179/+803
this prevents higher ranked goals from guiding selection
2024-04-03Add `if let` testsNadrieril-10/+80
2024-04-04Stabilize `Literal::c_string`Slanterns-25/+0
2024-04-04Stabilize `Literal::byte_character`Slanterns-24/+0
2024-04-03Rollup merge of #123301 - Nadrieril:unions, r=compiler-errorsMatthias Krüger-0/+69
pattern analysis: fix union handling Little known fact: rust supports union patterns. Exhaustiveness handles them soundly but reports nonsensical missing patterns. This PR fixes the reported patterns and documents what we're doing. r? `@compiler-errors`
2024-04-03Rollup merge of #123291 - c410-f3r:testsssssss, r=petrochenkovMatthias Krüger-20/+0
Move some tests r? `@petrochenkov`
2024-04-03Rollup merge of #122964 - joboet:pointer_expose, r=AmanieuMatthias Krüger-23/+23
Rename `expose_addr` to `expose_provenance` `expose_addr` is a bad name, an address is just a number and cannot be exposed. The operation is actually about the provenance of the pointer. This PR thus changes the name of the method to `expose_provenance` without changing its return type. There is sufficient precedence for returning a useful value from an operation that does something else without the name indicating such, e.g. [`Option::insert`](https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.insert) and [`MaybeUninit::write`](https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write). Returning the address is merely convenient, not a fundamental part of the operation. This is implied by the fact that integers do not have provenance since ```rust let addr = ptr.addr(); ptr.expose_provenance(); let new = ptr::with_exposed_provenance(addr); ``` must behave exactly like ```rust let addr = ptr.expose_provenance(); let new = ptr::with_exposed_provenance(addr); ``` as the result of `ptr.expose_provenance()` and `ptr.addr()` is the same integer. Therefore, this PR removes the `#[must_use]` annotation on the function and updates the documentation to reflect the important part. ~~An alternative name would be `expose_provenance`. I'm not at all opposed to that, but it makes a stronger implication than we might want that the provenance of the pointer returned by `ptr::with_exposed_provenance`[^1] is the same as that what was exposed, which is not yet specified as such IIUC. IMHO `expose` does not make that connection.~~ A previous version of this PR suggested `expose` as name, libs-api [decided on](https://github.com/rust-lang/rust/pull/122964#issuecomment-2033194319) `expose_provenance` to keep the symmetry with `with_exposed_provenance`. CC `@RalfJung` r? libs-api [^1]: I'm using the new name for `from_exposed_addr` suggested by #122935 here.
2024-04-03Rollup merge of #122619 - erikdesjardins:cast, r=compiler-errorsMatthias Krüger-6/+382
Fix some unsoundness with PassMode::Cast ABI Fixes #122617 Reviewable commit-by-commit. More info in each commit message.
2024-04-03Rollup merge of #121595 - strottos:issue_116615, r=compiler-errorsMatthias Krüger-26/+173
Better reporting on generic argument mismatchs This allows better reporting as per issue #116615 . If you have a function: ``` fn foo(a: T, b: T) {} ``` and call it like so: ``` foo(1, 2.) ``` it'll give improved error reported similar to the following: ``` error[E0308]: mismatched types --> generic-mismatch-reporting-issue-116615.rs:6:12 | 6 | foo(1, 2.); | --- - ^^ expected integer, found floating-point number | | | | | expected argument `b` to be an integer because that argument needs to match the type of this parameter | arguments to this function are incorrect | note: function defined here --> generic-mismatch-reporting-issue-116615.rs:1:4 | 1 | fn foo<T>(a: T, b: T) {} | ^^^ - ---- ---- | | | | | | | this parameter needs to match the integer type of `a` | | `b` needs to match the type of this parameter | `a` and `b` all reference this parameter T ``` Open question, do we need to worry about error message translation into other languages? Not sure what the status of that is in Rust. NB: Needs some checking over and some tests have altered that need sanity checking, but overall this is starting to get somewhere now. Will take out of draft PR status when this has been done, raising now to allow feedback at this stage, probably 90% ready.
2024-04-03Fix f16 and f128 feature gates in editions other than 2015Trevor Gross-20/+20
Fixes https://github.com/rust-lang/rust/issues/123282 Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
2024-04-03Update f16 and f128 tests to run on both 2015 and 2018 editionsTrevor Gross-10/+146
Reproduce the bug from <https://github.com/rust-lang/rust/issues/123282> that indicates this feature gate hits edition-dependent resolution paths. Resolution changed in edition 2018, so test that as well.
2024-04-03More precise false edgesNadrieril-16/+16
2024-04-03Add testsNadrieril-56/+154
2024-04-03Stop chopping off args for no reasonMichael Goulet-1/+19
2024-04-03Rollup merge of #123394 - compiler-errors:postfix-match-fixes, r=estebankMatthias Krüger-0/+35
Postfix match fixes 1. Don't ice on `expr as Ty.match {}` 2. Fix the suggestion span for non-exhaustive matches to add `_ => todo!(),` Fixes #123383
2024-04-03rename `expose_addr` to `expose_provenance`joboet-23/+23
2024-04-03Auto merge of #123322 - matthewjasper:remove-mir-unsafeck, ↵bors-1180/+631
r=lcnr,compiler-errors Remove MIR unsafe check Now that THIR unsafeck is enabled by default in stable I think we can remove MIR unsafeck entirely. This PR also removes safety information from MIR.
2024-04-03Remove MIR unsafe checkMatthew Jasper-1180/+631
This also remove safety information from MIR.
2024-04-03Auto merge of #123402 - workingjubilee:rollup-0j5ihn6, r=workingjubileebors-0/+92
Rollup of 4 pull requests Successful merges: - #122411 ( Provide cabi_realloc on wasm32-wasip2 by default ) - #123349 (Fix capture analysis for by-move closure bodies) - #123359 (Link against libc++abi and libunwind as well when building LLVM wrappers on AIX) - #123388 (use a consistent style for links) r? `@ghost` `@rustbot` modify labels: rollup
2024-04-02Rollup merge of #123349 - compiler-errors:async-closure-captures, r=oli-obkJubilee-0/+92
Fix capture analysis for by-move closure bodies The check we were doing to figure out if a coroutine was borrowing from its parent coroutine-closure was flat-out wrong -- a misunderstanding of mine of the way that `tcx.closure_captures` represents its captures. Fixes #123251 (the miri/ui test I added should more than cover that issue) r? `@oli-obk` -- I recognize that this PR may be underdocumented, so please ask me what I should explain further.
2024-04-03Auto merge of #122225 - DianQK:nits-120268, r=cjgillotbors-152/+200
Rename `UninhabitedEnumBranching` to `UnreachableEnumBranching` Per [#120268](https://github.com/rust-lang/rust/pull/120268#discussion_r1517492060), I rename `UninhabitedEnumBranching` to `UnreachableEnumBranching` . I solved some nits to add some comments. I adjusted the workaround restrictions. This should be useful for `a <= b` and `if let Some/Ok(v)`. For enum with few variants, `early-tailduplication` should not cause compile time overhead. r? RalfJung
2024-04-03Auto merge of #123396 - jhpratt:rollup-oa54mh1, r=jhprattbors-16/+85
Rollup of 5 pull requests Successful merges: - #122865 (Split hir ty lowerer's error reporting code in check functions to mod errors.) - #122935 (rename ptr::from_exposed_addr -> ptr::with_exposed_provenance) - #123182 (Avoid expanding to unstable internal method) - #123203 (Add `Context::ext`) - #123380 (Improve bootstrap comments) r? `@ghost` `@rustbot` modify labels: rollup
2024-04-02Rollup merge of #123203 - jkarneges:context-ext, r=AmanieuJacob Pratt-6/+38
Add `Context::ext` This change enables `Context` to carry arbitrary extension data via a single `&mut dyn Any` field. ```rust #![feature(context_ext)] impl Context { fn ext(&mut self) -> &mut dyn Any; } impl ContextBuilder { fn ext(self, data: &'a mut dyn Any) -> Self; fn from(cx: &'a mut Context<'_>) -> Self; fn waker(self, waker: &'a Waker) -> Self; } ``` Basic usage: ```rust struct MyExtensionData { executor_name: String, } let mut ext = MyExtensionData { executor_name: "foo".to_string(), }; let mut cx = ContextBuilder::from_waker(&waker).ext(&mut ext).build(); if let Some(ext) = cx.ext().downcast_mut::<MyExtensionData>() { println!("{}", ext.executor_name); } ``` Currently, `Context` only carries a `Waker`, but there is interest in having it carry other kinds of data. Examples include [LocalWaker](https://github.com/rust-lang/rust/issues/118959), [a reactor interface](https://github.com/rust-lang/libs-team/issues/347), and [multiple arbitrary values by type](https://docs.rs/context-rs/latest/context_rs/). There is also a general practice in the ecosystem of sharing data between executors and futures via thread-locals or globals that would arguably be better shared via `Context`, if it were possible. The `ext` field would provide a low friction (to stabilization) solution to enable experimentation. It would enable experimenting with what kinds of data we want to carry as well as with what data structures we may want to use to carry such data. Dedicated fields for specific kinds of data could still be added directly on `Context` when we have sufficient experience or understanding about the problem they are solving, such as with `LocalWaker`. The `ext` field would be for data for which we don't have such experience or understanding, and that could be graduated to dedicated fields once proven. Both the provider and consumer of the extension data must be aware of the concrete type behind the `Any`. This means it is not possible for the field to carry an abstract interface. However, the field can carry a concrete type which in turn carries an interface. There are different ways one can imagine an interface-carrying concrete type to work, hence the benefit of being able to experiment with such data structures. ## Passing interfaces Interfaces can be placed in a concrete type, such as a struct, and then that type can be casted to `Any`. However, one gotcha is `Any` cannot contain non-static references. This means one cannot simply do: ```rust struct Extensions<'a> { interface1: &'a mut dyn Trait1, interface2: &'a mut dyn Trait2, } let mut ext = Extensions { interface1: &mut impl1, interface2: &mut impl2, }; let ext: &mut dyn Any = &mut ext; ``` To work around this without boxing, unsafe code can be used to create a safe projection using accessors. For example: ```rust pub struct Extensions { interface1: *mut dyn Trait1, interface2: *mut dyn Trait2, } impl Extensions { pub fn new<'a>( interface1: &'a mut (dyn Trait1 + 'static), interface2: &'a mut (dyn Trait2 + 'static), scratch: &'a mut MaybeUninit<Self>, ) -> &'a mut Self { scratch.write(Self { interface1, interface2, }) } pub fn interface1(&mut self) -> &mut dyn Trait1 { unsafe { self.interface1.as_mut().unwrap() } } pub fn interface2(&mut self) -> &mut dyn Trait2 { unsafe { self.interface2.as_mut().unwrap() } } } let mut scratch = MaybeUninit::uninit(); let ext: &mut Extensions = Extensions::new(&mut impl1, &mut impl2, &mut scratch); // ext can now be casted to `&mut dyn Any` and back, and used safely let ext: &mut dyn Any = ext; ``` ## Context inheritance Sometimes when futures poll other futures they want to provide their own `Waker` which requires creating their own `Context`. Unfortunately, polling sub-futures with a fresh `Context` means any properties on the original `Context` won't get propagated along to the sub-futures. To help with this, some additional methods are added to `ContextBuilder`. Here's how to derive a new `Context` from another, overriding only the `Waker`: ```rust let mut cx = ContextBuilder::from(parent_cx).waker(&new_waker).build(); ```
2024-04-02Rollup merge of #123182 - jhpratt:fix-decodable-derive, r=davidtwcoJacob Pratt-0/+37
Avoid expanding to unstable internal method Fixes #123156 Rather than expanding to `std::rt::begin_panic`, the expansion is now to `unreachable!()`. The resulting behavior is identical. A test that previously triggered the same error as #123156 has been added to ensure it does not regress. r? compiler
2024-04-02Rollup merge of #122935 - RalfJung:with-exposed-provenance, r=AmanieuJacob Pratt-7/+7
rename ptr::from_exposed_addr -> ptr::with_exposed_provenance As discussed on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/To.20expose.20or.20not.20to.20expose/near/427757066). The old name, `from_exposed_addr`, makes little sense as it's not the address that is exposed, it's the provenance. (`ptr.expose_addr()` stays unchanged as we haven't found a better option yet. The intended interpretation is "expose the provenance and return the address".) The new name nicely matches `ptr::without_provenance`.
2024-04-02Rollup merge of #122865 - surechen:refactor_astconv_error_report_20240321, ↵Jacob Pratt-3/+3
r=lcnr Split hir ty lowerer's error reporting code in check functions to mod errors. Move some error report codes to mod `astconv/errors.rs` r? `@lcnr`
2024-04-03Auto merge of #122791 - compiler-errors:make-coinductive-always, r=lcnrbors-27/+95
Make inductive cycles always ambiguous This makes inductive cycles always result in ambiguity rather than be treated like a stack-dependent error. This has some interactions with specialization, and so breaks a few UI tests that I don't agree should've ever worked in the first place, and also breaks a handful of crates in a way that I don't believe is a problem. On the bright side, it puts us in a better spot when it comes to eventually enabling coinduction everywhere. ## Results This was cratered in https://github.com/rust-lang/rust/pull/116494#issuecomment-2008657494, which boils down to two regressions: * `lu_packets` - This code should have never compiled in the first place. More below. * **ALL** other regressions are due to `commit_verify@0.11.0-beta.1` (edit: and `commit_verify@0.10.x`) - This actually seems to be fixed in version `0.11.0-beta.5`, which is the *most* up to date version, but it's still prerelease on crates.io so I don't think cargo ends up picking `beta.5` when building dependent crates. ### `lu_packets` Firstly, this crate uses specialization, so I think it's automatically worth breaking. However, I've minimized [the regression](https://crater-reports.s3.amazonaws.com/pr-116494-3/try%23d614ed876e31a5f3ad1d0fbf848fcdab3a29d1d8/gh/lcdr.lu_packets/log.txt) to: ```rust // Upstream crate pub trait Serialize {} impl Serialize for &() {} impl<S> Serialize for &[S] where for<'a> &'a S: Serialize {} // ----------------------------------------------------------------------- // // Downstream crate #![feature(specialization)] #![allow(incomplete_features, unused)] use upstream::Serialize; trait Replica { fn serialize(); } impl<T> Replica for T { default fn serialize() {} } impl<T> Replica for Option<T> where for<'a> &'a T: Serialize, { fn serialize() {} } ``` Specifically this fails when computing the specialization graph for the `downstream` crate. The code ends up cycling on `&[?0]: Serialize` when we equate `&?0 = &[?1]` during impl matching, which ends up needing to prove `&[?1]: Serialize`, which since cycles are treated like ambiguity, ends up in a **fatal overflow**. For some reason this requires two crates, squashing them into one crate doesn't work. Side-note: This code is subtly order dependent. When minimizing, I ended up having the code start failing on `nightly` very easily after removing and reordering impls. This seems to me all the more reason to remove this behavior altogether. ## Side-note: Item Bounds (edit: this was fixed independently in #121123) Due to the changes in #120584 where we now consider an alias's item bounds *and* all the item bounds of the alias's nested self type aliases, I've had to add e6b64c61941120f734657106ae2479d05b463197 which is a hack to make sure we're not eagerly normalizing bounds that have nothing to do with the predicate we're trying to solve, and which result in. This is fixed in a more principled way in #121123. --- r? lcnr for an initial review
2024-04-02Comments, comments, commentsMichael Goulet-0/+2