Make Trace object-safe, allowing dynamic types and slices to be garbage collected#20
Closed
Make Trace object-safe, allowing dynamic types and slices to be garbage collected#20
Conversation
This is a problem because 'Trace' and 'GcSafe' have associated constants 'Trace::NEEDS_TRACE' and 'GcSafe::NEEDS_DROP'. I've seperated these associatred consts into their own GcTypeInfno trait. I've messed around with this all day...... So far it looks like we might end up requiring signficant amounts of nightly features D:
This will be required for allocation in a 'Gc', unless the type is a slice or something. All other types will just implement trace directly.
I was planning to have three traits (GcType, GcSlice, GcDynObject) for types which are sized, slices, and unsized respectively. This wont work out because they are overlapping impls -_-
Member
Author
|
This needs to be reimplemented with the new pointer metadata API. I'm considering just making everything thin pointers so that it is easier for the collector to trace, and more consistent with the . The most important |
Member
Author
|
Superceeded by #29 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The simple part is making a dynamically dispatched version of 'Trace' and 'GcVisitor'. I just added
where Self: Sizedbounds to all the generic methods and added an object-safe fallback.This main problem is that 'Trace' and 'GcSafe' have associated
constants 'Trace::NEEDS_TRACE' and 'GcSafe::NEEDS_DROP'.
I've separated these associated consts into their own GcTypeInfno
trait.
I've messed around with this all day.
So far it looks like we might end up requiring significant amounts of
nightly features D:
Fixes #15
Required for #16
Goals
NullTracemaker as a simpler alternativestd::mem::needs_dropmay return a false-positivetrueStaticTypeLayoutstruct in the futureApproaches
I see three main approaches that keep the current type hierarchy, and there are pitfalls to each one.
Right now I'm leaning towards separate
DynTracetypes or having separate trait requirements for sized and unsized types.Require
where *const Self: GcTypeInfofor all Trace typesDirectly extending
TracefromGcTypeInfodoesn't work. The rust compiler requires supertypes to be object-safe.When wrapped with a pointer, the type can then implement non-object-safe constants. We simply add functions
needs_traceandneeds_gc_dropwhich query<*const T as GcTypeInfo>::NEEDS_TRACE(orNEEDS_DROP).The big advantage is this approach works on stable!
The disadvantage is that the bound isn't implied for generic parameters.
If you have
impl<T: Trace> Trace for Box<T>then the compiler complains that*const Tdoesn't implementGcTypeInfo.You must explicitly add a where-bound
where *const T: GcTypeInfoto each and every generic parameter 🙄The implied generic parameters would be fixed by RFC 2089. However, this would probably require nightly, maybe even for API clients.
Specialization
We could use specialization internally to implement
needs_traceandneeds_dropfunctions.Problems
min_specializationspecializationfeature is unsound, so we absolutely want to avoid it#[rustc_unsafe_specialization_marker]GcTypeInfoto be implemented for allTrace + Sizedtypes?Associated Type
We could require an associated type
type Info: GcTypeInfo. By default, the associated type would beSelffor anySizedtypes. However, for unsized types we would haveInfo = DefaultTypeInfothat gives conservative defaults.Associated type defaults were accepted in RFC 2532.
Problems
Self: GcTypeInfobound on the trait?Separate erased traits:
DynTraceandDynGcVisitorThis is what erased serde did. This is the first approach I tried. It was complex because I had to essentially make the GC accept both
TraceandDynTrace. They often needed to be treated separately and there was unessicarry code duplication :(Maybe we should make the
Tracetrait object safe by default, but keepGcSafesized?The main type that requires
GcSafeisGc<'gc, T>(for safety). That requirement could certainly be relaxed to only the constructors.......Could we have separate traits
GcSafeandGcStaticType? Any sized type must implementGcStaticTypeand give us the flags (NEEDS_TRACE/NEEDS_DROP) that we want.