Skip to content

Supporting dyn Trait #762

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

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft

Supporting dyn Trait #762

wants to merge 28 commits into from

Conversation

ssyram
Copy link
Contributor

@ssyram ssyram commented Jul 8, 2025

Currently still a draft. Predicates done.

pub enum ExistentialPredicate {
Trait(ExistentialTraitRef),
Projection(ExistentialProjection),
AutoTrait(TraitDeclId),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not make this a separate variant, we can handle it as a Trait.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will store everything in the ExistentialTraitRef, this is more clean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not sure how, let us discuss in Zulip.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we keep the current structure?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's replace all the AutoTraits with Trait, and document what the projection applies to; after that yeah that's good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you mean we incorporate the AutoTraits in Trait? An ExistentialPredicate should then be: 1. a "Principal" ExistentialTraitRef (being a TraitRef), 2. a list of projections and 3. a list of auto trait ids? From enum to a struct?

@Nadrieril
Copy link
Member

Nadrieril commented Jul 8, 2025

Haven't reviewed everything but from what I've seen: could you change how we represent the existential predicates? The current encoding will cause issues with generics (see inline comments).

@ssyram
Copy link
Contributor Author

ssyram commented Jul 9, 2025

Thanks for all the suggestions from both of you! I'm still not sure about how to refractor the Predicate form. So I will leave it to the discussion in Zulip. Let me fetch & implement the vtable struct & instances first.

@ssyram
Copy link
Contributor Author

ssyram commented Jul 9, 2025

Many fixes applied. Thanks for the advice. Mainly involving the fix for the three kinds of existential predicates. But I'm still not sure about if they work as expected...

Comment on lines 115 to 118
let trait_decl_ref =
self.translate_trait_decl_ref_from_ex_trait_ref(span, &proj.def_id, &proj.args)?;
// self.translate_trait_decl_ref(span, item);
let args = self.translate_ex_generics(span, &proj.args)?;
let name = self.t_ctx.translate_trait_item_name(&proj.def_id)?;
let term = match &proj.term {
hax_frontend_exporter::Term::Ty(ty) => TyTerm::Ty(self.translate_ty(span, ty)?),
hax_frontend_exporter::Term::Ty(ty) => {
TyTerm::Ty(self.translate_ty(span, ty)?)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an assertion that the trait_ref is the one we expect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no trait_decl_ref now in Projection.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's exactly why you should check that the trait_ref you're ignoring is the one you expect. Because someone may write dyn Debug + Pointee<Metadata=()> where the projection applies to some trait other than the main one (I don't know if this is allowed today but this could be).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referring to Pointee like that is not possible. But it is still possible that the item refers to the associated type from super trait. Is there a way to refer to that? Using the item name itself seems not sufficient to resolve this. Shall we change the mechanism?

Copy link
Member

@Nadrieril Nadrieril Jul 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh true, could be a supertraits type that's a good example. I propose we error if that happens for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a known-failure test for that case please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another good point is that, Rust seems to not allow such specification to have shadowing names, hence the specification by name at the point can uniquely point to an assoc type. Or, it may be just that I'm not familiar with the syntax... At least I don't know how to express:

trait Base { type Assoc; }
trait Trait { type Assoc; }
fn main() {
  let x : &dyn Trait<Assoc=(), ???> = ...;
}

where ??? denotes the specification of Base::Assoc. The Rustc error hints that "consider renaming".

@Nadrieril
Copy link
Member

Nadrieril commented Jul 9, 2025

Could you add a lot of tests please? We need to cover edge cases even if we don't support them yet (write //@ known-failure at the top for these cases). We should have tests for supertraits, multiple supertraits, casting in a generic context, associated type projections, + 'a bounds, multiple trait bounds (dyn Any + Send), just builtins (dyn Send), traits with methods that are generic and have a Self: Sized bound (which makes them dyn-compatible but means the vtable doesn't have all the methods), etc.

Co-authored-by: Nadrieril <Nadrieril@users.noreply.github.com>
@ssyram
Copy link
Contributor Author

ssyram commented Jul 9, 2025

Yes, of course. Many tests are coming when the infrastructure is about to get done... Maybe we can focus on the implementation for now?

@Nadrieril
Copy link
Member

Nadrieril commented Jul 9, 2025

Maybe we can focus on the implementation for now?

The tests will help me understand what the implementation is doing, I can't just be running the code in my head. It's imo crucial to add the tests while doing the implementation because that's when we think of edge cases. When we're done implementing it's too late.

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

Successfully merging this pull request may close these issues.

3 participants