quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.83k stars 2.7k forks source link

Qute: Unexpected primitive equality #44610

Open neon-dev opened 1 day ago

neon-dev commented 1 day ago

Describe the bug

This Qute template is rendered as 0 is not 0:

{@long number=0L}
{number} is {#if number == 0}0{#else}not 0{/if}

The same happens when comparing a long returned from a method with an int in a template. I didn't check for other types.

Expected behavior

Primitive numbers should be compared by their value, not their type.

Actual behavior

== and != fail with primitive numbers of different data types.

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

3.15.2

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

quarkus-bot[bot] commented 1 day ago

/cc @mkouba (qute)

mkouba commented 23 hours ago

Hm, I believe that this is a duplicate of #40097.

It works if you change your template to:

{@long number=0L}
{number} is {#if number == 0l}0{#else}not 0{/if}

or even:

{@int number=0}
{number} is {#if number == 0}0{#else}not 0{/if}
neon-dev commented 22 hours ago

It works if you change your template to

Sure, but should this be necessary? In Java 0L == 0 is true, so I'd argue Qute should behave in the same way. In the example code such an issue is easy to spot, but if we compare some long count returned from a Java method in a Qute template it is no longer so obvious. For example, this would fail:

{#if stats:count != 0}

while this would work:

{#if stats:count > 0}
mkouba commented 22 hours ago

It works if you change your template to

Sure, but should this be necessary?

No, it should not, but it's already covered by #40097. In other words, if we fix #40097 then your template should work too because we should apply the "Widening Primitive Conversion" everywhere. That's why I said it's a duplicate.

For example, this would fail:

{#if stats:count != 0}

while this would work:

{#if stats:count > 0}

Hm, you're right that {#if} is a bit special and we could actually fix the condition easily. For the > operator we convert the values to BigDecimal if the types are not the same. It's not very efficient but we could use the same strategy for == and java.lang.Numbers.

I will try to propose something later today.

neon-dev commented 22 hours ago

That's why I said it's a duplicate.

Oh, then there must have been some misunderstanding here: https://github.com/quarkusio/quarkus/issues/40097#issuecomment-2490274020