At some point, I had thought to use this code to handle equality
comparisons for the `IfEq` verify bounds; at that point, we might not
have had an infcx to talk about. But we wound up doing "SCC
representatives" instead, so that's fine.
Instead, we talk about:
- creating the "next" universe
- universes "extending" one another
- and `u1.can_name(u2)`, meaning that `u1` contains all names from `u2`
[NLL] Check user types are well-formed
Also contains a change of span for AscribeUserType.
I'm not quite sure if this was what @nikomatsakis was thinking.
Closes#54620
r? @nikomatsakis
Better Diagnostic for Trait Object Capture
Part of #52663.
This commit enhances `LaterUseKind` detection to identify when a borrow
is captured by a trait object which helps explain why there is a borrow
error.
r? @nikomatsakis
cc @pnkfelix
Now when a `FnMut` closure is returning a closure that contains a
reference to a captured variable, we provide an error that makes it more
clear what is happening.
[NLL] Improve closure region bound errors
Previously, we would report free region errors that originate from closure with the span of the closure and a "closure body requires ..." message. This is now updated to use a reason and span from inside the closure.
This commit updates the captured trait object search logic to look for
unsized casts to boxed types rather than for functions that returned
trait objects.
Changed `BorrowExplanation::UsedLaterWhenDropped` to handle both named
locals and also unnamed (aka temporaries).
If the dropped temporary does not implement `Drop`, then we print its
full type; but when the dropped temporary is itself an ADT `D` that
implements `Drop`, then diagnostic points the user directly at `D`.
This is preparation for allowing the `BorrowExplanation` carry things
like `mir::Location` or `mir::Local` and still be able to generate
usable diagnostic text.
(I found it confusing to have calls to an `emit` method in our
error_reporting module where that `emit` method *wasn't* the
`DiagnosticBuffer::emit` method.)
adopt "placeholders" to represent universally quantified regions
This does a few preliminary refactorings that lay some groundwork for moving towards universe integration. Two things, primarily:
- Rename from "skolemized" to "placeholder"
- When instantiating `for<'a, 'b, 'c>`, just create one universe for all 3 regions, and distinguish them from one another using the `BoundRegion`.
- This is more accurate, and I think that in general we'll be moving towards a model of separating "binder" (universe, debruijn index) from "index within binder" in a number of places.
- In principle, it feels the current setup of making lots of universes could lead to us doing the wrong thing, but I've actually not been able to come up with an example where this is so.
r? @scalexm
cc @arielb1
Give a special message when the later use is from a call. Use the span
of the callee instead of the whole expression. For conflicting borrow
messages say that the later use is of the first borrow.
use closure def-id in returns, but base def-id in locals
The refactorings to handle `let x: impl Trait` wound up breaking `impl Trait` in closure return types. I think there are some deeper problems with the code in question, but this a least should make @eddyb's example work.
Fixes#54593
r? @eddyb
Before this patch running the following command would generate the given output:
$ rustc +stage1 src/test/ui/liveness/liveness-move-in-while.rs -Zborrowck=mir -Ztwo-phase-borrows
error[E0382]: borrow of moved value: `y`
--> src/main.rs:8:24
|
8 | println!("{}", y); //~ ERROR use of moved value: `y`
| ^ value borrowed here after move
9 | while true { while true { while true { x = y; x.clone(); } } }
| - value moved here
|
= note: move occurs because `y` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
We want to give the user more hint by telling them that the value was moved in the previous iteration of the
loop. After this patch, the error message adds the phrase "in previous iteration of loop" and in totality
looks like this:
$ rustc +stage1 src/test/ui/liveness/liveness-move-in-while.rs -Zborrowck=mir -Ztwo-phase-borrows
error[E0382]: borrow of moved value: `y`
--> src/test/ui/liveness/liveness-move-in-while.rs:17:24
|
17 | println!("{}", y); //~ ERROR use of moved value: `y`
| ^ value borrowed here after move
18 | while true { while true { while true { x = y; x.clone(); } } }
| - value moved here, in previous iteration of loop
|
= note: move occurs because `y` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
[NLL] Get Polonius borrow check to work in simple cases
* Restores the generation of outlives facts from subtyping.
* Restore liveness facts.
* Generate invalidates facts at the start point of each location,
where we check for errors.
* Add a small test for simple cases (previously these cases have compiled, and more recently ICEd).
Closes#54212
cc #53142 (will need test)
### Known limitations
* Two phase borrows aren't implemented for Polonius yet
* Invalidation facts haven't been updated for some of the recent changes to make `Drop` terminators access fewer things.
* Fact generation is not as optimized as it could be.
* Around 30 tests fail in compare mode, often tests that are ignored in nll compare mode
r? @nikomatsakis