os-rust/compiler
bors ec2b311914 Auto merge of #116733 - compiler-errors:alias-liveness-but-this-time-sound, r=aliemjay
Consider alias bounds when computing liveness in NLL (but this time sound hopefully)

This is a revival of #116040, except removing the changes to opaque lifetime captures check to make sure that we're not triggering any unsoundness due to the lack of general existential regions and the currently-existing `ReErased` hack we use instead.

r? `@aliemjay` -- I appreciate you pointing out the unsoundenss in the previous iteration of this PR, and I'd like to hear that you're happy with this iteration of this PR before this goes back into FCP :>

Fixes #116794 as well

---

(mostly copied from #116040 and reworked slightly)

# Background

Right now, liveness analysis in NLL is a bit simplistic. It simply walks through all of the regions of a type and marks them as being live at points. This is problematic in the case of aliases, since it requires that we mark **all** of the regions in their args[^1] as live, leading to bugs like #42940.

In reality, we may be able to deduce that fewer regions are allowed to be present in the projected type (or "hidden type" for opaques) via item bounds or where clauses, and therefore ideally, we should be able to soundly require fewer regions to be live in the alias.

For example:
```rust
trait Captures<'a> {}
impl<T> Captures<'_> for T {}

fn capture<'o>(_: &'o mut ()) -> impl Sized + Captures<'o> + 'static {}

fn test_two_mut(mut x: ()) {
    let _f1 = capture(&mut x);
    let _f2 = capture(&mut x);
    //~^ ERROR cannot borrow `x` as mutable more than once at a time
}
```

In the example above, we should be able to deduce from the `'static` bound on `capture`'s opaque that even though `'o` is a captured region, it *can never* show up in the opaque's hidden type, and can soundly be ignored for liveness purposes.

# The Fix

We apply a simple version of RFC 1214's `OutlivesProjectionEnv` and `OutlivesProjectionTraitDef` rules to NLL's `make_all_regions_live` computation.

Specifically, when we encounter an alias type, we:
1. Look for a unique outlives bound in the param-env or item bounds for that alias. If there is more than one unique region, bail, unless any of the outlives bound's regions is `'static`, and in that case, prefer `'static`. If we find such a unique region, we can mark that outlives region as live and skip walking through the args of the opaque.
2. Otherwise, walk through the alias's args recursively, as we do today.

## Limitation: Multiple choices

This approach has some limitations. Firstly, since liveness doesn't use the same type-test logic as outlives bounds do, we can't really try several options when we're faced with a choice.

If we encounter two unique outlives regions in the param-env or bounds, we simply fall back to walking the opaque via its args. I expect this to be mostly mitigated by the special treatment of `'static`, and can be fixed in a forwards-compatible by a more sophisticated analysis in the future.

## Limitation: Opaque hidden types

Secondly, we do not employ any of these rules when considering whether the regions captured by a hidden type are valid. That causes this code (cc #42940) to fail:

```rust
trait Captures<'a> {}
impl<T> Captures<'_> for T {}

fn a() -> impl Sized + 'static {
    b(&vec![])
}

fn b<'o>(_: &'o Vec<i32>) -> impl Sized + Captures<'o> + 'static {}
```

We need to have existential regions to avoid [unsoundness](https://github.com/rust-lang/rust/pull/116040#issuecomment-1751628189) when an opaque captures a region which is not represented in its own substs but which outlives a region that does.

## Read more

Context: https://github.com/rust-lang/rust/pull/115822#issuecomment-1731153952 (for the liveness case)
More context: https://github.com/rust-lang/rust/issues/42940#issuecomment-455198309 (for the opaque capture case, which this does not fix)

[^1]: except for bivariant region args in opaques, which will become less relevant when we move onto edition 2024 capture semantics for opaques.
2023-10-29 18:42:02 +00:00
..
rustc Split out the stable part of smir into its own crate to prevent accidental usage of forever unstable things 2023-09-25 14:38:27 +00:00
rustc_abi fix failure to detect a too-big-type after adding padding 2023-10-27 18:07:53 +02:00
rustc_arena Stabilize [const_]pointer_byte_offsets 2023-10-25 22:35:12 +00:00
rustc_ast Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_ast_lowering Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_ast_passes Feature gate gen blocks, even in 2024 edition 2023-10-27 13:05:48 +00:00
rustc_ast_pretty Add gen blocks to ast and do some broken ast lowering 2023-10-27 13:05:48 +00:00
rustc_attr Parse rustc version at compile time 2023-10-26 18:55:05 -07:00
rustc_baked_icu_data docs: add Rust logo to more compiler crates 2023-10-16 15:38:08 -07:00
rustc_borrowck Auto merge of #116733 - compiler-errors:alias-liveness-but-this-time-sound, r=aliemjay 2023-10-29 18:42:02 +00:00
rustc_builtin_macros Add gen blocks to ast and do some broken ast lowering 2023-10-27 13:05:48 +00:00
rustc_codegen_cranelift Auto merge of #81746 - bjorn3:cg_clif_rustup_component, r=Mark-Simulacrum 2023-10-28 15:16:27 +00:00
rustc_codegen_gcc Merge commit '09ce29d0591a21e1abae22eac4d41ffd32993af8' into subtree-update_cg_gcc_2023-10-25 2023-10-27 16:07:01 -04:00
rustc_codegen_llvm Auto merge of #117123 - Zalathar:bad-counter-ids, r=petrochenkov 2023-10-28 17:43:07 +00:00
rustc_codegen_ssa Auto merge of #117335 - workingjubilee:rollup-jsomm41, r=workingjubilee 2023-10-29 01:58:46 +00:00
rustc_const_eval Auto merge of #116270 - cjgillot:gvn-aggregate, r=oli-obk,RalfJung 2023-10-29 14:50:53 +00:00
rustc_data_structures Auto merge of #116849 - oli-obk:error_shenanigans, r=cjgillot 2023-10-23 09:59:40 +00:00
rustc_driver docs: add Rust logo to more compiler crates 2023-10-16 15:38:08 -07:00
rustc_driver_impl Rollup merge of #117268 - nnethercote:rustc_interface, r=oli-obk 2023-10-28 01:07:38 -07:00
rustc_error_codes Replace all uses of generator in markdown documentation with coroutine 2023-10-20 21:14:02 +00:00
rustc_error_messages docs: add Rust logo to more compiler crates 2023-10-16 15:38:08 -07:00
rustc_errors Stash and cancel cycle errors for auto trait leakage in opaques 2023-10-26 17:58:02 +00:00
rustc_expand Auto merge of #116818 - Nilstrieb:stop-submitting-bug-reports, r=wesleywiser 2023-10-26 02:08:07 +00:00
rustc_feature Feature gate gen blocks, even in 2024 edition 2023-10-27 13:05:48 +00:00
rustc_fluent_macro Use v0.0.0 in compiler crates 2023-10-18 21:55:15 +00:00
rustc_fs_util Add try_canonicalize to rustc_fs_util and use it over fs::canonicalize 2023-03-16 21:50:23 +01:00
rustc_graphviz rustdoc: remove rust logo from non-Rust crates 2023-10-08 20:17:53 -07:00
rustc_hir Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_hir_analysis Auto merge of #117171 - fee1-dead-contrib:deny-explicit-effect-params, r=oli-obk 2023-10-26 14:50:23 +00:00
rustc_hir_pretty Fiddle with State functions. 2023-10-11 10:46:55 +11:00
rustc_hir_typeck Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_incremental Reduce some function exposure. 2023-10-26 09:04:26 +11:00
rustc_index Preserve DebugInfo in DeadStoreElimination. 2023-10-06 15:46:11 +00:00
rustc_infer Auto merge of #116733 - compiler-errors:alias-liveness-but-this-time-sound, r=aliemjay 2023-10-29 18:42:02 +00:00
rustc_interface Rollup merge of #117268 - nnethercote:rustc_interface, r=oli-obk 2023-10-28 01:07:38 -07:00
rustc_lexer Use v0.0.0 in compiler crates 2023-10-18 21:55:15 +00:00
rustc_lint Make ty::print::Printer take &mut self instead of self 2023-10-21 11:33:05 +02:00
rustc_lint_defs Auto merge of #116734 - Nadrieril:lint-per-column, r=cjgillot 2023-10-21 11:04:19 +00:00
rustc_llvm For i586/NetBSD: fix another formatting insistence. 2023-10-27 09:37:25 +00:00
rustc_log use env variable to control thread ids in rustc_log 2023-10-10 09:39:47 +08:00
rustc_macros Rollup merge of #117256 - dtolnay:currentversion, r=compiler-errors 2023-10-28 01:07:38 -07:00
rustc_metadata s/generator/coroutine/ 2023-10-20 21:14:01 +00:00
rustc_middle Auto merge of #116270 - cjgillot:gvn-aggregate, r=oli-obk,RalfJung 2023-10-29 14:50:53 +00:00
rustc_mir_build Auto merge of #103208 - cjgillot:match-fake-read, r=oli-obk,RalfJung 2023-10-27 18:51:43 +00:00
rustc_mir_dataflow Auto merge of #116300 - cjgillot:split-move, r=petrochenkov 2023-10-24 00:25:32 +00:00
rustc_mir_transform Auto merge of #116270 - cjgillot:gvn-aggregate, r=oli-obk,RalfJung 2023-10-29 14:50:53 +00:00
rustc_monomorphize coverage: Change query codegened_and_inlined_items to a plain function 2023-10-21 12:20:05 +11:00
rustc_parse Auto merge of #116889 - MU001999:master, r=petrochenkov 2023-10-29 16:46:47 +00:00
rustc_parse_format rustdoc: remove rust logo from non-Rust crates 2023-10-08 20:17:53 -07:00
rustc_passes Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_plugin_impl rustdoc: remove rust logo from non-Rust crates 2023-10-08 20:17:53 -07:00
rustc_privacy Merge associated types with the other alias types 2023-10-23 10:10:22 +00:00
rustc_query_impl Rollup merge of #116534 - cjgillot:no-dep-tasks, r=davidtwco 2023-10-28 01:07:35 -07:00
rustc_query_system Rollup merge of #116534 - cjgillot:no-dep-tasks, r=davidtwco 2023-10-28 01:07:35 -07:00
rustc_resolve Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_serialize rustdoc: remove rust logo from non-Rust crates 2023-10-08 20:17:53 -07:00
rustc_session Rollup merge of #117311 - RalfJung:unpretty-thir-help, r=petrochenkov 2023-10-28 17:08:04 -07:00
rustc_smir Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_span Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_symbol_mangling Rollup merge of #116834 - nnethercote:rustc_symbol_mangling, r=davidtwco 2023-10-27 19:46:06 +02:00
rustc_target Auto merge of #117336 - workingjubilee:rollup-6negquv, r=workingjubilee 2023-10-29 03:53:36 +00:00
rustc_trait_selection Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_traits Detect cycle errors hidden by opaques during monomorphization 2023-09-13 17:35:44 +00:00
rustc_transmute Use v0.0.0 in compiler crates 2023-10-18 21:55:15 +00:00
rustc_ty_utils Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00
rustc_type_ir Replace type flag HAS_TY_GENERATOR with HAS_TY_COROUTINE 2023-10-26 15:18:50 +02:00
stable_mir Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors 2023-10-29 00:03:52 +00:00