Skip to content

Conversation

Kamirus
Copy link
Member

@Kamirus Kamirus commented Jul 26, 2025

Allow inference of invariant type variables when the solution has no proper subtypes nor supertypes (except Top/Bottom).
After:

let _ = VarArray.map(va, func x = debug_show(x)); // needs no explicit instantiation

Before:
Since the result of the map function is a mutable array, the type variable in the result is invariant. This causes the following error:

cannot implicitly instantiate function of type
  <T, U>([var T], T -> U) -> [var U]
to argument of type
  ([var Nat], Nat -> U)
because implicit instantiation of type parameter U is under-constrained with
  Text  <:  U  <:  Any
where
  Text  =/=  Any
so that explicit type instantiation is requiredMotoko(M0098)

The compiler complains that it cannot solve U as, for example, both Text and Any would fit but they are not equivalent, and U is invariant so the choice matters.

IMO, considering Any as the solution for U is impractical and users would be better off not providing type instantiations in such cases.

However, there is danger in allowing arbitrary types as solutions for invariant type variables, so I propose we restrict these types to "isolated" types (types that have no proper subtypes nor supertypes except Top/Bottom). See the tests for more examples.

@Kamirus Kamirus changed the title experiment: pick non-trivial invariant bound feat: Solve invariant when bound is isolated (no proper super/subtypes except Top/Bottom) Aug 21, 2025
@Kamirus Kamirus changed the title feat: Solve invariant when bound is isolated (no proper super/subtypes except Top/Bottom) feat: Infer invariant when bound is isolated (no proper super/subtypes except Top/Bottom) Aug 21, 2025
@Kamirus Kamirus marked this pull request as ready for review August 21, 2025 14:56
@Kamirus Kamirus requested a review from a team as a code owner August 21, 2025 14:56
@crusso
Copy link
Contributor

crusso commented Aug 21, 2025

At first glance this looks very nice! How do you feel about it?

@crusso
Copy link
Contributor

crusso commented Aug 21, 2025

Curious if the example from #5036 now works.

@Kamirus
Copy link
Member Author

Kamirus commented Aug 21, 2025

At first glance this looks very nice! How do you feel about it?

I feel good about it, I think this is a good change 😄

@Kamirus
Copy link
Member Author

Kamirus commented Aug 21, 2025

Curious if the example from #5036 now works.

I've just added a test for it, and yes it does infer now, because the bound was Text

@crusso
Copy link
Contributor

crusso commented Aug 21, 2025

@christoph-dfinity whaddya think? I like it...but maybe you can see a downside.

Copy link
Contributor

@christoph-dfinity christoph-dfinity left a comment

Choose a reason for hiding this comment

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

Code changes look good. I think I can follow the reasoning and motivation as well, so LGTM!

@Kamirus Kamirus merged commit d47441e into master Aug 25, 2025
24 checks passed
@Kamirus Kamirus deleted the kamil/invariant-bounds-choice branch August 25, 2025 10:45
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.

4 participants