Initial implementation of dyn*#101212
Conversation
|
This PR changes MIR cc @oli-obk, @RalfJung, @JakobDegen, @davidtwco, @celinval, @vakaras Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
|
Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
compiler-errors
left a comment
There was a problem hiding this comment.
left some initial comments, mostly nits! the code looks pretty good
There was a problem hiding this comment.
Can you explain why this is needed? Why can't this live in CastCheck, that is?
There was a problem hiding this comment.
When a dyn* cast check succeeds, there aren't any deferred checks we need to worry about, so it doesn't really make sense to build a CastCheck.
I guess another way to do this would be to make CastCheck::new return Result<Option<CastCheck>, ErrorGuaranteed>, but this way seemed cleaner to me. I'm happy to change it though if you think that's better.
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Outdated
Show resolved
Hide resolved
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Outdated
Show resolved
Hide resolved
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
Outdated
Show resolved
Hide resolved
compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
nit: Is it possible to put #[instrument] on the caller?
There was a problem hiding this comment.
If you can, I haven't figured out how to do it...
This comment has been minimized.
This comment has been minimized.
bjorn3
left a comment
There was a problem hiding this comment.
You missed the pointer_kind function in rustc_typeck/src/check/cast.rs. I think it needs to return Some(PointerKind::Thin) or None for dyn*. It didn't error because .. was used. Please also check other usages of Dynamic. For example I think you didn't change dyn* anywhere to be sized.
There was a problem hiding this comment.
What's the best way to test with the cranelift backend? I can make sure this doesn't crash cranelift.
Is this something we should fix as part of this PR, or would it be okay to do it as a follow up?
dyn* is sized here: https://github.com/rust-lang/rust/pull/101212/files#diff-34d5893dd95fe09f9a0fd3341efacd1c21853bb34ba29d9d79bb9af26bb8a0a0R1874 |
This comment has been minimized.
This comment has been minimized.
I just pushed a change that makes pointer_kind error for dyn*, like the other sized types do. That sort of seemed reasonable based on the surrounding code and comments, but I'm not 100% confident in that choice. What do you think? |
I think this is reasonable, but I'm not familiar with this code at all. r? rust-lang/compiler |
compiler/rustc_type_ir/src/sty.rs
Outdated
There was a problem hiding this comment.
Who decides the representation, where is that information (about the representation choice) encoded?
In the interpreter, it seems to always be a pointer to the real object (judging from the cast code, which is the only new code for this atm).
There was a problem hiding this comment.
The layout code sets the representation here: https://github.com/rust-lang/rust/pull/101212/files#diff-b0320c2b8868f325d83c027fc5d71732636e9763551e35895488f30fe057c6e9R627-R633
We construct these values here: https://github.com/rust-lang/rust/pull/101212/files#diff-db08b7c8b00530c7183cf2e42f25dc93b02da93fb40edadbd009eee6ad60e3a1R275-R289
There was a problem hiding this comment.
The first link does not set how things are represented, via pointer or via direct inlining. I was wondering how that is decided.
However the first link does say that the data part must be non-null, which should also be documented here.
Not sure where the second link is supposed to go; links into the 'diff' view of a PR are notoriously unrelaible...
There was a problem hiding this comment.
This should be more stable for the second link: https://github.com/rust-lang/rust/blob/242f9c128ebd5e107fc45ea3725e4e9745ff355b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs#L275...L289
At the moment the data part is made by basically transmuting whatever we are casting into it. The tests so far all work by casting a usize into a dyn*, for example: src/test/ui/dyn-star/method.rs.
Longer term we want to do this conversion using a family of lang traits called something like IntoDynPointer. I discuss this some in my blog post on async functions in traits. These would let types override the behavior. By default the implementation would probably be a straight cast for things that are already pointers and Box::new(self).into_raw() for things that are not, but we'd like to give flexibility in where async function return futures go.
The non-null requirement in the first link is incorrect, since it's totally reasonable to do 0 as dyn* Debug. I'll update that.
There was a problem hiding this comment.
Oh I see, so something somewhere checks that the LHS of an as dyn* is ptr-sized?
There was a problem hiding this comment.
It will in the future, but it doesn't now iirc...
compiler/rustc_type_ir/src/sty.rs
Outdated
There was a problem hiding this comment.
You can derive HashStable_Generic.
There was a problem hiding this comment.
I tried and got:
error[E0405]: cannot find trait `HashStableContext` in the crate root
--> compiler/rustc_type_ir/src/sty.rs:33:5
|
33 | HashStable_Generic
| ^^^^^^^^^^^^^^^^^^
| |
| not found in the crate root
| in this derive macro expansion
|
::: /home/ericholk/.cargo/registry/src/github.com-1ecc6299db9ec823/synstructure-0.12.6/src/macros.rs:94:9
|
94 | / pub fn $derives(
95 | | i: $crate::macros::TokenStream
96 | | ) -> $crate::macros::TokenStream {
| |________________________________________- in this expansion of `#[derive(HashStable_Generic)]`
A lot of other code in this file implements HashStable also, so I'm guessing there's some more fundamental reason we can't use this.
There was a problem hiding this comment.
You'll need to create an empty trait HashStableContext at the crate root, and implement it for ich::StableHashingContext in rustc_query_system. This is a bit convoluted, but I haven't found a better solution around the cyclic dependency issue.
There was a problem hiding this comment.
Given that this crate already has a lot of manual implementations for HashTable, I think it makes more sense to do the same here and then do a separate PR that moves as many as we can over to derive all at once. What do you think?
There was a problem hiding this comment.
I opened #101549 to do this for the other types. If that merges before this one (likely) then I'll update it here as well.
There was a problem hiding this comment.
That PR merged so I've updated this to use HashStable_Generic here too.
|
@bors r+ rollup=never rollup=never is since this might have perf effects or we might want to blame it for ICEs |
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (6153d3c): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression 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.
Footnotes |
|
Implemented for cg_clif in bjorn3/rustc_codegen_cranelift@879c86f. |
| Rvalue::Cast(CastKind::DynStar, _, _) => { | ||
| // FIXME(dyn-star) | ||
| unimplemented!() | ||
| }, |
There was a problem hiding this comment.
@eholk This doesn't look right. This gives me the feeling that Clippy might start panicking on every project that tries to use this nightly feature.
Is there a plan to address those unimplemented! macros?
Specify `DynKind::Dyn` ref: rust-lang#101212 (comment)
Specify `DynKind::Dyn` ref: rust-lang#101212 (comment)
Resolves 5542 Prior to rust-lang/rust#101212 the `ast::TraitObjectSyntax` enum only had two variants `Dyn` and `None`. The PR that introduced the `dyn*` syntax added a new variant `DynStar`, but did not update the formatting rules to account for the new variant. Now the new `DynStar` variant is properly handled and is no longer removed by rustfmt.
Specify `DynKind::Dyn` ref: rust-lang#101212 (comment)
Initial implementation of dyn* This PR adds extremely basic and incomplete support for [dyn*](https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/). The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things: * Introduce `dyn_star` feature flag * Adds parsing for `dyn* Trait` types * Defines `dyn* Trait` as a sized type * Adds support for explicit casts, like `42usize as dyn* Debug` * Including const evaluation of such casts * Adds codegen for drop glue so things are cleaned up properly when a `dyn* Trait` object goes out of scope * Adds codegen for method calls, at least for methods that take `&self` Quite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather `dyn*` is planned to be used as an implementation detail for async functions in dyn traits. Joint work with `@nikomatsakis` and `@compiler-errors.` r? `@bjorn3`
Initial implementation of dyn* This PR adds extremely basic and incomplete support for [dyn*](https://smallcultfollowing.com/babysteps//blog/2022/03/29/dyn-can-we-make-dyn-sized/). The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things: * Introduce `dyn_star` feature flag * Adds parsing for `dyn* Trait` types * Defines `dyn* Trait` as a sized type * Adds support for explicit casts, like `42usize as dyn* Debug` * Including const evaluation of such casts * Adds codegen for drop glue so things are cleaned up properly when a `dyn* Trait` object goes out of scope * Adds codegen for method calls, at least for methods that take `&self` Quite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather `dyn*` is planned to be used as an implementation detail for async functions in dyn traits. Joint work with `@nikomatsakis` and `@compiler-errors.` r? `@bjorn3`
| } | ||
|
|
||
| ty::Dynamic(_, _, ty::DynStar) => { | ||
| let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false)); |
There was a problem hiding this comment.
This sounds wrong -- if you are storing a pointer here, this should use a pointer layout, not an integer layout. Integers don't carry provenance, pointers do, so this makes a difference.
I am seeing some strange behavior in trying to get this to work in Miri and it looks like provenance is getting lost... so I am guessing this might be the reason. I see in an earlier commit this was using Pointer. Why did you change this to ptr_sized_integer?
Note that if something is either a pointer or an integer, then it must use a pointer type, not an integer type. Ptr-sized integers are a strict subset of pointers.
There was a problem hiding this comment.
I'm trying to fix this as part of #107728 but that leads to invalid LLVM IR errors...
| ty::Dynamic(_, _, ty::DynStar) => { | ||
| if i == 0 { | ||
| TyMaybeWithLayout::Ty(tcx.types.usize) | ||
| } else if i == 1 { | ||
| // FIXME(dyn-star) same FIXME as above applies here too | ||
| TyMaybeWithLayout::Ty( | ||
| tcx.mk_imm_ref( | ||
| tcx.lifetimes.re_static, | ||
| tcx.mk_array(tcx.types.usize, 3), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Is there some kind of implicit invariant that this must be consistent with layout_of_uncached? Nowadays these two functions are not even in the same crate. That seems very fragile. Am I missing something?
Cc @oli-obk
Resolves 5542 Prior to rust-lang/rust#101212 the `ast::TraitObjectSyntax` enum only had two variants `Dyn` and `None`. The PR that introduced the `dyn*` syntax added a new variant `DynStar`, but did not update the formatting rules to account for the new variant. Now the new `DynStar` variant is properly handled and is no longer removed by rustfmt.
Resolves 5542 Prior to rust-lang/rust#101212 the `ast::TraitObjectSyntax` enum only had two variants `Dyn` and `None`. The PR that introduced the `dyn*` syntax added a new variant `DynStar`, but did not update the formatting rules to account for the new variant. Now the new `DynStar` variant is properly handled and is no longer removed by rustfmt.
This PR adds extremely basic and incomplete support for dyn*. The goal is to get something in tree behind a flag to make collaboration easier, and also to make sure the implementation so far is not unreasonable. This PR does quite a few things:
dyn_starfeature flagdyn* Traittypesdyn* Traitas a sized type42usize as dyn* Debugdyn* Traitobject goes out of scope&selfQuite a bit is still missing, but this gives us a starting point. Note that this is never intended to become stable surface syntax for Rust, but rather
dyn*is planned to be used as an implementation detail for async functions in dyn traits.Joint work with @nikomatsakis and @compiler-errors.
r? @bjorn3