Skip to content

rec_check: expand fragile patterns for clarity#1911

Closed
gasche wants to merge 1 commit intoocaml:trunkfrom
gasche:minor-rec-check-refactoring
Closed

rec_check: expand fragile patterns for clarity#1911
gasche wants to merge 1 commit intoocaml:trunkfrom
gasche:minor-rec-check-refactoring

Conversation

@gasche
Copy link
Copy Markdown
Member

@gasche gasche commented Jul 17, 2018

As I was reading the code again I became convinced that there was
a mistake in the array-element-type classification code, because it
defaults to Paddrarray instead of Pgenarray -- which is the safe
default. I had to go through all the cases to convince me that there
was no bug (the default cases are all address-only cases), so
I propose to spell it out explicitly in the code for clarity.

(This small work was done as part of @Cemoixerestre's internship
on the recursive-value static check.)

@gasche gasche requested a review from yallop July 17, 2018 14:03
As I was reading the code again I became convinced that there was
a mistake in the array-element-type classification code, because it
defaults to Paddrarray instead of Pgenarray -- which is the safe
default. I had to go through all the cases to convince me that there
was no bug (the default cases are all address-only cases), so
I propose to spell it out explicitly in the code for clarity.
Copy link
Copy Markdown
Contributor

@trefis trefis left a comment

Choose a reason for hiding this comment

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

I feel like I'm missing something.

| Tlink _ | Tsubst _ ->
(* [Typeopt.scrape_ty] starts with [Ctype.expand_head_opt],
so these cases are impossible *)
assert false
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree that Tlink can't happen, because repr removes links.

I'm not sure your explanation holds for Tsubst though: try_expand_head_opt will raise Cannot_expand on Tsubsts, which will be caught by expand_head_opt which will then simply return its input (well, after calling repr on it).

Note: I'm not saying Tsubst can happen at this particular place, just that your explanation doesn't convince me.

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.

Thanks for the review. I don't know much about these internal invariants of the type-checker, and some of the things I wrote there are wishful thinking. It's very good that someone like you who knows more can double-check it. I agree that it's not clear what happens with Tsubst here, what motivated me to include it in the assert false is that other functions of ctype.ml failed on it in the same way.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

and some of the things I wrote there are wishful thinking

Please, don't (ever) do that again.

I agree that it's not clear what happens with Tsubst here, what motivated me to include it in the assert false is that other functions of ctype.ml failed on it in the same way.

Well, I guess that's because Tsubst can only appear in very few places, and are always (afaict) cleaned up right away.
It seems pretty obvious that your function is never called in these periods of time where Tsubst exists, so assert false is indeed fine.

I'd suggest either removing your comment, or splitting the cases and given a proper explanation to both.

@@ -169,7 +169,7 @@ let is_ref : Types.value_description -> bool = function
let scrape env ty =
(Ctype.repr (Ctype.expand_head_opt env (Ctype.correct_levels ty))).desc
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's not part of your diff, but that call to repr is useless I believe. (Though it doesn't cost much and makes it easier to reason about the code, so perhaps it's fine to just leave it here).

| Tpoly(t, _alphas) ->
(* this case should not occur after [scrape_ty],
but we handle it defensively *)
array_element_kind env t
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again, I don't understand why. Seems like repr (expand_head_opt (Tpoly(_)) would just be a noop. What am I missing?

@yallop
Copy link
Copy Markdown
Member

yallop commented Jul 18, 2018

I'll try to take a look at this next week.

@gasche
Copy link
Copy Markdown
Member Author

gasche commented Jul 18, 2018

@trefis wrote:

Again, I don't understand why [Tpoly cannot occur after scrape_ty].

Looking at this again, it seems indeed that my rationale is wrong. Tpoly is removed by scraping, but only the one above the array Tconstr, not one that could potentially occur below on the element type. On the other hand, I think that in fact we currently know the restricted set of places where Tpoly can occur (eg. record fields), and array element types are not one of them.

Note that Typeopt.classify, which is called by Typeopt.array_type_kind on the element type, asserts false on Tpoly node (and Tsubst btw.), and I think Typeopt.array_type_kind is called more often in the compiler than Rec_check.array_type_kind, so we should be safe.

Which raises the question: why is there this duplication in array-type-classification between Typeopt and Rec_check? Could we not use the Typeopt code instead of redoing the work? It looks like it has evolved to handle more cases, in particular its array_type_kind checks for the Predef.path_floatarray case which I guess is new.

(This may have been discussed when we reviewed the new rec-check, apologies for the redundant question.)

@trefis
Copy link
Copy Markdown
Contributor

trefis commented Jul 18, 2018

Tpoly is removed by scraping, but only the one above the array Tconstr, not one that could potentially occur below on the element type. On the other hand, I think that in fact we currently know the restricted set of places where Tpoly can occur (eg. record fields), and array element types are not one of them.

Again, I don't think Tpoly is ever removed by scrape, at least not the scrape I commented on above. But I agree with the rest indeed, we currently can't have Tconstr (_, [Tpoly _], _), ever.

@gasche
Copy link
Copy Markdown
Member Author

gasche commented Jul 20, 2018

This is now superseded by #1922.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants