Revert "Add rustc lint, warning when iterating over hashmaps"
Fixes perf regressions introduced in https://github.com/rust-lang/rust/pull/90235 by temporarily reverting the relevant PR.
Add BorrowSet to public api
This PR adds `BorrowSet` to the public api so that verification tools can obtain the activation and reservation points of two phase borrows without having to redo calculations themselves (and thus potentially differently from rustc).
Turns out we already can obtain `MoveData` thanks to the public `HasMoveData` trait, so constructing a `BorrowSet` should not provide much of an issue. However, I can't speak to the soundness of this approach, is it safe to take an under-approximation of `MoveData`?
r? `@nikomatsakis`
Implement coherence checks for negative trait impls
The main purpose of this PR is to be able to [move Error trait to core](https://github.com/rust-lang/project-error-handling/issues/3).
This feature is necessary to handle the following from impl on box.
```rust
impl From<&str> for Box<dyn Error> { ... }
```
Without having negative traits affect coherence moving the error trait into `core` and moving that `From` impl to `alloc` will cause the from impl to no longer compiler because of a potential future incompatibility. The compiler indicates that `&str` _could_ introduce an `Error` impl in the future, and thus prevents the `From` impl in `alloc` that would cause overlap with `From<E: Error> for Box<dyn Error>`. Adding `impl !Error for &str {}` with the negative trait coherence feature will disable this error by encoding a stability guarantee that `&str` will never implement `Error`, making the `From` impl compile.
We would have this in `alloc`:
```rust
impl From<&str> for Box<dyn Error> {} // A
impl<E> From<E> for Box<dyn Error> where E: Error {} // B
```
and this in `core`:
```rust
trait Error {}
impl !Error for &str {}
```
r? `@nikomatsakis`
This PR was built on top of `@yaahc` PR #85764.
Language team proposal: to https://github.com/rust-lang/lang-team/issues/96
Don't mark for loop iter expression as desugared
We typically don't mark spans of lowered things as desugared. This helps Clippy rightly discern when code is (not) from expansion. This was discovered by ``@flip1995`` at https://github.com/rust-lang/rust-clippy/pull/7789#issuecomment-939289501.
Adopt let_else across the compiler
This performs a substitution of code following the pattern:
```
let <id> = if let <pat> = ... { identity } else { ... : ! };
```
To simplify it to:
```
let <pat> = ... { identity } else { ... : ! };
```
By adopting the `let_else` feature (cc #87335).
The PR also updates the syn crate because the currently used version of the crate doesn't support `let_else` syntax yet.
Note: Generally I'm the person who *removes* usages of unstable features from the compiler, not adds more usages of them, but in this instance I think it hopefully helps the feature get stabilized sooner and in a better state. I have written a [comment](https://github.com/rust-lang/rust/issues/87335#issuecomment-944846205) on the tracking issue about my experience and what I feel could be improved before stabilization of `let_else`.
Remove redundant member-constraint check
impl trait will, for each lifetime in the hidden type, register a "member constraint" that says the lifetime must be equal or outlive one of the lifetimes of the impl trait. These member constraints will be solved by borrowck
But, as you can see in the big red block of removed code, there was an ad-hoc check for member constraints happening at the site where they get registered. This check had some minor effects on diagnostics, but will fall down on its feet with my big type alias impl trait refactor. So we removed it and I pulled the removal out into a (hopefully) reviewable PR that works on master directly.
This performs a substitution of code following the pattern:
let <id> = if let <pat> = ... { identity } else { ... : ! };
To simplify it to:
let <pat> = ... { identity } else { ... : ! };
By adopting the let_else feature.
Add check that live_region is live in sanitize_promoted
This pull request fixes#88434 by adding a check in `sanitize_promoted` to ensure that only regions which are actually live are added to the `liveness_constraints` of the `BorrowCheckContext`.
To implement this change, I needed to add a method to `LivenessValues` which gets the elements contained by a region:
/// Returns an iterator of all the elements contained by the region `r`
crate fn get_elements(&self, row: N) -> impl Iterator<Item = Location> + '_
Then, inside `sanitize_promoted`, we check whether the iterator returned by this method is non-empty to ensure that the region is actually live at at least one location before adding that region to the `liveness_constraints` of the `BorrowCheckContext`.
This is my first pull request to the Rust repo, so any feedback on how I can improve this pull request or if there is a better way to fix this issue would be very appreciated.
Re-use TypeChecker instead of passing around some of its fields
In the future (for lazy TAIT) we will need more of its fields, but even ignoring that, this change seems reasonable on its own to me.
Fixes#67007
Currently, a 'borrowed data escapes' error does not mention
the specific lifetime involved (except indirectly through a suggestion
about adding a lifetime bound). We now explain the specific lifetime
relationship that failed to hold, which improves otherwise vague
error messages.
Don't suggest replacing region with 'static in NLL
Fixes#73159
This is similar to #69350 - if the user didn't initially
write out a 'static lifetime, adding 'static in response to
a lifetime error is usually the wrong thing to do.
Stabilize `const_panic`
Closes#51999
FCP completed in #89006
```@rustbot``` label +A-const-eval +A-const-fn +T-lang
cc ```@oli-obk``` for review (not `r?`'ing as not on lang team)
Remove some feature gates
The first commit removes various feature gates that are unused. The second commit replaces some `Fn` implementations with `Iterator` implementations, which is much cleaner IMO. The third commit replaces an unboxed_closures feature gate with min_specialization. For some reason the unboxed_closures feature gate suppresses the min_specialization feature gate from triggering on an `TrustedStep` impl. The last comment just turns a regular comment into a doc comment as drive by cleanup. I can move it to a separate PR if preferred.
Fixes#73159
This is similar to #69350 - if the user didn't initially
write out a 'static lifetime, adding 'static in response to
a lifetime error is usually the wrong thing to do.
Pick one possible lifetime in case there are multiple choices
In case a lifetime variable is created, but doesn't have an obvious lifetime in the list of named lifetimes that it should be inferred to, just pick the first one for the diagnostic.
This happens e.g. in
```rust
fn foo<'a, 'b>(a: Struct<'a>, b: Struct<'b>) -> impl Trait<'a, 'b> {
if bar() { a } else { b }
}
```
where we get a lifetime variable that combines the lifetimes of `a` and `b` creating a lifetime that is the intersection of both. Right now the type system cannot express this and thus we get an error, but that error also can't express this.
I can also create an entirely new diagnostic that mentions all involved lifetimes, so it would actually mention `'a` and `'b` instead of just `'b`.
Avoid spurious "previous iteration of loop" errors
Only follow backwards edges during `get_moved_indexes` if the move path is definitely initialized at loop entry. Otherwise, the error occurred prior to the loop, so we ignore the backwards edges to avoid generating misleading "value moved here, in previous iteration of loop" errors.
This patch also slightly improves the analysis of inits, including `NonPanicPathOnly` initializations (which are ignored by `drop_flag_effects::for_location_inits`). This is required for the definite initialization analysis, but may also help find certain skipped reinits in rare cases.
Patch passes all non-ignored src/test/ui testcases.
Fixes#72649.
This PR has several interconnected pieces:
1. In some of the NLL region error code, we now pass
around an `ObligationCause`, instead of just a plain `Span`.
This gets forwarded into `fulfill_cx.register_predicate_obligation`
during error reporting.
2. The general InferCtxt error reporting code is extended to
handle `ObligationCauseCode::BindingObligation`
3. A new enum variant `ConstraintCategory::Predicate` is added.
We try to avoid using this as the 'best blame constraint' - instead,
we use it to enhance the `ObligationCause` of the `BlameConstraint`
that we do end up choosing.
As a result, several NLL error messages now contain the same
"the lifetime requirement is introduced here" message as non-NLL
errors.
Having an `ObligationCause` available will likely prove useful
for future improvements to NLL error messages.
Introduce `Rvalue::ShallowInitBox`
Polished version of #88700.
Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.
In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.
`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.
Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
Be explicit about using Binder::dummy
This is somewhat of a late followup to the binder refactor PR. It removes `ToPredicate` and `ToPolyTraitImpls` that hide the use of `Binder::dummy`. While this does make code a bit more verbose, it allows us be more careful about where we create binders.
Another alternative here might be to add a new trait `ToBinder` or something with a `dummy()` fn. Which could still allow grepping but allows doing something like `trait_ref.dummy()` (but I also wonder if longer-term, it would be better to be even more explicit with a `bind_with_vars(ty::List::empty())` *but* that's not clear yet.
r? ``@nikomatsakis``