| Age | Commit message (Collapse) | Author | Lines |
|
r=compiler-errors
`-Znext-solver=coherence`: suggest increasing recursion limit
r? `@compiler-errors`
|
|
|
|
Combine `Sub` and `Equate`
Combine `Sub` and `Equate` into a new relation called `TypeRelating` (that name sounds familiar...)
Tracks the difference between `Sub` and `Equate` via `ambient_variance: ty::Variance` much like the `NllTypeRelating` relation, but implemented slightly jankier because it's a more general purpose relation.
r? lcnr
|
|
Add stubs in IR and ABI for `f16` and `f128`
This is the very first step toward the changes in https://github.com/rust-lang/rust/pull/114607 and the [`f16` and `f128` RFC](https://rust-lang.github.io/rfcs/3453-f16-and-f128.html). It adds the types to `rustc_type_ir::FloatTy` and `rustc_abi::Primitive`, and just propagates those out as `unimplemented!` stubs where necessary.
These types do not parse yet so there is no feature gate, and it should be okay to use `unimplemented!`.
The next steps will probably be AST support with parsing and the feature gate.
r? `@compiler-errors`
cc `@Nilstrieb` suggested breaking the PR up in https://github.com/rust-lang/rust/pull/120645#issuecomment-1925900572
|
|
|
|
Safe Transmute: Revise safety analysis
This PR migrates `BikeshedIntrinsicFrom` to a simplified safety analysis (described [here](https://github.com/rust-lang/project-safe-transmute/issues/15)) that does not rely on analyzing the visibility of types and fields.
The revised analysis treats primitive types as safe, and user-defined types as potentially carrying safety invariants. If Rust gains explicit (un)safe fields, this PR is structured so that it will be fairly easy to thread support for those annotations into the analysis.
Notably, this PR removes the `Context` type parameter from `BikeshedIntrinsicFrom`. Most of the files changed by this PR are just UI tests tweaked to accommodate the removed parameter.
r? `@compiler-errors`
|
|
|
|
|
|
also change the number of allowed fixpoint steps to be fixed instead
of using the `log` of the total recursion depth.
|
|
Make changes necessary to support these types in the compiler.
|
|
|
|
|
|
Migrate to a simplified safety analysis that does not use visibility.
Closes https://github.com/rust-lang/project-safe-transmute/issues/15
|
|
|
|
Add `StructurallyRelateAliases` to allow instantiating infer vars with rigid aliases.
Change `instantiate_query_response` to be infallible in the new solver. This requires canonicalization to not hide any information used by the query, so weaken
universe compression. It also modifies `term_is_fully_unconstrained` to allow
region inference variables in a higher universe.
|
|
|
|
remove `sub_relations` from the `InferCtxt`
While doing so, I tried to remove the `delay_span_bug` in `rematch_impl` again, which lead me to discover another `freshen` bug, fixing that one in the second commit. See commit descriptions for the reasoning behind each change.
r? `@compiler-errors`
|
|
No need to `validate_alias_bound_self_from_param_env` in `assemble_alias_bound_candidates`
We already fully normalize the self type before we reach `assemble_alias_bound_candidates`, so there's no reason to double check that a projection is truly rigid by checking param-env bounds.
I think this is also blocked on us making sure to always normalize opaques: #120549.
r? lcnr
|
|
|
|
miscellaneous type system improvements
see review comments for rationale
r? `@compiler-errors`
|
|
|
|
|
|
|
|
Use fulfillment in next trait solver coherence
Use fulfillment in the new trait solver's `impl_intersection_has_impossible_obligation` routine. This means that inference that falls out of processing other obligations can influence whether we can determine if an obligation is impossible to satisfy. See the committed test.
This should be completely sound, since evaluation and fulfillment both respect intercrate mode equally.
We run the risk of breaking coherence later if we were to change the rules of fulfillment and/or inference during coherence, but this is a problem which affects evaluation, as nested obligations from a trait goal are processed together and can influence each other in the same way.
r? lcnr
cc #114862
Also changed obligationctxt -> fulfillmentctxt because it feels kind of redundant to use an ocx here. I don't really care enough and can change it back if it really matters much.
|
|
|
|
|
|
|
|
|
|
Do not assemble candidates for default impls
There is no reason (as far as I can tell?) that we should assemble an impl candidate for a default impl. This candidate itself does not prove that the impl holds, and any time that it *does* hold, there will be a more specializing non-default impl that also is assembled.
This is because `default impl<T> Foo for T {}` actually expands to `impl<T> Foo for T where T: Foo {}`. The only way to satisfy that where clause (without coinduction) is via *another* implementation that does hold -- precisely an impl that specializes it.
This should fix the specialization related regressions for #116494. That should lead to one root crate regression that doesn't have to do with specialization, which I think we can regress.
r? lcnr cc ``@rust-lang/types``
cc #31844
|
|
|
|
modify alias-relate to also normalize ambiguous opaques
allows a bunch of further cleanups and generally simplifies the type system. To handle https://github.com/rust-lang/trait-system-refactor-initiative/issues/8 we'll have to add a some additional complexity to the `(Alias, Infer)` branches in alias-relate, so removing the opaque type special case here is really valuable.
It does worsen `deduce_closure_signature` and friends even more as they now receive an inference variable which is only constrained via an `AliasRelate` goal. These probably have to look into alias relate goals somehow. Leaving that for a future PR as this is something we'll have to tackle regardless.
r? `@compiler-errors`
|
|
|
|
with this, alias-relate treats all aliases the same way
and it can be used for structural normalization.
|
|
Merge `impl_polarity` and `impl_trait_ref` queries
Hopefully this is perf neutral. I want to finish https://github.com/rust-lang/rust/pull/120835 and stop using the HIR in `coherent_trait`, which should then give us a perf improvement.
|
|
Dejargonize `subst`
In favor of #110793, replace almost every occurence of `subst` and `substitution` from rustc codes, but they still remains in subtrees under `src/tools/` like clippy and test codes (I'd like to replace them after this)
|
|
|
|
|
|
|
|
Harmonize `AsyncFn` implementations, make async closures conditionally impl `Fn*` traits
This PR implements several changes to the built-in and libcore-provided implementations of `Fn*` and `AsyncFn*` to address two problems:
1. async closures do not implement the `Fn*` family traits, leading to breakage: https://crater-reports.s3.amazonaws.com/pr-120361/index.html
2. *references* to async closures do not implement `AsyncFn*`, as a consequence of the existing blanket impls of the shape `AsyncFn for F where F: Fn, F::Output: Future`.
In order to fix (1.), we implement `Fn` traits appropriately for async closures. It turns out that async closures can:
* always implement `FnOnce`, meaning that they're drop-in compatible with `FnOnce`-bound combinators like `Option::map`.
* conditionally implement `Fn`/`FnMut` if they have no captures, which means that existing usages of async closures should *probably* work without breakage (crater checking this: https://github.com/rust-lang/rust/pull/120712#issuecomment-1930587805).
In order to fix (2.), we make all of the built-in callables implement `AsyncFn*` via built-in impls, and instead adjust the blanket impls for `AsyncFn*` provided by libcore to match the blanket impls for `Fn*`.
|
|
For a rigid projection, recursively look at the self type's item bounds to fix the `associated_type_bounds` feature
Given a deeply nested rigid projection like `<<<T as Trait1>::Assoc1 as Trait2>::Assoc2 as Trait3>::Assoc3`, this PR adjusts both trait solvers to look at the item bounds for all of `Assoc3`, `Assoc2`, and `Assoc1` in order to satisfy a goal. We do this because the item bounds for projections may contain relevant bounds for *other* nested projections when the `associated_type_bounds` (ATB) feature is enabled. For example:
```rust
#![feature(associated_type_bounds)]
trait Trait1 {
type Assoc1: Trait2<Assoc2: Foo>;
// Item bounds for `Assoc1` are:
// `<Self as Trait1>::Assoc1: Trait2`
// `<<Self as Trait1>::Assoc1 as Trait2>::Assoc2: Foo`
}
trait Trait2 {
type Assoc2;
}
trait Foo {}
fn hello<T: Trait1>(x: <<T as Trait1>::Assoc1 as Trait2>::Assoc2) {
fn is_foo(_: impl Foo) {}
is_foo(x);
// Currently fails with:
// ERROR the trait bound `<<Self as Trait1>::Assoc1 as Trait2>::Assoc2: Foo` is not satisfied
}
```
This has been a long-standing place of brokenness for ATBs, and is also part of the reason why ATBs currently desugar so differently in various positions (i.e. sometimes desugaring to param-env bounds, sometimes desugaring to RPITs, etc). For example, in RPIT and TAIT position, `impl Foo<Bar: Baz>` currently desugars to `impl Foo<Bar = impl Baz>` because we do not currently take advantage of these nested item bounds if we desugared them into a single set of item bounds on the opaque. This is obviously both strange and unnecessary if we just take advantage of these bounds as we should.
## Approach
This PR repeatedly peels off each projection of a given goal's self type and tries to match its item bounds against a goal, repeating with the self type of the projection. This is pretty straightforward to implement in the new solver, only requiring us to loop on the self type of a rigid projection to discover inner rigid projections, and we also need to introduce an extra probe so we can normalize them.
In the old solver, we can do essentially the same thing, however we rely on the fact that projections *should* be normalized already. This is obviously not always the case -- however, in the case that they are not fully normalized, such as a projection which has both infer vars and, we bail out with ambiguity if we hit an infer var for the self type.
## Caveats
⚠️ In the old solver, this has the side-effect of actually stalling some higher-ranked trait goals of the form `for<'a> <?0 as Tr<'a>>: Tr2`. Because we stall them, they no longer are eagerly treated as error -- this cause some existing `known-bug` tests to go from fail -> pass.
I'm pretty unconvinced that this is a problem since we make code that we expect to pass in the *new* solver also pass in the *old* solver, though this obviously doesn't solve the *full* problem.
## And then also...
We also adjust the desugaring of ATB to always desugar to a regular associated bound, rather than sometimes to an impl Trait **except** for when the ATB is present in a `dyn Trait`. We need to lower `dyn Trait<Assoc: Bar>` to `dyn Trait<Assoc = impl Bar>` because object types need all of their associated types specified.
I would also be in favor of splitting out the ATB feature and/or removing support for object types in order to stabilize just the set of positions for which the ATB feature is consistent (i.e. always elaborates to a bound).
|
|
hide impls if trait bound is proven from env
AVERT YOUR EYES `@compiler-errors`
fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/76 and https://github.com/rust-lang/trait-system-refactor-initiative/issues/12#issuecomment-1865234925
this is kinda ugly and I hate it, but I wasn't able to think of a cleaner approach for now. I am also unsure whether we have to refine this filtering later on, so by making the change pretty minimal it should be easier to improve going forward.
r? `@BoxyUwU`
|
|
improve normalization of `Pointee::Metadata`
This PR makes it so that `<Wrapper<Tail> as Pointee>::Metadata` is normalized to `<Tail as Pointee>::Metadata` if we don't know `Wrapper<Tail>: Sized`. With that, the trait solver can prove projection predicates like `<Wrapper<Tail> as Pointee>::Metadata == <Tail as Pointee>::Metadata`, which makes it possible to use the metadata APIs to cast between the tail and the wrapper:
```rust
#![feature(ptr_metadata)]
use std::ptr::{self, Pointee};
fn cast_same_meta<T: ?Sized, U: ?Sized>(ptr: *const T) -> *const U
where
T: Pointee<Metadata = <U as Pointee>::Metadata>,
{
let (thin, meta) = ptr.to_raw_parts();
ptr::from_raw_parts(thin, meta)
}
struct Wrapper<T: ?Sized>(T);
fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
cast_same_meta(ptr)
}
```
Previously, this failed to compile:
```
error[E0271]: type mismatch resolving `<Wrapper<T> as Pointee>::Metadata == <T as Pointee>::Metadata`
--> src/lib.rs:16:5
|
15 | fn cast_to_wrapper<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
| - found this type parameter
16 | cast_same_meta(ptr)
| ^^^^^^^^^^^^^^ expected `Wrapper<T>`, found type parameter `T`
|
= note: expected associated type `<Wrapper<T> as Pointee>::Metadata`
found associated type `<T as Pointee>::Metadata`
= note: an associated type was expected, but a different one was found
```
(Yes, you can already do this with `as` casts. But using functions is so much :sparkles: *safer* :sparkles:, because you can't change the metadata on accident.)
---
This PR essentially changes the built-in impls of `Pointee` from this:
```rust
// before
impl Pointee for u8 {
type Metadata = ();
}
impl Pointee for [u8] {
type Metadata = usize;
}
// ...
impl Pointee for Wrapper<u8> {
type Metadata = ();
}
impl Pointee for Wrapper<[u8]> {
type Metadata = usize;
}
// ...
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T: ?Sized> Pointee for Wrapper<T>
where
Wrapper<T>: Sized
{
type Metadata = ();
}
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
type Metadata = ();
}
```
to this:
```rust
// after
impl Pointee for u8 {
type Metadata = ();
}
impl Pointee for [u8] {
type Metadata = usize;
}
// ...
impl<T: ?Sized> Pointee for Wrapper<T> {
// in the old solver this will instead project to the "deep" tail directly,
// e.g. `Wrapper<Wrapper<T>>::Metadata = T::Metadata`
type Metadata = <T as Pointee>::Metadata;
}
// ...
// This impl is only selected if `T` is a type parameter or unnormalizable projection or opaque type.
fallback impl<T /*: Sized */> Pointee for T {
type Metadata = ();
}
```
|
|
|
|
|
|
|
|
|
|
Remove unused args from functions
`#[instrument]` suppresses the unused arguments from a function, *and* suppresses unused methods too! This PR removes things which are only used via `#[instrument]` calls, and fixes some other errors (privacy?) that I will comment inline.
It's possible that some of these arguments were being passed in for the purposes of being instrumented, but I am unconvinced by most of them.
|
|
|
|
|
|
|