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

[BUG] @print shortcomings #840

Closed
JohelEGP opened this issue Nov 17, 2023 · 10 comments
Closed

[BUG] @print shortcomings #840

JohelEGP opened this issue Nov 17, 2023 · 10 comments
Labels
bug Something isn't working

Comments

@JohelEGP
Copy link
Contributor

Title: Single-expression functions print with extra semicolon.

Description:

This makes the printed code invalid Cpp2:

example.cpp2(4,51): error: a single-expression function should end with a single semicolon (at ';')

Minimal reproducer (https://cpp2.godbolt.org/z/jGb31dK74):

#include <functional>
t: @struct @print type = {
  x: std::function<void()> = :() = _ = 0;
  y: std::function<void()> = :() 0;
}
main: () = { }
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp

Expected result: Printed Cpp2 code to be valid.

Actual result and error: public x: std::function<void()> = :() = _ = 0;;.

Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"


class t;
  

//=== Cpp2 type definitions and function declarations ===========================

#include <functional>
class t {
  public: std::function<void()> x {[]() -> void { static_cast<void>(0);  }}; 
  public: std::function<void()> y {[]() -> auto { return 0;  }}; 
};
auto main() -> int;

//=== Cpp2 function definitions =================================================


auto main() -> int{}
Output:
main.cpp2...

t: type = 
{
    public x: std::function<void()> = :() = _ = 0;;

    public y: std::function<void()> = :() -> move _ = 0;;
}
 ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks)

See also:

@JohelEGP JohelEGP added the bug Something isn't working label Nov 17, 2023
@JohelEGP
Copy link
Contributor Author

JohelEGP commented Nov 17, 2023

This is #479's test:

u: @struct @print type = {
  t: type = {
    operator[]: (this, f) = {}
  }

  main: () -> int = {
    (x := t()) { x[:() -> _ = 0]; }
    (x := t()) { x[:() -> _ = 0;]; }

    assert(!(:() = 0; is int));

    _ = :i32 = 0;
    assert(true);

    return :i32 = 0;
  }

  a: i32 == :i32 = 0;
  b: i32 = 0;
}

main: () = {}

What it prints:

u: type = {
  public t: type = {
    operator[]: (in this, in f: ) = {}
  }

  public main: () -> move int = {
    (in x := t()) { x[:() -> move _ = 0]; }
    (in x := t()) { x[:() -> move _ = 0;]; }
    assert(!(:() = 0; is int))
    _ = :i32 = 0;
    ;
    assert(true)
    return :i32 = 0;
    ;
  }

  public a: i32 == :i32 = 0;
  ;

  public b: i32 = 0;
}

And where the errors are at:

u: type = {
  public t: type = {
    operator[]: (in this, in f: ) = { }
  }

  public main: () -> move int = {
    (in x := t()) { x[:() -> move _ = 0]; }
    (in x := t()) { x[:() -> move _ = 0;]; }
    assert(!(:() = 0; is int)); // Added ';'.
    _ = :i32 = 0;               // x.cpp2(10,5): error: missing ';' after contract-statement (at '_')
    // ;                        // x.cpp2(11,5): error: empty statement is not allowed - remove extra semicolon (at ';')
    assert(true);    // Added ';'.
    return :i32 = 0; // x.cpp2(13,5): error: missing ';' after contract-statement (at 'return')
    // ;             // x.cpp2(14,5): error: empty statement is not allowed - remove extra semicolon (at ';')
  }

  public a: i32 == :i32 = 0;
  // ; // x.cpp2(18,3): error: empty statement is not allowed - remove extra semicolon (at ';')

  public b: i32 = 0;
}
  • asserts need ;. Resolved with commit b41f60e.
  • Statements ending in ; need to remove any extra ;.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Nov 18, 2023

Also, deduced type parameters print with : but without a type/placeholder. Apparently, it works.
And function expressions in initializers of constexpr variables have an extra line break.
See https://cpp2.godbolt.org/z/aoY3zqEW7.

t: @struct @print type = {
  i: int == :(_) 0;(0);
}
main: () = { }
t: type = 
{
    public i: int == 
:(in _:) -> move _ = 0;(0);
}

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Nov 18, 2023

@structs print without @struct,
so they can be invalid Cpp2
and be interpreted by the user wrongly.

@struct doesn't generate Cpp2 code,
but instead affects lowering.
So it should be @printed.

@JohelEGP JohelEGP changed the title [BUG] Single-expression functions print with extra semicolon [BUG] @print shortcomings Nov 18, 2023
@AbhinavK00
Copy link

Very sorry for the questions but what does print metafunction do? Also, is it confirmed that multiple metafunctions can be applied on the same type?

@JohelEGP
Copy link
Contributor Author

For @print, when you use it, like at 586ff20#diff-4ccd4b8a84887f1aadc839722d871182e36bd2a986f4bae0dfa9edfdfe1a3952,
cppfront will pretty-print it during compilation: 586ff20#diff-86374c72ff7e9b814ef80bc78f78f4cac4189bf2b4fbb78be253303ff4ee9d4b.
It can be useful to see what a metafunction generates.
For example, see #821 (comment).

Yes, metafunctions form a pipeline: #447 (comment).

@AbhinavK00
Copy link

Thanks for the answer!

@hsutter
Copy link
Owner

hsutter commented Dec 26, 2023

Thanks!

I think I got them all, including the ones in your test cases and a few more... but please check and reopen with a new test case if I missed some.

@JohelEGP
Copy link
Contributor Author

Thank you.
How about #840 (comment)?

@structs print without @struct,
so they can be invalid Cpp2
and be interpreted by the user wrongly.

@struct doesn't generate Cpp2 code,
but instead affects lowering.
So it should be @printed.

@hsutter
Copy link
Owner

hsutter commented Dec 29, 2023

@struct doesn't generate Cpp2 code,
but instead affects lowering.
So it should be @printed.

Good point, that's the simplest fix for now so I'll implement it that way. Thanks!

@JohelEGP
Copy link
Contributor Author

With program-defined metafunctions (#907), that can be generally true for all metafunctions.
So it might be better if the pretty print visualizer could print processed metafunctions in a C comment.

hsutter added a commit that referenced this issue Dec 29, 2023
And update a few stray regression test results post-merges
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants