Skip to content
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

Fixed implicit borrow of expressions #390

Merged
merged 3 commits into from
Dec 1, 2020
Merged

Conversation

vallentin
Copy link
Collaborator

@vallentin vallentin commented Dec 1, 2020

This does not introduce any breaking changes*.

The change fixes so expressions are now borrowed as a whole, instead of only the first value. Which would cause compile errors, for types that don't implement e.g. Add<T> for &T.

In short expressions now expand into &(...) instead of &....

* Technically, it would be considered a breaking change. However, I'd say it's highly unlikely someone has implemented e.g. Add<T> for &T and not Add<T> for T. To be able to rely on something that could be considered inconsistent behavior.


Example 1

Minimal example:

{{ true && true }}

Which expands like this:

Before: &true && true
After: &(true && true)

Resulting in the following compile error:

error[E0308]: mismatched types
   |
11 | #[derive(Template)]
   |          ^^^^^^^^ expected `bool`, found `&bool`

This isn't and was never an issue for e.g. {{ 1 + 2 }}, as the various operators e.g. Add<&T> for T are implemented for various types. However, this is not the case for short-circuit operators.

To have a more complete example of when this applies. I personally have a few macros, which accept booleans to decide on what it expands to.

{% macro foo(b) %}
    {% if b.clone() %}
        ...
    {% endif %}
{% endmacro %}

{% call foo(true && true) %}

Which expands like this:

Before: let (b) = (&true && true);
After: let (b) = (&(true && true));

The fact that .clone() is needed, is a whole other can of worms.


Example 2

Another example where this also manifests itself is:

#[derive(Template)]
#[template(path = "foo.html.jinja")]
struct Foo {
    time: SystemTime,
    dur: Duration,
}
{{ self.time + self.dur }}

Once again only Add<Duration> for SystemTime exists, so this also resulted in a compile error:

error[E0369]: cannot add `Duration` to `&SystemTime`

@djc djc merged commit f4065b0 into rinja-rs:main Dec 1, 2020
@djc
Copy link
Collaborator

djc commented Dec 1, 2020

LGTM, thanks!

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