Add match arm scopes and other scope fixes
* Add drop and lint scopes for match arms.
* Lint attributes are now respected on match arms.
* Make sure we emit a StorageDead if we diverge when initializing a temporary.
* Adjust MIR pretty printing of scopes for locals.
* Don't generate duplicate lint scopes for `let statements`.
* Add some previously missing fake borrows for matches.
closes#46525
cc @rust-lang/compiler
Simplify use of keyword symbols
They mirror non-keyword symbols now (see https://github.com/rust-lang/rust/pull/60630).
`keywords::MyKeyword.name()` -> `kw::MyKeyword`
`keywords::MyKeyword.ident()` -> `Ident::with_empty_ctxt(kw::MyKeyword)` (not common)
`keywords::Invalid.ident()` -> `Ident::invalid()` (more common)
Keywords are simply `Symbol` constants now, the `Keyword` struct is eliminated.
This means `kw::MyKeyword` can now be used in `match` in particular.
Update clippy submodule
r? @Manishearth
If anyone is wondering where the odd old commits are coming from, we merged all beta backport commits and so into master in order to make sure we don't need to keep those branches around.
rustc_metadata: parametrize schema::CrateRoot by 'tcx and rip out old unused incremental infra.
These are the first two commits of #59953, already reviewed and approved by @michaelwoerister.
r? @michaelwoerister
Simplify RefCell minimum_spanning_tree example
This simplifies the implementation of the `minimum_spanning_tree` example of `RefCell` in the `cell` module-level docs, avoiding an unnecessary recursive call. This also eliminates the need for a block to contain the scope of the borrow in this example. But since that use of a block served an important didactic purpose, we make up for this by instead introducing a block in the initial, simpler example of `RefCell`, where the point will hopefully be conveyed to the reader more easily.
Always try to project predicates when finding auto traits in rustdoc
Fixes#60726
Previous, AutoTraitFinder would only try to project predicates when the
predicate type contained an inference variable. When finding auto
traits, we only project to try to unify inference variables - we don't
otherwise learn any new information about the required bounds.
However, this lead to failing to properly generate a negative auto trait
impl (indicating that a type never implements a certain auto trait) in
the following unusual scenario:
In almost all cases, a type has an (implicit) negative impl of an auto
trait due some other type having an explicit *negative* impl of that
auto trait. For example:
struct MyType<T> {
field: *const T
}
has an implicit 'impl<T> !Send for MyType<T>', due to the explicit
negative impl (in libcore) 'impl<T: ?Sized> !Send for *const T'.
However, as exposed by the 'abi_stable' crate, this isn't always the
case. This minimzed example shows how a type can never implement
'Send', due to a projection error:
```
pub struct True;
pub struct False;
pub trait MyTrait {
type Project;
}
pub struct MyStruct<T> {
field: T
}
impl MyTrait for u8 {
type Project = False;
}
unsafe impl<T> Send for MyStruct<T>
where T: MyTrait<Project=True> {}
pub struct Wrapper {
inner: MyStruct<u8>
}
```
In this example, `<u8 as MyTrait>::Project == True'
must hold for 'MyStruct<u8>: Send' to hold.
However, '<u8 as MyTrait>::Project == False' holds instead
To properly account for this unusual case, we need to call
'poly_project_and_unify' on *all* predicates, not just those with
inference variables. This ensures that we catch the projection error
that occurs above, and don't incorrectly determine that 'Wrapper: Send'
holds.
Allow null-pointer-optimized enums in FFI if their underlying representation is FFI safe
I'm not sure if this requires an RFC. I attempted to start [a discussion on internals.rust-lang.org](https://internals.rust-lang.org/t/options-ffi-safety-and-guarantees-for-abi-compatibility-with-nonnull-optimizations/9784) and when no one really objected I figured I'd go ahead and try implementing this.
This allows types like `Option<NonZeroU8>` to be used in FFI without triggering the `improper_ctypes` lint. This works by changing the `is_repr_nullable_ptr` function to consider an enum `E` to be FFI-safe if:
- `E` has no explicit `#[repr(...)]`.
- It only has two variants.
- One of those variants is empty (meaning it has no fields).
- The other variant has only one field.
- That field is one of the following:
- `&T`
- `&mut T`
- `extern "C" fn`
- `core::num::NonZero*`
- `core::ptr::NonNull<T>`
- `#[repr(transparent)] struct` wrapper around one of the types in this list.
- The size of `E` and its field are both known and are both the same size (implying `E` is participating in the nonnull optimization).
This logic seems consistent with [the Rust nomicon](https://doc.rust-lang.org/nomicon/repr-rust.html).
This allows types like Option<NonZeroU8> to be used in FFI without triggering the improper_ctypes lint. This works by changing the is_repr_nullable_ptr function to consider an enum E to be FFI-safe if:
- E has no explicit #[repr(...)].
- It only has two variants.
- One of those variants is empty (meaning it has no fields).
- The other variant has only one field.
- That field is one of the following:
- &T
- &mut T
- extern "C" fn
- core::num::NonZero*
- core::ptr::NonNull<T>
- #[repr(transparent)] struct wrapper around one of the types in this list.
- The size of E and its field are both known and are both the same size (implying E is participating in the nonnull optimization).
Ban multi-trait objects via trait aliases
Obviously, multi-trait objects are not normally supported, so they should not be supported via trait aliases.
This has been factored out from the previous PR https://github.com/rust-lang/rust/pull/55994 (see point 1).
r? @Centril
CC @nikomatsakis
------------------
### RELNOTES:
We now allow `dyn Send + fmt::Debug` with equivalent semantics to `dyn fmt::Debug + Send`.
That is, the order of the mentioned traits does not matter wrt. principal/not-principal traits.
This is a small change that might deserve a mention in the blog post because it is a language change but most likely not.
See ce2ee305f9/src/test/ui/traits/wf-trait-object-reverse-order.rs.
// @Centril
Preserve local scopes in generator MIR
Part of #52924, depended upon by the generator layout optimization #60187.
This PR adds `StorageDead` statements in more places in generators, so we can see when non-`Drop` locals have gone out of scope and recover their storage.
The reason this is only done for generators is compiler performance. See https://github.com/rust-lang/rust/pull/60187#issuecomment-485637811 for what happens when we do this for all functions.
For `Drop` locals, we modify the `MaybeStorageLive` analysis to use `drop` to indicate that storage is no longer live for the local. Once `drop` returns or unwinds to our function, we implicitly assume that the local is `StorageDead`.
Instead of using `drop`, it is possible to emit more `StorageDead` statements in the MIR for `Drop` locals so we can handle all locals the same. I am fine with doing it that way, but this was the simplest approach for my purposes. It is also likely to be more performant.
r? @Zoxc (feel free to reassign)
cc @cramertj @eddyb @RalfJung @rust-lang/wg-async-await
Rollup of 10 pull requests
Successful merges:
- #59742 (Move `edition` outside the hygiene lock and avoid accessing it)
- #60581 (convert custom try macro to `?`)
- #60963 (Update boxed::Box docs on memory layout)
- #60973 (Avoid symbol interning in `file_metadata`.)
- #60982 (Do not fail on child without DefId)
- #60991 (LocalDecl push returns Local len)
- #60995 (Add stream_to_parser_with_base_dir)
- #60998 (static_assert: make use of anonymous constants)
- #61003 (Remove impls for `InternedString`/string equality.)
- #61006 (adjust deprecation date of mem::uninitialized)
Failed merges:
r? @ghost
Remove impls for `InternedString`/string equality.
`Symbol` received the same treatment in #60630.
Also, we can derive `PartialEq` for `InternedString`.
r? @petrochenkov
Add stream_to_parser_with_base_dir
This PR adds `stream_to_parser_with_base_dir`, which creates a parser from a token stream and a base directory.
Context: I would like to parse `cfg_if!` macro and get a list of modules defined inside it from rustfmt so that rustfmt can format those modules (cc https://github.com/rust-lang/rustfmt/issues/3253). To do so, I need to create a parser from `TokenStream` and set the directory of `Parser` to the same directory as the parent directory of a file which contains `cfg_if!` invocation. AFAIK there is no way to achieve this, and hence this PR.
Alternatively, I could change the visibility of `Parser.directory` from `crate` to `pub` so that the value can be modified after initializing a parser. I don't have a preference over either approach (or others, as long as it works).
Avoid symbol interning in `file_metadata`.
This commit changes `created_files` so it uses strings directly as keys,
rather than symbols derived from the strings. This avoids the cost of
having to do the hash table lookups to produce the symbols from the
strings.
The commit also uses `entry` to avoid doing a repeated hash table lookup
(`get` + `insert`).
Note that PR #60467 improved this code somewhat; this is a further
improvement.
r? @davidtwco
Update boxed::Box docs on memory layout
The existing docs for the `Box` type state that "the way `Box` allocates and releases memory is unspecified", and that therefore the only valid pointer to pass to `Box::from_raw` is one obtained from `Box::into_raw`. This is inconsistent with the module-level docs which specify,
> It is valid to convert both ways between a Box and a raw pointer allocated with the Global allocator, given that the Layout used with the allocator is correct for the type. More precisely, a value: *mut T that has been allocated with the Global allocator with Layout::for_value(&*value) may be converted into a box using Box::<T>::from_raw(value). Conversely, the memory backing a value: *mut T obtained from Box::<T>::into_raw may be deallocated using the Global allocator with Layout::for_value(&*value).
This pull request updates the docs for `Box` to make them consistent with the module-level docs and adds some examples of how to use the global allocator in conjunction with `Box::from_raw` and `Box::into_raw`.
debuginfo: Revert to old/more verbose behavior for -Cdebuginfo=1
https://github.com/rust-lang/rust/commit/cff075009 made LLVM emit less debuginfo when compiling with "line-tables-only". The change was essentially correct but the reduced amount of debuginfo broke
a number of tools.
This commit reverts the change so we get back the old behavior, until we figure out how to do this properly and give external tools to adapt to the new format.
See https://github.com/rust-lang/rust/issues/60020 for more info.
r? @cuviper
cc @jrmuizel & @froydnj
I was incorrectly under the impression that this would only lead to
duplicates. See `mir-opt/match-arm-scope.rs` (upcomming commit) for a
case where we didn't emit a fake borrow of `items.1`.