Add E0790 as more specific variant of E0283
Fixes#81701
I think this should be good to go, there are only two things where I am somewhat unsure:
- Is there a better way to get the fully-qualified path for the suggestion? I tried `self.tcx.def_path_str`, but that didn't seem to always give a correct path for the context.
- Should all this be extracted into it's own method or is it fine where it is?
r? `@estebank`
`replace_bound_vars` fast path: check predicates, don't check consts
split out from #98900
`ty::Const` doesn't have precomputed type flags, so
computing `has_vars_bound_at_or_above` for constants
requires us to visit the const and its contained types
and constants. A noop fold should be pretty much equally as
fast so removing it prevents us from walking the constant twice
in case it contains bound vars.
r? `@jackh726`
`arena > Rc` for query results
The `Rc`s have to live for the whole duration as their count cannot go below 1 while stored as part of the query results.
By storing them in an arena we should save a bit of memory because we don't have as many independent allocations and also don't have to clone the `Rc` anymore.
Don't pass InferCtxt to WfPredicates
Simple cleanup. Infer vars will get passed up as obligations and shallowed resolved later. This actually improves one test output.
Revert "Highlight conflicting param-env candidates"
This reverts #98794, commit 08135254dc.
Seems to have caused an incremental compilation bug. The root cause of the incr comp bug is somewhat unrelated but is triggered by this PR, so I don't feel comfortable with having this PR in the codebase until it can be investigated further. Fixes#99233.
Better error message for generic_const_exprs inference failure
Fixes#90531
This code:
```rs
#![feature(generic_const_exprs)]
fn foo<const N: usize>(_arr: [u64; N + 1]) where [u64; N + 1]: {}
fn main() {
let arr = [5; 5];
foo(arr);
}
```
Will now emit the following error:
```rs
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
--> test.rs:1:12
|
1 | #![feature(generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
error[E0284]: type annotations needed
--> test.rs:8:7
|
8 | foo(arr);
| ^^^ cannot infer the value of the const parameter `N` declared on the function `foo`
|
note: required by a bound in `foo`
--> test.rs:3:56
|
3 | fn foo<const N: usize>(_arr: [u64; N + 1]) where [u64; N + 1]: {}
| ^^^^^ required by this bound in `foo`
help: consider specifying the generic argument
|
8 | foo::<N>(arr);
| +++++
error: aborting due to previous error; 1 warning emitted
```
cc: `@lcnr` thanks a lot again for the help on this
Move abstract const to middle
Moves AbstractConst (and all associated methods) to rustc middle for use in `rustc_infer`.
This allows for const resolution in infer to use abstract consts to walk consts and check if
they are resolvable.
This attempts to resolve the issue where `Foo<{ concrete const }, generic T>` is incorrectly marked as conflicting, and is independent from the other issue where nested abstract consts must be resolved.
r? `@lcnr`
`ty::Const` doesn't have precomputed type flags, so
computing `has_vars_bound_at_or_above` for constants
requires us to visit the const and its contained types
and constants. A noop fold should be pretty much equally as
fast so removing it prevents us from walking the constant twice
in case it contains bound vars.
Implement `for<>` lifetime binder for closures
This PR implements RFC 3216 ([TI](https://github.com/rust-lang/rust/issues/97362)) and allows code like the following:
```rust
let _f = for<'a, 'b> |a: &'a A, b: &'b B| -> &'b C { b.c(a) };
// ^^^^^^^^^^^--- new!
```
cc ``@Aaron1011`` ``@cjgillot``
Lower let-else in MIR
This MR will switch to lower let-else statements in MIR building instead.
To lower let-else in MIR, we build a mini-switch two branches. One branch leads to the matching case, and the other leads to the `else` block. This arrangement will allow temporary lifetime analysis running as-is so that the temporaries are properly extended according to the same rule applied to regular `let` statements.
cc https://github.com/rust-lang/rust/issues/87335Fix#98672
Fix duplicated type annotation suggestion
Before, there was more or less duplicated suggestions to add type hints.
Fix by clearing more generic suggestions when a more specific suggestion
is possible.
This fixes#93506 .
There are several indications that we should not ZST as a ScalarInt:
- We had two ways to have ZST valtrees, either an empty `Branch` or a `Leaf` with a ZST in it.
`ValTree::zst()` used the former, but the latter could possibly arise as well.
- Likewise, the interpreter had `Immediate::Uninit` and `Immediate::Scalar(Scalar::ZST)`.
- LLVM codegen already had to special-case ZST ScalarInt.
So instead add new ZST variants to those types that did not have other variants
which could be used for this purpose.
Before, there was more or less duplicated suggestions to add type hints.
Fix by clearing more generic suggestions when a more specific suggestion
is possible.
This fixes#93506 .
Track implicit `Sized` obligations in type params
When we evaluate `ty::GenericPredicates` we introduce the implicit
`Sized` predicate of type params, but we do so with only the `Predicate`
its `Span` as context, we don't have an `Obligation` or
`ObligationCauseCode` we could influence. To try and carry this
information through, we add a new field to `ty::GenericPredicates` that
tracks both which predicates come from a type param and whether that
param has any bounds already (to use in suggestions).
We also suggest adding a `?Sized` bound if appropriate on E0599.
Address part of #98539.
don't succeed `evaluate_obligation` query if new opaque types were registered
fixes#98608fixes#98604
The root cause of all this is that in type flag computation we entirely ignore nongeneric things like struct fields and the signature of function items. So if a flag had to be set for a struct if it is set for a field, that will only happen if the field is generic, as only the generic parameters are checked.
I now believe we cannot use type flags to handle opaque types. They seem like the wrong tool for this.
Instead, this PR replaces the previous logic by adding a new variant of `EvaluatedToOk`: `EvaluatedToOkModuloOpaqueTypes`, which says that there were some opaque types that got hidden types bound, but that binding may not have been legal (because we don't know if the opaque type was in its defining scope or not).
Highlight conflicting param-env candidates
This could probably be further improved by noting _why_ equivalent param-env candidates (modulo regions) leads to ambiguity.
Fixes#98786
macros: `LintDiagnostic` derive
- Move `LintDiagnosticBuilder` into `rustc_errors` so that a diagnostic derive can refer to it.
- Introduce a `DecorateLint` trait, which is equivalent to `SessionDiagnostic` or `AddToDiagnostic` but for lints. Necessary without making more changes to the lint infrastructure as `DecorateLint` takes a `LintDiagnosticBuilder` and re-uses all of the existing logic for determining what type of diagnostic a lint should be emitted as (e.g. error/warning).
- Various refactorings of the diagnostic derive machinery (extracting `build_field_mapping` helper and moving `sess` field out of the `DiagnosticDeriveBuilder`).
- Introduce a `LintDiagnostic` derive macro that works almost exactly like the `SessionDiagnostic` derive macro except that it derives a `DecorateLint` implementation instead. A new derive is necessary for this because `SessionDiagnostic` is intended for when the generated code creates the diagnostic. `AddToDiagnostic` could have been used but it would have required more changes to the lint machinery.
~~At time of opening this pull request, ignore all of the commits from #98624, it's just the last few commits that are new.~~
r? `@oli-obk`
Avoid some `&str` to `String` conversions with `MultiSpan::push_span_label`
This patch removes some`&str` to `String` conversions with `MultiSpan::push_span_label`.
Erase regions in New Abstract Consts
When an abstract const is constructed, we previously included lifetimes in the set of substitutes, so it was not able to unify two abstract consts if their lifetimes did not match but the values did, despite the values not depending on the lifetimes. This caused code that should have compiled to not compile.
Fixes#98452
r? ```@lcnr```
Currently, `search_for_structural_match_violation` constructs an `infcx`
from a `tcx` and then only uses the `tcx` within the `infcx`. This is
wasteful because `infcx` is a big type.
This commit changes it to use the `tcx` directly. When compiling
`pest-2.1.3`, this changes the memcpy stats reported by DHAT for a `check full`
build from this:
```
433,008,916 bytes (100%, 99,787.93/Minstr) in 2,148,668 blocks (100%, 495.17/Minstr), avg size 201.52 bytes
```
to this:
```
101,422,347 bytes (99.98%, 25,243.59/Minstr) in 1,318,407 blocks (99.96%, 328.15/Minstr), avg size 76.93 bytes
```
This translates to a 4.3% reduction in instruction counts.
Reverse folder hierarchy
#91318 introduced a trait for infallible folders distinct from the fallible version. For some reason (completely unfathomable to me now that I look at it with fresh eyes), the infallible trait was a supertrait of the fallible one: that is, all fallible folders were required to also be infallible. Moreover the `Error` associated type was defined on the infallible trait! It's so absurd that it has me questioning whether I was entirely sane.
This trait reverses the hierarchy, so that the fallible trait is a supertrait of the infallible one: all infallible folders are required to also be fallible (which is a trivial blanket implementation). This of course makes much more sense! It also enables the `Error` associated type to sit on the fallible trait, where it sensibly belongs.
There is one downside however: folders expose a `tcx` accessor method. Since the blanket fallible implementation for infallible folders only has access to a generic `F: TypeFolder`, we need that trait to expose such an accessor to which we can delegate. Alternatively it's possible to extract that accessor into a separate `HasTcx` trait (or similar) that would then be a supertrait of both the fallible and infallible folder traits: this would ensure that there's only one unambiguous `tcx` method, at the cost of a little additional boilerplate. If desired, I can submit that as a separate PR.
r? ````@jackh726````
Greatly improve error reporting for futures and generators in `note_obligation_cause_code`
Most futures don't go through this code path, because they're caught by
`maybe_note_obligation_cause_for_async_await`. But all generators do,
and `maybe_note` is imperfect and doesn't catch all futures. Improve the error message for those it misses.
At some point, we may want to consider unifying this with the code for `maybe_note_async_await`,
so that `async_await` notes all parent constraints, and `note_obligation` can point to yield points.
But both functions are quite complicated, and it's not clear to me how to combine them;
this seems like a good incremental improvement.
Helps with https://github.com/rust-lang/rust/issues/97332.
r? ``@estebank`` cc ``@eholk`` ``@compiler-errors``
#91318 introduced a trait for infallible folders distinct from the fallible version. For some reason (completely unfathomable to me now that I look at it with fresh eyes), the infallible trait was a supertrait of the fallible one: that is, all fallible folders were required to also be infallible. Moreover the `Error` associated type was defined on the infallible trait! It's so absurd that it has me questioning whether I was entirely sane.
This trait reverses the hierarchy, so that the fallible trait is a supertrait of the infallible one: all infallible folders are required to also be fallible (which is a trivial blanket implementation). This of course makes much more sense! It also enables the `Error` associated type to sit on the fallible trait, where it sensibly belongs.
There is one downside however: folders expose a `tcx` accessor method. Since the blanket fallible implementation for infallible folders only has access to a generic `F: TypeFolder`, we need that trait to expose such an accessor to which we can delegate. Alternatively it's possible to extract that accessor into a separate `HasTcx` trait (or similar) that would then be a supertrait of both the fallible and infallible folder traits: this would ensure that there's only one unambiguous `tcx` method, at the cost of a little additional boilerplate. If desired, I can submit that as a separate PR.
r? @jackh726
Add proper tracing spans to rustc_trait_selection::traits::error_reporting
While I was trying to figure out #97704 I did some of this to make the logs more legible, so I figured I'd do the whole module and open a PR with it. afaict this is an ongoing process in the compiler from the log->tracing transition? but lmk if there was a reason for the more verbose forms of logging as they are.
Also, for some of the functions with only one log in them, I put the function name as a message for that log instead of `#[instrument]`-ing the whole function with a span? but maybe the latter would actually be preferable, I'm not actually sure.
Most futures don't go through this code path, because they're caught by
`maybe_note_obligation_cause_for_async_await`. But all generators do,
and `maybe_note` is imperfect and doesn't catch all futures. Improve the error message for those it misses.
At some point, we may want to consider unifying this with the code for `maybe_note_async_await`,
so that `async_await` notes all parent constraints, and `note_obligation` can point to yield points.
But both functions are quite complicated, and it's not clear to me how to combine them;
this seems like a good incremental improvement.
Rename `impl_constness` to `constness`
The current code is a basis for `is_const_fn_raw`, and `impl_constness`
is no longer a valid name, which is previously used for determining the
constness of impls, and not items in general.
r? `@oli-obk`
The current code is a basis for `is_const_fn_raw`, and `impl_constness`
is no longer a valid name, which is previously used for determining the
constness of impls, and not items in general.
Make `ExprKind::Closure` a struct variant.
Simple refactor since we both need it to introduce additional fields in `ExprKind::Closure`.
r? ``@Aaron1011``
Rename the `ConstS::val` field as `kind`.
And likewise for the `Const::val` method.
Because its type is called `ConstKind`. Also `val` is a confusing name
because `ConstKind` is an enum with seven variants, one of which is
called `Value`. Also, this gives consistency with `TyS` and `PredicateS`
which have `kind` fields.
The commit also renames a few `Const` variables from `val` to `c`, to
avoid confusion with the `ConstKind::Value` variant.
r? `@BoxyUwU`
Remove RegionckMode in favor of calling new skip_region_resolution
Simple cleanup. We can skip a bunch of stuff for places where NLL does the region checking, so skip earlier.
r? rust-lang/types
And likewise for the `Const::val` method.
Because its type is called `ConstKind`. Also `val` is a confusing name
because `ConstKind` is an enum with seven variants, one of which is
called `Value`. Also, this gives consistency with `TyS` and `PredicateS`
which have `kind` fields.
The commit also renames a few `Const` variables from `val` to `c`, to
avoid confusion with the `ConstKind::Value` variant.
Remove unwrap from get_vtable
This avoids ICE on issue #97381 I think the bug is a bit deeper though, it compiles fine when `v` is `&v` which makes me think `Deref` is causing some issue with borrowck but it's fine I guess since this thing crashes since `nightly-2020-09-17` 😅
This commit makes type folding more like the way chalk does it.
Currently, `TypeFoldable` has `fold_with` and `super_fold_with` methods.
- `fold_with` is the standard entry point, and defaults to calling
`super_fold_with`.
- `super_fold_with` does the actual work of traversing a type.
- For a few types of interest (`Ty`, `Region`, etc.) `fold_with` instead
calls into a `TypeFolder`, which can then call back into
`super_fold_with`.
With the new approach, `TypeFoldable` has `fold_with` and
`TypeSuperFoldable` has `super_fold_with`.
- `fold_with` is still the standard entry point, *and* it does the
actual work of traversing a type, for all types except types of
interest.
- `super_fold_with` is only implemented for the types of interest.
Benefits of the new model.
- I find it easier to understand. The distinction between types of
interest and other types is clearer, and `super_fold_with` doesn't
exist for most types.
- With the current model is easy to get confused and implement a
`super_fold_with` method that should be left defaulted. (Some of the
precursor commits fixed such cases.)
- With the current model it's easy to call `super_fold_with` within
`TypeFolder` impls where `fold_with` should be called. The new
approach makes this mistake impossible, and this commit fixes a number
of such cases.
- It's potentially faster, because it avoids the `fold_with` ->
`super_fold_with` call in all cases except types of interest. A lot of
the time the compile would inline those away, but not necessarily
always.
Do `suggest_await_before_try` with infer variables in self, and clean up binders
Fixes#97704
Also cleans up binders in this fn, since everything is a `Poly*` and we really shouldn't have stray escaping late-bound regions everywhere. That's why the function changed so much. This isn't necessary, so I can revert if necessary.
Because it really has two halves:
- A read-only part that checks if further work is needed.
- The further work part, which is much less hot.
This makes things a bit clearer and nicer.
Replace `&Vec<_>`s with `&[_]`s
It's generally preferable to use `&[_]` since it's one less indirection and it can be created from types other that `Vec`.
I've left `&Vec` in some locals where it doesn't really matter, in cases where `TypeFoldable` is expected (`TypeFoldable: Clone` so slice can't implement it) and in cases where it's `&TypeAliasThatIsActiallyVec`. Nothing important, really, I was just a little annoyed by `visit_generic_param_vec` :D
r? `@compiler-errors`