Skip to content
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

Removing generics from Type #266

Open
oscartbeaumont opened this issue Jul 3, 2024 · 0 comments
Open

Removing generics from Type #266

oscartbeaumont opened this issue Jul 3, 2024 · 0 comments

Comments

@oscartbeaumont
Copy link
Member

I don't think we are doing this but this is an overview to the options copied from my notes so it's preserved.

Why generics?

  1. Say you have struct A<T>(T). Everything is within a single impl Type for A so we know of the generic and it's usage.
  2. Say now you have struct B<T>(Option<T>). This involves two impls, one for impl Type for Option<U> and one for impl Type for B<T>. How do we correlate them?
    • Thoughts:
      • A stack of generics by name???
      • Remove generics from inline but leave it for the rest.

Assuming case 2 flow old system:

  • <A<T> as Type>::reference - generics: &[GenericType("T")]

    • <Option<U> as Type>::reference - generics: &[GenericType("U")]

    How can I go Option<String> to that is the U generic?
    Type aliases blow shit up.
    Take into account bounds, does the inner type have a weird ass bound that any placeholder type might break?
    Is this actually supported properly by the current system? I think it is but idk.

    <A<T> as Type>::Reference::reference() - This approach doesn't get us closer to the goal.

    We could replace the generics.
    Eg. struct A<T>(Option<T>) becomes Option<GenericT> and then we let Rust do it's thing.
    This system would solve type aliases, however it would break if you have custom bounds Eg. Option<U: Debug> because GenericT can't magically have Debug.
    Can we taint the DataType and replace it on the way back???

Option should emit:
DataType::Nullable(DataType::Generic { pos: 1 })) -> This would have the same problem

Let's try this again:

  • Given any A<T> or A their can only be a single valid set of bounds (due to conflicting impls)
    • Therefore impls can't be differentiated by their bounds
    • Basically so I can ignore them for the reference generation cause they will be checked by the inline impl.
  • We also have zero knowledge of which type the generic is used on. It may be hidden by an unexpanded macro.
    • This is the hard problem because the crazy destructuring isn't a viable path.
    • Replace it with an Infer placeholder brings up some major problems mainly:
      • All primitive impls become cringe because they have to account for it
      • Combinatoric explosion for Result<T: Type | Placeholder, U: Type | Placeholder>
    • So I wonder if Type::definition should be lifted off Type so that it has no bounds.

Basically we can support macros to generate types or we can support type aliases.

Come back to:

  • So I wonder if Type::definition should be lifted off Type so that it has no bounds.

Distill the problem

Say we have:

type Input<U> = HashMap<String, HashMap<U, ()>>;
pub struct A<T = ()>(Input<T>)

How does HashMap::definition know when to use T (which equals but is not U) instead of ().
Well:
- We can't rely on the type's ID because it shows up twice in the type.

Let's say we work backwards.

  • HashMap<T, U>::reference returns [DataType::Generic; 2]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant