dead-code lint: say "constructed" for structs
Respectively.
This is a sequel to November 2017's #46103 / 1a9dc2e9. It had been
reported (more than once—at least #19140, #44083, and #44565) that the
"never used" language was confusing for enum variants that were "used"
as match patterns, so the wording was changed to say never "constructed"
specifically for enum variants. More recently, the same issue was raised
for structs (#52325). It seems consistent to say "constructed" here,
too, for the same reasons.
~~While we're here, we can also use more specific word "called" for unused
functions and methods. (We declined to do this in #46103, but the
rationale given in the commit message doesn't actually make sense.)~~
This resolves#52325.
make `everybody_loops` preserve item declarations
First half of https://github.com/rust-lang/rust/issues/52545.
`everybody_loops` is used by rustdoc to ensure we don't contain erroneous references to platform APIs if one of its uses is pulled in by `#[doc(cfg)]`. However, you can also implement traits for public types inside of functions. This is used by Diesel (probably others, but they were the example that was reported) to get around a recent macro hygiene fix, which has caused their crate to fail to document. While this won't make the traits show up in documentation (that step comes later), it will at least allow files to be generated.
rustdoc: refactor how passes are structured, and turn intra-doc-link collection into a pass
This builds on https://github.com/rust-lang/rust/pull/52751 and should not be merged until that finally finishes the bors queue
Part 2 of my passes refactor. This introduces the concept of an "early pass", which is run right before exiting the compiler context. This is important for passes that may want to ask the compiler about things. For example, i took out the intra-doc-link collection and turned it into a early pass. I also made the `strip-hidden`, `strip-private` and `strip-priv-imports` passes occur as early passes, so that intra-doc-link collection wouldn't run on docs that weren't getting printed.
Fixes https://github.com/rust-lang/rust/issues/51684, technically https://github.com/rust-lang/rust/issues/51468 too but that version of `h2` hits a legit intra-link error after that `>_>`
r? @rust-lang/rustdoc
[NLL] Use smaller spans for errors involving closure captures
Closes#51170Closes#46599
Error messages involving closures now point to the captured variable/closure args.
r? @pnkfelix
avoid computing liveness for locals that escape into statics
Fixes#52713
I poked at this on the plane and I think it's working -- but I want to do a bit more investigation and double check. The idea is to identify those local variables where the entire value will "escape" into the return -- for them, we don't need to compute liveness, since we know that the outlives relations from the return type will force those regions to be equal to free regions. This should help with html5ever in particular.
- [x] test performance
- [x] verify correctness
- [x] add comments
r? @pnkfelix
cc @lqd
App-lint-cability
@eminence recently pointed out (rust-lang/cargo#5846) that it's
surprising that `cargo fix` (now shipping with Cargo itself!) doesn't
fix very common lint warnings, which is as good of a reminder as any
that we should finish #50723.
(Previously, we did this on the librustc and libsyntax crates in #50724. I filed cmr/this-week-in-rust#685 in hopes of recruiting new contributors to do the rest.)
r? @estebank
Reintroduce `Undef` and properly check constant value sizes
r? @RalfJung
cc @eddyb
basically all kinds of silent failures that never occurred are assertions now
resolve: Implement prelude search for macro paths, implement tool attributes
When identifier is macro path is resolved in scopes (i.e. the first path segment - `foo` in `foo::mac!()` or `foo!()`), scopes are searched in the same order as for non-macro paths - items in modules, extern prelude, tool prelude (see later), standard library prelude, language prelude, but with some extra shadowing restrictions (names from globs and macro expansions cannot shadow names from outer scopes). See the comment in `fn resolve_lexical_macro_path_segment` for more details.
"Tool prelude" currently contains two "tool modules" `rustfmt` and `clippy`, and is searched immediately after extern prelude.
This makes the [possible long-term solution](https://github.com/rust-lang/rfcs/blob/master/text/2103-tool-attributes.md#long-term-solution) for tool attributes exactly equivalent to the existing extern prelude scheme, except that `--extern=my_crate` making crate names available in scope is replaced with something like `--tool=my_tool` making tool names available in scope.
The `tool_attributes` feature is still unstable and `#![feature(tool_attributes)]` now implicitly enables `#![feature(use_extern_macros)]`. `use_extern_macros` is a prerequisite for `tool_attributes`, so their stabilization will happen in the same order.
If `use_extern_macros` is not enabled, then tool attributes are treated as custom attributes (this is temporary, anyway).
Fixes https://github.com/rust-lang/rust/issues/52576
Fixes https://github.com/rust-lang/rust/issues/52512
Fixes https://github.com/rust-lang/rust/issues/51277
cc https://github.com/rust-lang/rust/issues/52269
[NLL] Dangly paths for box
Special-case `Box` in `rustc_mir::borrow_check`.
Since we know dropping a box will not access any `&mut` or `&` references, it is safe to model its destructor as only touching the contents *owned* by the box.
----
There are three main things going on here:
1. The first main thing, this PR is fixing a bug in NLL where `rustc` previously would issue a diagnostic error in a case like this:
```rust
fn foo(x: Box<&mut i32>) -> &mut i32 { &mut **x }
```
such code was accepted by the AST-borrowck in the past, but NLL was rejecting it with the following message ([playground](https://play.rust-lang.org/?gist=13c5560f73bfb16d6dab3ceaad44c0f8&version=nightly&mode=release&edition=2015))
```
error[E0597]: `**x` does not live long enough
--> src/main.rs:3:40
|
3 | fn foo(x: Box<&mut i32>) -> &mut i32 { &mut **x }
| ^^^^^^^^ - `**x` dropped here while still borrowed
| |
| borrowed value does not live long enough
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 3:1...
--> src/main.rs:3:1
|
3 | fn foo(x: Box<&mut i32>) -> &mut i32 { &mut **x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
```
2. The second main thing: The reason such code was previously rejected was because NLL (MIR-borrowck) incorporates a fix for issue #31567, where it models a destructor's execution as potentially accessing any borrows held by the thing being destructed. The tests with `Scribble` model this, showing that the compiler now catches such unsoundness.
However, that fix for issue #31567 is too strong, in that NLL (MIR-borrowck) includes `Box` as one of the types with a destructor that potentially accesses any borrows held by the box. This thus was the cause of the main remaining discrepancy between AST-borrowck and MIR-borrowck, as documented in issue #45696, specifically in [the last example of this comment](https://github.com/rust-lang/rust/issues/45696#issuecomment-345367873), which I have adapted into the `fn foo` shown above.
We did close issue #45696 back in December of 2017, but AFAICT that example was not fixed by PR #46268. (And we did not include a test, etc etc.)
This PR fixes that case, by trying to model the so-called `DerefPure` semantics of `Box<T>` when we traverse the type of the input to `visit_terminator_drop`.
3. The third main thing is that during a review of the first draft of this PR, @matthewjasper pointed out that the new traversal of `Box<T>` could cause the compiler to infinite loop. I have adjusted the PR to avoid this (by tracking what types we have previously seen), and added a much needed test of this somewhat odd scenario. (Its an odd scenario because the particular case only arises for things like `struct A(Box<A>);`, something which cannot be constructed in practice.)
Fix#45696.
Reexport tests without polluting namespaces
This should fix issue #52557.
Basically now we gensym a new name for the test function and reexport that.
That way the test function's reexport name can't conflict because it was impossible for the test author to write it down.
We then use a `use` statement to expose the original name using the original visibility.
Andrew Chin recently pointed out (rust-lang/cargo#5846) that it's
surprising that `cargo fix` (now shipping with Cargo itself!) doesn't
fix very common lint warnings, which is as good of a reminder as any
that we should finish #50723.
rustc_resolve: record single-segment extern crate import resolutions.
Fixes#52489 by recording special-cased single-segment imports for later (e.g. stability) checks.
cc @alexcrichton @Mark-Simulacrum @petrochenkov
Does this need to be backported?
rustc: Trim down the `rust_2018_idioms` lint group
These migration lints aren't all up to par in terms of a good migration
experience. Some, like `unreachable_pub`, hit bugs like #52665 and unprepared
macros to be handled enough of the time. Others like linting against
`#[macro_use]` are swimming upstream in an ecosystem that's not quite ready (and
slightly buggy pending a few current PRs).
The general idea is that we will continue to recommend the `rust_2018_idioms`
lint group as part of the transition guide (as an optional step) but we'll be
much more selective about which lints make it into this group. Only those with a
strong track record of not causing too much churn will make the cut.
cc #52679
[NLL] Allow conflicting borrows of promoted length zero arrays
This is currently overkill as there's no way to create two conflicting borrows of any promoted.
It is possible that the following code might not fail due to const eval in the future (@oli-obk?). In which case either the array marked needs to not be promoted, or to be checked for conflicts
```rust
static mut A: () = {
let mut y = None;
let z;
let mut done_y = false;
loop {
let x = &mut [1]; // < this array
if done_y {
z = x;
break;
}
y = Some(x);
done_y = true;
}
some_const_fn(y, z); // some_const_fn expects that y to not alias z.
};
```
r? @pnkfelix @nikomatsakis
closes#52671
cc #51823