Automated conversion using the untry tool [1] and the following command:
```
$ find -name '*.rs' -type f | xargs untry
```
at the root of the Rust repo.
[1]: https://github.com/japaric/untry
Move analysis for MIR borrowck
This PR adds code for doing MIR-based gathering of the moves in a `fn` and the dataflow to determine where uninitialized locations flow to, analogous to how the same thing is done in `borrowck`.
It also adds a couple attributes to print out graphviz visualizations of the analyzed MIR that includes the dataflow analysis results.
cc @nikomatsakis
emit (via debug!) scary message from `fn borrowck_mir` until basic
prototype is in place.
Gather children of move paths and set their kill bits in
dataflow. (Each node has a link to the child that is first among its
siblings.)
Hooked in libgraphviz based rendering, including of borrowck dataflow
state.
doing this well required some refactoring of the code, so I cleaned it
up more generally (adding comments to explain what its trying to do
and how it is doing it).
Update: this newer version addresses most review comments (at least
the ones that were largely mechanical changes), but I left the more
interesting revisions to separate followup commits (in this same PR).
Implement RFC 1210: impl specialization
This PR implements [impl specialization](https://github.com/rust-lang/rfcs/pull/1210),
carefully following the proposal laid out in the RFC.
The implementation covers the bulk of the RFC. The remaining gaps I know of are:
- no checking for lifetime-dependent specialization (a soundness hole);
- no `default impl` yet;
- no support for `default` with associated consts;
I plan to cover these gaps in follow-up PRs, as per @nikomatsakis's preference.
The basic strategy is to build up a *specialization graph* during
coherence checking. Insertion into the graph locates the right place
to put an impl in the specialization hierarchy; if there is no right
place (due to partial overlap but no containment), you get an overlap
error. Specialization is consulted when selecting an impl (of course),
and the graph is consulted when propagating defaults down the
specialization hierarchy.
You might expect that the specialization graph would be used during
selection -- i.e., when actually performing specialization. This is
not done for two reasons:
- It's merely an optimization: given a set of candidates that apply,
we can determine the most specialized one by comparing them directly
for specialization, rather than consulting the graph. Given that we
also cache the results of selection, the benefit of this
optimization is questionable.
- To build the specialization graph in the first place, we need to use
selection (because we need to determine whether one impl specializes
another). Dealing with this reentrancy would require some additional
mode switch for selection. Given that there seems to be no strong
reason to use the graph anyway, we stick with a simpler approach in
selection, and use the graph only for propagating default
implementations.
Trait impl selection can succeed even when multiple impls can apply,
as long as they are part of the same specialization family. In that
case, it returns a *single* impl on success -- this is the most
specialized impl *known* to apply. However, if there are any inference
variables in play, the returned impl may not be the actual impl we
will use at trans time. Thus, we take special care to avoid projecting
associated types unless either (1) the associated type does not use
`default` and thus cannot be overridden or (2) all input types are
known concretely.
r? @nikomatsakis
Add Pass manager for MIR
A new PR, since rebasing the original one (https://github.com/rust-lang/rust/pull/31448) properly was a pain. Since then there has been several changes most notable of which:
1. Removed the pretty-printing with `#[rustc_mir(graphviz/pretty)]`, mostly because we now have `--unpretty=mir`, IMHO that’s the direction we should expand this functionality into;
2. Reverted the infercx change done for typeck, because typeck can make an infercx for itself by being a `MirMapPass`
r? @nikomatsakis
Distinguish fn item types to allow reification from nothing to fn pointers.
The first commit is a rebase of #26284, except for files that have moved since.
This is a [breaking-change], due to:
* each FFI function has a distinct type, like all other functions currently do
* all generic parameters on functions are recorded in their item types, e.g.:
`size_of::<u8>` & `size_of::<i8>`'s types differ despite their identical signature.
* function items are zero-sized, which will stop transmutes from working on them
The first two cases are handled in most cases with the new coerce-unify logic,
which will combine incompatible function item types into function pointers,
at the outer-most level of if-else chains, match arms and array literals.
The last case is specially handled during type-checking such that transmutes
from a function item type to a pointer or integer type will continue to work for
another release cycle, but are being linted against. To get rid of warnings and
ensure your code will continue to compile, cast to a pointer before transmuting.
Fix incorrect trait privacy error
This PR fixes#21670 by using the crate metadata instead of `ExternalExports` to determine if an external item is public.
r? @nikomatsakis
There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
Show `cfg` as possible argument to `--print` and make it so that `--print cfg` also outputs the `target_feature`s.
Should I also extend `src/test/run-make/print-cfg/Makefile` to check that `target_feature`s are actually printed?
Gated cfg attributes are not available on the stable and beta release
channels, therefore they should not be presented to users of those
channels in order to avoid confusion.
The configuration returned by `config::build_configuration` needs to
be modified with `target_features::add_configuration` in order to also
contain the target features. This is already done for the
configuration used when compiling and when creating the documentation,
but was missing in the `cfg` printing code.
This commit adds support for *truly* unstable options in the compiler, as well
as adding warnings for the start of the deprecation path of
unstable-but-not-really options. Specifically, the following behavior is now in
place for handling unstable options:
* As before, an unconditional error is emitted if an unstable option is passed
and the `-Z unstable-options` flag is not present. Note that passing another
`-Z` flag does not require passing `-Z unstable-options` as well.
* New flags added to the compiler will be in the `Unstable` category as opposed
to the `UnstableButNotReally` category which means they will unconditionally
emit an error when used on stable.
* All current flags are in a category where they will emit warnings when used
that the option will soon be a hard error.
Also as before, it is intended that `-Z` is akin to `#![feature]` in a crate
where it is required to unlock unstable functionality. A nightly compiler which
is used without any `-Z` flags should only be exercising stable behavior.
r? @brson
cc @alexcrichton
I still need to add error code explanation test with this, but I can't figure out a way to generate the `.md` files in order to test example source codes.
Will fix#27328.