Expansion-driven outline module parsing
After this PR, the parser will not do any conditional compilation or loading of external module files when `mod foo;` is encountered. Instead, the parser only leaves `mod foo;` in place in the AST, with no items filled in. Expansion later kicks in and will load the actual files and do the parsing. This entails that the following is now valid:
```rust
#[cfg(FALSE)]
mod foo {
mod bar {
mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
}
}
```
Fixes https://github.com/rust-lang/rust/issues/64197.
r? @petrochenkov
Unify and improve const-prop lints
Add a single helper method for all lints emitted by const-prop, and make that lint different from the CTFE `const_err` lint. Also consistently check overflow on *arithmetic*, not on the assertion, to make behavior the same for debug and release builds.
See [this summary comment](https://github.com/rust-lang/rust/pull/69185#issuecomment-587924754) for details and the latest status.
In terms of lint formatting, I went for what seems to be the better style: have a general message above the code, and then a specific message at the span:
```
error: this arithmetic operation will overflow
--> $DIR/const-err2.rs:21:18
|
LL | let a_i128 = -std::i128::MIN;
| ^^^^^^^^^^^^^^^ attempt to negate with overflow
```
We could also just have the specific message above and no text at the span if that is preferred.
I also converted some of the existing tests to use compiletest revisions, so that the same test can check a bunch of different compile flags.
Fixes https://github.com/rust-lang/rust/issues/69020.
Helps with https://github.com/rust-lang/rust/issues/69021: debug/release are now consistent, but the assoc-const test in that issue still fails (there is a FIXME in the PR for this). The reason seems to be that const-prop notices the assoc const in `T::N << 42` and does not even bother calling `const_prop` on that operation.
Has no effect on https://github.com/rust-lang/rust/issues/61821; the duplication there has entirely different reasons.
Address inconsistency in using "is" with "declared here"
"is" was generally used for NLL diagnostics, but not other diagnostics. Using "is" makes the diagnostics sound more natural and readable, so it seems sensible to commit to them throughout.
r? @Centril
Stabilize `#[repr(transparent)]` on `enum`s in Rust 1.42.0
# Stabilization report
The following is the stabilization report for `#![feature(transparent_enums)]`.
Tracking issue: https://github.com/rust-lang/rust/issues/60405
[Version target](https://forge.rust-lang.org/#current-release-versions): 1.42 (2020-01-30 => beta, 2020-03-12 => stable).
## User guide
A `struct` with only a single non-ZST field (let's call it `foo`) can be marked as `#[repr(transparent)]`. Such a `struct` has the same layout and ABI as `foo`. Here, we also extend this ability to `enum`s with only one variant, subject to the same restrictions as for the equivalent `struct`. That is, you can now write:
```rust
#[repr(transparent)]
enum Foo { Bar(u8) }
```
which, in terms of layout and ABI, is equivalent to:
```rust
#[repr(transparent)]
struct Foo(u8);
```
## Motivation
This is not a major feature that will unlock new and important use-cases. The utility of `repr(transparent)` `enum`s is indeed limited. However, there is still some value in it:
1. It provides conceptual simplification of the language in terms of treating univariant `enum`s and `struct`s the same, as both are product types. Indeed, languages like Haskell only have `data` as the only way to construct user-defined ADTs in the language.
2. In rare occasions, it might be that the user started out with a univariant `enum` for whatever reason (e.g. they thought they might extend it later). Now they want to make this `enum` `transparent` without breaking users by turning it into a `struct`. By lifting the restriction here, now they can.
## Technical specification
The reference specifies [`repr(transparent)` on a `struct`](https://doc.rust-lang.org/nightly/reference/type-layout.html#the-transparent-representation) as:
> ### The transparent Representation
>
> The `transparent` representation can only be used on `struct`s that have:
> - a single field with non-zero size, and
> - any number of fields with size 0 and alignment 1 (e.g. `PhantomData<T>`).
>
> Structs with this representation have the same layout and ABI as the single non-zero sized field.
>
> This is different than the `C` representation because a struct with the `C` representation will always have the ABI of a `C` `struct` while, for example, a struct with the `transparent` representation with a primitive field will have the ABI of the primitive field.
>
> Because this representation delegates type layout to another type, it cannot be used with any other representation.
Here, we amend this to include univariant `enum`s as well with the same static restrictions and the same effects on dynamic semantics.
## Tests
All the relevant tests are adjusted in the PR diff but are recounted here:
- `src/test/ui/repr/repr-transparent.rs` checks that `repr(transparent)` on an `enum` must be univariant, rather than having zero or more than one variant. Restrictions on the fields inside the only variants, like for those on `struct`s, are also checked here.
- A number of codegen tests are provided as well:
- `src/test/codegen/repr-transparent.rs` (the canonical test)
- `src/test/codegen/repr-transparent-aggregates-1.rs`
- `src/test/codegen/repr-transparent-aggregates-2.rs`
- `src/test/codegen/repr-transparent-aggregates-3.rs`
- `src/test/ui/lint/lint-ctypes-enum.rs` tests the interactions with the `improper_ctypes` lint.
## History
- 2019-04-30, RFC https://github.com/rust-lang/rfcs/pull/2645
Author: @mjbshaw
Reviewers: The Language Team
This is the RFC that proposes allowing `#[repr(transparent)]` on `enum`s and `union`.
- 2019-06-11, PR https://github.com/rust-lang/rust/pull/60463
Author: @mjbshaw
Reviewers: @varkor and @rkruppe
The PR implements the RFC aforementioned in full.
- 2019, PR https://github.com/rust-lang/rust/pull/67323
Author: @Centril
Reviewers: @davidtwco
The PR reorganizes the static checks taking advantage of the fact that `struct`s and `union`s are internally represented as ADTs with a single variant.
- This PR stabilizes `transparent_enums`.
## Related / possible future work
The remaining work here is to figure out the semantics of `#[repr(transparent)]` on `union`s and stabilize those. This work continues to be tracked in https://github.com/rust-lang/rust/issues/60405.