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] Braces around assignment's RHS prevents deduction #312

Closed
JohelEGP opened this issue Apr 2, 2023 · 7 comments
Closed

[BUG] Braces around assignment's RHS prevents deduction #312

JohelEGP opened this issue Apr 2, 2023 · 7 comments
Labels
bug Something isn't working

Comments

@JohelEGP
Copy link
Contributor

JohelEGP commented Apr 2, 2023

Describe the bug
feff640 added braces around the RHS of assignment in emitted assignment operators. This prevents deduction when the invoked assignment operator is a template, as a braced-init-list has no type.

To Reproduce
Steps to reproduce the behavior:

  1. Sample code
t1: type = {
  operator=: (out this, x) = {}
}

t2: type = {
  m: t1;
  operator=: (out this, a) = {
    m = a;
  }
}

main: () = {
  x: t2 = 0;
  x = 0;
}
  1. Command lines including which C++ compiler you are using
~/root/bin/cppfront x.cpp2 
~/root/clang/bin/clang++ -std=c++20 -I $CPPFRONT_INCLUDE_DIR x.cpp
clang version 17.0.0
  1. Expected result - what you expected to happen
    What happened before feff640.
  2. Actual result/error
x.cpp2:8:7: error: no viable overloaded '='
    m = {a};
    ~ ^ ~~~
x.cpp2:14:5: note: in instantiation of function template specialization 't2::operator=<int>' requested here
  x = 0;
    ^
x.cpp2:2:12: note: candidate template ignored: couldn't infer template argument 'x:auto'
  auto t1::operator=(auto const& x) -> t1& {
           ^
x.cpp2:1:7: note: candidate function (the implicit copy assignment operator) not viable: cannot convert initializer list argument to 'const t1'
class t1 {
      ^
x.cpp2:1:7: note: candidate function (the implicit move assignment operator) not viable: cannot convert initializer list argument to 't1'
class t1 {
      ^
1 error generated.
@JohelEGP JohelEGP added the bug Something isn't working label Apr 2, 2023
@filipsajdak
Copy link
Contributor

feff640 was needed to solve #291

m = {a};

Can be replaced with:

m = t1{a}; // t1 is a type of m

Maybe that will be a good generic solution.

@JohelEGP
Copy link
Contributor Author

JohelEGP commented Apr 2, 2023

But that'll construct a t1 and then move assign.

@hsutter
Copy link
Owner

hsutter commented Apr 2, 2023

I agree with @JohelEGP ... the reason I added { } everywhere is that it was an easy way to avoid emitting an empty initializer, but now I think it was a lazy solution and I should just detect that the initializer is empty and if so emit just the empty initializer as {}.

That way we also won't get the Clang warning, to stay warning-clean.

@hsutter hsutter closed this as completed in f608b78 Apr 2, 2023
@hsutter
Copy link
Owner

hsutter commented Apr 2, 2023

Fix pushed... and it still keeps #291 solved. Thanks everyone!

@filipsajdak
Copy link
Contributor

@hsutter Please remember it is not only about empty initializer. There are also cases like the following:

element: type = {
    children: std::vector<int> = (1,2,3);
    tab : std::vector<int>;

    operator=: (out this, t : int ) = {
        tab = (3,2,1);
    }
}

That previously generated:

#line 5 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator_4.cpp2"
    element::element(cpp2::in<int> t)
        : tab{ 3, 2, 1 }
#line 5 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator_4.cpp2"
    {

    }
#line 5 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator_4.cpp2"
    auto element::operator=(cpp2::in<int> t) -> element& {
        children = 1, 2, 3;
        tab = 3, 2, 1;
        return *this;

#line 7 "/Users/filipsajdak/dev/execspec/external/tests/bug_assignement_operator_4.cpp2"
    }

children and tab does not have empty initializers and need braces around them.

@filipsajdak
Copy link
Contributor

But I think we can add braces when the initializer is empty or when the initializer was created with parentheses.

@filipsajdak
Copy link
Contributor

@hsutter, the current implementation generates again:

        children = 1, 2, 3;
        tab = 3, 2, 1;

as here: #312 (comment)

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