### Changes
This commit implements unwind ABI's, specified in RFC 2945.
We adjust the `rustc_middle::ty::layout::fn_can_unwind` function,
used to compute whether or not a `FnAbi` object represents a
function that should be able to unwind when `panic=unwind` is in
use.
Changes are also made to
`rustc_mir_build::build::should_abort_on_panic` so that the
function ABI is used to determind whether it should abort, assuming
that the `panic=unwind` strategy is being used, and no explicit
unwind attribute was provided.
### Tests
Unit tests, checking that the behavior is correct for `C-unwind`,
`stdcall-unwind`, `system-unwind`, and `thiscall-unwind`, are
included. These alternative `unwind` ABI strings are specified in
RFC 2945, in the "_Other `unwind` ABI strings_" section.
Additionally, a test case is included to assert that the LLVM IR
generated for an external function defined with the `C-unwind` ABI
will be appropriately labeled with the `nounwind` LLVM attribute
when the `panic=abort` compilation flag is used.
### Ignore Directives
This commit uses `ignore-*` directives in two of our `*-unwind` ABI
test cases.
Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases
ignore architectures that do not support `stdcall` and `thiscall`,
respectively.
These directives are cribbed from
`src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and
`src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
Implement NOOP_METHOD_CALL lint
Implements the beginnings of https://github.com/rust-lang/lang-team/issues/67 - a lint for detecting noop method calls (e.g, calling `<&T as Clone>::clone()` when `T: !Clone`).
This PR does not fully realize the vision and has a few limitations that need to be addressed either before merging or in subsequent PRs:
* [ ] No UFCS support
* [ ] The warning message is pretty plain
* [ ] Doesn't work for `ToOwned`
The implementation uses [`Instance::resolve`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/instance/struct.Instance.html#method.resolve) which is normally later in the compiler. It seems that there are some invariants that this function relies on that we try our best to respect. For instance, it expects substitutions to have happened, which haven't yet performed, but we check first for `needs_subst` to ensure we're dealing with a monomorphic type.
Thank you to ```@davidtwco,``` ```@Aaron1011,``` and ```@wesleywiser``` for helping me at various points through out this PR ❤️.
2229: Fix issues with move closures and mutability
This PR fixes two issues when feature `capture_disjoint_fields` is used.
1. Can't mutate using a mutable reference
2. Move closures try to move value out through a reference.
To do so, we
1. Compute the mutability of the capture and store it as part of the `CapturedPlace` that is written in TypeckResults
2. Restrict capture precision. Note this is temporary for now, to allow the feature to be used with move closures and ByValue captures and might change depending on discussions with the lang team.
- No Derefs are captured for ByValue captures, since that will result in value behind a reference getting moved.
- No projections are applied to raw pointers since these require unsafe blocks. We capture
them completely.
r? `````@nikomatsakis`````
Support FRU pattern with `[feature(capture_disjoint_fields)]`
In case of a functional record update syntax for creating a structure, `ExprUseVisitor` to only detect the precise use of some of the field in the `..x` part of the syntax. However, when we start building MIR, we
1. First, build the place for `x`
2. and then, add precise field projections so that only some parts of `x` end up getting read.
When `capture_disjoint_fields` is enabled, and FRU is used within a closure `x` won't be completely captured, and therefore the first step will fail. This PR updates `mir_build` to create a place builder in the first step and then create place from the builder only after applying the field projection.
Closes https://github.com/rust-lang/project-rfc-2229/issues/32
r? ``````@nikomatsakis``````
When `capture_disjoint_fields` is not enabled, checking if the root variable
binding is mutable would suffice.
However with the feature enabled, the captured place might be mutable
because it dereferences a mutable reference.
This PR computes the mutability of each capture after capture analysis
in rustc_typeck. We store this in `ty::CapturedPlace` and then use
`ty::CapturedPlace::mutability` in mir_build and borrow_check.
Refractor a few more types to `rustc_type_ir`
In the continuation of #79169, ~~blocked on that PR~~.
This PR:
- moves `IntVarValue`, `FloatVarValue`, `InferTy` (and friends) and `Variance`
- creates the `IntTy`, `UintTy` and `FloatTy` enums in `rustc_type_ir`, based on their `ast` and `chalk_ir` equilavents, and uses them for types in the rest of the compiler.
~~I will split up that commit to make this easier to review and to have a better commit history.~~
EDIT: done, I split the PR in commits of 200-ish lines each
r? `````@nikomatsakis````` cc `````@jackh726`````
implement ptr::write without dedicated intrinsic
This makes `ptr::write` more consistent with `ptr::write_unaligned`, `ptr::read`, `ptr::read_unaligned`, all of which are implemented in terms of `copy_nonoverlapping`.
This means we can also remove `move_val_init` implementations in codegen and Miri, and its special handling in the borrow checker.
Also see [this Zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/ptr.3A.3Aread.20vs.20ptr.3A.3Awrite).
Implement if-let match guards
Implements rust-lang/rfcs#2294 (tracking issue: #51114).
I probably should do a few more things before this can be merged:
- [x] Add tests (added basic tests, more advanced tests could be done in the future?)
- [x] Add lint for exhaustive if-let guard (comparable to normal if-let statements)
- [x] Fix clippy
However since this is a nightly feature maybe it's fine to land this and do those steps in follow-up PRs.
Thanks a lot `@matthewjasper` ❤️ for helping me with lowering to MIR! Would you be interested in reviewing this?
r? `@ghost` for now
[mir-opt] Allow debuginfo to be generated for a constant or a Place
Prior to this commit, debuginfo was always generated by mapping a name
to a Place. This has the side-effect that `SimplifyLocals` cannot remove
locals that are only used for debuginfo because their other uses have
been const-propagated.
To allow these locals to be removed, we now allow debuginfo to point to
a constant value. The `ConstProp` pass detects when debuginfo points to
a local with a known constant value and replaces it with the value. This
allows the later `SimplifyLocals` pass to remove the local.
fix more clippy::complexity findings
fix clippy::unnecessary_filter_map
use if let Some(x) = .. instead of ...map(|x|) to conditionally run fns that return () (clippy::option_map_unit_fn)
fix clippy::{needless_bool, manual_unwrap_or}
don't clone types that are copy (clippy::clone_on_copy)
don't convert types into identical types with .into() (clippy::useless_conversion)
use strip_prefix over slicing (clippy::manual_strip)
r? ``@Dylan-DPC``
Capture precise paths in THIR and MIR
This PR allows THIR and MIR to use the result of the new capture analysis to actually capture precise paths
To achieve we:
- Writeback min capture results to TypeckResults
- Move handling upvars to PlaceBuilder in mir_build
- Lower precise paths in THIR build by reading min_captures
- Search for ancestors in min_capture when trying to build a MIR place which starts off of an upvar
Closes: https://github.com/rust-lang/project-rfc-2229/issues/10
Partly implements: rust-lang/project-rfc-2229#18
Work that remains (not in this PR):
- [ ] [Known bugs when feature gate is enabled](https://github.com/rust-lang/project-rfc-2229/projects/1?card_filter_query=label%3Abug)
- [ ] Use min_capure_map for
- [ ] Liveness analysis
- [ ] rustc_mir/interpret/validity.rs
- [ ] regionck
- [ ] rust-lang/project-rfc-2229#8
- [ ] remove closure_captures and upvar_capture_map
r? `@ghost`
- Closures now use closure_min_captures to figure out captured paths
- Build upvar_mutbls using closure_min_captures
- Change logic in limit_capture_mutability to differentiate b/w
capturing parent's local variable or capturing a variable that is
captured by the parent (in case of nested closure) using PlaceBase.
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
- Use closure_min_capture maps to capture precise paths
- PlaceBuilder now searches for ancestors in min_capture list
- Add API to `Ty` to allow access to the n-th element in a
tuple in O(1) time.
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
Prior to this commit, debuginfo was always generated by mapping a name
to a Place. This has the side-effect that `SimplifyLocals` cannot remove
locals that are only used for debuginfo because their other uses have
been const-propagated.
To allow these locals to be removed, we now allow debuginfo to point to
a constant value. The `ConstProp` pass detects when debuginfo points to
a local with a known constant value and replaces it with the value. This
allows the later `SimplifyLocals` pass to remove the local.
- This allows us to delay figuring out the index of a capture
in the closure structure when all projections to atleast form
a capture have been applied to the builder
Co-authored-by: Roxane Fruytier <roxane.fruytier@hotmail.com>
ExprKind::SelfRef was used to express accessing `self` in
the desugared Closure/Generator struct when lowering captures in THIR.
Since we handle captures in MIR now, we don't need `ExprKind::Self`.