-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make Thin
a supertrait of Sized
#122553
make Thin
a supertrait of Sized
#122553
Conversation
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
// about `<T as Pointee>::Metadata == ()` that can be fixed by `T: Sized`. | ||
if error.predicate.to_opt_poly_projection_pred().is_some() | ||
&& error2.predicate.to_opt_poly_trait_pred().is_some() | ||
&& self.error_fixed_by( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can just use error_fixed_by
everywhere -- it seems more general than error_implied_by
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessarily in this PR, but maybe tracked as a FIXME.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I tried first, but there are multiple problems with this approach:
error_fixed_by
does not work when there are any infer vars incond
(first arg). This adds a lot of duplicate diagnostics.- There are some cases where
A fixed-by B
+not (B fixed-by A)
+B fixed-by C
+not (C fixed-by B)
+C fixed-by A
+not (A fixed-by C)
. In these cases, replacingerror_implied_by
witherror_fixed_by
causes no diagnostics to be emitted. This cannot happen witherror_implied_by
, becauseA implied-by B
is transitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- There are some cases where
A fixed-by B
+not (B fixed-by A)
+B fixed-by C
+not (C fixed-by B)
+C fixed-by A
+not (A fixed-by C)
.
After thinking about this again, I'm actually not sure anymore whether this can actually happen and can't come up with a concrete example. I had a test failing and thought that was due a cycle like that, but after trying it again it turned out to be an unrelated implementation bug.
This comment has been minimized.
This comment has been minimized.
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
This comment has been minimized.
This comment has been minimized.
The Miri subtree was changed cc @rust-lang/miri |
@@ -9,33 +9,33 @@ LL | let x: Vec<dyn Trait + Sized> = Vec::new(); | |||
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Trait + Sized {}` | |||
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits> | |||
|
|||
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time | |||
error[E0277]: the size for values of type `dyn Trait<Metadata = ()>` cannot be known at compilation time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This happens, because we do lower multiple principals in trait objects like dyn Trait + Copy
during astconv (HIR->Ty lowering), but most code that consumes Ty
s does not handle trait objects with multiple principals correctly, including the pretty printer.
I can fix this in a follow-up, either by making the pretty print work with multiple principals or by just stopping to lower more than one principal.
☔ The latest upstream changes (presumably #122493) made this pull request unmergeable. Please resolve the merge conflicts. |
the changes look good. Want a perf + crater run here though |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
make `Thin` a supertrait of `Sized` This is a follow-up to rust-lang#120354 to address rust-lang#120354 (comment) and remove the "fallback impl" hack from `<T as Pointee>::Metadata` normalization in both trait solvers. We make `Thin` and therefore `Pointee<Metadata = ()>` a supertrait of `Sized`, such that every (implicit or explicit) `T: Sized` bound now also requires `T: Thin` and `<T as Pointee>::Metadata == ()`. These new bounds will be used when normalizing `<T as Pointee>::Metadata` instead of a hacky builtin impl that only applies for type parameters and aliases and overlaps with other builtin impls. Note that [RFC 2580](https://rust-lang.github.io/rfcs/2580-ptr-meta.html), which introduced `Pointee` and `Thin`, lists these unresolved questions: > Should `Thin` be added as a supertrait of `Sized`? Or could it ever make sense to have fat pointers to statically-sized types? For now, they are answered with yes and no respectively. If we end up deciding that we do want types that are `Sized + !Thin`, then a possible alternative is to add make `Thin` a defaulted trait bound that can be relaxed with `T: ?Thin` and remove `Thin` as supertrait from `Sized` before the stabilization of `feature(ptr_metadata)`. --- The removal of the "fallback impl" also allows us to always project to the shallow struct tail in the old solver, making the implementation in the old solver almost identical to the new solver. This is required to make `<Wrapper<T> as Pointee>::Metadata` work correctly in the presence of trivial bounds, for example if we know `[T]: Thin`, then we should also know `Wrapper<T>: Thin`. Lastly, this PR implements some diagnostics changes to hide errors about `` type mismatch resolving `<T as Pointee>::Metadata == ()` `` when the actual error comes from `T: Sized`. This is a continuation of rust-lang#121863. r? `@lcnr`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (32beed4): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 669.396s -> 672.715s (0.50%) |
could the perf impact be reduced by also checking |
That would be wrong if there are any I've already found out that 100% of the extra time is spent in |
[perf] cache type info for ParamEnv This is an attempt to mitigate some of the perf regressions in rust-lang#122553 (comment), but seems worth to test and land separately. r? `@ghost`
Ok so, update on the perf situation and why fixing perf is taking so long: After some extensive testing, it looks like the majority of the slowdown is actually caused by the larger A hacky workaround would be to reduce the clauses in the param env, by "downgrading" The real fix is to make the trait solver not slow in the presence of large param envs, which I'll try to work towards to. To start this endeavor I've opened #123058, which already seems to help significantly. @rustbot author Footnotes
|
[perf] cache type info for ParamEnv This is an attempt to mitigate some of the perf regressions in rust-lang#122553 (comment), but seems worth to test and land separately, since it is mostly unrelated to that PR.
[perf] cache type info for ParamEnv This is an attempt to mitigate some of the perf regressions in rust-lang/rust#122553 (comment), but seems worth to test and land separately, since it is mostly unrelated to that PR.
@lukas-code any updates on this? thanks |
@Dylan-DPC I'm still working on the performance regressions an have some updates on an experimental branch here: https://github.com/lukas-code/rust/tree/sized-thin-wip. But I'm not entirely happy with my implementation yet and there are still some outstanding performance issues, especially for the |
Thanks, that's fine. Though alternatively i would recommend closing this pr and working on your branch and once you have found the way through to submit a pr to prevent this pr going stale and bitrotting and then turning out a mess to rebase but i'll keep it open for now |
Ping from triage: I'm closing this due to inactivity, Please reopen when you are ready to continue with this. @rustbot label: +S-inactive |
This is a follow-up to #120354 to address #120354 (comment) and remove the "fallback impl" hack from
<T as Pointee>::Metadata
normalization in both trait solvers.We make
Thin
and thereforePointee<Metadata = ()>
a supertrait ofSized
, such that every (implicit or explicit)T: Sized
bound now also requiresT: Thin
and<T as Pointee>::Metadata == ()
. These new bounds will be used when normalizing<T as Pointee>::Metadata
instead of a hacky builtin impl that only applies for type parameters and aliases and overlaps with other builtin impls.Note that RFC 2580, which introduced
Pointee
andThin
, lists these unresolved questions:For now, they are answered with yes and no respectively. If we end up deciding that we do want types that are
Sized + !Thin
, then a possible alternative is to add makeThin
a defaulted trait bound that can be relaxed withT: ?Thin
and removeThin
as supertrait fromSized
before the stabilization offeature(ptr_metadata)
.The removal of the "fallback impl" also allows us to always project to the shallow struct tail in the old solver, making the implementation in the old solver almost identical to the new solver. This is required to make
<Wrapper<T> as Pointee>::Metadata
work correctly in the presence of trivial bounds, for example if we know[T]: Thin
, then we should also knowWrapper<T>: Thin
.Lastly, this PR implements some diagnostics changes to hide errors about
type mismatch resolving `<T as Pointee>::Metadata == ()`
when the actual error comes fromT: Sized
. This is a continuation of #121863.r? @lcnr