Move `Fn*` traits malformedness protections to typeck
I found it strange that we were doing a custom well-formedness check just for the `Fn*` traits' `call_*` fn items. My understanding from the git history is that this is just to avoid ICEs later on in typeck.
Well, that well-formedness check isn't even implemented correctly for `FnOnce::call_once`, or `FnMut::call_mut` for that matter. Instead, this PR just makes the typeck checks more robust, and leaves it up to the call-site to report errors when lang items are implemented in funny ways.
This coincidentally fixes another ICE where a the `Add` lang item is implemented with a `add` item that's a const instead of a method.
Name placeholder in some region errors
Also don't print `ReVar` or `ReLateBound` as debug... these error messages are super uncommon anyways, but in the case they do trigger, let's be slightly more helpful.
remove unstable `pick_stable_methods_before_any_unstable` flag
This flag was only added in #90329 in case there was any issue with the impl so that it would be easy to tell nightly users to use the flag to disable the new logic to fix their code. It's now been enabled for two years and also I can't find any issues corresponding to this new functionality? This flag made it way harder to understand how this code works so it would be nice to remove it and simplify what's going on.
cc `@nbdd0121`
r? `@oli-obk`
Add rpitit queries
This is part of the changes we are making to lower RPITITs as an associated type. The rest of the stuff will follow under a `-Z` flag.
I still need to add comments to the code, explain stuff and also I'd need to avoid encoding in metadata when rpitit queries return `&[]`
r? `@compiler-errors`
lint: don't suggest MaybeUninit::assume_init for uninhabited types
Creating a zeroed uninhabited type such as `!` or an empty enum with `mem::zeroed()` (or transmuting `()` to `!`) currently triggers this lint:
```rs
warning: the type `!` does not permit zero-initialization
--> test.rs:5:23
|
5 | let _val: ! = mem::zeroed();
| ^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: the `!` type has no valid value
```
The `MaybeUninit` suggestion in the help message seems confusing/useless for uninhabited types, as such a type cannot be fully initialized in the first place (as the note implies).
This PR limits this help message to inhabited types which can be initialized
Miri: basic dyn* support
As usual I am very unsure about the dynamic dispatch stuff, but it passes even the `Pin<&mut dyn* Trait>` test so that is something.
TBH I think it was a mistake to make `dyn Trait` and `dyn* Trait` part of the same `TyKind` variant. Almost everywhere in Miri this lead to the wrong default behavior, resulting in strange ICEs instead of nice "unimplemented" messages. The two types describe pretty different runtime data layout after all.
Strangely I did not need to do the equivalent of [this diff](https://github.com/rust-lang/rust/pull/106532#discussion_r1087095963) in Miri. Maybe that is because the unsizing logic matches on `ty::Dynamic(.., ty::Dyn)` already? In `unsized_info` I don't think the `target_dyn_kind` can be `DynStar`, since then it wouldn't be unsized!
r? `@oli-obk` Cc `@eholk` (dyn-star) https://github.com/rust-lang/rust/issues/102425
Remove old FIXME that no longer applies
it looks like Encodable was fallible at some point, but that was changed which means that this FIXME is no longer applicable
Remove old FIXMEs referring to #19596
Having an inner function that accepts a mutable reference seems to be the only way this can be expressed. Taking a mutable reference would call the same function with a new type &mut F which then causes the infinite recursion error in #19596.
Refine error span for trait error into borrowed expression
Extends the error span refinement in #106477 to drill into borrowed expressions just like tuples/struct/enum literals. For example,
```rs
trait Fancy {}
trait Good {}
impl <'a, T> Fancy for &'a T where T: Good {}
impl <S> Good for Option<S> where S: Iterator {}
fn want_fancy<F>(f: F) where F: Fancy {}
fn example() {
want_fancy(&Some(5));
// (BEFORE) ^^^^^^^^ `{integer}` is not an iterator
// (AFTER) ^ `{integer}` is not an iterator
}
```
Existing heuristics try to find the right part of the expression to "point at"; current heuristics look at e.g. struct constructors and tuples. This PR adds a new check for borrowed expressions when looking into a borrowed type.
Use restricted Damerau-Levenshtein distance for diagnostics
This replaces the existing Levenshtein algorithm with the Damerau-Levenshtein algorithm. This means that "ab" to "ba" is one change (a transposition) instead of two (a deletion and insertion). More specifically, this is a _restricted_ implementation, in that "ca" to "abc" cannot be performed as "ca" → "ac" → "abc", as there is an insertion in the middle of a transposition. I believe that errors like that are sufficiently rare that it's not worth taking into account.
This was first brought up [on IRLO](https://internals.rust-lang.org/t/18227) when it was noticed that the diagnostic for `prinltn!` (transposed L and T) was `print!` and not `println!`. Only a single existing UI test was effected, with the result being an objective improvement.
~~I have left the method name and various other references to the Levenshtein algorithm untouched, as the exact manner in which the edit distance is calculated should not be relevant to the caller.~~
r? ``@estebank``
``@rustbot`` label +A-diagnostics +C-enhancement
create dummy placeholder crate to prevent compiler from panicing
This PR is to address the panic found in https://github.com/rust-lang/rust/issues/105700.
There are 2 separate things going on with this panic.
First the code could not generate a dummy response for crate fragment types when it hits the recursion limit.
This PR adds the method to the trait implementation for `DymmyResult` to be able to create a dummy crate node.
This stops the panic from happening.
The second thing that is not addressed (and maybe does not need addressing? 🤷🏻)
is that when you have multiple attributes it ends up treating attributes that follow another as being the result of expanding the former (maybe there is a better way to say that). So you end up hitting the recursion limit. Even though you would think there is no expansion happening here.
If you did not hit the recursion limit the compiler would output that `invalid_attribute` does not exists. But it currently exits before the resolution step when the recursion limit is reached here.
Type-directed probing for inherent associated types
When probing for inherent associated types (IATs), equate the Self-type found in the projection with the Self-type of the relevant inherent impl blocks and check if all predicates are satisfied.
Previously, we didn't look at the Self-type or at the bounds and just picked the first inherent impl block containing an associated type with the name we were searching for which is obviously incorrect.
Regarding the implementation, I basically copied what we do during method probing (`assemble_inherent_impl_probe`, `consider_probe`). Unfortunately, I had to duplicate a lot of the diagnostic code found in `rustc_hir_typeck::method::suggest` which we don't have access to in `rustc_hir_analysis`. Not sure if there is a simple way to unify the error handling. Note that in the future, `rustc_hir_analysis::astconv` might not actually be the place where we resolve inherent associated types (see https://github.com/rust-lang/rust/pull/103621#issuecomment-1304309565) but `rustc_hir_typeck` (?) in which case the duplication may naturally just disappear. While inherent associated *constants* are currently resolved during "method" probing, I did not find a straightforward way to incorporate IAT lookup into it as types and values (functions & constants) are two separate entities for which distinct code paths are taken.
Fixes#104251 (incl. https://github.com/rust-lang/rust/issues/104251#issuecomment-1338501171).
Fixes#105305.
Fixes#107468.
`@rustbot` label T-types F-inherent_associated_types
r? types
Make codegen choose whether to emit overflow checks
ConstProp and DataflowConstProp currently have a specific code path not to propagate constants when they overflow. This is meant to have the correct behaviour when inlining from a crate with overflow checks (like `core`) into a crate compiled without.
This PR shifts the behaviour change to the `Assert(Overflow*)` MIR terminators: if the crate is compiled without overflow checks, just skip emitting the assertions. This is already what happens with `OverflowNeg`.
This allows ConstProp and DataflowConstProp to transform `CheckedBinaryOp(Add, u8::MAX, 1)` into `const (0, true)`, and let codegen ignore the `true`.
The interpreter is modified to conform to this behaviour.
Fixes#35310
NB: Since we are using the same InferCtxt in each iteration,
we essentially *spoil* the inference variables and we only
ever get at most *one* applicable candidate (only the 1st candidate
has clean variables that can still unify correctly).
Fix RPITITs in default trait methods (by assuming projection predicates in param-env)
Instead of having special projection logic that allows us to turn `ProjectionTy(RPITIT, [Self#0, ...])` into `OpaqueTy(RPITIT, [Self#0, ...])`, we can instead augment the param-env of default trait method bodies to assume these as projection predicates. This should allow us to only project where we're allowed to!
In order to make this work without introducing a bunch of cycle errors, we additionally tweak the `OpaqueTypeExpander` used by `ParamEnv::with_reveal_all_normalized` to not normalize the right-hand side of projection predicates. This should be fine, because if we use the projection predicate to normalize some other projection type, we'll continue to normalize the opaque that it gets projected to.
This also makes it possible to support default trait methods with RPITITs in an associated-type based RPITIT lowering strategy without too much extra effort.
Fixes#107002
Alternative to #108142
Correctly handle links starting with whitespace
Part of https://github.com/rust-lang/rust/issues/107995.
I just got this issue, wrote a fix and then saw the issue. So here's the PR. ^^'
r? `@petrochenkov`
Rollup of 7 pull requests
Successful merges:
- #104659 (reflow the stack size story)
- #106933 (Update documentation of select_nth_unstable and select_nth_unstable_by to state O(n^2) complexity)
- #107783 (rustdoc: simplify DOM for `.item-table`)
- #107951 (resolve: Fix doc links referring to other crates when documenting proc macro crates directly)
- #108130 ("Basic usage" is redundant for there is just one example)
- #108146 (rustdoc: hide `reference` methods in search index)
- #108189 (Fix some more `non_lifetime_binders` stuff with higher-ranked trait bounds)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Fix some more `non_lifetime_binders` stuff with higher-ranked trait bounds
1. When assembling candidates for `for<T> T: Sized`, we can't ICE because the self-type is a bound type.
2. Fix an issue where, when canonicalizing in non-universe preserving mode, we don't actually set the universe for placeholders to the root even though we do the same for region vars.
3. Make `Placeholder("T")` format like `T` in error messages.
Fixes#108180Fixes#108182
r? types
Make `dyn*`'s value backend type a pointer
One tweak on top of Ralf's commit should fix using `usize` as a `dyn*`-coercible type, and should fix when we're using various other pointer types when LLVM opaque pointers is disabled.
r? `@eholk` but feel free to reassign
cc https://github.com/rust-lang/rust/pull/107728#issuecomment-1421231823 `@RalfJung`