Only check the own predicates of associated types when confirming
projection candidates.
Also consider implied bounds when comparing trait and impl methods.
Normalizing `<dyn Iterator<Item = ()> as Iterator>::Item` no longer
requires selecting `dyn Iterator<Item = ()>: Iterator`. This was
previously worked around by using a special type-folder to normalize
things.
If a symbol name can only be imported from one place for a type, and
as long as it was not glob-imported anywhere in the current crate, we
can trim its printed path and print only the name.
This has wide implications on error messages with types, for example,
shortening `std::vec::Vec` to just `Vec`, as long as there is no other
`Vec` importable anywhere.
This adds a new '-Z trim-diagnostic-paths=false' option to control this
feature.
On the good path, with no diagnosis printed, we should try to avoid
issuing this query, so we need to prevent trimmed_def_paths query on
several cases.
This change also relies on a previous commit that differentiates
between `Debug` and `Display` on various rustc types, where the latter
is trimmed and presented to the user and the former is not.
Currently, the def span of a funtion encompasses the entire function
signature and body. However, this is usually unnecessarily verbose - when we are
pointing at an entire function in a diagnostic, we almost always want to
point at the signature. The actual contents of the body tends to be
irrelevant to the diagnostic we are emitting, and just takes up
additional screen space.
This commit changes the `def_span` of all function items (freestanding
functions, `impl`-block methods, and `trait`-block methods) to be the
span of the signature. For example, the function
```rust
pub fn foo<T>(val: T) -> T { val }
```
now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T`
(everything before the opening curly brace).
Trait methods without a body have a `def_span` which includes the
trailing semicolon. For example:
```rust
trait Foo {
fn bar();
}```
the function definition `Foo::bar` has a `def_span` of `fn bar();`
This makes our diagnostic output much shorter, and emphasizes
information that is relevant to whatever diagnostic we are reporting.
We continue to use the full span (including the body) in a few of
places:
* MIR building uses the full span when building source scopes.
* 'Outlives suggestions' use the full span to sort the diagnostics being
emitted.
* The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]`
attribute points the entire scope body.
* The 'unconditional recursion' lint uses the full span to show
additional context for the recursive call.
All of these cases work only with local items, so we don't need to
add anything extra to crate metadata.
In particular, it no longer occurs during the subtyping check. This is
important for enabling lazy normalization, because the subtyping check
will be producing sub-obligations that could affect its results.
Consider an example like
for<'a> fn(<&'a as Mirror>::Item) =
fn(&'b u8)
where `<T as Mirror>::Item = T` for all `T`. We will wish to produce a
new subobligation like
<'!1 as Mirror>::Item = &'b u8
This will, after being solved, ultimately yield a constraint that `'!1
= 'b` which will fail. But with the leak-check being performed on
subtyping, there is no opportunity to normalize `<'!1 as
Mirror>::Item` (unless we invoke that normalization directly from
within subtyping, and I would prefer that subtyping and unification
are distinct operations rather than part of the trait solving stack).
The reason to keep the leak check during coherence and trait
evaluation is partly for backwards compatibility. The coherence change
permits impls for `fn(T)` and `fn(&T)` to co-exist, and the trait
evaluation change means that we can distinguish those two cases
without ambiguity errors. It also avoids recreating #57639, where we
were incorrectly choosing a where clause that would have failed the
leak check over the impl which succeeds.
The other reason to keep the leak check in those places is that I
think it is actually close to the model we want. To the point, I think
the trait solver ought to have the job of "breaking down"
higher-ranked region obligation like ``!1: '2` into into region
obligations that operate on things in the root universe, at which
point they should be handed off to polonius. The leak check isn't
*really* doing that -- these obligations are still handed to the
region solver to process -- but if/when we do adopt that model, the
decision to pass/fail would be happening in roughly this part of the
code.
This change had somewhat more side-effects than I anticipated. It
seems like there are cases where the leak-check was not being enforced
during method proving and trait selection. I haven't quite tracked
this down but I think it ought to be documented, so that we know what
precisely we are committing to.
One surprising test was `issue-30786.rs`. The behavior there seems a
bit "fishy" to me, but the problem is not related to the leak check
change as far as I can tell, but more to do with the closure signature
inference code and perhaps the associated type projection, which
together seem to be conspiring to produce an unexpected
signature. Nonetheless, it is an example of where changing the
leak-check can have some unexpected consequences: we're now failing to
resolve a method earlier than we were, which suggests we might change
some method resolutions that would have been ambiguous to be
successful.
TODO:
* figure out remainig test failures
* add new coherence tests for the patterns we ARE disallowing
In the new leak check, instead of getting a list of placeholders to
track, we look for any placeholder that is part of a universe which
was created during the snapshot.
We are looking for the following error patterns:
* P1: P2, where P1 != P2
* P1: R, where R is in some universe that cannot name P1
This new leak check is more precise than before, in that it accepts
this patterns:
* R: P1, even if R cannot name P1, because R = 'static is a valid
sol'n
* R: P1, R: P2, as above
Note that this leak check, when running during subtyping, is less
efficient than before in some sense because it is going to check and
re-check all the universes created since the snapshot. We're going to
move when the leak check runs to try and correct that.
Display information about captured variable in `FnMut` error
Fixes#69446
When we encounter a region error involving an `FnMut` closure, we
display a specialized error message. However, we currently do not
tell the user which upvar was captured. This makes it difficult to
determine the cause of the error, especially when the closure is large.
This commit records marks constraints involving closure upvars
with `ConstraintCategory::ClosureUpvar`. When we decide to 'blame'
a `ConstraintCategory::Return`, we additionall store
the captured upvar if we found a `ConstraintCategory::ClosureUpvar` in
the path.
When generating an error message, we point to relevant spans if we have
closure upvar information available. We further customize the message if
an `async` closure is being returned, to make it clear that the captured
variable is being returned indirectly.
Detect type parameter that might require lifetime constraint.
Do not name `ReVar`s in expected/found output.
Reword text suggesting to check the lifetimes.
Fixes#69446
When we encounter a region error involving an `FnMut` closure, we
display a specialized error message. However, we currently do not
tell the user which upvar was captured. This makes it difficult to
determine the cause of the error, especially when the closure is large.
This commit records marks constraints involving closure upvars
with `ConstraintCategory::ClosureUpvar`. When we decide to 'blame'
a `ConstraintCategory::Return`, we additionall store
the captured upvar if we found a `ConstraintCategory::ClosureUpvar` in
the path.
When generating an error message, we point to relevant spans if we have
closure upvar information available. We further customize the message if
an `async` closure is being returned, to make it clear that the captured
variable is being returned indirectly.
Overhaul of the `AllocRef` trait to match allocator-wg's latest consens; Take 2
GitHub won't let me reopen#69889 so I make a new PR.
In addition to #69889 this fixes the unsoundness of `RawVec::into_box` when using allocators supporting overallocating. Also it uses `MemoryBlock` in `AllocRef` to unify `_in_place` methods by passing `&mut MemoryBlock`. Additionally, `RawVec` now checks for `size_of::<T>()` again and ignore every ZST. The internal capacity of `RawVec` isn't used by ZSTs anymore, as `into_box` now requires a length to be specified.
r? @Amanieu
fixesrust-lang/wg-allocators#38fixesrust-lang/wg-allocators#41fixesrust-lang/wg-allocators#44fixesrust-lang/wg-allocators#51