Skip to content

[interpreter] Descriptor type validation - #66

Merged
tlively merged 1 commit into
mainfrom
interp-descriptor-validation
Oct 22, 2025
Merged

[interpreter] Descriptor type validation#66
tlively merged 1 commit into
mainfrom
interp-descriptor-validation

Conversation

@tlively

@tlively tlively commented Oct 13, 2025

Copy link
Copy Markdown
Member

Check that descriptor and described types are properly paired, are
structs, and follow the subtyping rules.

let DescT (ut1, ut2, ct) = dt in
let DescT (ut1', ut2', ct') = dt' in
match ut1, ut1' with
| (Some ut1, Some ut1') ->

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@rossberg, I'm trying to validate that if dt <: dt', then we also have ut1 <: ut1', where ut1 and ut1' are the types described by dt and dt'.

I have this working in some cases, but it's super ugly and it breaks in other cases. Specifically, the idx_of_typeuse ut on line 178 fails when the four types are all in the same rec group because in that case it is a Rec rather than an idx.

Do you have a suggestion about how to do these checks more generally and cleanly?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh yes, defining that isn't going to be straightforward, due to all the mutual recursion going on. I'll probably have to think about it. Unfortunately, I just arrived at ICFP/OOPSLA today, so might lack the quiet moment this week and the next. But yeah, assuming you can extract indices is not going to work.

Check that descriptor and described types are properly paired, are
structs, and follow the subtyping rules.
@tlively
tlively force-pushed the interp-descriptor-validation branch from 589cc59 to ace53e5 Compare October 22, 2025 04:33
@tlively
tlively marked this pull request as ready for review October 22, 2025 04:33
@tlively

tlively commented Oct 22, 2025

Copy link
Copy Markdown
Member Author

@rossberg, this works now and is ready for review.

@tlively

tlively commented Oct 22, 2025

Copy link
Copy Markdown
Member Author

Landing now to be able to use the tests downstream, but happy to address any feedback in a follow-up.

@tlively
tlively merged commit 09abbe7 into main Oct 22, 2025
1 check passed

@rossberg rossberg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not

Comment on lines +183 to +184
| (None, None) -> ();
match ut2, ut2' with

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you fell for one of OCaml's syntax traps: this doesn't mean what you probably think it does. You want to put some parens around the prior match, otherwise this match is just part of the last branch.

So currently, the conditions on ut2/ut2' are not actually checked in the presence of a descriptor clause, nor the ones on ct/ct'. That may also suggest that we lack sufficient negative tests.

Comment on lines +191 to +192
| (Some _, None) | (None, None) -> ();
require (match_comptype c.types ct ct') at ("sub type " ^ I32.to_string_u x ^

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here.

match_heaptype c (UseHT (Inexact, ut1)) (UseHT (Inexact, (Def dt2)))
) uts1

let match_typeuse c ut1 ut2 (rt1 : rectype) (rt2 : rectype) =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Passing in the rectypes looks like a hack to me. Any such side information should rather come from the context.

In the formal rules (e.g. in SpecTec), the context has another component recs, which bind recusive type indices. So far, this wasn't needed in the interpreter, as it was only needed to validate rolled deftypes, which only occurs in the soundness proof. Hence the interpreter omits it. But perhaps a version of this is what's needed here?

But I'm rather confused why that should be the case. Where are the rec type indices actually coming from that can enter this function? AFAICS, all calls either use unrolled or not yet rolled arguments, so I would expect no rec type index to occur. If you asserted false for them, would this fail?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Indeed, it looks like everything still works out if the Rec i cases assert false. I guess I didn't consider that it would be ok for match_typeuse to be partial, and therefore had to pass rt1 and rt2 in to handle the recursive cases.

@tlively

tlively commented Nov 3, 2025

Copy link
Copy Markdown
Member Author

I'm not

I am very curious about what the rest of this sentence will be :)

tlively added a commit that referenced this pull request Nov 4, 2025
Update `check_desctype_sub` with the feedback from #66.
@rossberg

rossberg commented Nov 4, 2025

Copy link
Copy Markdown
Member

I'm not

I am very curious about what the rest of this sentence will be :)

Ha, it probably was something like "I'm not sure if the Rec case should be needed", but then I decided to put that inline. :)

tlively added a commit that referenced this pull request Nov 4, 2025
Update `check_desctype_sub` with the feedback from #66.
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.

2 participants